Merge branch 'errata-en-la-configuracion-del-satelite-en-windows' into 'develop'
Update Tentacle to the latest version. See merge request artica/pandorafms!1594
This commit is contained in:
commit
5723cfca15
|
@ -58,6 +58,8 @@ use strict;
|
|||
use File::Basename;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use Socket (qw(SOCK_STREAM AF_INET AF_INET6));
|
||||
my $SOCKET_MODULE =
|
||||
eval { require IO::Socket::INET6 } ? 'IO::Socket::INET6'
|
||||
|
@ -131,6 +133,12 @@ my $t_ssl_pwd = '';
|
|||
# Timeout for socket read/write operations in seconds
|
||||
my $t_timeout = 1;
|
||||
|
||||
# bind ipaddr
|
||||
my $t_bind_address = undef;
|
||||
|
||||
# Compress data before sending it through the socket.
|
||||
my $t_zip = 0;
|
||||
|
||||
################################################################################
|
||||
## SUB print_help
|
||||
## Print help screen.
|
||||
|
@ -141,6 +149,7 @@ sub print_help {
|
|||
print ("Tentacle client v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||
print ("Options:\n");
|
||||
print ("\t-a address\tServer address (default $t_address).\n");
|
||||
print ("\t-b localaddress\tLocal address to bind.\n");
|
||||
print ("\t-c\t\tEnable SSL without a client certificate.\n");
|
||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||
print ("\t-f ca\t\tVerify that the peer certificate is signed by a ca.\n");
|
||||
|
@ -154,7 +163,8 @@ sub print_help {
|
|||
print ("\t-v\t\tBe verbose.\n");
|
||||
print ("\t-w\t\tPrompt for OpenSSL private key password.\n");
|
||||
print ("\t-x pwd\t\tServer password.\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n");
|
||||
print ("\t-z Compress data.\n\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -166,7 +176,7 @@ sub parse_options {
|
|||
my $tmp;
|
||||
|
||||
# Get options
|
||||
if (getopts ('a:ce:f:ghk:p:qr:t:vwx:y:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
if (getopts ('a:b:ce:f:ghk:p:qr:t:vwx:y:z', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
print_help ();
|
||||
exit 1;
|
||||
}
|
||||
|
@ -183,6 +193,18 @@ sub parse_options {
|
|||
|
||||
}
|
||||
|
||||
# Bind local address
|
||||
if (defined ($opts{'b'})) {
|
||||
$t_bind_address = $opts{'b'};
|
||||
if (($t_bind_address !~ /^[a-zA-Z\.][a-zA-Z0-9\.\-]+$/ && ($t_bind_address !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) &&
|
||||
($t_address !~ /^[0-9a-f:]+$/o)) {
|
||||
error ("Local address $t_bind_address is not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Enable SSL without a client certificate
|
||||
if (defined ($opts{'c'})) {
|
||||
require IO::Socket::SSL;
|
||||
|
@ -299,6 +321,11 @@ sub parse_options {
|
|||
error ("Proxy port $t_proxy_port is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
# Compress data
|
||||
if (defined ($opts{'z'})) {
|
||||
$t_zip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -309,20 +336,42 @@ sub start_client {
|
|||
|
||||
# Connect to server
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -344,18 +393,38 @@ sub start_client_proxy {
|
|||
|
||||
# Connect to proxy
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -408,6 +477,8 @@ sub start_ssl {
|
|||
if ($t_ssl_cert eq ''){
|
||||
IO::Socket::SSL->start_SSL (
|
||||
$t_socket,
|
||||
# No authentication
|
||||
SSL_verify_mode => 0x00,
|
||||
);
|
||||
}
|
||||
elsif ($t_ssl_ca eq '') {
|
||||
|
@ -525,6 +596,46 @@ sub recv_file {
|
|||
print_log ("Received file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file from the server
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $data = '';
|
||||
my $file = $_[0];
|
||||
my $response;
|
||||
my $size;
|
||||
my $zdata = '';
|
||||
|
||||
# Request file
|
||||
send_data ("ZRECV <$file>\n");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response !~ /^ZRECV SIZE (\d+)$/) {
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
$size = $1;
|
||||
send_data ("ZRECV OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZRECV ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
print_log ("Received compressed file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the server
|
||||
|
@ -578,6 +689,55 @@ sub send_file {
|
|||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the server (compressed)
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name;
|
||||
my $data = '';
|
||||
my $response = '';
|
||||
my $retries;
|
||||
my $file = $_[0];
|
||||
my $size;
|
||||
my $written;
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
$base_name = basename ($file);
|
||||
|
||||
# Request to send file
|
||||
send_data ("ZSEND <$base_name> SIZE $size\n");
|
||||
print_log ("Request to send file '$base_name' size ${size}b (compressed)");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
|
||||
# Server rejected the file
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("Server responded SEND OK");
|
||||
send_data ($data);
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
@ -830,13 +990,21 @@ if ($t_recv == 0) {
|
|||
|
||||
# Send the files
|
||||
foreach $file (@ARGV) {
|
||||
send_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zsend_file($file);
|
||||
} else {
|
||||
send_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Send the files
|
||||
# Receive the files
|
||||
foreach $file (@ARGV) {
|
||||
recv_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zrecv_file ($file);
|
||||
} else {
|
||||
recv_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,6 +1050,8 @@ __END__
|
|||
|
||||
=item I<-x pwd> B<Server password>.
|
||||
|
||||
=item I<-z> Compress data.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
|
|
@ -60,6 +60,8 @@ use strict;
|
|||
use warnings;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use threads;
|
||||
use Thread::Semaphore;
|
||||
use POSIX ":sys_wait_h";
|
||||
|
@ -959,6 +961,15 @@ sub serve_connection {
|
|||
print_info ("Request to receive file '$1' from " . $t_client_socket->sockhost ());
|
||||
send_file ($1);
|
||||
}
|
||||
elsif ($command =~ /^ZSEND <(.*)> SIZE (\d+)$/) {
|
||||
print_info ("Request to send compressed file '$1' size ${2}b from " . $t_client_socket->sockhost ());
|
||||
zrecv_file ($1, $2);
|
||||
}
|
||||
# Client wants to receive a file
|
||||
elsif ($command =~ /^ZRECV <(.*)>$/) {
|
||||
print_info ("Request to receive compressed file '$1' from " . $t_client_socket->sockhost ());
|
||||
zsend_file ($1);
|
||||
}
|
||||
# Quit
|
||||
elsif ($command =~ /^QUIT$/) {
|
||||
print_info ("Connection closed from " . $t_client_socket->sockhost ());
|
||||
|
@ -1070,6 +1081,61 @@ sub recv_file {
|
|||
print_info ("Received file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file of size $_[1] and save it in $t_directory as $_[0].
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $size = $_[1];
|
||||
my $zdata = '';
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZSEND ERR (invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Check file size, empty files are not allowed
|
||||
if ($size < 1 || $size > $t_max_size) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " is too big");
|
||||
send_data ("ZSEND ERR (file is too big)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (-f $file && $t_overwrite == 0) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " already exists");
|
||||
send_data ("ZSEND ERR (file already exists)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZSEND ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
print_info ("Received compressed file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the client
|
||||
|
@ -1122,6 +1188,57 @@ sub send_file {
|
|||
print_log ("Requested file '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the client
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $response;
|
||||
my $size;
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("Requested compressed file '$base_name' from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZRECV ERR (file has an invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (! -f $file) {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " does not exist");
|
||||
send_data ("ZRECV ERR (file does not exist)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
send_data ("ZRECV SIZE $size\n");
|
||||
|
||||
# Wait for client response
|
||||
$response = recv_command ($t_block_size);
|
||||
if ($response ne "ZRECV OK") {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " not sent");
|
||||
return;
|
||||
}
|
||||
|
||||
# Send the file
|
||||
send_data ($data);
|
||||
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
|
|
@ -58,6 +58,8 @@ use strict;
|
|||
use File::Basename;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use Socket (qw(SOCK_STREAM AF_INET AF_INET6));
|
||||
my $SOCKET_MODULE =
|
||||
eval { require IO::Socket::INET6 } ? 'IO::Socket::INET6'
|
||||
|
@ -131,6 +133,12 @@ my $t_ssl_pwd = '';
|
|||
# Timeout for socket read/write operations in seconds
|
||||
my $t_timeout = 1;
|
||||
|
||||
# bind ipaddr
|
||||
my $t_bind_address = undef;
|
||||
|
||||
# Compress data before sending it through the socket.
|
||||
my $t_zip = 0;
|
||||
|
||||
################################################################################
|
||||
## SUB print_help
|
||||
## Print help screen.
|
||||
|
@ -141,6 +149,7 @@ sub print_help {
|
|||
print ("Tentacle client v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||
print ("Options:\n");
|
||||
print ("\t-a address\tServer address (default $t_address).\n");
|
||||
print ("\t-b localaddress\tLocal address to bind.\n");
|
||||
print ("\t-c\t\tEnable SSL without a client certificate.\n");
|
||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||
print ("\t-f ca\t\tVerify that the peer certificate is signed by a ca.\n");
|
||||
|
@ -154,7 +163,8 @@ sub print_help {
|
|||
print ("\t-v\t\tBe verbose.\n");
|
||||
print ("\t-w\t\tPrompt for OpenSSL private key password.\n");
|
||||
print ("\t-x pwd\t\tServer password.\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n");
|
||||
print ("\t-z Compress data.\n\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -166,7 +176,7 @@ sub parse_options {
|
|||
my $tmp;
|
||||
|
||||
# Get options
|
||||
if (getopts ('a:ce:f:ghk:p:qr:t:vwx:y:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
if (getopts ('a:b:ce:f:ghk:p:qr:t:vwx:y:z', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
print_help ();
|
||||
exit 1;
|
||||
}
|
||||
|
@ -183,6 +193,18 @@ sub parse_options {
|
|||
|
||||
}
|
||||
|
||||
# Bind local address
|
||||
if (defined ($opts{'b'})) {
|
||||
$t_bind_address = $opts{'b'};
|
||||
if (($t_bind_address !~ /^[a-zA-Z\.][a-zA-Z0-9\.\-]+$/ && ($t_bind_address !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) &&
|
||||
($t_address !~ /^[0-9a-f:]+$/o)) {
|
||||
error ("Local address $t_bind_address is not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Enable SSL without a client certificate
|
||||
if (defined ($opts{'c'})) {
|
||||
require IO::Socket::SSL;
|
||||
|
@ -299,6 +321,11 @@ sub parse_options {
|
|||
error ("Proxy port $t_proxy_port is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
# Compress data
|
||||
if (defined ($opts{'z'})) {
|
||||
$t_zip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -309,20 +336,42 @@ sub start_client {
|
|||
|
||||
# Connect to server
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -344,18 +393,38 @@ sub start_client_proxy {
|
|||
|
||||
# Connect to proxy
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -408,6 +477,8 @@ sub start_ssl {
|
|||
if ($t_ssl_cert eq ''){
|
||||
IO::Socket::SSL->start_SSL (
|
||||
$t_socket,
|
||||
# No authentication
|
||||
SSL_verify_mode => 0x00,
|
||||
);
|
||||
}
|
||||
elsif ($t_ssl_ca eq '') {
|
||||
|
@ -525,6 +596,46 @@ sub recv_file {
|
|||
print_log ("Received file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file from the server
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $data = '';
|
||||
my $file = $_[0];
|
||||
my $response;
|
||||
my $size;
|
||||
my $zdata = '';
|
||||
|
||||
# Request file
|
||||
send_data ("ZRECV <$file>\n");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response !~ /^ZRECV SIZE (\d+)$/) {
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
$size = $1;
|
||||
send_data ("ZRECV OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZRECV ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
print_log ("Received compressed file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the server
|
||||
|
@ -578,6 +689,55 @@ sub send_file {
|
|||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the server (compressed)
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name;
|
||||
my $data = '';
|
||||
my $response = '';
|
||||
my $retries;
|
||||
my $file = $_[0];
|
||||
my $size;
|
||||
my $written;
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
$base_name = basename ($file);
|
||||
|
||||
# Request to send file
|
||||
send_data ("ZSEND <$base_name> SIZE $size\n");
|
||||
print_log ("Request to send file '$base_name' size ${size}b (compressed)");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
|
||||
# Server rejected the file
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("Server responded SEND OK");
|
||||
send_data ($data);
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
@ -830,13 +990,21 @@ if ($t_recv == 0) {
|
|||
|
||||
# Send the files
|
||||
foreach $file (@ARGV) {
|
||||
send_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zsend_file($file);
|
||||
} else {
|
||||
send_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Send the files
|
||||
# Receive the files
|
||||
foreach $file (@ARGV) {
|
||||
recv_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zrecv_file ($file);
|
||||
} else {
|
||||
recv_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,6 +1050,8 @@ __END__
|
|||
|
||||
=item I<-x pwd> B<Server password>.
|
||||
|
||||
=item I<-z> Compress data.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
|
|
@ -58,6 +58,8 @@ use strict;
|
|||
use File::Basename;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use Socket (qw(SOCK_STREAM AF_INET AF_INET6));
|
||||
my $SOCKET_MODULE =
|
||||
eval { require IO::Socket::INET6 } ? 'IO::Socket::INET6'
|
||||
|
@ -131,6 +133,12 @@ my $t_ssl_pwd = '';
|
|||
# Timeout for socket read/write operations in seconds
|
||||
my $t_timeout = 1;
|
||||
|
||||
# bind ipaddr
|
||||
my $t_bind_address = undef;
|
||||
|
||||
# Compress data before sending it through the socket.
|
||||
my $t_zip = 0;
|
||||
|
||||
################################################################################
|
||||
## SUB print_help
|
||||
## Print help screen.
|
||||
|
@ -141,6 +149,7 @@ sub print_help {
|
|||
print ("Tentacle client v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||
print ("Options:\n");
|
||||
print ("\t-a address\tServer address (default $t_address).\n");
|
||||
print ("\t-b localaddress\tLocal address to bind.\n");
|
||||
print ("\t-c\t\tEnable SSL without a client certificate.\n");
|
||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||
print ("\t-f ca\t\tVerify that the peer certificate is signed by a ca.\n");
|
||||
|
@ -154,7 +163,8 @@ sub print_help {
|
|||
print ("\t-v\t\tBe verbose.\n");
|
||||
print ("\t-w\t\tPrompt for OpenSSL private key password.\n");
|
||||
print ("\t-x pwd\t\tServer password.\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n");
|
||||
print ("\t-z Compress data.\n\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -166,7 +176,7 @@ sub parse_options {
|
|||
my $tmp;
|
||||
|
||||
# Get options
|
||||
if (getopts ('a:ce:f:ghk:p:qr:t:vwx:y:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
if (getopts ('a:b:ce:f:ghk:p:qr:t:vwx:y:z', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
print_help ();
|
||||
exit 1;
|
||||
}
|
||||
|
@ -183,6 +193,18 @@ sub parse_options {
|
|||
|
||||
}
|
||||
|
||||
# Bind local address
|
||||
if (defined ($opts{'b'})) {
|
||||
$t_bind_address = $opts{'b'};
|
||||
if (($t_bind_address !~ /^[a-zA-Z\.][a-zA-Z0-9\.\-]+$/ && ($t_bind_address !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) &&
|
||||
($t_address !~ /^[0-9a-f:]+$/o)) {
|
||||
error ("Local address $t_bind_address is not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Enable SSL without a client certificate
|
||||
if (defined ($opts{'c'})) {
|
||||
require IO::Socket::SSL;
|
||||
|
@ -299,6 +321,11 @@ sub parse_options {
|
|||
error ("Proxy port $t_proxy_port is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
# Compress data
|
||||
if (defined ($opts{'z'})) {
|
||||
$t_zip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -309,20 +336,42 @@ sub start_client {
|
|||
|
||||
# Connect to server
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -344,18 +393,38 @@ sub start_client_proxy {
|
|||
|
||||
# Connect to proxy
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -408,6 +477,8 @@ sub start_ssl {
|
|||
if ($t_ssl_cert eq ''){
|
||||
IO::Socket::SSL->start_SSL (
|
||||
$t_socket,
|
||||
# No authentication
|
||||
SSL_verify_mode => 0x00,
|
||||
);
|
||||
}
|
||||
elsif ($t_ssl_ca eq '') {
|
||||
|
@ -525,6 +596,46 @@ sub recv_file {
|
|||
print_log ("Received file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file from the server
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $data = '';
|
||||
my $file = $_[0];
|
||||
my $response;
|
||||
my $size;
|
||||
my $zdata = '';
|
||||
|
||||
# Request file
|
||||
send_data ("ZRECV <$file>\n");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response !~ /^ZRECV SIZE (\d+)$/) {
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
$size = $1;
|
||||
send_data ("ZRECV OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZRECV ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
print_log ("Received compressed file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the server
|
||||
|
@ -578,6 +689,55 @@ sub send_file {
|
|||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the server (compressed)
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name;
|
||||
my $data = '';
|
||||
my $response = '';
|
||||
my $retries;
|
||||
my $file = $_[0];
|
||||
my $size;
|
||||
my $written;
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
$base_name = basename ($file);
|
||||
|
||||
# Request to send file
|
||||
send_data ("ZSEND <$base_name> SIZE $size\n");
|
||||
print_log ("Request to send file '$base_name' size ${size}b (compressed)");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
|
||||
# Server rejected the file
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("Server responded SEND OK");
|
||||
send_data ($data);
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
@ -830,13 +990,21 @@ if ($t_recv == 0) {
|
|||
|
||||
# Send the files
|
||||
foreach $file (@ARGV) {
|
||||
send_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zsend_file($file);
|
||||
} else {
|
||||
send_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Send the files
|
||||
# Receive the files
|
||||
foreach $file (@ARGV) {
|
||||
recv_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zrecv_file ($file);
|
||||
} else {
|
||||
recv_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,6 +1050,8 @@ __END__
|
|||
|
||||
=item I<-x pwd> B<Server password>.
|
||||
|
||||
=item I<-z> Compress data.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
|
|
@ -58,6 +58,8 @@ use strict;
|
|||
use File::Basename;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use Socket (qw(SOCK_STREAM AF_INET AF_INET6));
|
||||
my $SOCKET_MODULE =
|
||||
eval { require IO::Socket::INET6 } ? 'IO::Socket::INET6'
|
||||
|
@ -131,6 +133,12 @@ my $t_ssl_pwd = '';
|
|||
# Timeout for socket read/write operations in seconds
|
||||
my $t_timeout = 1;
|
||||
|
||||
# bind ipaddr
|
||||
my $t_bind_address = undef;
|
||||
|
||||
# Compress data before sending it through the socket.
|
||||
my $t_zip = 0;
|
||||
|
||||
################################################################################
|
||||
## SUB print_help
|
||||
## Print help screen.
|
||||
|
@ -141,6 +149,7 @@ sub print_help {
|
|||
print ("Tentacle client v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||
print ("Options:\n");
|
||||
print ("\t-a address\tServer address (default $t_address).\n");
|
||||
print ("\t-b localaddress\tLocal address to bind.\n");
|
||||
print ("\t-c\t\tEnable SSL without a client certificate.\n");
|
||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||
print ("\t-f ca\t\tVerify that the peer certificate is signed by a ca.\n");
|
||||
|
@ -154,7 +163,8 @@ sub print_help {
|
|||
print ("\t-v\t\tBe verbose.\n");
|
||||
print ("\t-w\t\tPrompt for OpenSSL private key password.\n");
|
||||
print ("\t-x pwd\t\tServer password.\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n\n");
|
||||
print ("\t-y proxy\tProxy server string (user:password\@address:port).\n");
|
||||
print ("\t-z Compress data.\n\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -166,7 +176,7 @@ sub parse_options {
|
|||
my $tmp;
|
||||
|
||||
# Get options
|
||||
if (getopts ('a:ce:f:ghk:p:qr:t:vwx:y:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
if (getopts ('a:b:ce:f:ghk:p:qr:t:vwx:y:z', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
print_help ();
|
||||
exit 1;
|
||||
}
|
||||
|
@ -183,6 +193,18 @@ sub parse_options {
|
|||
|
||||
}
|
||||
|
||||
# Bind local address
|
||||
if (defined ($opts{'b'})) {
|
||||
$t_bind_address = $opts{'b'};
|
||||
if (($t_bind_address !~ /^[a-zA-Z\.][a-zA-Z0-9\.\-]+$/ && ($t_bind_address !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) &&
|
||||
($t_address !~ /^[0-9a-f:]+$/o)) {
|
||||
error ("Local address $t_bind_address is not valid.");
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
# Enable SSL without a client certificate
|
||||
if (defined ($opts{'c'})) {
|
||||
require IO::Socket::SSL;
|
||||
|
@ -299,6 +321,11 @@ sub parse_options {
|
|||
error ("Proxy port $t_proxy_port is not valid.");
|
||||
}
|
||||
}
|
||||
|
||||
# Compress data
|
||||
if (defined ($opts{'z'})) {
|
||||
$t_zip = 1;
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -309,20 +336,42 @@ sub start_client {
|
|||
|
||||
# Connect to server
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_address,
|
||||
PeerPort => $t_port,
|
||||
Type => SOCK_STREAM
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -344,18 +393,38 @@ sub start_client_proxy {
|
|||
|
||||
# Connect to proxy
|
||||
if ($SOCKET_MODULE ne 'IO::Socket::INET') {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET6,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
if (! defined ($t_socket)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
if (defined ($t_bind_address)) {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
LocalAddr => $t_bind_address,
|
||||
);
|
||||
}
|
||||
else {
|
||||
$t_socket = $SOCKET_MODULE->new (
|
||||
Domain => AF_INET,
|
||||
PeerAddr => $t_proxy_address,
|
||||
PeerPort => $t_proxy_port,
|
||||
);
|
||||
}
|
||||
}
|
||||
|
||||
if (! defined ($t_socket)) {
|
||||
|
@ -408,6 +477,8 @@ sub start_ssl {
|
|||
if ($t_ssl_cert eq ''){
|
||||
IO::Socket::SSL->start_SSL (
|
||||
$t_socket,
|
||||
# No authentication
|
||||
SSL_verify_mode => 0x00,
|
||||
);
|
||||
}
|
||||
elsif ($t_ssl_ca eq '') {
|
||||
|
@ -525,6 +596,46 @@ sub recv_file {
|
|||
print_log ("Received file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file from the server
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $data = '';
|
||||
my $file = $_[0];
|
||||
my $response;
|
||||
my $size;
|
||||
my $zdata = '';
|
||||
|
||||
# Request file
|
||||
send_data ("ZRECV <$file>\n");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response !~ /^ZRECV SIZE (\d+)$/) {
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
$size = $1;
|
||||
send_data ("ZRECV OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZRECV ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
print_log ("Received compressed file '$file'");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the server
|
||||
|
@ -578,6 +689,55 @@ sub send_file {
|
|||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the server (compressed)
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name;
|
||||
my $data = '';
|
||||
my $response = '';
|
||||
my $retries;
|
||||
my $file = $_[0];
|
||||
my $size;
|
||||
my $written;
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
$base_name = basename ($file);
|
||||
|
||||
# Request to send file
|
||||
send_data ("ZSEND <$base_name> SIZE $size\n");
|
||||
print_log ("Request to send file '$base_name' size ${size}b (compressed)");
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
|
||||
# Server rejected the file
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("Server responded SEND OK");
|
||||
send_data ($data);
|
||||
|
||||
# Wait for server response
|
||||
$response = recv_command ();
|
||||
if ($response ne "ZSEND OK") {
|
||||
send_data ("QUIT\n");
|
||||
error ("Server responded $response.");
|
||||
}
|
||||
|
||||
print_log ("File sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
@ -830,13 +990,21 @@ if ($t_recv == 0) {
|
|||
|
||||
# Send the files
|
||||
foreach $file (@ARGV) {
|
||||
send_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zsend_file($file);
|
||||
} else {
|
||||
send_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
else {
|
||||
# Send the files
|
||||
# Receive the files
|
||||
foreach $file (@ARGV) {
|
||||
recv_file ($file);
|
||||
if ($t_zip == 1) {
|
||||
zrecv_file ($file);
|
||||
} else {
|
||||
recv_file ($file);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -882,6 +1050,8 @@ __END__
|
|||
|
||||
=item I<-x pwd> B<Server password>.
|
||||
|
||||
=item I<-z> Compress data.
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
|
|
@ -60,6 +60,8 @@ use strict;
|
|||
use warnings;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use threads;
|
||||
use Thread::Semaphore;
|
||||
use POSIX ":sys_wait_h";
|
||||
|
@ -959,6 +961,15 @@ sub serve_connection {
|
|||
print_info ("Request to receive file '$1' from " . $t_client_socket->sockhost ());
|
||||
send_file ($1);
|
||||
}
|
||||
elsif ($command =~ /^ZSEND <(.*)> SIZE (\d+)$/) {
|
||||
print_info ("Request to send compressed file '$1' size ${2}b from " . $t_client_socket->sockhost ());
|
||||
zrecv_file ($1, $2);
|
||||
}
|
||||
# Client wants to receive a file
|
||||
elsif ($command =~ /^ZRECV <(.*)>$/) {
|
||||
print_info ("Request to receive compressed file '$1' from " . $t_client_socket->sockhost ());
|
||||
zsend_file ($1);
|
||||
}
|
||||
# Quit
|
||||
elsif ($command =~ /^QUIT$/) {
|
||||
print_info ("Connection closed from " . $t_client_socket->sockhost ());
|
||||
|
@ -1070,6 +1081,61 @@ sub recv_file {
|
|||
print_info ("Received file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file of size $_[1] and save it in $t_directory as $_[0].
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $size = $_[1];
|
||||
my $zdata = '';
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZSEND ERR (invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Check file size, empty files are not allowed
|
||||
if ($size < 1 || $size > $t_max_size) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " is too big");
|
||||
send_data ("ZSEND ERR (file is too big)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (-f $file && $t_overwrite == 0) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " already exists");
|
||||
send_data ("ZSEND ERR (file already exists)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZSEND ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
print_info ("Received compressed file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the client
|
||||
|
@ -1122,6 +1188,57 @@ sub send_file {
|
|||
print_log ("Requested file '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the client
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $response;
|
||||
my $size;
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("Requested compressed file '$base_name' from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZRECV ERR (file has an invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (! -f $file) {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " does not exist");
|
||||
send_data ("ZRECV ERR (file does not exist)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
send_data ("ZRECV SIZE $size\n");
|
||||
|
||||
# Wait for client response
|
||||
$response = recv_command ($t_block_size);
|
||||
if ($response ne "ZRECV OK") {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " not sent");
|
||||
return;
|
||||
}
|
||||
|
||||
# Send the file
|
||||
send_data ($data);
|
||||
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
|
@ -60,6 +60,8 @@ use strict;
|
|||
use warnings;
|
||||
use Getopt::Std;
|
||||
use IO::Select;
|
||||
use IO::Compress::Zip qw(zip $ZipError);
|
||||
use IO::Uncompress::Unzip qw(unzip $UnzipError);
|
||||
use threads;
|
||||
use Thread::Semaphore;
|
||||
use POSIX ":sys_wait_h";
|
||||
|
@ -959,6 +961,15 @@ sub serve_connection {
|
|||
print_info ("Request to receive file '$1' from " . $t_client_socket->sockhost ());
|
||||
send_file ($1);
|
||||
}
|
||||
elsif ($command =~ /^ZSEND <(.*)> SIZE (\d+)$/) {
|
||||
print_info ("Request to send compressed file '$1' size ${2}b from " . $t_client_socket->sockhost ());
|
||||
zrecv_file ($1, $2);
|
||||
}
|
||||
# Client wants to receive a file
|
||||
elsif ($command =~ /^ZRECV <(.*)>$/) {
|
||||
print_info ("Request to receive compressed file '$1' from " . $t_client_socket->sockhost ());
|
||||
zsend_file ($1);
|
||||
}
|
||||
# Quit
|
||||
elsif ($command =~ /^QUIT$/) {
|
||||
print_info ("Connection closed from " . $t_client_socket->sockhost ());
|
||||
|
@ -1070,6 +1081,61 @@ sub recv_file {
|
|||
print_info ("Received file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zrecv_file
|
||||
## Receive a compressed file of size $_[1] and save it in $t_directory as $_[0].
|
||||
################################################################################
|
||||
sub zrecv_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $size = $_[1];
|
||||
my $zdata = '';
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZSEND ERR (invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Check file size, empty files are not allowed
|
||||
if ($size < 1 || $size > $t_max_size) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " is too big");
|
||||
send_data ("ZSEND ERR (file is too big)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (-f $file && $t_overwrite == 0) {
|
||||
print_log ("File '$base_name' size ${size}b from " . $t_client_socket->sockhost () . " already exists");
|
||||
send_data ("ZSEND ERR (file already exists)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
|
||||
# Receive file
|
||||
$zdata = recv_data_block ($size);
|
||||
if (!unzip(\$zdata => \$data)) {
|
||||
print_log ("Uncompress error: $UnzipError");
|
||||
send_data ("ZSEND ERR\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Write it to disk
|
||||
open (FILE, "> $file") || error ("Cannot open file '$file' for writing.");
|
||||
binmode (FILE);
|
||||
print (FILE $data);
|
||||
close (FILE);
|
||||
|
||||
send_data ("ZSEND OK\n");
|
||||
print_info ("Received compressed file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the client
|
||||
|
@ -1122,6 +1188,57 @@ sub send_file {
|
|||
print_log ("Requested file '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB zsend_file
|
||||
## Send a file to the client
|
||||
################################################################################
|
||||
sub zsend_file {
|
||||
my $base_name = $_[0];
|
||||
my $data = '';
|
||||
my $file;
|
||||
my $response;
|
||||
my $size;
|
||||
|
||||
# Check file name
|
||||
if ($base_name =~ /[$t_invalid_chars]/) {
|
||||
print_log ("Requested compressed file '$base_name' from " . $t_client_socket->sockhost () . " has an invalid file name");
|
||||
send_data ("ZRECV ERR (file has an invalid file name)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Apply filters
|
||||
$file = "$t_directory/" . apply_filters ($base_name) . $base_name;
|
||||
|
||||
# Check if file exists
|
||||
if (! -f $file) {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " does not exist");
|
||||
send_data ("ZRECV ERR (file does not exist)\n");
|
||||
return;
|
||||
}
|
||||
|
||||
# Read the file and compress its contents
|
||||
if (! zip($file => \$data)) {
|
||||
send_data ("QUIT\n");
|
||||
error ("Compression error: $ZipError");
|
||||
return;
|
||||
}
|
||||
|
||||
$size = length($data);
|
||||
send_data ("ZRECV SIZE $size\n");
|
||||
|
||||
# Wait for client response
|
||||
$response = recv_command ($t_block_size);
|
||||
if ($response ne "ZRECV OK") {
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " not sent");
|
||||
return;
|
||||
}
|
||||
|
||||
# Send the file
|
||||
send_data ($data);
|
||||
|
||||
print_log ("Requested compressed '$file' from " . $t_client_socket->sockhost () . " sent");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
# Common functions
|
||||
################################################################################
|
||||
|
|
Loading…
Reference in New Issue