Code

* bugfix: gosaTriggered.pm: all functions work now
[gosa.git] / gosa-si / gosa-si-bus
index 29e31ff3754786ef86f3ce8a0014c8cf5d10cf7e..37d54002cfa8899372b8036ca35b34742401e97e 100755 (executable)
@@ -28,33 +28,35 @@ 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 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 +175,7 @@ sub check_pid {
 #===============================================================================
 sub usage {
     print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config]
+usage: $prg [-hvf] [-c config]
 
     -h        : this (help) message
     -c <file> : config file
@@ -213,10 +215,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 +406,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 = <PROC_NET_ROUTE>;
+
+                       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 +468,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 +482,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 +497,7 @@ sub encrypt_msg {
 
 
 sub decrypt_msg {
+
     my ($msg, $key) = @_ ;
     $msg = &decode_base64($msg);
     my $my_cipher = &create_ciphering($key);
@@ -470,12 +520,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 +538,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 +546,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 +556,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;
 }
 
@@ -680,7 +772,7 @@ sub bus_input {
         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) && $target_l[0] eq $bus_address ) {
+        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);
@@ -716,11 +808,11 @@ sub bus_input {
                         next;
                     } 
 
-                    daemon_log("ERROR:unknown host, can not process message '$header'", 1);
+                    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 * 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 );
                     if( 1 > keys(%{$query_res})) {
                         daemon_log("ERROR: there are more than one hosts in bus_known_clients_db with mac address '$target'", 1);
@@ -744,7 +836,7 @@ sub bus_input {
                 }
                 else {
                     daemon_log("ERROR: target address '$target' does not match neiter ".
-                        "to ip address nor to mac address, can not process msg", 1);
+                        "to ip address nor to mac address, can not send msg", 1);
                 }
 
             }
@@ -833,9 +925,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
@@ -900,7 +992,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,
        }
 );