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:
vgilc 2018-07-04 16:31:59 +02:00
commit 5723cfca15
9 changed files with 4850 additions and 180 deletions

View File

@ -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

View File

@ -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
################################################################################

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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

View File

@ -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
################################################################################