diff options
author | Martin Willi <martin@strongswan.org> | 2008-08-20 08:51:18 +0000 |
---|---|---|
committer | Martin Willi <martin@strongswan.org> | 2008-08-20 08:51:18 +0000 |
commit | 142eaea43c9feb4033c1e07151771f68da8630cc (patch) | |
tree | bd80507320f7e8b52d608e536835fd92d87451ba | |
parent | 592dc30108c0f850a14cdf14a9fde4d974a6d9d1 (diff) | |
download | strongswan-142eaea43c9feb4033c1e07151771f68da8630cc.tar.bz2 strongswan-142eaea43c9feb4033c1e07151771f68da8630cc.tar.xz |
fixed shared key lookup by ID
proper auth method selection
-rw-r--r-- | src/charon/plugins/nm/gnome/nm-strongswan-service.name.in | 2 | ||||
-rw-r--r-- | src/charon/plugins/nm/gnome/properties/nm-strongswan.c | 23 | ||||
-rw-r--r-- | src/charon/plugins/nm/nm_creds.c | 106 | ||||
-rw-r--r-- | src/charon/plugins/nm/nm_creds.h | 5 | ||||
-rw-r--r-- | src/charon/plugins/nm/nm_service.c | 22 |
5 files changed, 134 insertions, 24 deletions
diff --git a/src/charon/plugins/nm/gnome/nm-strongswan-service.name.in b/src/charon/plugins/nm/gnome/nm-strongswan-service.name.in index 1555d489f..9d8f0f0f5 100644 --- a/src/charon/plugins/nm/gnome/nm-strongswan-service.name.in +++ b/src/charon/plugins/nm/gnome/nm-strongswan-service.name.in @@ -4,5 +4,5 @@ service=org.freedesktop.NetworkManager.strongswan program=@LIBEXECDIR@/ipsec/charon [GNOME] -auth-dialog=nm-strongswan-auth-dialog +auth-dialog=@LIBEXECDIR@/nm-strongswan-auth-dialog properties=libnm-strongswan-properties diff --git a/src/charon/plugins/nm/gnome/properties/nm-strongswan.c b/src/charon/plugins/nm/gnome/properties/nm-strongswan.c index 285a7f7b4..edaaf0302 100644 --- a/src/charon/plugins/nm/gnome/properties/nm-strongswan.c +++ b/src/charon/plugins/nm/gnome/properties/nm-strongswan.c @@ -178,12 +178,16 @@ init_plugin_ui (StrongswanPluginUiWidget *self, NMConnection *connection, GError widget = glade_xml_get_widget (priv->xml, "method-combo"); if (!widget) return FALSE; - gtk_combo_box_append_text (GTK_COMBO_BOX (widget), "EAP"); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("EAP")); + gtk_combo_box_append_text (GTK_COMBO_BOX (widget), _("PSK (insecure)")); value = g_hash_table_lookup (settings->data, "method"); if (value) { - if (g_strcasecmp (value, "EAP") == 0) { + if (g_strcasecmp (value, "eap") == 0) { gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 0); } + if (g_strcasecmp (value, "psk") == 0) { + gtk_combo_box_set_active (GTK_COMBO_BOX (widget), 1); + } } g_signal_connect (G_OBJECT (widget), "changed", G_CALLBACK (stuff_changed_cb), self); if (gtk_combo_box_get_active (GTK_COMBO_BOX (widget)) == -1) @@ -272,10 +276,19 @@ update_connection (NMVpnPluginUiWidgetInterface *iface, } widget = glade_xml_get_widget (priv->xml, "method-combo"); - str = (char *) gtk_combo_box_get_active_text (GTK_COMBO_BOX (widget)); - if (str) { - g_hash_table_insert (settings->data, g_strdup ("method"), g_strdup(str)); + switch (gtk_combo_box_get_active (GTK_COMBO_BOX (widget))) + { + default: + str = "eap"; + break; + case 1: + str = "psk"; + break; + case 2: + str = "pubkey"; + break; } + g_hash_table_insert (settings->data, g_strdup ("method"), g_strdup(str)); widget = glade_xml_get_widget (priv->xml, "virtual-check"); active = gtk_toggle_button_get_active(GTK_TOGGLE_BUTTON(widget)); diff --git a/src/charon/plugins/nm/nm_creds.c b/src/charon/plugins/nm/nm_creds.c index ebfc10177..cb06c7499 100644 --- a/src/charon/plugins/nm/nm_creds.c +++ b/src/charon/plugins/nm/nm_creds.c @@ -40,6 +40,11 @@ struct private_nm_creds_t { certificate_t *cert; /** + * User name + */ + identification_t *user; + + /** * User password */ char *pass; @@ -57,33 +62,107 @@ static enumerator_t* create_cert_enumerator(private_nm_creds_t *this, certificate_type_t cert, key_type_t key, identification_t *id, bool trusted) { - if (!this->cert || - (cert != CERT_ANY && cert != this->cert->get_type(this->cert))) + if (!this->cert) + { + return NULL; + } + if (cert != CERT_ANY && cert != this->cert->get_type(this->cert)) { return NULL; } + if (id && !this->cert->has_subject(this->cert, id)) + { + return NULL; + } + if (key != KEY_ANY) + { + public_key_t *public; + + public = this->cert->get_public_key(this->cert); + if (!public) + { + return NULL; + } + if (public->get_type(public) != key) + { + public->destroy(public); + return NULL; + } + public->destroy(public); + } + pthread_rwlock_rdlock(&this->lock); return enumerator_create_cleaner(enumerator_create_single(this->cert, NULL), (void*)pthread_rwlock_unlock, &this->lock); } /** + * shared key enumerator implementation + */ +typedef struct { + enumerator_t public; + private_nm_creds_t *this; + shared_key_t *key; + bool done; +} shared_enumerator_t; + +/** + * enumerate function for shared enumerator + */ +static bool shared_enumerate(shared_enumerator_t *this, shared_key_t **key, + id_match_t *me, id_match_t *other) +{ + if (this->done) + { + return FALSE; + } + *key = this->key; + *me = ID_MATCH_PERFECT; + *other = ID_MATCH_ANY; + this->done = TRUE; + return TRUE; +} + +/** + * Destroy function for shared enumerator + */ +static void shared_destroy(shared_enumerator_t *this) +{ + this->key->destroy(this->key); + pthread_rwlock_unlock(&this->this->lock); + free(this); +} +/** * Implements credential_set_t.create_cert_enumerator */ static enumerator_t* create_shared_enumerator(private_nm_creds_t *this, shared_key_type_t type, identification_t *me, identification_t *other) { - shared_key_t *key; + shared_enumerator_t *enumerator; - if (!this->pass || (type != SHARED_EAP && type != SHARED_IKE)) + if (!this->pass || !this->user) + { + return NULL; + } + if (type != SHARED_EAP && type != SHARED_IKE) { return NULL; } - key = shared_key_create(type, chunk_clone( - chunk_create(this->pass, strlen(this->pass)))); - return enumerator_create_cleaner( - enumerator_create_single(key, (void*)key->destroy), - (void*)pthread_rwlock_unlock, &this->lock); + if (me && !me->equals(me, this->user)) + { + return NULL; + } + + enumerator = malloc_thing(shared_enumerator_t); + enumerator->public.enumerate = (void*)shared_enumerate; + enumerator->public.destroy = (void*)shared_destroy; + enumerator->this = this; + enumerator->done = FALSE; + pthread_rwlock_rdlock(&this->lock); + enumerator->key = shared_key_create(type, + chunk_clone(chunk_create(this->pass, + strlen(this->pass)))); + return &enumerator->public; } /** @@ -100,9 +179,12 @@ static void set_certificate(private_nm_creds_t *this, certificate_t *cert) /** * Implementation of nm_creds_t.set_password */ -static void set_password(private_nm_creds_t *this, char *password) +static void set_password(private_nm_creds_t *this, identification_t *id, + char *password) { pthread_rwlock_wrlock(&this->lock); + DESTROY_IF(this->user); + this->user = id->clone(id); free(this->pass); this->pass = strdup(password); pthread_rwlock_unlock(&this->lock); @@ -114,6 +196,7 @@ static void set_password(private_nm_creds_t *this, char *password) static void destroy(private_nm_creds_t *this) { DESTROY_IF(this->cert); + DESTROY_IF(this->user); free(this->pass); pthread_rwlock_destroy(&this->lock); free(this); @@ -132,12 +215,13 @@ nm_creds_t *nm_creds_create() this->public.set.create_cdp_enumerator = (void*)return_null; this->public.set.cache_cert = (void*)nop; this->public.set_certificate = (void(*)(nm_creds_t*, certificate_t *cert))set_certificate; - this->public.set_password = (void(*)(nm_creds_t*, char *password))set_password; + this->public.set_password = (void(*)(nm_creds_t*, identification_t *id, char *password))set_password; this->public.destroy = (void(*)(nm_creds_t*))destroy; pthread_rwlock_init(&this->lock, NULL); this->cert = NULL; + this->user = NULL; this->pass = NULL; return &this->public; diff --git a/src/charon/plugins/nm/nm_creds.h b/src/charon/plugins/nm/nm_creds.h index 773f241cc..40cfb7776 100644 --- a/src/charon/plugins/nm/nm_creds.h +++ b/src/charon/plugins/nm/nm_creds.h @@ -45,11 +45,12 @@ struct nm_creds_t { void (*set_certificate)(nm_creds_t *this, certificate_t *cert); /** - * Set the users password for authentication. + * Set the username/password for authentication. * + * @param id ID of the user * @param password password to use for authentication */ - void (*set_password)(nm_creds_t *this, char *password); + void (*set_password)(nm_creds_t *this, identification_t *id, char *password); /** * Destroy a nm_creds instance. diff --git a/src/charon/plugins/nm/nm_service.c b/src/charon/plugins/nm/nm_service.c index 123251a76..2fc4ab227 100644 --- a/src/charon/plugins/nm/nm_service.c +++ b/src/charon/plugins/nm/nm_service.c @@ -142,10 +142,9 @@ bool listen_bus(bus_listener_t *listener, signal_t signal, level_t level, /* FALL */ case IKE_UP_FAILED: case CHD_UP_FAILED: + /* TODO: NM does not handle this failure!? nm_vpn_plugin_failure(private->plugin, - NM_VPN_PLUGIN_FAILURE_CONNECT_FAILED); - /* TODO: NM does not react on this failure!? So additionaly - * reset state */ + NM_VPN_PLUGIN_FAILURE_LOGIN_FAILED); */ nm_vpn_plugin_set_state(private->plugin, NM_VPN_SERVICE_STATE_STOPPED); return FALSE; @@ -172,6 +171,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, child_cfg_t *child_cfg; traffic_selector_t *ts; ike_sa_t *ike_sa; + config_auth_method_t method = CONF_AUTH_EAP; /** * Read parameters @@ -207,6 +207,18 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, encap = str && streq(str, "yes"); str = g_hash_table_lookup(settings->data, "ipcomp"); ipcomp = str && streq(str, "yes"); + str = g_hash_table_lookup(settings->data, "method"); + if (str) + { + if (streq(str, "psk")) + { + method = CONF_AUTH_PSK; + } + else if (streq(str, "pubkey")) + { + method = CONF_AUTH_PUBKEY; + } + } /** * Register credentials @@ -225,7 +237,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, str = g_hash_table_lookup(settings->data, "password"); if (str) { - creds->set_password(creds, str); + creds->set_password(creds, user, str); } /** @@ -235,7 +247,7 @@ static gboolean connect_(NMVPNPlugin *plugin, NMConnection *connection, ike_cfg->add_proposal(ike_cfg, proposal_create_default(PROTO_IKE)); peer_cfg = peer_cfg_create(CONFIG_NAME, 2, ike_cfg, user, identification_create_from_encoding(ID_ANY, chunk_empty), - CERT_SEND_IF_ASKED, UNIQUE_REPLACE, CONF_AUTH_PSK, + CERT_SEND_IF_ASKED, UNIQUE_REPLACE, method, 0, 0, 1, /* EAP method, vendor, keyingtries */ 18000, 0, /* rekey 5h, reauth none */ 600, 600, /* jitter, over 10min */ |