summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJiří Klimeš <jklimes@redhat.com>2015-12-11 21:47:27 +0100
committerJiří Klimeš <jklimes@redhat.com>2015-12-12 22:29:25 +0100
commit348ba7645b01fe7286d7cd1ec3309d240a37bdfa (patch)
tree6240e2c33565cbae7c7386cef8d71748a1493b85
parentd6b98449a814cb54c5a62dbca9342445e340e754 (diff)
downloadNetworkManager-348ba7645b01fe7286d7cd1ec3309d240a37bdfa.tar.gz
clients: add a helper function to get required openconnect VPN secrets
OpenConnect needs three secrets - COOKIE, HOST and FINGERPRINT. They can be obtained by authenticating to the server. This can be performed by running "openconnect --authenticate <host>" and the three values are printed to stdout. Note that the function may (probably will) interactively ask user for his credentials. Alternatively, it would be possible to dlopen() libopenconnect and call its functions. However, as that would be more complicated and would also require implementing functionality that openconnect simply does for free for us, it is not worth it, I think. (cherry picked from commit ea54b7f2c0228dff422ce05200a46fcf77f67810)
-rw-r--r--clients/common/nm-vpn-helpers.c78
-rw-r--r--clients/common/nm-vpn-helpers.h7
2 files changed, 85 insertions, 0 deletions
diff --git a/clients/common/nm-vpn-helpers.c b/clients/common/nm-vpn-helpers.c
index 121b87a129..4a0cd23afc 100644
--- a/clients/common/nm-vpn-helpers.c
+++ b/clients/common/nm-vpn-helpers.c
@@ -32,6 +32,7 @@
#include <NetworkManager.h>
+#include "nm-utils.h"
#include "nm-vpn-helpers.h"
@@ -268,3 +269,80 @@ nm_vpn_get_secret_names (const char *vpn_type)
return NULL;
}
+static gboolean
+_extract_variable_value (char *line, const char *tag, char **value)
+{
+ char *p1, *p2;
+
+ if (g_str_has_prefix (line, tag)) {
+ p1 = line + strlen (tag);
+ p2 = line + strlen (line) - 1;
+ if ((*p1 == '\'' || *p1 == '"') && (*p1 == *p2)) {
+ p1++;
+ *p2 = '\0';
+ }
+ if (value)
+ *value = g_strdup (p1);
+ return TRUE;
+ }
+ return FALSE;
+}
+
+gboolean
+nm_vpn_openconnect_authenticate_helper (const char *host,
+ char **cookie,
+ char **gateway,
+ char **gwcert,
+ int *status,
+ GError **error)
+{
+ char *output = NULL;
+ gboolean ret;
+ char **strv = NULL, **iter;
+ char *argv[4];
+ const char *path;
+ const char *const DEFAULT_PATHS[] = {
+ "/sbin/",
+ "/usr/sbin/",
+ "/usr/local/sbin/",
+ "/bin/",
+ "/usr/bin/",
+ "/usr/local/bin/",
+ NULL,
+ };
+
+ path = nm_utils_file_search_in_paths ("openconnect", "/usr/sbin/openconnect", DEFAULT_PATHS,
+ G_FILE_TEST_IS_EXECUTABLE, NULL, NULL, error);
+ if (!path)
+ return FALSE;
+
+ argv[0] = (char *) path;
+ argv[1] = "--authenticate";
+ argv[2] = (char *) host;
+ argv[3] = NULL;
+
+ ret = g_spawn_sync (NULL, argv, NULL,
+ G_SPAWN_SEARCH_PATH | G_SPAWN_CHILD_INHERITS_STDIN,
+ NULL, NULL, &output, NULL,
+ status, error);
+
+ if (!ret)
+ return FALSE;
+
+ /* Parse output and set cookie, gateway and gwcert
+ * output example:
+ * COOKIE='loremipsum'
+ * HOST='1.2.3.4'
+ * FINGERPRINT='sha1:32bac90cf09a722e10ecc1942c67fe2ac8c21e2e'
+ */
+ strv = g_strsplit_set (output ? output : "", "\r\n", 0);
+ for (iter = strv; iter && *iter; iter++) {
+ _extract_variable_value (*iter, "COOKIE=", cookie);
+ _extract_variable_value (*iter, "HOST=", gateway);
+ _extract_variable_value (*iter, "FINGERPRINT=", gwcert);
+ }
+ g_strfreev (strv);
+
+ return TRUE;
+}
+
diff --git a/clients/common/nm-vpn-helpers.h b/clients/common/nm-vpn-helpers.h
index 50e1251004..6b3396efb1 100644
--- a/clients/common/nm-vpn-helpers.h
+++ b/clients/common/nm-vpn-helpers.h
@@ -37,4 +37,11 @@ gboolean nm_vpn_supports_ipv6 (NMConnection *connection);
const VpnPasswordName * nm_vpn_get_secret_names (const char *vpn_type);
+gboolean nm_vpn_openconnect_authenticate_helper (const char *host,
+ char **cookie,
+ char **gateway,
+ char **gwcert,
+ int *status,
+ GError **error);
+
#endif /* __NM_VPN_HELPERS_H__ */