Code

Updated socket class
[gosa.git] / gosa-si / modules / GosaSupportDaemon.pm
1 package GOSA::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 get_time send_msg); 
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;
17 BEGIN {}
19 END {}
21 ### Start ######################################################################
23 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:  create_xml_hash
38 #   PARAMETERS:  header - string - message header (required)
39 #                source - string - where the message come from (required)
40 #                target - string - where the message should go to (required)
41 #                [header_value] - string - something usefull (optional)
42 #      RETURNS:  hash - hash - nomen est omen
43 #  DESCRIPTION:  creates a key-value hash, all values are stored in a array
44 #===============================================================================
45 sub create_xml_hash {
46     my ($header, $source, $target, $header_value) = @_;
47     my $hash = {
48             header => [$header],
49             source => [$source],
50             target => [$target],
51             $header => [$header_value],
52     };
53     return $hash
54 }
57 sub transform_msg2hash {
58     my ($msg) = @_ ;
59     my $hash = $xml->XMLin($msg, ForceArray=>1);
60     
61     # xml tags without a content are created as an empty hash
62     # substitute it with an empty list
63     while( my ($xml_tag, $xml_content) = each %{ $hash } ) {
64         if( 1 == @{ $xml_content } ) {
65             # there is only one element in xml_content list ...
66             my $element = @{ $xml_content }[0];
67             if( ref($element) eq "HASH" ) {
68                 # and this element is an hash ...
69                 my $len_element = keys %{ $element };
70                 if( $len_element == 0 ) {
71                     # and this hash is empty, then substitute the xml_content
72                     # with an empty string in list
73                     $hash->{$xml_tag} = [ "none" ];
74                 }
75             }
76         }
77     }
79     return $hash;
80 }
83 #===  FUNCTION  ================================================================
84 #         NAME:  send_msg_hash2address
85 #   PARAMETERS:  msg_hash - hash - xml_hash created with function create_xml_hash
86 #                PeerAddr string - socket address to send msg
87 #                PeerPort string - socket port, if not included in socket address
88 #      RETURNS:  nothing
89 #  DESCRIPTION:  ????
90 #===============================================================================
91 sub send_msg_hash2address ($$$){
92     my ($msg_hash, $address, $passwd) = @_ ;
94     # fetch header for logging
95     my $header = @{$msg_hash->{header}}[0];  
97     # generate xml string
98     my $msg_xml = &create_xml_string($msg_hash);
99     
100     # create ciphering object
101     my $act_cipher = &create_ciphering($passwd);
102     
103     # encrypt xml msg
104     my $crypted_msg = &encrypt_msg($msg_xml, $act_cipher);
105     
106     # opensocket
107     my $socket = &open_socket($address);
108     if(not defined $socket){
109         daemon_log("cannot send '$header'-msg to $address , server not reachable", 5);
110         return 1;
111     }
112     
113     # send xml msg
114     print $socket $crypted_msg."\n";
115     
116     close $socket;
118     daemon_log("send '$header'-msg to $address", 1);
119     daemon_log("message:\n$msg_xml", 8);
120     return 0;
124 #===  FUNCTION  ================================================================
125 #         NAME:  get_content_from_xml_hash
126 #   PARAMETERS:  xml_ref - ref - reference of the xml hash
127 #                element - string - key of the value you want
128 #      RETURNS:  value - string - if key is either header, target or source
129 #                value - list - for all other keys in xml hash
130 #  DESCRIPTION:
131 #===============================================================================
132 sub get_content_from_xml_hash {
133     my ($xml_ref, $element) = @_ ;
134     #my $result = $main::xml_ref->{$element};
135     #if( $element eq "header" || $element eq "target" || $element eq "source") {
136     #    return @$result[0];
137     #}
138     my @result = $xml_ref->{$element};
139     return \@result;
143 #===  FUNCTION  ================================================================
144 #         NAME:  add_content2xml_hash
145 #   PARAMETERS:  xml_ref - ref - reference to a hash from function create_xml_hash
146 #                element - string - key for the hash
147 #                content - string - value for the hash
148 #      RETURNS:  nothing
149 #  DESCRIPTION:  add key-value pair to xml_ref, if key alread exists, 
150 #                then append value to list
151 #===============================================================================
152 sub add_content2xml_hash {
153     my ($xml_ref, $element, $content) = @_;
154     if(not exists $$xml_ref{$element} ) {
155         $$xml_ref{$element} = [];
156     }
157     my $tmp = $$xml_ref{$element};
158     push(@$tmp, $content);
159     return;
163 #===  FUNCTION  ================================================================
164 #         NAME:  create_xml_string
165 #   PARAMETERS:  xml_hash - hash - hash from function create_xml_hash
166 #      RETURNS:  xml_string - string - xml string representation of the hash
167 #  DESCRIPTION:  transform the hash to a string using XML::Simple module
168 #===============================================================================
169 sub create_xml_string {
170     my ($xml_hash) = @_ ;
171     my $xml_string = $xml->XMLout($xml_hash, RootName => 'xml');
172     #$xml_string =~ s/[\n]+//g;
173     #daemon_log("create_xml_string:",7);
174     #daemon_log("$xml_string\n", 7);
175     return $xml_string;
179 #===  FUNCTION  ================================================================
180 #         NAME:  encrypt_msg
181 #   PARAMETERS:  msg - string - message to encrypt
182 #                my_cipher - ref - reference to a Crypt::Rijndael object
183 #      RETURNS:  crypted_msg - string - crypted message
184 #  DESCRIPTION:  crypts the incoming message with the Crypt::Rijndael module
185 #===============================================================================
186 sub encrypt_msg {
187     my ($msg, $my_cipher) = @_;
188     if(not defined $my_cipher) { print "no cipher object\n"; }
189     $msg = "\0"x(16-length($msg)%16).$msg;
190     $msg = $my_cipher->encrypt($msg);
191     chomp($msg = &encode_base64($msg));
192     return $msg;
196 #===  FUNCTION  ================================================================
197 #         NAME:  decrypt_msg
198 #   PARAMETERS:  crypted_msg - string - message to decrypt
199 #                my_cipher - ref - reference to a Crypt::Rijndael object
200 #      RETURNS:  msg - string - decrypted message
201 #  DESCRIPTION:  decrypts the incoming message with the Crypt::Rijndael module
202 #===============================================================================
203 sub decrypt_msg {
204     my ($msg, $my_cipher) = @_ ;
205     if(defined $msg && defined $my_cipher) {
206         $msg = &decode_base64($msg);
207     }
208     $msg = $my_cipher->decrypt($msg); 
209     $msg =~ s/\0*//g;
210     return $msg;
214 #===  FUNCTION  ================================================================
215 #         NAME:  create_ciphering
216 #   PARAMETERS:  passwd - string - used to create ciphering
217 #      RETURNS:  cipher - object
218 #  DESCRIPTION:  creates a Crypt::Rijndael::MODE_CBC object with passwd as key
219 #===============================================================================
220 sub create_ciphering {
221     my ($passwd) = @_;
222     $passwd = substr(md5_hex("$passwd") x 32, 0, 32);
223     my $iv = substr(md5_hex('GONICUS GmbH'),0, 16);
225     #daemon_log("iv: $iv", 7);
226     #daemon_log("key: $passwd", 7);
227     my $my_cipher = Crypt::Rijndael->new($passwd , Crypt::Rijndael::MODE_CBC());
228     $my_cipher->set_iv($iv);
229     return $my_cipher;
233 #===  FUNCTION  ================================================================
234 #         NAME:  open_socket
235 #   PARAMETERS:  PeerAddr string something like 192.168.1.1 or 192.168.1.1:10000
236 #                [PeerPort] string necessary if port not appended by PeerAddr
237 #      RETURNS:  socket IO::Socket::INET
238 #  DESCRIPTION:  open a socket to PeerAddr
239 #===============================================================================
240 sub open_socket {
241     my ($PeerAddr, $PeerPort) = @_ ;
242     if(defined($PeerPort)){
243         $PeerAddr = $PeerAddr.":".$PeerPort;
244     }
245     my $socket;
246     $socket = new IO::Socket::INET(PeerAddr => $PeerAddr,
247             Porto => "tcp",
248             Type => SOCK_STREAM,
249             Timeout => 5,
250             );
251     if(not defined $socket) {
252         return;
253     }
254     &daemon_log("open_socket: $PeerAddr", 7);
255     return $socket;
259 sub get_time {
260     my ($seconds, $minutes, $hours, $monthday, $month,
261             $year, $weekday, $yearday, $sommertime) = localtime(time);
262     $hours = $hours < 10 ? $hours = "0".$hours : $hours;
263     $minutes = $minutes < 10 ? $minutes = "0".$minutes : $minutes;
264     $seconds = $seconds < 10 ? $seconds = "0".$seconds : $seconds;
265     $month+=1;
266     $month = $month < 10 ? $month = "0".$month : $month;
267     $monthday = $monthday < 10 ? $monthday = "0".$monthday : $monthday;
268     $year+=1900;
269     return "$year$month$monthday$hours$minutes$seconds";
274 #===  FUNCTION  ================================================================
275 #         NAME: send_msg
276 #  DESCRIPTION: Send a message to a destination
277 #   PARAMETERS: [header] Name of the header
278 #               [from]   sender ip
279 #               [to]     recipient ip
280 #               [data]   Hash containing additional attributes for the xml
281 #                        package
282 #      RETURNS:  nothing
283 #===============================================================================
284 sub send_msg ($$$$$) {
285         my ($header, $from, $to, $data, $hostkey) = @_;
287         my $out_hash = &create_xml_hash($header, $from, $to);
289         while ( my ($key, $value) = each(%$data) ) {
290                 if(ref($value) eq 'ARRAY'){
291                         map(&add_content2xml_hash($out_hash, $key, $_), @$value);
292                 } else {
293                         &add_content2xml_hash($out_hash, $key, $value);
294                 }
295         }
297         &send_msg_hash2address($out_hash, $to, $hostkey);
300 1;