]> asedeno.scripts.mit.edu Git - PuTTY.git/blobdiff - unix/gtkdlg.c
Properly check the lengths of Unix-socket pathnames.
[PuTTY.git] / unix / gtkdlg.c
index 573111aeede967676f5f2d6c4a86c87c43226046..f16119488e035018cb349432207b3b0e05373d0c 100644 (file)
@@ -33,6 +33,7 @@
 #include "storage.h"
 #include "dialog.h"
 #include "tree234.h"
+#include "licence.h"
 
 #if GTK_CHECK_VERSION(2,0,0)
 /* Decide which of GtkFileChooserDialog and GtkFileSelection to use */
@@ -2083,6 +2084,8 @@ GtkWidget *layout_ctrls(struct dlgparam *dp, struct Shortcuts *scs,
                                                       G_TYPE_STRING);
                    w = gtk_combo_box_new_with_model_and_entry
                        (GTK_TREE_MODEL(uc->listmodel));
+                    g_object_set(G_OBJECT(w), "entry-text-column", 1,
+                                 (const char *)NULL);
                    /* We cannot support password combo boxes. */
                    assert(!ctrl->editbox.password);
                    uc->combo = w;
@@ -3301,6 +3304,7 @@ int do_config_box(const char *title, Conf *conf, int midsession,
 
     dlg_cleanup(&dp);
     sfree(selparams);
+    ctrl_free_box(ctrlbox);
 
     return dp.retval;
 }
@@ -3312,12 +3316,12 @@ static void messagebox_handler(union control *ctrl, void *dlg,
        dlg_end(dlg, ctrl->generic.context.i);
 }
 int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
-               int minwid, ...)
+               int minwid, int selectable, ...)
 {
     GtkWidget *window, *w0, *w1;
     struct controlbox *ctrlbox;
     struct controlset *s0, *s1;
-    union control *c;
+    union control *c, *textctrl;
     struct dlgparam dp;
     struct Shortcuts scs;
     int index, ncols, min_type;
@@ -3336,7 +3340,7 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
      * buttons and find out what kinds there are.
      */
     ncols = 0;
-    va_start(ap, minwid);
+    va_start(ap, selectable);
     min_type = +1;
     while (va_arg(ap, char *) != NULL) {
         int type;
@@ -3357,7 +3361,7 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
     c->columns.percentages = sresize(c->columns.percentages, ncols, int);
     for (index = 0; index < ncols; index++)
        c->columns.percentages[index] = (index+1)*100/ncols - index*100/ncols;
-    va_start(ap, minwid);
+    va_start(ap, selectable);
     index = 0;
     while (1) {
        char *title = va_arg(ap, char *);
@@ -3388,7 +3392,7 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
     va_end(ap);
 
     s1 = ctrl_getset(ctrlbox, "x", "", "");
-    ctrl_text(s1, msg, HELPCTX(no_help));
+    textctrl = ctrl_text(s1, msg, HELPCTX(no_help));
 
     window = our_dialog_new();
     gtk_window_set_title(GTK_WINDOW(window), title);
@@ -3406,6 +3410,26 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
     dp.retval = 0;
     dp.window = window;
 
+    if (selectable) {
+#if GTK_CHECK_VERSION(2,0,0)
+        struct uctrl *uc = dlg_find_byctrl(&dp, textctrl);
+        gtk_label_set_selectable(GTK_LABEL(uc->text), TRUE);
+
+        /*
+         * GTK selectable labels have a habit of selecting their
+         * entire contents when they gain focus. It's ugly to have
+         * text in a message box start up all selected, so we suppress
+         * this by manually selecting none of it - but we must do this
+         * when the widget _already has_ focus, otherwise our work
+         * will be undone when it gains it shortly.
+         */
+        gtk_widget_grab_focus(uc->text);
+        gtk_label_select_region(GTK_LABEL(uc->text), 0, 0);
+#else
+        (void)textctrl;                /* placate warning */
+#endif
+    }
+
     gtk_window_set_modal(GTK_WINDOW(window), TRUE);
     if (parentwin) {
         set_transient_window_pos(parentwin, window);
@@ -3413,7 +3437,9 @@ int messagebox(GtkWidget *parentwin, const char *title, const char *msg,
                                     GTK_WINDOW(parentwin));
     } else
        gtk_window_set_position(GTK_WINDOW(window), GTK_WIN_POS_CENTER);
+    gtk_container_set_focus_child(GTK_CONTAINER(window), NULL);
     gtk_widget_show(window);
+    gtk_window_set_focus(GTK_WINDOW(window), NULL);
 
     g_signal_connect(G_OBJECT(window), "destroy",
                      G_CALLBACK(window_destroy), NULL);
@@ -3435,6 +3461,7 @@ int reallyclose(void *frontend)
     int ret = messagebox(GTK_WIDGET(get_window(frontend)),
                         title, "Are you sure you want to close this session?",
                         string_width("Most of the width of the above text"),
+                         FALSE,
                         "Yes", 'y', +1, 1,
                         "No", 'n', -1, 0,
                         NULL);
@@ -3488,6 +3515,7 @@ int verify_ssh_host_key(void *frontend, char *host, int port,
     ret = messagebox(GTK_WIDGET(get_window(frontend)),
                     "PuTTY Security Alert", text,
                     string_width(fingerprint),
+                     TRUE,
                     "Accept", 'a', 0, 2,
                     "Connect Once", 'o', 0, 1,
                     "Cancel", 'c', -1, 0,
@@ -3522,6 +3550,38 @@ int askalg(void *frontend, const char *algtype, const char *algname,
                     "PuTTY Security Alert", text,
                     string_width("Reasonably long line of text as a width"
                                   " template"),
+                     FALSE,
+                    "Yes", 'y', 0, 1,
+                    "No", 'n', 0, 0,
+                    NULL);
+    sfree(text);
+
+    if (ret) {
+       return 1;
+    } else {
+       return 0;
+    }
+}
+
+int askhk(void *frontend, const char *algname, const char *betteralgs,
+          void (*callback)(void *ctx, int result), void *ctx)
+{
+    static const char msg[] =
+       "The first host key type we have stored for this server\n"
+       "is %s, which is below the configured warning threshold.\n"
+       "The server also provides the following types of host key\n"
+        "above the threshold, which we do not have stored:\n"
+        "%s\n"
+       "Continue with connection?";
+    char *text;
+    int ret;
+
+    text = dupprintf(msg, algname, betteralgs);
+    ret = messagebox(GTK_WIDGET(get_window(frontend)),
+                    "PuTTY Security Alert", text,
+                    string_width("is ecdsa-nistp521, which is"
+                                  " below the configured warning threshold."),
+                     FALSE,
                     "Yes", 'y', 0, 1,
                     "No", 'n', 0, 0,
                     NULL);
@@ -3545,14 +3605,14 @@ void fatal_message_box(void *window, const char *msg)
 {
     messagebox(window, "PuTTY Fatal Error", msg,
                string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"),
-               "OK", 'o', 1, 1, NULL);
+               FALSE, "OK", 'o', 1, 1, NULL);
 }
 
 void nonfatal_message_box(void *window, const char *msg)
 {
     messagebox(window, "PuTTY Error", msg,
                string_width("REASONABLY LONG LINE OF TEXT FOR BASIC SANITY"),
-               "OK", 'o', 1, 1, NULL);
+               FALSE, "OK", 'o', 1, 1, NULL);
 }
 
 void fatalbox(const char *p, ...)
@@ -3599,42 +3659,12 @@ static void licence_clicked(GtkButton *button, gpointer data)
 {
     char *title;
 
-    const char *licence =
-       "Copyright 1997-2015 Simon Tatham.\n\n"
-
-       "Portions copyright Robert de Bath, Joris van Rantwijk, Delian "
-       "Delchev, Andreas Schultz, Jeroen Massar, Wez Furlong, Nicolas "
-       "Barry, Justin Bradford, Ben Harris, Malcolm Smith, Ahmad Khalifa, "
-       "Markus Kuhn, Colin Watson, Christopher Staite, and CORE SDI S.A.\n\n"
-
-       "Permission is hereby granted, free of charge, to any person "
-       "obtaining a copy of this software and associated documentation "
-       "files (the ""Software""), to deal in the Software without restriction, "
-       "including without limitation the rights to use, copy, modify, merge, "
-       "publish, distribute, sublicense, and/or sell copies of the Software, "
-       "and to permit persons to whom the Software is furnished to do so, "
-       "subject to the following conditions:\n\n"
-
-       "The above copyright notice and this permission notice shall be "
-       "included in all copies or substantial portions of the Software.\n\n"
-
-       "THE SOFTWARE IS PROVIDED ""AS IS"", WITHOUT "
-       "WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, "
-       "INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF "
-       "MERCHANTABILITY, FITNESS FOR A PARTICULAR "
-       "PURPOSE AND NONINFRINGEMENT.  IN NO EVENT SHALL THE "
-       "COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES "
-       "OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, "
-       "TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN "
-       "CONNECTION WITH THE SOFTWARE OR THE USE OR "
-       "OTHER DEALINGS IN THE SOFTWARE.";
-
     title = dupcat(appname, " Licence", NULL);
     assert(aboutbox != NULL);
-    messagebox(aboutbox, title, licence,
+    messagebox(aboutbox, title, LICENCE_TEXT("\n\n"),
               string_width("LONGISH LINE OF TEXT SO THE LICENCE"
                            " BOX ISN'T EXCESSIVELY TALL AND THIN"),
-              "OK", 'o', 1, 1, NULL);
+               TRUE, "OK", 'o', 1, 1, NULL);
     sfree(title);
 }
 
@@ -3671,16 +3701,27 @@ void about_box(void *window)
                      G_CALLBACK(licence_clicked), NULL);
     gtk_widget_show(w);
 
-    w = gtk_label_new(appname);
+    {
+        char *buildinfo_text = buildinfo("\n");
+        char *label_text = dupprintf
+            ("%s\n\n%s\n\n%s\n\n%s",
+             appname, ver, buildinfo_text,
+             "Copyright " SHORT_COPYRIGHT_DETAILS ". All rights reserved");
+        w = gtk_label_new(label_text);
+        gtk_label_set_justify(GTK_LABEL(w), GTK_JUSTIFY_CENTER);
+#if GTK_CHECK_VERSION(2,0,0)
+        gtk_label_set_selectable(GTK_LABEL(w), TRUE);
+#endif
+        sfree(label_text);
+    }
     our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 0);
-    gtk_widget_show(w);
-
-    w = gtk_label_new(ver);
-    our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 5);
-    gtk_widget_show(w);
-
-    w = gtk_label_new("Copyright 1997-2015 Simon Tatham. All rights reserved");
-    our_dialog_add_to_content_area(GTK_WINDOW(aboutbox), w, FALSE, FALSE, 5);
+#if GTK_CHECK_VERSION(2,0,0)
+    /*
+     * Same precautions against initial select-all as in messagebox().
+     */
+    gtk_widget_grab_focus(w);
+    gtk_label_select_region(GTK_LABEL(w), 0, 0);
+#endif
     gtk_widget_show(w);
 
     g_signal_connect(G_OBJECT(aboutbox), "key_press_event",
@@ -3689,7 +3730,9 @@ void about_box(void *window)
     set_transient_window_pos(GTK_WIDGET(window), aboutbox);
     gtk_window_set_transient_for(GTK_WINDOW(aboutbox),
                                 GTK_WINDOW(window));
+    gtk_container_set_focus_child(GTK_CONTAINER(aboutbox), NULL);
     gtk_widget_show(aboutbox);
+    gtk_window_set_focus(GTK_WINDOW(aboutbox), NULL);
 }
 
 struct eventlog_stuff {
@@ -3951,6 +3994,7 @@ int askappend(void *frontend, Filename *filename,
     mbret = messagebox(get_window(frontend), mbtitle, message,
                       string_width("LINE OF TEXT SUITABLE FOR THE"
                                    " ASKAPPEND WIDTH"),
+                       FALSE,
                       "Overwrite", 'o', 1, 2,
                       "Append", 'a', 0, 1,
                       "Disable", 'd', -1, 0,