All of lore.kernel.org
 help / color / mirror / Atom feed
From: "Lukáš Karas" <lukas.karas@centrum.cz>
To: connman@lists.linux.dev
Subject: [PATCH] make possible to use alternative auth group with 2nd password
Date: Wed, 04 Aug 2021 18:39:39 +0200	[thread overview]
Message-ID: <1666033.JRX4bv1jlI@latitudemachine> (raw)


[-- Attachment #1.1: Type: text/plain, Size: 388 bytes --]

Some servers are configured with multiple authentication groups.
OpenConnect request just authentication entries that are valid
for specific group (process_auth_form method). So, authentication
group have to setup first, and new form have to be requested then.

Some authentication groups may require secondary password.
For example one-time password from Google Authenticator app.

Lukas

[-- Attachment #1.2: 0001-make-possible-to-use-alternative-auth-group-with-2nd.patch --]
[-- Type: text/x-patch, Size: 7168 bytes --]

From 775bfdb98cfd0d61a502399389ec68d5284a2af2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?Luk=C3=A1=C5=A1=20Karas?= <lukas.karas@centrum.cz>
Date: Tue, 3 Aug 2021 17:00:26 +0200
Subject: [PATCH] make possible to use alternative auth group with 2nd password

Some servers are configured with multiple authentication groups.
OpenConnect request just authentication entries that are valid
for specific group (process_auth_form method). So, authentication
group have to setup first, and new form have to be requested then.

Some authentication groups may require secondary password.
For example one-time password from Google Authenticator app.

Signed-off-by: Lukáš Karas <lukas.karas@centrum.cz>
---
 client/agent.c            |  1 +
 vpn/plugins/openconnect.c | 79 ++++++++++++++++++++++++++++++++++++++-
 2 files changed, 78 insertions(+), 2 deletions(-)

diff --git a/client/agent.c b/client/agent.c
index 1cad3e03..abede4c6 100644
--- a/client/agent.c
+++ b/client/agent.c
@@ -102,6 +102,7 @@ static struct agent_input_data vpnagent_input_handler[] = {
 	  request_input_string_return },
 	{ "Username", false, "VPN username? ", request_input_string_return },
 	{ "Password", false, "VPN password? ", request_input_string_return },
+	{ "OpenConnect.SecondPassword", false, "VPN one-time password? ", request_input_string_return },
 	{ },
 };
 
diff --git a/vpn/plugins/openconnect.c b/vpn/plugins/openconnect.c
index fc6ceff0..954bed8e 100644
--- a/vpn/plugins/openconnect.c
+++ b/vpn/plugins/openconnect.c
@@ -110,6 +110,7 @@ struct oc_private_data {
 	GIOChannel *err_ch;
 	enum oc_connect_type connect_type;
 	bool tried_passphrase;
+	bool group_set;
 };
 
 typedef void (*request_input_reply_cb_t) (DBusMessage *reply,
@@ -473,6 +474,7 @@ static void clear_provider_credentials(struct vpn_provider *provider,
 	const char *keys[] = { "OpenConnect.PKCSPassword",
 				"OpenConnect.Username",
 				"OpenConnect.Password",
+				"OpenConnect.SecondPassword",
 				"OpenConnect.Cookie",
 				NULL
 	};
@@ -796,11 +798,39 @@ static gboolean process_auth_form(void *user_data)
 	struct oc_private_data *data = form_data->data;
 	struct oc_form_opt *opt;
 	const char *password;
+	int i;
 
 	g_mutex_lock(&form_data->mutex);
 
 	DBG("");
 
+	/*
+	 * Special handling for "GROUP:" field, if present.
+	 * Different group selections can make other fields disappear/appear
+	 */
+	if (form_data->form->authgroup_opt) {
+		struct oc_form_opt_select *authgroup_opt = form_data->form->authgroup_opt;
+		const char *group = vpn_provider_get_string(data->provider,
+							    "OpenConnect.Group");
+		if (group && !data->group_set) {
+			for (i = 0; i < authgroup_opt->nr_choices; i++) {
+				struct oc_choice *choice = authgroup_opt->choices[i];
+				if (strcmp(group, choice->label) == 0) {
+					DBG("Switching to auth group: %s", group);
+					openconnect_set_option_value(&authgroup_opt->form, choice->name);
+					data->group_set = true;
+					form_data->status = OC_FORM_RESULT_NEWGROUP;
+					goto out;
+				}
+			}
+			connman_warn("Group choice %s not present", group);
+			data->err = -EACCES;
+			clear_provider_credentials(data->provider, true);
+			form_data->status = OC_FORM_RESULT_ERR;
+			goto out;
+		}
+	}
+
 	switch (data->connect_type) {
 	case OC_CONNECT_USERPASS:
 	case OC_CONNECT_COOKIE_WITH_USERPASS:
@@ -872,12 +902,21 @@ static gboolean process_auth_form(void *user_data)
 						"OpenConnect.Username");
 			if (user)
 				opt->_value = strdup(user);
-		} else if (opt->type == OC_FORM_OPT_PASSWORD) {
+		} else if (opt->type == OC_FORM_OPT_PASSWORD &&
+				g_str_has_prefix(opt->name, "password")) {
+
 			const char *pass = vpn_provider_get_string(
 						data->provider,
 						"OpenConnect.Password");
 			if (pass)
 				opt->_value = strdup(pass);
+		} else if (opt->type == OC_FORM_OPT_PASSWORD &&
+				g_str_has_prefix(opt->name, "secondary_password")) {
+			const char *pass = vpn_provider_get_string(
+				data->provider,
+				"OpenConnect.SecondPassword");
+			if (pass)
+				opt->_value = strdup(pass);
 		}
 	}
 
@@ -1201,6 +1240,7 @@ static void request_input_credentials_reply(DBusMessage *reply, void *user_data)
 	const char *vpnhost = NULL;
 	const char *username = NULL;
 	const char *password = NULL;
+	const char *second_password = NULL;
 	const char *pkcspassword = NULL;
 	const char *key;
 	DBusMessageIter iter, dict;
@@ -1298,6 +1338,18 @@ static void request_input_credentials_reply(DBusMessage *reply, void *user_data)
 			dbus_message_iter_get_basic(&value, &password);
 			vpn_provider_set_string_hide_value(data->provider,
 					"OpenConnect.Password", password);
+		} else if (g_str_equal(key, "OpenConnect.SecondPassword")) {
+			dbus_message_iter_next(&entry);
+			if (dbus_message_iter_get_arg_type(&entry)
+			!= DBUS_TYPE_VARIANT)
+				break;
+			dbus_message_iter_recurse(&entry, &value);
+			if (dbus_message_iter_get_arg_type(&value)
+			!= DBUS_TYPE_STRING)
+				break;
+			dbus_message_iter_get_basic(&value, &second_password);
+			vpn_provider_set_string_hide_value(data->provider,
+							   "OpenConnect.SecondPassword", second_password);
 		} else if (g_str_equal(key, "OpenConnect.PKCSPassword")) {
 			dbus_message_iter_next(&entry);
 			if (dbus_message_iter_get_arg_type(&entry)
@@ -1374,6 +1426,7 @@ static int request_input_credentials_full(
 	DBusMessageIter dict;
 	int err;
 	void *agent;
+	bool use_second_password = false;
 
 	if (!data || !cb)
 		return -ESRCH;
@@ -1440,6 +1493,16 @@ static int request_input_credentials_full(
 		username = vpn_provider_get_string(data->provider,
 					"OpenConnect.Username");
 		vpn_agent_append_user_info(&dict, data->provider, username);
+
+		use_second_password = vpn_provider_get_boolean(data->provider,
+					"OpenConnect.UseSecondPassword",
+					false);
+
+		if (use_second_password)
+			request_input_append_to_dict(data->provider, &dict,
+					request_input_append_password,
+					"OpenConnect.SecondPassword");
+
 		break;
 	case OC_CONNECT_PUBLICKEY:
 		return -EINVAL;
@@ -1520,8 +1583,10 @@ static int oc_connect(struct vpn_provider *provider,
 	const char *certificate;
 	const char *username;
 	const char *password;
+	const char *second_password = NULL;
 	const char *private_key;
 	int err;
+	bool use_second_password = false;
 
 	connman_info("provider %p task %p", provider, task);
 
@@ -1551,8 +1616,18 @@ static int oc_connect(struct vpn_provider *provider,
 					"OpenConnect.Username");
 		password = vpn_provider_get_string(provider,
 					"OpenConnect.Password");
+
+		use_second_password = vpn_provider_get_boolean(provider,
+					"OpenConnect.UseSecondPassword",
+					false);
+
+		if (use_second_password)
+			second_password = vpn_provider_get_string(provider,
+					"OpenConnect.SecondPassword");
+
 		if (!username || !password || !g_strcmp0(username, "-") ||
-					!g_strcmp0(password, "-"))
+					!g_strcmp0(password, "-") ||
+					(use_second_password && !second_password))
 			goto request_input;
 
 		break;
-- 
2.27.0


[-- Attachment #2: This is a digitally signed message part. --]
[-- Type: application/pgp-signature, Size: 488 bytes --]

             reply	other threads:[~2021-08-04 16:41 UTC|newest]

Thread overview: 5+ messages / expand[flat|nested]  mbox.gz  Atom feed  top
2021-08-04 16:39 Lukáš Karas [this message]
2021-08-05  6:14 ` [PATCH] make possible to use alternative auth group with 2nd password Daniel Wagner
2021-08-30  6:52   ` Lukáš Karas
2021-08-30  8:16     ` Daniel Wagner
2021-08-30 17:37 ` Daniel Wagner

Reply instructions:

You may reply publicly to this message via plain-text email
using any one of the following methods:

* Save the following mbox file, import it into your mail client,
  and reply-to-all from there: mbox

  Avoid top-posting and favor interleaved quoting:
  https://en.wikipedia.org/wiki/Posting_style#Interleaved_style

* Reply using the --to, --cc, and --in-reply-to
  switches of git-send-email(1):

  git send-email \
    --in-reply-to=1666033.JRX4bv1jlI@latitudemachine \
    --to=lukas.karas@centrum.cz \
    --cc=connman@lists.linux.dev \
    /path/to/YOUR_REPLY

  https://kernel.org/pub/software/scm/git/docs/git-send-email.html

* If your mail client supports setting the In-Reply-To header
  via mailto: links, try the mailto: link
Be sure your reply has a Subject: header at the top and a blank line before the message body.
This is an external index of several public inboxes,
see mirroring instructions on how to clone and mirror
all data and code used by this external index.