2 * OpenConnect (SSL + DTLS) VPN client
4 * Copyright © 2008-2010 Intel Corporation.
5 * Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
7 * Author: David Woodhouse <dwmw2@infradead.org>
9 * This program is free software; you can redistribute it and/or
10 * modify it under the terms of the GNU Lesser General Public License
11 * version 2.1, as published by the Free Software Foundation.
13 * This program is distributed in the hope that it will be useful, but
14 * WITHOUT ANY WARRANTY; without even the implied warranty of
15 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
16 * Lesser General Public License for more details.
18 * You should have received a copy of the GNU Lesser General Public
19 * License along with this library; if not, write to:
21 * Free Software Foundation, Inc.
22 * 51 Franklin Street, Fifth Floor,
23 * Boston, MA 02110-1301 USA
30 #include <sys/types.h>
33 #include <libxml/parser.h>
34 #include <libxml/tree.h>
37 #include "openconnect-internal.h"
39 int config_lookup_host(struct openconnect_info *vpninfo, const char *host)
45 unsigned char sha1[SHA_DIGEST_LENGTH];
47 xmlNode *xml_node, *xml_node2;
49 if (!vpninfo->xmlconfig)
52 fd = open(vpninfo->xmlconfig, O_RDONLY);
54 perror(_("Open XML config file"));
55 fprintf(stderr, _("Treating host \"%s\" as a raw hostname\n"),
61 perror(_("fstat XML config file"));
65 xmlfile = mmap(NULL, st.st_size, PROT_READ, MAP_SHARED, fd, 0);
66 if (xmlfile == MAP_FAILED) {
67 perror(_("mmap XML config file"));
73 EVP_Digest(xmlfile, st.st_size, sha1, NULL, EVP_sha1(), NULL);
74 EVP_MD_CTX_cleanup(&c);
76 for (i = 0; i < SHA_DIGEST_LENGTH; i++)
77 sprintf(&vpninfo->xmlsha1[i*2], "%02x", sha1[i]);
79 vpn_progress(vpninfo, PRG_TRACE, _("XML config file SHA1: %s\n"),
82 xml_doc = xmlReadMemory(xmlfile, st.st_size, "noname.xml", NULL, 0);
83 munmap(xmlfile, st.st_size);
86 fprintf(stderr, _("Failed to parse XML config file %s\n"),
88 fprintf(stderr, _("Treating host \"%s\" as a raw hostname\n"),
92 xml_node = xmlDocGetRootElement(xml_doc);
94 for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
95 if (xml_node->type == XML_ELEMENT_NODE &&
96 !strcmp((char *)xml_node->name, "ServerList")) {
98 for (xml_node = xml_node->children; xml_node && !vpninfo->hostname;
99 xml_node = xml_node->next) {
101 if (xml_node->type == XML_ELEMENT_NODE &&
102 !strcmp((char *)xml_node->name, "HostEntry")) {
105 for (xml_node2 = xml_node->children;
106 match >= 0 && xml_node2; xml_node2 = xml_node2->next) {
108 if (xml_node2->type != XML_ELEMENT_NODE)
111 if (!match && !strcmp((char *)xml_node2->name, "HostName")) {
112 char *content = (char *)xmlNodeGetContent(xml_node2);
113 if (content && !strcmp(content, host))
119 !strcmp((char *)xml_node2->name, "HostAddress")) {
120 char *content = (char *)xmlNodeGetContent(xml_node2);
122 vpninfo->hostname = content;
123 printf(_("Host \"%s\" has address \"%s\"\n"),
127 !strcmp((char *)xml_node2->name, "UserGroup")) {
128 char *content = (char *)xmlNodeGetContent(xml_node2);
130 free(vpninfo->urlpath);
131 vpninfo->urlpath = content;
132 printf(_("Host \"%s\" has UserGroup \"%s\"\n"),
145 if (!vpninfo->hostname) {
146 fprintf(stderr, _("Host \"%s\" not listed in config; treating as raw hostname\n"),