[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

first patch to security problem



Hi All,

Here's a first attempt at a patch. You may need to change your netscape
URL handler for certain URLs to work properly. i.e.:

from:      !netscape -remote 'openURL(%s)'
to  :      !netscape -remote 'openURL('%s')'

if you don't make the change, it doesn't mean `shutdown` etc will still
run! It just means legit URLs using `$&|' etc characters won't go to
netscape properly.

A perfect test is to do something like /echo www.yahoo.com/|/ and then
try to click the URL (New Window). See if it shows up in netscape's URL
bar correctly.

Feedback please...

-- 
Peter. <zed@linuxpower.org>
--- /home/zed/xchat/files/xchat-1.5.6/src/fe-gtk/menu.c	Wed Jul 19 22:50:02 2000
+++ menu.c	Sat Aug 26 13:59:22 2000
@@ -44,6 +44,7 @@
 extern GSList *sess_list;
 extern GdkFont *font_normal;
 extern GtkWidget *main_window, *main_book;
+extern GtkWidget *main_menu_bar;
 
 extern int cfg_get_bool (char *var);
 extern void maingui_showhide_topic (GtkWidget * button, session * sess);
@@ -97,6 +98,40 @@
 extern GSList *urlhandler_list;
 static GSList *submenu_list;
 
+/* escapes \ $ ` ' " & | ; */
+
+static char *
+url_escape_chars (char *url)
+{
+	char *buf, *orig_buf;
+
+	orig_buf = buf = malloc ((strlen (url) * 2) + 1);
+
+	while (1)
+	{
+		switch (*url)
+		{
+		case 0:
+			*buf = '\0';
+			return orig_buf;
+		case '\\':
+		case '`':
+		case '\'':
+		case '\"':
+		case '$':
+		case '&':
+		case '|':
+		case ';':
+			*buf = '\\';
+			buf++;
+		default:
+			*buf = *url;
+			buf++;
+		}
+		url++;
+	}
+}
+
 void
 goto_url (void *unused, char *url)
 {
@@ -104,7 +139,11 @@
 	gnome_url_show (url);
 #else
 	char tbuf[256];
-	snprintf (tbuf, sizeof tbuf, "netscape -remote 'openURL(%s)'", url);
+
+	url = url_escape_chars (url);
+	snprintf (tbuf, sizeof (tbuf), "netscape -remote 'openURL('%s')'", url);
+	free (url);
+
 	my_system (tbuf);
 #endif
 }
@@ -115,8 +154,10 @@
 nick_command (session * sess, char *cmd)
 {
 	if (*cmd == '!')
+	{
+		printf ("executing: /bin/sh -c %s\n", cmd + 1);
 		my_system (cmd + 1);
-	else
+	} else
 		handle_command (cmd, sess, FALSE, FALSE);
 }
 
@@ -362,7 +403,7 @@
 	gtk_widget_show (menu);
 }
 
-static char *nick_copy = 0;
+static char *str_copy = 0;		/* for all pop-up menus */
 
 void
 menu_nickmenu (session *sess, GdkEventButton *event, char *nick)
@@ -371,16 +412,16 @@
 	struct User *user;
 	GtkWidget *wid, *submenu, *menu = gtk_menu_new ();
 
-	if (nick_copy)
-		free (nick_copy);
-	nick_copy = strdup (nick);
+	if (str_copy)
+		free (str_copy);
+	str_copy = strdup (nick);
 
 	submenu_list = 0;	/* first time though, might not be 0 */
 
 	user = find_name_global (menu_sess->server, nick);
 	if (user)
 	{
-		submenu = menu_quick_sub (nick_copy, menu);
+		submenu = menu_quick_sub (str_copy, menu);
 
 		sprintf (buf, "User: %s",
 					user->hostname ? user->hostname : "Unknown");
@@ -409,12 +450,10 @@
 		menu_quick_item (0, 0, menu, 1, 0);
 	}
 
-	menu_create (menu, popup_list, nick_copy);
+	menu_create (menu, popup_list, str_copy);
 	menu_popup (menu, event);
 }
 
-extern GtkWidget *main_menu_bar;
-
 void
 menu_showhide (session *sess, int force_hide)
 {
@@ -468,29 +507,29 @@
 
 	menu = createmenus (0, sess, 0);
 
-	menu_toggle_item ("Menu Bar", menu, (void*)menu_middle_cb, 0, GTK_WIDGET_VISIBLE (main_menu_bar));
+	/*menu_toggle_item ("Menu Bar", menu, (void*)menu_middle_cb, 0, GTK_WIDGET_VISIBLE (main_menu_bar));*/
+	menu_toggle_item ("Menu Bar", menu, (void*)menu_middle_cb, 0, !prefs.hidemenu);
 	menu_toggle_item ("Topic Bar", menu, (void*)menu_middle_cb, (void*)1, prefs.topicbar);
 	menu_toggle_item ("User List", menu, (void*)menu_middle_cb, (void*)2, !prefs.hideuserlist);
 
 	menu_popup (menu, event);
 }
 
-static char *url_copy = 0;
-
 void
 menu_urlmenu (session *sess, GdkEventButton *event, char *url)
 {
 	GtkWidget *menu;
 
-	if (url_copy)
-		free (url_copy);
-	url_copy = strdup (url);
+	if (str_copy)
+		free (str_copy);
+/*	str_copy = strdup (url);*/
+	str_copy = url_escape_chars (url);
 
 	menu = gtk_menu_new ();
 	menu_quick_item (0, url, menu, 1, 0);
 	menu_quick_item (0, 0, menu, 1, 0);
 
-	menu_create (menu, urlhandler_list, url_copy);
+	menu_create (menu, urlhandler_list, str_copy);
 	menu_popup (menu, event);
 }
 
@@ -552,25 +591,24 @@
 		list = list->next;
 	}
 
-	if (url_copy)
-		free (url_copy);
-
-	url_copy = strdup (chan);
+	if (str_copy)
+		free (str_copy);
+	str_copy = strdup (chan);
 
 	menu = gtk_menu_new ();
 
-	menu_quick_item (0, chan, menu, 1, url_copy);
-	menu_quick_item (0, 0, menu, 1, url_copy);
+	menu_quick_item (0, chan, menu, 1, str_copy);
+	menu_quick_item (0, 0, menu, 1, str_copy);
 
 	if (!is_joined)
 		menu_quick_item_with_callback (menu_chan_join, "Join Channel", menu,
-												 url_copy);
+												 str_copy);
 	else
 	{
 		menu_quick_item_with_callback (menu_chan_part, "Part Channel", menu,
-												 url_copy);
+												 str_copy);
 		menu_quick_item_with_callback (menu_chan_cycle, "Cycle Channel", menu,
-												 url_copy);
+												 str_copy);
 	}
 
 	gtk_menu_popup (GTK_MENU (menu), NULL, NULL, NULL, NULL,