diff --git a/gosa-si/gosa-si-bus b/gosa-si/gosa-si-bus
index c37d14b7eb0dbde7c0e699c85f3cfc8dac1d212e..f1da0ba054484b770c43b024289afa80ddc9f4cc 100755 (executable)
--- a/gosa-si/gosa-si-bus
+++ b/gosa-si/gosa-si-bus
use POE qw(Component::Server::TCP);
use Data::Dumper;
use Crypt::Rijndael;
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 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 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;
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" => {
$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"],
"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 =====================================================
);
#=== FUNCTIONS = functions =====================================================
#===============================================================================
sub usage {
print STDERR << "EOF" ;
#===============================================================================
sub usage {
print STDERR << "EOF" ;
-usage: $0 [-hvf] [-c config]
+usage: $prg [-hvf] [-c config]
-h : this (help) message
-c <file> : config file
-h : this (help) message
-c <file> : config file
$month = $monthnames[$month];
$monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
$year+=1900;
$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;
print LOG_HANDLE $log_msg;
if( $foreground ) {
print STDERR $log_msg;
return $result;
}
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
#=== FUNCTION ================================================================
# NAME: create_passwd
sub create_ciphering {
my ($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());
$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());
sub encrypt_msg {
my ($msg, $key) = @_;
my $my_cipher = &create_ciphering($key);
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
$msg = $my_cipher->encrypt($msg);
chomp($msg = &encode_base64($msg));
# there are no newlines allowed inside msg
sub decrypt_msg {
sub decrypt_msg {
+
my ($msg, $key) = @_ ;
$msg = &decode_base64($msg);
my $my_cipher = &create_ciphering($key);
my ($msg, $key) = @_ ;
$msg = &decode_base64($msg);
my $my_cipher = &create_ciphering($key);
sub send_msg_to_target {
my ($msg, $address, $encrypt_key, $msg_header) = @_ ;
my $error = 0;
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 ) {
if( $msg_header ) {
- $msg_header = "'$msg_header'-";
+ $header = "'$msg_header'-";
}
else {
}
else {
- $msg_header = "";
+ $header = "";
}
# encrypt xml msg
}
# encrypt xml msg
# opensocket
my $socket = &open_socket($address);
if( !$socket ) {
# 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++;
}
$error++;
}
# send xml msg
print $socket $crypted_msg."\n";
# 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);
}
daemon_log("message:\n$msg", 8);
}
close $socket;
}
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;
}
return;
}
my $source = @{$msg_hash->{'source'}}[0];
my $header = @{$msg_hash->{header}}[0];
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
# 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
$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) {
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
# 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
}
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='$target'";
my $query_res = $bus_known_clients_db->select_dbentry( $sql_statement );
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<\/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 {
}
else {
-
+ daemon_log("ERROR: target address '$target' does not match neiter ".
+ "to ip address nor to mac address, can not send msg", 1);
}
}
}
}
timestamp=>$act_timestamp,
};
$bus_known_clients_db->add_dbentry($add_hash);
timestamp=>$act_timestamp,
};
$bus_known_clients_db->add_dbentry($add_hash);
+ daemon_log("add new client '$new_client' to bus_known_clients_db", 3);
}
}
_start => \&_start,
_default => \&_default,
here_i_am => \&here_i_am,
_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,
}
);
new_client => \&new_client,
}
);