+NetworkManager-strongswan-1.2.0
+-------------------------------
+
+- Added Smartcard support
+
NetworkManager-strongswan-1.1.2
-------------------------------
g_object_unref (program);
return 1;
}
- if (!strcmp(type, "eap") || !strcmp(type, "key"))
+ if (!strcmp(type, "eap") || !strcmp(type, "key") || !strcmp(type, "smartcard"))
{
pass = lookup_password(name, service);
if (!pass || retry)
dialog = gnome_password_dialog_new(_("VPN password required"),
_("EAP password required to establish VPN connection:"),
NULL, NULL, TRUE);
+ gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
}
- else
+ else if (!strcmp(type, "key"))
{
dialog = gnome_password_dialog_new(_("VPN password required"),
_("Private key decryption password required to establish VPN connection:"),
NULL, NULL, TRUE);
+ gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
+ }
+ else /* smartcard */
+ {
+ dialog = gnome_password_dialog_new(_("VPN password required"),
+ _("Smartcard PIN required to establish VPN connection:"),
+ NULL, NULL, TRUE);
+ gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), FALSE);
}
- gnome_password_dialog_set_show_remember(GNOME_PASSWORD_DIALOG(dialog), TRUE);
gnome_password_dialog_set_show_username(GNOME_PASSWORD_DIALOG(dialog), FALSE);
if (pass)
{
AC_PREREQ(2.52)
-AC_INIT(NetworkManager-strongswan, 1.1.2, martin@strongswan.org, NetworkManager-strongswan)
+AC_INIT(NetworkManager-strongswan, 1.2.0, martin@strongswan.org, NetworkManager-strongswan)
AM_INIT_AUTOMAKE([subdir-objects])
AM_MAINTAINER_MODE
msgstr ""
"Project-Id-Version: NetworkManager-strongswan\n"
"Report-Msgid-Bugs-To: \n"
-"POT-Creation-Date: 2010-02-18 09:20+0100\n"
+"POT-Creation-Date: 2010-08-11 16:12+0200\n"
"PO-Revision-Date: 2010-02-18 09:20+0100\n"
"Last-Translator: Martin Willi <martin@strongswan.org>\n"
"Language-Team: de <martin@strongswan.org>\n"
msgid "IPsec with the IKEv2 key exchange protocol."
msgstr "IPsec mit dem IKEv2 Protokoll."
-#: ../properties/nm-strongswan.c:200
+#: ../properties/nm-strongswan.c:208
msgid "Certificate/private key"
msgstr "Zertifikat/Privater Schlüssel"
-#: ../properties/nm-strongswan.c:201
+#: ../properties/nm-strongswan.c:209
msgid "Certificate/ssh-agent"
msgstr "Zertifikat/ssh-agent"
-#: ../properties/nm-strongswan.c:202
+#: ../properties/nm-strongswan.c:210
+msgid "Smartcard"
+msgstr "Smartcard"
+
+#: ../properties/nm-strongswan.c:211
msgid "EAP"
msgstr "EAP"
"IPComp compresses raw IP packets before they get encrypted. This saves some "
"bandwith, but uses more processing power."
msgstr ""
-"IPComp komprimiert IP-Pakete, bevor sie verschlsselt werden. Diese Option "
-"kann Bandbreite sparen, bentigt jedoch zustzliche Rechenleistung."
+"IPComp komprimiert IP-Pakete, bevor sie verschlüsselt werden. Diese Option "
+"kann Bandbreite sparen, benötigt jedoch zusätzliche Rechenleistung."
#: ../properties/nm-strongswan-dialog.glade.h:13
msgid "Private _key:"
#: ../properties/nm-strongswan-dialog.glade.h:18
msgid "The username (identity) to use for authentication against the gateway."
-msgstr "Benutzername/Identitt für die Authentisierung gegenüber dem Gateway."
+msgstr "Benutzername/Identität für die Authentisierung gegenüber dem Gateway."
#: ../properties/nm-strongswan-dialog.glade.h:19
msgid "Use IP c_ompression"
msgid "_Username:"
msgstr "_Benutzername:"
-#: ../auth-dialog/main.c:172 ../auth-dialog/main.c:178
+#: ../auth-dialog/main.c:172 ../auth-dialog/main.c:179
+#: ../auth-dialog/main.c:186
msgid "VPN password required"
msgstr "VPN Passwort notwendig"
msgid "EAP password required to establish VPN connection:"
msgstr "Für die Erstellung des VPN-Tunnels ist ein EAP-Passwort erforderlich:"
-#: ../auth-dialog/main.c:179
+#: ../auth-dialog/main.c:180
msgid "Private key decryption password required to establish VPN connection:"
msgstr ""
"Der Private Schlüssel für die Erstellung des VPN-Tunnels ist durch ein "
"Passwort geschützt:"
-#: ../auth-dialog/main.c:225
+#: ../auth-dialog/main.c:187
+#, fuzzy
+msgid "Smartcard PIN required to establish VPN connection:"
+msgstr "Für die Smartcard ist eine PIN erforderlich:"
+
+#: ../auth-dialog/main.c:233
msgid ""
"Configuration uses ssh-agent for authentication, but ssh-agent is not "
"running!"
gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
break;
case 2:
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-button"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "user-entry"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-label"));
+ gtk_widget_hide (glade_xml_get_widget (priv->xml, "userkey-button"));
+ break;
+ case 3:
gtk_widget_show (glade_xml_get_widget (priv->xml, "user-label"));
gtk_widget_show (glade_xml_get_widget (priv->xml, "user-entry"));
gtk_widget_hide (glade_xml_get_widget (priv->xml, "usercert-label"));
widget = glade_xml_get_widget (priv->xml, "method-combo");
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/private key"));
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Certificate/ssh-agent"));
+ gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("Smartcard"));
gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("EAP"));
value = nm_setting_vpn_get_data_item (settings, "method");
if (value) {
if (g_strcmp0 (value, "agent") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1);
}
- if (g_strcmp0 (value, "eap") == 0) {
+ if (g_strcmp0 (value, "smartcard") == 0) {
gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 2);
}
+ if (g_strcmp0 (value, "eap") == 0) {
+ gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 3);
+ }
}
if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1)
{
str = "agent";
break;
case 2:
+ str = "smartcard";
+ break;
+ case 3:
widget = glade_xml_get_widget (priv->xml, "user-entry");
str = (char *) gtk_entry_get_text (GTK_ENTRY (widget));
if (str && strlen (str)) {
char *pass;
/**
- * Private key decryption password
+ * Private key decryption password / smartcard pin
*/
char *keypass;
/**
+ * private key ID of smartcard key
+ */
+ chunk_t keyid;
+
+ /**
* users certificate
*/
certificate_t *usercert;
}
key = chunk_create(this->keypass, strlen(this->keypass));
break;
+ case SHARED_PIN:
+ if (!this->keypass || !me ||
+ !chunk_equals(me->get_encoding(me), this->keyid))
+ {
+ return NULL;
+ }
+ key = chunk_create(this->keypass, strlen(this->keypass));
+ break;
default:
return NULL;
}
}
/**
+ * Implementation of nm_creds_t.set_pin
+ */
+static void set_pin(private_nm_creds_t *this, chunk_t keyid, char *pin)
+{
+ this->lock->write_lock(this->lock);
+ free(this->keypass);
+ free(this->keyid.ptr);
+ this->keypass = pin ? strdup(pin) : NULL;
+ this->keyid = chunk_clone(keyid);
+ this->lock->unlock(this->lock);
+}
+
+/**
* Implementation of nm_creds_t.set_cert_and_key
*/
static void set_cert_and_key(private_nm_creds_t *this, certificate_t *cert,
}
DESTROY_IF(this->user);
free(this->pass);
+ free(this->keypass);
+ free(this->keyid.ptr);
DESTROY_IF(this->usercert);
DESTROY_IF(this->key);
this->key = NULL;
this->usercert = NULL;
this->pass = NULL;
this->user = NULL;
+ this->keypass = NULL;
+ this->keyid = chunk_empty;
}
/**
this->public.load_ca_dir = (void(*)(nm_creds_t*, char *dir))load_ca_dir;
this->public.set_username_password = (void(*)(nm_creds_t*, identification_t *id, char *password))set_username_password;
this->public.set_key_password = (void(*)(nm_creds_t*, char *password))set_key_password;
+ this->public.set_pin = (void(*)(nm_creds_t*, chunk_t keyid, char *pin))set_pin;
this->public.set_cert_and_key = (void(*)(nm_creds_t*, certificate_t *cert, private_key_t *key))set_cert_and_key;
this->public.clear = (void(*)(nm_creds_t*))clear;
this->public.destroy = (void(*)(nm_creds_t*))destroy;
this->pass = NULL;
this->usercert = NULL;
this->key = NULL;
+ this->keypass = NULL;
+ this->keyid = chunk_empty;
return &this->public;
}
void (*set_key_password)(nm_creds_t *this, char *password);
/**
+ * Set the PIN to unlock a smartcard.
+ *
+ * @param keyid keyid of the smartcard key
+ * @param pin PIN
+ */
+ void (*set_pin)(nm_creds_t *this, chunk_t keyid, char *pin);
+
+ /**
* Set the certificate and private key to use for client authentication.
*
* @param cert client certificate
}
/**
+ * Find a certificate for which we have a private key on a smartcard
+ */
+static identification_t *find_smartcard_key(NMStrongswanPluginPrivate *priv,
+ char *pin)
+{
+ enumerator_t *enumerator, *sans;
+ identification_t *id = NULL;
+ certificate_t *cert;
+ x509_t *x509;
+ private_key_t *key;
+ chunk_t keyid;
+
+ enumerator = lib->credmgr->create_cert_enumerator(lib->credmgr,
+ CERT_X509, KEY_ANY, NULL, FALSE);
+ while (enumerator->enumerate(enumerator, &cert))
+ {
+ x509 = (x509_t*)cert;
+
+ /* there might be a lot of certificates, filter them by usage */
+ if ((x509->get_flags(x509) & X509_CLIENT_AUTH) &&
+ !(x509->get_flags(x509) & X509_CA))
+ {
+ keyid = x509->get_subjectKeyIdentifier(x509);
+ if (keyid.ptr)
+ {
+ /* try to find a private key by the certificate keyid */
+ priv->creds->set_pin(priv->creds, keyid, pin);
+ key = lib->creds->create(lib->creds, CRED_PRIVATE_KEY,
+ KEY_ANY, BUILD_PKCS11_KEYID, keyid, BUILD_END);
+ if (key)
+ {
+ /* prefer a more convenient subjectAltName */
+ sans = x509->create_subjectAltName_enumerator(x509);
+ if (!sans->enumerate(sans, &id))
+ {
+ id = cert->get_subject(cert);
+ }
+ id = id->clone(id);
+ sans->destroy(sans);
+
+ DBG1(DBG_CFG, "using smartcard certificate '%Y'", id);
+ priv->creds->set_cert_and_key(priv->creds,
+ cert->get_ref(cert), key);
+ break;
+ }
+ }
+ }
+ }
+ enumerator->destroy(enumerator);
+ return id;
+}
+
+/**
* Connect function called from NM via DBUS
*/
static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection,
auth_class_t auth_class = AUTH_CLASS_EAP;
certificate_t *cert = NULL;
x509_t *x509;
- bool agent = FALSE;
+ bool agent = FALSE, smartcard = FALSE;
lifetime_cfg_t lifetime = {
.time = {
.life = 10800 /* 3h */,
{
auth_class = AUTH_CLASS_PUBKEY;
}
+ else if (streq(str, "smartcard"))
+ {
+ auth_class = AUTH_CLASS_PUBKEY;
+ smartcard = TRUE;
+ }
}
/**
if (auth_class == AUTH_CLASS_PUBKEY)
{
+ if (smartcard)
+ {
+ char *pin;
+
+ pin = (char*)nm_setting_vpn_get_secret(vpn, "password");
+ if (pin)
+ {
+ user = find_smartcard_key(priv, pin);
+ }
+ if (!user)
+ {
+ g_set_error(err, NM_VPN_PLUGIN_ERROR,
+ NM_VPN_PLUGIN_ERROR_BAD_ARGUMENTS,
+ "no usable smartcard certificate found.");
+ gateway->destroy(gateway);
+ return FALSE;
+ }
+ }
/* ... or certificate/private key authenitcation */
- str = nm_setting_vpn_get_data_item(vpn, "usercert");
- if (str)
+ else if ((str = nm_setting_vpn_get_data_item(vpn, "usercert")))
{
public_key_t *public;
private_key_t *private = NULL;
}
}
}
+ else if streq(method, "smartcard")
+ {
+ if (nm_setting_vpn_get_secret(settings, "password"))
+ {
+ return FALSE;
+ }
+ }
}
*setting_name = NM_SETTING_VPN_SETTING_NAME;
return TRUE;