Skip to content

Latest commit

 

History

History
213 lines (180 loc) · 4.96 KB

xml.c

File metadata and controls

213 lines (180 loc) · 4.96 KB
 
Sep 30, 2008
Sep 30, 2008
1
/*
Nov 20, 2008
Nov 20, 2008
2
* OpenConnect (SSL + DTLS) VPN client
Sep 30, 2008
Sep 30, 2008
3
*
Jan 26, 2015
Jan 26, 2015
4
* Copyright © 2008-2015 Intel Corporation.
Apr 9, 2009
Apr 9, 2009
5
* Copyright © 2008 Nick Andrew <nick@nick-andrew.net>
Sep 30, 2008
Sep 30, 2008
6
*
Nov 20, 2008
Nov 20, 2008
7
8
9
* Author: David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
Oct 4, 2008
Oct 4, 2008
10
* modify it under the terms of the GNU Lesser General Public License
Nov 20, 2008
Nov 20, 2008
11
* version 2.1, as published by the Free Software Foundation.
Sep 30, 2008
Sep 30, 2008
12
*
Nov 20, 2008
Nov 20, 2008
13
* This program is distributed in the hope that it will be useful, but
Oct 4, 2008
Oct 4, 2008
14
15
16
* WITHOUT ANY WARRANTY; without even the implied warranty of
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
* Lesser General Public License for more details.
Sep 30, 2008
Sep 30, 2008
17
18
*/
Jul 1, 2014
Jul 1, 2014
19
20
#include <config.h>
Sep 30, 2008
Sep 30, 2008
21
22
#include <stdio.h>
#include <stdlib.h>
Apr 9, 2009
Apr 9, 2009
23
#include <unistd.h>
Sep 30, 2008
Sep 30, 2008
24
25
26
27
28
#include <fcntl.h>
#include <sys/types.h>
#include <sys/stat.h>
#include <libxml/parser.h>
#include <libxml/tree.h>
Oct 15, 2008
Oct 15, 2008
29
#include <string.h>
Aug 2, 2014
Aug 2, 2014
30
#include <ctype.h>
Feb 15, 2014
Feb 15, 2014
31
#include <errno.h>
Sep 30, 2008
Sep 30, 2008
32
Mar 9, 2011
Mar 9, 2011
33
#include "openconnect-internal.h"
Sep 30, 2008
Sep 30, 2008
34
Aug 2, 2014
Aug 2, 2014
35
36
ssize_t read_file_into_string(struct openconnect_info *vpninfo, const char *fname,
char **ptr)
Sep 30, 2008
Sep 30, 2008
37
{
Aug 2, 2014
Aug 2, 2014
38
int fd, len;
Sep 30, 2008
Sep 30, 2008
39
struct stat st;
Aug 2, 2014
Aug 2, 2014
40
char *buf;
Sep 30, 2008
Sep 30, 2008
41
Aug 4, 2014
Aug 4, 2014
42
fd = openconnect_open_utf8(vpninfo, fname, O_RDONLY|O_BINARY);
Sep 30, 2008
Sep 30, 2008
43
if (fd < 0) {
Feb 5, 2014
Feb 5, 2014
44
vpn_progress(vpninfo, PRG_ERR,
Aug 2, 2014
Aug 2, 2014
45
46
47
_("Failed to open %s: %s\n"),
fname, strerror(errno));
return -ENOENT;
Sep 30, 2008
Sep 30, 2008
48
49
50
}
if (fstat(fd, &st)) {
Feb 5, 2014
Feb 5, 2014
51
vpn_progress(vpninfo, PRG_ERR,
Aug 2, 2014
Aug 2, 2014
52
53
54
55
_("Failed to fstat() %s: %s\n"),
fname, strerror(errno));
close(fd);
return -EIO;
Sep 30, 2008
Sep 30, 2008
56
57
}
Aug 2, 2014
Aug 2, 2014
58
59
60
len = st.st_size;
buf = malloc(len + 1);
if (!buf) {
Feb 5, 2014
Feb 5, 2014
61
vpn_progress(vpninfo, PRG_ERR,
Aug 2, 2014
Aug 2, 2014
62
63
64
65
_("Failed to allocate %d bytes for %s\n"),
len + 1, fname);
close(fd);
return -ENOMEM;
Feb 5, 2014
Feb 5, 2014
66
67
}
Aug 2, 2014
Aug 2, 2014
68
if (read(fd, buf, len) != len) {
Feb 5, 2014
Feb 5, 2014
69
vpn_progress(vpninfo, PRG_ERR,
Aug 2, 2014
Aug 2, 2014
70
71
72
73
74
_("Failed to read %s: %s\n"),
fname, strerror(errno));
free(buf);
close(fd);
return -EIO;
Sep 30, 2008
Sep 30, 2008
75
76
}
Aug 2, 2014
Aug 2, 2014
77
buf[len] = 0;
Mar 19, 2014
Mar 19, 2014
78
close(fd);
Aug 2, 2014
Aug 2, 2014
79
80
*ptr = buf;
return len;
Feb 5, 2014
Feb 5, 2014
81
82
}
Aug 2, 2014
Aug 2, 2014
83
84
85
86
87
88
89
90
91
92
static char *fetch_and_trim(xmlNode *node)
{
char *str = (char *)xmlNodeGetContent(node), *p;
int i, len;
if (!str)
return NULL;
len = strlen(str);
for (i = len-1; i >= 0; i--) {
Aug 4, 2014
Aug 4, 2014
93
if (isspace((int)(unsigned char)str[i]))
Aug 2, 2014
Aug 2, 2014
94
95
96
97
98
str[i] = 0;
else
break;
}
Aug 4, 2014
Aug 4, 2014
99
for (p = str; isspace((int)(unsigned char)*p); p++)
Aug 2, 2014
Aug 2, 2014
100
101
102
103
104
105
106
107
108
109
;
if (p == str)
return str;
p = strdup(p);
free(str);
return p;
}
Feb 5, 2014
Feb 5, 2014
110
111
int config_lookup_host(struct openconnect_info *vpninfo, const char *host)
{
Aug 2, 2014
Aug 2, 2014
112
113
int i;
ssize_t size;
Feb 5, 2014
Feb 5, 2014
114
115
116
117
118
119
120
121
char *xmlfile;
unsigned char sha1[SHA1_SIZE];
xmlDocPtr xml_doc;
xmlNode *xml_node, *xml_node2;
if (!vpninfo->xmlconfig)
return 0;
Aug 2, 2014
Aug 2, 2014
122
123
124
125
126
127
size = read_file_into_string(vpninfo, vpninfo->xmlconfig, &xmlfile);
if (size == -ENOENT) {
fprintf(stderr, _("Treating host \"%s\" as a raw hostname\n"), host);
return 0;
} else if (size <= 0) {
return size;
Feb 5, 2014
Feb 5, 2014
128
129
130
}
if (openconnect_sha1(sha1, xmlfile, size)) {
May 29, 2012
May 29, 2012
131
fprintf(stderr, _("Failed to SHA1 existing file\n"));
Feb 28, 2015
Feb 28, 2015
132
free(xmlfile);
May 29, 2012
May 29, 2012
133
134
return -1;
}
Sep 30, 2008
Sep 30, 2008
135
May 29, 2012
May 29, 2012
136
for (i = 0; i < SHA1_SIZE; i++)
Jun 30, 2014
Jun 30, 2014
137
snprintf(&vpninfo->xmlsha1[i*2], 3, "%02x", sha1[i]);
Sep 30, 2008
Sep 30, 2008
138
Jun 13, 2014
Jun 13, 2014
139
vpn_progress(vpninfo, PRG_DEBUG, _("XML config file SHA1: %s\n"),
Sep 22, 2011
Sep 22, 2011
140
vpninfo->xmlsha1);
Sep 30, 2008
Sep 30, 2008
141
Feb 5, 2014
Feb 5, 2014
142
143
144
145
xml_doc = xmlReadMemory(xmlfile, size, "noname.xml", NULL, 0);
free(xmlfile);
Sep 30, 2008
Sep 30, 2008
146
if (!xml_doc) {
Oct 7, 2011
Oct 7, 2011
147
148
149
150
fprintf(stderr, _("Failed to parse XML config file %s\n"),
vpninfo->xmlconfig);
fprintf(stderr, _("Treating host \"%s\" as a raw hostname\n"),
host);
Sep 30, 2008
Sep 30, 2008
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
return 0;
}
xml_node = xmlDocGetRootElement(xml_doc);
for (xml_node = xml_node->children; xml_node; xml_node = xml_node->next) {
if (xml_node->type == XML_ELEMENT_NODE &&
!strcmp((char *)xml_node->name, "ServerList")) {
for (xml_node = xml_node->children; xml_node && !vpninfo->hostname;
xml_node = xml_node->next) {
if (xml_node->type == XML_ELEMENT_NODE &&
!strcmp((char *)xml_node->name, "HostEntry")) {
int match = 0;
for (xml_node2 = xml_node->children;
match >= 0 && xml_node2; xml_node2 = xml_node2->next) {
if (xml_node2->type != XML_ELEMENT_NODE)
continue;
if (!match && !strcmp((char *)xml_node2->name, "HostName")) {
Aug 2, 2014
Aug 2, 2014
173
char *content = fetch_and_trim(xml_node2);
Sep 30, 2008
Sep 30, 2008
174
175
176
177
if (content && !strcmp(content, host))
match = 1;
else
match = -1;
Jan 1, 2010
Jan 1, 2010
178
free(content);
Sep 30, 2008
Sep 30, 2008
179
180
} else if (match &&
!strcmp((char *)xml_node2->name, "HostAddress")) {
Aug 2, 2014
Aug 2, 2014
181
char *content = fetch_and_trim(xml_node2);
Aug 2, 2014
Aug 2, 2014
182
183
if (content &&
!openconnect_parse_url(vpninfo, content)) {
Oct 7, 2011
Oct 7, 2011
184
printf(_("Host \"%s\" has address \"%s\"\n"),
Sep 30, 2008
Sep 30, 2008
185
host, content);
Mar 31, 2009
Mar 31, 2009
186
}
Aug 2, 2014
Aug 2, 2014
187
free(content);
Mar 31, 2009
Mar 31, 2009
188
189
} else if (match &&
!strcmp((char *)xml_node2->name, "UserGroup")) {
Aug 2, 2014
Aug 2, 2014
190
char *content = fetch_and_trim(xml_node2);
Mar 31, 2009
Mar 31, 2009
191
if (content) {
Apr 1, 2009
Apr 1, 2009
192
free(vpninfo->urlpath);
Jan 1, 2010
Jan 1, 2010
193
vpninfo->urlpath = content;
Oct 7, 2011
Oct 7, 2011
194
printf(_("Host \"%s\" has UserGroup \"%s\"\n"),
Mar 31, 2009
Mar 31, 2009
195
host, content);
Sep 30, 2008
Sep 30, 2008
196
197
198
199
200
201
202
203
204
205
206
207
}
}
}
}
}
break;
}
}
xmlFreeDoc(xml_doc);
if (!vpninfo->hostname) {
Oct 7, 2011
Oct 7, 2011
208
fprintf(stderr, _("Host \"%s\" not listed in config; treating as raw hostname\n"),
Sep 30, 2008
Sep 30, 2008
209
210
host);
}
Apr 9, 2009
Apr 9, 2009
211
Sep 30, 2008
Sep 30, 2008
212
213
return 0;
}