/pidgin/main: 0f7e07af75fc: Fix security-related url notificatio...
Tomasz Wasilczyk
tomkiewicz at cpw.pidgin.im
Tue Jan 28 10:38:09 EST 2014
Changeset: 0f7e07af75fc0441e163fb38bf47732be724cbab
Author: Tomasz Wasilczyk <tomkiewicz at cpw.pidgin.im>
Date: 2013-06-22 19:08 +0200
Branch: release-2.x.y
URL: https://hg.pidgin.im/pidgin/main/rev/0f7e07af75fc
Description:
Fix security-related url notification issues: xdg-open remote execution, replacing g_spawn_command_line_ with g_spawn_ and opera 'open in current tab' bug
diffstat:
pidgin/gtknotify.c | 409 ++++++++++++++++++++++++++++++----------------------
1 files changed, 234 insertions(+), 175 deletions(-)
diffs (truncated from 473 to 300 lines):
diff --git a/pidgin/gtknotify.c b/pidgin/gtknotify.c
--- a/pidgin/gtknotify.c
+++ b/pidgin/gtknotify.c
@@ -1192,51 +1192,85 @@ pidgin_close_notify(PurpleNotifyType typ
}
#ifndef _WIN32
-static gint
-uri_command(const char *command, gboolean sync)
+static gboolean
+uri_command(GSList *arg_list, gboolean sync)
{
gchar *tmp;
GError *error = NULL;
- gint ret = 0;
+ GSList *it;
+ gchar **argv;
+ gint argc, i;
+ gchar *program;
- purple_debug_misc("gtknotify", "Executing %s\n", command);
+ g_return_val_if_fail(arg_list != NULL, FALSE);
- if (!purple_program_is_valid(command))
- {
- tmp = g_strdup_printf(_("The browser command \"%s\" is invalid."),
- command ? command : "(none)");
+ program = arg_list->data;
+ purple_debug_misc("gtknotify", "Executing %s (%s)\n", program,
+ sync ? "sync" : "async");
+
+ if (!purple_program_is_valid(program)) {
+ purple_debug_error("gtknotify", "Command \"%s\" is invalid\n",
+ program);
+ tmp = g_strdup_printf(
+ _("The browser command \"%s\" is invalid."),
+ program ? program : "(null)");
purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp);
g_free(tmp);
- }
- else if (sync)
- {
- gint status;
-
- if (!g_spawn_command_line_sync(command, NULL, NULL, &status, &error))
- {
- tmp = g_strdup_printf(_("Error launching \"%s\": %s"),
- command, error->message);
- purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp);
- g_free(tmp);
- g_error_free(error);
- }
- else
- ret = status;
- }
- else
- {
- if (!g_spawn_command_line_async(command, &error))
- {
- tmp = g_strdup_printf(_("Error launching \"%s\": %s"),
- command, error->message);
- purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp);
- g_free(tmp);
- g_error_free(error);
- }
+ return FALSE;
}
- return ret;
+ argc = g_slist_length(arg_list);
+ argv = g_new(gchar*, argc + 1);
+ i = 0;
+ for (it = arg_list; it; it = g_slist_next(it)) {
+ if (purple_debug_is_verbose()) {
+ purple_debug_misc("gtknotify", "argv[%d] = \"%s\"\n",
+ i, (gchar*)it->data);
+ }
+ argv[i++] = it->data;
+ }
+ argv[i] = NULL;
+
+ if (sync) {
+ gint exit_status = 0;
+
+ if (g_spawn_sync(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL,
+ NULL, NULL, NULL, NULL, &exit_status, &error) &&
+ exit_status == 0)
+ {
+ g_free(argv);
+ return TRUE;
+ }
+
+ purple_debug_error("gtknotify",
+ "Error launching \"%s\": %s (status: %d)\n", program,
+ error ? error->message : "(null)", exit_status);
+ tmp = g_strdup_printf(_("Error launching \"%s\": %s"), program,
+ error ? error->message : "(null)");
+ g_error_free(error);
+ purple_notify_error(NULL, NULL, _("Unable to open URL"), tmp);
+ g_free(tmp);
+
+ g_free(argv);
+ return FALSE;
+ }
+
+ if (g_spawn_async(NULL, argv, NULL, G_SPAWN_SEARCH_PATH |
+ G_SPAWN_STDOUT_TO_DEV_NULL | G_SPAWN_STDERR_TO_DEV_NULL, NULL,
+ NULL, NULL, &error))
+ {
+ g_free(argv);
+ return TRUE;
+ }
+
+ purple_debug_warning("gtknotify", "Error launching \"%s\": %s\n",
+ program, error ? error->message : "(null)");
+ g_error_free(error);
+
+ g_free(argv);
+ return FALSE;
}
#endif /* _WIN32 */
@@ -1244,183 +1278,208 @@ static void *
pidgin_notify_uri(const char *uri)
{
#ifndef _WIN32
- char *escaped = g_shell_quote(uri);
- char *command = NULL;
- char *remote_command = NULL;
const char *web_browser;
int place;
+ gchar *uri_escaped, *uri_custom = NULL;
+ GSList *argv = NULL, *argv_remote = NULL;
+ gchar **usercmd_argv = NULL;
- web_browser = purple_prefs_get_string(PIDGIN_PREFS_ROOT "/browsers/browser");
+ uri_escaped = g_uri_escape_string(uri, ":/%#,+", FALSE);
+
+ web_browser = purple_prefs_get_string(PIDGIN_PREFS_ROOT
+ "/browsers/browser");
place = purple_prefs_get_int(PIDGIN_PREFS_ROOT "/browsers/place");
/* if they are running gnome, use the gnome web browser */
- if (purple_running_gnome() == TRUE)
- {
+ if (purple_running_gnome() == TRUE) {
char *tmp = g_find_program_in_path("xdg-open");
if (tmp == NULL)
- command = g_strdup_printf("gnome-open %s", escaped);
+ argv = g_slist_append(argv, "gnome-open");
else
- command = g_strdup_printf("xdg-open %s", escaped);
+ argv = g_slist_append(argv, "xdg-open");
g_free(tmp);
- }
- else if (purple_running_osx() == TRUE)
- {
- command = g_strdup_printf("open %s", escaped);
- }
- else if (!strcmp(web_browser, "epiphany") ||
+ argv = g_slist_append(argv, uri_escaped);
+ } else if (purple_running_osx() == TRUE) {
+ argv = g_slist_append(argv, "open");
+ argv = g_slist_append(argv, (gpointer)uri);
+ } else if (!strcmp(web_browser, "epiphany") ||
!strcmp(web_browser, "galeon"))
{
+ argv = g_slist_append(argv, (gpointer)web_browser);
+
if (place == PIDGIN_BROWSER_NEW_WINDOW)
- command = g_strdup_printf("%s -w %s", web_browser, escaped);
+ argv = g_slist_append(argv, "-w");
else if (place == PIDGIN_BROWSER_NEW_TAB)
- command = g_strdup_printf("%s -n %s", web_browser, escaped);
- else
- command = g_strdup_printf("%s %s", web_browser, escaped);
- }
- else if (!strcmp(web_browser, "xdg-open"))
- {
- command = g_strdup_printf("xdg-open %s", escaped);
- }
- else if (!strcmp(web_browser, "gnome-open"))
- {
- command = g_strdup_printf("gnome-open %s", escaped);
- }
- else if (!strcmp(web_browser, "kfmclient"))
- {
- command = g_strdup_printf("kfmclient openURL %s", escaped);
+ argv = g_slist_append(argv, "-n");
+
+ argv = g_slist_append(argv, (gpointer)uri);
+ } else if (!strcmp(web_browser, "xdg-open")) {
+ argv = g_slist_append(argv, "xdg-open");
+ argv = g_slist_append(argv, uri_escaped);
+ } else if (!strcmp(web_browser, "gnome-open")) {
+ argv = g_slist_append(argv, "gnome-open");
+ argv = g_slist_append(argv, uri_escaped);
+ } else if (!strcmp(web_browser, "kfmclient")) {
+ argv = g_slist_append(argv, "kfmclient");
+ argv = g_slist_append(argv, "openURL");
+ argv = g_slist_append(argv, (gpointer)uri);
/*
* Does Konqueror have options to open in new tab
* and/or current window?
*/
- }
- else if (!strcmp(web_browser, "mozilla") ||
- !strcmp(web_browser, "mozilla-firebird") ||
- !strcmp(web_browser, "firefox") ||
- !strcmp(web_browser, "seamonkey"))
+ } else if (!strcmp(web_browser, "mozilla") ||
+ !strcmp(web_browser, "mozilla-firebird") ||
+ !strcmp(web_browser, "firefox") ||
+ !strcmp(web_browser, "seamonkey"))
{
- char *args = "";
+ argv = g_slist_append(argv, (gpointer)web_browser);
+ argv = g_slist_append(argv, uri_escaped);
- command = g_strdup_printf("%s %s", web_browser, escaped);
+ g_assert(uri_custom == NULL);
+ if (place == PIDGIN_BROWSER_NEW_WINDOW) {
+ uri_custom = g_strdup_printf("openURL(%s,new-window)",
+ uri_escaped);
+ } else if (place == PIDGIN_BROWSER_NEW_TAB) {
+ uri_custom = g_strdup_printf("openURL(%s,new-tab)",
+ uri_escaped);
+ } else if (place == PIDGIN_BROWSER_CURRENT) {
+ uri_custom = g_strdup_printf("openURL(%s)",
+ uri_escaped);
+ }
- /*
- * Firefox 0.9 and higher require a "-a firefox" option when
- * using -remote commands. This breaks older versions of
- * mozilla. So we include this other handly little string
- * when calling firefox. If the API for remote calls changes
- * any more in firefox then firefox should probably be split
- * apart from mozilla-firebird and mozilla... but this is good
- * for now.
- */
- if (!strcmp(web_browser, "firefox"))
- args = "-a firefox";
+ if (uri_custom != NULL) {
+ argv_remote = g_slist_append(argv_remote,
+ (gpointer)web_browser);
+
+ /* Firefox 0.9 and higher require a "-a firefox" option
+ * when using -remote commands. This breaks older
+ * versions of mozilla. So we include this other handly
+ * little string when calling firefox. If the API for
+ * remote calls changes any more in firefox then firefox
+ * should probably be split apart from mozilla-firebird
+ * and mozilla... but this is good for now.
+ */
+ if (!strcmp(web_browser, "firefox")) {
+ argv_remote = g_slist_append(argv_remote, "-a");
+ argv_remote = g_slist_append(argv_remote,
+ "firefox");
+ }
+
+ argv_remote = g_slist_append(argv_remote, "-remote");
+ argv_remote = g_slist_append(argv_remote, uri_custom);
+ }
+ } else if (!strcmp(web_browser, "netscape")) {
+ argv = g_slist_append(argv, "netscape");
+ argv = g_slist_append(argv, (gpointer)uri);
+
+ if (place == PIDGIN_BROWSER_NEW_WINDOW) {
+ uri_custom = g_strdup_printf("openURL(%s,new-window)",
+ uri_escaped);
+ } else if (place == PIDGIN_BROWSER_CURRENT) {
+ uri_custom = g_strdup_printf("openURL(%s)",
+ uri_escaped);
+ }
+
+ if (uri_custom) {
+ argv_remote = g_slist_append(argv_remote, "netscape");
+ argv_remote = g_slist_append(argv_remote, "-remote");
+ argv_remote = g_slist_append(argv_remote, uri_custom);
+ }
+ } else if (!strcmp(web_browser, "opera")) {
+ argv = g_slist_append(argv, "opera");
if (place == PIDGIN_BROWSER_NEW_WINDOW)
- remote_command = g_strdup_printf("%s %s -remote "
- "openURL(%s,new-window)",
- web_browser, args, escaped);
+ argv = g_slist_append(argv, "-newwindow");
else if (place == PIDGIN_BROWSER_NEW_TAB)
- remote_command = g_strdup_printf("%s %s -remote "
- "openURL(%s,new-tab)",
- web_browser, args, escaped);
+ argv = g_slist_append(argv, "-newpage");
else if (place == PIDGIN_BROWSER_CURRENT)
- remote_command = g_strdup_printf("%s %s -remote "
- "openURL(%s)",
- web_browser, args, escaped);
More information about the Commits
mailing list