Index: trunk/src/sh_prelude.c
===================================================================
--- trunk/src/sh_prelude.c	(revision 131)
+++ trunk/src/sh_prelude.c	(revision 169)
@@ -85,5 +85,5 @@
 #define SH_NEED_PWD_GRP 1
 #include "sh_static.h"
-
+char * sh_util_strdup (const char * str) SH_GNUC_MALLOC;
 /*
  * When SH_USE_XML is set, value are formated using name="value".
@@ -651,4 +651,11 @@
 #endif
 
+#ifdef SH_USE_PORTCHECK
+		{ MSG_PORT_MISS, N_("Service closed"), IDMEF_IMPACT_TYPE_OTHER },
+		{ MSG_PORT_NEW, N_("Service opened"), IDMEF_IMPACT_TYPE_OTHER },
+		{ MSG_PORT_RESTART, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER },
+		{ MSG_PORT_NEWPORT, N_("Service restarted"), IDMEF_IMPACT_TYPE_OTHER },
+#endif
+
 #ifdef SH_USE_SUIDCHK
                 { MSG_SUID_POLICY, N_("SUID/SGID File Detected"), IDMEF_IMPACT_TYPE_FILE },
@@ -684,4 +691,158 @@
 
 
+#ifdef SH_USE_PORTCHECK
+static int get_service_info(char *msg, idmef_alert_t *alert)
+{
+        int ret;
+	long port;
+	char *ptr, *new, *tmp, *ip, *srv, *end;
+        prelude_string_t *str;
+        idmef_address_t *address;
+        idmef_node_t *node;
+        idmef_service_t *service;
+        idmef_source_t *source = idmef_alert_get_next_source(alert, NULL);
+
+        new = sh_util_strdup(msg);
+ 
+        ptr = strstr(new, _("port: "));
+        if ( ! ptr ) {
+                sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+                                _("malformed Samhain port check message"), _("get_service_info"));
+		SH_FREE( new );
+                return -1;
+        }
+
+        ptr += 6; /* skip 'port: ', position on first byte of interface */
+        tmp = strchr(ptr, ':');
+        if ( ! tmp ) {
+                sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+                                _("malformed Samhain port check message (no port)"), _("get_service_info"));
+		SH_FREE( new );
+                return -1;
+        }
+	*tmp = '\0';
+
+	ip = strdup(ptr);
+        if ( ip ) {
+                if ( ! source ) {
+                        ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
+                        if ( ret < 0 ) {
+                                free(ip);
+				SH_FREE( new );
+                                return ret;
+                        }
+                }
+
+                ret = idmef_source_new_node(source, &node);
+                if ( ret < 0 ) {
+                        free(ip);
+			SH_FREE( new );
+                        return ret;
+                }
+                
+                ret = idmef_node_new_address(node, &address, IDMEF_LIST_APPEND);
+                if ( ret < 0 ) {
+                        free(ip);
+			SH_FREE( new );
+                        return ret;
+                }
+                
+                ret = idmef_address_new_address(address, &str);
+                if ( ret < 0 ) {
+                        free(ip);
+			SH_FREE( new );
+                        return ret;
+                }
+                
+                prelude_string_set_nodup(str, ip);
+        }
+
+	ptr = tmp;
+	++ptr;
+        tmp = strchr(ptr, '/');
+        if ( ! tmp ) {
+                sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+                                _("malformed Samhain port check message (no protocol)"), _("get_service_info"));
+		SH_FREE( new );
+                return -1;
+        }
+	*tmp = '\0';
+
+	port = strtol(ptr, &end, 0);
+        if ( *ptr && *end == '\0' && port >= 0 && port < 65536) {
+
+                if ( ! source ) {
+                        ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
+                        if ( ret < 0 ) {
+                                free(srv);
+				SH_FREE( new );
+                                return ret;
+                        }
+                }
+
+                ret = idmef_source_new_service(source, &service);
+                if ( ret < 0 ) {
+                        free(srv);
+			SH_FREE( new );
+                        return ret;
+                }
+
+		idmef_service_set_port(service, port);
+	}
+
+	ptr = tmp;
+	++ptr;
+        ptr = strchr(ptr, '(');
+        if ( ! ptr ) {
+                sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+                                _("malformed Samhain port check message (no service)"), _("get_service_info"));
+		SH_FREE( new );
+                return -1;
+        }
+	++ptr;
+        tmp = strchr(ptr, ')');
+        if ( ! tmp ) {
+                sh_error_handle((-1), FIL__, __LINE__, -1, MSG_E_SUBGEN,
+                                _("malformed Samhain port check message (service not closed)"), _("get_service_info"));
+		SH_FREE( new );
+                return -1;
+        }
+	*tmp = '\0';
+
+	srv = strdup(ptr);
+        if ( srv ) {
+                if ( ! source ) {
+                        ret = idmef_alert_new_source(alert, &source, IDMEF_LIST_APPEND);
+                        if ( ret < 0 ) {
+                                free(srv);
+				SH_FREE( new );
+                                return ret;
+                        }
+                }
+
+		if ( ! service ) {
+                        ret = idmef_source_new_service(source, &service);
+			if ( ret < 0 ) {
+                                free(srv);
+				SH_FREE( new );
+				return ret;
+			}
+                }
+
+                ret = idmef_service_new_ident(service, &str);
+                if ( ret < 0 ) {
+                        free(srv);
+			SH_FREE( new );
+                        return ret;
+                }
+                
+                prelude_string_set_nodup(str, srv);
+        }
+
+	SH_FREE( new );
+
+	return 0;
+}
+#endif
 
 static int get_login_info(char *msg, idmef_alert_t *alert)
@@ -902,4 +1063,12 @@
                 goto err;
         
+#ifdef SH_USE_PORTCHECK
+	if (msgid == MSG_PORT_MISS || msgid == MSG_PORT_NEW || msgid == MSG_PORT_RESTART || msgid == MSG_PORT_NEWPORT) {
+	        ret = get_service_info(message, alert);
+		if ( ret < 0 )
+		        goto err;
+        }
+#endif
+   
         map_policy_to_class(message, msgid, impact, str);
 
