[network-manager-openvpn/th/export-bgo764132: 3/27] properties: refactor export code to properly escape strings
- From: Thomas Haller <thaller src gnome org>
- To: commits-list gnome org
- Cc:
- Subject: [network-manager-openvpn/th/export-bgo764132: 3/27] properties: refactor export code to properly escape strings
- Date: Fri, 25 Mar 2016 19:48:28 +0000 (UTC)
commit 4580dbd2996d2df5581b21c85e4a423e2c754020
Author: Thomas Haller <thaller redhat com>
Date: Wed Mar 23 11:50:04 2016 +0100
properties: refactor export code to properly escape strings
When exporting the VPN settings to a ovpn file, we must properly
handle special characters, like white space.
properties/import-export.c | 236 +++++++++++++++++++++++++++++++-------------
1 files changed, 169 insertions(+), 67 deletions(-)
---
diff --git a/properties/import-export.c b/properties/import-export.c
index 2d1a4c1..f92cec2 100644
--- a/properties/import-export.c
+++ b/properties/import-export.c
@@ -1503,6 +1503,106 @@ out_error:
/*****************************************************************************/
+static const char *
+escape_arg (const char *value, char **buf)
+{
+ const char *s;
+ char *result, *i_result;
+ gboolean has_single_quote = FALSE;
+ gboolean needs_quotation = FALSE;
+ gsize len;
+
+ nm_assert (value);
+ nm_assert (buf && !*buf);
+
+ if (value[0] == '\0')
+ return (*buf = g_strdup ("''"));
+
+ /* check if the string contains only benign characters... */
+ len = 0;
+ for (s = value; s[0]; s++) {
+ char c = s[0];
+
+ len++;
+ if ( (c >= '0' && c <= '9')
+ || (c >= 'a' && c <= 'z')
+ || (c >= 'A' && c <= 'Z')
+ || NM_IN_SET (c, '_', '-', ':', '/'))
+ continue;
+ needs_quotation = TRUE;
+ if (c == '\'')
+ has_single_quote = TRUE;
+ }
+ if (!needs_quotation)
+ return value;
+
+ if (!has_single_quote) {
+ result = g_malloc (len + 2 + 1);
+ result[0] = '\'';
+ memcpy (&result[1], value, len);
+ result[1 + len] = '\'';
+ result[2 + len] = '\0';
+ } else {
+ i_result = result = g_malloc (len * 2 + 1);
+ for (s = value; s[0]; s++) {
+ if (NM_IN_SET (s[0], '\\', '"'))
+ *(i_result++) = '\\';
+ *(i_result++) = s[0];
+ }
+ *(i_result++) = '\0';
+ }
+
+ *buf = result;
+ return result;
+}
+
+static void
+args_write_line_v (FILE *f, gsize nargs, const char **args)
+{
+ gsize i;
+ gboolean printed;
+
+ nm_assert (args);
+ nm_assert (args[0]);
+
+ for (i = 0; i < nargs; i++) {
+ gs_free char *tmp = NULL;
+
+ /* NULL is skipped. This is for convenience to specify
+ * optional arguments. */
+ if (!args[i])
+ continue;
+
+ if (printed)
+ fprintf (f, " ");
+ printed = TRUE;
+ fprintf (f, "%s", escape_arg (args[i], &tmp));
+ }
+ fprintf (f, "\n");
+}
+#define args_write_line(f, ...) args_write_line_v(f, NM_NARG (__VA_ARGS__), (const char *[]) { __VA_ARGS__ })
+
+static void
+args_write_line_int64 (FILE *f, const char *key, gint64 value)
+{
+ char tmp[64];
+
+ args_write_line (f, key, nm_sprintf_buf (tmp, "%"G_GINT64_FORMAT, value));
+}
+
+static void
+args_write_line_int64_str (FILE *f, const char *key, const char *value)
+{
+ gint64 v;
+
+ v = _nm_utils_ascii_str_to_int64 (value, 10, G_MININT64, G_MAXINT64, 0);
+ if (errno)
+ return;
+ args_write_line_int64 (f, key, v);
+}
+
+/*****************************************************************************/
+
gboolean
do_export (const char *path, NMConnection *connection, GError **error)
{
@@ -1538,7 +1638,7 @@ do_export (const char *path, NMConnection *connection, GError **error)
gboolean use_lzo = FALSE;
gboolean use_float = FALSE;
gboolean reneg_exists = FALSE;
- guint32 reneg = 0;
+ glong reneg = 0;
gboolean keysize_exists = FALSE;
guint32 keysize = 0;
gboolean randomize_hosts = FALSE;
@@ -1703,12 +1803,13 @@ do_export (const char *path, NMConnection *connection, GError **error)
/* Advanced values end */
- fprintf (f, "client\n");
+ args_write_line (f, "client");
/* 'remote' */
gw_list = g_strsplit_set (gateways, " ,", 0);
for (gw_iter = gw_list; gw_iter && *gw_iter; gw_iter++) {
char *tmp_host, *tmp_port,*tmp_proto;
+
if (**gw_iter == '\0')
continue;
tmp_host = g_strstrip (*gw_iter);
@@ -1723,108 +1824,109 @@ do_export (const char *path, NMConnection *connection, GError **error)
if (tmp_proto && !*tmp_proto)
tmp_proto = NULL;
- fprintf (f, "remote %s%s%s%s%s\n",
- *gw_iter,
- tmp_port ? " " : tmp_proto ? " " : "",
- tmp_port ? tmp_port : tmp_proto ? !strcmp (tmp_proto, "udp") ? "1194" : "443": "",
- tmp_proto ? " " : "",
- tmp_proto ? tmp_proto : "");
+ args_write_line (f,
+ "remote",
+ *gw_iter,
+ tmp_port
+ ? tmp_port
+ : (tmp_proto
+ ? (!strcmp (tmp_proto, "udp")
+ ? "1194"
+ : "443")
+ : NULL),
+ tmp_proto);
}
g_strfreev (gw_list);
if (randomize_hosts)
- fprintf (f, "remote-random\n");
+ args_write_line (f, "remote-random");
if (tun_ipv6)
- fprintf (f, "tun-ipv6\n");
+ args_write_line (f, "tun-ipv6");
/* Handle PKCS#12 (all certs are the same file) */
if ( cacert && user_cert && private_key
&& !strcmp (cacert, user_cert) && !strcmp (cacert, private_key))
- fprintf (f, "pkcs12 %s\n", cacert);
+ args_write_line (f, "pkcs12", cacert);
else {
if (cacert)
- fprintf (f, "ca %s\n", cacert);
+ args_write_line (f, "ca", cacert);
if (user_cert)
- fprintf (f, "cert %s\n", user_cert);
+ args_write_line (f, "cert", user_cert);
if (private_key)
- fprintf(f, "key %s\n", private_key);
+ args_write_line (f, "key", private_key);
}
if ( !strcmp(connection_type, NM_OPENVPN_CONTYPE_PASSWORD)
|| !strcmp(connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS))
- fprintf (f, "auth-user-pass\n");
+ args_write_line (f, "auth-user-pass");
if (!strcmp (connection_type, NM_OPENVPN_CONTYPE_STATIC_KEY)) {
- if (static_key) {
- fprintf (f, "secret %s%s%s\n",
- static_key,
- static_key_direction ? " " : "",
- static_key_direction ? static_key_direction : "");
- }
+ if (static_key)
+ args_write_line (f, "secret", static_key, static_key_direction);
}
if (reneg_exists)
- fprintf (f, "reneg-sec %d\n", reneg);
+ args_write_line_int64 (f, "reneg-sec", reneg);
if (cipher)
- fprintf (f, "cipher %s\n", cipher);
+ args_write_line (f, "cipher", cipher);
if (keysize_exists)
- fprintf (f, "keysize %d\n", keysize);
+ args_write_line_int64 (f, "keysize", keysize);
if (use_lzo)
- fprintf (f, "comp-lzo yes\n");
+ args_write_line (f, "comp-lzo", "yes");
if (use_float)
- fprintf (f, "float\n");
+ args_write_line (f, "float");
value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_MSSFIX);
- if (value && strlen (value)) {
- if (!strcmp (value, "yes"))
- fprintf (f, TAG_MSSFIX "\n");
- }
+ if (nm_streq0 (value, "yes"))
+ args_write_line (f, TAG_MSSFIX);
value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_TUNNEL_MTU);
if (value && strlen (value))
- fprintf (f, TAG_TUN_MTU " %d\n", (int) strtol (value, NULL, 10));
+ args_write_line_int64_str (f, TAG_TUN_MTU, value);
value = nm_setting_vpn_get_data_item (s_vpn, NM_OPENVPN_KEY_FRAGMENT_SIZE);
if (value && strlen (value))
- fprintf (f, TAG_FRAGMENT " %d\n", (int) strtol (value, NULL, 10));
+ args_write_line_int64_str (f, TAG_FRAGMENT, value);
- fprintf (f, "dev %s\n", device ? device : (device_type ? device_type : device_default));
+ args_write_line (f,
+ "dev",
+ device ?: (device_type ?: device_default));
if (device_type)
- fprintf (f, "dev-type %s\n", device_type);
- fprintf (f, "proto %s\n", proto_udp ? "udp" : "tcp");
+ args_write_line (f, "dev-type", device_type);
+ args_write_line (f, "proto", proto_udp ? "udp" : "tcp");
if (port)
- fprintf (f, "port %s\n", port);
+ args_write_line (f, "port", port);
if (ping)
- fprintf (f, "ping %s\n", ping);
+ args_write_line (f, "ping", ping);
if (ping_exit)
- fprintf (f, "ping-exit %s\n", ping_exit);
+ args_write_line (f, "ping-exit", ping_exit);
if (ping_restart)
- fprintf (f, "ping-restart %s\n", ping_restart);
+ args_write_line (f, "ping-restart", ping_restart);
if (local_ip && remote_ip)
- fprintf (f, "ifconfig %s %s\n", local_ip, remote_ip);
+ args_write_line (f, "ifconfig", local_ip, remote_ip);
if ( !strcmp(connection_type, NM_OPENVPN_CONTYPE_TLS)
|| !strcmp(connection_type, NM_OPENVPN_CONTYPE_PASSWORD_TLS)) {
if (tls_remote)
- fprintf (f,"tls-remote \"%s\"\n", tls_remote);
+ args_write_line (f, "tls-remote", tls_remote);
if (remote_cert_tls)
- fprintf (f,"remote-cert-tls %s\n", remote_cert_tls);
+ args_write_line (f, "remote-cert-tls", remote_cert_tls);
if (tls_auth) {
- fprintf (f, "tls-auth %s%s%s\n",
- tls_auth,
- tls_auth_dir ? " " : "",
- tls_auth_dir ? tls_auth_dir : "");
+ args_write_line (f,
+ "tls-auth",
+ tls_auth,
+ tls_auth_dir);
}
}
@@ -1850,13 +1952,13 @@ do_export (const char *path, NMConnection *connection, GError **error)
g_free (base);
g_free (dirname);
- fprintf (f, "http-proxy %s %s%s%s\n",
- proxy_server,
- proxy_port,
- proxy_username ? " " : "",
- proxy_username ? authfile : "");
+ args_write_line (f,
+ "http-proxy",
+ proxy_server,
+ proxy_port,
+ proxy_username ? authfile : NULL);
if (proxy_retry && !strcmp (proxy_retry, "yes"))
- fprintf (f, "http-proxy-retry\n");
+ args_write_line (f, "http-proxy-retry");
/* Write out the authfile */
if (proxy_username) {
@@ -1870,9 +1972,9 @@ do_export (const char *path, NMConnection *connection, GError **error)
} else if (!strcmp (proxy_type, "socks") && proxy_server && proxy_port) {
if (!proxy_port)
proxy_port = "1080";
- fprintf (f, "socks-proxy %s %s\n", proxy_server, proxy_port);
+ args_write_line (f, "socks-proxy", proxy_server, proxy_port);
if (proxy_retry && !strcmp (proxy_retry, "yes"))
- fprintf (f, "socks-proxy-retry\n");
+ args_write_line (f, "socks-proxy-retry");
}
}
@@ -1918,23 +2020,23 @@ do_export (const char *path, NMConnection *connection, GError **error)
netmask = nm_utils_ip4_prefix_to_netmask (prefix);
inet_ntop (AF_INET, (const void *) &netmask, netmask_str, sizeof (netmask_str));
- fprintf (f, "route %s %s %s%s\n",
- dest_str,
- netmask_str,
- next_hop_str,
- metric == -1 ? "" : nm_sprintf_buf (metric_buf, " %u", (unsigned) metric));
+ args_write_line (f,
+ "route",
+ dest_str,
+ netmask_str,
+ next_hop_str,
+ metric == -1 ? NULL : nm_sprintf_buf (metric_buf, "%u", (unsigned)
metric));
}
}
/* Add hard-coded stuff */
- fprintf (f,
- "nobind\n"
- "auth-nocache\n"
- "script-security 2\n"
- "persist-key\n"
- "persist-tun\n"
- "user openvpn\n"
- "group openvpn\n");
+ args_write_line (f, "nobind");
+ args_write_line (f, "auth-nocache");
+ args_write_line (f, "script-security", "2");
+ args_write_line (f, "persist-key");
+ args_write_line (f, "persist-tun");
+ args_write_line (f, "user", "openvpn");
+ args_write_line (f, "group", "openvpn");
success = TRUE;
done:
[
Date Prev][
Date Next] [
Thread Prev][
Thread Next]
[
Thread Index]
[
Date Index]
[
Author Index]