ifcfg-rh: add support for certificate passwords

This commit is contained in:
Lubomir Rintel
2017-02-09 15:17:17 +01:00
parent 538e510473
commit e599e96572
2 changed files with 62 additions and 23 deletions

View File

@@ -2568,16 +2568,26 @@ eap_tls_reader (const char *eap_method,
{ {
char *value; char *value;
char *ca_cert = NULL; char *ca_cert = NULL;
char *ca_cert_password = NULL;
char *real_cert_value = NULL; char *real_cert_value = NULL;
char *client_cert = NULL; char *client_cert = NULL;
char *client_cert_password = NULL;
char *privkey = NULL; char *privkey = NULL;
char *privkey_password = NULL; char *privkey_password = NULL;
gboolean success = FALSE; gboolean success = FALSE;
NMSetting8021xCKFormat privkey_format = NM_SETTING_802_1X_CK_FORMAT_UNKNOWN; 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 *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 *ca_cert_pw_key = phase2 ? "IEEE_8021X_INNER_CA_CERT_PASSWORD" : "IEEE_8021X_CA_CERT_PASSWORD";
const char *pk_key = phase2 ? "IEEE_8021X_INNER_PRIVATE_KEY" : "IEEE_8021X_PRIVATE_KEY"; 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_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_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; 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; NMSettingSecretFlags flags;
@@ -2601,6 +2611,16 @@ eap_tls_reader (const char *eap_method,
} }
g_free (real_cert_value); g_free (real_cert_value);
real_cert_value = NULL; 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 { } else {
PARSE_WARNING ("missing %s for EAP method '%s'; this is insecure!", PARSE_WARNING ("missing %s for EAP method '%s'; this is insecure!",
ca_cert_key, eap_method); ca_cert_key, eap_method);
@@ -2685,6 +2705,16 @@ eap_tls_reader (const char *eap_method,
} }
g_free (real_cert_value); g_free (real_cert_value);
real_cert_value = NULL; 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; success = TRUE;

View File

@@ -152,6 +152,8 @@ typedef struct ObjectType {
const char * (*path_func) (NMSetting8021x *setting); const char * (*path_func) (NMSetting8021x *setting);
GBytes * (*blob_func) (NMSetting8021x *setting); GBytes * (*blob_func) (NMSetting8021x *setting);
const char * (*uri_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 *ifcfg_key;
const char *suffix; const char *suffix;
} ObjectType; } 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_path,
nm_setting_802_1x_get_ca_cert_blob, nm_setting_802_1x_get_ca_cert_blob,
nm_setting_802_1x_get_ca_cert_uri, 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", "IEEE_8021X_CA_CERT",
"ca-cert.der" "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_path,
nm_setting_802_1x_get_phase2_ca_cert_blob, 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_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", "IEEE_8021X_INNER_CA_CERT",
"inner-ca-cert.der" "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_path,
nm_setting_802_1x_get_client_cert_blob, nm_setting_802_1x_get_client_cert_blob,
nm_setting_802_1x_get_client_cert_uri, 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", "IEEE_8021X_CLIENT_CERT",
"client-cert.der" "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_path,
nm_setting_802_1x_get_phase2_client_cert_blob, 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_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", "IEEE_8021X_INNER_CLIENT_CERT",
"inner-client-cert.der" "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_path,
nm_setting_802_1x_get_private_key_blob, nm_setting_802_1x_get_private_key_blob,
nm_setting_802_1x_get_private_key_uri, 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", "IEEE_8021X_PRIVATE_KEY",
"private-key.pem" "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_path,
nm_setting_802_1x_get_phase2_private_key_blob, 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_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", "IEEE_8021X_INNER_PRIVATE_KEY",
"inner-private-key.pem" "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_path,
nm_setting_802_1x_get_private_key_blob, nm_setting_802_1x_get_private_key_blob,
nm_setting_802_1x_get_private_key_uri, 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", "IEEE_8021X_PRIVATE_KEY",
"private-key.p12" "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_path,
nm_setting_802_1x_get_phase2_private_key_blob, 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_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", "IEEE_8021X_INNER_PRIVATE_KEY",
"inner-private-key.p12" "inner-private-key.p12"
}; };
@@ -245,6 +263,9 @@ write_object (NMSetting8021x *s_8021x,
NMSetting8021xCKScheme scheme; NMSetting8021xCKScheme scheme;
const char *value = NULL; const char *value = NULL;
GBytes *blob = 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 (ifcfg != NULL, FALSE);
g_return_val_if_fail (objtype != NULL, FALSE); g_return_val_if_fail (objtype != NULL, FALSE);
@@ -268,6 +289,15 @@ write_object (NMSetting8021x *s_8021x,
return FALSE; 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 /* If certificate/private key wasn't sent, the connection may no longer be
* 802.1x and thus we clear out the paths and certs. * 802.1x and thus we clear out the paths and certs.
*/ */
@@ -344,10 +374,8 @@ write_8021x_certs (NMSetting8021x *s_8021x,
shvarFile *ifcfg, shvarFile *ifcfg,
GError **error) GError **error)
{ {
const char *password = NULL;
gboolean success = FALSE, is_pkcs12 = FALSE; gboolean success = FALSE, is_pkcs12 = FALSE;
const ObjectType *otype = NULL; const ObjectType *otype = NULL;
NMSettingSecretFlags flags = NM_SETTING_SECRET_FLAG_NONE;
/* CA certificate */ /* CA certificate */
if (!write_object (s_8021x, ifcfg, phase2 ? &phase2_ca_type : &ca_type, error)) 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; otype = &phase2_p12_type;
is_pkcs12 = TRUE; 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 { } else {
otype = &pk_type; otype = &pk_type;
if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) { if (nm_setting_802_1x_get_private_key_format (s_8021x) == NM_SETTING_802_1X_CK_FORMAT_PKCS12) {
otype = &p12_type; otype = &p12_type;
is_pkcs12 = TRUE; 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 */ /* Save the private key */
if (!write_object (s_8021x, ifcfg, otype, error)) if (!write_object (s_8021x, ifcfg, otype, error))
goto out; 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 */ /* Client certificate */
if (is_pkcs12) { if (is_pkcs12) {
/* Don't need a client certificate with PKCS#12 since the file is both /* Don't need a client certificate with PKCS#12 since the file is both