mirror of
https://github.com/pandorafms/pandorafms.git
synced 2025-07-30 17:25:26 +02:00
2013-09-22 Junichi Satoh <junichi@rworks.jp>
* bin/tentacle_server: Upgraded to 0.4.0. (Imported from trunk of tentacled repository.) Added support for IPv6 and improved to be able to bind multiple interfaces and/or IP addresses. Added support for 'TCP Wrappers'. When the 'Authen::Libwrap' is installed and -T option is specified, this feature can be used. git-svn-id: https://svn.code.sf.net/p/pandora/code/trunk@8796 c3f86ba8-e40f-0410-aaad-9ba5e7f4b01f
This commit is contained in:
parent
50cad8805c
commit
b32278225c
@ -1,3 +1,12 @@
|
|||||||
|
2013-09-22 Junichi Satoh <junichi@rworks.jp>
|
||||||
|
|
||||||
|
* bin/tentacle_server: Upgraded to 0.4.0. (Imported from trunk of
|
||||||
|
tentacled repository.)
|
||||||
|
Added support for IPv6 and improved to be able to bind multiple
|
||||||
|
interfaces and/or IP addresses.
|
||||||
|
Added support for 'TCP Wrappers'. When the 'Authen::Libwrap' is
|
||||||
|
installed and -T option is specified, this feature can be used.
|
||||||
|
|
||||||
2013-09-13 Ramon Novoa <rnovoa@artica.es>
|
2013-09-13 Ramon Novoa <rnovoa@artica.es>
|
||||||
|
|
||||||
* lib/PandoraFMS/Core.pm: Validate existing events with the same 'ID extra' instead
|
* lib/PandoraFMS/Core.pm: Validate existing events with the same 'ID extra' instead
|
||||||
|
@ -30,7 +30,7 @@ tentacle_server - Tentacle Server
|
|||||||
|
|
||||||
=head1 VERSION
|
=head1 VERSION
|
||||||
|
|
||||||
Version 0.3.0
|
Version 0.4.0
|
||||||
|
|
||||||
=head1 USAGE
|
=head1 USAGE
|
||||||
|
|
||||||
@ -56,20 +56,36 @@ The client and server (B<TCP port 41121>) are designed to be run from the comman
|
|||||||
|
|
||||||
=cut
|
=cut
|
||||||
|
|
||||||
|
|
||||||
use strict;
|
use strict;
|
||||||
use warnings;
|
use warnings;
|
||||||
use Getopt::Std;
|
use Getopt::Std;
|
||||||
use IO::Select;
|
use IO::Select;
|
||||||
use IO::Socket::INET;
|
|
||||||
use Thread::Semaphore;
|
use Thread::Semaphore;
|
||||||
use POSIX ":sys_wait_h";
|
use POSIX ":sys_wait_h";
|
||||||
|
|
||||||
# Program version
|
my $t_libwrap_installed = eval { require Authen::Libwrap } ? 1 : 0;
|
||||||
our $VERSION = '0.3.0';
|
|
||||||
|
|
||||||
# Address to listen on
|
if ($t_libwrap_installed) {
|
||||||
my $t_address = '0.0.0.0';
|
Authen::Libwrap->import( qw( hosts_ctl STRING_UNKNOWN ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
# Log messages, 1 enabled, 0 disabled
|
||||||
|
my $t_log = 0;
|
||||||
|
|
||||||
|
my $SOCKET_MODULE =
|
||||||
|
eval { require IO::Socket::INET6 } ? 'IO::Socket::INET6'
|
||||||
|
: eval { require IO::Socket::INET } ? 'IO::Socket::INET'
|
||||||
|
: die $@;
|
||||||
|
|
||||||
|
if ($SOCKET_MODULE eq 'IO::Socket::INET') {
|
||||||
|
print_log ("IO::Socket::INET6 is not found. IPv6 is disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
|
# Program version
|
||||||
|
our $VERSION = '0.4.0';
|
||||||
|
|
||||||
|
# IPv4 address to listen on
|
||||||
|
my @t_addresses = ('0', '0.0.0.0');
|
||||||
|
|
||||||
# Block size for socket read/write operations in bytes
|
# Block size for socket read/write operations in bytes
|
||||||
my $t_block_size = 1024;
|
my $t_block_size = 1024;
|
||||||
@ -89,9 +105,6 @@ my @t_filters;
|
|||||||
# String containing quoted invalid file name characters
|
# String containing quoted invalid file name characters
|
||||||
my $t_invalid_chars = '\?\[\]\/\\\=\+\<\>\:\;\'\,\*\~';
|
my $t_invalid_chars = '\?\[\]\/\\\=\+\<\>\:\;\'\,\*\~';
|
||||||
|
|
||||||
# Log messages, 1 enabled, 0 disabled
|
|
||||||
my $t_log = 0;
|
|
||||||
|
|
||||||
# Maximum number of simultaneous connections
|
# Maximum number of simultaneous connections
|
||||||
my $t_max_conn = 10;
|
my $t_max_conn = 10;
|
||||||
|
|
||||||
@ -120,7 +133,8 @@ my $t_select;
|
|||||||
my $t_sem;
|
my $t_sem;
|
||||||
|
|
||||||
# Server socket
|
# Server socket
|
||||||
my $t_server_socket;
|
my @t_server_sockets;
|
||||||
|
my $select;
|
||||||
|
|
||||||
# Use SSL, 1 true, 0 false
|
# Use SSL, 1 true, 0 false
|
||||||
my $t_ssl = 0;
|
my $t_ssl = 0;
|
||||||
@ -152,16 +166,25 @@ my $t_proxy_socket;
|
|||||||
# Proxy selected handler
|
# Proxy selected handler
|
||||||
my $t_proxy_select;
|
my $t_proxy_select;
|
||||||
|
|
||||||
|
# Use libwrap, 1 true, 0 false
|
||||||
|
my $t_use_libwrap = 0;
|
||||||
|
|
||||||
|
# Program name for libwrap
|
||||||
|
my $t_program_name = $0;
|
||||||
|
$t_program_name =~ s/.*\///g;
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
## SUB print_help
|
## SUB print_help
|
||||||
## Print help screen.
|
## Print help screen.
|
||||||
################################################################################
|
################################################################################
|
||||||
sub print_help {
|
sub print_help {
|
||||||
|
$" = ',';
|
||||||
|
|
||||||
print ("Usage: $0 -s <storage directory> [options]\n\n");
|
print ("Usage: $0 -s <storage directory> [options]\n\n");
|
||||||
print ("Tentacle server v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
print ("Tentacle server v$VERSION. See http://www.openideas.info/wiki for protocol description.\n\n");
|
||||||
print ("Options:\n");
|
print ("Options:\n");
|
||||||
print ("\t-a ip_address\tAddress to listen on (default $t_address).\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-c number\tMaximum number of simultaneous connections (default $t_max_conn).\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-d\t\tRun as daemon.\n");
|
||||||
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
print ("\t-e cert\t\tOpenSSL certificate file. Enables SSL.\n");
|
||||||
@ -180,6 +203,8 @@ sub print_help {
|
|||||||
print ("\t-x pwd\t\tServer password.\n\n");
|
print ("\t-x pwd\t\tServer password.\n\n");
|
||||||
print ("\t-b proxy_ip_address\t\tProxied server address.\n\n");
|
print ("\t-b proxy_ip_address\t\tProxied server address.\n\n");
|
||||||
print ("\t-g proxy_port\t\tPort of proxied server.\n\n");
|
print ("\t-g proxy_port\t\tPort of proxied server.\n\n");
|
||||||
|
print ("\t-T\t\tEnable tcpwrappers support.\n");
|
||||||
|
print ("\t\t(To use this option, 'Authen::Libwrap' should be installed.)\n\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -243,20 +268,29 @@ sub daemonize {
|
|||||||
sub parse_options {
|
sub parse_options {
|
||||||
my %opts;
|
my %opts;
|
||||||
my $tmp;
|
my $tmp;
|
||||||
|
my @t_addresses_tmp;
|
||||||
|
|
||||||
# Get options
|
# Get options
|
||||||
if (getopts ('a:c:de:f:hi:k:m:op:qr:s:t:vwx:b:g:', \%opts) == 0 || defined ($opts{'h'})) {
|
if (getopts ('a:c:de:f:hi:k:m:op:qr:s:t:vwx:b:g:T', \%opts) == 0 || defined ($opts{'h'})) {
|
||||||
print_help ();
|
print_help ();
|
||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
# Address
|
# Address
|
||||||
if (defined ($opts{'a'})) {
|
if (defined ($opts{'a'})) {
|
||||||
$t_address = $opts{'a'};
|
@t_addresses = ();
|
||||||
if ($t_address !~ /^[a-zA-Z\.]+$/ && ($t_address !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
@t_addresses_tmp = split(/,/, $opts{'a'});
|
||||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
|
||||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) {
|
foreach my $t_address (@t_addresses_tmp) {
|
||||||
error ("Address $t_address is not valid.");
|
$t_address =~ s/^ *(.*?) *$/$1/;
|
||||||
|
if (($t_address ne '0') &&
|
||||||
|
($t_address !~ /^[a-zA-Z\.]+$/ && ($t_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 ("Address $t_address is not valid.");
|
||||||
|
}
|
||||||
|
push @t_addresses, $t_address;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -411,7 +445,8 @@ sub parse_options {
|
|||||||
$t_proxy_ip = $opts{'b'};
|
$t_proxy_ip = $opts{'b'};
|
||||||
if ($t_proxy_ip !~ /^[a-zA-Z\.]+$/ && ($t_proxy_ip !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
if ($t_proxy_ip !~ /^[a-zA-Z\.]+$/ && ($t_proxy_ip !~ /^(\d+)\.(\d+)\.(\d+)\.(\d+)$/
|
||||||
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
|| $1 < 0 || $1 > 255 || $2 < 0 || $2 > 255
|
||||||
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255)) {
|
|| $3 < 0 || $3 > 255 || $4 < 0 || $4 > 255) &&
|
||||||
|
$t_proxy_ip !~ /^[0-9a-f:]+$/o) {
|
||||||
error ("Proxy address $t_proxy_ip is not valid.");
|
error ("Proxy address $t_proxy_ip is not valid.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -423,6 +458,15 @@ sub parse_options {
|
|||||||
error ("Proxy port $t_port is not valid.");
|
error ("Proxy port $t_port is not valid.");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# TCP wrappers support
|
||||||
|
if (defined ($opts{'T'})) {
|
||||||
|
if ($t_libwrap_installed) {
|
||||||
|
$t_use_libwrap = 1;
|
||||||
|
} else {
|
||||||
|
error ("Authen::Libwrap is not installed.");
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -445,7 +489,7 @@ sub sigchld_handler {
|
|||||||
sub open_proxy {
|
sub open_proxy {
|
||||||
|
|
||||||
# Connect to server
|
# Connect to server
|
||||||
$t_proxy_socket = IO::Socket::INET->new (
|
$t_proxy_socket = $SOCKET_MODULE->new (
|
||||||
PeerAddr => $t_proxy_ip,
|
PeerAddr => $t_proxy_ip,
|
||||||
PeerPort => $t_proxy_port,
|
PeerPort => $t_proxy_port,
|
||||||
);
|
);
|
||||||
@ -466,25 +510,41 @@ sub open_proxy {
|
|||||||
################################################################################
|
################################################################################
|
||||||
sub start_server {
|
sub start_server {
|
||||||
|
|
||||||
$t_server_socket = IO::Socket::INET->new (
|
my $t_server_socket;
|
||||||
Listen => $t_max_conn,
|
|
||||||
LocalAddr => $t_address,
|
|
||||||
LocalPort => $t_port,
|
|
||||||
Proto => 'tcp',
|
|
||||||
ReuseAddr => 1,
|
|
||||||
);
|
|
||||||
|
|
||||||
if (! defined ($t_server_socket)) {
|
foreach my $t_address (@t_addresses) {
|
||||||
error ("Cannot open socket for address $t_address on port $t_port: $!.");
|
|
||||||
}
|
|
||||||
|
|
||||||
print_log ("Server listening on $t_address port $t_port (press <ctr-c> to stop)");
|
$t_server_socket = $SOCKET_MODULE->new (
|
||||||
|
Listen => $t_max_conn,
|
||||||
|
LocalAddr => $t_address,
|
||||||
|
LocalPort => $t_port,
|
||||||
|
Proto => 'tcp',
|
||||||
|
ReuseAddr => 1,
|
||||||
|
);
|
||||||
|
|
||||||
|
if (! defined ($t_server_socket)) {
|
||||||
|
print_log ("Cannot open socket for address $t_address on port $t_port: $!.");
|
||||||
|
next;
|
||||||
|
}
|
||||||
|
|
||||||
|
print_log ("Server listening on $t_address port $t_port (press <ctr-c> to stop)");
|
||||||
|
|
||||||
# Say message if tentacle proxy is enable
|
# Say message if tentacle proxy is enable
|
||||||
if (defined ($t_proxy_ip)) {
|
if (defined ($t_proxy_ip)) {
|
||||||
print_log ("Proxy Mode enable, data will be sent to $t_proxy_ip port $t_proxy_port");
|
print_log ("Proxy Mode enable, data will be sent to $t_proxy_ip port $t_proxy_port");
|
||||||
|
}
|
||||||
|
|
||||||
|
push @t_server_sockets, $t_server_socket;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (!@t_server_sockets) {
|
||||||
|
error ("Cannot open socket for all addresses on port $t_port: $!.");
|
||||||
|
}
|
||||||
|
|
||||||
|
$select = IO::Select->new();
|
||||||
|
foreach my $t_server_socket (@t_server_sockets){
|
||||||
|
$select->add($t_server_socket);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -551,8 +611,10 @@ sub close_proxy {
|
|||||||
## Close the server socket.
|
## Close the server socket.
|
||||||
################################################################################
|
################################################################################
|
||||||
sub stop_server {
|
sub stop_server {
|
||||||
|
|
||||||
$t_server_socket->close ();
|
foreach my $t_server_socket (@t_server_sockets) {
|
||||||
|
$t_server_socket->close ();
|
||||||
|
}
|
||||||
print_log ("Server going down");
|
print_log ("Server going down");
|
||||||
|
|
||||||
exit 0;
|
exit 0;
|
||||||
@ -603,8 +665,11 @@ sub start_ssl {
|
|||||||
################################################################################
|
################################################################################
|
||||||
sub accept_connection {
|
sub accept_connection {
|
||||||
my $pid;
|
my $pid;
|
||||||
|
my $t_server_socket;
|
||||||
|
|
||||||
while (1) {
|
my @ready = $select->can_read;
|
||||||
|
|
||||||
|
foreach $t_server_socket (@ready) {
|
||||||
|
|
||||||
# Accept connection
|
# Accept connection
|
||||||
$t_client_socket = $t_server_socket->accept ();
|
$t_client_socket = $t_server_socket->accept ();
|
||||||
@ -619,55 +684,63 @@ sub accept_connection {
|
|||||||
error ("accept: $!.");
|
error ("accept: $!.");
|
||||||
}
|
}
|
||||||
|
|
||||||
last;
|
print_log ("Client connected from " . $t_client_socket->sockhost ());
|
||||||
}
|
|
||||||
|
|
||||||
print_log ("Client connected from " . $t_client_socket->sockhost ());
|
# Fork and serve the client
|
||||||
|
$pid = fork ();
|
||||||
# Fork and serve the client
|
if (! defined ($pid)) {
|
||||||
$pid = fork ();
|
error ("Cannot fork: $!.");
|
||||||
if (! defined ($pid)) {
|
}
|
||||||
error ("Cannot fork: $!.");
|
|
||||||
}
|
|
||||||
|
|
||||||
# Child
|
# Child
|
||||||
if ($pid == 0) {
|
if ($pid == 0) {
|
||||||
|
|
||||||
# We do not need the server socket
|
# We do not need the server socket
|
||||||
$t_server_socket->close ();
|
$t_server_socket->close ();
|
||||||
|
|
||||||
|
if ($t_use_libwrap) {
|
||||||
|
if (! hosts_ctl($t_program_name, $t_client_socket)) {
|
||||||
|
print_log ("Connection from " . $t_client_socket->sockhost() . " is closed by tcpwrappers.");
|
||||||
|
$t_client_socket->close ();
|
||||||
|
|
||||||
|
exit;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
# Add client socket to select queue
|
# Add client socket to select queue
|
||||||
$t_select = IO::Select->new ();
|
$t_select = IO::Select->new ();
|
||||||
$t_select->add ($t_client_socket);
|
$t_select->add ($t_client_socket);
|
||||||
|
|
||||||
# Start SSL
|
# Start SSL
|
||||||
if ($t_ssl == 1) {
|
if ($t_ssl == 1) {
|
||||||
start_ssl ();
|
start_ssl ();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Authenticate client
|
# Authenticate client
|
||||||
if ($t_pwd ne '') {
|
if ($t_pwd ne '') {
|
||||||
auth_pwd ();
|
auth_pwd ();
|
||||||
}
|
}
|
||||||
|
|
||||||
# Check if proxy mode is enable
|
# Check if proxy mode is enable
|
||||||
if (defined ($t_proxy_ip)) {
|
if (defined ($t_proxy_ip)) {
|
||||||
|
|
||||||
serve_proxy_connection ();
|
serve_proxy_connection ();
|
||||||
|
|
||||||
} else {
|
} else {
|
||||||
|
|
||||||
serve_connection ();
|
serve_connection ();
|
||||||
|
}
|
||||||
|
|
||||||
|
$t_client_socket->close ();
|
||||||
|
|
||||||
|
# Must exit now
|
||||||
|
exit;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Parent
|
||||||
$t_client_socket->close ();
|
$t_client_socket->close ();
|
||||||
|
|
||||||
# Must exit now
|
|
||||||
exit;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
# Parent
|
|
||||||
$t_client_socket->close ();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
################################################################################
|
################################################################################
|
||||||
@ -1359,6 +1432,11 @@ if ($#ARGV != -1) {
|
|||||||
exit 1;
|
exit 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
# Show IPv6 status
|
||||||
|
if ($SOCKET_MODULE eq 'IO::Socket::INET') {
|
||||||
|
print_log ("IO::Socket::INET6 is not found. IPv6 is disabled.");
|
||||||
|
}
|
||||||
|
|
||||||
# Run as daemon?
|
# Run as daemon?
|
||||||
if ($t_daemon == 1 && $^O ne 'MSWin32') {
|
if ($t_daemon == 1 && $^O ne 'MSWin32') {
|
||||||
daemonize ();
|
daemonize ();
|
||||||
|
Loading…
x
Reference in New Issue
Block a user