Code

Fixed grey out for proxy setting, when in multiple edit
[gosa.git] / gosa-si / modules / GosaSupportDaemon.pm
1 package GosaSupportDaemon;
3 use Exporter;
4 @ISA = qw(Exporter);
5 @EXPORT = qw(create_xml_hash send_msg_hash2address get_content_from_xml_hash add_content2xml_hash create_xml_string encrypt_msg decrypt_msg create_ciphering transform_msg2hash); 
7 use strict;
8 use warnings;
9 use IO::Socket::INET;
10 use Crypt::Rijndael;
11 use Digest::MD5  qw(md5 md5_hex md5_base64);
12 use MIME::Base64;
13 use XML::Simple;
16 BEGIN {}
18 END {}
20 ### Start ######################################################################
22 my $xml = new XML::Simple();
25 sub process_incoming_msg {
26     return;
27 }
29 sub daemon_log {
30     my ($msg, $level) = @_ ;
31     &main::daemon_log($msg, $level);
32     return;
33 }
36 ##===  FUNCTION  ================================================================
37 ##         NAME:  logging
38 ##   PARAMETERS:  level - string - default 'info'
39 ##                msg - string -
40 ##                facility - string - default 'LOG_DAEMON'
41 ##      RETURNS:  nothing
42 ##  DESCRIPTION:  function for logging
43 ##===============================================================================
44 #my $log_file = $main::log_file;
45 #my $verbose = $main::verbose;
46 #my $foreground = $main::forground;
47 #sub daemon_log {
48 #    # log into log_file
49 #    my( $msg, $level ) = @_;
50 #    if(not defined $msg) { return }
51 #    if(not defined $level) { $level = 1 }
52 #    if(defined $log_file){
53 #        open(LOG_HANDLE, ">>$log_file");
54 #        if(not defined open( LOG_HANDLE, ">>$log_file" )) {
55 #            print STDERR "cannot open $log_file: $!";
56 #            return }
57 #            chomp($msg);
58 #            if($level <= $verbose){
59 #                print LOG_HANDLE "$level $msg\n";
60 #                if(defined $foreground) { print $msg."\n" }
61 #            }
62 #    }
63 #    close( LOG_HANDLE );
64 ##log into syslog
65 ##    my ($msg, $level, $facility) = @_;
66 ##    if(not defined $msg) {return}
67 ##    if(not defined $level) {$level = "info"}
68 ##    if(not defined $facility) {$facility = "LOG_DAEMON"}
69 ##    openlog($0, "pid,cons,", $facility);
70 ##    syslog($level, $msg);
71 ##    closelog;
72 ##    return;
73 #}
76 #===  FUNCTION  ================================================================
77 #         NAME:  create_xml_hash
78 #   PARAMETERS:  header - string - message header (required)
79 #                source - string - where the message come from (required)
80 #                target - string - where the message should go to (required)
81 #                [header_value] - string - something usefull (optional)
82 #      RETURNS:  hash - hash - nomen est omen
83 #  DESCRIPTION:  creates a key-value hash, all values are stored in a array
84 #===============================================================================
85 sub create_xml_hash {
86     my ($header, $source, $target, $header_value) = @_;
87     my $hash = {
88             header => [$header],
89             source => [$source],
90             target => [$target],
91             $header => [$header_value],
92     };
93     #daemon_log("create_xml_hash:", 7),
94     #chomp(my $tmp = Dumper $hash);
95     #daemon_log("\t$tmp", 7);
96     return $hash
97 }
100 sub transform_msg2hash {
101     my ($msg) = @_ ;
102     
103     my $hash = $xml->XMLin($msg, ForceArray=>1);
104     return $hash;
108 #===  FUNCTION  ================================================================
109 #         NAME:  send_msg_hash2address
110 #   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
111 #                PeerAddr string - socket address to send msg
112 #                PeerPort string - socket port, if not included in socket address
113 #      RETURNS:  nothing
114 #  DESCRIPTION:  ????
115 #===============================================================================
116 sub send_msg_hash2address {
117     my ($msg_hash, $address, $passwd) = @_ ;
119     # fetch header for logging
120     my $header = @{$msg_hash->{header}}[0];  
122     # generate xml string
123     my $msg_xml = &create_xml_string($msg_hash);
124     
125     # fetch the appropriated passwd from hash 
126     if(not defined $passwd) {
127         if(exists $main::known_daemons->{$address}) {
128             $passwd = $main::known_daemons->{$address}->{passwd};
129         } elsif(exists $main::known_clients->{$address}) {
130             $passwd = $main::known_clients->{$address}->{passwd};
131             
132         } else {
133             daemon_log("$address not known, neither as server nor as client", 1);
134             return 1;
135         }
136     }
137     
138     # create ciphering object
139     my $act_cipher = &create_ciphering($passwd);
140     
141     # encrypt xml msg
142     my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
143     
144     # opensocket
145     my $socket = &open_socket($address);
146     if(not defined $socket){
147         daemon_log("cannot send '$header'-msg to $address , server not reachable",
148                     5);
150         if (exists $main::known_clients->{$address}) {
151             if ($main::known_clients->{$address}->{status} eq "down") {
152                 # if status of not reachable client is already 'down', 
153                 # then delete client from known_clients
154                 &clean_up_known_clients($address);
156             } else {
157                 # update status to 'down'
158                 &update_known_clients(hostname=>$address, status=>"down");        
160             }
161         }
162         return 1;
163     }
164     
165     # send xml msg
166     print $socket $crypted_msg."\n";
167     
168     close $socket;
170     daemon_log("send '$header'-msg to $address", 1);
172     daemon_log("$msg_xml", 5);
174     #daemon_log("crypted message:",7);
175     #daemon_log("\t$crypted_msg", 7);
177     # update status of client in known_clients with last send msg
178     if(exists $main::known_daemons->{$address}) {
179         #&update_known_daemons();
180     } elsif(exists $main::known_clients->{$address}) {
181         &main::update_known_clients(hostname=>$address, status=>$header);
182     }
184     return 0;
188 #===  FUNCTION  ================================================================
189 #         NAME:  get_content_from_xml_hash
190 #   PARAMETERS:  xml_ref - ref - reference of the xml hash
191 #                element - string - key of the value you want
192 #      RETURNS:  value - string - if key is either header, target or source
193 #                value - list - for all other keys in xml hash
194 #  DESCRIPTION:
195 #===============================================================================
196 sub get_content_from_xml_hash {
197     my ($xml_ref, $element) = @_ ;
198     #my $result = $main::xml_ref->{$element};
199     #if( $element eq "header" || $element eq "target" || $element eq "source") {
200     #    return @$result[0];
201     #}
202     my @result = $xml_ref->{$element};
203     return \@result;
207 #===  FUNCTION  ================================================================
208 #         NAME:  add_content2xml_hash
209 #   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
210 #                element - string - key for the hash
211 #                content - string - value for the hash
212 #      RETURNS:  nothing
213 #  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, 
214 #                then append value to list
215 #===============================================================================
216 sub add_content2xml_hash {
217     my ($xml_ref, $element, $content) = @_;
218     if(not exists $$xml_ref{$element} ) {
219         $$xml_ref{$element} = [];
220     }
221     my $tmp = $$xml_ref{$element};
222     push(@$tmp, $content);
223     return;
227 #===  FUNCTION  ================================================================
228 #         NAME:  create_xml_string
229 #   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
230 #      RETURNS:  xml_string - string - xml string representation of the hash
231 #  DESCRIPTION:  transform the hash to a string using XML::Simple module
232 #===============================================================================
233 sub create_xml_string {
234     my ($xml_hash) = @_ ;
235     my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
236     $xml_string =~ s/[\n]+//g;
237     #daemon_log("create_xml_string:",7);
238     #daemon_log("$xml_string\n", 7);
239     return $xml_string;
243 #===  FUNCTION  ================================================================
244 #         NAME:  encrypt_msg
245 #   PARAMETERS:  msg - string - message to encrypt
246 #                my_cipher - ref - reference to a Crypt::Rijndael object
247 #      RETURNS:  crypted_msg - string - crypted message
248 #  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
249 #===============================================================================
250 sub encrypt_msg {
251     my ($msg, $my_cipher) = @_;
252     if(not defined $my_cipher) { print "no cipher object\n"; }
253     $msg = "\0"x(16-length($msg)%16).$msg;
254     my $crypted_msg = $my_cipher->encrypt($msg);
255     chomp($crypted_msg = &encode_base64($crypted_msg));
256     return $crypted_msg;
260 #===  FUNCTION  ================================================================
261 #         NAME:  decrypt_msg
262 #   PARAMETERS:  crypted_msg - string - message to decrypt
263 #                my_cipher - ref - reference to a Crypt::Rijndael object
264 #      RETURNS:  msg - string - decrypted message
265 #  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
266 #===============================================================================
267 sub decrypt_msg {
268     my ($crypted_msg, $my_cipher) = @_ ;
269     $crypted_msg = &decode_base64($crypted_msg);
270     my $msg = $my_cipher->decrypt($crypted_msg); 
271     $msg =~ s/\0*//g;
272     return $msg;
276 #===  FUNCTION  ================================================================
277 #         NAME:  create_ciphering
278 #   PARAMETERS:  passwd - string - used to create ciphering
279 #      RETURNS:  cipher - object
280 #  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
281 #===============================================================================
282 sub create_ciphering {
283     my ($passwd) = @_;
284     $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
285     my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
287     #daemon_log("iv: $iv", 7);
288     #daemon_log("key: $passwd", 7);
289     my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
290     $my_cipher->set_iv($iv);
291     return $my_cipher;
295 #===  FUNCTION  ================================================================
296 #         NAME:  open_socket
297 #   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
298 #                [PeerPort] string necessary if port not appended by PeerAddr
299 #      RETURNS:  socket IO::Socket::INET
300 #  DESCRIPTION:  open a socket to PeerAddr
301 #===============================================================================
302 sub open_socket {
303     my ($PeerAddr, $PeerPort) = @_ ;
304     if(defined($PeerPort)){
305         $PeerAddr = $PeerAddr.":".$PeerPort;
306     }
307     my $socket;
308     $socket = new IO::Socket::INET(PeerAddr => $PeerAddr,
309             Porto => "tcp",
310             Type => SOCK_STREAM,
311             Timeout => 5,
312             );
313     if(not defined $socket) {
314         return;
315     }
316     &daemon_log("open_socket:", 7);
317     &daemon_log("\t$PeerAddr", 7);
318     return $socket;