X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-bus;h=dd848c182c3b4ade9d9ae1dd35a1e7a4edc7564d;hb=db15b7b88560f1ee2f3f3178883511739f1b21fd;hp=a56a38e1a2f9a46763ab00bc46aa29040cb0fffd;hpb=e38d4123a43ac0f63d6b101f8f8e71b083110491;p=gosa.git diff --git a/gosa-si/gosa-si-bus b/gosa-si/gosa-si-bus index a56a38e1a..dd848c182 100755 --- a/gosa-si/gosa-si-bus +++ b/gosa-si/gosa-si-bus @@ -34,22 +34,18 @@ use Data::Dumper; use Sys::Syslog qw( :DEFAULT setlogsock); use Cwd; use File::Spec; -use IPC::Shareable qw( :lock); -IPC::Shareable->clean_up_all; +use GOSA::GosaSupportDaemon; +use GOSA::DBsqlite; my ($cfg_file, $default_cfg_file, %cfg_defaults, $foreground, $verbose); -my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address); +my ($bus_activ, $bus_passwd, $bus_ip, $bus_port, $bus_address, $bus, $bus_mac_address, $network_interface); my ($pid_file, $procid, $pid, $log_file, $my_own_address); my (%free_child, %busy_child, $child_max, $child_min, %child_alive_time, $child_timeout); -my ($xml, $bus_cipher, $known_daemons, $shmkh); +my ($bus_known_server_db, $bus_known_server_file_name); +my ($xml, $bus_cipher); $foreground = 0 ; -$known_daemons = {}; -$shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, - exclusive => 1, - mode => 0666, - destroy => 1, - }); + %cfg_defaults = ("general" => {"log_file" => [\$log_file, "/var/run/".$0.".log"], @@ -57,11 +53,12 @@ $shmkh = tie($known_daemons, 'IPC::Shareable', undef, {create => 1, "child_max" => [\$child_max, 10], "child_min" => [\$child_min, 3], "child_timeout" => [\$child_timeout, 180], - + "bus_known_server_file_name" => [\$bus_known_server_file_name, "/var/lib/gosa-si/bus_known_server.db"] }, "bus" => {"bus_activ" => [\$bus_activ, "on"], "bus_passwd" => [\$bus_passwd, ""], + "bus_ip" => [\$bus_ip, "0.0.0.0"], "bus_port" => [\$bus_port, "20080"], } ); @@ -109,7 +106,7 @@ sub daemon_log { print STDERR "cannot open $log_file: $!"; return } chomp($msg); - if($level <= $verbose){ + if($level && $verbose && $level <= $verbose){ print LOG_HANDLE $msg."\n"; if(defined $foreground) { print $msg."\n" } } @@ -136,9 +133,8 @@ sub check_cmdline_param () { my $err_counter = 0; if( not defined( $cfg_file)) { my $cwd = getcwd; - my $name = "/etc/gosa/gosa-si-bus.conf"; + my $name = "/etc/gosa-si/bus.conf"; $cfg_file = File::Spec->catfile( $cwd, $name ); - print STDERR "no conf file specified\n try to use default: $cfg_file\n"; } if( $err_counter > 0 ) { &usage( "", 1 ); @@ -229,38 +225,130 @@ sub sig_int_handler { print "$bus closed\n"; } print "$signal\n"; - IPC::Shareable->clean_up; exit(1); } $SIG{INT} = \&sig_int_handler; +#=== FUNCTION ================================================================ +# NAME: get_interface_for_ip +# PARAMETERS: ip address (i.e. 192.168.0.1) +# RETURNS: array: list of interfaces if ip=0.0.0.0, matching interface if found, undef else +# DESCRIPTION: Uses proc fs (/proc/net/dev) to get list of interfaces. +#=============================================================================== +sub get_interface_for_ip { + my $result; + my $ip= shift; + if ($ip && length($ip) > 0) { + my @ifs= &get_interfaces(); + if($ip eq "0.0.0.0") { + $result = "all"; + } else { + foreach (@ifs) { + my $if=$_; + if(get_ip($if) eq $ip) { + $result = $if; + } + } + } + } + return $result; +} #=== FUNCTION ================================================================ -# NAME: get_ip_and_mac -# PARAMETERS: nothing -# RETURNS: (ip, mac) -# DESCRIPTION: executes /sbin/ifconfig and parses the output, the first occurence -# of a inet address is returned as well as the mac address in the line -# above the inet address +# NAME: get_interfaces +# PARAMETERS: none +# RETURNS: (list of interfaces) +# DESCRIPTION: Uses proc fs (/proc/net/dev) to get list of interfaces. #=============================================================================== -sub get_ip_and_mac { - my $ip = "0.0.0.0.0"; # Defualt-IP - my $mac_address = "00:00:00:00:00:00"; # Default-MAC - my @ifconfig = qx(/sbin/ifconfig); - foreach(@ifconfig) { - if (/Hardware Adresse (\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2}):(\S{2})/) { - $mac_address = "$1:$2:$3:$4:$5:$6"; - next; +sub get_interfaces { + my @result; + my $PROC_NET_DEV= ('/proc/net/dev'); + + open(PROC_NET_DEV, "<$PROC_NET_DEV") + or die "Could not open $PROC_NET_DEV"; + + my @ifs = ; + + close(PROC_NET_DEV); + + # Eat first two line + shift @ifs; + shift @ifs; + + chomp @ifs; + foreach my $line(@ifs) { + my $if= (split /:/, $line)[0]; + $if =~ s/^\s+//; + push @result, $if; } - if (/inet Adresse:(\d+).(\d+).(\d+).(\d+)/) { - $ip = "$1.$2.$3.$4"; - last; + + return @result; +} + +#=== FUNCTION ================================================================ +# NAME: get_mac +# PARAMETERS: interface name (i.e. eth0) +# RETURNS: (mac address) +# DESCRIPTION: Uses ioctl to get mac address directly from system. +#=============================================================================== +sub get_mac { + my $ifreq= shift; + my $result; + if ($ifreq && length($ifreq) > 0) { + if($ifreq eq "all") { + $result = "00:00:00:00:00:00"; + } else { + my $SIOCGIFHWADDR= 0x8927; # man 2 ioctl_list + + # A configured MAC Address should always override a guessed value + if ($bus_mac_address and length($bus_mac_address) > 0) { + return $bus_mac_address; + } + + socket SOCKET, PF_INET, SOCK_DGRAM, getprotobyname('ip') + or die "socket: $!"; + + if(ioctl SOCKET, $SIOCGIFHWADDR, $ifreq) { + my ($if, $mac)= unpack 'h36 H12', $ifreq; + + if (length($mac) > 0) { + $mac=~ m/^([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])([0-9a-f][0-9a-f])$/; + $mac= sprintf("%s:%s:%s:%s:%s:%s", $1, $2, $3, $4, $5, $6); + $result = $mac; + } + } } } - return ($ip, $mac_address); + return $result; } +#=== FUNCTION ================================================================ +# NAME: get_ip +# PARAMETERS: interface name (i.e. eth0) +# RETURNS: (ip address) +# DESCRIPTION: Uses ioctl to get ip address directly from system. +#=============================================================================== +sub get_ip { + my $ifreq= shift; + my $result= ""; + my $SIOCGIFADDR= 0x8915; # man 2 ioctl_list + my $proto= getprotobyname('ip'); + + socket SOCKET, PF_INET, SOCK_DGRAM, $proto + or die "socket: $!"; + + if(ioctl SOCKET, $SIOCGIFADDR, $ifreq) { + my ($if, $sin) = unpack 'a16 a16', $ifreq; + my ($port, $addr) = sockaddr_in $sin; + my $ip = inet_ntoa $addr; + + if ($ip && length($ip) > 0) { + $result = $ip; + } + } + return $result; +} #=== FUNCTION ================================================================ # NAME: activating_child @@ -436,127 +524,145 @@ sub process_incoming_msg { $crypted_msg = $1; my $host = sprintf("%s.%s.%s.%s", $2, $3, $4, $5); - daemon_log("msg from host:\n\t$host", 1); - daemon_log("crypted_msg:\n\t$crypted_msg", 7); - - my @valid_keys; - my @daemon_keys = keys %$known_daemons; - foreach my $daemon_key (@daemon_keys) { - if($daemon_key =~ "^$daemon_key") { - push(@valid_keys, $daemon_key); + my $msg; + my $msg_hash; + my $host_name; + my $host_key; + + # check wether incoming msg is a new msg + $host_name = $bus_address; + $host_key = $bus_passwd; + daemon_log("process_incoming_msg: host_name: $host_name", 7); + daemon_log("process_incoming_msg: host_key: $host_key", 7); + eval{ + my $key_cipher = &create_ciphering($host_key); + $msg = &decrypt_msg($crypted_msg, $key_cipher); + $msg_hash = &transform_msg2hash($msg); + }; + if($@) { + daemon_log("process_incoming_msg: deciphering raise error", 7); + daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; + $host_name = undef; + $host_key = undef; + } + + # check wether incoming msg is from a bus_known_server + if( not defined $msg ) { + my $sql_statement= "SELECT * FROM bus_known_server"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { + $host_name = $hit->{hostname}; + if( not $host_name =~ "^$host") { + next; + } + $host_key = $hit->{hostkey}; + daemon_log("process_incoming_msg: host_name: $host_name", 7); + daemon_log("process_incoming_msg: host_key: $host_key", 7); + eval{ + my $key_cipher = &create_ciphering($host_key); + $msg = &decrypt_msg($crypted_msg, $key_cipher); + $msg_hash = &transform_msg2hash($msg); + }; + if($@) { + daemon_log("process_incoming_msg: deciphering raise error", 7); + daemon_log("$@", 8); + $msg = undef; + $msg_hash = undef; + $host_name = undef; + $host_key = undef; + } else { + last; + } } } - my $l = @valid_keys; - daemon_log("number of valid daemons: $l\n", 7); - - my ($msg, $msg_hash); - my $msg_flag = 0; - - # collect addresses from possible incoming clients - foreach my $host_key (@valid_keys) { - eval{ - daemon_log( "daemon: $host_key\n", 7); - my $key_passwd = $known_daemons->{$host_key}->{passwd}; - daemon_log("daemon_passwd: $key_passwd\n", 7); - my $key_cipher = &create_ciphering($key_passwd); - $msg = &decrypt_msg($crypted_msg, $key_cipher); - daemon_log("daemon decrypted msg:$msg", 7); - $msg_hash = $xml->XMLin($msg, ForceArray=>1); - }; - if($@) { - daemon_log("msg processing raise error", 7); - daemon_log("error string: $@", 7); - $msg_flag += 1; - } else { - last; - } - } - - if($msg_flag >= $l) { - daemon_log("\nERROR: do not understand the message:\n$msg" , 1); + if( not defined $msg ) { + daemon_log("WARNING: bus does not understand the message:", 5); return; } - my $header = &get_content_from_xml_hash($msg_hash, "header"); - my $target = &get_content_from_xml_hash($msg_hash, "target"); - - daemon_log("header from msg:\n\t$header", 1); - daemon_log("msg to process:\n\t$msg", 5); - daemon_log("msg is for: \n\t$target", 7); - - if($target eq $bus_address) { - # msg is for bus - if($header eq 'here_i_am'){ &here_i_am($msg_hash)} - elsif($header eq 'confirm_new_passwd'){ &confirm_new_passwd($msg_hash)} - elsif($header eq 'got_ping') { &got_ping($msg_hash)} - elsif($header eq 'ping') { &ping($msg_hash)} - elsif($header eq 'who_has') { &who_has($msg_hash)} - elsif($header eq 'new_client') { &new_client($msg_hash)} - elsif($header eq 'delete_client') { &delete_client($msg_hash)} - } else { - # msg is for any other server - my @targets = @{$msg_hash->{target}}; - my $len_targets = @targets; - - if ($len_targets == 0){ - # no targets specified - - daemon_log("ERROR: no target specified for msg $header", 1); - - } elsif ($targets[0] eq "*"){ - # all deamons in known_daemons are targets - - my $target = $targets[0]; - my $source = @{$msg_hash->{source}}[0]; - my @target_addresses = keys(%$known_daemons); - foreach my $target_address (@target_addresses) { - if ($target_address eq $source) { next; } - if ($target_address eq $bus_address) { next ; } - $msg_hash->{target} = [$target_address]; - &send_msg_hash2address($msg_hash, $target_address); + # process incoming msg + my $header = @{$msg_hash->{header}}[0]; + my $source = @{$msg_hash->{source}}[0]; + + daemon_log("header from msg: $header", 1); + daemon_log("msg to process:", 5); + daemon_log($msg, 5); + + my @targets = @{$msg_hash->{target}}; + my $len_targets = @targets; + + if ($len_targets == 0){ + daemon_log("ERROR: no target specified for msg $header", 1); + + } elsif ($len_targets == 1){ + # we have only one target symbol + my $target = $targets[0]; + daemon_log("msg is for: $target", 7); + + if($target eq $bus_address) { + # msg is for bus + if($header eq 'here_i_am'){ &here_i_am($msg_hash)} + elsif($header eq 'confirm_new_passwd'){ &confirm_new_passwd($msg_hash)} + elsif($header eq 'got_ping') { &got_ping($msg_hash)} + elsif($header eq 'ping') { &ping($msg_hash)} + elsif($header eq 'who_has') { &who_has($msg_hash)} + elsif($header eq 'new_client') { &new_client($msg_hash)} + elsif($header eq 'delete_client') { &delete_client($msg_hash)} + + } elsif ($target eq "*"){ + # msg is for all server + my $sql_statement= "SELECT * FROM known_server"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + while( my ($hit_num, $hit) = each %{ $query_res } ) { + $host_name = $hit->{hostname}; + $host_key = $hit->{hostkey}; + $msg_hash->{target} = [$host_name]; + &send_msg_hash2address($msg_hash, $host_name, $host_key); } + return; + } - } else { - # a list of targets is specified - - my $target_address; - foreach $target_address (@targets) { - if (exists $known_daemons->{$target_address}) { - &send_msg_hash2address($msg_hash, $target_address); - } else { - my @daemon_addresses = keys %$known_daemons; - my $daemon_address; - foreach $daemon_address (@daemon_addresses) { - if (exists $known_daemons->{$daemon_address}->{clients}->{$target_address}) { - my $header = &get_content_from_xml_hash($msg_hash, "header"); - &send_msg_hash2address($msg_hash, $daemon_address); - daemon_log("bus forwards msg $header for client $target_address to server $daemon_address", 3); - last; + } else { + # a list of targets is specified + my $target_address; + foreach $target_address (@targets) { + + my $sql_statement= "SELECT * FROM known_server WHERE hostname='$target_address'"; + my $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + if( 1 == keys %{$query_res} ) { + $host_key = $query_res->{1}->{hostkey}; + &send_msg_hash2address($msg_hash, $target_address, $host_key); + next; + + } else { + my $sql_statement= "SELECT * FROM known_server"; + $query_res = $bus_known_server_db->select_dbentry( $sql_statement ); + while( my ($hit_num, $hit) = each %{$query_res} ) { + my $host_name = $hit->{hostname}; + my $host_key = $hit->{hostkey}; + my $clients = $hit->{clients}; + my @clients = split(/,/, $clients); + foreach my $client (@clients) { + if( not $client eq $target_address ) { + next; } + $msg_hash->{target} = [ $target_address ]; + &send_msg_hash2address($msg_hash, $host_name, $host_key); + daemon_log("bus forwards msg $header for client $target_address to server $host_name", 3); + last; } - } } } } - &print_known_daemons_hash(); return; } -#=== FUNCTION ================================================================ -# NAME: get_content_of_known_daemons -# PARAMETERS: -# RETURNS: -# DESCRIPTION: -#=============================================================================== -#sub get_content_of_known_daemons { -# my ($host, $content) = @_; -# return; -#} - #=== FUNCTION ================================================================ # NAME: create_passwd @@ -573,164 +679,6 @@ sub create_passwd { } -#=== FUNCTION ================================================================ -# NAME: create_ciphering -# PARAMETERS: passwd - string - used to create ciphering -# RETURNS: cipher - object -# DESCRIPTION: creates a Crypt::Rijndael::MODE_CBC object with passwd as key -#=============================================================================== -sub create_ciphering { - my ($passwd) = @_; - $passwd = substr(md5_hex("$passwd") x 32, 0, 32); - my $iv = substr(md5_hex('GONICUS GmbH'),0, 16); - - #daemon_log("iv: $iv", 7); - #daemon_log("key: $passwd", 7); - my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC()); - $my_cipher->set_iv($iv); - return $my_cipher; -} - - -#=== FUNCTION ================================================================ -# NAME: encrypt_msg -# PARAMETERS: msg - string - message to encrypt -# my_cipher - ref - reference to a Crypt::Rijndael object -# RETURNS: crypted_msg - string - crypted message -# DESCRIPTION: crypts the incoming message with the Crypt::Rijndael module -#=============================================================================== -sub encrypt_msg { - my ($msg, $my_cipher) = @_; - if(not defined $my_cipher) { print "no cipher object\n"; } - $msg = "\0"x(16-length($msg)%16).$msg; - my $crypted_msg = $my_cipher->encrypt($msg); - chomp($crypted_msg = &encode_base64($crypted_msg)); - return $crypted_msg; -} - - -#=== FUNCTION ================================================================ -# NAME: decrypt_msg -# PARAMETERS: crypted_msg - string - message to decrypt -# my_cipher - ref - reference to a Crypt::Rijndael object -# RETURNS: msg - string - decrypted message -# DESCRIPTION: decrypts the incoming message with the Crypt::Rijndael module -#=============================================================================== -sub decrypt_msg { - my ($crypted_msg, $my_cipher) = @_ ; - $crypted_msg = &decode_base64($crypted_msg); - my $msg = $my_cipher->decrypt($crypted_msg); - $msg =~ s/^\0*//g; - return $msg; -} - - -#=== FUNCTION ================================================================ -# NAME: create_xml_hash -# PARAMETERS: header - string - message header (required) -# source - string - where the message come from (required) -# target - string - where the message should go to (required) -# [header_value] - string - something usefull (optional) -# RETURNS: hash - hash - nomen est omen -# DESCRIPTION: creates a key-value hash, all values are stored in a array -#=============================================================================== -sub create_xml_hash { - my ($header, $source, $target, $header_value) = @_ ; - - if (not defined $header || not defined $source || not defined $target) { - daemon_log("ERROR: create_xml_hash function is invoked with uncompleted parameters", 7); - } - - my $hash = { - header => [$header], - source => [$source], - target => [$target], - $header => [$header_value], - }; - #daemon_log("create_xml_hash:", 7), - #chomp(my $tmp = Dumper $hash); - #daemon_log("\t$tmp\n", 7); - return $hash -} - - -#=== FUNCTION ================================================================ -# NAME: create_xml_string -# PARAMETERS: xml_hash - hash - hash from function create_xml_hash -# RETURNS: xml_string - string - xml string representation of the hash -# DESCRIPTION: transform the hash to a string using XML::Simple module -#=============================================================================== -sub create_xml_string { - my ($xml_hash) = @_ ; - my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml'); - $xml_string =~ s/[\n]+//g; - return $xml_string; -} - - -#=== FUNCTION ================================================================ -# NAME: add_content2xml_hash -# PARAMETERS: xml_ref - ref - reference to a hash from function create_xml_hash -# element - string - key for the hash -# content - string - value for the hash -# RETURNS: nothing -# DESCRIPTION: add key-value pair to xml_ref, if key alread exists, then append value to list -#=============================================================================== -sub add_content2xml_hash { - my ($xml_ref, $element, $content) = @_; - if(not exists $$xml_ref{$element} ) { - $$xml_ref{$element} = []; - } - my $tmp = $$xml_ref{$element}; - push(@$tmp, $content); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: get_content_from_xml_hash -# PARAMETERS: xml_ref - ref - reference of the xml hash -# element - string - key of the value you want -# RETURNS: value - string - if key is either header, target or source -# value - list - for all other keys in xml hash -# DESCRIPTION: -#=============================================================================== -sub get_content_from_xml_hash { - my ($xml_ref, $element) = @_; - my $result = $xml_ref->{$element}; - if( $element eq "header" || $element eq "target" || $element eq "source") { - return @$result[0]; - } - return @$result; -} - - -#=== FUNCTION ================================================================ -# NAME: open_socket -# PARAMETERS: PeerAddr - string - something like 192.168.1.1 or 192.168.1.1:10000 -# [PeerPort] - string - necessary if port not appended by PeerAddr -# RETURNS: socket - IO::Socket::INET -# DESCRIPTION: open a socket to PeerAddr -#=============================================================================== -sub open_socket { - my ($PeerAddr, $PeerPort) = @_ ; - if(defined($PeerPort)){ - $PeerAddr = $PeerAddr.":".$PeerPort; - } - my $socket; - $socket = new IO::Socket::INET(PeerAddr => $PeerAddr , - Porto => "tcp" , - Type => SOCK_STREAM, - Reuse => 1, - Timeout => 5, - ); - if(not defined $socket) { - return; - } - return $socket; -} - - #=== FUNCTION ================================================================ # NAME: read_from_socket # PARAMETERS: socket - fh - filehandel to read from @@ -762,99 +710,6 @@ sub read_from_socket { } -#=== FUNCTION ================================================================ -# NAME: send_msg_hash2address -# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash -# PeerAddr string - socket address to send msg -# PeerPort string - socket port, if not included in socket address -# RETURNS: nothing -# DESCRIPTION: ???? -#=============================================================================== -sub send_msg_hash2address { - my ($msg_hash, $address) = @_ ; - - # fetch header for logging - my $header = &get_content_from_xml_hash($msg_hash, "header"); - - # generate xml string - my $msg_xml = &create_xml_string($msg_hash); - - # fetch the appropriated passwd from hash - my $passwd = $known_daemons->{$address}->{passwd}; - - # create a ciphering object - my $act_cipher = &create_ciphering($passwd); - - # encrypt xml msg - my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - - # open socket - my $socket = &open_socket($address); - if(not defined $socket){ - daemon_log("ERROR: cannot send '$header'-msg to $address , server not reachable", 1); - return; - } - - # send xml msg - print $socket $crypted_msg."\n"; - - close $socket; - daemon_log("send '$header'-msg to $address", 5); - daemon_log("crypted_msg:\n\t$crypted_msg", 7); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: send_msg_hash2all -# PARAMETERS: msg_hash - hash - xml_hash created with function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: send msg_hash to all registered daemons -#=============================================================================== -sub send_msg_hash2all { - my ($msg_hash) = @_; - - # fetch header for logging - my $header = &get_content_from_xml_hash($msg_hash, "header"); - - # generate xml string - my $msg_xml = &create_xml_string($msg_hash); - - # fetch a list of all target addresses - my @targets = keys(%$known_daemons); - - # itterates through the list an send each the msg - foreach my $target (@targets) { - if($target eq $bus_address) {next}; # do not send msg to bus - - # fetch the appropriated passwd - my $passwd = $known_daemons->{$target}->{passwd}; - - # create ciphering object - my $act_cipher = &create_ciphering($passwd); - - # encrypt xml msg - my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher); - - # open socket - my $socket = &open_socket($target); - if(not defined $socket){ - daemon_log("ERROR: cannot open socket to $target , server not reachable", 1); - &update_known_daemons_entry(hostname=>$target, status=>"down"); - next; - } - - # send xml msg - print $socket $crypted_msg."\n"; - - close $socket; - daemon_log("send '$header'-msg to $target", 5); - daemon_log("crypted_msg:\n\t$crypted_msg", 7); - } - return; -} - - #=== FUNCTION ================================================================ # NAME: here_i_am # PARAMETERS: msg_hash - hash - hash from function create_xml_hash @@ -863,21 +718,30 @@ sub send_msg_hash2all { #=============================================================================== sub here_i_am { my ($msg_hash) = @_ ; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - - my $new_passwd = &create_passwd(); - - # create known_daemons entry - &create_known_daemons_entry($source); - &update_known_daemons_entry(hostname=>$source, status=>"registered", passwd=>$bus_passwd); + my $source = @{$msg_hash->{source}}[0];; + + my $new_key = &create_passwd(); + + # create bus_known_server entry + my $add_hash = { + table=>"bus_known_server", + primkey=>"hostname", + hostname=>$source, + status=>"registered", + hostkey=>$bus_passwd, + clients=>"", + }; + $bus_known_server_db->add_dbentry($add_hash); # create outgoing msg - my $out_hash = &create_xml_hash("new_passwd", "$bus_ip:$bus_port", $source, $new_passwd); - &send_msg_hash2address($out_hash, $source); + my $out_hash = &create_xml_hash("new_passwd", $bus_address, $source, $new_key); + &send_msg_hash2address($out_hash, $source, $bus_passwd); - # change passwd, reason - # &send_msg_hash2address takes $known_daemons->{"$source"}->{passwd} to cipher msg - &update_known_daemons_entry(hostname=>$source, status=>"new_passwd", passwd=>$new_passwd); + # change hostkey, reason + my $where_str= " WHERE hostname='$source'"; + my $update_str= " SET hostkey='$new_key'"; + my $sql_statement= "UPDATE bus_known_server $update_str $where_str"; + $bus_known_server_db->update_dbentry($sql_statement); return; } @@ -891,8 +755,13 @@ sub here_i_am { #=============================================================================== sub confirm_new_passwd { my ($msg_hash) = @_ ; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - &update_known_daemons_entry(hostname=>$source, status=>"confirmed_new_passwd"); + my $source = @{$msg_hash->{source}}[0]; + my $sql_statement= "UPDATE bus_known_server ". + "SET status='key_confirmed' ". + "WHERE hostname='$source' "; + + $bus_known_server_db->update_dbentry($sql_statement); + return; } @@ -905,25 +774,19 @@ sub confirm_new_passwd { #=============================================================================== sub ping { my ($msg_hash) = @_ ; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - &update_known_daemons_entry(hostname=>$source, status=>"ping"); - my $out_hash = &create_xml_hash("got_ping", $bus_address, $source); - &send_msg_hash2address($out_hash, $source); - return; -} + my $header = @{$msg_hash->{header}}[0]; + my $source = @{$msg_hash->{source}}[0]; + my $sql_statement= "UPDATE bus_known_server SET status='$header' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry($sql_statement); + + my $out_hash = &create_xml_hash("got_ping", $bus_address, $source); + + $sql_statement= "SELECT * FROM bus_known_server WHERE hostname='$source'"; + my $res = $bus_known_server_db->select_dbentry( $sql_statement ); + my $hostkey = $res->{1}->{hostkey}; + &send_msg_hash2address($out_hash, $source, $hostkey); -#=== FUNCTION ================================================================ -# NAME: make ping -# PARAMETERS: address - string - address which should be pinged -# RETURNS: nothing -# DESCRIPTION: send ping message to address -#=============================================================================== -sub make_ping { - my ($address) = @_; - daemon_log("ping:$address\n", 1); - my $out_hash = &create_xml_hash("ping", "$bus_ip:$bus_port", $address); - &send_msg_hash2address($out_hash, $address); return; } @@ -936,8 +799,11 @@ sub make_ping { #=============================================================================== sub got_ping { my ($msg_hash) = @_; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - &update_known_daemons_entry(hostname=>$source, status=>"got_ping"); + my $source = @{$msg_hash->{source}}[0]; + + my $sql_statement= "UPDATE bus_known_server SET status='got_ping' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry($sql_statement); + return; } @@ -950,135 +816,23 @@ sub got_ping { #=============================================================================== sub new_client { my ($msg_hash) = @_ ; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - my $header = &get_content_from_xml_hash($msg_hash, "header"); - my $new_client = (&get_content_from_xml_hash($msg_hash, $header))[0]; - - &update_known_daemons_entry(hostname=>$source, client=>$new_client); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: delete_client -# PARAMETERS: msg_hash - hash - hash from function create_xml_hash -# RETURNS: nothing -# DESCRIPTION: process this incoming message -#=============================================================================== -sub delete_client { - my ($msg_hash) = @_ ; - my $source = &get_content_from_xml_hash($msg_hash, "source"); - my $header = &get_content_from_xml_hash($msg_hash, "header"); - my $del_client = (&get_content_from_xml_hash($msg_hash, $header))[0]; - - if (not exists $known_daemons->{$source}->{$del_client}) { - daemon_log - } - delete $known_daemons->{$source}->{$del_client}; - - return; -} - - -#=== FUNCTION ================================================================ -# NAME: print_known_daemons_hash -# PARAMETERS: nothing -# RETURNS: nothing -# DESCRIPTION: nome est omen -#=============================================================================== -sub print_known_daemons_hash { - my ($tmp) = @_; - print "####################################\n"; - print "# status of known_daemons\n"; - my $hosts; - my $host_hash; - $shmkh->shlock(LOCK_EX); - my @hosts = keys %$known_daemons; - foreach my $host (@hosts) { - my $status = $known_daemons->{$host}->{status} ; - my $passwd = $known_daemons->{$host}->{passwd}; - my $timestamp = $known_daemons->{$host}->{timestamp}; - my @clients = keys %{$known_daemons->{$host}->{clients}}; - my $client_string = join(", ", @clients); - print "$host\n"; - print "\tstatus: $status\n"; - print "\tpasswd: $passwd\n"; - print "\ttimestamp: $timestamp\n"; - print "\tclients: $client_string\n"; - - } - $shmkh->shunlock(LOCK_EX); - print "####################################\n\n"; - return; -} - - -#=== FUNCTION ================================================================ -# NAME: create_known_daemons_entry -# PARAMETERS: hostname - string - ip address and port of host -# RETURNS: nothing -# DESCRIPTION: nome est omen -#=============================================================================== -sub create_known_daemons_entry { - my ($hostname) = @_; - $shmkh->shlock(LOCK_EX); - $known_daemons->{$hostname} = {}; - $known_daemons->{$hostname}->{status} = "none"; - $known_daemons->{$hostname}->{passwd} = "none"; - $known_daemons->{$hostname}->{timestamp} = "none"; - $known_daemons->{$hostname}->{clients} = {}; - $shmkh->shunlock(LOCK_EX); - return; -} - - -#=== FUNCTION ================================================================ -# NAME: update_known_daemons_entry -# PARAMETERS: hostname - string - ip address and port of host (required) -# status - string - (optional) -# passwd - string - (optional) -# client - string - ip address and port of client (optional) -# RETURNS: nothing -# DESCRIPTION: nome est omen and updates each time the timestamp of hostname -#=============================================================================== -sub update_known_daemons_entry { - my $arg = { - hostname => undef, status => undef, passwd => undef, - client => undef, - @_ }; - my $hostname = $arg->{hostname}; - my $status = $arg->{status}; - my $passwd = $arg->{passwd}; - my $client = $arg->{client}; - - if (not defined $hostname) { - daemon_log("ERROR: function add_content2known_daemons is not invoked with requiered parameter 'hostname'", 1); - return; + my $source = @{$msg_hash->{source}}[0]; + my $header = @{$msg_hash->{header}}[0]; + my $new_client = @{$msg_hash->{$header}}[0]; + + my $sql_statement= "SELECT * FROM bus_known_server WHERE hostname='$source'"; + my $res = $bus_known_server_db->select_dbentry( $sql_statement ); + my $clients = $res->{1}->{clients}; + + # if host has alread more clients, than just append + if( length($clients) != 0 ) { + $clients .= ",$new_client"; + } else { + $clients = $new_client; } - my ($seconds, $minutes, $hours, $monthday, $month, - $year, $weekday, $yearday, $sommertime) = localtime(time); - $hours = $hours < 10 ? $hours = "0".$hours : $hours; - $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; - $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; - $month+=1; - $month = $month < 10 ? $month = "0".$month : $month; - $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; - $year+=1900; - my $t = "$year$month$monthday$hours$minutes$seconds"; - - $shmkh->shlock(LOCK_EX); - if (defined $status) { - $known_daemons->{$hostname}->{status} = $status; - } - if (defined $passwd) { - $known_daemons->{$hostname}->{passwd} = $passwd; - } - if (defined $client) { - $known_daemons->{$hostname}->{clients}->{$client} = ""; - } - $known_daemons->{$hostname}->{timestamp} = $t; - $shmkh->shunlock(LOCK_EX); + $sql_statement= "UPDATE bus_known_server SET clients='$clients' WHERE hostname='$source'"; + $bus_known_server_db->update_dbentry( $sql_statement ); return; } @@ -1102,28 +856,50 @@ $SIG{CHLD} = 'IGNORE'; # restart daemon log file if(-e $log_file ) { unlink $log_file } -daemon_log("$0 started!"); +daemon_log(" ", 1); +daemon_log("$0 started!", 1); + +# delete old DBsqlite lock files +system('rm -f /tmp/gosa_si_lock*'); + +# forward error messages to logfile +if( ! $foreground ) { + open(STDERR, '>>', $log_file); + open(STDOUT, '>>', $log_file); +} # Just fork, if we"re not in foreground mode -if( ! $foreground ) { $pid = fork(); } -else { $pid = $$; } +if( ! $foreground ) { + chdir '/' or die "Can't chdir to /: $!"; + $pid = fork; + setsid or die "Can't start a new session: $!"; + umask 0; +} else { + $pid = $$; +} # Do something useful - put our PID into the pid_file if( 0 != $pid ) { open( LOCK_FILE, ">$pid_file" ); print LOCK_FILE "$pid\n"; close( LOCK_FILE ); - if( !$foreground ) { exit( 0 ) }; + if( ! $foreground ) { exit( 0 ) }; } +# connect to bus_known_server_db +my @server_col_names = ('hostname', 'status', 'hostkey', 'timestamp', 'clients' ); +$bus_known_server_db = GOSA::DBsqlite->new($bus_known_server_file_name); +$bus_known_server_db->create_table('bus_known_server', \@server_col_names); + + # detect own ip and mac address -($bus_ip, $bus_mac_address) = &get_ip_and_mac(); -if (not defined $bus_ip) { - die "EXIT: ip address of $0 could not be detected"; -} +$network_interface= &get_interface_for_ip($bus_ip); +$bus_mac_address= &get_mac($network_interface); daemon_log("bus ip address detected: $bus_ip", 1); daemon_log("bus mac address detected: $bus_mac_address", 1); +# complete addresses +$bus_address = "$bus_ip:$bus_port"; # setup xml parser $xml = new XML::Simple(); @@ -1137,6 +913,7 @@ my $rbits = my $wbits = my $ebits = ""; # open the bus socket if($bus_activ eq "on") { + daemon_log(" ", 1); $bus = IO::Socket::INET->new(LocalPort => $bus_port, Type => SOCK_STREAM, Reuse => 1, @@ -1144,12 +921,13 @@ if($bus_activ eq "on") { ) or die "kann kein TCP-Server an Port $bus_port sein: $@\n"; vec($rbits, fileno $bus, 1) = 1; vec($wbits, fileno $bus, 1) = 1; - print "start bus at $bus_ip:$bus_port\n"; + daemon_log ("start bus at $bus_ip:$bus_port", 1); } # add bus to known_daemons -&create_known_daemons_entry($bus_address); -&update_known_daemons_entry(hostname=>$bus_address, status=>"bus", passwd=>$bus_passwd); + +#&create_known_daemons_entry($bus_address); +#&update_known_daemons_entry(hostname=>$bus_address, status=>"bus", passwd=>$bus_passwd); while(1) {