Variables encoded twice

Armin Wolfermann aw at osn.de
Thu Aug 7 11:07:03 CEST 2008


* Bernd Arnold <bernd_a at gmx.de> [05.08.2008 21:30]:
> But it's not complete yet. Try "John's server" in the histogram.cgi
> and trends.cgi, and you'll get <option value='John's server'>John's
> server Maybe you'll have a look at this; I will also, but I don't have
> the time today.

Oops, I searched only for "input" but not for "option". An updated patch
is attached.

> They don't appear if I declare your escape_string function in the
> cgiutils.h files (I don't know the difference between cgiutils.h and
> cgiutils.h.in, so I patched both files).

cgiutils.h is generated from cgiutils.h.in by autoconf and is not in CVS.

Regards,
Armin Wolfermann
OSN Online Service Nuremberg
-------------- next part --------------
Index: cgi/avail.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/avail.c,v
retrieving revision 1.50
diff -u -r1.50 avail.c
--- cgi/avail.c	23 Jun 2008 20:47:42 -0000	1.50
+++ cgi/avail.c	7 Aug 2008 08:54:43 -0000
@@ -510,13 +510,13 @@
 			if(full_log_entries==TRUE)
 				printf("<input type='hidden' name='full_log_entries' value=''>\n");
 			if(display_type==DISPLAY_HOSTGROUP_AVAIL)
-				printf("<input type='hidden' name='hostgroup' value='%s'>\n",hostgroup_name);
+				printf("<input type='hidden' name='hostgroup' value='%s'>\n",escape_string(hostgroup_name));
 			if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL)
-				printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
+				printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 			if(display_type==DISPLAY_SERVICE_AVAIL)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 			if(display_type==DISPLAY_SERVICEGROUP_AVAIL)
-				printf("<input type='hidden' name='servicegroup' value='%s'>\n",url_encode(servicegroup_name));
+				printf("<input type='hidden' name='servicegroup' value='%s'>\n",escape_string(servicegroup_name));
 
 			printf("<input type='hidden' name='assumeinitialstates' value='%s'>\n",(assume_initial_states==TRUE)?"yes":"no");
 			printf("<input type='hidden' name='assumestateretention' value='%s'>\n",(assume_state_retention==TRUE)?"yes":"no");
@@ -645,13 +645,13 @@
 	        printf("<form method=\"get\" action=\"%s\">\n",AVAIL_CGI);
 		printf("<input type='hidden' name='show_log_entries' value=''>\n");
 		if(display_type==DISPLAY_HOSTGROUP_AVAIL)
-			printf("<input type='hidden' name='hostgroup' value='%s'>\n",hostgroup_name);
+			printf("<input type='hidden' name='hostgroup' value='%s'>\n",escape_string(hostgroup_name));
 		if(display_type==DISPLAY_HOST_AVAIL || display_type==DISPLAY_SERVICE_AVAIL)
-			printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 		if(display_type==DISPLAY_SERVICE_AVAIL)
-			printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+			printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 		if(display_type==DISPLAY_SERVICEGROUP_AVAIL)
-			printf("<input type='hidden' name='servicegroup' value='%s'>\n",servicegroup_name);
+			printf("<input type='hidden' name='servicegroup' value='%s'>\n",escape_string(servicegroup_name));
 
 		printf("<table border=0 cellpadding=5>\n");
 
@@ -736,7 +736,7 @@
 		printf("<option value=\"\">None\n");
 		/* check all the time periods... */
 		for(temp_timeperiod=timeperiod_list;temp_timeperiod!=NULL;temp_timeperiod=temp_timeperiod->next)
-			printf("<option value=%s>%s\n",url_encode(temp_timeperiod->name),temp_timeperiod->name);
+			printf("<option value=%s>%s\n",escape_string(temp_timeperiod->name),temp_timeperiod->name);
 		printf("</select>\n");
 		printf("</td>\n");
 		printf("</tr>\n");
@@ -838,7 +838,7 @@
 		printf("<option value='all'>** ALL HOSTGROUPS **\n");
 		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
 			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_hostgroup->group_name,temp_hostgroup->group_name);
+				printf("<option value='%s'>%s\n",escape_string(temp_hostgroup->group_name),temp_hostgroup->group_name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
@@ -868,7 +868,7 @@
 		printf("<option value='all'>** ALL HOSTS **\n");
 		for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 			if(is_authorized_for_host(temp_host,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_host->name,temp_host->name);
+				printf("<option value='%s'>%s\n",escape_string(temp_host->name),temp_host->name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
@@ -900,7 +900,7 @@
 		printf("<option value='all'>** ALL SERVICEGROUPS **\n");
 		for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){
 			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_servicegroup->group_name,temp_servicegroup->group_name);
+				printf("<option value='%s'>%s\n",escape_string(temp_servicegroup->group_name),temp_servicegroup->group_name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
@@ -941,7 +941,7 @@
 
 	        printf("<form method=\"get\" action=\"%s\" name='serviceform'>\n",AVAIL_CGI);
 		printf("<input type='hidden' name='get_date_parts'>\n");
-		printf("<input type='hidden' name='host' value='%s'>\n",(firsthostpointer==NULL)?"unknown":firsthostpointer);
+		printf("<input type='hidden' name='host' value='%s'>\n",(firsthostpointer==NULL)?"unknown":escape_string(firsthostpointer));
 
 		printf("<table border=0 cellpadding=5>\n");
 
@@ -950,7 +950,7 @@
 		printf("<option value='all'>** ALL SERVICES **\n");
 		for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
 			if(is_authorized_for_service(temp_service,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s;%s\n",temp_service->description,temp_service->host_name,temp_service->description);
+				printf("<option value='%s'>%s;%s\n",escape_string(temp_service->description),temp_service->host_name,temp_service->description);
 		        }
 
 		printf("</select>\n");
Index: cgi/cgiutils.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/cgiutils.c,v
retrieving revision 1.81
diff -u -r1.81 cgiutils.c
--- cgi/cgiutils.c	23 Jun 2008 20:47:44 -0000	1.81
+++ cgi/cgiutils.c	7 Aug 2008 08:54:44 -0000
@@ -1492,6 +1492,54 @@
 
 
 
+/* escape string for html form usage */
+char * escape_string(char *input){
+	int len,output_len;
+	int x,y;
+	char temp_expansion[10];
+
+	/* we need up to six times the space to do the conversion */
+	len=(int)strlen(input);
+	output_len=len*6;
+	if((encoded_html_string=(char *)malloc(output_len+1))==NULL)
+		return "";
+
+	strcpy(encoded_html_string,"");
+
+	for(x=0,y=0;x<=len;x++){
+
+		/* end of string */
+		if((char)input[x]==(char)'\x0'){
+			encoded_html_string[y]='\x0';
+			break;
+			}
+
+		/* alpha-numeric characters don't get encoded */
+		else if(((char)input[x]>='0' && (char)input[x]<='9') || ((char)input[x]>='A' && (char)input[x]<='Z') || ((char)input[x]>=(char)'a' && (char)input[x]<=(char)'z'))
+			encoded_html_string[y++]=input[x];
+
+		/* spaces, hyphens, periods, underscores and colons don't get encoded */
+		else if(((char)input[x]==(char)' ') || ((char)input[x]==(char)'-') || ((char)input[x]==(char)'.') || ((char)input[x]==(char)'_') || ((char)input[x]==(char)':'))
+			encoded_html_string[y++]=input[x];
+
+		/* for simplicity, all other chars represented by their numeric value */
+		else{
+			encoded_html_string[y]='\x0';
+			sprintf(temp_expansion,"&#%d;",(unsigned char)input[x]);
+			if((int)strlen(encoded_html_string)<(output_len-strlen(temp_expansion))){
+				strcat(encoded_html_string,temp_expansion);
+				y+=strlen(temp_expansion);
+				}
+			}
+	        }
+
+	encoded_html_string[y++]='\x0';
+
+	return encoded_html_string;
+        }
+
+
+
 /* determines the log file we should use (from current time) */
 void get_log_archive_to_use(int archive,char *buffer,int buffer_length){
 	struct tm *t;
Index: cgi/histogram.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/histogram.c,v
retrieving revision 1.27
diff -u -r1.27 histogram.c
--- cgi/histogram.c	19 May 2008 18:42:26 -0000	1.27
+++ cgi/histogram.c	7 Aug 2008 08:54:45 -0000
@@ -407,9 +407,9 @@
 			printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);
 			printf("<input type='hidden' name='t1' value='%lu'>\n",(unsigned long)t1);
 			printf("<input type='hidden' name='t2' value='%lu'>\n",(unsigned long)t2);
-			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 			if(display_type==DISPLAY_SERVICE_HISTOGRAM)
-				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
+				printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 
 
 			printf("<tr><td CLASS='optBoxItem' valign=top align=left>Report period:</td><td CLASS='optBoxItem' valign=top align=left>Assume state retention:</td></tr>\n");
@@ -697,7 +697,7 @@
 
 			for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 				if(is_authorized_for_host(temp_host,&current_authdata)==TRUE)
-					printf("<option value='%s'>%s\n",temp_host->name,temp_host->name);
+					printf("<option value='%s'>%s\n",escape_string(temp_host->name),temp_host->name);
 			        }
 
 			printf("</select>\n");
@@ -746,7 +746,7 @@
 			printf("<TABLE BORDER=0 cellpadding=5>\n");
 			printf("<form method=\"GET\" action=\"%s\" name=\"serviceform\">\n",HISTOGRAM_CGI);
 			printf("<input type='hidden' name='input' value='getoptions'>\n");
-			printf("<input type='hidden' name='host' value='%s'>\n",(first_service==NULL)?"unknown":first_service);
+			printf("<input type='hidden' name='host' value='%s'>\n",(first_service==NULL)?"unknown":escape_string(first_service));
 
 			printf("<tr><td class='reportSelectSubTitle'>Service:</td>\n");
 			printf("<td class='reportSelectItem'>\n");
@@ -754,7 +754,7 @@
 
 			for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
 				if(is_authorized_for_service(temp_service,&current_authdata)==TRUE)
-					printf("<option value='%s'>%s;%s\n",temp_service->description,temp_service->host_name,temp_service->description);
+					printf("<option value='%s'>%s;%s\n",escape_string(temp_service->description),temp_service->host_name,temp_service->description);
 		                }
 
 			printf("</select>\n");
@@ -789,9 +789,9 @@
 
 			printf("<TABLE BORDER=0 cellpadding=5>\n");
 			printf("<form method=\"GET\" action=\"%s\">\n",HISTOGRAM_CGI);
-			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 			if(display_type==DISPLAY_SERVICE_HISTOGRAM)
-				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
+				printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 
 			printf("<tr><td class='reportSelectSubTitle' align=right>Report Period:</td>\n");
 			printf("<td class='reportSelectItem'>\n");
Index: cgi/history.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/history.c,v
retrieving revision 1.31
diff -u -r1.31 history.c
--- cgi/history.c	23 Jun 2008 20:47:44 -0000	1.31
+++ cgi/history.c	7 Aug 2008 08:54:45 -0000
@@ -204,9 +204,9 @@
 
 		printf("<table border=0 CLASS='optBox'>\n");
 		printf("<form method=\"GET\" action=\"%s\">\n",HISTORY_CGI);
-		printf("<input type='hidden' name='host' value='%s'>\n",(show_all_hosts==TRUE)?"all":url_encode(host_name));
+		printf("<input type='hidden' name='host' value='%s'>\n",(show_all_hosts==TRUE)?"all":escape_string(host_name));
 		if(display_type==DISPLAY_SERVICES)
-			printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
+			printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 		printf("<input type='hidden' name='archive' value='%d'>\n",log_archive);
 
 		printf("<tr>\n");
Index: cgi/notifications.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/notifications.c,v
retrieving revision 1.25
diff -u -r1.25 notifications.c
--- cgi/notifications.c	19 May 2008 18:42:27 -0000	1.25
+++ cgi/notifications.c	7 Aug 2008 08:54:45 -0000
@@ -212,11 +212,11 @@
 		printf("<table border=0 CLASS='optBox'>\n");
 		printf("<form method='GET' action='%s'>\n",NOTIFICATIONS_CGI);
 		if(query_type==FIND_SERVICE){
-			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(query_host_name));
-			printf("<input type='hidden' name='service' value='%s'>\n",url_encode(query_svc_description));
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(query_host_name));
+			printf("<input type='hidden' name='service' value='%s'>\n",escape_string(query_svc_description));
 	                }
 		else
-			printf("<input type='hidden' name='%s' value='%s'>\n",(query_type==FIND_HOST)?"host":"contact",url_encode((query_type==FIND_HOST)?query_host_name:query_contact_name));
+			printf("<input type='hidden' name='%s' value='%s'>\n",(query_type==FIND_HOST)?"host":"contact",(query_type==FIND_HOST)?escape_string(query_host_name):escape_string(query_contact_name));
 		printf("<input type='hidden' name='archive' value='%d'>\n",log_archive);
 		printf("<tr>\n");
 		if(query_type==FIND_SERVICE)
Index: cgi/statusmap.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/statusmap.c,v
retrieving revision 1.40
diff -u -r1.40 statusmap.c
--- cgi/statusmap.c	19 May 2008 18:42:28 -0000	1.40
+++ cgi/statusmap.c	7 Aug 2008 08:54:46 -0000
@@ -700,8 +700,8 @@
 		printf("<form method=\"POST\" action=\"%s\">\n",STATUSMAP_CGI);
 		printf("<table border=0 CLASS='optBox'>\n");
 		printf("<tr><td valign=top>\n");
-		printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
-		printf("<input type='hidden' name='layout' value='%d'>\n",layout_method);
+		printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
+		printf("<input type='hidden' name='layout' value='%d'>\n",escape_string(layout_method));
 
 		printf("</td><td valign=top>\n");
 
@@ -763,7 +763,7 @@
 					break;
 				        }
 			        }
-			printf("<option value='%s' %s>%s\n",temp_hostgroup->group_name,(found==1)?"SELECTED":"",temp_hostgroup->alias);
+			printf("<option value='%s' %s>%s\n",escape_string(temp_hostgroup->group_name),(found==1)?"SELECTED":"",temp_hostgroup->alias);
 		        }
 		printf("</select>\n");
 		printf("</td><td CLASS='optBoxItem' valign=top>Layer mode:<br>");
@@ -2390,7 +2390,7 @@
 		if(get_method==TRUE)
 			printf("&layer=%s",temp_layer->layer_name);
 		else
-			printf("<input type='hidden' name='layer' value='%s'>\n",temp_layer->layer_name);
+			printf("<input type='hidden' name='layer' value='%s'>\n",escape_string(temp_layer->layer_name));
 	        }
 
 	if(get_method==TRUE)
Index: cgi/summary.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/summary.c,v
retrieving revision 1.27
diff -u -r1.27 summary.c
--- cgi/summary.c	24 Jan 2008 02:51:30 -0000	1.27
+++ cgi/summary.c	7 Aug 2008 08:54:47 -0000
@@ -588,7 +588,7 @@
 		printf("<option value='all'>** ALL HOSTGROUPS **\n");
 		for(temp_hostgroup=hostgroup_list;temp_hostgroup!=NULL;temp_hostgroup=temp_hostgroup->next){
 			if(is_authorized_for_hostgroup(temp_hostgroup,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_hostgroup->group_name,temp_hostgroup->group_name);
+				printf("<option value='%s'>%s\n",escape_string(temp_hostgroup->group_name),temp_hostgroup->group_name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
@@ -598,7 +598,7 @@
 		printf("<option value='all'>** ALL SERVICEGROUPS **\n");
 		for(temp_servicegroup=servicegroup_list;temp_servicegroup!=NULL;temp_servicegroup=temp_servicegroup->next){
 			if(is_authorized_for_servicegroup(temp_servicegroup,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_servicegroup->group_name,temp_servicegroup->group_name);
+				printf("<option value='%s'>%s\n",escape_string(temp_servicegroup->group_name),temp_servicegroup->group_name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
@@ -609,7 +609,7 @@
 
 		for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 			if(is_authorized_for_host(temp_host,&current_authdata)==TRUE)
-				printf("<option value='%s'>%s\n",temp_host->name,temp_host->name);
+				printf("<option value='%s'>%s\n",escape_string(temp_host->name),temp_host->name);
 		        }
 		printf("</select>\n");
 		printf("</td></tr>\n");
Index: cgi/trends.c
===================================================================
RCS file: /cvsroot/nagios/nagios/cgi/trends.c,v
retrieving revision 1.41
diff -u -r1.41 trends.c
--- cgi/trends.c	23 Jun 2008 20:47:46 -0000	1.41
+++ cgi/trends.c	7 Aug 2008 08:54:48 -0000
@@ -454,9 +454,9 @@
 				printf("<input type='hidden' name='nomap' value=''>\n");
 			printf("<input type='hidden' name='t1' value='%lu'>\n",(unsigned long)t1);
 			printf("<input type='hidden' name='t2' value='%lu'>\n",(unsigned long)t2);
-			printf("<input type='hidden' name='host' value='%s'>\n",url_encode(host_name));
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 			if(display_type==DISPLAY_SERVICE_TRENDS)
-				printf("<input type='hidden' name='service' value='%s'>\n",url_encode(svc_description));
+				printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 
 			printf("<input type='hidden' name='assumeinitialstates' value='%s'>\n",(assume_initial_states==TRUE)?"yes":"no");
 			printf("<input type='hidden' name='assumestateretention' value='%s'>\n",(assume_state_retention==TRUE)?"yes":"no");
@@ -809,7 +809,7 @@
 
 			for(temp_host=host_list;temp_host!=NULL;temp_host=temp_host->next){
 				if(is_authorized_for_host(temp_host,&current_authdata)==TRUE)
-					printf("<option value='%s'>%s\n",temp_host->name,temp_host->name);
+					printf("<option value='%s'>%s\n",escape_string(temp_host->name),temp_host->name);
 			        }
 
 			printf("</select>\n");
@@ -858,7 +858,7 @@
 			printf("<TABLE BORDER=0 cellpadding=5>\n");
 			printf("<form method=\"GET\" action=\"%s\" name=\"serviceform\">\n",TRENDS_CGI);
 			printf("<input type='hidden' name='input' value='getoptions'>\n");
-			printf("<input type='hidden' name='host' value='%s'>\n",(first_service==NULL)?"unknown":first_service);
+			printf("<input type='hidden' name='host' value='%s'>\n",(first_service==NULL)?"unknown":escape_string(first_service));
 
 			printf("<tr><td class='reportSelectSubTitle'>Service:</td>\n");
 			printf("<td class='reportSelectItem'>\n");
@@ -866,7 +866,7 @@
 
 			for(temp_service=service_list;temp_service!=NULL;temp_service=temp_service->next){
 				if(is_authorized_for_service(temp_service,&current_authdata)==TRUE)
-					printf("<option value='%s'>%s;%s\n",temp_service->description,temp_service->host_name,temp_service->description);
+					printf("<option value='%s'>%s;%s\n",escape_string(temp_service->description),temp_service->host_name,temp_service->description);
 		                }
 
 			printf("</select>\n");
@@ -901,9 +901,9 @@
 
 			printf("<TABLE BORDER=0 CELLPADDING=5>\n");
 			printf("<form method=\"GET\" action=\"%s\">\n",TRENDS_CGI);
-			printf("<input type='hidden' name='host' value='%s'>\n",host_name);
+			printf("<input type='hidden' name='host' value='%s'>\n",escape_string(host_name));
 			if(display_type==DISPLAY_SERVICE_TRENDS)
-				printf("<input type='hidden' name='service' value='%s'>\n",svc_description);
+				printf("<input type='hidden' name='service' value='%s'>\n",escape_string(svc_description));
 
 			printf("<tr><td class='reportSelectSubTitle' align=right>Report period:</td>\n");
 			printf("<td class='reportSelectItem'>\n");
Index: include/cgiutils.h.in
===================================================================
RCS file: /cvsroot/nagios/nagios/include/cgiutils.h.in,v
retrieving revision 1.27
diff -u -r1.27 cgiutils.h.in
--- include/cgiutils.h.in	10 Nov 2007 23:34:26 -0000	1.27
+++ include/cgiutils.h.in	7 Aug 2008 08:54:52 -0000
@@ -484,6 +484,7 @@
 
 char * url_encode(char *);		        		/* encodes a string in proper URL format */
 char * html_encode(char *,int);					/* encodes a string in HTML format (for what the user sees) */
+char * escape_string(char *);					/* escape string for html form usage */
 
 void get_time_breakdown(unsigned long,int *,int *,int *,int *);	/* given total seconds, get days, hours, minutes, seconds */
 
-------------- next part --------------
-------------------------------------------------------------------------
This SF.Net email is sponsored by the Moblin Your Move Developer's challenge
Build the coolest Linux based applications with Moblin SDK & win great prizes
Grand prize is a trip for two to an Open Source event anywhere in the world
http://moblin-contest.org/redirect.php?banner_id=100&url=/
-------------- next part --------------
_______________________________________________
Nagios-devel mailing list
Nagios-devel at lists.sourceforge.net
https://lists.sourceforge.net/lists/listinfo/nagios-devel


More information about the Developers mailing list