Updated tentacle_server as the same as under pandora_server directory.
This commit is contained in:
parent
594870f0e9
commit
5f1041cfc3
|
@ -30,7 +30,7 @@ tentacle_server - Tentacle Server
|
|||
|
||||
=head1 VERSION
|
||||
|
||||
Version 0.4.0
|
||||
Version 0.5.0
|
||||
|
||||
=head1 USAGE
|
||||
|
||||
|
@ -86,8 +86,11 @@ my $SOCKET_MODULE =
|
|||
# Service name for Win32.
|
||||
my $SERVICE_NAME="Tentacle Server";
|
||||
|
||||
# Service parameters.
|
||||
my $SERVICE_PARAMS=join(' ', @ARGV);
|
||||
|
||||
# Program version
|
||||
our $VERSION = '0.4.0';
|
||||
our $VERSION = '0.5.0';
|
||||
|
||||
# IPv4 address to listen on
|
||||
my @t_addresses = ('0', '0.0.0.0');
|
||||
|
@ -139,7 +142,9 @@ my $t_sem :shared;
|
|||
|
||||
# Server socket
|
||||
my @t_server_sockets;
|
||||
my $select;
|
||||
|
||||
# Server select handler
|
||||
my $t_server_select;
|
||||
|
||||
# Use SSL, 1 true, 0 false
|
||||
my $t_ssl = 0;
|
||||
|
@ -159,10 +164,10 @@ my $t_ssl_pwd = '';
|
|||
# Timeout for socket read/write operations in seconds
|
||||
my $t_timeout = 1;
|
||||
|
||||
#Bridge IP to actuate as a proxy
|
||||
# Address to proxy client requests to
|
||||
my $t_proxy_ip = undef;
|
||||
|
||||
# Proxy port by default 41121
|
||||
# Port to proxy client requests to
|
||||
my $t_proxy_port = 41121;
|
||||
|
||||
# Proxy socket
|
||||
|
@ -171,9 +176,6 @@ my $t_proxy_socket;
|
|||
# Proxy selected handler
|
||||
my $t_proxy_select;
|
||||
|
||||
# Use SSL for proxy, 1 true, 0 false
|
||||
my $t_proxy_ssl = 0;
|
||||
|
||||
# Use libwrap, 1 true, 0 false
|
||||
my $t_use_libwrap = 0;
|
||||
|
||||
|
@ -192,7 +194,7 @@ sub print_help {
|
|||
print ("Tentacle server v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||
print ("Options:\n");
|
||||
print ("\t-a ip_addresses\tIP addresses to listen on (default @t_addresses).\n");
|
||||
print ("\t\t(Multiple addresses separated by comma can be defined.)\n");
|
||||
print ("\t \t(Multiple addresses separated by comma can be defined.)\n");
|
||||
print ("\t-c number\tMaximum number of simultaneous connections (default $t_max_conn).\n");
|
||||
print ("\t-d\t\tRun as daemon.\n");
|
||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||
|
@ -210,11 +212,10 @@ 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-b proxy_ip_address\tProxied server address.\n");
|
||||
print ("\t-g proxy_port\t\tPort of proxied server.\n");
|
||||
print ("\t-C\t\tEnable SSL for proxy connection without a client certificate.\n");
|
||||
print ("\t-b ip_address\tProxy requests to the given address.\n");
|
||||
print ("\t-g port\t\tProxy requests to the given port.\n");
|
||||
print ("\t-T\t\tEnable tcpwrappers support.\n");
|
||||
print ("\t\t\t(To use this option, 'Authen::Libwrap' should be installed.)\n\n");
|
||||
print ("\t \t\t(To use this option, 'Authen::Libwrap' should be installed.)\n\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -260,11 +261,28 @@ sub parse_options {
|
|||
my @t_addresses_tmp;
|
||||
|
||||
# Get options
|
||||
if (getopts ('a:b:c:Cde:f:g:hi:k:m:op:qr:s:S:t:Tvwx:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
if (getopts ('a:b:c:de:f:g:hi:k:m:op:qr:s:S:t:Tvwx:', \%opts) == 0 || defined ($opts{'h'})) {
|
||||
print_help ();
|
||||
exit 1;
|
||||
}
|
||||
|
||||
# The Win32 service must be installed/uninstalled without checking other parameters.
|
||||
if (defined ($opts{'S'})) {
|
||||
my $service_action = $opts{'S'};
|
||||
if ($^O ne 'MSWin32') {
|
||||
error ("Windows services are only available on Win32.");
|
||||
} else {
|
||||
eval "use Win32::Daemon";
|
||||
die($@) if ($@);
|
||||
|
||||
if ($service_action eq 'install') {
|
||||
install_service();
|
||||
} elsif ($service_action eq 'uninstall') {
|
||||
uninstall_service();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
# Address
|
||||
if (defined ($opts{'a'})) {
|
||||
@t_addresses = ();
|
||||
|
@ -448,15 +466,6 @@ sub parse_options {
|
|||
}
|
||||
}
|
||||
|
||||
# Enable SSL without a client certificate
|
||||
if (defined ($opts{'C'})) {
|
||||
|
||||
require IO::Socket::SSL;
|
||||
|
||||
$t_proxy_ssl = 1;
|
||||
}
|
||||
|
||||
|
||||
# TCP wrappers support
|
||||
if (defined ($opts{'T'})) {
|
||||
if ($t_libwrap_installed) {
|
||||
|
@ -475,11 +484,7 @@ sub parse_options {
|
|||
eval "use Win32::Daemon";
|
||||
die($@) if ($@);
|
||||
|
||||
if ($service_action eq 'install') {
|
||||
install_service();
|
||||
} elsif ($service_action eq 'uninstall') {
|
||||
uninstall_service();
|
||||
} elsif ($service_action eq 'run') {
|
||||
if ($service_action eq 'run') {
|
||||
Win32::Daemon::RegisterCallbacks({
|
||||
start => \&callback_start,
|
||||
running => \&callback_running,
|
||||
|
@ -496,9 +501,9 @@ sub parse_options {
|
|||
|
||||
################################################################################
|
||||
## SUB start_proxy
|
||||
## Open the server socket.
|
||||
## Open the proxy server socket.
|
||||
################################################################################
|
||||
sub open_proxy {
|
||||
sub start_proxy {
|
||||
|
||||
# Connect to server
|
||||
$t_proxy_socket = $SOCKET_MODULE->new (
|
||||
|
@ -511,8 +516,8 @@ sub open_proxy {
|
|||
}
|
||||
|
||||
# Create proxy selector
|
||||
$t_proxy_select = IO::Select->new ();
|
||||
$t_proxy_select->add ($t_proxy_socket);
|
||||
$t_proxy_select = IO::Select->new ();
|
||||
$t_proxy_select->add ($t_proxy_socket);
|
||||
|
||||
}
|
||||
|
||||
|
@ -551,11 +556,11 @@ sub start_server {
|
|||
|
||||
if (!@t_server_sockets) {
|
||||
error ("Cannot open socket for all addresses on port $t_port: $!.");
|
||||
}
|
||||
}
|
||||
|
||||
$select = IO::Select->new();
|
||||
$t_server_select = IO::Select->new();
|
||||
foreach my $t_server_socket (@t_server_sockets){
|
||||
$select->add($t_server_socket);
|
||||
$t_server_select->add($t_server_socket);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -613,9 +618,8 @@ sub send_data_proxy {
|
|||
## Close the proxy socket.
|
||||
################################################################################
|
||||
sub close_proxy {
|
||||
$t_proxy_socket->shutdown (2);
|
||||
$t_proxy_socket->close ();
|
||||
print_log ("Proxy socket closed");
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
|
@ -625,6 +629,7 @@ sub close_proxy {
|
|||
sub stop_server {
|
||||
|
||||
foreach my $t_server_socket (@t_server_sockets) {
|
||||
$t_server_socket->shutdown (2);
|
||||
$t_server_socket->close ();
|
||||
}
|
||||
print_log ("Server going down");
|
||||
|
@ -671,30 +676,6 @@ sub start_ssl {
|
|||
print_log ("SSL started for " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB start_proxy_ssl
|
||||
## Convert the proxy socket to an IO::Socket::SSL socket.
|
||||
################################################################################
|
||||
sub start_proxy_ssl {
|
||||
my $err;
|
||||
|
||||
if ($t_proxy_ssl != 1) {
|
||||
return;
|
||||
}
|
||||
|
||||
IO::Socket::SSL->start_SSL (
|
||||
$t_proxy_socket,
|
||||
SSL_verify_mode => 0x00,
|
||||
);
|
||||
|
||||
$err = IO::Socket::SSL::errstr ();
|
||||
if ($err ne '') {
|
||||
error ($err);
|
||||
}
|
||||
|
||||
print_log ("proxy SSL started for " . $t_proxy_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB accept_connections
|
||||
## Manage incoming connections.
|
||||
|
@ -703,6 +684,9 @@ sub accept_connections {
|
|||
my $pid;
|
||||
my $t_server_socket;
|
||||
|
||||
# Ignore SIGPIPE errors (happens on FreeBSD when SSL is enabled ¿?)
|
||||
$SIG{PIPE} = 'IGNORE';
|
||||
|
||||
# Start server
|
||||
start_server ();
|
||||
|
||||
|
@ -710,7 +694,7 @@ sub accept_connections {
|
|||
$t_sem = Thread::Semaphore->new ($t_max_conn);
|
||||
|
||||
while (1) {
|
||||
my @ready = $select->can_read;
|
||||
my @ready = $t_server_select->can_read;
|
||||
foreach $t_server_socket (@ready) {
|
||||
|
||||
# Accept connection
|
||||
|
@ -725,6 +709,7 @@ sub accept_connections {
|
|||
|
||||
if ($t_use_libwrap && (! hosts_ctl($t_program_name, $t_client_socket))) {
|
||||
print_log ("Connection from " . $t_client_socket->peerhost() . " is closed by tcpwrappers.");
|
||||
$t_client_socket->shutdown (2);
|
||||
$t_client_socket->close();
|
||||
}
|
||||
else {
|
||||
|
@ -773,6 +758,8 @@ sub serve_client() {
|
|||
}
|
||||
};
|
||||
|
||||
$t_client_socket->shutdown (2);
|
||||
$t_client_socket->close ();
|
||||
$t_sem->up();
|
||||
}
|
||||
|
||||
|
@ -781,45 +768,25 @@ sub serve_client() {
|
|||
## Actuate as a proxy between its client and other tentacle server.
|
||||
################################################################################
|
||||
sub serve_proxy_connection {
|
||||
my $read;
|
||||
my $data=1;
|
||||
|
||||
# Start a connection with the other Tentacle Server
|
||||
open_proxy();
|
||||
# We are a proxy! Start a connection to the Tentacle Server.
|
||||
start_proxy();
|
||||
|
||||
# Start SSL for proxy
|
||||
if ($t_proxy_ssl == 1) {
|
||||
start_proxy_ssl();
|
||||
}
|
||||
|
||||
my $command;
|
||||
|
||||
# Read commands
|
||||
while ($command = recv_command ($t_block_size)) {
|
||||
# Client wants to send a file
|
||||
if ($command =~ /^SEND <(.*)> SIZE (\d+)$/) {
|
||||
recv_file_proxy($command, $2);
|
||||
# Forward data between the client and the server.
|
||||
eval {
|
||||
while (1) {
|
||||
if ($t_select->can_read(0)) {
|
||||
my ($read, $data) = recv_data($t_block_size);
|
||||
send_data_proxy($data);
|
||||
}
|
||||
if ($t_proxy_select->can_read(0)) {
|
||||
my ($read, $data) = recv_data_proxy($t_block_size);
|
||||
send_data($data);
|
||||
}
|
||||
}
|
||||
# Client wants to receive a file
|
||||
elsif ($command =~ /^RECV <(.*)>$/) {
|
||||
send_file_proxy ($command);
|
||||
}
|
||||
# Quit
|
||||
elsif ($command =~ /^QUIT$/) {
|
||||
print_log ("Connection closed from " . $t_client_socket->sockhost ());
|
||||
|
||||
# End proxy connection
|
||||
send_data_proxy("QUIT\n");
|
||||
last;
|
||||
}
|
||||
# Unknown command
|
||||
else {
|
||||
print_log ("Unknown command '$command' from " . $t_client_socket->sockhost ());
|
||||
last;
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
# End a connection with the other Tentacle Server
|
||||
# Close the connection to the Tentacle Server.
|
||||
close_proxy();
|
||||
}
|
||||
|
||||
|
@ -885,43 +852,6 @@ sub auth_pwd {
|
|||
send_data ("PASS OK\n");
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB recv_file_proxy
|
||||
## Redirect file from agent to proxy
|
||||
################################################################################
|
||||
sub recv_file_proxy ($$) {
|
||||
my ($command, $size) = @_;
|
||||
|
||||
# Send command to proxy
|
||||
print_log ("[PROXY] Host: ".$t_client_socket->sockhost()." send ".$command." to ".$t_proxy_socket->sockhost ());
|
||||
send_data_proxy($command."\n");
|
||||
|
||||
# Proxied server response
|
||||
my $rc = dump_data($t_proxy_socket, $t_client_socket);
|
||||
|
||||
# Check if there was an error
|
||||
if ($rc == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Client send data to server
|
||||
$rc = dump_data($t_client_socket, $t_proxy_socket, $size);
|
||||
|
||||
# Check if there was an error
|
||||
if ($rc == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Server says if data was recieved or not
|
||||
$rc = dump_data($t_proxy_socket, $t_client_socket);
|
||||
|
||||
# Check if there was an error
|
||||
if ($rc == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB recv_file
|
||||
## Receive a file of size $_[1] and save it in $t_directory as $_[0].
|
||||
|
@ -971,45 +901,6 @@ sub recv_file {
|
|||
print_log ("Received file '$base_name' size ${size}b from " . $t_client_socket->sockhost ());
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file_proxy
|
||||
## Redirect file from agent to proxy
|
||||
################################################################################
|
||||
sub send_file_proxy ($) {
|
||||
my ($command) = @_;
|
||||
my $size;
|
||||
# Send command to proxy
|
||||
print_log ("[PROXY] ".$t_client_socket->sockhost()." send ".$command." to ".$t_proxy_socket->sockhost ());
|
||||
send_data_proxy($command."\n");
|
||||
|
||||
$command = recv_command_proxy($t_block_size);
|
||||
|
||||
if ($command =~ /^RECV SIZE (\d+)$/) {
|
||||
$size = $1;
|
||||
}
|
||||
|
||||
print_log ("[PROXY] ".$t_proxy_socket->sockhost()." send ".$command." to ".$t_client_socket->sockhost ());
|
||||
|
||||
send_data($command."\n");
|
||||
|
||||
# Client send OK to server
|
||||
my $rc = dump_data($t_client_socket, $t_proxy_socket);
|
||||
|
||||
# Check if there was an error
|
||||
if ($rc == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
# Proxied server send the file to client
|
||||
$rc = dump_data($t_proxy_socket, $t_client_socket, $size);
|
||||
|
||||
# Check if there was an error
|
||||
if ($rc == -1) {
|
||||
return;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB send_file
|
||||
## Send a file to the client
|
||||
|
@ -1218,127 +1109,6 @@ sub send_data {
|
|||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB dump_data
|
||||
## Dump data from a socket to another one. Following Tentacle Protocol.
|
||||
################################################################################
|
||||
sub dump_data($$;$) {
|
||||
my ($from, $to, $size) = @_;
|
||||
my $read;
|
||||
my $data;
|
||||
my $buffer = "";
|
||||
my $written;
|
||||
my $total = $size;
|
||||
my $t_select_read = undef;
|
||||
my $t_select_write = undef;
|
||||
|
||||
# Assign the correct selector for each socket
|
||||
if ($from == $t_proxy_socket) {
|
||||
# We must read from t_proxy_socket
|
||||
$t_select_read = $t_proxy_select;
|
||||
$t_select_write = $t_select;
|
||||
} else {
|
||||
# We must read from t_client_socket
|
||||
$t_select_read = $t_select;
|
||||
$t_select_write = $t_proxy_select;
|
||||
}
|
||||
|
||||
while (1) {
|
||||
|
||||
# Ensure we can read from socket
|
||||
if ($t_select_read->can_read()) {
|
||||
# Ensure we can write from socket
|
||||
if ($t_select_write->can_write()) {
|
||||
|
||||
$read = "";
|
||||
$read = sysread ($from, $data, $t_block_size);
|
||||
|
||||
# Read error
|
||||
if (! defined ($read)) {
|
||||
error ("Read error from " . $from->sockhost () . ": $!.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
# EOF
|
||||
if ($read == 0) {
|
||||
error ("Connection from " . $from->sockhost () . " unexpectedly closed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
$written = syswrite ($to, $data, $read);
|
||||
|
||||
if ($written != $read) {
|
||||
error ("Connection from " . $to->sockhost () . " unexpectedly closed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
$buffer .= $data;
|
||||
|
||||
if (! defined ($size)) {
|
||||
# If no size defined check for \n
|
||||
# because a command was sent.
|
||||
|
||||
if ($buffer =~ /\n$/) {
|
||||
|
||||
# Delete CHAR \n
|
||||
chop($buffer);
|
||||
|
||||
print_log ("[PROXY] ".$from->sockhost()." send ".$buffer." to ".$to->sockhost ());
|
||||
|
||||
# Returns error if proxy returns error to end connection
|
||||
if ($buffer =~ /SEND ERR/) {
|
||||
return -1;
|
||||
} else {
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
} else {
|
||||
# If size is defined check if all bytes were sent
|
||||
$size = $size - $read;
|
||||
|
||||
if ($size == 0) {
|
||||
print_log ("[PROXY] ".$from->sockhost()." send ".$total."b to ".$to->sockhost());
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB recv_command_proxy
|
||||
## Read a command from the proxied server, ended by a new line character.
|
||||
################################################################################
|
||||
sub recv_command_proxy {
|
||||
my $buffer;
|
||||
my $char;
|
||||
my $command = '';
|
||||
my $read;
|
||||
my $total = 0;
|
||||
|
||||
while (1) {
|
||||
|
||||
($read, $buffer) = recv_data_proxy ($t_block_size);
|
||||
$command .= $buffer;
|
||||
$total += $read;
|
||||
|
||||
# Check if the command is complete
|
||||
$char = chop ($command);
|
||||
if ($char eq "\n") {
|
||||
return $command;
|
||||
}
|
||||
|
||||
$command .= $char;
|
||||
|
||||
# Avoid overflow
|
||||
if ($total > $t_block_size) {
|
||||
error ("Received too much data from " . $t_proxy_socket->sockhost () . ".");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
################################################################################
|
||||
## SUB recv_command
|
||||
## Read a command from the client, ended by a new line character.
|
||||
|
@ -1456,7 +1226,10 @@ sub apply_filters ($) {
|
|||
sub install_service() {
|
||||
|
||||
my $service_path = $0;
|
||||
my $service_params = "-s \"$t_directory\" -S run";
|
||||
my $service_params = $SERVICE_PARAMS;
|
||||
|
||||
# Change the service parameter from 'install' to 'run'.
|
||||
$service_params =~ s/\-S\s+\S+/\-S run/;
|
||||
|
||||
my %service_hash = (
|
||||
machine => '',
|
||||
|
@ -1527,6 +1300,7 @@ sub callback_start {
|
|||
sub callback_stop {
|
||||
|
||||
foreach my $t_server_socket (@t_server_sockets) {
|
||||
$t_server_socket->shutdown (2);
|
||||
$t_server_socket->close ();
|
||||
}
|
||||
|
||||
|
@ -1624,14 +1398,6 @@ __END__
|
|||
|
||||
=item I<-x> pwd B<Server password>.
|
||||
|
||||
=item I<-b proxy_ip_address> B<Proxied server> address.
|
||||
|
||||
=item I<-g proxy_port> B<Port> of proxied server.
|
||||
|
||||
=item I<-C> Enable SSL for proxy without a client certificate.
|
||||
|
||||
=item I<-T> Enable tcpwrappers support ('Authen::Libwrap' required).
|
||||
|
||||
=back
|
||||
|
||||
=head1 EXIT STATUS
|
||||
|
|
Loading…
Reference in New Issue