X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-bus;h=3ab5e917a1853770a0c184e371614e855913b67d;hb=d5f30695ab99e6c016b0a9a1cc7224869acadeb7;hp=c37d14b7eb0dbde7c0e699c85f3cfc8dac1d212e;hpb=706eb68e0982d0805024d220893bba575ddadd59;p=gosa.git diff --git a/gosa-si/gosa-si-bus b/gosa-si/gosa-si-bus index c37d14b7e..3ab5e917a 100755 --- a/gosa-si/gosa-si-bus +++ b/gosa-si/gosa-si-bus @@ -28,33 +28,36 @@ use Time::HiRes qw( gettimeofday ); use POE qw(Component::Server::TCP); use Data::Dumper; use Crypt::Rijndael; -use GOSA::DBsqlite; -use GOSA::GosaSupportDaemon; use IO::Socket::INET; use NetAddr::IP; use XML::Simple; use MIME::Base64; +use File::Basename; use Digest::MD5 qw(md5 md5_hex md5_base64); +use utf8; +use GOSA::GosaSupportDaemon; +use GOSA::DBsqlite; my ($cfg_file, $default_cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file,); my ($bus_address, $bus_key, $bus_ip, $bus_port, $bus_mac_address); my ($bus_known_server_db, $bus_known_server_file_name, $bus_known_clients_db, $bus_known_clients_file_name); my $xml; +our $prg= basename($0); $foreground = 0 ; %cfg_defaults = ( "general" => { - "log_file" => [\$log_file, "/var/run/".$0.".log"], - "pid_file" => [\$pid_file, "/var/run/".$0.".pid"], - "bus_known_server_file_name" => [\$bus_known_server_file_name, "/var/lib/gosa-si/gosa-si-bus_known_server.db"], - "bus_known_clients_file_name" => [\$bus_known_clients_file_name, "/var/lib/gosa-si/gosa-si-bus_known_clients.db"], + "log_file" => [\$log_file, "/var/run/".$prg.".log"], + "pid_file" => [\$pid_file, "/var/run/".$prg.".pid"], }, -"GOsa-si-bus" => { +"bus" => { "key" => [\$bus_key, "secret-bus-password"], "ip" => [\$bus_ip, "0.0.0.0"], "port" => [\$bus_port, "20080"], - }, + "known-servers" => [\$bus_known_server_file_name, "/var/lib/gosa-si/bus-servers.db"], + "known-clients" => [\$bus_known_clients_file_name, "/var/lib/gosa-si/bus-clients.db"], + }, ); #=== FUNCTIONS = functions ===================================================== @@ -173,7 +176,7 @@ sub check_pid { #=============================================================================== sub usage { print STDERR << "EOF" ; -usage: $0 [-hvf] [-c config] +usage: $prg [-hvf] [-c config] -h : this (help) message -c : config file @@ -213,10 +216,8 @@ sub daemon_log { $month = $monthnames[$month]; $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; $year+=1900; - my $name = $0; - $name =~ s/\.\///; - my $log_msg = "$month $monthday $hours:$minutes:$seconds $name $msg\n"; + my $log_msg = "$month $monthday $hours:$minutes:$seconds $prg $msg\n"; print LOG_HANDLE $log_msg; if( $foreground ) { print STDERR $log_msg; @@ -406,6 +407,50 @@ sub get_local_mac_for_remote_ip { return $result; } +sub bus_matches { + my $target = shift; + my $target_ip = sprintf("%s", $target =~ /^([0-9\.]*?):.*$/); + my $result = 0; + + if($bus_ip eq $target_ip) { + $result= 1; + } elsif ($bus_ip eq "0.0.0.0") { + if ($target_ip eq "127.0.0.1") { + $result= 1; + } else { + my $PROC_NET_ROUTE= ('/proc/net/route'); + + open(PROC_NET_ROUTE, "<$PROC_NET_ROUTE") + or die "Could not open $PROC_NET_ROUTE"; + + my @ifs = ; + + close(PROC_NET_ROUTE); + + # Eat header line + shift @ifs; + chomp @ifs; + foreach my $line(@ifs) { + my ($Iface,$Destination,$Gateway,$Flags,$RefCnt,$Use,$Metric,$Mask,$MTU,$Window,$IRTT)=split(/\s/, $line); + my $destination; + my $mask; + my ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Destination); + $destination= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d)); + ($d,$c,$b,$a)=unpack('a2 a2 a2 a2', $Mask); + $mask= sprintf("%d.%d.%d.%d", hex($a), hex($b), hex($c), hex($d)); + if(new NetAddr::IP($target_ip)->within(new NetAddr::IP($destination, $mask))) { + # destination matches route, save mac and exit + $result= 1; + last; + } + } + } + } else { + &main::daemon_log("Target ip $target_ip does not match bus ip $bus_ip",1); + } + + return $result; +} #=== FUNCTION ================================================================ # NAME: create_passwd @@ -424,6 +469,9 @@ sub create_passwd { sub create_ciphering { my ($passwd) = @_; + if((!defined($passwd)) || length($passwd)==0) { + $passwd = ""; + } $passwd = substr(md5_hex("$passwd") x 32, 0, 32); my $iv = substr(md5_hex('GONICUS GmbH'),0, 16); my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC()); @@ -435,10 +483,12 @@ sub create_ciphering { sub encrypt_msg { my ($msg, $key) = @_; my $my_cipher = &create_ciphering($key); + my $len; { - use bytes; - $msg = "\0"x(16-length($msg)%16).$msg; + use bytes; + $len= 16-length($msg)%16; } + $msg = "\0"x($len).$msg; $msg = $my_cipher->encrypt($msg); chomp($msg = &encode_base64($msg)); # there are no newlines allowed inside msg @@ -448,6 +498,7 @@ sub encrypt_msg { sub decrypt_msg { + my ($msg, $key) = @_ ; $msg = &decode_base64($msg); my $my_cipher = &create_ciphering($key); @@ -470,12 +521,16 @@ sub send_msg_hash2address { sub send_msg_to_target { my ($msg, $address, $encrypt_key, $msg_header) = @_ ; my $error = 0; + my $header; + my $new_status; + my $act_status; + my ($sql_statement, $res); if( $msg_header ) { - $msg_header = "'$msg_header'-"; + $header = "'$msg_header'-"; } else { - $msg_header = ""; + $header = ""; } # encrypt xml msg @@ -484,7 +539,7 @@ sub send_msg_to_target { # opensocket my $socket = &open_socket($address); if( !$socket ) { - daemon_log("cannot send ".$msg_header."msg to $address , host not reachable", 1); + daemon_log("cannot send ".$header."msg to $address , host not reachable", 1); $error++; } @@ -492,7 +547,7 @@ sub send_msg_to_target { # send xml msg print $socket $crypted_msg."\n"; - daemon_log("send ".$msg_header."msg to $address", 1); + daemon_log("send ".$header."msg to $address", 1); daemon_log("message:\n$msg", 8); } @@ -502,6 +557,44 @@ sub send_msg_to_target { close $socket; } + if( $error > 0 ) { $new_status = "down"; } + else { $new_status = $msg_header; } + + + # known_clients + $sql_statement = "SELECT * FROM bus_known_clients WHERE hostname='$address'"; + $res = $bus_known_clients_db->select_dbentry($sql_statement); + if( keys(%$res) > 0 ) { + $act_status = $res->{1}->{'status'}; + if( $act_status eq "down" ) { + $sql_statement = "DELETE FROM bus_known_clients WHERE hostname='$address'"; + $res = $bus_known_clients_db->del_dbentry($sql_statement); + daemon_log("WARNING: failed 2x to send msg to host '$address', delete host from bus_known_clients", 3); + } + else { + $sql_statement = "UPDATE bus_known_clients SET status='$new_status' WHERE hostname='$address'"; + $res = $bus_known_clients_db->update_dbentry($sql_statement); + daemon_log("INFO: set '$address' from status '$act_status' to '$new_status'", 5); + } + } + + # known_server + $sql_statement = "SELECT * FROM bus_known_server WHERE hostname='$address'"; + $res = $bus_known_server_db->select_dbentry($sql_statement); + if( keys(%$res) > 0) { + $act_status = $res->{1}->{'status'}; + if( $act_status eq "down" ) { + $sql_statement = "DELETE FROM bus_known_clients WHERE hostname='$address'"; + $res = $bus_known_clients_db->del_dbentry($sql_statement); + daemon_log("WARNING: failed 2x to a send msg to host '$address', delete host from bus_known_server", 3); + } + else { + $sql_statement = "UPDATE bus_known_server SET status='$new_status' WHERE hostname='$address'"; + $res = $bus_known_server_db->update_dbentry($sql_statement); + daemon_log("INFO: set '$address' from status '$act_status' to '$new_status'", 5) + } + } + return; } @@ -677,33 +770,74 @@ sub bus_input { my $source = @{$msg_hash->{'source'}}[0]; my $header = @{$msg_hash->{header}}[0]; - if( 1 == length(@target_l) && $target_l[0] eq $bus_address ) { + my $target_string = join(",", @target_l); + daemon_log("got msg '$header' with target '$target_string' from ".$heap->{'remote_ip'}, 3); + + if( 1 == length(@target_l) && &bus_matches($target_l[0]) ) { # msg is for bus +#print STDERR "msg is for bus\n"; $kernel->post('gosa_si_bus_session', $header, $msg, $msg_hash); } else { # msg is for someone else, deliver it - print STDERR "msg is for someone else\n"; +#print STDERR "msg is for someone else\n"; foreach my $target (@target_l) { - print STDERR "target: $target\n"; - if( $target =~ /(\d{3}\.\d{3}\.\d{3}\.\d{3}:\d+)/ ) { + if( $target =~ /(\d{0,3}\.\d{0,3}\.\d{0,3}\.\d{0,3}:\d+)/ ) { # target is a ip address - - my $sql_statement = "SELECT * FROM bus_known_server WHERE hostname='$target'"; - my $sql_statement = "SELECT * FROM bus_known_clients WHERE hostname='$target'"; + my ($sql_statement, $query_res); + + $sql_statement = "SELECT * FROM bus_known_server WHERE hostname='$target'"; + $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + if( 1 == keys(%$query_res) ) { + my $host_name = $query_res->{1}->{'hostname'}; + my $host_key = $query_res->{1}->{'hostkey'}; + &send_msg_to_target($msg, $host_name, $host_key, $header); + next; + } + + $sql_statement = "SELECT * FROM bus_known_clients WHERE hostname='$target'"; + $query_res = $bus_known_clients_db->select_dbentry( $sql_statement ); + if( 1 == keys(%$query_res) ) { + my $host_name = $query_res->{1}->{'hostname'}; + my $server_name = $query_res->{1}->{'registered'}; + # fetch correct key for server + my $sql_statement = "SELECT * FROM bus_known_server WHERE hostname='$server_name'"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + my $server_key = $query_res->{1}->{'hostkey'}; + &send_msg_to_target($msg, $server_name, $server_key, $header); + next; + } + + daemon_log("ERROR:unknown host, can not send message '$header' to target '$target'", 1); } elsif( $target =~ /([0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2}:[0-9a-f]{2})/ ) { # target is a mac address - - my $sql_statement = "SELECT registerd FROM bus_known_clients WHERE macaddress='$target'"; + my $sql_statement = "SELECT * FROM bus_known_clients WHERE macaddress LIKE '$target'"; my $query_res = $bus_known_clients_db->select_dbentry( $sql_statement ); - print Dumper $query_res; - - + if( 1 > keys(%{$query_res})) { + daemon_log("ERROR: there are more than one hosts in bus_known_clients_db with mac address '$target'", 1); + } + elsif( 0 == keys(%{$query_res})) { + daemon_log("WARNING: no host found in bus_known_clients_db with mac address '$target'", 3); + } + else { + my $host_name = $query_res->{1}->{'hostname'}; + my $server_name = $query_res->{1}->{'registered'}; + my $out_msg = $msg; + $out_msg =~ s/$target<\/target>/$host_name<\/target>/; + + # fetch correct key for server + my $sql_statement = "SELECT * FROM bus_known_server WHERE hostname='$server_name'"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + my $server_key = $query_res->{1}->{'hostkey'}; + + &send_msg_to_target($out_msg, $server_name, $server_key, $header); + } } else { - + daemon_log("ERROR: target address '$target' does not match neiter ". + "to ip address nor to mac address, can not send msg", 1); } } @@ -766,6 +900,7 @@ sub new_client { timestamp=>$act_timestamp, }; $bus_known_clients_db->add_dbentry($add_hash); + daemon_log("add new client '$new_client' to bus_known_clients_db", 3); } @@ -791,9 +926,9 @@ $SIG{CHLD} = 'IGNORE'; # forward error messages to logfile if ( ! $foreground ) { - open STDIN, '/dev/null' or die "Can’t read /dev/null: $!"; - open STDOUT, '>>/dev/null' or die "Can't write to /dev/null: $!"; - open STDERR, '>>/dev/null' or die "Can't write to /dev/null: $!"; + open( STDIN, '+>/dev/null' ); + open( STDOUT, '+>&STDIN' ); + open( STDERR, '+>&STDIN' ); } # Just fork, if we are not in foreground mode @@ -858,7 +993,7 @@ POE::Session->create( _start => \&_start, _default => \&_default, here_i_am => \&here_i_am, - confirm_new_passwd => \&confirm_new_key, + confirm_new_key => \&confirm_new_key, new_client => \&new_client, } );