First integration of imspector, some more work to do.
authorChristian Schmidt <christian.schmidt@ipfire.org>
Sat, 28 Aug 2010 06:38:10 +0000 (08:38 +0200)
committerChristian Schmidt <christian.schmidt@ipfire.org>
Sat, 28 Aug 2010 06:38:10 +0000 (08:38 +0200)
config/backup/includes/imspector [new file with mode: 0644]
config/imspector/imspector.conf [new file with mode: 0644]
config/menu/EX-imspector.menu [new file with mode: 0644]
config/rootfiles/common/initscripts
config/rootfiles/packages/imspector [new file with mode: 0644]
doc/packages-list.txt
html/cgi-bin/imspector.cgi [new file with mode: 0644]
lfs/imspector [new file with mode: 0644]
lfs/initscripts
make.sh
src/initscripts/init.d/imspector [new file with mode: 0644]

diff --git a/config/backup/includes/imspector b/config/backup/includes/imspector
new file mode 100644 (file)
index 0000000..cc7ef16
--- /dev/null
@@ -0,0 +1,3 @@
+/etc/imspector/acl.txt
+/etc/imspector/badwords.txt
+/etc/imspector/imspector.conf
\ No newline at end of file
diff --git a/config/imspector/imspector.conf b/config/imspector/imspector.conf
new file mode 100644 (file)
index 0000000..a37241d
--- /dev/null
@@ -0,0 +1,24 @@
+# The listening port for redirected connections
+port=16667
+
+# For dropping privs - you probably want to do this.
+user=nobody
+group=nobody
+
+# Prefix and postfix to all responses using all responder plugins
+response_prefix=Message from IMSpector: -=
+response_postfix==-
+
+# Will load enabled plugins in plugin_dir
+icq_protocol=on
+irc_protocol=on
+msn_protocol=on
+yahoo_protocol=on
+gg_protocol=on
+jabber_protocol=on
+
+# Location where the file logging plugin will start from.
+file_logging_dir=/var/log/imspector/
+log_typing_events=on
+
+plugin_dir=/usr/lib/imspector
diff --git a/config/menu/EX-imspector.menu b/config/menu/EX-imspector.menu
new file mode 100644 (file)
index 0000000..c88866f
--- /dev/null
@@ -0,0 +1,5 @@
+    $subipfire->{'30.imspector'} = {'caption' => 'Imspector',
+                                 'uri' => '/cgi-bin/imspector.cgi',
+                                 'title' => 'Imspector',
+                                 'enabled' => 1,
+                                 };
index 180666f..87f4318 100644 (file)
@@ -33,6 +33,7 @@ etc/rc.d/init.d/functions
 etc/rc.d/init.d/halt
 #etc/rc.d/init.d/hostapd
 #etc/rc.d/init.d/icecream
+#etc/rc.d/init.d/imspector
 #etc/rc.d/init.d/ipfireseeder
 etc/rc.d/init.d/ipsec
 #etc/rc.d/init.d/lcd4linux
diff --git a/config/rootfiles/packages/imspector b/config/rootfiles/packages/imspector
new file mode 100644 (file)
index 0000000..0cd6ee8
--- /dev/null
@@ -0,0 +1,27 @@
+etc/imspector
+#etc/imspector/acl.txt
+#etc/imspector/badwords.txt
+#etc/imspector/imspector.conf
+usr/lib/imspector
+usr/lib/imspector/aclfilterplugin.so
+usr/lib/imspector/badwordsfilterplugin.so
+usr/lib/imspector/catsloggingplugin.so
+usr/lib/imspector/censordfilterplugin.so
+usr/lib/imspector/debugloggingplugin.so
+usr/lib/imspector/fileloggingplugin.so
+usr/lib/imspector/ggprotocolplugin.so
+usr/lib/imspector/httpsprotocolplugin.so
+usr/lib/imspector/icqprotocolplugin.so
+usr/lib/imspector/ircprotocolplugin.so
+usr/lib/imspector/jabberprotocolplugin.so
+usr/lib/imspector/miscfilterplugin.so
+usr/lib/imspector/msnprotocolplugin.so
+usr/lib/imspector/yahooprotocolplugin.so
+usr/lib/libimspector.so
+usr/sbin/imspector
+var/ipfire/backup/addons/includes/imspector
+var/lib/imspector
+var/log/imspector
+etc/rc.d/init.d/imspector
+srv/web/ipfire/cgi-bin/imspector.cgi
+var/ipfire/menu.d/EX-imspector.menu
index 1f60b70..c8dbc2e 100644 (file)
 * icegenerator-0.5.5-pre2
 * iftop-0.17
 * igmpproxy-0.1
+* imspector-0.9
 * inetutils-1.4.2
 * ipaddr-1.2
 * iperf-2.0.4
diff --git a/html/cgi-bin/imspector.cgi b/html/cgi-bin/imspector.cgi
new file mode 100644 (file)
index 0000000..7cc2e64
--- /dev/null
@@ -0,0 +1,607 @@
+#!/usr/bin/perl
+#
+# IMSpector real-time log viewer
+# (c) SmoothWall Ltd 2008
+#
+# Released under the GPL v2.
+
+use POSIX qw(strftime);
+
+# Common configuration parameters.
+
+my $logbase = "/var/log/imspector/";
+my $oururl = '/cgi-bin/imspector.cgi';
+
+# Colours
+
+my $protocol_colour     = '#06264d';
+my $local_colour        = '#1d398b';
+my $remote_colour       = '#2149c1';
+my $conversation_colour = '#335ebe';
+
+my $local_user_colour   = 'blue';
+my $remote_user_colour  = 'green';
+
+# No need to change anything from this point
+
+# Page declaration, The following code should parse the CGI headers, and render the page
+# accordingly... How you do this depends what environment you're in.
+
+my %cgiparams;
+
+print "Content-type: text/html\n";
+print "\n";
+
+if ($ENV{'QUERY_STRING'})
+{
+       my @vars = split('\&', $ENV{'QUERY_STRING'});
+       foreach $_ (@vars)
+       {
+               my ($var, $val) = split(/\=/);
+               $cgiparams{$var} = $val;
+       }
+}
+
+# Act in Tail mode (as in just generate the raw logs and pass back to the other CGI
+
+if ( defined $cgiparams{'mode'} and $cgiparams{'mode'} eq "render" ){
+       &parser( $cgiparams{'section'}, $cgiparams{'offset'}, $cgiparams{'conversation'}, $cgiparams{'skimhtml'} );
+       exit;
+}
+
+# Start rendering the Page using Express' rendering functions
+
+my $script = &scriptheader();
+
+# Print Some header information 
+
+print qq|
+<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
+<html>
+<head>
+       <title>IMSpector real-time log viewer</title>
+       $script
+</head>
+<body>
+|;
+
+print &pagebody();
+
+# and now finish off the HTML page.
+
+print qq|
+</body>
+</html>
+|;
+
+exit;
+
+# -----------------------------------------------------------------------------
+# ---------------------- IMSPector Log Viewer Code ----------------------------
+# -----------------------------------------------------------------------------
+#           ^"^                                                 ^"^
+
+# Scriptheader
+# ------------
+# Return the bulk of the page, which should reside in the pages <head> field
+
+sub scriptheader
+{
+       my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) = localtime( time() );
+       $year += 1900; $mon++;
+       my $conversation = sprintf( "%.4d-%.2d-%.2d", $year, $mon, $mday );
+
+       my $script = qq {
+<script language="Javascript">
+var section         ='none';
+var moveit          = 1;
+var skimhtml        = 1;
+var the_timeout;
+var offset          = 0;
+var fragment        = "";
+var conversationdate = "$conversation";
+
+function xmlhttpPost()
+{
+       var self = this;
+       
+       if (window.XMLHttpRequest) {
+               // Mozilla/Safari
+               self.xmlHttpReq = new XMLHttpRequest();
+       } else if (window.ActiveXObject) {
+               // IE
+               self.xmlHttpReq = new ActiveXObject("Microsoft.XMLHTTP");
+       }
+
+       var url = "$url" + "?mode=render&section=" + section + "&skimhtml=" + skimhtml + "&offset=" + offset + "&conversation=" + conversationdate;
+       self.xmlHttpReq.open('POST', url, true);
+       self.xmlHttpReq.setRequestHeader('Content-Type', 'application/x-www-form-urlencoded');
+
+       self.xmlHttpReq.onreadystatechange = function() {
+               if ( self.xmlHttpReq && self.xmlHttpReq.readyState == 4) {
+                       updatepage(self.xmlHttpReq.responseText);
+               }
+       }
+
+       document.getElementById('status').style.display = "inline";
+
+       self.xmlHttpReq.send( url );
+       delete self;
+}
+
+function updatepage(str){
+       /* update the list of conversations ( if we need to ) */
+
+       var parts = str.split( "--END--\\n" );
+
+       var lines = parts[0].split( "\\n" );
+
+       for ( var line = 0 ; line < lines.length ; line ++ ){
+               var a = lines[line].split("|");
+
+               if ( !a[1] || !a[2] || !a[3] ){
+                       continue;
+               }
+
+               /* convert the modification stamp into something sensible */
+               a[5] = parseInt( a[5] * 24 * 60 * 60 );
+
+               /* create titling information if needed */
+               if ( !document.getElementById( a[1] ) ){
+                       document.getElementById('conversations').innerHTML += "<div id='" + a[1] + "_t' style='width: 100%; background-color: #d9d9f3; color: $protocol_colour;'>" + a[1] + "</div><div id='" + a[1] + "' style='width: 100%; background-color: #e5e5f3;'></div>";
+               }
+
+               if ( !document.getElementById( a[1] + "_" + a[2] ) ){
+                       document.getElementById( a[1] ).innerHTML += "<div id='" + a[1] + "_" + a[2] + "_t' style='width: 100%; color: $local_colour; padding-left: 5px;'>" + a[2] + "</div><div id='" + a[1] + "_" + a[2] + "' style='width: 100%; background-color: #efeffa; border-bottom: solid 1px #d9d9f3;'></div>";
+               }
+
+               if ( !document.getElementById( a[1] + "_" + a[2] + "_" + a[3] ) ){
+                       document.getElementById( a[1] + "_" + a[2] ).innerHTML += "<div id='" + a[1] + "_" + a[2] + "_" + a[3] + "_t' style='width: 100%; color: $remote_colour; padding-left: 10px; cursor: pointer;' onClick=" + '"' + "setsection('" + a[1] + "|" + a[2] + "|" + a[3] + "|" + a[4] + "');" + '"' + "' + >&raquo;&nbsp;" + a[3] + "</div><div id='" + a[1] + "_" + a[2] + "_" + a[3] + "' style='width: 1%; display: none;'></div>";
+               }
+
+               if ( document.getElementById( a[1] + "_" + a[2] + "_" + a[3] ) && a[5] <= 60 ){
+                       /* modified within the last minute! */
+                       document.getElementById( a[1] + "_" + a[2] + "_" + a[3] + "_t" ).style.fontWeight = "bold";
+               } else {
+                       document.getElementById( a[1] + "_" + a[2] + "_" + a[3] + "_t" ).style.fontWeight = "normal";
+               }
+               delete a;
+       }
+
+       delete lines;
+
+       /* rework the list of active conversation dates ... */
+
+       var lines = parts[1].split( "\\n" );
+
+       var the_select = document.getElementById('conversationdates');
+       the_select.options.length = 0;
+               
+       for ( var line = 0 ; line < lines.length ; line ++ ){
+               if ( lines[ line ] != "" ){
+                       the_select.options.length ++;
+                       the_select.options[ line ].text  = lines[line];
+                       the_select.options[ line ].value = lines[line];
+                       if ( lines[line] == conversationdate ){
+                               the_select.selectedIndex = line;
+                       }
+               }
+       }
+
+       delete the_select;
+       delete lines;
+
+       /* determine the title of this conversation */
+       if ( parts[2] ){
+               var details = parts[2].split(",");
+               var title = details[0] + " conversation between <span style='color: $local_user_colour;'>" + details[ 1 ] + "</span> and <span style='color: $remote_user_colour;'>" + details[2] + "</span>";
+               if ( !details[1] ){
+                       title = "&nbsp;";
+               }
+
+               document.getElementById('status').style.display = "none";
+       
+               var bottom  = parseInt( document.getElementById('content').scrollTop );
+               var bottom2 = parseInt( document.getElementById('content').style.height );
+               var absheight = parseInt( bottom + bottom2 );
+
+               if ( absheight == document.getElementById('content').scrollHeight ){    
+                       moveit = 1;
+               }
+
+               fragment += parts[4];
+               document.getElementById('content').innerHTML = "<table style='width: 100%'>" + fragment + "</table>";
+               if (moveit == 1 ){
+                       document.getElementById('content').scrollTop = 0;
+                       document.getElementById('content').scrollTop = document.getElementById('content').scrollHeight;
+               }
+
+               document.getElementById('content_title').innerHTML = title;
+               delete details;
+               delete title;
+               delete bottom;
+               delete bottom2;
+               delete absheight;
+       }
+
+       /* set the file offset */
+       offset = parts[3];
+
+       if ( moveit == 1 ){
+               document.getElementById('scrlck').style.color = 'green';
+       } else {
+               document.getElementById('scrlck').style.color = '#202020';
+       }
+
+       if ( skimhtml == 1 ){
+               document.getElementById('skimhtml').style.color = 'green';
+       } else {
+               document.getElementById('skimhtml').style.color = '#202020';
+       }
+
+       delete parts;
+
+       the_timeout = setTimeout( "xmlhttpPost();", 5000 );
+}
+
+function setsection( value )
+{
+       section = value;
+       offset = 0;
+       fragment = "";
+       moveit = 1;
+       clearTimeout(the_timeout);
+       xmlhttpPost();
+       document.getElementById('content').scrollTop = 0;
+       document.getElementById('content').scrollTop = document.getElementById('content').scrollHeight;
+}
+
+function togglescrlck()
+{
+       if ( moveit == 1 ){
+               moveit = 0;
+               document.getElementById('scrlck').style.color = '#202020';
+       } else {
+               moveit = 1;
+               document.getElementById('scrlck').style.color = 'green';
+       }
+}
+
+function toggleskimhtml()
+{
+       if ( skimhtml == 1 ){
+               skimhtml = 0;
+               document.getElementById('skimhtml').style.color = '#202020';
+       } else {
+               skimhtml = 1;
+               document.getElementById('skimhtml').style.color = 'green';
+       }
+       clearTimeout(the_timeout);
+       xmlhttpPost();
+}
+
+function setDate()
+{
+       var the_select = document.getElementById('conversationdates');
+       conversationdate = the_select.options[ the_select.selectedIndex ].value;
+       document.getElementById('conversations').innerHTML = "";
+       fragment = "";
+       offset = 0;
+       section = "";
+       clearTimeout(the_timeout);
+       xmlhttpPost();
+}
+
+</script>
+       };
+
+       return $script;
+}
+
+# pagebody function 
+# -----------------
+# Return the HTML fragment which includes the page body.
+
+sub pagebody
+{
+       my $body = qq {
+       <div style='width: 100%; text-align: right;'><span id='status' style='background-color: #fef1b5; display: none;'>Updating</span>&nbsp;</div>
+       <style>
+       
+.powerbutton {
+       color:  #202020;
+       font-size: 9pt;
+       cursor: pointer;
+}
+
+.remoteuser {
+       color: $remote_user_colour;
+       font-size: 9pt;
+}
+
+.localuser {
+       color: $local_user_colour;
+       font-size: 9pt;
+}
+
+       </style>
+       <table style='width: 100%;'>
+               <tr>
+                       <td style='width: 170px; text-align: left; vertical-align: top; overflow: auto; font-size: 8pt; border: solid 1px #c0c0c0;'><div id='conversations' style='height: 400px; overflow: auto; font-size: 10px; overflow-x: hidden;'></div></td>
+                       <td style='border: solid 1px #c0c0c0;'>
+                               <div id='content_title' style='height: 20px; overflow: auto; vertical-align: top; background-color: #E6E8FA; border-bottom: solid 1px #c0c0c0;'></div>
+                               <div id='content' style='height: 376px; overflow: auto; vertical-align: bottom; border-bottom: solid 1px #c0c0c0; overflow-x: hidden;'></div>
+                               <div id='content_subtitle' style='height: 24px; overflow: auto; vertical-align: top; background-color: #E6E8FA; width: 100%; padding: 2px;'>
+                                       <div style='width: 60%; float: left;' id='statuswindow'>
+                                               For conversations on:&nbsp;
+                                               <select id='conversationdates' onChange='setDate()';>
+                                               </select>
+                                       </div>
+                                       <div style='width: 40%; text-align: right; float: right;'>
+                                               <span class='powerbutton' id='skimhtml' onClick='toggleskimhtml();'>[HTML]</span>
+                                               <span class='powerbutton' id='scrlck' onClick='togglescrlck();'>[SCROLL LOCK]</span>
+                                       </div>
+                               </div>
+                       </td>
+               </tr>
+       </table>
+       <script>xmlhttpPost();</script>
+       };
+       return $body;
+}
+
+# Parser function ...
+# ---------------
+# Retrieves the IMspector logs from their nestling place and displays them accordingly.
+
+sub parser
+{
+       my ( $section, $offset, $conversationdate, $skimhtml ) = @_;
+       # render the user list ...
+
+       chomp $offset;  
+
+       unless ( $offset =~ /^([\d]*)$/ ){
+               print STDERR "Illegal offset ($offset $1) resetting...\n";
+               $offset = 0;
+       }
+
+       # browse for the available protocols
+       unless ( opendir DIR, $logbase ){
+               exit;
+       }
+
+       my %conversationaldates;
+       my @protocols = grep {!/^\./} readdir(DIR);             
+
+       foreach my $protocol ( @protocols ){
+               unless ( opendir LUSER, "$logbase$protocol" ){
+                       next;
+               }
+       
+               my @localusers = grep {!/^\./} readdir(LUSER);          
+               foreach my $localuser ( @localusers ){
+                       unless ( opendir RUSER, "$logbase$protocol/$localuser/" ){
+                               next;
+                       }
+                       my @remoteusers = grep {!/^\./} readdir( RUSER );
+                       foreach my $remoteuser ( @remoteusers ){
+                               unless ( opendir CONVERSATIONS, "$logbase$protocol/$localuser/$remoteuser/" ){
+                                       next;
+                               }
+                               my @conversations = grep {!/^\./} readdir( CONVERSATIONS );
+                               foreach my $conversation ( @conversations ){
+                                       $conversationaldates{ $conversation } = $localuser;
+                               }
+
+                               closedir CONVERSATIONS;
+
+                               my ( $sec, $min, $hour, $mday, $mon, $year, $wday, $yday ) = localtime( time() );
+                               $year += 1900; $mon++;
+                               my $conversation = sprintf( "%.4d-%.2d-%.2d", $year, $mon, $mday );
+
+                               $conversation = $conversationdate if ( defined $conversationdate and $conversationdate ne "" );
+
+                               if ( -e "$logbase$protocol/$localuser/$remoteuser/$conversation" ){
+                                       my $modi = -M "$logbase$protocol/$localuser/$remoteuser/$conversation";
+                                       print "|$protocol|$localuser|$remoteuser|$conversation|$modi\n";
+                               }
+                       }
+                       closedir RUSER;
+               }
+               closedir LUSER;
+       }
+       closedir DIR;
+
+       print "--END--\n";
+
+       # display a list of conversational dates .. i.e. the dates which we have conversations on.
+       foreach my $key ( sort keys %conversationaldates ){
+               print "$key\n";
+       }
+       
+       print "--END--\n";
+
+
+       # now check the log file ...
+       
+       if ( $section ne "none" ){
+               my ( $protocol, $localuser, $remoteuser, $conversation ) = split /\|/, $section;
+               
+               print "$protocol, $localuser, $remoteuser, $conversation\n";
+               print "--END--\n";
+               
+               my $filename = "$logbase$protocol/$localuser/$remoteuser/$conversation";
+               
+               unless ( open(FD, "$filename" ) ){
+                       exit;
+               };
+
+               # perform some *reasonably* complicated file hopping and stuff of that ilk.
+               # it's not beyond reason that logs *could* be extremely large, so what we
+               # should do to speed up their processing is to jump to the end of the file,
+               # then backtrack a little (say a meg, which is a reasonably amount of logs)
+               # and parse from that point onwards.  This, *post* filtering might of course
+               # not leave us with the desired resolution for the tail.  If this is the case,
+               # we keep that array and jump back another meg and have another go, concatinating
+               # the logs as we go.... <wheh>
+
+               my $jumpback = 100000; # not quite a meg, but hey ho    
+               my $goneback = 0;
+               my $gonebacklimit = 1000000000;  # don't go back more than 100MB
+
+               # firstly jump to the end of the file.
+               seek( FD, 0, 2 );
+
+               my $log_position = tell( FD );
+               my $end = $log_position;
+               my $end_position = $log_position;
+
+               my $lines;
+               my @content;
+
+               my $TAILSIZE = 100;
+
+               do {
+                       $end_position = $log_position;
+
+                       if ( $offset != 0 ){
+                               # we were given a hint as to where we should have been anyhow ..
+                               # so we might as well use that to go back to.
+                               $log_position = $offset;
+                               $goneback = $end_position - $log_position;
+                       } else {
+                               $log_position -= $jumpback;
+                               $goneback += $jumpback;
+                       }
+
+                       last if ( $goneback > $gonebacklimit );
+
+                       if ( $log_position > 0 ){
+                               seek( FD, $log_position, 0 );
+                       } else {
+                               seek( FD, 0, 0 );
+                       }
+       
+                       my @newcontent;
+
+                       while ( my $line = <FD> and ( tell( FD ) <= $end_position ) ){
+                               chomp $line;
+                               push @content, $line;
+                       }
+                       shift @content if $#content >= $TAILSIZE;
+               } while ( $#content < $TAILSIZE and $log_position > 0 and $offset == 0 );
+
+               # trim the content down as we may have more entries than we should.
+       
+               while ( $#content > $TAILSIZE ){ shift @content; };
+               close FD;
+
+               print "$end_position\n--END--\n";
+
+               foreach my $line ( @content ){
+                       my ( $address, $timestamp, $direction, $type, $filtered, $cat, $data );
+
+                       ( $address, $timestamp, $direction, $type, $filtered, $cat, $data ) = ( $line =~ /([^,]*),(\d+),(\d+),(\d+),(\d+),([^,]*),(.*)/ );
+
+                       # are we using the oldstyle or new style logs ?
+                       if ( not defined $address and not defined $timestamp ){
+                               ( $address, $timestamp, $type, $data ) = ( $line =~ /([^,]*),([^,]*),([^,]*),(.*)/ );
+                               if ( $type eq "1" ){
+                                       $direction = 0;
+                                       $type      = 1;
+                               } elsif ( $type eq "2" ){
+                                       $direction = 1;
+                                       $type      = 1;
+                               } elsif ( $type eq "3" ){
+                                       $direction = 0;
+                                       $type      = 2;
+                               } elsif ( $type eq "4" ){
+                                       $direction = 1;
+                                       $type      = 4;
+                               }
+                       }
+                       
+                       my ( $severity, $classification ) = '0', 'None';
+                       if ($cat) {
+                               ( $severity, $classification) = split(/ /, $cat, 2); }
+                       else {
+                               $cat = 'N/A'; }
+
+                       my $red = 255;
+                       my $green = 255;
+                       my $blue = 255;
+
+                       if ($severity < 0 && $severity >= -5) {
+                               $red = 0; $green = abs($severity) * (255 / 5); $blue = 0; }
+                       elsif ($severity > 0 && $severity <= 5) {
+                               $red = $severity * (255 / 5); $green = 0; $blue = 0; }
+                       else {
+                               $red = 0; $green = 0; $blue = 0; }
+                       
+                       my $severitycolour = '';
+                       if ($cat ne 'N/A') {
+                               $severitycolour = sprintf("background-color: #%02x%02x%02x;", $red, $green, $blue); }
+
+                       # some protocols (ICQ, I'm looking in your direction) have a habit of starting 
+                       # and ending each sentence with HTML (evil program)             
+
+                       if ( defined $skimhtml and $skimhtml eq "1" ){  
+                               $data =~ s/^<HTML><BODY[^>]*><FONT[^>]*>//ig;   
+                               $data =~ s/<\/FONT><\/BODY><\/HTML>//ig;        
+                       }
+
+                       $data = &htmlescape($data);
+                       $data =~ s/\r\\n/<br>\n/g;
+                       my $user = "";
+
+                       my $bstyle = "";
+                       $bstyle = "style='background-color: #FFE4E1;'" if ( $filtered eq "1" );
+
+                       if ( $type eq "1" ){
+                               # a message message (from remote user)
+                               if ( $direction eq "0" ){
+                                       # incoming
+                                       my $u = $remoteuser;
+                                       $u =~ s/\@.*//g;
+                                       $user = "&lt;<span class='remoteuser'>$u</span>&gt;";
+                               } else { 
+                                       # outgoing message
+                                       my $u = $localuser;
+                                       $u =~ s/\@.*//g;
+                                       $user = "&lt;<span class='localuser'>$u</span>&gt;";
+                               }
+                       } elsif ($type eq "2") {
+                               if ( $direction eq "0" ){
+                                       # incoming file
+                                       my $u = $remoteuser;
+                                       $u =~ s/\@.*//g;
+                                       $user = "&lt;<span class='remoteuser'><b><i>$u</i></b></span>&gt;";
+                               } else {
+                                       # outgoing file
+                                       my $u = $localuser;
+                                       $u =~ s/\@.*//g;
+                                       $user = "&lt;<span class='localuser'><b><i>$u</i></b></span>&gt;";
+                               }
+                       }
+
+                       my $t = strftime "%H:%M:%S", localtime($timestamp);
+                       if ($type eq "3" or $type eq "4") {
+                               $data = "<b><i>$data</i></b>";
+                       }
+                       print "<tr $bstyle><td style='width: 30px; vertical-align: top;'>[$t]</td><td style='width: 10px; $severitycolour' title='$cat'><td style=' width: 60px; vertical-align: top;'>$user</td><td style='vertical-align: top;'>$data</td></tr>";
+               }
+       }
+       return;
+}
+
+sub htmlescape
+{
+       my ($value) = @_;
+       $value =~ s/&/\&amp;/g;
+       $value =~ s/</\&lt;/g;
+       $value =~ s/>/\&gt;/g;
+       $value =~ s/"/\&quot;/g;
+       $value =~ s/'/\&#39;/g;
+       return $value;
+}
diff --git a/lfs/imspector b/lfs/imspector
new file mode 100644 (file)
index 0000000..31e358d
--- /dev/null
@@ -0,0 +1,87 @@
+###############################################################################
+#                                                                             #
+# IPFire.org - A linux based firewall                                         #
+# Copyright (C) 2010  Michael Tremer & Christian Schmidt                      #
+#                                                                             #
+# This program is free software: you can redistribute it and/or modify        #
+# it under the terms of the GNU General Public License as published by        #
+# the Free Software Foundation, either version 3 of the License, or           #
+# (at your option) any later version.                                         #
+#                                                                             #
+# This program is distributed in the hope that it will be useful,             #
+# but WITHOUT ANY WARRANTY; without even the implied warranty of              #
+# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the               #
+# GNU General Public License for more details.                                #
+#                                                                             #
+# You should have received a copy of the GNU General Public License           #
+# along with this program.  If not, see <http://www.gnu.org/licenses/>.       #
+#                                                                             #
+###############################################################################
+
+###############################################################################
+# Definitions
+###############################################################################
+
+include Config
+
+VER        = 0.9
+
+THISAPP    = imspector-$(VER)
+DL_FILE    = $(THISAPP).tar.gz
+DL_FROM    = $(URL_IPFIRE)
+DIR_APP    = $(DIR_SRC)/$(THISAPP)
+TARGET     = $(DIR_INFO)/$(THISAPP)
+PROG       = imspector
+PAK_VER    = 1
+
+DEPS       = ""
+
+###############################################################################
+# Top-level Rules
+###############################################################################
+
+objects = $(DL_FILE)
+
+$(DL_FILE) = $(DL_FROM)/$(DL_FILE)
+
+$(DL_FILE)_MD5 = 626abf7c2b8f15d56df679ad66624575
+
+install : $(TARGET)
+
+check : $(patsubst %,$(DIR_CHK)/%,$(objects))
+
+download :$(patsubst %,$(DIR_DL)/%,$(objects))
+
+md5 : $(subst %,%_MD5,$(objects))
+
+dist: 
+       @$(PAK)
+
+###############################################################################
+# Downloading, checking, md5sum
+###############################################################################
+
+$(patsubst %,$(DIR_CHK)/%,$(objects)) :
+       @$(CHECK)
+
+$(patsubst %,$(DIR_DL)/%,$(objects)) :
+       @$(LOAD)
+
+$(subst %,%_MD5,$(objects)) :
+       @$(MD5)
+
+###############################################################################
+# Installation Details
+###############################################################################
+
+$(TARGET) : $(patsubst %,$(DIR_DL)/%,$(objects))
+       @$(PREBUILD)
+       @rm -rf $(DIR_APP) && cd $(DIR_SRC) && tar zxf $(DIR_DL)/$(DL_FILE)
+       cd $(DIR_APP) && make install
+       -mv /usr/etc/imspector /etc/imspector
+       install -v -m 755  $(DIR_CONF)/imspector/imspector.conf /etc/imspector.conf
+       install -v -m 644 $(DIR_SRC)/config/backup/includes/imspector /var/ipfire/backup/addons/includes/imspector
+       chmod 755 /srv/web/ipfire/cgi-bin/imspector.cgi
+       chown nobody:nobody -R /var/log/imspector
+       @rm -rf $(DIR_APP)
+       @$(POSTBUILD)
index a9fadf4..ffb18c9 100644 (file)
@@ -146,6 +146,9 @@ $(TARGET) :
        ln -sf ../init.d/motion      /etc/rc.d/rc3.d/S99motion
        ln -sf ../init.d/motion      /etc/rc.d/rc0.d/K01motion
        ln -sf ../init.d/motion      /etc/rc.d/rc6.d/K01motion
+       ln -sf ../init.d/imspetor    /etc/rc.d/rc3.d/S99imspetor
+       ln -sf ../init.d/imspetor    /etc/rc.d/rc0.d/K01imspetor
+       ln -sf ../init.d/imspetor    /etc/rc.d/rc6.d/K01imspetor
        ln -sf  ../init.d/cyrus-sasl /etc/rc.d/rc0.d/K49cyrus-sasl
        ln -sf  ../init.d/cyrus-sasl /etc/rc.d/rc3.d/S24cyrus-sasl
        ln -sf  ../init.d/cyrus-sasl /etc/rc.d/rc6.d/K49cyrus-sasl
diff --git a/make.sh b/make.sh
index a7cda09..4e72c00 100755 (executable)
--- a/make.sh
+++ b/make.sh
@@ -643,6 +643,7 @@ buildipfire() {
   ipfiremake pound
   ipfiremake minicom
   ipfiremake ddrescue
+  ipfiremake imspector
   echo Build on $HOSTNAME > $BASEDIR/build/var/ipfire/firebuild
   cat /proc/version >> $BASEDIR/build/var/ipfire/firebuild
   echo >> $BASEDIR/build/var/ipfire/firebuild
diff --git a/src/initscripts/init.d/imspector b/src/initscripts/init.d/imspector
new file mode 100644 (file)
index 0000000..7a5a986
--- /dev/null
@@ -0,0 +1,54 @@
+#!/bin/sh
+# Begin $rc_base/init.d/imspector
+
+. /etc/sysconfig/rc
+. $rc_functions
+
+case "$1" in
+       start)
+               boot_mesg "Inserting imspector redirects..."
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 1863 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 5222 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 5223 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 5190 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 5050 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 6667 -j REDIRECT --to-ports 16667
+                       iptables -t nat -A CUSTOMPREROUTING -p tcp --destination-port 8074 -j REDIRECT --to-ports 16667
+
+               boot_mesg "Starting imspector Deamon..."
+                       loadproc imspector -c /etc/imspector/imspector.conf
+                       evaluate_retval 
+               ;;
+
+       stop)
+               boot_mesg "Stopping imspector Deamon..."
+               killproc /usr/sbin/imspector
+               evaluate_retval
+
+               boot_mesg "Remove imspector redirects..."
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 1863 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 5222 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 5223 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 5190 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 5050 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 6667 -j REDIRECT --to-ports 16667
+                       iptables -t nat -D CUSTOMPREROUTING -p tcp --destination-port 8074 -j REDIRECT --to-ports 16667
+               ;;
+
+       restart)
+               $0 stop
+               sleep 1
+               $0 start
+               ;;
+
+       status)
+               statusproc /usr/sbin/imspector
+               ;;
+
+       *)
+               echo "Usage: $0 {start|stop|restart|status}"
+               exit 1
+               ;;
+esac
+
+# End $rc_base/init.d/imspector