Patch by Robert Scheck for NetworkManager-openvpn <= 0.8.0.997 which backports the keysize option. This keysize feature patch was originally written by Jiří Klimeš for NetworkManager-openvpn 0.9.x, reviewed by Thomas Haller and Dan Williams . In order to have this feature also available for Red Hat Enterprise Linux 6 (and derivates), this patch has been backported for NetworkManager-openvpn 0.8.x. See https://git.gnome.org/browse/network-manager-openvpn/commit/?id=3d10af0947ed6eb02d9812b120a33508d68c7b86 and https://bugzilla.gnome.org/show_bug.cgi?id=706775 as well as https://bugzilla.redhat.com/show_bug.cgi?id=471397 for some further information. --- NetworkManager-openvpn-0.8.0.997/properties/auth-helpers.c 2010-05-04 08:12:34.000000000 +0200 +++ NetworkManager-openvpn-0.8.0.997/properties/auth-helpers.c.keysize 2014-03-19 01:45:06.000000000 +0100 @@ -846,6 +846,7 @@ NM_OPENVPN_KEY_TAP_DEV, NM_OPENVPN_KEY_PROTO_TCP, NM_OPENVPN_KEY_CIPHER, + NM_OPENVPN_KEY_KEYSIZE, NM_OPENVPN_KEY_AUTH, NM_OPENVPN_KEY_TA_DIR, NM_OPENVPN_KEY_TA, @@ -922,6 +923,16 @@ gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))); } +static void +keysize_toggled_cb (GtkWidget *check, gpointer user_data) +{ + GladeXML *xml = (GladeXML *) user_data; + GtkWidget *widget; + + widget = glade_xml_get_widget (xml, "keysize_spinbutton"); + gtk_widget_set_sensitive (widget, gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (check))); +} + static const char * nm_find_openvpn (void) { @@ -1278,6 +1289,30 @@ value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_CIPHER); populate_cipher_combo (GTK_COMBO_BOX (widget), value); + widget = glade_xml_get_widget (xml, "keysize_checkbutton"); + g_assert (widget); + g_signal_connect (G_OBJECT (widget), "toggled", G_CALLBACK (keysize_toggled_cb), xml); + value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_KEYSIZE); + if (value && strlen (value)) { + long int tmp; + + errno = 0; + tmp = strtol (value, NULL, 10); + if (errno == 0 && tmp > 0 && tmp < 65536) { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), TRUE); + + widget = glade_xml_get_widget (xml, "keysize_spinbutton"); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), (gdouble) tmp); + gtk_widget_set_sensitive (widget, TRUE); + } + } else { + gtk_toggle_button_set_active (GTK_TOGGLE_BUTTON (widget), FALSE); + + widget = glade_xml_get_widget (xml, "keysize_spinbutton"); + gtk_spin_button_set_value (GTK_SPIN_BUTTON (widget), 128.0); + gtk_widget_set_sensitive (widget, FALSE); + } + widget = glade_xml_get_widget (xml, "hmacauth_combo"); value = g_hash_table_lookup (hash, NM_OPENVPN_KEY_AUTH); populate_hmacauth_combo (GTK_COMBO_BOX (widget), value); @@ -1436,6 +1471,15 @@ } } + widget = glade_xml_get_widget (xml, "keysize_checkbutton"); + if (gtk_toggle_button_get_active (GTK_TOGGLE_BUTTON (widget))) { + int keysize_val; + + widget = glade_xml_get_widget (xml, "keysize_spinbutton"); + keysize_val = gtk_spin_button_get_value_as_int (GTK_SPIN_BUTTON (widget)); + g_hash_table_insert (hash, g_strdup (NM_OPENVPN_KEY_KEYSIZE), g_strdup_printf ("%d", keysize_val)); + } + widget = glade_xml_get_widget (xml, "hmacauth_combo"); model = gtk_combo_box_get_model (GTK_COMBO_BOX (widget)); if (gtk_combo_box_get_active_iter (GTK_COMBO_BOX (widget), &iter)) { --- NetworkManager-openvpn-0.8.0.997/properties/import-export.c 2010-05-04 08:12:34.000000000 +0200 +++ NetworkManager-openvpn-0.8.0.997/properties/import-export.c.keysize 2014-03-19 01:58:00.000000000 +0100 @@ -52,6 +52,7 @@ #define CERT_TAG "cert" #define KEY_TAG "key" #define CIPHER_TAG "cipher" +#define KEYSIZE_TAG "keysize " #define COMP_TAG "comp-lzo" #define IFCONFIG_TAG "ifconfig " #define SECRET_TAG "secret" @@ -433,6 +434,26 @@ continue; } + if (!strncmp (*line, KEYSIZE_TAG, strlen (KEYSIZE_TAG))) { + items = get_args (*line + strlen (KEYSIZE_TAG)); + if (g_strv_length (items) >= 1) { + glong key_size; + char *tmp; + + errno = 0; + key_size = strtol (items[0], NULL, 10); + if ((errno == 0) && (key_size > 0) && (key_size <= 65535)) { + tmp = g_strdup_printf ("%d", (guint32) key_size); + nm_setting_vpn_add_data_item (s_vpn, NM_OPENVPN_KEY_KEYSIZE, tmp); + g_free (tmp); + } else + g_warning ("%s: invalid key size in option '%s'", __func__, *line); + } else + g_warning ("%s: invalid number of arguments in option '%s'", __func__, *line); + g_strfreev (items); + continue; + } + /* tls-remote */ if (!strncmp (*line, TLS_REMOTE_TAG, strlen (TLS_REMOTE_TAG))) { char *unquoted = unquote (*line + strlen (TLS_REMOTE_TAG), NULL); @@ -558,6 +579,8 @@ gboolean use_lzo = FALSE; gboolean reneg_exists = FALSE; guint32 reneg = 0; + gboolean keysize_exists = FALSE; + guint32 keysize = 0; s_con = NM_SETTING_CONNECTION (nm_connection_get_setting (connection, NM_TYPE_SETTING_CONNECTION)); g_assert (s_con); @@ -644,6 +667,12 @@ if (value && strlen (value)) cipher = value; + value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_KEYSIZE); + if (value && strlen (value)) { + keysize_exists = TRUE; + keysize = strtol (value, NULL, 10); + } + value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_LOCAL_IP); if (value && strlen (value)) local_ip = value; @@ -701,6 +730,9 @@ if (cipher) fprintf (f, "cipher %s\n", cipher); + if (keysize_exists) + fprintf (f, "keysize %d\n", keysize); + if (use_lzo) fprintf (f, "comp-lzo yes\n"); --- NetworkManager-openvpn-0.8.0.997/properties/nm-openvpn-dialog.glade 2010-03-03 20:06:26.000000000 +0100 +++ NetworkManager-openvpn-0.8.0.997/properties/nm-openvpn-dialog.glade.keysize 2014-03-19 01:25:18.000000000 +0100 @@ -1131,7 +1131,7 @@ True - 2 + 3 2 12 12 @@ -1164,8 +1164,8 @@ HMAC Authentication: - 1 - 2 + 2 + 3 @@ -1178,6 +1178,41 @@ 1 2 + 2 + 3 + + + + + + Use custom _size of cipher key: + True + True + False + Set cipher key size to a custom value. If unspecified, it defaults to cipher-specific size. +config: keysize <n> + True + True + + + 1 + 2 + GTK_FILL + + + + + + True + True + Set cipher key size to a custom value. If unspecified, it defaults to cipher-specific size. +config: keysize <n> + + 128 1 65535 1 10 10 + + + 1 + 2 1 2 --- NetworkManager-openvpn-0.8.0.997/properties/tests/conf/keysize.ovpn 1970-01-01 01:00:00.000000000 +0100 +++ NetworkManager-openvpn-0.8.0.997/properties/tests/conf/keysize.ovpn.keysize 2014-03-19 01:26:44.000000000 +0100 @@ -0,0 +1,19 @@ +client +dev tun +proto tcp +remote miami.proxpn.com 443 +resolv-retry infinite +nobind +persist-key +persist-tun +comp-lzo +tun-mtu 1500 +mssfix 1450 +auth-user-pass +reneg-sec 0 + +ca ssl/ca.crt +cert ssl/client.crt +key ssl/client.key +cipher BF-CBC +keysize 512 --- NetworkManager-openvpn-0.8.0.997/properties/tests/conf/Makefile.am 2010-03-03 20:06:10.000000000 +0100 +++ NetworkManager-openvpn-0.8.0.997/properties/tests/conf/Makefile.am.keysize 2014-03-19 01:25:58.000000000 +0100 @@ -7,6 +7,7 @@ port.ovpn \ rport.ovpn \ tun-opts.conf \ - pkcs12.ovpn + pkcs12.ovpn \ + keysize.ovpn --- NetworkManager-openvpn-0.8.0.997/properties/tests/conf/Makefile.in 2010-05-10 09:27:40.000000000 +0200 +++ NetworkManager-openvpn-0.8.0.997/properties/tests/conf/Makefile.in.keysize 2014-03-19 01:46:18.000000000 +0100 @@ -212,7 +212,8 @@ port.ovpn \ rport.ovpn \ tun-opts.conf \ - pkcs12.ovpn + pkcs12.ovpn \ + keysize.ovpn all: all-am --- NetworkManager-openvpn-0.8.0.997/properties/tests/test-import-export.c 2010-05-04 08:12:34.000000000 +0200 +++ NetworkManager-openvpn-0.8.0.997/properties/tests/test-import-export.c.keysize 2014-03-19 01:34:51.000000000 +0100 @@ -747,6 +747,65 @@ g_free (path); } +static void +test_keysize_import (NMVpnPluginUiInterface *plugin, const char *dir) +{ + NMConnection *connection; + NMSettingVPN *s_vpn; + + connection = get_basic_connection ("keysize-import", plugin, dir, "keysize.ovpn"); + ASSERT (connection != NULL, "keysize-import", "failed to import connection"); + + /* VPN setting */ + s_vpn = (NMSettingVPN *) nm_connection_get_setting (connection, NM_TYPE_SETTING_VPN); + ASSERT (s_vpn != NULL, "keysize-import", "missing 'vpn' setting"); + + /* Data items */ + test_item ("keysize-import-data", s_vpn, NM_OPENVPN_KEY_KEYSIZE, "512"); + + g_object_unref (connection); +} + +#define KEYSIZE_EXPORTED_NAME "keysize.ovpntest" +static void +test_keysize_export (NMVpnPluginUiInterface *plugin, const char *dir) +{ + NMConnection *connection; + NMConnection *reimported; + char *path; + gboolean success; + GError *error = NULL; + + connection = get_basic_connection ("keysize-export", plugin, dir, "keysize.ovpn"); + ASSERT (connection != NULL, "keysize-export", "failed to import connection"); + + path = g_build_path ("/", dir, KEYSIZE_EXPORTED_NAME, NULL); + success = nm_vpn_plugin_ui_interface_export (plugin, path, connection, &error); + if (!success) { + if (!error) + FAIL ("keysize-export", "export failed with missing error"); + else + FAIL ("keysize-export", "export failed: %s", error->message); + } + + /* Now re-import it and compare the connections to ensure they are the same */ + reimported = get_basic_connection ("keysize-export", plugin, dir, KEYSIZE_EXPORTED_NAME); + (void) unlink (path); + ASSERT (reimported != NULL, "keysize-export", "failed to re-import connection"); + + /* Clear secrets first, since they don't get exported, and thus would + * make the connection comparison below fail. + */ + remove_secrets (connection); + + ASSERT (nm_connection_compare (connection, reimported, NM_SETTING_COMPARE_FLAG_EXACT) == TRUE, + "keysize-export", "original and reimported connection differ"); + + g_object_unref (reimported); + g_object_unref (connection); + g_free (path); +} + int main (int argc, char **argv) { GError *error = NULL; @@ -793,6 +852,9 @@ test_tun_opts_import (plugin, argv[1]); test_tun_opts_export (plugin, argv[1]); + test_keysize_import (plugin, argv[1]); + test_keysize_export (plugin, argv[1]); + g_object_unref (plugin); basename = g_path_get_basename (argv[0]); --- NetworkManager-openvpn-0.8.0.997/src/nm-openvpn-service.c 2010-05-04 08:12:34.000000000 +0200 +++ NetworkManager-openvpn-0.8.0.997/src/nm-openvpn-service.c.keysize 2014-03-19 01:36:40.000000000 +0100 @@ -88,6 +88,7 @@ { NM_OPENVPN_KEY_CA, G_TYPE_STRING, 0, 0, FALSE }, { NM_OPENVPN_KEY_CERT, G_TYPE_STRING, 0, 0, FALSE }, { NM_OPENVPN_KEY_CIPHER, G_TYPE_STRING, 0, 0, FALSE }, + { NM_OPENVPN_KEY_KEYSIZE, G_TYPE_INT, 1, 65535, FALSE }, { NM_OPENVPN_KEY_COMP_LZO, G_TYPE_BOOLEAN, 0, 0, FALSE }, { NM_OPENVPN_KEY_MSSFIX, G_TYPE_BOOLEAN, 0, 0, FALSE }, { NM_OPENVPN_KEY_TUNNEL_MTU, G_TYPE_INT, 0, G_MAXINT, FALSE }, @@ -775,6 +776,21 @@ add_openvpn_arg (args, tmp); } + /* Keysize */ + tmp = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_KEYSIZE); + if (tmp && strlen (tmp)) { + add_openvpn_arg (args, "--keysize"); + if (!add_openvpn_arg_int (args, tmp)) { + g_set_error (error, + NM_VPN_PLUGIN_ERROR, + NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS, + _("Invalid keysize '%s'."), + tmp); + free_openvpn_args (args); + return FALSE; + } + } + /* Auth */ if (auth) { add_openvpn_arg (args, "--auth"); --- NetworkManager-openvpn-0.8.0.997/src/nm-openvpn-service.h 2010-03-06 07:52:42.000000000 +0100 +++ NetworkManager-openvpn-0.8.0.997/src/nm-openvpn-service.h.keysize 2014-03-19 01:36:58.000000000 +0100 @@ -42,6 +42,7 @@ #define NM_OPENVPN_KEY_CA "ca" #define NM_OPENVPN_KEY_CERT "cert" #define NM_OPENVPN_KEY_CIPHER "cipher" +#define NM_OPENVPN_KEY_KEYSIZE "keysize" #define NM_OPENVPN_KEY_COMP_LZO "comp-lzo" #define NM_OPENVPN_KEY_MSSFIX "mssfix" #define NM_OPENVPN_KEY_TUNNEL_MTU "tunnel-mtu"