summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorLubomir Rintel <lkundrak@v3.sk>2018-07-16 12:59:08 +0200
committerLubomir Rintel <lkundrak@v3.sk>2018-10-22 18:15:25 +0200
commit3dfb72b92687131a030a1c19e21f29ac26c26a32 (patch)
treec8664388e76bdc9f8731c35f77dfd586f9c3eb3c
parent669bd330229e9d73bb3f0d82ddb164c0437233b4 (diff)
downloadNetworkManager-3dfb72b92687131a030a1c19e21f29ac26c26a32.tar.gz
service-plugin: allow continuations in the auth-dialog protocol
Equals sign was picked as a continuation character arbitratily. It would simplify parsing, if we cared. DATA_KEY=some-key DATA_VAL=string =continued after a line break SECRET_KEY=key names =can have =continuations too SECRET_VAL=value DONE
-rw-r--r--libnm/nm-vpn-service-plugin.c60
1 files changed, 40 insertions, 20 deletions
diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c
index 56f5dc6b7d..94a1ebbc04 100644
--- a/libnm/nm-vpn-service-plugin.c
+++ b/libnm/nm-vpn-service-plugin.c
@@ -787,10 +787,13 @@ nm_vpn_service_plugin_read_vpn_details (int fd,
gs_unref_hashtable GHashTable *data = NULL;
gs_unref_hashtable GHashTable *secrets = NULL;
gboolean success = FALSE;
- char *key = NULL, *val = NULL;
+ GHashTable *hash = NULL;
+ GString *key = NULL, *val = NULL;
nm_auto_free_gstring GString *line = NULL;
char c;
+ GString *str = NULL;
+
if (out_data)
g_return_val_if_fail (*out_data == NULL, FALSE);
if (out_secrets)
@@ -804,7 +807,6 @@ nm_vpn_service_plugin_read_vpn_details (int fd,
/* Read stdin for data and secret items until we get a DONE */
while (1) {
ssize_t nr;
- GHashTable *hash = NULL;
errno = 0;
nr = read (fd, &c, 1);
@@ -821,32 +823,50 @@ nm_vpn_service_plugin_read_vpn_details (int fd,
continue;
}
- /* Check for the finish marker */
- if (strcmp (line->str, "DONE") == 0)
- break;
+ if (str && *line->str == '=') {
+ /* continuation */
+ g_string_append_c (str, '\n');
+ g_string_append (str, line->str + 1);
+ } else if (key && val) {
+ /* done a line */
+ g_return_val_if_fail (hash, FALSE);
+ g_hash_table_insert (hash,
+ g_string_free (key, FALSE),
+ g_string_free (val, FALSE));
+ key = NULL;
+ val = NULL;
+ hash = NULL;
+ success = TRUE; /* Got at least one value */
+ }
- /* Otherwise it's a data/secret item */
- if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) {
+ if (strcmp (line->str, "DONE") == 0) {
+ /* finish marker */
+ break;
+ } else if (strncmp (line->str, DATA_KEY_TAG, strlen (DATA_KEY_TAG)) == 0) {
+ if (key != NULL)
+ g_string_free (key, TRUE);
+ key = g_string_new (line->str + strlen (DATA_KEY_TAG));
+ str = key;
hash = data;
- key = g_strdup (line->str + strlen (DATA_KEY_TAG));
} else if (strncmp (line->str, DATA_VAL_TAG, strlen (DATA_VAL_TAG)) == 0) {
- hash = data;
- val = g_strdup (line->str + strlen (DATA_VAL_TAG));
+ if (val != NULL)
+ g_string_free (val, TRUE);
+ val = g_string_new (line->str + strlen (DATA_VAL_TAG));
+ str = val;
} else if (strncmp (line->str, SECRET_KEY_TAG, strlen (SECRET_KEY_TAG)) == 0) {
+ if (key != NULL)
+ g_string_free (key, TRUE);
+ key = g_string_new (line->str + strlen (SECRET_KEY_TAG));
+ str = key;
hash = secrets;
- key = g_strdup (line->str + strlen (SECRET_KEY_TAG));
} else if (strncmp (line->str, SECRET_VAL_TAG, strlen (SECRET_VAL_TAG)) == 0) {
- hash = secrets;
- val = g_strdup (line->str + strlen (SECRET_VAL_TAG));
+ if (val != NULL)
+ g_string_free (val, TRUE);
+ val = g_string_new (line->str + strlen (SECRET_VAL_TAG));
+ str = val;
}
- g_string_truncate (line, 0);
- if (key && val && hash) {
- g_hash_table_insert (hash, key, val);
- key = NULL;
- val = NULL;
- success = TRUE; /* Got at least one value */
- }
+ g_string_truncate (line, 0);
}
if (success) {