Commit c1a93f9f authored by apatard's avatar apatard

Add support for wpa_supplicant engine-id / key-id, engine2-id / key2-id

There's no need to try to set the engine/engine2 parameters, they're
automatically set.

Support tested with :
- eap-tls on libvirt/kvm virtual machine and real system
- wpa2-eap-peap-tls on real system. (TODO: setting test VM with mac80211_hwsim)
The certificate key is protected by tpm2. No pin.

Modifications done to  libnm-core/nm-setting-8021x.c :
o verify_tls() to make sure that if engine_id/engine2_id are specified
  key_id/key2_id are specified too. If engine_id/engine2_id not specified, behaves
  as before.
o need_secrets_tls() modified to not look for a passphrase for a certificate if
  an engine id is set for phase 1 or phase 2.
o verify_ttls() to work in my phase 2 peap-tls case. Could have used a new fonction
  but was a little bit easier to adapt verify_ttls(). The function nows check:
  - we're using phase2 auth or autheap
  - there's an identity set
  - in case of ttls(), check that anonymous identity is set.

Example of 802-1x section for ethernet eap-tls case:
[802-1x]
ca-cert=/home/rtp/ca.pem
client-cert=/home/rtp/tpm2/csr2/client-tpm-qemu.crt
eap=tls;
identity=nm-tpm2
phase1-engine-id=tpm2tss
phase1-key-id=/home/rtp/tpm2/csr2/pri_pub_blob.key
Signed-off-by: apatard's avatarArnaud Patard <apatard@hupstream.com>
parent d0db41c1
Pipeline #68984 passed with stages
in 36 minutes and 45 seconds
......@@ -4608,6 +4608,12 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
.typ_flags = NM_META_PROPERTY_TYP_FLAG_ENUM_GET_PARSABLE_TEXT,
),
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_ENGINE_ID,
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE1_KEY_ID,
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_AUTH,
.property_type = &_pt_gobject_string,
.property_typ_data = DEFINE_PROPERTY_TYP_DATA (
......@@ -4679,6 +4685,12 @@ static const NMMetaPropertyInfo *const property_infos_802_1X[] = {
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS,
.property_type = &_pt_gobject_secret_flags,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_ENGINE_ID,
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PHASE2_KEY_ID,
.property_type = &_pt_gobject_string,
),
PROPERTY_INFO_WITH_DESC (NM_SETTING_802_1X_PASSWORD,
.is_secret = TRUE,
.property_type = &_pt_gobject_string,
......
......@@ -60,7 +60,9 @@
#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD_RAW N_("Password used for EAP authentication methods, given as a byte array to allow passwords in other encodings than UTF-8 to be used. If both the \"password\" property and the \"password-raw\" property are specified, \"password\" is preferred.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PASSWORD_RAW_FLAGS N_("Flags indicating how to handle the \"password-raw\" property.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_AUTH_FLAGS N_("Specifies authentication flags to use in \"phase 1\" outer authentication using NMSetting8021xAuthFlags options. The individual TLS versions can be explicitly disabled. If a certain TLS disable flag is not set, it is up to the supplicant to allow or forbid it. The TLS options map to tls_disable_tlsv1_x settings. See the wpa_supplicant documentation for more details.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_ENGINE_ID N_("Specify which openssl engine id to use as engine for the EAP method in the \"eap\" property.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING N_("Enables or disables in-line provisioning of EAP-FAST credentials when FAST is specified as the EAP method in the \"eap\" property. Recognized values are \"0\" (disabled), \"1\" (allow unauthenticated provisioning), \"2\" (allow authenticated provisioning), and \"3\" (allow both authenticated and unauthenticated provisioning). See the wpa_supplicant documentation for more details.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_KEY_ID N_("Specify which key id to use for the EAP method in the \"eap\" property.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_PEAPLABEL N_("Forces use of the new PEAP label during key derivation. Some RADIUS servers may require forcing the new PEAP label to interoperate with PEAPv1. Set to \"1\" to force use of the new PEAP label. See the wpa_supplicant documentation for more details.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE1_PEAPVER N_("Forces which PEAP version is used when PEAP is set as the EAP method in the \"eap\" property. When unset, the version reported by the server will be used. Sometimes when using older RADIUS servers, it is necessary to force the client to use a particular PEAP version. To do so, this property may be set to \"0\" or \"1\" to force that specific PEAP version.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_ALTSUBJECT_MATCHES N_("List of strings to be matched against the altSubjectName of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If the list is empty, no verification of the server certificate's altSubjectName is performed.")
......@@ -74,6 +76,8 @@
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD N_("The password used to access the \"phase2\" client certificate stored in \"phase2-client-cert\" property. Only makes sense if the certificate is stored on a PKCS#11 token that requires a login.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-client-cert-password\" property.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_DOMAIN_SUFFIX_MATCH N_("Constraint for server domain name. If set, this FQDN is used as a suffix match requirement for dNSName element(s) of the certificate presented by the authentication server during the inner \"phase 2\" authentication. If a matching dNSName is found, this constraint is met. If no dNSName values are present, this constraint is matched against SubjectName CN using same suffix match comparison.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_ENGINE_ID N_("Specify which openssl engine id to use as engine for EAP in the phase 2")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_KEY_ID N_("Specify which key id to use for phase 2 EAP method")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY N_("Contains the \"phase 2\" inner private key when the \"phase2-auth\" or \"phase2-autheap\" property is set to \"tls\". Key data is specified using a \"scheme\"; two are currently supported: blob and path. When using the blob scheme and private keys, this property should be set to the key's encrypted PEM encoded data. When using private keys with the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte. When using PKCS#12 format private keys and the blob scheme, this property should be set to the PKCS#12 data and the \"phase2-private-key-password\" property must be set to password used to decrypt the PKCS#12 certificate and key. When using PKCS#12 files and the path scheme, this property should be set to the full UTF-8 encoded path of the key, prefixed with the string \"file://\" and ending with a terminating NUL byte, and as with the blob scheme the \"phase2-private-key-password\" property must be set to the password used to decode the PKCS#12 private key and certificate.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD N_("The password used to decrypt the \"phase 2\" private key specified in the \"phase2-private-key\" property when the private key either uses the path scheme, or is a PKCS#12 format key.")
#define DESCRIBE_DOC_NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD_FLAGS N_("Flags indicating how to handle the \"phase2-private-key-password\" property.")
......
......@@ -99,6 +99,8 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSetting8021x,
PROP_PHASE1_PEAPLABEL,
PROP_PHASE1_FAST_PROVISIONING,
PROP_PHASE1_AUTH_FLAGS,
PROP_PHASE1_ENGINE_ID,
PROP_PHASE1_KEY_ID,
PROP_PHASE2_AUTH,
PROP_PHASE2_AUTHEAP,
PROP_PHASE2_CA_CERT,
......@@ -111,6 +113,8 @@ NM_GOBJECT_PROPERTIES_DEFINE (NMSetting8021x,
PROP_PHASE2_CLIENT_CERT,
PROP_PHASE2_CLIENT_CERT_PASSWORD,
PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS,
PROP_PHASE2_ENGINE_ID,
PROP_PHASE2_KEY_ID,
PROP_PASSWORD,
PROP_PASSWORD_FLAGS,
PROP_PASSWORD_RAW,
......@@ -172,6 +176,10 @@ typedef struct {
NMSettingSecretFlags phase2_private_key_password_flags;
gboolean system_ca_certs;
int auth_timeout;
char *phase1_engine_id;
char *phase1_key_id;
char *phase2_engine_id;
char *phase2_key_id;
} NMSetting8021xPrivate;
G_DEFINE_TYPE (NMSetting8021x, nm_setting_802_1x, NM_TYPE_SETTING)
......@@ -1447,6 +1455,34 @@ nm_setting_802_1x_get_phase1_auth_flags (NMSetting8021x *setting)
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_auth_flags;
}
/**
* nm_setting_802_1x_get_phase1_engine_id:
* @setting: the #NMSetting8021x
*
* Returns: the "phase 1" openssl engine to use. By default, set to NULL.
**/
const char *
nm_setting_802_1x_get_phase1_engine_id (NMSetting8021x *setting)
{
g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_engine_id;
}
/**
* nm_setting_802_1x_get_phase1_key_id:
* @setting: the #NMSetting8021x
*
* Returns: the "phase 1" openssl key id to use. By default, set to NULL.
**/
const char *
nm_setting_802_1x_get_phase1_key_id (NMSetting8021x *setting)
{
g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase1_key_id;
}
/**
* nm_setting_802_1x_get_phase2_auth:
* @setting: the #NMSetting8021x
......@@ -1962,6 +1998,34 @@ nm_setting_802_1x_get_phase2_client_cert_password_flags (NMSetting8021x *setting
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_client_cert_password_flags;
}
/**
* nm_setting_802_1x_get_phase2_engine_id:
* @setting: the #NMSetting8021x
*
* Returns: the "phase 2" openssl engine to use. By default, set to NULL.
**/
const char *
nm_setting_802_1x_get_phase2_engine_id (NMSetting8021x *setting)
{
g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_engine_id;
}
/**
* nm_setting_802_1x_get_phase2_key_id:
* @setting: the #NMSetting8021x
*
* Returns: the "phase 2" openssl key id to use. By default, set to NULL.
**/
const char *
nm_setting_802_1x_get_phase2_key_id (NMSetting8021x *setting)
{
g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL);
return NM_SETTING_802_1X_GET_PRIVATE (setting)->phase2_key_id;
}
/**
* nm_setting_802_1x_get_password:
* @setting: the #NMSetting8021x
......@@ -2482,21 +2546,29 @@ need_secrets_tls (NMSetting8021x *self,
NMSetting8021xCKScheme scheme;
GBytes *blob = NULL;
const char *path = NULL;
const char *engine_id, *key_id;
if (phase2) {
scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
path = nm_setting_802_1x_get_phase2_private_key_path (self);
else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
blob = nm_setting_802_1x_get_phase2_private_key_blob (self);
else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11)
g_warning ("%s: unknown phase2 private key scheme %d", __func__, scheme);
if (need_private_key_password (blob, scheme, path,
priv->phase2_private_key_password,
priv->phase2_private_key_password_flags))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
engine_id = priv->phase2_engine_id;
if (engine_id) {
key_id = priv->phase2_key_id;
if (!key_id)
g_warning ("%s: phase 2 : SSL engine specified with no key", __func__);
return;
} else {
scheme = nm_setting_802_1x_get_phase2_private_key_scheme (self);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
path = nm_setting_802_1x_get_phase2_private_key_path (self);
else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
blob = nm_setting_802_1x_get_phase2_private_key_blob (self);
else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11)
g_warning ("%s: unknown phase2 private key scheme %d", __func__, scheme);
if (need_private_key_password (blob, scheme, path,
priv->phase2_private_key_password,
priv->phase2_private_key_password_flags))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD);
}
scheme = nm_setting_802_1x_get_phase2_ca_cert_scheme (self);
if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11
&& !( priv->phase2_ca_cert_password_flags == NM_SETTING_SECRET_FLAG_NONE
......@@ -2511,19 +2583,26 @@ need_secrets_tls (NMSetting8021x *self,
&& !priv->phase2_client_cert_password)
g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD);
} else {
scheme = nm_setting_802_1x_get_private_key_scheme (self);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
path = nm_setting_802_1x_get_private_key_path (self);
else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
blob = nm_setting_802_1x_get_private_key_blob (self);
else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11)
g_warning ("%s: unknown private key scheme %d", __func__, scheme);
if (need_private_key_password (blob, scheme, path,
priv->private_key_password,
priv->private_key_password_flags))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
engine_id = priv->phase1_engine_id;
if (engine_id) {
key_id = priv->phase1_key_id;
if (!key_id)
g_warning ("%s: phase 1 : SSL engine specified with no key", __func__);
return;
} else {
scheme = nm_setting_802_1x_get_private_key_scheme (self);
if (scheme == NM_SETTING_802_1X_CK_SCHEME_PATH)
path = nm_setting_802_1x_get_private_key_path (self);
else if (scheme == NM_SETTING_802_1X_CK_SCHEME_BLOB)
blob = nm_setting_802_1x_get_private_key_blob (self);
else if (scheme != NM_SETTING_802_1X_CK_SCHEME_PKCS11)
g_warning ("%s: unknown private key scheme %d", __func__, scheme);
if (need_private_key_password (blob, scheme, path,
priv->private_key_password,
priv->private_key_password_flags))
g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD);
}
scheme = nm_setting_802_1x_get_ca_cert_scheme (self);
if ( scheme == NM_SETTING_802_1X_CK_SCHEME_PKCS11
&& !( priv->ca_cert_password_flags & NM_SETTING_SECRET_FLAG_NOT_REQUIRED
......@@ -2563,6 +2642,18 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
}
/* Private key is required for TLS */
if (priv->phase2_engine_id) {
if (!priv->phase2_key_id) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
"property is missing");
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_KEY_ID);
return FALSE;
}
return TRUE;
}
if (!priv->phase2_private_key) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
......@@ -2611,6 +2702,18 @@ verify_tls (NMSetting8021x *self, gboolean phase2, GError **error)
}
/* Private key is required for TLS */
if (priv->phase1_engine_id) {
if (!priv->phase1_key_id) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
"property is missing");
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_KEY_ID);
return FALSE;
}
return TRUE;
}
if (!priv->private_key) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
......@@ -2650,63 +2753,73 @@ static gboolean
verify_ttls (NMSetting8021x *self, gboolean phase2, GError **error)
{
NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self);
char *method = NULL;
if ( (!priv->identity || !strlen (priv->identity))
&& (!priv->anonymous_identity || !strlen (priv->anonymous_identity))) {
if (!priv->identity) {
if ( (!priv->phase2_auth || !strlen (priv->phase2_auth))
&& (!priv->phase2_autheap || !strlen (priv->phase2_autheap))) {
if (!priv->phase2_auth) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
} else if (!strlen (priv->identity)) {
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
} else if (!strlen (priv->phase2_auth)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
} else if (!priv->anonymous_identity) {
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
} else if (!priv->phase2_autheap) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
} else {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
}
return FALSE;
}
if ( (!priv->phase2_auth || !strlen (priv->phase2_auth))
&& (!priv->phase2_autheap || !strlen (priv->phase2_autheap))) {
if (!priv->phase2_auth) {
if (!priv->identity || !strlen (priv->identity)) {
if (!priv->identity) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
} else if (!strlen (priv->phase2_auth)) {
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
} else if (!strlen (priv->identity)) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTH);
} else if (!priv->phase2_autheap) {
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_IDENTITY);
}
}
method = priv->phase2_auth;
if (!method && priv->phase2_autheap)
method = priv->phase2_autheap;
if (!strcmp(method, "ttls")
&& (!priv->anonymous_identity || !strlen (priv->anonymous_identity))) {
if (!priv->anonymous_identity) {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_MISSING_PROPERTY,
_("property is missing"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
} else {
g_set_error_literal (error,
NM_CONNECTION_ERROR,
NM_CONNECTION_ERROR_INVALID_PROPERTY,
_("property is empty"));
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_PHASE2_AUTHEAP);
g_prefix_error (error, "%s.%s: ", NM_SETTING_802_1X_SETTING_NAME, NM_SETTING_802_1X_ANONYMOUS_IDENTITY);
}
return FALSE;
}
......@@ -3063,6 +3176,12 @@ get_property (GObject *object, guint prop_id,
case PROP_PHASE1_AUTH_FLAGS:
g_value_set_uint (value, priv->phase1_auth_flags);
break;
case PROP_PHASE1_ENGINE_ID:
g_value_set_string (value, priv->phase1_engine_id);
break;
case PROP_PHASE1_KEY_ID:
g_value_set_string (value, priv->phase1_key_id);
break;
case PROP_PHASE2_AUTH:
g_value_set_string (value, priv->phase2_auth);
break;
......@@ -3099,6 +3218,12 @@ get_property (GObject *object, guint prop_id,
case PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS:
g_value_set_flags (value, priv->phase2_client_cert_password_flags);
break;
case PROP_PHASE2_ENGINE_ID:
g_value_set_string (value, priv->phase2_engine_id);
break;
case PROP_PHASE2_KEY_ID:
g_value_set_string (value, priv->phase2_key_id);
break;
case PROP_PASSWORD:
g_value_set_string (value, priv->password);
break;
......@@ -3224,6 +3349,14 @@ set_property (GObject *object, guint prop_id,
case PROP_PHASE1_AUTH_FLAGS:
priv->phase1_auth_flags = g_value_get_uint (value);
break;
case PROP_PHASE1_ENGINE_ID:
g_free (priv->phase1_engine_id);
priv->phase1_engine_id = g_value_dup_string (value);
break;
case PROP_PHASE1_KEY_ID:
g_free (priv->phase1_key_id);
priv->phase1_key_id = g_value_dup_string (value);
break;
case PROP_PHASE2_AUTH:
g_free (priv->phase2_auth);
priv->phase2_auth = g_value_dup_string (value);
......@@ -3270,6 +3403,14 @@ set_property (GObject *object, guint prop_id,
case PROP_PHASE2_CLIENT_CERT_PASSWORD_FLAGS:
priv->phase2_client_cert_password_flags = g_value_get_flags (value);
break;
case PROP_PHASE2_ENGINE_ID:
g_free (priv->phase2_engine_id);
priv->phase2_engine_id = g_value_dup_string (value);
break;
case PROP_PHASE2_KEY_ID:
g_free (priv->phase2_key_id);
priv->phase2_key_id = g_value_dup_string (value);
break;
case PROP_PASSWORD:
g_free (priv->password);
priv->password = g_value_dup_string (value);
......@@ -3359,11 +3500,15 @@ finalize (GObject *object)
g_free (priv->phase1_peapver);
g_free (priv->phase1_peaplabel);
g_free (priv->phase1_fast_provisioning);
g_free (priv->phase1_engine_id);
g_free (priv->phase1_key_id);
g_free (priv->phase2_auth);
g_free (priv->phase2_autheap);
g_free (priv->phase2_ca_path);
g_free (priv->phase2_subject_match);
g_free (priv->phase2_domain_suffix_match);
g_free (priv->phase2_engine_id);
g_free (priv->phase2_key_id);
g_free (priv->password);
g_bytes_unref (priv->password_raw);
g_free (priv->pin);
......@@ -3794,6 +3939,30 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:phase1-engine-id:
*
* Specify which openssl engine id to use as engine for the EAP method in
* the #NMSetting8021x:eap property.
**/
obj_properties[PROP_PHASE1_ENGINE_ID] =
g_param_spec_string (NM_SETTING_802_1X_PHASE1_ENGINE_ID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:phase1-key-id:
*
* Specify which key id to use for the EAP method in
* the #NMSetting8021x:eap property.
**/
obj_properties[PROP_PHASE1_KEY_ID] =
g_param_spec_string (NM_SETTING_802_1X_PHASE1_KEY_ID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:phase2-auth:
*
......@@ -4052,6 +4221,28 @@ nm_setting_802_1x_class_init (NMSetting8021xClass *klass)
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:phase2-engine-id:
*
* Specify which openssl engine id to use as engine for EAP in the phase 2
**/
obj_properties[PROP_PHASE2_ENGINE_ID] =
g_param_spec_string (NM_SETTING_802_1X_PHASE2_ENGINE_ID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:phase2-key-id:
*
* Specify which key id to use for phase 2 EAP method
**/
obj_properties[PROP_PHASE2_KEY_ID] =
g_param_spec_string (NM_SETTING_802_1X_PHASE2_KEY_ID, "", "",
NULL,
G_PARAM_READWRITE |
G_PARAM_STATIC_STRINGS);
/**
* NMSetting8021x:password:
*
......
......@@ -111,6 +111,8 @@ typedef enum { /*< flags, underscore_name=nm_setting_802_1x_auth_flags >*/
#define NM_SETTING_802_1X_PHASE1_PEAPLABEL "phase1-peaplabel"
#define NM_SETTING_802_1X_PHASE1_FAST_PROVISIONING "phase1-fast-provisioning"
#define NM_SETTING_802_1X_PHASE1_AUTH_FLAGS "phase1-auth-flags"
#define NM_SETTING_802_1X_PHASE1_ENGINE_ID "phase1-engine-id"
#define NM_SETTING_802_1X_PHASE1_KEY_ID "phase1-key-id"
#define NM_SETTING_802_1X_PHASE2_AUTH "phase2-auth"
#define NM_SETTING_802_1X_PHASE2_AUTHEAP "phase2-autheap"
#define NM_SETTING_802_1X_PHASE2_CA_CERT "phase2-ca-cert"
......@@ -123,6 +125,8 @@ typedef enum { /*< flags, underscore_name=nm_setting_802_1x_auth_flags >*/
#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT "phase2-client-cert"
#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD "phase2-client-cert-password"
#define NM_SETTING_802_1X_PHASE2_CLIENT_CERT_PASSWORD_FLAGS "phase2-client-cert-password-flags"
#define NM_SETTING_802_1X_PHASE2_ENGINE_ID "phase2-engine-id"
#define NM_SETTING_802_1X_PHASE2_KEY_ID "phase2-key-id"
#define NM_SETTING_802_1X_PASSWORD "password"
#define NM_SETTING_802_1X_PASSWORD_FLAGS "password-flags"
#define NM_SETTING_802_1X_PASSWORD_RAW "password-raw"
......@@ -251,6 +255,10 @@ const char * nm_setting_802_1x_get_phase1_peaplabel (NMSetting8
const char * nm_setting_802_1x_get_phase1_fast_provisioning (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase1_engine_id (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase1_key_id (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase2_auth (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase2_autheap (NMSetting8021x *setting);
......@@ -302,6 +310,10 @@ const char * nm_setting_802_1x_get_phase2_client_cert_password (NMSett
NM_AVAILABLE_IN_1_8
NMSettingSecretFlags nm_setting_802_1x_get_phase2_client_cert_password_flags (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase2_engine_id (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_phase2_key_id (NMSetting8021x *setting);
const char * nm_setting_802_1x_get_password (NMSetting8021x *setting);
NMSettingSecretFlags nm_setting_802_1x_get_password_flags (NMSetting8021x *setting);
GBytes * nm_setting_802_1x_get_password_raw (NMSetting8021x *setting);
......
......@@ -1036,6 +1036,7 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
NMSupplicantConfigPrivate *priv;
char *tmp;
const char *peapver, *value, *path;
const char *engine_id, *key_id;
gboolean added;
GString *phase1, *phase2;
GBytes *bytes;
......@@ -1167,6 +1168,19 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
}
g_string_free (phase1, TRUE);
engine_id = nm_setting_802_1x_get_phase1_engine_id (setting);
if (engine_id) {
const char *on = "1";
add_string_val (self, on, "engine", FALSE, NULL, error);
add_string_val (self, engine_id, "engine_id", FALSE, NULL, error);
key_id = nm_setting_802_1x_get_phase1_key_id (setting);
if (key_id) {
add_string_val (self, key_id, "key_id", FALSE, NULL, error);
path = nm_setting_802_1x_get_client_cert_path (setting);
add_string_val (self, path, "client_cert", FALSE, NULL, error);
}
}
phase2 = g_string_new (NULL);
if (nm_setting_802_1x_get_phase2_auth (setting) && !fast_provisoning_allowed) {
tmp = g_ascii_strup (nm_setting_802_1x_get_phase2_auth (setting), -1);
......@@ -1182,6 +1196,19 @@ nm_supplicant_config_add_setting_8021x (NMSupplicantConfig *self,
g_free (tmp);
}
engine_id = nm_setting_802_1x_get_phase2_engine_id (setting);
if (engine_id) {
const char *on = "1";
add_string_val (self, on, "engine2", FALSE, NULL, error);
add_string_val (self, engine_id, "engine2_id", FALSE, NULL, error);
key_id = nm_setting_802_1x_get_phase2_key_id (setting);
if (key_id) {
add_string_val (self, key_id, "key2_id", FALSE, NULL, error);
path = nm_setting_802_1x_get_phase2_client_cert_path (setting);
add_string_val (self, path, "client_cert2", FALSE, NULL, error);
}
}
if (phase2->len) {
if (!add_string_val (self, phase2->str, "phase2", FALSE, NULL, error)) {
g_string_free (phase2, TRUE);
......
......@@ -120,8 +120,11 @@ static const struct Opt opt_table[] = {
{ "eappsk", TYPE_BYTES, 0, 0, FALSE, NULL },
{ "pac_file", TYPE_BYTES, 0, 0, FALSE, NULL },
{ "engine", TYPE_INT, 0, 1, FALSE, NULL },
{ "engine_id", TYPE_BYTES, 0, 0, FALSE, NULL },
{ "key_id", TYPE_BYTES, 0, 0, FALSE, NULL },
{ "engine_id", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "key_id", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "engine2", TYPE_INT, 0, 1, FALSE, NULL },
{ "engine2_id", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "key2_id", TYPE_BYTES, 0, 65536, FALSE, NULL },
{ "fragment_size", TYPE_INT, 1, 2000, FALSE, NULL },
{ "proactive_key_caching", TYPE_INT, 0, 1, FALSE, NULL },
{ "bgscan", TYPE_BYTES, 0, 0, FALSE, NULL },
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment