(also fixes a small bug in d2cbc42c, where David Woodhouse forgot to change the name of the xmlNode variable for the <portal-name> tag in one place) Signed-off-by: Daniel Lenski <dlenski at gmail.com> --- auth-globalprotect.c | 19 ++++++++++--------- http.c | 13 +++++++++++++ openconnect-internal.h | 1 + 3 files changed, 24 insertions(+), 9 deletions(-) diff --git a/auth-globalprotect.c b/auth-globalprotect.c index 8e27cfb..f6d704d 100644 --- a/auth-globalprotect.c +++ b/auth-globalprotect.c @@ -212,7 +212,7 @@ static int parse_portal_xml(struct openconnect_info *vpninfo, xmlNode *xml_node) if (xmlnode_is_named(xml_node, "policy")) { for (x = xml_node->children, xml_node = NULL; x; x = x->next) { if (xmlnode_is_named(x, "portal-name")) - portal = (char *)xmlNodeGetContent(xml_node); + portal = (char *)xmlNodeGetContent(x); else if (xmlnode_is_named(x, "gateways")) xml_node = x; } @@ -235,11 +235,9 @@ gateways: buf = buf_alloc(); buf_append(buf, "<GPPortal>\n <ServerList>\n"); if (portal) { - /* XXX: What if the name in 'portal' has characters which need to be - * escaped in XML? Either build up a tree using libxml "properly" - * so it does it for us, or at the very least we need a - * buf_append_xmlescaped(), don't we? */ - buf_append(buf, " <HostEntry><HostName>%s</HostName><HostAddress>%s", portal, vpninfo->hostname); + buf_append(buf, " <HostEntry><HostName>"); + buf_append_xmlescaped(buf, portal); + buf_append(buf, "</HostName><HostAddress>%s", vpninfo->hostname); if (vpninfo->port!=443) buf_append(buf, ":%d", vpninfo->port); buf_append(buf, "/global-protect</HostAddress></HostEntry>\n"); @@ -270,10 +268,13 @@ gateways: xmlnode_get_prop(xml_node, "name", &choice->name); for (x = xml_node->children; x; x=x->next) - if (xmlnode_is_named(x, "description")) - buf_append(buf, " <HostEntry><HostName>%s</HostName><HostAddress>%s/ssl-vpn</HostAddress></HostEntry>\n", - choice->label = (char *)xmlNodeGetContent(x), + if (xmlnode_is_named(x, "description")) { + choice->label = (char *)xmlNodeGetContent(x); + buf_append(buf, " <HostEntry><HostName>"); + buf_append_xmlescaped(buf, choice->label); + buf_append(buf, "</HostName><HostAddress>%s/ssl-vpn</HostAddress></HostEntry>\n", choice->name); + } opt->choices[opt->nr_choices++] = choice; vpn_progress(vpninfo, PRG_INFO, _(" %s (%s)\n"), diff --git a/http.c b/http.c index 5307d82..a860ae4 100644 --- a/http.c +++ b/http.c @@ -54,6 +54,19 @@ void buf_append_urlencoded(struct oc_text_buf *buf, const char *str) } } +void buf_append_xmlescaped(struct oc_text_buf *buf, const char *str) +{ + while (str && *str) { + unsigned char c = *str; + if (c=='<' || c=='>' || c=='&' || c=='"' || c=='\'') + buf_append(buf, "&#x%02x;", c); + else + buf_append_bytes(buf, str, 1); + + str++; + } +} + void buf_append_hex(struct oc_text_buf *buf, const void *str, unsigned len) { const unsigned char *data = str; diff --git a/openconnect-internal.h b/openconnect-internal.h index 3bb6a77..8f77f22 100644 --- a/openconnect-internal.h +++ b/openconnect-internal.h @@ -1038,6 +1038,7 @@ int get_utf8char(const char **utf8); void buf_append_from_utf16le(struct oc_text_buf *buf, const void *utf16); void buf_truncate(struct oc_text_buf *buf); void buf_append_urlencoded(struct oc_text_buf *buf, const char *str); +void buf_append_xmlescaped(struct oc_text_buf *buf, const char *str); int buf_error(struct oc_text_buf *buf); int buf_free(struct oc_text_buf *buf); char *openconnect_create_useragent(const char *base); -- 2.7.4