diff options
Diffstat (limited to 'libnm/nm-vpn-service-plugin.c')
-rw-r--r-- | libnm/nm-vpn-service-plugin.c | 72 |
1 files changed, 52 insertions, 20 deletions
diff --git a/libnm/nm-vpn-service-plugin.c b/libnm/nm-vpn-service-plugin.c index 56f5dc6b7d..8d6c43a260 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,62 @@ 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_warning ("a value expected"); + 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); + if (val || !key || hash != data) { + g_warning ("%s not preceded by %s", DATA_VAL_TAG, DATA_KEY_TAG); + break; + } + 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_warning ("a value expected"); + 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); + if (val || !key || hash != secrets) { + g_warning ("%s not preceded by %s", SECRET_VAL_TAG, SECRET_KEY_TAG); + break; + } + 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) { |