[network-manager-openvpn/bg/dynamic-challenge-bgo751842: 3/4] service: don't reuse the password secret for dynamic challenge
- From: Beniamino Galvani <bgalvani src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/bg/dynamic-challenge-bgo751842: 3/4] service: don't reuse the password secret for dynamic challenge
- Date: Wed, 2 Aug 2017 12:24:10 +0000 (UTC)
commit 78a0bbf068a79b9ef0bc50020e9f5edb0b9418f0
Author: Beniamino Galvani <bgalvani redhat com>
Date: Wed Aug 2 08:52:32 2017 +0200
service: don't reuse the password secret for dynamic challenge
Currently, the response to a dynamic challenge is asked as if it was
the password. This is wrong, because it's a different secret and the
password could be persisted, while the challenge must be always asked
to user.
shared/nm-service-defines.h | 3 +
src/nm-openvpn-service.c | 88 ++++++++++++++++++++++++++++---------------
2 files changed, 60 insertions(+), 31 deletions(-)
---
diff --git a/shared/nm-service-defines.h b/shared/nm-service-defines.h
index 513fec4..bb3629f 100644
--- a/shared/nm-service-defines.h
+++ b/shared/nm-service-defines.h
@@ -75,6 +75,9 @@
#define NM_OPENVPN_KEY_PASSWORD "password"
#define NM_OPENVPN_KEY_CERTPASS "cert-pass"
#define NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD "http-proxy-password"
+
+#define NM_OPENVPN_KEY_CHALLENGE_DYNAMIC "x-vpn-challenge-dynamic"
+
/* Internal auth-dialog -> service token indicating that no secrets are
* required for the connection.
*/
diff --git a/src/nm-openvpn-service.c b/src/nm-openvpn-service.c
index fc2b1e9..8ca658a 100644
--- a/src/nm-openvpn-service.c
+++ b/src/nm-openvpn-service.c
@@ -109,10 +109,14 @@ typedef struct {
char *proxy_username;
char *proxy_password;
char *pending_auth;
- char *challenge_state_id;
- char *challenge_text;
GIOChannel *socket_channel;
guint socket_channel_eventid;
+ struct {
+ char *state_id;
+ char *text;
+ char *user;
+ char *response;
+ } challenge;
} NMOpenvpnPluginIOData;
typedef struct {
@@ -589,8 +593,11 @@ nm_openvpn_disconnect_management_socket (NMOpenvpnPlugin *plugin)
if (io_data->proxy_password)
memset (io_data->proxy_password, 0, strlen (io_data->proxy_password));
g_free (io_data->proxy_password);
- g_free (io_data->challenge_state_id);
- g_free (io_data->challenge_text);
+
+ g_free (io_data->challenge.state_id);
+ g_free (io_data->challenge.text);
+ g_free (io_data->challenge.user);
+ g_free (io_data->challenge.response);
g_free (priv->io_data);
priv->io_data = NULL;
@@ -638,9 +645,10 @@ get_detail (const char *input, const char *prefix)
* CRV1:flags:state_id:username:text
*/
static gboolean
-parse_challenge (const char *failure_reason, char **challenge_state_id, char **challenge_text)
+parse_challenge (const char *failure_reason, char **challenge_state_id, char **challenge_text, char
**challenge_user)
{
const char *colon[4];
+ gsize out_len;
if ( !failure_reason
|| !g_str_has_prefix (failure_reason, "CRV1:"))
@@ -664,6 +672,10 @@ parse_challenge (const char *failure_reason, char **challenge_state_id, char **c
*challenge_state_id = g_strndup (colon[1] + 1, colon[2] - colon[1] - 1);
*challenge_text = g_strdup (colon[3] + 1);
+ *challenge_user = g_strndup (colon[2] + 1, colon[3] - colon[2] - 1);
+ g_base64_decode_inplace (*challenge_user, &out_len);
+ (*challenge_user)[out_len] = 0;
+
return TRUE;
}
@@ -708,44 +720,50 @@ handle_auth (NMOpenvpnPluginIOData *io_data,
g_return_val_if_fail (out_message != NULL, FALSE);
g_return_val_if_fail (out_hints != NULL, FALSE);
- if (strcmp (requested_auth, "Auth") == 0) {
+ if (nm_streq (requested_auth, "Auth")) {
const char *username = io_data->username;
/* Fall back to the default username if it wasn't overridden by the user */
if (!username)
username = io_data->default_username;
- if (username != NULL && io_data->password != NULL && io_data->challenge_state_id) {
- gs_free char *response = NULL;
+ if (io_data->challenge.response) {
+ gs_free char *password = NULL;
- response = g_strdup_printf ("CRV1::%s::%s",
- io_data->challenge_state_id,
- io_data->password);
+ password = g_strdup_printf ("CRV1::%s::%s",
+ io_data->challenge.state_id,
+ io_data->challenge.response);
write_user_pass (io_data->socket_channel,
requested_auth,
- username,
- response);
- nm_clear_g_free (&io_data->challenge_state_id);
- nm_clear_g_free (&io_data->challenge_text);
- } else if (username != NULL && io_data->password != NULL) {
+ io_data->challenge.user,
+ password);
+ nm_clear_g_free (&io_data->challenge.state_id);
+ nm_clear_g_free (&io_data->challenge.text);
+ nm_clear_g_free (&io_data->challenge.user);
+ nm_clear_g_free (&io_data->challenge.response);
+ } else if (username && io_data->password) {
write_user_pass (io_data->socket_channel,
requested_auth,
username,
io_data->password);
} else {
hints = g_new0 (char *, 3);
- if (!username) {
- hints[i++] = NM_OPENVPN_KEY_USERNAME;
- *out_message = _("A username is required.");
- }
- if (!io_data->password) {
- hints[i++] = NM_OPENVPN_KEY_PASSWORD;
- *out_message = _("A password is required.");
+
+ if (io_data->challenge.text) {
+ hints[i++] = NM_OPENVPN_KEY_CHALLENGE_DYNAMIC;
+ *out_message = io_data->challenge.text;
+ } else {
+ if (!username) {
+ hints[i++] = NM_OPENVPN_KEY_USERNAME;
+ *out_message = _("A username is required.");
+ }
+ if (!io_data->password) {
+ hints[i++] = NM_OPENVPN_KEY_PASSWORD;
+ *out_message = _("A password is required.");
+ }
+ if (!username && !io_data->password)
+ *out_message = _("A username and password are required.");
}
- if (!username && !io_data->password)
- *out_message = _("A username and password are required.");
- if (io_data->challenge_text)
- *out_message = io_data->challenge_text;
}
handled = TRUE;
} else if (!strcmp (requested_auth, "Private Key")) {
@@ -862,10 +880,14 @@ handle_management_socket (NMOpenvpnPlugin *plugin,
gs_free char *failure_reason = NULL;
failure_reason = get_detail (str, ">PASSWORD:Verification Failed: 'Auth' ['");
- if (parse_challenge (failure_reason, &priv->io_data->challenge_state_id,
&priv->io_data->challenge_text)) {
- _LOGD ("Received challenge '%s' for state '%s'",
- priv->io_data->challenge_state_id,
- priv->io_data->challenge_text);
+ if (parse_challenge (failure_reason,
+ &priv->io_data->challenge.state_id,
+ &priv->io_data->challenge.text,
+ &priv->io_data->challenge.user)) {
+ _LOGD ("Received challenge '%s' for user '%s' and state '%s'",
+ priv->io_data->challenge.state_id,
+ priv->io_data->challenge.text,
+ priv->io_data->challenge.user);
} else
_LOGW ("Password verification failed");
@@ -1167,6 +1189,10 @@ update_io_data_from_vpn_setting (NMOpenvpnPluginIOData *io_data,
}
tmp = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_HTTP_PROXY_PASSWORD);
io_data->proxy_password = tmp ? g_strdup (tmp) : NULL;
+
+ g_free (io_data->challenge.response);
+ tmp = nm_setting_vpn_get_secret (s_vpn, NM_OPENVPN_KEY_CHALLENGE_DYNAMIC);
+ io_data->challenge.response = g_strdup (tmp);
}
static char *
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]