EasyTCP
view release on metacpan or search on metacpan
0.05
- Fixed a bug where calling the receive() method may have failed if a signal (such as child dying)
was delivered to the process at the same time. The bug became apparent on heavily-stormed
servers with many forked() children dying, causing the negotiation with new clients to sometimes
fail.
- Re-wrote the server-side negotiating code to prevent it from blocking for couple of seconds during
negotiating with a newly connected client.
0.04
- Fixed a bug where older versions of Crypt::CBC were not called correctly causing "make test"
and almost everything else to fail.
- Minor changes to the protocol negotiation
0.03
- Added encryption support for Crypt::DES_EDE3, Crypt::DES and Crypt::Blowfish
- Added 2 new methods to determine what type of compression and encryption has been negotiated.
0.02
use IO::Socket;
use IO::Select;
use Storable qw(nfreeze thaw);
#
# This block's purpose is to:
# Put the list of available modules in %_COMPRESS_AVAILABLE and %_ENCRYPT_AVAILABLE and %_MISC_AVAILABLE
#
BEGIN {
my $version;
my $hasCBC;
my @_compress_modules = (
#
# MAKE SURE WE DO NOT EVER ASSIGN THE SAME KEY TO MORE THAN ONE MODULE, EVEN OLD ONES NO LONGER IN THE LIST
#
# HIGHEST EVER USED: 2
#
[ '1', 'Compress::Zlib' ],
[ '2', 'Compress::LZF' ],
);
my @_encrypt_modules = (
#
# MAKE SURE WE DO NOT EVER ASSIGN THE SAME KEY TO MORE THAN ONE MODULE, EVEN OLD ONES NO LONGER IN THE LIST
#
# HIGHEST EVER USED: E
#
[ 'B', 'Crypt::RSA', 0, 0 ],
[ '3', 'Crypt::CBC', 0, 0 ],
[ 'A', 'Crypt::Rijndael', 1, 1 ],
[ '9', 'Crypt::RC6', 1, 1 ],
[ '4', 'Crypt::Blowfish', 1, 1 ],
[ '6', 'Crypt::DES_EDE3', 1, 1 ],
[ '5', 'Crypt::DES', 1, 1 ],
[ 'C', 'Crypt::Twofish2', 1, 1 ],
[ 'D', 'Crypt::Twofish', 1, 1 ],
[ 'E', 'Crypt::TEA', 1, 1 ],
[ '2', 'Crypt::CipherSaber', 0, 1 ],
);
# (this is not as necessary as compress and encrypt since it's not transmitted to peers, but just in case...)
#
# HIGHEST EVER USED: 1
#
[ '1', 'Crypt::Random' ],
);
#
# Let's reset some variables:
#
$hasCBC = 0;
$_COMPRESS_AVAILABLE{_order} = [];
$_ENCRYPT_AVAILABLE{_order} = [];
$_MISC_AVAILABLE{_order} = [];
#
# Now we check the compress array for existing modules
#
foreach (@_compress_modules) {
$@ = undef;
eval {
#
# Now we check the encrypt array for existing modules
#
foreach (@_encrypt_modules) {
$@ = undef;
eval {
eval("require $_->[1];") || die "$_->[1] not found\n";
$version = eval("\$$_->[1]::VERSION;") || die "Failed to determine version for $_->[1]\n";
};
if (!$@) {
if ($_->[1] eq 'Crypt::CBC') {
$hasCBC = 1;
}
elsif (($hasCBC && $_->[2]) || !$_->[2]) {
push(@{ $_ENCRYPT_AVAILABLE{_order} }, $_->[0]);
$_ENCRYPT_AVAILABLE{ $_->[0] }{name} = $_->[1];
$_ENCRYPT_AVAILABLE{ $_->[0] }{cbc} = $_->[2];
$_ENCRYPT_AVAILABLE{ $_->[0] }{mergewithpassword} = $_->[3];
$_ENCRYPT_AVAILABLE{ $_->[0] }{version} = $version;
}
}
}
#
Symmetric encryption will be automatically enabled if one (or more) of: L<Crypt::Rijndael|Crypt::Rijndael>* or L<Crypt::RC6|Crypt::RC6>* or L<Crypt::Blowfish|Crypt::Blowfish>* or L<Crypt::DES_EDE3|Crypt::DES_EDE3>* or L<Crypt::DES|Crypt::DES>* or L<C...
Strong randomization will be automatically enabled if L<Crypt::Random|Crypt::Random> is installed; otherwise perl's internal rand() is used to generate random keys.
Preference to the compression/encryption method used is determind by availablity checking following the order in which they are presented in the above lists.
Note that during the negotiation upon connection, servers and clients written using Net::EasyTCP version lower than 0.20 communicated the version of the selected encryption/compression modules. If a version mismatch is found, the client reported a c...
To find out which module(s) have been negotiated for use you can use the compression() and encryption() methods.
* Note that for this class's purposes, L<Crypt::CBC|Crypt::CBC> is a requirement to use any of the encryption modules with a * next to it's name in the above list. So eventhough you may have these modules installed on both the client and the server,...
* Note that the nature of symmetric cryptography dictates sharing the secret keys somehow. It is therefore highly recommend to use an As-symmetric cryptography module (such as Crypt::RSA) for serious encryption needs; as a determined hacker might fi...
* Note that if symmetric cryptography is used, then it is highly recommended to also use the "password" feature on your servers and clients; since then the "password" will, aside from authentication, be also used in the "secret key" to encrypt the d...
If the above modules are installed but you want to forcefully disable compression or encryption, supply the "donotcompress" and/or "donotencrypt" keys to the new() constructor. If you would like to forcefully disable the use of only some modules, su...
=head1 RETURN VALUES AND ERRORS
The constructor and all methods return something that evaluates to true when successful, and to false when not successful.
=back
=head1 AUTHOR
Mina Naguib
http://www.topfx.com
mnaguib@cpan.org
=head1 SEE ALSO
Perl(1), L<IO::Socket>, L<IO::Select>, L<Compress::Zlib>, L<Compress::LZF>, L<Crypt::RSA>, L<Crypt::CBC>, L<Crypt::Rijndael>, L<Crypt::RC6>, L<Crypt::Blowfish>, L<Crypt::DES_EDE3>, L<Crypt::DES>, L<Crypt::Twofish2>, L<Crypt::Twofish>, L<Crypt::TEA>, ...
=head1 COPYRIGHT
Copyright (C) 2001-2003 Mina Naguib. All rights reserved. Use is subject to the Perl license.
=cut
#
# The main constructor. This calls either _new_client or _new_server depending on the supplied mode
#
Armour => 0,
)
or die "Failed to encrypt data with Crypt::RSA: " . $temp->errstr() . "\n";
};
}
elsif ($module eq 'Crypt::CipherSaber') {
$temp = Crypt::CipherSaber->new($publickey);
$newdata = $temp->encrypt($$rdata);
}
elsif ($cbc) {
$temp = Crypt::CBC->new($publickey, $module);
$newdata = $temp->encrypt($$rdata);
}
else {
$@ = "Unknown encryption module [$module] modulekey [$modulekey]";
}
#
# Finally, override reference if encryption succeeded
#
if ($newdata) {
Armour => 0,
)
or die "Failed to decrypt data with Crypt::RSA : " . $temp->errstr() . "\n";
};
}
elsif ($module eq 'Crypt::CipherSaber') {
$temp = Crypt::CipherSaber->new($privatekey);
$newdata = $temp->decrypt($$rdata);
}
elsif ($cbc) {
$temp = Crypt::CBC->new($privatekey, $module);
$newdata = $temp->decrypt($$rdata);
}
else {
$@ = "Unknown encryption module [$module] modulekey [$modulekey]";
}
#
# Finally, override reference if decryption succeeded
#
if ($newdata) {
( run in 0.859 second using v1.01-cache-2.11-cpan-e1769b4cff6 )