Fix parsing of cert filename, prevent the Tools / SSL/TLS Certificates dialog from...
authorwwp <subscript@free.fr>
Mon, 17 Dec 2018 20:11:19 +0000 (21:11 +0100)
committerwwp <subscript@free.fr>
Mon, 17 Dec 2018 20:11:19 +0000 (21:11 +0100)
src/common/utils.c
src/common/utils.h
src/ssl_manager.c

index b9a6f95..0e6e674 100644 (file)
@@ -4611,3 +4611,60 @@ get_random_bytes(void *buf, size_t count)
 
        return TRUE;
 }
+
+/* returns FALSE if parsing failed, otherwise returns TRUE and sets *server, *port
+   and eventually *fp from filename (if not NULL, they must be free'd by caller after
+   user.
+   filenames we expect: 'host.name.port.cert' or 'host.name.port.f:i:n:g:e:r:p:r:i:n:t.cert' */
+gboolean get_serverportfp_from_filename(const gchar *str, gchar **server, gchar **port, gchar **fp)
+{
+       const gchar *pos, *dotport_pos = NULL, *dotcert_pos = NULL, *dotfp_pos = NULL;
+
+       g_return_val_if_fail(str != NULL, FALSE);
+
+       pos = str + strlen(str) - 1;
+       while ((pos > str) && !dotport_pos) {
+               if (*pos == '.') {
+                       if (!dotcert_pos) {
+                               /* match the .cert suffix */
+                               if (strcmp(pos, ".cert") == 0) {
+                                       dotcert_pos = pos;
+                               }
+                       } else {
+                               if (!dotfp_pos) {
+                                       /* match an eventual fingerprint */
+                                       /* or the port number */
+                                       if (strncmp(pos + 3, ":", 1) == 0) {
+                                               dotfp_pos = pos;
+                                       } else {
+                                               dotport_pos = pos;      
+                                       }
+                               } else {
+                                       /* match the port number */
+                                       dotport_pos = pos;      
+                               }
+                       }
+               }
+               pos--;
+       }
+       if (!dotport_pos || !dotcert_pos) {
+               g_warning("could not parse filename %s", str);
+               return FALSE;
+       }
+
+       *server = g_strndup(str, dotport_pos - str);
+       if (dotfp_pos) {
+               *port = g_strndup(dotport_pos + 1, dotfp_pos - dotport_pos - 1);
+               *fp = g_strndup(dotfp_pos + 1, dotcert_pos - dotfp_pos - 1);
+       } else {
+               *port = g_strndup(dotport_pos + 1, dotcert_pos - dotport_pos - 1);
+               *fp = NULL;
+       }
+
+       debug_print("filename='%s' => server='%s' port='%s' fp='%s'\n", str, *server, *port, *fp);
+       if (!*server || !*port)
+               return FALSE;
+       else
+               return TRUE;
+}
+
index 40c3576..1799935 100644 (file)
@@ -541,4 +541,6 @@ gboolean get_random_bytes(void *buf, size_t count);
 }
 #endif
 
+gboolean get_serverportfp_from_filename(const gchar *str, gchar **server, gchar **port, gchar **fp);
+
 #endif /* __UTILS_H__ */
index 495edf7..f51ca33 100644 (file)
@@ -164,7 +164,6 @@ static GtkWidget *ssl_manager_list_view_create      (void)
        ssl_manager_create_list_view_columns(GTK_WIDGET(list_view));
 
        return GTK_WIDGET(list_view);
-
 }
 
 void ssl_manager_create(void)
@@ -240,58 +239,6 @@ void ssl_manager_create(void)
        gtk_widget_show(window);
 }
 
-static gboolean get_serverport(const gchar *str, gchar **server, gchar **port)
-{
-       const gchar *pos, *prevpos;
-
-       g_return_val_if_fail(str != NULL, FALSE);
-
-       /* We expect 'host.name.port.cert' here, only set
-        * server and port if we find that.
-        * Validity of string in port should be checked by caller. */
-       for (prevpos = str, pos = strstr(str, ".");
-                       pos != NULL;
-                       prevpos = pos, pos = strstr(pos+1, ".")) {
-               if (!strcmp(pos, ".cert")) {
-                       if (prevpos > str) {
-                               *server = g_strndup(str, prevpos - str);
-                               *port = g_strndup(prevpos+1, pos - prevpos - 1);
-                       } else {
-                               *server = *port = NULL;
-                       }
-
-                       return TRUE;
-               }
-       }
-
-       return FALSE;
-}
-
-static char *get_fingerprint(const char *str)
-{
-       char *ret = NULL, *tmp = g_strdup(str), *tmp2 = tmp;
-       char *previous_pos = NULL, *last_pos = NULL;
-
-       if (!strchr(tmp, ':')) {
-               /* no fingerprint */
-               if (strstr(tmp, ".cert"))
-                       *(strstr(tmp, ".cert")+1) = '.';
-       }
-
-       while (tmp2 && (tmp2 = strstr(tmp2,".")) != NULL) {
-               tmp2++;
-               previous_pos = last_pos;
-               last_pos = tmp2;
-       }
-       if (last_pos && previous_pos && (int)(last_pos - previous_pos - 1) > 0)
-               ret = g_strndup(previous_pos, (int)(last_pos - previous_pos - 1));
-       else
-               ret = NULL;
-       g_free(tmp);
-       return ret;
-       
-}
-
 static void ssl_manager_list_view_insert_cert(GtkWidget *list_view,
                                                  GtkTreeIter *row_iter,
                                                  gchar *host, 
@@ -307,6 +254,8 @@ static void ssl_manager_list_view_insert_cert(GtkWidget *list_view,
        GtkListStore *list_store = GTK_LIST_STORE(gtk_tree_view_get_model
                                        (GTK_TREE_VIEW(list_view)));
 
+       g_return_if_fail(cert != NULL);
+
        exp_time_t = gnutls_x509_crt_get_expiration_time(cert->x509_cert);
 
        memset(buf, 0, sizeof(buf));
@@ -321,7 +270,7 @@ static void ssl_manager_list_view_insert_cert(GtkWidget *list_view,
 
        sig_status = ssl_certificate_check_signer(cert, cert->status);
 
-       if (sig_status==NULL)
+       if (sig_status == NULL)
                sig_status = g_strdup_printf(_("Correct%s"),exp_time_t < time(NULL)? _(" (expired)"): "");
        else {
                 weight = PANGO_WEIGHT_BOLD;
@@ -380,21 +329,21 @@ static void ssl_manager_load_certs (void)
                if(strstr(d, ".cert") != d + (strlen(d) - strlen(".cert"))) 
                        continue;
 
-               get_serverport(d, &server, &port);
-               fp = get_fingerprint(d);
+               if (get_serverportfp_from_filename(d, &server, &port, &fp)) {
 
-               if (server != NULL && port != NULL) {
-                       gint portnum = atoi(port);
-                       if (portnum > 0 && portnum <= 65535) {
-                               cert = ssl_certificate_find(server, portnum, fp);
-                               ssl_manager_list_view_insert_cert(manager.certlist, NULL,
-                                               server, port, cert);
+                       if (server != NULL && port != NULL) {
+                               gint portnum = atoi(port);
+                               if (portnum > 0 && portnum <= 65535) {
+                                       cert = ssl_certificate_find(server, portnum, fp);
+                                       ssl_manager_list_view_insert_cert(manager.certlist, NULL,
+                                                       server, port, cert);
+                               }
                        }
-               }
                
-               g_free(server);
-               g_free(port);
-               g_free(fp);
+                       g_free(server);
+                       g_free(port);
+                       g_free(fp);
+               }
                row++;
        }
        g_dir_close(dir);