From e599e96572eac1e955a6d6c20b574d01031cb40f Mon Sep 17 00:00:00 2001 From: Lubomir Rintel Date: Thu, 9 Feb 2017 15:17:17 +0100 Subject: [PATCH] ifcfg-rh: add support for certificate passwords --- .../plugins/ifcfg-rh/nms-ifcfg-rh-reader.c | 34 ++++++++++++- .../plugins/ifcfg-rh/nms-ifcfg-rh-writer.c | 51 +++++++++++-------- 2 files changed, 62 insertions(+), 23 deletions(-) diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c index 1adc7f8cb..4fcabec66 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-reader.c @@ -2568,16 +2568,26 @@ eap_tls_reader (const char *eap_method, { char *value; char *ca_cert = NULL; + char *ca_cert_password = NULL; char *real_cert_value = NULL; char *client_cert = NULL; + char *client_cert_password = NULL; char *privkey = NULL; char *privkey_password = NULL; gboolean success = FALSE; NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; const char *ca_cert_key = phase2 ? "IEEE_8021X_INNER_CA_CERT" : "IEEE_8021X_CA_CERT"; - const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD"; - const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; + const char *ca_cert_pw_key = phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD"; + const char *ca_cert_pw_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD : NM_SETTING_802_1X_CA_CERT_PASSWORD; + const char *ca_cert_pw_flags_key = phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD_FLAGS" : "IEEE_8021X_CA_CERT_PASSWORD_FLAGS"; + const char *ca_cert_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CA_CERT_PASSWORD_FLAGS : NM_SETTING_802_1X_CA_CERT_PASSWORD_FLAGS; const char *cli_cert_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT" : "IEEE_8021X_CLIENT_CERT"; + const char *cli_cert_pw_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD" : "IEEE_8021X_CLIENT_CERT_PASSWORD"; + const char *cli_cert_pw_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD; + const char *cli_cert_pw_flags_key = phase2 ? "IEEE_8021X_INNER_CLIENT_CERT_PASSWORD_FLAGS" : "IEEE_8021X_CLIENT_CERT_PASSWORD_FLAGS"; + const char *cli_cert_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS : NM_SETTING_802_1X_CLIENT_CERT_PASSWORD_FLAGS; + const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; + const char *pk_pw_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD": "IEEE_8021X_PRIVATE_KEY_PASSWORD"; const char *pk_pw_flags_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS": "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS"; const char *pk_pw_flags_prop = phase2 ? NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS : NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD_FLAGS; NMSettingSecretFlags flags; @@ -2601,6 +2611,16 @@ eap_tls_reader (const char *eap_method, } g_free (real_cert_value); real_cert_value = NULL; + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + flags = read_secret_flags (ifcfg, ca_cert_pw_flags_key); + g_object_set (s_8021x, ca_cert_pw_flags_prop, flags, NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + ca_cert_password = svGetValueString (ifcfg, ca_cert_pw_key); + g_object_set (s_8021x, ca_cert_pw_prop, ca_cert_password, NULL); + } + } } else { PARSE_WARNING ("missing %s for EAP method '%s'; this is insecure!", ca_cert_key, eap_method); @@ -2685,6 +2705,16 @@ eap_tls_reader (const char *eap_method, } g_free (real_cert_value); real_cert_value = NULL; + + if (scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11) { + flags = read_secret_flags (ifcfg, cli_cert_pw_flags_key); + g_object_set (s_8021x, cli_cert_pw_flags_prop, flags, NULL); + + if (flags == NM_SETTING_SECRET_FLAG_NONE) { + client_cert_password = svGetValueString (ifcfg, cli_cert_pw_key); + g_object_set (s_8021x, cli_cert_pw_prop, client_cert_password, NULL); + } + } } success = TRUE; diff --git a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c index 1cc630191..57dbcafcb 100644 --- a/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c +++ b/src/settings/plugins/ifcfg-rh/nms-ifcfg-rh-writer.c @@ -152,6 +152,8 @@ typedef struct ObjectType { const char * (*path_func) (NMSetting8021x *setting); GBytes * (*blob_func) (NMSetting8021x *setting); const char * (*uri_func) (NMSetting8021x *setting); + const char * (*passwd_func)(NMSetting8021x *setting); + NMSettingSecretFlags (*pwflag_func)(NMSetting8021x *setting); const char *ifcfg_key; const char *suffix; } ObjectType; @@ -162,6 +164,8 @@ static const ObjectType ca_type = { nm_setting_802_1x_get_ca_cert_path, nm_setting_802_1x_get_ca_cert_blob, nm_setting_802_1x_get_ca_cert_uri, + nm_setting_802_1x_get_ca_cert_password, + nm_setting_802_1x_get_ca_cert_password_flags, "IEEE_8021X_CA_CERT", "ca-cert.der" }; @@ -172,6 +176,8 @@ static const ObjectType phase2_ca_type = { nm_setting_802_1x_get_phase2_ca_cert_path, nm_setting_802_1x_get_phase2_ca_cert_blob, nm_setting_802_1x_get_phase2_ca_cert_uri, + nm_setting_802_1x_get_phase2_ca_cert_password, + nm_setting_802_1x_get_phase2_ca_cert_password_flags, "IEEE_8021X_INNER_CA_CERT", "inner-ca-cert.der" }; @@ -182,6 +188,8 @@ static const ObjectType client_type = { nm_setting_802_1x_get_client_cert_path, nm_setting_802_1x_get_client_cert_blob, nm_setting_802_1x_get_client_cert_uri, + nm_setting_802_1x_get_client_cert_password, + nm_setting_802_1x_get_client_cert_password_flags, "IEEE_8021X_CLIENT_CERT", "client-cert.der" }; @@ -192,6 +200,8 @@ static const ObjectType phase2_client_type = { nm_setting_802_1x_get_phase2_client_cert_path, nm_setting_802_1x_get_phase2_client_cert_blob, nm_setting_802_1x_get_phase2_client_cert_uri, + nm_setting_802_1x_get_phase2_client_cert_password, + nm_setting_802_1x_get_phase2_client_cert_password_flags, "IEEE_8021X_INNER_CLIENT_CERT", "inner-client-cert.der" }; @@ -202,6 +212,8 @@ static const ObjectType pk_type = { nm_setting_802_1x_get_private_key_path, nm_setting_802_1x_get_private_key_blob, nm_setting_802_1x_get_private_key_uri, + nm_setting_802_1x_get_private_key_password, + nm_setting_802_1x_get_private_key_password_flags, "IEEE_8021X_PRIVATE_KEY", "private-key.pem" }; @@ -212,6 +224,8 @@ static const ObjectType phase2_pk_type = { nm_setting_802_1x_get_phase2_private_key_path, nm_setting_802_1x_get_phase2_private_key_blob, nm_setting_802_1x_get_phase2_private_key_uri, + nm_setting_802_1x_get_phase2_private_key_password, + nm_setting_802_1x_get_phase2_private_key_password_flags, "IEEE_8021X_INNER_PRIVATE_KEY", "inner-private-key.pem" }; @@ -222,6 +236,8 @@ static const ObjectType p12_type = { nm_setting_802_1x_get_private_key_path, nm_setting_802_1x_get_private_key_blob, nm_setting_802_1x_get_private_key_uri, + nm_setting_802_1x_get_private_key_password, + nm_setting_802_1x_get_private_key_password_flags, "IEEE_8021X_PRIVATE_KEY", "private-key.p12" }; @@ -232,6 +248,8 @@ static const ObjectType phase2_p12_type = { nm_setting_802_1x_get_phase2_private_key_path, nm_setting_802_1x_get_phase2_private_key_blob, nm_setting_802_1x_get_phase2_private_key_uri, + nm_setting_802_1x_get_phase2_private_key_password, + nm_setting_802_1x_get_phase2_private_key_password_flags, "IEEE_8021X_INNER_PRIVATE_KEY", "inner-private-key.p12" }; @@ -245,6 +263,9 @@ write_object (NMSetting8021x *s_8021x, NMSetting8021xCKScheme scheme; const char *value = NULL; GBytes *blob = NULL; + const char *password = NULL; + NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; + char *secret_name, *secret_flags; g_return_val_if_fail (ifcfg != NULL, FALSE); g_return_val_if_fail (objtype != NULL, FALSE); @@ -268,6 +289,15 @@ write_object (NMSetting8021x *s_8021x, return FALSE; } + /* Set the password for certificate/private key. */ + secret_name = g_strdup_printf ("%s_PASSWORD", objtype->ifcfg_key); + secret_flags = g_strdup_printf ("%s_PASSWORD_FLAGS", objtype->ifcfg_key); + password = (*(objtype->passwd_func))(s_8021x); + flags = (*(objtype->pwflag_func))(s_8021x); + set_secret (ifcfg, secret_name, password, secret_flags, flags); + g_free (secret_name); + g_free (secret_flags); + /* If certificate/private key wasn't sent, the connection may no longer be * 802.1x and thus we clear out the paths and certs. */ @@ -344,10 +374,8 @@ write_8021x_certs (NMSetting8021x *s_8021x, shvarFile *ifcfg, GError **error) { - const char *password = NULL; gboolean success = FALSE, is_pkcs12 = FALSE; const ObjectType *otype = NULL; - NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE; /* CA certificate */ if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_ca_type : &ca_type, error)) @@ -360,37 +388,18 @@ write_8021x_certs (NMSetting8021x *s_8021x, otype = &phase2_p12_type; is_pkcs12 = TRUE; } - password = nm_setting_802_1x_get_phase2_private_key_password (s_8021x); - flags = nm_setting_802_1x_get_phase2_private_key_password_flags (s_8021x); } else { otype = &pk_type; if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { otype = &p12_type; is_pkcs12 = TRUE; } - password = nm_setting_802_1x_get_private_key_password (s_8021x); - flags = nm_setting_802_1x_get_private_key_password_flags (s_8021x); } /* Save the private key */ if (!write_object (s_8021x, ifcfg, otype, error)) goto out; - /* Private key password */ - if (phase2) { - set_secret (ifcfg, - "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD", - password, - "IEEE_8021X_INNER_PRIVATE_KEY_PASSWORD_FLAGS", - flags); - } else { - set_secret (ifcfg, - "IEEE_8021X_PRIVATE_KEY_PASSWORD", - password, - "IEEE_8021X_PRIVATE_KEY_PASSWORD_FLAGS", - flags); - } - /* Client certificate */ if (is_pkcs12) { /* Don't need a client certificate with PKCS#12 since the file is both