diff options
author | Lubomir Rintel <lkundrak@v3.sk> | 2018-07-16 12:59:08 +0200 |
---|---|---|
committer | Lubomir Rintel <lkundrak@v3.sk> | 2018-10-22 18:15:25 +0200 |
commit | 3dfb72b92687131a030a1c19e21f29ac26c26a32 (patch) | |
tree | c8664388e76bdc9f8731c35f77dfd586f9c3eb3c | |
parent | 669bd330229e9d73bb3f0d82ddb164c0437233b4 (diff) | |
download | NetworkManager-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.c | 60 |
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) { |