aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorTobias Brunner <tobias@strongswan.org>2012-04-17 11:18:37 +0200
committerTobias Brunner <tobias@strongswan.org>2012-04-17 14:20:58 +0200
commit9f1b303afc9131b8f87806ad0081962d0b9f0b4e (patch)
tree334ed2cca2e76753291555fdfa424048e2fc4c0c /src
parent7b00fdeb8480a34dab912091d581febe7010d8dc (diff)
downloadstrongswan-9f1b303afc9131b8f87806ad0081962d0b9f0b4e.tar.bz2
strongswan-9f1b303afc9131b8f87806ad0081962d0b9f0b4e.tar.xz
Added stroke user-creds command, to set username/password for a connection.
Diffstat (limited to 'src')
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.c137
-rw-r--r--src/libcharon/plugins/stroke/stroke_config.h10
-rw-r--r--src/libcharon/plugins/stroke/stroke_socket.c20
-rw-r--r--src/stroke/stroke.c28
-rw-r--r--src/stroke/stroke_keywords.h1
-rw-r--r--src/stroke/stroke_keywords.txt1
-rw-r--r--src/stroke/stroke_msg.h9
7 files changed, 204 insertions, 2 deletions
diff --git a/src/libcharon/plugins/stroke/stroke_config.c b/src/libcharon/plugins/stroke/stroke_config.c
index f09c74155..3a4574a91 100644
--- a/src/libcharon/plugins/stroke/stroke_config.c
+++ b/src/libcharon/plugins/stroke/stroke_config.c
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -956,6 +957,141 @@ METHOD(stroke_config_t, del, void,
}
}
+METHOD(stroke_config_t, set_user_credentials, void,
+ private_stroke_config_t *this, stroke_msg_t *msg, FILE *prompt)
+{
+ enumerator_t *enumerator, *children;
+ peer_cfg_t *peer, *found = NULL;
+ auth_class_t auth_class;
+ auth_cfg_t *auth_cfg;
+ child_cfg_t *child;
+ identification_t *id;
+ shared_key_type_t type = SHARED_ANY;
+ chunk_t password = chunk_empty;
+
+ this->mutex->lock(this->mutex);
+ enumerator = this->list->create_enumerator(this->list);
+ while (enumerator->enumerate(enumerator, (void**)&peer))
+ { /* find the peer (or child) config with the given name */
+ if (streq(peer->get_name(peer), msg->user_creds.name))
+ {
+ found = peer;
+ }
+ else
+ {
+ children = peer->create_child_cfg_enumerator(peer);
+ while (children->enumerate(children, &child))
+ {
+ if (streq(child->get_name(child), msg->user_creds.name))
+ {
+ found = peer;
+ break;
+ }
+ }
+ children->destroy(children);
+ }
+
+ if (found)
+ {
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (!found)
+ {
+ DBG1(DBG_CFG, " no config named '%s'", msg->user_creds.name);
+ fprintf(prompt, "no config named '%s'\n", msg->user_creds.name);
+ this->mutex->unlock(this->mutex);
+ return;
+ }
+
+ id = identification_create_from_string(msg->user_creds.username);
+ if (strlen(msg->user_creds.username) == 0 ||
+ !id || id->get_type(id) == ID_ANY)
+ {
+ DBG1(DBG_CFG, " invalid username '%s'", msg->user_creds.username);
+ fprintf(prompt, "invalid username '%s'\n", msg->user_creds.username);
+ this->mutex->unlock(this->mutex);
+ DESTROY_IF(id);
+ return;
+ }
+
+ /* replace/set the username in the first suitable auth_cfg */
+ enumerator = found->create_auth_cfg_enumerator(found, TRUE);
+ while (enumerator->enumerate(enumerator, (void**)&auth_cfg))
+ {
+ auth_class = (uintptr_t)auth_cfg->get(auth_cfg, AUTH_RULE_AUTH_CLASS);
+ if (auth_class == AUTH_CLASS_EAP)
+ {
+ DBG1(DBG_CFG, " configured EAP-Identity %Y", id);
+ if (!auth_cfg->replace_value(auth_cfg, AUTH_RULE_EAP_IDENTITY, id))
+ {
+ auth_cfg->add(auth_cfg, AUTH_RULE_EAP_IDENTITY, id);
+ }
+ type = SHARED_EAP;
+ break;
+ }
+ }
+ enumerator->destroy(enumerator);
+
+ if (type == SHARED_ANY)
+ {
+ DBG1(DBG_CFG, " config '%s' unsuitable for user credentials",
+ msg->user_creds.name);
+ fprintf(prompt, "config '%s' unsuitable for user credentials\n",
+ msg->user_creds.name);
+ this->mutex->unlock(this->mutex);
+ id->destroy(id);
+ return;
+ }
+ this->mutex->unlock(this->mutex);
+
+ if (msg->user_creds.password)
+ {
+ char *pass;
+
+ pass = msg->user_creds.password;
+ password = chunk_clone(chunk_create(pass, strlen(pass)));
+ memwipe(pass, strlen(pass));
+ }
+ else
+ { /* prompt the user for the password */
+ char buf[256];
+
+ fprintf(prompt, "Password:\n");
+ if (fgets(buf, sizeof(buf), prompt))
+ {
+ password = chunk_clone(chunk_create(buf, strlen(buf)));
+ if (password.len > 0)
+ { /* trim trailing \n */
+ password.len--;
+ }
+ memwipe(buf, sizeof(buf));
+ }
+ }
+
+ if (password.len)
+ {
+ shared_key_t *shared;
+ linked_list_t *owners;
+
+ shared = shared_key_create(type, password);
+
+ owners = linked_list_create();
+ owners->insert_last(owners, id->clone(id));
+ this->cred->add_shared(this->cred, shared, owners);
+
+ DBG1(DBG_CFG, " added %N secret for %Y", shared_key_type_names,
+ type, id);
+ DBG4(DBG_CFG, " secret: %#B", &password);
+ }
+ else
+ { /* in case a user answers the password prompt by just pressing enter */
+ chunk_clear(&password);
+ }
+}
+
METHOD(stroke_config_t, destroy, void,
private_stroke_config_t *this)
{
@@ -980,6 +1116,7 @@ stroke_config_t *stroke_config_create(stroke_ca_t *ca, stroke_cred_t *cred)
},
.add = _add,
.del = _del,
+ .set_user_credentials = _set_user_credentials,
.destroy = _destroy,
},
.list = linked_list_create(),
diff --git a/src/libcharon/plugins/stroke/stroke_config.h b/src/libcharon/plugins/stroke/stroke_config.h
index 05e4665ca..450d517f3 100644
--- a/src/libcharon/plugins/stroke/stroke_config.h
+++ b/src/libcharon/plugins/stroke/stroke_config.h
@@ -1,4 +1,5 @@
/*
+ * Copyright (C) 2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -53,6 +54,15 @@ struct stroke_config_t {
void (*del)(stroke_config_t *this, stroke_msg_t *msg);
/**
+ * Set the username and password for a connection in this backend.
+ *
+ * @param msg received stroke message
+ * @param prompt I/O channel to prompt for the password
+ */
+ void (*set_user_credentials)(stroke_config_t *this, stroke_msg_t *msg,
+ FILE *prompt);
+
+ /**
* Destroy a stroke_config instance.
*/
void (*destroy)(stroke_config_t *this);
diff --git a/src/libcharon/plugins/stroke/stroke_socket.c b/src/libcharon/plugins/stroke/stroke_socket.c
index 72757ec16..d51cdafde 100644
--- a/src/libcharon/plugins/stroke/stroke_socket.c
+++ b/src/libcharon/plugins/stroke/stroke_socket.c
@@ -1,5 +1,5 @@
/*
- * Copyright (C) 2011 Tobias Brunner
+ * Copyright (C) 2011-2012 Tobias Brunner
* Copyright (C) 2008 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -472,6 +472,21 @@ static void stroke_memusage(private_stroke_socket_t *this,
}
/**
+ * Set username and password for a connection
+ */
+static void stroke_user_creds(private_stroke_socket_t *this,
+ stroke_msg_t *msg, FILE *out)
+{
+ pop_string(msg, &msg->user_creds.name);
+ pop_string(msg, &msg->user_creds.username);
+ pop_string(msg, &msg->user_creds.password);
+
+ DBG1(DBG_CFG, "received stroke: user-creds '%s'", msg->user_creds.name);
+
+ this->config->set_user_credentials(this->config, msg, out);
+}
+
+/**
* set the verbosity debug output
*/
static void stroke_loglevel(private_stroke_socket_t *this,
@@ -644,6 +659,9 @@ static job_requeue_t process(stroke_job_context_t *ctx)
case STR_MEMUSAGE:
stroke_memusage(this, msg, out);
break;
+ case STR_USER_CREDS:
+ stroke_user_creds(this, msg, out);
+ break;
default:
DBG1(DBG_CFG, "received unknown stroke");
break;
diff --git a/src/stroke/stroke.c b/src/stroke/stroke.c
index 2e081147c..bb299567b 100644
--- a/src/stroke/stroke.c
+++ b/src/stroke/stroke.c
@@ -1,5 +1,5 @@
/* Stroke for charon is the counterpart to whack from pluto
- * Copyright (C) 2007 Tobias Brunner
+ * Copyright (C) 2007-2012 Tobias Brunner
* Copyright (C) 2006 Martin Willi
* Hochschule fuer Technik Rapperswil
*
@@ -352,6 +352,19 @@ static int memusage()
return send_stroke_msg(&msg);
}
+static int user_credentials(char *name, char *user, char *pass)
+{
+ stroke_msg_t msg;
+
+ msg.type = STR_USER_CREDS;
+ msg.length = offsetof(stroke_msg_t, buffer);
+ msg.user_creds.name = push_string(&msg, name);
+ msg.user_creds.username = push_string(&msg, user);
+ msg.user_creds.password = push_string(&msg, pass);
+ return send_stroke_msg(&msg);
+}
+
+
static int set_loglevel(char *type, u_int level)
{
stroke_msg_t msg;
@@ -427,6 +440,11 @@ static void exit_usage(char *error)
printf(" stroke memusage\n");
printf(" Show leases of a pool:\n");
printf(" stroke leases [POOL [ADDRESS]]\n");
+ printf(" Set username and password for a connection:\n");
+ printf(" stroke user-creds NAME USERNAME [PASSWORD]\n");
+ printf(" where: NAME is a connection name added with \"stroke add\"\n");
+ printf(" USERNAME is the username\n");
+ printf(" PASSWORD is the optional password, you'll be asked to enter it if not given\n");
exit_error(error);
}
@@ -567,6 +585,14 @@ int main(int argc, char *argv[])
case STROKE_MEMUSAGE:
res = memusage();
break;
+ case STROKE_USER_CREDS:
+ if (argc < 4)
+ {
+ exit_usage("\"user-creds\" needs a connection name, "
+ "username and optionally a password");
+ }
+ res = user_credentials(argv[2], argv[3], argc > 4 ? argv[4] : NULL);
+ break;
default:
exit_usage(NULL);
}
diff --git a/src/stroke/stroke_keywords.h b/src/stroke/stroke_keywords.h
index 3bd68bdc3..554d071f3 100644
--- a/src/stroke/stroke_keywords.h
+++ b/src/stroke/stroke_keywords.h
@@ -57,6 +57,7 @@ typedef enum {
STROKE_EXPORT_X509,
STROKE_LEASES,
STROKE_MEMUSAGE,
+ STROKE_USER_CREDS,
} stroke_keyword_t;
#define STROKE_LIST_FIRST STROKE_LIST_PUBKEYS
diff --git a/src/stroke/stroke_keywords.txt b/src/stroke/stroke_keywords.txt
index 4a4cc57a9..1d7ab8a45 100644
--- a/src/stroke/stroke_keywords.txt
+++ b/src/stroke/stroke_keywords.txt
@@ -64,3 +64,4 @@ purgeike, STROKE_PURGE_IKE
exportx509, STROKE_EXPORT_X509
leases, STROKE_LEASES
memusage, STROKE_MEMUSAGE
+user-creds, STROKE_USER_CREDS
diff --git a/src/stroke/stroke_msg.h b/src/stroke/stroke_msg.h
index f3c525ba7..7a469d3ac 100644
--- a/src/stroke/stroke_msg.h
+++ b/src/stroke/stroke_msg.h
@@ -218,6 +218,8 @@ struct stroke_msg_t {
STR_EXPORT,
/* print memory usage details */
STR_MEMUSAGE,
+ /* set username and password for a connection */
+ STR_USER_CREDS,
/* more to come */
} type;
@@ -340,6 +342,13 @@ struct stroke_msg_t {
char *pool;
char *address;
} leases;
+
+ /* data for STR_USER_CREDS */
+ struct {
+ char *name;
+ char *username;
+ char *password;
+ } user_creds;
};
char buffer[STROKE_BUF_LEN];
};