X-Git-Url: https://git.tokkee.org/?a=blobdiff_plain;f=gosa-si%2Fgosa-si-client;h=3d627c9b070a20ee51c733819ab2fe9c56be833b;hb=4cae4bffe01e5281e535055bc03bd74d8de5f7ac;hp=1f0ae9b9ba4115943da54a9f2c4dc06a8e45f668;hpb=cdf7879e21725a42604b3a54a7659a51dc9a4901;p=gosa.git diff --git a/gosa-si/gosa-si-client b/gosa-si/gosa-si-client index 1f0ae9b9b..3d627c9b0 100755 --- a/gosa-si/gosa-si-client +++ b/gosa-si/gosa-si-client @@ -34,20 +34,13 @@ use GOSA::GosaSupportDaemon; use Digest::MD5 qw(md5_hex md5 md5_base64); use MIME::Base64; use XML::Simple; - - -#use Fcntl; -#use Sys::Syslog qw( :DEFAULT setlogsock); -#use File::Spec; -#use Cwd; - - +use Net::DNS; my $event_dir = "/usr/lib/gosa-si/client/events"; use lib "/usr/lib/gosa-si/client/events"; my ($cfg_file, %cfg_defaults, $foreground, $verbose, $pid_file, $procid, $pid, $log_file); -my ($server_ip, $server_port, $server_key, $server_timeout, $server_domain); +my ($server_ip, $server_port, $server_key, $server_timeout, $server_domain, $server_key_lifetime); my ($client_ip, $client_port, $client_mac_address, $ldap_enabled, $ldap_config, $pam_config, $nss_config); my $xml; my $default_server_key; @@ -72,7 +65,7 @@ our $REGISTERED_FLAG = 1; "client" => {"client_port" => [\$client_port, "20083"], "client_ip" => [\$client_ip, "0.0.0.0"], - "client_mac_address" => [\$client_mac_address, "00:00:00:00:00:00:00"], + "client_mac_address" => [\$client_mac_address, "00:00:00:00:00:00"], "ldap" => [\$ldap_enabled, 1], "ldap_config" => [\$ldap_config, "/etc/ldap/ldap.conf"], "pam_config" => [\$pam_config, "/etc/pam_ldap.conf"], @@ -84,6 +77,7 @@ our $REGISTERED_FLAG = 1; "server_key" => [\$server_key, ""], "server_timeout" => [\$server_timeout, 10], "server_domain" => [\$server_domain, ""], + "server_key_lifetime" => [\$server_key_lifetime, 600], }, ); @@ -217,7 +211,7 @@ sub daemon_log { $hours = $hours < 10 ? $hours = "0".$hours : $hours; $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes; $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds; - my @monthnames = ("Jan", "Feb", "Mar", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); + my @monthnames = ("Jan", "Feb", "Mar", "Apr", "May", "Jun", "Jul", "Aug", "Sep", "Oct", "Nov", "Dec"); $month = $monthnames[$month]; $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday; $year+=1900; @@ -289,7 +283,7 @@ sub get_mac { if(defined($server_ip)) { $result = &get_local_mac_for_remote_ip($server_ip); } - elsif ($client_mac_address && length($client_mac_address) > 0){ + elsif ($client_mac_address && length($client_mac_address) > 0 && !($client_mac_address eq "00:00:00:00:00:00")){ $result = &client_mac_address; } else { @@ -299,7 +293,7 @@ sub get_mac { my $SIOCGIFHWADDR= 0x8927; # man 2 ioctl_list # A configured MAC Address should always override a guessed value - if ($client_mac_address and length($client_mac_address) > 0) { + if ($client_mac_address and length($client_mac_address) > 0 and not($client_mac_address eq "00:00:00:00:00:00")) { $result= $client_mac_address; } else { @@ -386,40 +380,83 @@ sub get_ip { # matches (defaultroute last). #=============================================================================== sub get_local_mac_for_remote_ip { - my $ifreq= shift; - my $result= "00:00:00:00:00:00"; - 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($server_ip)->within(new NetAddr::IP($destination, $mask))) { - # destination matches route, save mac and exit - $result= &get_mac($Iface); - last; - } - } + my $server_ip= shift; + my $result= "00:00:00:00:00:00"; + + if($server_ip =~ /^(\d\d?\d?\.){3}\d\d?\d?$/) { + 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($server_ip)->within(new NetAddr::IP($destination, $mask))) { + # destination matches route, save mac and exit + $result= &get_mac($Iface); + last; + } + } + } else { + daemon_log("get_local_mac_for_remote_ip was called with a non-ip parameter: $server_ip", 1); + } + return $result; +} +sub get_local_ip_for_remote_ip { + my $server_ip= shift; + my $result="0.0.0.0"; - return $result; + if($server_ip =~ /^(\d\d?\d?\.){3}\d\d?\d?$/) { + if($server_ip eq "127.0.0.1") { + $result="127.0.0.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($server_ip)->within(new NetAddr::IP($destination, $mask))) { + # destination matches route, save mac and exit + $result= &get_ip($Iface); + last; + } + } + } + } else { + daemon_log("get_local_ip_for_remote_ip was called with a non-ip parameter: $server_ip", 1); + } + return $result; } - sub new_ldap_config { my ($msg_hash) = @_ ; my $element; @@ -583,33 +620,62 @@ sub create_passwd { sub get_server_addresses { my $domain= shift; my @result; - my $dig_cmd= 'dig +nocomments srv _gosad._tcp.'.$domain; - - my $output= `$dig_cmd 2>&1`; - open (PIPE, "$dig_cmd 2>&1 |"); - while() { - chomp $_; - # If it's not a comment - if($_ =~ m/^[^;]/) { - my @matches= split /\s+/; - - # Push hostname with port - if($matches[3] eq 'SRV') { - push @result, $matches[7].':'.$matches[6]; - } elsif ($matches[3] eq 'A') { - my $i=0; - - # Substitute the hostname with the ip address of the matching A record - foreach my $host (@result) { - if ((split /\:/, $host)[0] eq $matches[0]) { - $result[$i]= $matches[4].':'.(split /\:/, $host)[1]; - } - $i++; + + my $error = 0; + my $res = Net::DNS::Resolver->new; + my $query = $res->send("_gosad._tcp.".$domain, "SRV"); + my @hits; + + if ($query) { + foreach my $rr ($query->answer) { + push(@hits, $rr->target.":".$rr->port); + } + } + else { + #warn "query failed: ", $res->errorstring, "\n"; + $error++; + } + + if( $error == 0 ) { + foreach my $hit (@hits) { + my ($hit_name, $hit_port) = split(/:/, $hit); + + my $address_query = $res->send($hit_name); + if( 1 == length($address_query->answer) ) { + foreach my $rr ($address_query->answer) { + push(@result, $rr->address.":".$hit_port); } } } } - close(PIPE); + +# my $dig_cmd= 'dig +nocomments srv _gosad._tcp.'.$domain; +# +# my $output= `$dig_cmd 2>&1`; +# open (PIPE, "$dig_cmd 2>&1 |"); +# while() { +# chomp $_; +# # If it's not a comment +# if($_ =~ m/^[^;]/) { +# my @matches= split /\s+/; +# +# # Push hostname with port +# if($matches[3] eq 'SRV') { +# push @result, $matches[7].':'.$matches[6]; +# } elsif ($matches[3] eq 'A') { +# my $i=0; +# +# # Substitute the hostname with the ip address of the matching A record +# foreach my $host (@result) { +# if ((split /\:/, $host)[0] eq $matches[0]) { +# $result[$i]= $matches[4].':'.(split /\:/, $host)[1]; +# } +# $i++; +# } +# } +# } +# } +# close(PIPE); return @result; } @@ -792,18 +858,27 @@ sub register_at_gosa_si_server { } # create registration msg - my $register_hash = &create_xml_hash("here_i_am", $client_address, $server); + my $register_hash = &create_xml_hash("here_i_am", &get_local_ip_for_remote_ip(sprintf("%s", $server =~ /^([0-9\.]*?):.*$/)).":".$client_port, $server); &add_content2xml_hash($register_hash, "new_passwd", $server_key); - &add_content2xml_hash($register_hash, "mac_address", $client_mac_address); + &add_content2xml_hash($register_hash, "mac_address", &get_local_mac_for_remote_ip(sprintf("%s", $server =~ /^([0-9\.]*?):.*$/))); &add_content2xml_hash($register_hash, "events", $events); &add_content2xml_hash($register_hash, "gotoHardwareChecksum", $gotoHardwareChecksum); # send xml hash to server with general server passwd my $res = &send_msg_hash2address($register_hash, $server, $default_server_key); - last; + if($res == 0) { + # Set fixed client address + $client_ip= &get_local_ip_for_remote_ip(sprintf("%s", $server =~ /^([0-9\.]*?):.*$/)); + $client_address= "$client_ip:$client_port"; + last; + } else { + next; + } } daemon_log("waiting for msg 'register_at_gosa_si_server'",1); - $kernel->delay_set('register_at_gosa_si_server',2); + $kernel->delay_set('register_at_gosa_si_server',180); + # clear old settings and set it again + $kernel->delay_set('trigger_new_key', $server_key_lifetime); } return; } @@ -889,9 +964,26 @@ sub import_events { } } +sub trigger_new_key { + my ($kernel) = $_[KERNEL] ; + + my $msg = "
new_key
$client_address$client_address
"; + &send_msg_to_target($msg, $client_address, $server_key, 'new_key'); + + $kernel->delay_set('trigger_new_key', $server_key_lifetime); + +} + + +sub _start { + my ($kernel) = $_[KERNEL]; + $kernel->alias_set('client_session'); + $kernel->yield('register_at_gosa_si_server'); +} + sub server_input { - my ($heap,$input,$wheel) = @_[HEAP, ARG0, ARG1]; + my ($kernel, $heap, $input, $wheel) = @_[KERNEL, HEAP, ARG0, ARG1]; my $error = 0; my $answer; @@ -920,11 +1012,20 @@ sub server_input { ######## # answer if( $answer ) { + # preprocessing if( $answer =~ "
registered
") { + # set registered flag to true to stop sending further registered msgs $REGISTERED_FLAG = 0; } else { - &send_msg_to_address($answer, $server_address, $server_key); + &send_msg_to_target($answer, $server_address, $server_key); + } + # postprocessing + if( $answer =~ "
new_key
") { + # set new key to global variable + $answer =~ /(\S*?)<\/new_key>/; + my $new_key = $1; + $server_key = $new_key; } } @@ -1035,8 +1136,9 @@ daemon_log("found servers in configuration file and via DNS: $servers_string", 5 POE::Session->create( inline_states => { - _start => \®ister_at_gosa_si_server , + _start => \&_start, register_at_gosa_si_server => \®ister_at_gosa_si_server, + trigger_new_key => \&trigger_new_key, } );