[NetworkManager-openvpn/wip/ernestask/tls-crypt-v2-client] Handle tls-crypt-v2 keys




commit 7be297924a5d93e5c4d6a2e65398875bfc9dbb57
Author: Ernestas Kulik <ernestas@baltic.engineering>
Date:   Mon Jan 11 17:30:13 2021 +0200

    Handle tls-crypt-v2 keys
    
    OpenVPN 2.5.0 adds client-specific tls-crypt keys under the tls-crypt-v2
    option, which is currently not supported. This commit adds the necessary
    import/export machinery to support it.

 properties/import-export.c            | 16 ++++++++++-
 properties/nm-openvpn-dialog.ui       |  3 +++
 properties/nm-openvpn-editor.c        | 23 ++++++++++++----
 properties/tests/conf/tls4.ovpn       | 28 +++++++++++++++++++
 properties/tests/test-import-export.c | 51 +++++++++++++++++++++++++++++++++++
 shared/nm-service-defines.h           |  1 +
 shared/utils.h                        |  1 +
 src/nm-openvpn-service.c              |  8 ++++++
 8 files changed, 125 insertions(+), 6 deletions(-)
---
diff --git a/properties/import-export.c b/properties/import-export.c
index ad9505d..7b7e95a 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -47,6 +47,7 @@
 #define INLINE_BLOB_SECRET              NMV_OVPN_TAG_SECRET
 #define INLINE_BLOB_TLS_AUTH            NMV_OVPN_TAG_TLS_AUTH
 #define INLINE_BLOB_TLS_CRYPT           NMV_OVPN_TAG_TLS_CRYPT
+#define INLINE_BLOB_TLS_CRYPT_v2        NMV_OVPN_TAG_TLS_CRYPT_v2
 
 const char *_nmovpn_test_temp_path = NULL;
 
@@ -1268,7 +1269,8 @@ do_import (const char *path, const char *contents, gsize contents_len, GError **
                                  NMV_OVPN_TAG_PKCS12,
                                  NMV_OVPN_TAG_SECRET,
                                  NMV_OVPN_TAG_TLS_AUTH,
-                                 NMV_OVPN_TAG_TLS_CRYPT)) {
+                                 NMV_OVPN_TAG_TLS_CRYPT,
+                                 NMV_OVPN_TAG_TLS_CRYPT_v2)) {
                        const char *file;
                        gs_free char *file_free = NULL;
                        gboolean can_have_direction;
@@ -1324,6 +1326,8 @@ do_import (const char *path, const char *contents, gsize contents_len, GError **
                                allow_ta_direction = TRUE;
                        } else if (NM_IN_STRSET (params[0], NMV_OVPN_TAG_TLS_CRYPT))
                                setting_vpn_add_data_item_path (s_vpn, NM_OPENVPN_KEY_TLS_CRYPT, file);
+                       else if (NM_IN_STRSET (params[0], NMV_OVPN_TAG_TLS_CRYPT_v2))
+                               setting_vpn_add_data_item_path (s_vpn, NM_OPENVPN_KEY_TLS_CRYPT_v2, file);
                        else if (NM_IN_STRSET (params[0], NMV_OVPN_TAG_EXTRA_CERTS))
                                setting_vpn_add_data_item_path (s_vpn, NM_OPENVPN_KEY_EXTRA_CERTS, file);
                        else
@@ -1538,6 +1542,8 @@ do_import (const char *path, const char *contents, gsize contents_len, GError **
                                key = NM_OPENVPN_KEY_CRL_VERIFY_FILE;
                        else if (nm_streq (token, INLINE_BLOB_TLS_CRYPT))
                                key = NM_OPENVPN_KEY_TLS_CRYPT;
+                       else if (nm_streq (token, INLINE_BLOB_TLS_CRYPT_v2))
+                               key = NM_OPENVPN_KEY_TLS_CRYPT_v2;
                        else if (nm_streq (token, INLINE_BLOB_TLS_AUTH)) {
                                key = NM_OPENVPN_KEY_TA;
                                allow_ta_direction = TRUE;
@@ -2216,6 +2222,14 @@ do_export_create (NMConnection *connection, const char *path, GError **error)
                                         nm_utils_str_utf8safe_unescape (key, &s_free));
                }
 
+               key = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_CRYPT_v2);
+               if (nmovpn_arg_is_set (key)) {
+                       gs_free char *s_free = NULL;
+                       args_write_line (f,
+                                        NMV_OVPN_TAG_TLS_CRYPT_v2,
+                                        nm_utils_str_utf8safe_unescape (key, &s_free));
+               }
+
                key = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_VERSION_MIN);
                if (nmovpn_arg_is_set (key))
                        args_write_line (f, NMV_OVPN_TAG_TLS_VERSION_MIN, key);
diff --git a/properties/nm-openvpn-dialog.ui b/properties/nm-openvpn-dialog.ui
index cffbc2d..228cca5 100644
--- a/properties/nm-openvpn-dialog.ui
+++ b/properties/nm-openvpn-dialog.ui
@@ -118,6 +118,9 @@
       <row>
         <col id="0" translatable="yes">TLS-Crypt</col>
       </row>
+      <row>
+        <col id="0" translatable="yes">TLS-Crypt v2</col>
+      </row>
     </data>
   </object>
   <object class="GtkListStore" id="model11">
diff --git a/properties/nm-openvpn-editor.c b/properties/nm-openvpn-editor.c
index 4f82ab3..80d94fa 100644
--- a/properties/nm-openvpn-editor.c
+++ b/properties/nm-openvpn-editor.c
@@ -713,6 +713,7 @@ static const char *const advanced_keys[] = {
        NM_OPENVPN_KEY_TAP_DEV,
        NM_OPENVPN_KEY_TA_DIR,
        NM_OPENVPN_KEY_TLS_CRYPT,
+       NM_OPENVPN_KEY_TLS_CRYPT_v2,
        NM_OPENVPN_KEY_TLS_REMOTE,
        NM_OPENVPN_KEY_TLS_VERSION_MIN,
        NM_OPENVPN_KEY_TLS_VERSION_MAX,
@@ -1121,9 +1122,10 @@ populate_remote_cert_tls_combo (GtkComboBox *box, const char *remote_cert)
        g_object_unref (store);
 }
 
-#define TLS_AUTH_MODE_NONE  0
-#define TLS_AUTH_MODE_AUTH  1
-#define TLS_AUTH_MODE_CRYPT 2
+#define TLS_AUTH_MODE_NONE     0
+#define TLS_AUTH_MODE_AUTH     1
+#define TLS_AUTH_MODE_CRYPT    2
+#define TLS_AUTH_MODE_CRYPT_v2 3
 
 static void
 tls_auth_toggled_cb (GtkWidget *widget, gpointer user_data)
@@ -1455,7 +1457,7 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
        GtkBuilder *builder;
        GtkWidget *dialog = NULL;
        GtkWidget *widget, *combo, *spin, *entry, *ok_button;
-       const char *value, *value2;
+       const char *value, *value2, *value3;
        const char *dev, *dev_type, *tap_dev;
        GtkListStore *store;
        GtkTreeIter iter;
@@ -1699,7 +1701,11 @@ advanced_dialog_new (GHashTable *hash, const char *contype)
                widget = GTK_WIDGET (gtk_builder_get_object (builder, "tls_auth_chooser"));
                value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TA);
                value2 = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TLS_CRYPT);
-               if (value2 && value2[0]) {
+               value3 = g_hash_table_lookup (hash, NM_OPENVPN_KEY_TLS_CRYPT_v2);
+               if (value3 && value3[0]) {
+                       gtk_combo_box_set_active (GTK_COMBO_BOX (combo), TLS_AUTH_MODE_CRYPT_v2);
+                       gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value3);
+               } else if (value2 && value2[0]) {
                        gtk_combo_box_set_active (GTK_COMBO_BOX (combo), TLS_AUTH_MODE_CRYPT);
                        gtk_file_chooser_set_filename (GTK_FILE_CHOOSER (widget), value2);
                } else if (value && value[0]) {
@@ -2131,6 +2137,13 @@ advanced_dialog_new_hash_from_dialog (GtkWidget *dialog)
                                g_hash_table_insert (hash, NM_OPENVPN_KEY_TLS_CRYPT, g_strdup (filename));
                        g_free (filename);
                        break;
+               case TLS_AUTH_MODE_CRYPT_v2:
+                       widget = GTK_WIDGET (gtk_builder_get_object (builder, "tls_auth_chooser"));
+                       filename = gtk_file_chooser_get_filename (GTK_FILE_CHOOSER (widget));
+                       if (filename && filename[0])
+                               g_hash_table_insert (hash, NM_OPENVPN_KEY_TLS_CRYPT_v2, g_strdup (filename));
+                       g_free (filename);
+                       break;
                case TLS_AUTH_MODE_NONE:
                        break;
                }
diff --git a/properties/tests/conf/tls4.ovpn b/properties/tests/conf/tls4.ovpn
new file mode 100644
index 0000000..d6ab2bf
--- /dev/null
+++ b/properties/tests/conf/tls4.ovpn
@@ -0,0 +1,28 @@
+remote 173.8.149.245 1194
+resolv-retry infinite
+
+dev tun
+persist-key
+persist-tun
+link-mtu 1400
+proto udp
+nobind
+pull
+tls-client
+
+float
+
+ca keys/mg8.ca
+cert keys/clee.crt
+key keys/clee.key
+
+tls-crypt-v2 keys/46.key
+remote-cert-tls server
+tls-remote "/CN=myvpn.company.com"
+verify-x509-name "C=US, L=Cambridge, CN=GNOME, emailAddress=networkmanager-list gnome org" subject
+
+comp-lzo
+verb 3
+
+tls-version-min 1.0
+tls-version-max 1.2
diff --git a/properties/tests/test-import-export.c b/properties/tests/test-import-export.c
index c8b43e8..ff4dfa5 100644
--- a/properties/tests/test-import-export.c
+++ b/properties/tests/test-import-export.c
@@ -431,6 +431,54 @@ test_tls_import_3 (void)
 
 }
 
+static void
+test_tls_import_4 (void)
+{
+       _CREATE_PLUGIN (plugin);
+       gs_unref_object NMConnection *connection = NULL;
+       NMSettingConnection *s_con;
+       NMSettingVpn *s_vpn;
+
+       connection = get_basic_connection (plugin, SRCDIR, "tls4.ovpn");
+
+       s_con = _get_setting_connection (connection);
+       g_assert_cmpstr (nm_setting_connection_get_id (s_con), ==, "tls4");
+       g_assert (!nm_setting_connection_get_uuid (s_con));
+
+       s_vpn = _get_setting_vpn (connection);
+
+       _check_item (s_vpn, NM_OPENVPN_KEY_CONNECTION_TYPE, NM_OPENVPN_CONTYPE_TLS);
+       _check_item (s_vpn, NM_OPENVPN_KEY_DEV, "tun");
+       _check_item (s_vpn, NM_OPENVPN_KEY_PROTO_TCP, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_COMP_LZO, "adaptive");
+       _check_item (s_vpn, NM_OPENVPN_KEY_FLOAT, "yes");
+       _check_item (s_vpn, NM_OPENVPN_KEY_RENEG_SECONDS, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_REMOTE, "173.8.149.245:1194");
+       _check_item (s_vpn, NM_OPENVPN_KEY_PORT, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_STATIC_KEY, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_STATIC_KEY_DIRECTION, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_CIPHER, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_LOCAL_IP, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_REMOTE_IP, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_AUTH, NULL);
+       _check_item (s_vpn, NM_OPENVPN_KEY_TLS_REMOTE, "/CN=myvpn.company.com");
+       _check_item (s_vpn, NM_OPENVPN_KEY_VERIFY_X509_NAME,
+                    "subject:C=US, L=Cambridge, CN=GNOME, emailAddress=networkmanager-list gnome org");
+       _check_item (s_vpn, NM_OPENVPN_KEY_REMOTE_CERT_TLS, "server");
+
+       _check_item (s_vpn, NM_OPENVPN_KEY_CA,           SRCDIR"/keys/mg8.ca");
+       _check_item (s_vpn, NM_OPENVPN_KEY_CERT,         SRCDIR"/keys/clee.crt");
+       _check_item (s_vpn, NM_OPENVPN_KEY_KEY,          SRCDIR"/keys/clee.key");
+       _check_item (s_vpn, NM_OPENVPN_KEY_TLS_CRYPT_v2, SRCDIR"/keys/46.key");
+
+       _check_secret (s_vpn, NM_OPENVPN_KEY_PASSWORD, NULL);
+       _check_secret (s_vpn, NM_OPENVPN_KEY_CERTPASS, NULL);
+
+       _check_item (s_vpn, NM_OPENVPN_KEY_TLS_VERSION_MIN, "1.0");
+       _check_item (s_vpn, NM_OPENVPN_KEY_TLS_VERSION_MAX, "1.2");
+
+}
+
 static void
 test_file_contents (const char *id,
                     const char *dir,
@@ -1286,6 +1334,9 @@ int main (int argc, char **argv)
        _add_test_func_simple (test_tls_import_3);
        _add_test_func ("tls3-export", test_export_compare, "tls3.ovpn", "tls3.ovpntest");
 
+       _add_test_func_simple (test_tls_import_4);
+       _add_test_func ("tls4-export", test_export_compare, "tls4.ovpn", "tls4.ovpntest");
+
        _add_test_func_simple (test_pkcs12_import);
        _add_test_func ("pkcs12-export", test_export_compare, "pkcs12.ovpn", "pkcs12.ovpntest");
 
diff --git a/shared/nm-service-defines.h b/shared/nm-service-defines.h
index 46b4104..b4205fb 100644
--- a/shared/nm-service-defines.h
+++ b/shared/nm-service-defines.h
@@ -77,6 +77,7 @@
 #define NM_OPENVPN_KEY_TA_DIR                    "ta-dir"
 #define NM_OPENVPN_KEY_TLS_CIPHER                "tls-cipher"
 #define NM_OPENVPN_KEY_TLS_CRYPT                 "tls-crypt"
+#define NM_OPENVPN_KEY_TLS_CRYPT_v2              "tls-crypt-v2"
 #define NM_OPENVPN_KEY_TLS_REMOTE                "tls-remote"
 #define NM_OPENVPN_KEY_TLS_VERSION_MIN           "tls-version-min"
 #define NM_OPENVPN_KEY_TLS_VERSION_MAX           "tls-version-max"
diff --git a/shared/utils.h b/shared/utils.h
index 477ad70..e9a98ec 100644
--- a/shared/utils.h
+++ b/shared/utils.h
@@ -79,6 +79,7 @@
 #define NMV_OVPN_TAG_TLS_CIPHER             "tls-cipher"
 #define NMV_OVPN_TAG_TLS_CLIENT             "tls-client"
 #define NMV_OVPN_TAG_TLS_CRYPT              "tls-crypt"
+#define NMV_OVPN_TAG_TLS_CRYPT_v2           "tls-crypt-v2"
 #define NMV_OVPN_TAG_TLS_REMOTE             "tls-remote"
 #define NMV_OVPN_TAG_TLS_VERSION_MIN        "tls-version-min"
 #define NMV_OVPN_TAG_TLS_VERSION_MAX        "tls-version-max"
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index 034556f..d0f10e3 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -185,6 +185,7 @@ static const ValidProperty valid_properties[] = {
        { NM_OPENVPN_KEY_TUN_IPV6,                  G_TYPE_STRING, 0, 0, FALSE },
        { NM_OPENVPN_KEY_TLS_CIPHER,                G_TYPE_STRING, 0, 0, FALSE },
        { NM_OPENVPN_KEY_TLS_CRYPT,                 G_TYPE_STRING, 0, 0, FALSE },
+       { NM_OPENVPN_KEY_TLS_CRYPT_v2,              G_TYPE_STRING, 0, 0, FALSE },
        { NM_OPENVPN_KEY_TLS_REMOTE,                G_TYPE_STRING, 0, 0, FALSE },
        { NM_OPENVPN_KEY_VERIFY_X509_NAME,          G_TYPE_STRING, 0, 0, FALSE },
        { NM_OPENVPN_KEY_REMOTE_CERT_TLS,           G_TYPE_STRING, 0, 0, FALSE },
@@ -1699,6 +1700,13 @@ nm_openvpn_start_openvpn_binary (NMOpenvpnPlugin *plugin,
                args_add_strv (args, "--tls-crypt");
                args_add_utf8safe_str (args, tmp);
        }
+
+       tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_CRYPT_v2);
+       if (nmovpn_arg_is_set (tmp)) {
+               args_add_strv (args, "--tls-crypt-v2");
+               args_add_utf8safe_str (args, tmp);
+       
+       }
        tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TLS_VERSION_MIN);
        if (nmovpn_arg_is_set (tmp)) {
                args_add_strv (args, "--tls-version-min");


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