--- libnm-util/libnm-util.ver | 10 libnm-util/nm-setting-8021x.c | 303 ++++++++++++++++- libnm-util/nm-setting-8021x.h | 21 + src/supplicant-manager/nm-supplicant-config.c | 99 +++++ src/supplicant-manager/nm-supplicant-config.h | 15 src/supplicant-manager/nm-supplicant-interface.c | 37 ++ src/supplicant-manager/nm-supplicant-settings-verify.c | 7 7 files changed, 485 insertions(+), 7 deletions(-) --- a/libnm-util/libnm-util.ver +++ b/libnm-util/libnm-util.ver @@ -76,6 +76,16 @@ nm_setting_802_1x_get_phase2_private_key_type; nm_setting_802_1x_set_phase2_private_key; nm_setting_802_1x_get_pin; + nm_setting_802_1x_get_pkcs11_engine_path; + nm_setting_802_1x_get_pkcs11_module_path; + nm_setting_802_1x_get_pkcs11_module_init_args; + nm_setting_802_1x_get_pkcs11_slot; + nm_setting_802_1x_get_pkcs11_ca_cert; + nm_setting_802_1x_get_pkcs11_client_cert; + nm_setting_802_1x_get_pkcs11_private_key; + nm_setting_802_1x_get_pkcs11_phase2_ca_cert; + nm_setting_802_1x_get_pkcs11_phase2_client_cert; + nm_setting_802_1x_get_pkcs11_phase2_private_key; nm_setting_802_1x_get_private_key; nm_setting_802_1x_get_private_key_blob; nm_setting_802_1x_get_private_key_format; --- a/libnm-util/nm-setting-8021x.c +++ b/libnm-util/nm-setting-8021x.c @@ -132,6 +132,16 @@ GByteArray *phase2_private_key; char *phase2_private_key_password; gboolean system_ca_certs; + char *pkcs11_engine_path; + char *pkcs11_module_path; + char *pkcs11_module_init_args; + guint pkcs11_slot; + char *pkcs11_ca_cert; + char *pkcs11_client_cert; + char *pkcs11_private_key; + char *pkcs11_phase2_ca_cert; + char *pkcs11_phase2_client_cert; + char *pkcs11_phase2_private_key; } NMSetting8021xPrivate; enum { @@ -158,6 +168,16 @@ PROP_PIN, PROP_PSK, PROP_SYSTEM_CA_CERTS, + PROP_PKCS11_ENGINE_PATH, + PROP_PKCS11_MODULE_PATH, + PROP_PKCS11_MODULE_INIT_ARGS, + PROP_PKCS11_SLOT, + PROP_PKCS11_CA_CERT, + PROP_PKCS11_CLIENT_CERT, + PROP_PKCS11_PRIVATE_KEY, + PROP_PKCS11_PHASE2_CA_CERT, + PROP_PKCS11_PHASE2_CLIENT_CERT, + PROP_PKCS11_PHASE2_PRIVATE_KEY, LAST_PROP }; @@ -2150,6 +2170,86 @@ return ck_format_to_type (nm_setting_802_1x_get_phase2_private_key_format (setting)); } +const char * +nm_setting_802_1x_get_pkcs11_engine_path (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_engine_path; +} + +const char * +nm_setting_802_1x_get_pkcs11_module_path (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_module_path; +} + +const char * +nm_setting_802_1x_get_pkcs11_module_init_args (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_module_init_args; +} + +guint +nm_setting_802_1x_get_pkcs11_slot (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), 0); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_slot; +} + +const char * +nm_setting_802_1x_get_pkcs11_ca_cert (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_ca_cert; +} + +const char * +nm_setting_802_1x_get_pkcs11_client_cert (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_client_cert; +} + +const char * +nm_setting_802_1x_get_pkcs11_private_key (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_private_key; +} + +const char * +nm_setting_802_1x_get_pkcs11_phase2_ca_cert (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_ca_cert; +} + +const char * +nm_setting_802_1x_get_pkcs11_phase2_client_cert (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_client_cert; +} + +const char * +nm_setting_802_1x_get_pkcs11_phase2_private_key (NMSetting8021x *setting) +{ + g_return_val_if_fail (NM_IS_SETTING_802_1X (setting), NULL); + + return NM_SETTING_802_1X_GET_PRIVATE (setting)->pkcs11_phase2_private_key; +} + static void need_secrets_password (NMSetting8021x *self, GPtrArray *secrets, @@ -2219,7 +2319,8 @@ const char *path = NULL; if (phase2) { - if (!priv->phase2_private_key || !priv->phase2_private_key->len) { + if (!priv->pkcs11_phase2_private_key && + (!priv->phase2_private_key || !priv->phase2_private_key->len)) { g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY); return; } @@ -2235,10 +2336,12 @@ return; } - if (need_private_key_password (blob, path, priv->phase2_private_key_password)) + if (!priv->pkcs11_phase2_private_key && + need_private_key_password (blob, path, priv->phase2_private_key_password)) g_ptr_array_add (secrets, NM_SETTING_802_1X_PHASE2_PRIVATE_KEY_PASSWORD); } else { - if (!priv->private_key || !priv->private_key->len) { + if (!priv->pkcs11_private_key && + (!priv->private_key || !priv->private_key->len)) { g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY); return; } @@ -2254,7 +2357,8 @@ return; } - if (need_private_key_password (blob, path, priv->private_key_password)) + if (!priv->pkcs11_private_key && + need_private_key_password (blob, path, priv->private_key_password)) g_ptr_array_add (secrets, NM_SETTING_802_1X_PRIVATE_KEY_PASSWORD); } } @@ -2265,6 +2369,11 @@ NMSetting8021xPrivate *priv = NM_SETTING_802_1X_GET_PRIVATE (self); if (phase2) { + /* TODO: add better checks for pkcs11 case */ + if (priv->pkcs11_phase2_client_cert && + priv->pkcs11_phase2_private_key) + return TRUE; + if (!priv->phase2_client_cert) { g_set_error (error, NM_SETTING_802_1X_ERROR, @@ -2300,6 +2409,10 @@ } } } else { + /* TODO: add better checks for pkcs11 case */ + if (priv->pkcs11_client_cert && + priv->pkcs11_private_key) + return TRUE; if (!priv->client_cert) { g_set_error (error, NM_SETTING_802_1X_ERROR, @@ -2692,6 +2805,16 @@ g_free (priv->phase2_autheap); g_free (priv->phase2_ca_path); g_free (priv->password); + g_free (priv->pin); + g_free (priv->pkcs11_engine_path); + g_free (priv->pkcs11_module_path); + g_free (priv->pkcs11_module_init_args); + g_free (priv->pkcs11_ca_cert); + g_free (priv->pkcs11_client_cert); + g_free (priv->pkcs11_private_key); + g_free (priv->pkcs11_phase2_ca_cert); + g_free (priv->pkcs11_phase2_client_cert); + g_free (priv->pkcs11_phase2_private_key); nm_utils_slist_free (priv->eap, g_free); @@ -2832,6 +2955,10 @@ g_free (priv->password); priv->password = g_value_dup_string (value); break; + case PROP_PIN: + g_free (priv->pin); + priv->pin = g_value_dup_string (value); + break; case PROP_PRIVATE_KEY: if (priv->private_key) { g_byte_array_free (priv->private_key, TRUE); @@ -2867,6 +2994,45 @@ case PROP_SYSTEM_CA_CERTS: priv->system_ca_certs = g_value_get_boolean (value); break; + case PROP_PKCS11_ENGINE_PATH: + g_free (priv->pkcs11_engine_path); + priv->pkcs11_engine_path = g_value_dup_string (value); + break; + case PROP_PKCS11_MODULE_PATH: + g_free (priv->pkcs11_module_path); + priv->pkcs11_module_path = g_value_dup_string (value); + break; + case PROP_PKCS11_MODULE_INIT_ARGS: + g_free (priv->pkcs11_module_init_args); + priv->pkcs11_module_init_args = g_value_dup_string (value); + break; + case PROP_PKCS11_SLOT: + priv->pkcs11_slot = g_value_get_uint (value); + break; + case PROP_PKCS11_CA_CERT: + g_free (priv->pkcs11_ca_cert); + priv->pkcs11_ca_cert = g_value_dup_string (value); + break; + case PROP_PKCS11_CLIENT_CERT: + g_free (priv->pkcs11_client_cert); + priv->pkcs11_client_cert = g_value_dup_string (value); + break; + case PROP_PKCS11_PRIVATE_KEY: + g_free (priv->pkcs11_private_key); + priv->pkcs11_private_key = g_value_dup_string (value); + break; + case PROP_PKCS11_PHASE2_CA_CERT: + g_free (priv->pkcs11_phase2_ca_cert); + priv->pkcs11_phase2_ca_cert = g_value_dup_string (value); + break; + case PROP_PKCS11_PHASE2_CLIENT_CERT: + g_free (priv->pkcs11_phase2_client_cert); + priv->pkcs11_phase2_client_cert = g_value_dup_string (value); + break; + case PROP_PKCS11_PHASE2_PRIVATE_KEY: + g_free (priv->pkcs11_phase2_private_key); + priv->pkcs11_phase2_private_key = g_value_dup_string (value); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -2926,6 +3092,9 @@ case PROP_PASSWORD: g_value_set_string (value, priv->password); break; + case PROP_PIN: + g_value_set_string (value, priv->pin); + break; case PROP_PRIVATE_KEY: g_value_set_boxed (value, priv->private_key); break; @@ -2941,6 +3110,36 @@ case PROP_SYSTEM_CA_CERTS: g_value_set_boolean (value, priv->system_ca_certs); break; + case PROP_PKCS11_ENGINE_PATH: + g_value_set_string (value, priv->pkcs11_engine_path); + break; + case PROP_PKCS11_MODULE_PATH: + g_value_set_string (value, priv->pkcs11_module_path); + break; + case PROP_PKCS11_MODULE_INIT_ARGS: + g_value_set_string (value, priv->pkcs11_module_init_args); + break; + case PROP_PKCS11_SLOT: + g_value_set_uint (value, priv->pkcs11_slot); + break; + case PROP_PKCS11_CA_CERT: + g_value_set_string (value, priv->pkcs11_ca_cert); + break; + case PROP_PKCS11_CLIENT_CERT: + g_value_set_string (value, priv->pkcs11_client_cert); + break; + case PROP_PKCS11_PRIVATE_KEY: + g_value_set_string (value, priv->pkcs11_private_key); + break; + case PROP_PKCS11_PHASE2_CA_CERT: + g_value_set_string (value, priv->pkcs11_phase2_ca_cert); + break; + case PROP_PKCS11_PHASE2_CLIENT_CERT: + g_value_set_string (value, priv->pkcs11_phase2_client_cert); + break; + case PROP_PKCS11_PHASE2_PRIVATE_KEY: + g_value_set_string (value, priv->pkcs11_phase2_private_key); + break; default: G_OBJECT_WARN_INVALID_PROPERTY_ID (object, prop_id, pspec); break; @@ -3200,6 +3399,19 @@ G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); /** + * NMSetting8021x:pin: + * + * PIN used for 802.1x auth. + **/ + g_object_class_install_property + (object_class, PROP_PIN, + g_param_spec_string (NM_SETTING_802_1X_PIN, + "PIN", + "PIN", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE | NM_SETTING_PARAM_SECRET)); + + /** * NMSetting8021x:password: * * Password used for EAP authentication methods. @@ -3309,6 +3521,87 @@ FALSE, G_PARAM_READWRITE | G_PARAM_CONSTRUCT | NM_SETTING_PARAM_SERIALIZE)); + g_object_class_install_property + (object_class, PROP_PKCS11_ENGINE_PATH, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_ENGINE_PATH, + "OpenSSL pkcs11 engine path", + "OpenSSL pkcs11 engine path", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_MODULE_PATH, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_MODULE_PATH, + "PKCS11 smartcard library module path", + "PKCS11 smartcard library module path", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_MODULE_INIT_ARGS, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_MODULE_INIT_ARGS, + "PKCS11 smartcard library initialization arguments", + "PKCS11 smartcard library initialization arguments", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_SLOT, + g_param_spec_uint (NM_SETTING_802_1X_PKCS11_SLOT, + "PKCS11 slot", + "PKCS11 slot", + 0, 1000, 0, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_CA_CERT, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_CA_CERT, + "PKCS11 object ID of CA certificate", + "PKCS11 object ID of CA certificate", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_CLIENT_CERT, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_CLIENT_CERT, + "PKCS11 object ID of client certificate", + "PKCS11 object ID of client certificate", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_PRIVATE_KEY, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_PRIVATE_KEY, + "PKCS11 object ID of private key", + "PKCS11 object ID of private key", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_PHASE2_CA_CERT, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_CA_CERT, + "PKCS11 object ID of phase2 CA certificate", + "PKCS11 object ID of phase2 CA certificate", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_PHASE2_CLIENT_CERT, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_CLIENT_CERT, + "PKCS11 object ID of phase2 client certificate", + "PKCS11 object ID of phase2 client certificate", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + g_object_class_install_property + (object_class, PROP_PKCS11_PHASE2_PRIVATE_KEY, + g_param_spec_string (NM_SETTING_802_1X_PKCS11_PHASE2_PRIVATE_KEY, + "PKCS11 object ID of phase2 private key", + "PKCS11 object ID of phase2 private key", + NULL, + G_PARAM_READWRITE | NM_SETTING_PARAM_SERIALIZE)); + + /* Initialize crypto lbrary. */ if (!nm_utils_init (&error)) { g_warning ("Couldn't initilize nm-utils/crypto system: %d %s", --- a/libnm-util/nm-setting-8021x.h +++ b/libnm-util/nm-setting-8021x.h @@ -88,6 +88,16 @@ #define NM_SETTING_802_1X_PIN "pin" #define NM_SETTING_802_1X_PSK "psk" #define NM_SETTING_802_1X_SYSTEM_CA_CERTS "system-ca-certs" +#define NM_SETTING_802_1X_PKCS11_ENGINE_PATH "pkcs11-engine-path" +#define NM_SETTING_802_1X_PKCS11_MODULE_PATH "pkcs11-module-path" +#define NM_SETTING_802_1X_PKCS11_MODULE_INIT_ARGS "pkcs11-module-init-args" +#define NM_SETTING_802_1X_PKCS11_SLOT "pkcs11-slot" +#define NM_SETTING_802_1X_PKCS11_CA_CERT "pkcs11-ca-cert" +#define NM_SETTING_802_1X_PKCS11_CLIENT_CERT "pkcs11-client-cert" +#define NM_SETTING_802_1X_PKCS11_PRIVATE_KEY "pkcs11-private-key" +#define NM_SETTING_802_1X_PKCS11_PHASE2_CA_CERT "pkcs11-phase2-ca-cert" +#define NM_SETTING_802_1X_PKCS11_PHASE2_CLIENT_CERT "pkcs11-phase2-client-cert" +#define NM_SETTING_802_1X_PKCS11_PHASE2_PRIVATE_KEY "pkcs11-phase2-private-key" /* PRIVATE KEY NOTE: when setting PKCS#12 private keys directly via properties * using the "blob" scheme, the data must be passed in PKCS#12 format. In this @@ -275,6 +285,17 @@ NMSetting8021xCKType nm_setting_802_1x_get_phase2_private_key_type (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_engine_path (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_module_path (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_module_init_args (NMSetting8021x *setting); +guint nm_setting_802_1x_get_pkcs11_slot (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_ca_cert (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_client_cert (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_private_key (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_phase2_ca_cert (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_phase2_client_cert (NMSetting8021x *setting); +const char * nm_setting_802_1x_get_pkcs11_phase2_private_key (NMSetting8021x *setting); + G_END_DECLS #endif /* NM_SETTING_8021X_H */ --- a/src/supplicant-manager/nm-supplicant-config.c +++ b/src/supplicant-manager/nm-supplicant-config.c @@ -57,6 +57,9 @@ GHashTable *blobs; guint32 ap_scan; gboolean dispose_has_run; + char *pkcs11_engine_path; + char *pkcs11_module_path; + char *pkcs11_module_init_args; } NMSupplicantConfigPrivate; NMSupplicantConfig * @@ -93,6 +96,7 @@ priv->ap_scan = 1; priv->dispose_has_run = FALSE; + priv->pkcs11_engine_path = g_strdup ("/usr/lib/engines/engine_pkcs11.so"); } static gboolean @@ -242,9 +246,14 @@ static void nm_supplicant_config_finalize (GObject *object) { + NMSupplicantConfigPrivate *priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (object); + /* Complete object destruction */ - g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->config); - g_hash_table_destroy (NM_SUPPLICANT_CONFIG_GET_PRIVATE (object)->blobs); + g_hash_table_destroy (priv->config); + g_hash_table_destroy (priv->blobs); + g_free (priv->pkcs11_engine_path); + g_free (priv->pkcs11_module_path); + g_free (priv->pkcs11_module_init_args); /* Chain up to the parent class */ G_OBJECT_CLASS (nm_supplicant_config_parent_class)->finalize (object); @@ -279,6 +288,69 @@ NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->ap_scan = ap_scan; } +const char * +nm_supplicant_config_get_pkcs11_engine_path (NMSupplicantConfig * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_engine_path; +} + +void +nm_supplicant_config_set_pkcs11_engine_path (NMSupplicantConfig * self, + const char *pkcs11_engine_path) +{ + NMSupplicantConfigPrivate *priv; + + g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + g_free (priv->pkcs11_engine_path); + priv->pkcs11_engine_path = g_strdup (pkcs11_engine_path); +} + +const char * +nm_supplicant_config_get_pkcs11_module_path (NMSupplicantConfig * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_module_path; +} + +void +nm_supplicant_config_set_pkcs11_module_path (NMSupplicantConfig * self, + const char *pkcs11_module_path) +{ + NMSupplicantConfigPrivate *priv; + + g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + g_free (priv->pkcs11_module_path); + priv->pkcs11_module_path = g_strdup (pkcs11_module_path); +} + +const char * +nm_supplicant_config_get_pkcs11_module_init_args (NMSupplicantConfig * self) +{ + g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), NULL); + + return NM_SUPPLICANT_CONFIG_GET_PRIVATE (self)->pkcs11_module_init_args; +} + +void +nm_supplicant_config_set_pkcs11_module_init_args (NMSupplicantConfig * self, + const char *pkcs11_module_init_args) +{ + NMSupplicantConfigPrivate *priv; + + g_return_if_fail (NM_IS_SUPPLICANT_CONFIG (self)); + + priv = NM_SUPPLICANT_CONFIG_GET_PRIVATE (self); + g_free (priv->pkcs11_module_init_args); + priv->pkcs11_module_init_args = g_strdup (pkcs11_module_init_args); +} + static void get_hash_cb (gpointer key, gpointer value, gpointer user_data) { @@ -581,6 +653,8 @@ gboolean success; const char *key_mgmt, *auth_alg; const char *psk; + const char *pkcs11_engine_path; + const char *pkcs11_module_path; g_return_val_if_fail (NM_IS_SUPPLICANT_CONFIG (self), FALSE); g_return_val_if_fail (setting != NULL, FALSE); @@ -691,6 +765,27 @@ } } + pkcs11_engine_path = nm_setting_802_1x_get_pkcs11_engine_path (setting_8021x); + pkcs11_module_path = nm_setting_802_1x_get_pkcs11_module_path (setting_8021x); + + if (pkcs11_engine_path && pkcs11_module_path) { + nm_supplicant_config_set_pkcs11_engine_path (self, pkcs11_engine_path); + nm_supplicant_config_set_pkcs11_module_path (self, pkcs11_module_path); + nm_supplicant_config_set_pkcs11_module_init_args (self, + nm_setting_802_1x_get_pkcs11_module_init_args (setting_8021x)); + + add_string_val (self, "1", "engine", FALSE, FALSE); + add_string_val (self, "pkcs11", "engine_id", FALSE, FALSE); + + /* TODO: handle more than one slot */ + add_string_val (self, nm_setting_802_1x_get_pkcs11_ca_cert (setting_8021x), "ca_cert_id", FALSE, FALSE); + add_string_val (self, nm_setting_802_1x_get_pkcs11_client_cert (setting_8021x), "cert_id", FALSE, FALSE); + add_string_val (self, nm_setting_802_1x_get_pkcs11_private_key (setting_8021x), "key_id", FALSE, FALSE); + add_string_val (self, nm_setting_802_1x_get_pkcs11_phase2_ca_cert (setting_8021x), "ca_cert2_id", FALSE, FALSE); + add_string_val (self, nm_setting_802_1x_get_pkcs11_phase2_client_cert (setting_8021x), "cert2_id", FALSE, FALSE); + add_string_val (self, nm_setting_802_1x_get_pkcs11_phase2_private_key (setting_8021x), "key2_id", FALSE, FALSE); + } + return TRUE; } --- a/src/supplicant-manager/nm-supplicant-config.h +++ b/src/supplicant-manager/nm-supplicant-config.h @@ -57,6 +57,21 @@ void nm_supplicant_config_set_ap_scan (NMSupplicantConfig *self, guint32 ap_scan); +const char *nm_supplicant_config_get_pkcs11_engine_path (NMSupplicantConfig * self); + +void nm_supplicant_config_set_pkcs11_engine_path (NMSupplicantConfig * self, + const char *pkcs11_engine_path); + +const char *nm_supplicant_config_get_pkcs11_module_path (NMSupplicantConfig * self); + +void nm_supplicant_config_set_pkcs11_module_path (NMSupplicantConfig * self, + const char *pkcs11_module_path); + +const char *nm_supplicant_config_get_pkcs11_module_init_args (NMSupplicantConfig * self); + +void nm_supplicant_config_set_pkcs11_module_init_args (NMSupplicantConfig * self, + const char *pkcs11_module_init_args); + GHashTable *nm_supplicant_config_get_hash (NMSupplicantConfig *self); GHashTable *nm_supplicant_config_get_blobs (NMSupplicantConfig *self); --- a/src/supplicant-manager/nm-supplicant-interface.c +++ b/src/supplicant-manager/nm-supplicant-interface.c @@ -1259,6 +1259,8 @@ NMSupplicantInfo *info; DBusGProxyCall *call; guint32 ap_scan; + const char *pkcs11_engine_path; + const char *pkcs11_module_path; g_return_val_if_fail (NM_IS_SUPPLICANT_INTERFACE (self), FALSE); @@ -1285,6 +1287,41 @@ G_TYPE_INVALID); nm_supplicant_info_set_call (info, call); + if (!call) + return FALSE; + + pkcs11_engine_path = nm_supplicant_config_get_pkcs11_engine_path (priv->cfg); + pkcs11_module_path = nm_supplicant_config_get_pkcs11_module_path (priv->cfg); + + if (pkcs11_engine_path && pkcs11_module_path) { + GHashTable *pkcs11_config_hash; + GValue *val; + + pkcs11_config_hash = g_hash_table_new_full (g_str_hash, g_str_equal, NULL, (GDestroyNotify) blob_free); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, pkcs11_engine_path); + g_hash_table_insert (pkcs11_config_hash, "pkcs11_engine_path", val); + + val = g_slice_new0 (GValue); + g_value_init (val, G_TYPE_STRING); + g_value_set_string (val, pkcs11_module_path); + g_hash_table_insert (pkcs11_config_hash, "pkcs11_module_path", val); + + /* TODO: waiting on pkcs11_module_init_args support in wpasupplicant + tmp = nm_supplicant_config_get_pkcs11_module_init_args (priv->cfg); + g_hash_table_insert (pkcs11_config_hash, "pkcs11_module_init_args", + str_to_gvalue(tmp)); + */ + + dbus_g_proxy_call_no_reply (priv->iface_proxy, "setSmartcardModules", + DBUS_TYPE_G_MAP_OF_VARIANT, + pkcs11_config_hash, + G_TYPE_INVALID); + g_hash_table_destroy (pkcs11_config_hash); + } + return call != NULL; } --- a/src/supplicant-manager/nm-supplicant-settings-verify.c +++ b/src/supplicant-manager/nm-supplicant-settings-verify.c @@ -121,7 +121,12 @@ { "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 }, + { "ca_cert_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "cert_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "key_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "ca_cert2_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "cert2_id", TYPE_BYTES, 0, 0, FALSE, NULL }, + { "key2_id", TYPE_BYTES, 0, 0, FALSE, NULL }, { "fragment_size", TYPE_INT, 1, 2000, FALSE, NULL }, };