[network-manager-openvpn] core/ui: allow specifying port and protocol for gateways (bgo #712710)



commit c55ba4e8c21f4980af848881cd1615460c7f0622
Author: Jiří Klimeš <jklimes redhat com>
Date:   Wed Jun 25 19:30:19 2014 +0200

    core/ui: allow specifying port and protocol for gateways (bgo #712710)
    
    The original commit cb81bdce that brought multiple gateway support didn't take
    port and protocol into account.
    
    https://bugzilla.gnome.org/show_bug.cgi?id=712710

 properties/nm-openvpn-dialog.ui |    2 +-
 properties/nm-openvpn.c         |   54 ++++++++++++++++++++++++++++++++++++++-
 src/nm-openvpn-service.c        |   42 +++++++++++++++++++++++++++---
 3 files changed, 92 insertions(+), 6 deletions(-)
---
diff --git a/properties/nm-openvpn-dialog.ui b/properties/nm-openvpn-dialog.ui
index 16bd554..569a7f1 100644
--- a/properties/nm-openvpn-dialog.ui
+++ b/properties/nm-openvpn-dialog.ui
@@ -1345,7 +1345,7 @@ config: http-proxy-retry or socks-proxy-retry</property>
                       <object class="GtkEntry" id="gateway_entry">
                         <property name="visible">True</property>
                         <property name="can_focus">True</property>
-                        <property name="tooltip_text" translatable="yes">Remote host name or IP address. You 
can specify multiple items for redundancy (use commas to separate the entries).
+                        <property name="tooltip_text" translatable="yes">Remote gateway(s), with optional 
port and protocol (e.g. ovpn.corp.com:1234:tcp). You can specify multiple hosts for redundancy (use commas or 
spaces as delimiters).
 config: remote</property>
                       </object>
                     </child>
diff --git a/properties/nm-openvpn.c b/properties/nm-openvpn.c
index a7404b9..b49fece 100644
--- a/properties/nm-openvpn.c
+++ b/properties/nm-openvpn.c
@@ -127,6 +127,51 @@ openvpn_plugin_ui_error_get_type (void)
        return etype;
 }
 
+/* Example: abc.com:1234:udp, ovpnserver.company.com:443, vpn.example.com::tcp */
+static gboolean
+check_gateway_entry (const char *str)
+{
+       char **list, **iter;
+       char *host, *port, *proto;
+       long int port_int;
+       gboolean success = FALSE;
+
+       if (!str || !*str)
+               return FALSE;
+
+       list = g_strsplit_set (str, " \t,", -1);
+       for (iter = list; iter && *iter; iter++) {
+               if (!**iter)
+                       continue;
+               host = g_strstrip (*iter);
+               port = strchr (host, ':');
+               proto = port ? strchr (port + 1, ':') : NULL;
+               if (port)
+                       *port++ = '\0';
+               if (proto)
+                       *proto++ = '\0';
+
+               /* check hostname */
+               if (!host || !*host)
+                       goto out;
+               /* check port */
+               if (port && *port) {
+                       char *end;
+                       errno = 0;
+                       port_int = strtol (port, &end, 10);
+                       if (errno != 0 || *end != '\0' || port_int < 1 || port_int > 65535)
+                               goto out;
+               }
+               /* check proto */
+               if (proto && strcmp (proto, "udp") && strcmp (proto, "tcp"))
+                       goto out;
+       }
+       success = TRUE;
+out:
+       g_strfreev (list);
+       return success;
+}
+
 static gboolean
 check_validity (OpenvpnPluginUiWidget *self, GError **error)
 {
@@ -136,10 +181,17 @@ check_validity (OpenvpnPluginUiWidget *self, GError **error)
        GtkTreeModel *model;
        GtkTreeIter iter;
        const char *contype = NULL;
+       GdkRGBA rgba;
+       gboolean gateway_valid;
 
        widget = GTK_WIDGET (gtk_builder_get_object (priv->builder, "gateway_entry"));
        str = gtk_entry_get_text (GTK_ENTRY (widget));
-       if (!str || !strlen (str)) {
+       gateway_valid = check_gateway_entry (str);
+       /* Change entry background colour while editing */
+       if (!gateway_valid)
+               gdk_rgba_parse (&rgba, "red3");
+       gtk_widget_override_background_color (widget, GTK_STATE_NORMAL, !gateway_valid ? &rgba : NULL);
+       if (!gateway_valid) {
                g_set_error (error,
                             OPENVPN_PLUGIN_UI_ERROR,
                             OPENVPN_PLUGIN_UI_ERROR_INVALID_PROPERTY,
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index b45eb28..a9656bc 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -908,14 +908,48 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
        add_openvpn_arg (args, openvpn_binary);
 
        tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_REMOTE);
-       if (tmp && strlen (tmp)) {
-               char *tok;
-               while ((tok = strsep((char**)&tmp, " ,")) != NULL) {
-                       if (strlen(tok)) {
+       if (tmp && *tmp) {
+               char *tok, *port, *proto;
+               char *tmp_dup = strdup (tmp);
+               while ((tok = strsep (&tmp_dup, " \t,")) != NULL) {
+                       if (*tok) {
+                               port = strchr (tok, ':');
+                               proto = port ? strchr (port + 1, ':') : NULL;
+                               if (port)
+                                       *port++ = '\0';
+                               if (proto)
+                                       *proto++ = '\0';
+
                                add_openvpn_arg (args, "--remote");
                                add_openvpn_arg (args, tok);
+                               if (port) {
+                                       if (!add_openvpn_arg_int (args, port)) {
+                                               g_set_error (error,
+                                                            NM_VPN_PLUGIN_ERROR,
+                                                            NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+                                                            _("Invalid port number '%s'."), port);
+                                               free_openvpn_args (args);
+                                               g_free (tmp_dup);
+                                               return FALSE;
+                                       }
+                               } else
+                                       add_openvpn_arg (args, "1194"); /* use default IANA port */
+                               if (proto) {
+                                       if (!strcmp (proto, "udp") || !strcmp (proto, "tcp"))
+                                               add_openvpn_arg (args, proto);
+                                       else {
+                                               g_set_error (error,
+                                                            NM_VPN_PLUGIN_ERROR,
+                                                            NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+                                                            _("Invalid proto '%s'."), proto);
+                                               free_openvpn_args (args);
+                                               g_free (tmp_dup);
+                                               return FALSE;
+                                       }
+                               }
                        }
                }
+               g_free (tmp_dup);
        }
 
        /* Remote random */


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