Skip to content

Latest commit

 

History

History
1157 lines (1012 loc) · 28.7 KB

ssl.c

File metadata and controls

1157 lines (1012 loc) · 28.7 KB
 
Sep 22, 2008
Sep 22, 2008
1
/*
Nov 20, 2008
Nov 20, 2008
2
* OpenConnect (SSL + DTLS) VPN client
Sep 22, 2008
Sep 22, 2008
3
*
Jan 26, 2015
Jan 26, 2015
4
* Copyright © 2008-2015 Intel Corporation.
Sep 22, 2008
Sep 22, 2008
5
*
Nov 20, 2008
Nov 20, 2008
6
7
8
* Author: David Woodhouse <dwmw2@infradead.org>
*
* This program is free software; you can redistribute it and/or
Oct 4, 2008
Oct 4, 2008
9
* modify it under the terms of the GNU Lesser General Public License
Nov 20, 2008
Nov 20, 2008
10
* version 2.1, as published by the Free Software Foundation.
Sep 22, 2008
Sep 22, 2008
11
*
Nov 20, 2008
Nov 20, 2008
12
* This program is distributed in the hope that it will be useful, but
Oct 4, 2008
Oct 4, 2008
13
14
15
* 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 22, 2008
Sep 22, 2008
16
*/
Jun 1, 2009
Jun 1, 2009
17
Jul 1, 2014
Jul 1, 2014
18
19
#include <config.h>
Jun 1, 2009
Jun 1, 2009
20
#include <sys/types.h>
Jun 17, 2012
Jun 17, 2012
21
#include <sys/stat.h>
Sep 22, 2008
Sep 22, 2008
22
#include <unistd.h>
Sep 22, 2008
Sep 22, 2008
23
#include <fcntl.h>
Jun 1, 2009
Jun 1, 2009
24
#include <string.h>
Nov 6, 2009
Nov 6, 2009
25
#include <stdio.h>
May 29, 2012
May 29, 2012
26
#include <errno.h>
May 29, 2012
May 29, 2012
27
#include <stdlib.h>
May 31, 2012
May 31, 2012
28
#include <stdarg.h>
Jan 15, 2014
Jan 15, 2014
29
#include <time.h>
Mar 11, 2013
Mar 11, 2013
30
#if defined(__linux__) || defined(__ANDROID__)
Jun 1, 2009
Jun 1, 2009
31
#include <sys/vfs.h>
Apr 9, 2010
Apr 9, 2010
32
#elif defined(__FreeBSD__) || defined(__FreeBSD_kernel__) || defined(__OpenBSD__) || defined(__APPLE__)
Jun 1, 2009
Jun 1, 2009
33
34
#include <sys/param.h>
#include <sys/mount.h>
Mar 10, 2013
Mar 10, 2013
35
#elif defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__)
Nov 6, 2009
Nov 6, 2009
36
#include <sys/statvfs.h>
Mar 10, 2013
Mar 10, 2013
37
#elif defined(__GNU__)
Aug 16, 2011
Aug 16, 2011
38
#include <sys/statfs.h>
Jun 1, 2009
Jun 1, 2009
39
#endif
Sep 22, 2008
Sep 22, 2008
40
Mar 9, 2011
Mar 9, 2011
41
#include "openconnect-internal.h"
Sep 22, 2008
Sep 22, 2008
42
Mar 3, 2013
Mar 3, 2013
43
44
45
46
#ifdef ANDROID_KEYSTORE
#include <sys/un.h>
#endif
Feb 23, 2010
Feb 23, 2010
47
48
49
50
51
/* OSX < 1.6 doesn't have AI_NUMERICSERV */
#ifndef AI_NUMERICSERV
#define AI_NUMERICSERV 0
#endif
Jan 12, 2019
Jan 12, 2019
52
53
54
55
/* GNU Hurd doesn't yet declare IPV6_TCLASS */
#ifndef IPV6_TCLASS
#if defined(__GNU__)
#define IPV6_TCLASS 61
Jan 14, 2019
Jan 14, 2019
56
57
#elif defined(__APPLE__)
#define IPV6_TCLASS 36
Jan 12, 2019
Jan 12, 2019
58
59
60
#endif
#endif
Feb 10, 2014
Feb 10, 2014
61
62
63
64
65
66
67
68
static inline int connect_pending()
{
#ifdef _WIN32
return WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EINPROGRESS;
#endif
}
Mar 26, 2015
Mar 26, 2015
69
70
71
72
73
74
75
/* Windows is interminably horrid, and has disjoint errno spaces.
* So if we return a positive value, that's a WSA Error and should
* be handled with openconnect__win32_strerror(). But if we return a
* negative value, that's a normal errno and should be handled with
* strerror(). No, you can't just pass the latter value (negated) to
* openconnect__win32_strerror() because it gives nonsense results. */
May 12, 2012
May 12, 2012
76
77
78
79
80
static int cancellable_connect(struct openconnect_info *vpninfo, int sockfd,
const struct sockaddr *addr, socklen_t addrlen)
{
struct sockaddr_storage peer;
socklen_t peerlen = sizeof(peer);
Mar 26, 2015
Mar 26, 2015
81
fd_set wr_set, rd_set, ex_set;
May 12, 2012
May 12, 2012
82
int maxfd = sockfd;
Mar 26, 2015
Mar 26, 2015
83
int err;
May 12, 2012
May 12, 2012
84
Feb 6, 2014
Feb 6, 2014
85
set_sock_nonblock(sockfd);
Jan 15, 2014
Jan 15, 2014
86
87
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, sockfd);
May 12, 2012
May 12, 2012
88
Mar 26, 2015
Mar 26, 2015
89
90
91
92
93
94
95
if (connect(sockfd, addr, addrlen) < 0 && !connect_pending()) {
#ifdef _WIN32
return WSAGetLastError();
#else
return -errno;
#endif
}
May 12, 2012
May 12, 2012
96
Jan 15, 2014
Jan 15, 2014
97
98
99
do {
FD_ZERO(&wr_set);
FD_ZERO(&rd_set);
Mar 26, 2015
Mar 26, 2015
100
FD_ZERO(&ex_set);
Jan 15, 2014
Jan 15, 2014
101
FD_SET(sockfd, &wr_set);
Mar 26, 2015
Mar 26, 2015
102
103
104
#ifdef _WIN32 /* Windows indicates failure this way, not in wr_set */
FD_SET(sockfd, &ex_set);
#endif
Jan 15, 2014
Jan 15, 2014
105
cmd_fd_set(vpninfo, &rd_set, &maxfd);
Mar 26, 2015
Mar 26, 2015
106
select(maxfd + 1, &rd_set, &wr_set, &ex_set, NULL);
Jan 15, 2014
Jan 15, 2014
107
108
if (is_cancel_pending(vpninfo, &rd_set)) {
vpn_progress(vpninfo, PRG_ERR, _("Socket connect cancelled\n"));
Mar 26, 2015
Mar 26, 2015
109
return -EINTR;
Jan 15, 2014
Jan 15, 2014
110
}
Mar 26, 2015
Mar 26, 2015
111
112
} while (!FD_ISSET(sockfd, &wr_set) && !FD_ISSET(sockfd, &ex_set) &&
!vpninfo->got_pause_cmd);
Mar 10, 2013
Mar 10, 2013
113
May 12, 2012
May 12, 2012
114
115
/* Check whether connect() succeeded or failed by using
getpeername(). See http://cr.yp.to/docs/connect.html */
Mar 26, 2015
Mar 26, 2015
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
if (!getpeername(sockfd, (void *)&peer, &peerlen))
return 0;
#ifdef _WIN32 /* On Windows, use getsockopt() to determine the error.
* We don't ddo this on Windows because it just reports
* -ENOTCONN, which we already knew. */
err = WSAGetLastError();
if (err == WSAENOTCONN) {
socklen_t errlen = sizeof(err);
getsockopt(sockfd, SOL_SOCKET, SO_ERROR,
(void *)&err, &errlen);
}
#else
err = -errno;
if (err == -ENOTCONN) {
int ch;
if (read(sockfd, &ch, 1) < 0)
err = -errno;
/* It should *always* fail! */
Mar 26, 2015
Mar 26, 2015
138
}
Mar 26, 2015
Mar 26, 2015
139
140
#endif
return err;
May 12, 2012
May 12, 2012
141
142
}
Mar 3, 2014
Mar 3, 2014
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
/* checks whether the provided string is an IP or a hostname.
*/
unsigned string_is_hostname(const char *str)
{
struct in_addr buf;
/* We don't use inet_pton() because an IPv6 literal is likely to
be encased in []. So just check for a colon, which shouldn't
occur in hostnames anyway. */
if (!str || inet_aton(str, &buf) || strchr(str, ':'))
return 0;
return 1;
}
Dec 5, 2014
Dec 5, 2014
158
159
160
161
162
163
164
165
166
167
168
static int match_sockaddr(struct sockaddr *a, struct sockaddr *b)
{
if (a->sa_family == AF_INET) {
struct sockaddr_in *a4 = (void *)a;
struct sockaddr_in *b4 = (void *)b;
return (a4->sin_addr.s_addr == b4->sin_addr.s_addr) &&
(a4->sin_port == b4->sin_port);
} else if (a->sa_family == AF_INET6) {
struct sockaddr_in6 *a6 = (void *)a;
struct sockaddr_in6 *b6 = (void *)b;
Dec 7, 2014
Dec 7, 2014
169
170
return !memcmp(&a6->sin6_addr, &b6->sin6_addr, sizeof(a6->sin6_addr)) &&
a6->sin6_port == b6->sin6_port;
Dec 5, 2014
Dec 5, 2014
171
172
173
174
} else
return 0;
}
May 29, 2012
May 29, 2012
175
int connect_https_socket(struct openconnect_info *vpninfo)
Sep 22, 2008
Sep 22, 2008
176
{
Jun 3, 2009
Jun 3, 2009
177
int ssl_sock = -1;
Sep 22, 2008
Sep 22, 2008
178
179
int err;
Dec 23, 2009
Dec 23, 2009
180
181
182
if (!vpninfo->port)
vpninfo->port = 443;
Dec 5, 2014
Dec 5, 2014
183
184
185
186
187
/* If we're talking to a server which told us it has dynamic DNS, don't
just re-use its previous IP address. If we're talking to a proxy, we
can use *its* previous IP address. We expect it'll re-do the DNS
lookup for the server anyway. */
if (vpninfo->peer_addr && (!vpninfo->is_dyndns || vpninfo->proxy)) {
Jun 20, 2014
Jun 20, 2014
188
reconnect:
May 17, 2012
May 17, 2012
189
190
191
192
193
194
#ifdef SOCK_CLOEXEC
ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM | SOCK_CLOEXEC, IPPROTO_IP);
if (ssl_sock < 0)
#endif
{
ssl_sock = socket(vpninfo->peer_addr->sa_family, SOCK_STREAM, IPPROTO_IP);
Mar 26, 2015
Mar 26, 2015
195
196
197
198
199
200
if (ssl_sock < 0) {
#ifdef _WIN32
err = WSAGetLastError();
#else
err = -errno;
#endif
May 17, 2012
May 17, 2012
201
goto reconn_err;
Mar 26, 2015
Mar 26, 2015
202
}
Feb 6, 2014
Feb 6, 2014
203
set_fd_cloexec(ssl_sock);
May 17, 2012
May 17, 2012
204
}
Mar 26, 2015
Mar 26, 2015
205
206
207
err = cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen);
if (err) {
char *errstr;
Dec 7, 2009
Dec 7, 2009
208
reconn_err:
Mar 26, 2015
Mar 26, 2015
209
210
211
212
213
214
#ifdef _WIN32
if (err > 0)
errstr = openconnect__win32_strerror(err);
else
#endif
errstr = strerror(-err);
Sep 22, 2011
Sep 22, 2011
215
if (vpninfo->proxy) {
Sep 26, 2012
Sep 26, 2012
216
vpn_progress(vpninfo, PRG_ERR,
Mar 26, 2015
Mar 26, 2015
217
_("Failed to reconnect to proxy %s: %s\n"),
Mar 26, 2015
Mar 26, 2015
218
vpninfo->proxy, errstr);
Sep 22, 2011
Sep 22, 2011
219
} else {
Sep 26, 2012
Sep 26, 2012
220
vpn_progress(vpninfo, PRG_ERR,
Mar 26, 2015
Mar 26, 2015
221
_("Failed to reconnect to host %s: %s\n"),
Mar 26, 2015
Mar 26, 2015
222
vpninfo->hostname, errstr);
Sep 22, 2011
Sep 22, 2011
223
}
Mar 26, 2015
Mar 26, 2015
224
225
226
227
#ifdef _WIN32
if (err > 0)
free(errstr);
#endif
Sep 26, 2012
Sep 26, 2012
228
if (ssl_sock >= 0)
Feb 6, 2014
Feb 6, 2014
229
closesocket(ssl_sock);
Jul 21, 2014
Jul 21, 2014
230
231
ssl_sock = -EINVAL;
goto out;
Sep 22, 2008
Sep 22, 2008
232
}
Dec 7, 2009
Dec 7, 2009
233
234
} else {
struct addrinfo hints, *result, *rp;
Jan 1, 2010
Jan 1, 2010
235
char *hostname;
Dec 23, 2009
Dec 23, 2009
236
char port[6];
Dec 7, 2009
Dec 7, 2009
237
238
239
240
241
242
243
244
245
246
memset(&hints, 0, sizeof(struct addrinfo));
hints.ai_family = AF_UNSPEC;
hints.ai_socktype = SOCK_STREAM;
hints.ai_flags = AI_PASSIVE | AI_NUMERICSERV;
hints.ai_protocol = 0;
hints.ai_canonname = NULL;
hints.ai_addr = NULL;
hints.ai_next = NULL;
Jan 1, 2010
Jan 1, 2010
247
248
249
250
/* The 'port' variable is a string because it's easier
this way than if we pass NULL to getaddrinfo() and
then try to fill in the numeric value into
different types of returned sockaddr_in{6,}. */
Sep 22, 2011
Sep 22, 2011
251
#ifdef LIBPROXY_HDR
Jan 2, 2010
Jan 2, 2010
252
if (vpninfo->proxy_factory) {
Aug 25, 2016
Aug 25, 2016
253
struct oc_text_buf *url_buf = buf_alloc();
Jan 2, 2010
Jan 2, 2010
254
255
256
char **proxies;
int i = 0;
Jan 2, 2010
Jan 2, 2010
257
258
free(vpninfo->proxy_type);
vpninfo->proxy_type = NULL;
Jan 2, 2010
Jan 2, 2010
259
260
261
free(vpninfo->proxy);
vpninfo->proxy = NULL;
Aug 25, 2016
Aug 25, 2016
262
263
264
265
266
267
buf_append(url_buf, "https://%s", vpninfo->hostname);
if (vpninfo->port != 443)
buf_append(url_buf, ":%d", vpninfo->port);
buf_append(url_buf, "/%s", vpninfo->urlpath?:"");
if (buf_error(url_buf)) {
buf_free(url_buf);
Jul 21, 2014
Jul 21, 2014
268
269
270
ssl_sock = -ENOMEM;
goto out;
}
Jan 2, 2010
Jan 2, 2010
271
272
proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
Aug 25, 2016
Aug 25, 2016
273
url_buf->data);
Dec 3, 2011
Dec 3, 2011
274
i = 0;
Jan 2, 2010
Jan 2, 2010
275
while (proxies && proxies[i]) {
Jan 2, 2010
Jan 2, 2010
276
277
278
279
if (!vpninfo->proxy &&
(!strncmp(proxies[i], "http://", 7) ||
!strncmp(proxies[i], "socks://", 8) ||
!strncmp(proxies[i], "socks5://", 9)))
Mar 9, 2011
Mar 9, 2011
280
internal_parse_url(proxies[i], &vpninfo->proxy_type,
Jan 2, 2010
Jan 2, 2010
281
282
&vpninfo->proxy, &vpninfo->proxy_port,
NULL, 0);
Jan 2, 2010
Jan 2, 2010
283
284
i++;
}
Aug 25, 2016
Aug 25, 2016
285
buf_free(url_buf);
Jan 2, 2010
Jan 2, 2010
286
287
free(proxies);
if (vpninfo->proxy)
Jun 13, 2014
Jun 13, 2014
288
vpn_progress(vpninfo, PRG_DEBUG,
Sep 22, 2011
Sep 22, 2011
289
290
_("Proxy from libproxy: %s://%s:%d/\n"),
vpninfo->proxy_type, vpninfo->proxy, vpninfo->port);
Jan 2, 2010
Jan 2, 2010
291
292
}
#endif
Jan 1, 2010
Jan 1, 2010
293
294
if (vpninfo->proxy) {
hostname = vpninfo->proxy;
Feb 22, 2010
Feb 22, 2010
295
snprintf(port, 6, "%d", vpninfo->proxy_port);
Jan 1, 2010
Jan 1, 2010
296
297
} else {
hostname = vpninfo->hostname;
Feb 22, 2010
Feb 22, 2010
298
snprintf(port, 6, "%d", vpninfo->port);
Jan 1, 2010
Jan 1, 2010
299
300
}
Jan 1, 2010
Jan 1, 2010
301
if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') {
Jul 3, 2014
Jul 3, 2014
302
hostname = strndup(hostname + 1, strlen(hostname) - 2);
Jul 21, 2014
Jul 21, 2014
303
304
305
306
if (!hostname) {
ssl_sock = -ENOMEM;
goto out;
}
Jan 1, 2010
Jan 1, 2010
307
308
309
hints.ai_flags |= AI_NUMERICHOST;
}
Mar 26, 2015
Mar 26, 2015
310
311
312
313
if (vpninfo->getaddrinfo_override)
err = vpninfo->getaddrinfo_override(vpninfo->cbdata, hostname, port, &hints, &result);
else
err = getaddrinfo(hostname, port, &hints, &result);
Jan 1, 2010
Jan 1, 2010
314
Dec 7, 2009
Dec 7, 2009
315
if (err) {
Sep 22, 2011
Sep 22, 2011
316
317
318
vpn_progress(vpninfo, PRG_ERR,
_("getaddrinfo failed for host '%s': %s\n"),
hostname, gai_strerror(err));
Sep 26, 2012
Sep 26, 2012
319
320
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
Jul 21, 2014
Jul 21, 2014
321
ssl_sock = -EINVAL;
Dec 5, 2014
Dec 5, 2014
322
323
324
325
326
327
328
/* If we were just retrying for dynamic DNS, reconnct using
the previously-known IP address */
if (vpninfo->peer_addr) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnecting to DynDNS server using previously cached IP address\n"));
goto reconnect;
}
Jul 21, 2014
Jul 21, 2014
329
goto out;
Dec 7, 2009
Dec 7, 2009
330
}
Sep 26, 2012
Sep 26, 2012
331
332
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
Dec 7, 2009
Dec 7, 2009
333
334
for (rp = result; rp ; rp = rp->ai_next) {
Jan 1, 2010
Jan 1, 2010
335
336
char host[80];
Feb 4, 2013
Feb 4, 2013
337
host[0] = 0;
Jan 1, 2010
Jan 1, 2010
338
339
if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host,
sizeof(host), NULL, 0, NI_NUMERICHOST))
Mar 26, 2015
Mar 26, 2015
340
vpn_progress(vpninfo, PRG_DEBUG, vpninfo->proxy_type ?
Mar 10, 2013
Mar 10, 2013
341
_("Attempting to connect to proxy %s%s%s:%s\n") :
Sep 23, 2012
Sep 23, 2012
342
_("Attempting to connect to server %s%s%s:%s\n"),
Mar 10, 2013
Mar 10, 2013
343
rp->ai_family == AF_INET6 ? "[" : "",
Sep 22, 2011
Sep 22, 2011
344
host,
Mar 10, 2013
Mar 10, 2013
345
rp->ai_family == AF_INET6 ? "]" : "",
Sep 22, 2011
Sep 22, 2011
346
port);
Sep 23, 2012
Sep 23, 2012
347
Dec 7, 2009
Dec 7, 2009
348
349
350
351
ssl_sock = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (ssl_sock < 0)
continue;
Feb 6, 2014
Feb 6, 2014
352
set_fd_cloexec(ssl_sock);
Mar 26, 2015
Mar 26, 2015
353
354
err = cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen);
if (!err) {
Dec 7, 2009
Dec 7, 2009
355
356
/* Store the peer address we actually used, so that DTLS can
use it again later */
Mar 8, 2016
Mar 8, 2016
357
358
359
360
361
free(vpninfo->ip_info.gateway_addr);
vpninfo->ip_info.gateway_addr = NULL;
if (host[0]) {
vpninfo->ip_info.gateway_addr = strdup(host);
Mar 26, 2015
Mar 26, 2015
362
363
364
365
366
vpn_progress(vpninfo, PRG_INFO, _("Connected to %s%s%s:%s\n"),
rp->ai_family == AF_INET6 ? "[" : "",
host,
rp->ai_family == AF_INET6 ? "]" : "",
port);
Mar 8, 2016
Mar 8, 2016
367
}
Mar 26, 2015
Mar 26, 2015
368
Dec 5, 2014
Dec 5, 2014
369
370
free(vpninfo->peer_addr);
vpninfo->peer_addrlen = 0;
Dec 7, 2009
Dec 7, 2009
371
372
vpninfo->peer_addr = malloc(rp->ai_addrlen);
if (!vpninfo->peer_addr) {
Sep 22, 2011
Sep 22, 2011
373
374
vpn_progress(vpninfo, PRG_ERR,
_("Failed to allocate sockaddr storage\n"));
Feb 6, 2014
Feb 6, 2014
375
closesocket(ssl_sock);
Jul 21, 2014
Jul 21, 2014
376
377
ssl_sock = -ENOMEM;
goto out;
Dec 7, 2009
Dec 7, 2009
378
379
380
}
vpninfo->peer_addrlen = rp->ai_addrlen;
memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
Jan 7, 2015
Jan 7, 2015
381
382
383
384
385
386
387
388
389
390
391
/* If no proxy, ensure that we output *this* IP address in
* authentication results because we're going to need to
* reconnect to the *same* server from the rotation. And with
* some trick DNS setups, it might possibly be a "rotation"
* even if we only got one result from getaddrinfo() this
* time.
*
* If there's a proxy, we're kind of screwed; we can't know
* which IP address we connected to. Perhaps we ought to do
* the DNS lookup locally and connect to a specific IP? */
if (!vpninfo->proxy && host[0]) {
Feb 5, 2013
Feb 5, 2013
392
char *p = malloc(strlen(host) + 3);
Feb 4, 2013
Feb 4, 2013
393
if (p) {
Feb 22, 2013
Feb 22, 2013
394
395
free(vpninfo->unique_hostname);
vpninfo->unique_hostname = p;
Feb 4, 2013
Feb 4, 2013
396
397
398
399
400
401
if (rp->ai_family == AF_INET6)
*p++ = '[';
memcpy(p, host, strlen(host));
p += strlen(host);
if (rp->ai_family == AF_INET6)
*p++ = ']';
Feb 5, 2013
Feb 5, 2013
402
*p = 0;
Feb 4, 2013
Feb 4, 2013
403
404
}
}
Dec 7, 2009
Dec 7, 2009
405
406
break;
}
Mar 26, 2015
Mar 26, 2015
407
408
409
410
411
412
413
414
415
if (host[0]) {
char *errstr;
#ifdef _WIN32
if (err > 0)
errstr = openconnect__win32_strerror(err);
else
#endif
errstr = strerror(-err);
Mar 26, 2015
Mar 26, 2015
416
417
418
419
vpn_progress(vpninfo, PRG_INFO, _("Failed to connect to %s%s%s:%s: %s\n"),
rp->ai_family == AF_INET6 ? "[" : "",
host,
rp->ai_family == AF_INET6 ? "]" : "",
Mar 26, 2015
Mar 26, 2015
420
421
422
423
424
425
port, errstr);
#ifdef _WIN32
if (err > 0)
free(errstr);
#endif
}
Feb 6, 2014
Feb 6, 2014
426
closesocket(ssl_sock);
Dec 7, 2009
Dec 7, 2009
427
ssl_sock = -1;
Dec 5, 2014
Dec 5, 2014
428
429
430
431
432
433
434
435
436
437
/* If we're in DynDNS mode but this *was* the cached IP address,
* don't bother falling back to it if it didn't work. */
if (vpninfo->peer_addr && vpninfo->peer_addrlen == rp->ai_addrlen &&
match_sockaddr(vpninfo->peer_addr, rp->ai_addr)) {
vpn_progress(vpninfo, PRG_TRACE,
_("Forgetting non-functional previous peer address\n"));
free(vpninfo->peer_addr);
vpninfo->peer_addr = 0;
vpninfo->peer_addrlen = 0;
Mar 8, 2016
Mar 8, 2016
438
439
free(vpninfo->ip_info.gateway_addr);
vpninfo->ip_info.gateway_addr = NULL;
Dec 5, 2014
Dec 5, 2014
440
}
Dec 7, 2009
Dec 7, 2009
441
442
}
freeaddrinfo(result);
Mar 10, 2013
Mar 10, 2013
443
Dec 7, 2009
Dec 7, 2009
444
if (ssl_sock < 0) {
Sep 22, 2011
Sep 22, 2011
445
446
447
vpn_progress(vpninfo, PRG_ERR,
_("Failed to connect to host %s\n"),
vpninfo->proxy?:vpninfo->hostname);
Jul 21, 2014
Jul 21, 2014
448
ssl_sock = -EINVAL;
Dec 5, 2014
Dec 5, 2014
449
450
451
452
453
if (vpninfo->peer_addr) {
vpn_progress(vpninfo, PRG_ERR,
_("Reconnecting to DynDNS server using previously cached IP address\n"));
goto reconnect;
}
Jul 21, 2014
Jul 21, 2014
454
goto out;
Dec 7, 2009
Dec 7, 2009
455
}
Sep 22, 2008
Sep 22, 2008
456
457
}
Jan 1, 2010
Jan 1, 2010
458
if (vpninfo->proxy) {
Jan 2, 2010
Jan 2, 2010
459
err = process_proxy(vpninfo, ssl_sock);
Jan 1, 2010
Jan 1, 2010
460
if (err) {
Feb 6, 2014
Feb 6, 2014
461
closesocket(ssl_sock);
Jun 20, 2014
Jun 20, 2014
462
463
464
465
466
467
if (err == -EAGAIN) {
/* Proxy authentication failed and we need to retry */
vpn_progress(vpninfo, PRG_DEBUG,
_("Reconnecting to proxy %s\n"), vpninfo->proxy);
goto reconnect;
}
Jul 21, 2014
Jul 21, 2014
468
ssl_sock = err;
Jan 1, 2010
Jan 1, 2010
469
470
}
}
Jul 21, 2014
Jul 21, 2014
471
472
473
out:
/* If proxy processing returned -EAGAIN to reconnect before attempting
further auth, and we failed to reconnect, we have to clean up here. */
Feb 24, 2015
Feb 24, 2015
474
clear_auth_states(vpninfo, vpninfo->proxy_auth, 1);
May 29, 2012
May 29, 2012
475
476
477
return ssl_sock;
}
May 31, 2012
May 31, 2012
478
479
480
481
482
483
484
485
486
487
488
int __attribute__ ((format (printf, 2, 3)))
openconnect_SSL_printf(struct openconnect_info *vpninfo, const char *fmt, ...)
{
char buf[1024];
va_list args;
buf[1023] = 0;
va_start(args, fmt);
vsnprintf(buf, 1023, fmt, args);
va_end(args);
Jun 18, 2014
Jun 18, 2014
489
return vpninfo->ssl_write(vpninfo, buf, strlen(buf));
May 31, 2012
May 31, 2012
490
491
492
}
Oct 29, 2014
Oct 29, 2014
493
494
int __attribute__ ((format(printf, 4, 5)))
request_passphrase(struct openconnect_info *vpninfo, const char *label,
Jun 4, 2012
Jun 4, 2012
495
496
497
498
499
500
501
502
503
504
505
506
507
508
char **response, const char *fmt, ...)
{
struct oc_auth_form f;
struct oc_form_opt o;
char buf[1024];
va_list args;
int ret;
buf[1023] = 0;
memset(&f, 0, sizeof(f));
va_start(args, fmt);
vsnprintf(buf, 1023, fmt, args);
va_end(args);
Jun 13, 2012
Jun 13, 2012
509
f.auth_id = (char *)label;
Jun 4, 2012
Jun 4, 2012
510
511
512
513
f.opts = &o;
o.next = NULL;
o.type = OC_FORM_OPT_PASSWORD;
Jun 13, 2012
Jun 13, 2012
514
o.name = (char *)label;
Jun 4, 2012
Jun 4, 2012
515
o.label = buf;
Oct 9, 2014
Oct 9, 2014
516
o._value = NULL;
Jun 4, 2012
Jun 4, 2012
517
Jan 15, 2014
Jan 15, 2014
518
ret = process_auth_form(vpninfo, &f);
Jun 4, 2012
Jun 4, 2012
519
if (!ret) {
Oct 9, 2014
Oct 9, 2014
520
*response = o._value;
Jun 4, 2012
Jun 4, 2012
521
522
523
524
525
526
return 0;
}
return -EIO;
}
May 7, 2010
May 7, 2010
527
#if defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__)
Nov 16, 2010
Nov 16, 2010
528
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
Nov 3, 2009
Nov 3, 2009
529
530
{
struct statvfs buf;
Jul 31, 2014
Jul 31, 2014
531
532
char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey);
int err = 0;
Nov 3, 2009
Nov 3, 2009
533
Jul 31, 2014
Jul 31, 2014
534
535
if (statvfs(sslkey, &buf)) {
err = -errno;
Sep 22, 2011
Sep 22, 2011
536
537
vpn_progress(vpninfo, PRG_ERR, _("statvfs: %s\n"),
strerror(errno));
Jul 31, 2014
Jul 31, 2014
538
} else if (asprintf(&vpninfo->cert_password, "%lx", buf.f_fsid) == -1)
Jul 31, 2014
Jul 31, 2014
539
540
541
542
543
err = -ENOMEM;
if (sslkey != vpninfo->sslkey)
free(sslkey);
return err;
Nov 3, 2009
Nov 3, 2009
544
}
Feb 6, 2014
Feb 6, 2014
545
546
#elif defined(_WIN32)
#include <fileapi.h>
Jul 25, 2014
Jul 25, 2014
547
548
typedef BOOL WINAPI (*GVIBH)(HANDLE, LPWSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPWSTR, DWORD);
Feb 6, 2014
Feb 6, 2014
549
550
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
{
Feb 12, 2014
Feb 12, 2014
551
HANDLE h;
Feb 6, 2014
Feb 6, 2014
552
DWORD serial;
Jul 25, 2014
Jul 25, 2014
553
554
HINSTANCE kernlib;
GVIBH func = NULL;
Feb 12, 2014
Feb 12, 2014
555
int success;
Jul 31, 2014
Jul 31, 2014
556
int fd;
Feb 6, 2014
Feb 6, 2014
557
Jul 25, 2014
Jul 25, 2014
558
559
560
561
562
563
564
565
566
567
568
569
570
571
/* Some versions of Windows don't have this so don't use standard
load-time linking or it'll cause failures. */
kernlib = LoadLibraryA("Kernel32.dll");
if (!kernlib) {
notsupp:
vpn_progress(vpninfo, PRG_ERR,
_("Could not obtain file system ID for passphrase\n"));
return -EOPNOTSUPP;
}
func = (GVIBH)GetProcAddress(kernlib, "GetVolumeInformationByHandleW");
FreeLibrary(kernlib);
if (!func)
goto notsupp;
Aug 3, 2014
Aug 3, 2014
572
fd = openconnect_open_utf8(vpninfo, vpninfo->sslkey, O_RDONLY);
Jul 31, 2014
Jul 31, 2014
573
574
575
576
577
578
if (fd == -1) {
vpn_progress(vpninfo, PRG_ERR,
_("Failed to open private key file '%s': %s\n"),
vpninfo->sslkey, strerror(errno));
return -ENOENT;
}
Feb 6, 2014
Feb 6, 2014
579
Jul 31, 2014
Jul 31, 2014
580
h = (HANDLE)_get_osfhandle(fd);
Jul 25, 2014
Jul 25, 2014
581
success = func(h, NULL, 0, &serial, NULL, NULL, NULL, 0);
Jul 31, 2014
Jul 31, 2014
582
close(fd);
Feb 12, 2014
Feb 12, 2014
583
584
if (!success)
Feb 6, 2014
Feb 6, 2014
585
586
return -EIO;
Jul 31, 2014
Jul 31, 2014
587
if (asprintf(&vpninfo->cert_password, "%lx", serial) == -1)
Feb 6, 2014
Feb 6, 2014
588
589
return -ENOMEM;
Feb 12, 2014
Feb 12, 2014
590
return 0;
Feb 6, 2014
Feb 6, 2014
591
}
Mar 8, 2016
Mar 8, 2016
592
#elif defined(HAVE_STATFS)
Nov 16, 2010
Nov 16, 2010
593
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
May 28, 2009
May 28, 2009
594
{
Jul 31, 2014
Jul 31, 2014
595
char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey);
May 28, 2009
May 28, 2009
596
597
598
struct statfs buf;
unsigned *fsid = (unsigned *)&buf.f_fsid;
unsigned long long fsid64;
Jul 31, 2014
Jul 31, 2014
599
int err = 0;
May 28, 2009
May 28, 2009
600
Jul 31, 2014
Jul 31, 2014
601
602
if (statfs(sslkey, &buf)) {
err = -errno;
Sep 22, 2011
Sep 22, 2011
603
604
vpn_progress(vpninfo, PRG_ERR, _("statfs: %s\n"),
strerror(errno));
May 28, 2009
May 28, 2009
605
return -err;
Jul 31, 2014
Jul 31, 2014
606
607
608
} else {
fsid64 = ((unsigned long long)fsid[0] << 32) | fsid[1];
Jul 31, 2014
Jul 31, 2014
609
if (asprintf(&vpninfo->cert_password, "%llx", fsid64) == -1)
Jul 31, 2014
Jul 31, 2014
610
err = -ENOMEM;
May 28, 2009
May 28, 2009
611
}
Nov 6, 2009
Nov 6, 2009
612
Jul 31, 2014
Jul 31, 2014
613
614
615
616
if (sslkey != vpninfo->sslkey)
free(sslkey);
return err;
May 28, 2009
May 28, 2009
617
}
Mar 8, 2016
Mar 8, 2016
618
619
620
621
622
#else
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
{
return -EOPNOTSUPP;
}
Nov 3, 2009
Nov 3, 2009
623
#endif
Jun 11, 2012
Jun 11, 2012
624
Sep 10, 2016
Sep 10, 2016
625
#if defined(OPENCONNECT_OPENSSL)
Jun 11, 2012
Jun 11, 2012
626
627
/* We put this here rather than in openssl.c because it might be needed
for OpenSSL DTLS support even when GnuTLS is being used for HTTPS */
Jun 14, 2012
Jun 14, 2012
628
int openconnect_print_err_cb(const char *str, size_t len, void *ptr)
Jun 11, 2012
Jun 11, 2012
629
630
631
632
633
634
635
{
struct openconnect_info *vpninfo = ptr;
vpn_progress(vpninfo, PRG_ERR, "%s", str);
return 0;
}
#endif
Jun 17, 2012
Jun 17, 2012
636
637
638
639
640
641
642
643
644
645
646
647
648
649
650
651
652
653
654
655
656
657
658
#ifdef FAKE_ANDROID_KEYSTORE
char *keystore_strerror(int err)
{
return (char *)strerror(-err);
}
int keystore_fetch(const char *key, unsigned char **result)
{
unsigned char *data;
struct stat st;
int fd;
int ret;
fd = open(key, O_RDONLY);
if (fd < 0)
return -errno;
if (fstat(fd, &st)) {
ret = -errno;
goto out_fd;
}
Jun 19, 2012
Jun 19, 2012
659
data = malloc(st.st_size + 1);
Jun 17, 2012
Jun 17, 2012
660
661
662
663
664
665
666
667
668
669
if (!data) {
ret = -ENOMEM;
goto out_fd;
}
if (read(fd, data, st.st_size) != st.st_size) {
ret = -EIO;
free(data);
goto out_fd;
}
Jun 19, 2012
Jun 19, 2012
670
671
data[st.st_size] = 0;
Jun 17, 2012
Jun 17, 2012
672
673
674
675
676
677
*result = data;
ret = st.st_size;
out_fd:
close(fd);
return ret;
}
Mar 10, 2013
Mar 10, 2013
678
#elif defined(ANDROID_KEYSTORE)
Mar 3, 2013
Mar 3, 2013
679
680
681
682
683
684
685
686
687
688
689
690
691
/* keystore.h isn't in the NDK so we need to define these */
#define NO_ERROR 1
#define LOCKED 2
#define UNINITIALIZED 3
#define SYSTEM_ERROR 4
#define PROTOCOL_ERROR 5
#define PERMISSION_DENIED 6
#define KEY_NOT_FOUND 7
#define VALUE_CORRUPTED 8
#define UNDEFINED_ACTION 9
#define WRONG_PASSWORD 10
const char *keystore_strerror(int err)
Jun 17, 2012
Jun 17, 2012
692
693
694
{
switch (-err) {
case NO_ERROR: return _("No error");
Oct 17, 2012
Oct 17, 2012
695
case LOCKED: return _("Keystore locked");
Jun 17, 2012
Jun 17, 2012
696
697
698
699
700
701
702
case UNINITIALIZED: return _("Keystore uninitialized");
case SYSTEM_ERROR: return _("System error");
case PROTOCOL_ERROR: return _("Protocol error");
case PERMISSION_DENIED: return _("Permission denied");
case KEY_NOT_FOUND: return _("Key not found");
case VALUE_CORRUPTED: return _("Value corrupted");
case UNDEFINED_ACTION: return _("Undefined action");
Mar 3, 2013
Mar 3, 2013
703
704
705
706
case WRONG_PASSWORD:
case WRONG_PASSWORD+1:
case WRONG_PASSWORD+2:
case WRONG_PASSWORD+3: return _("Wrong password");
Jun 17, 2012
Jun 17, 2012
707
708
709
710
711
712
713
714
default: return _("Unknown error");
}
}
/* Returns length, or a negative errno in its own namespace (handled by its
own strerror function above). The numbers are from Android's keystore.h */
int keystore_fetch(const char *key, unsigned char **result)
{
Mar 3, 2013
Mar 3, 2013
715
716
struct sockaddr_un sa = { AF_UNIX, "/dev/socket/keystore" };
socklen_t sl = offsetof(struct sockaddr_un, sun_path) + strlen(sa.sun_path) + 1;
Jun 17, 2012
Jun 17, 2012
717
718
unsigned char *data, *p;
unsigned char buf[3];
Mar 6, 2013
Mar 6, 2013
719
int len, fd;
Jun 17, 2012
Jun 17, 2012
720
721
int ret = -SYSTEM_ERROR;
Mar 3, 2013
Mar 3, 2013
722
fd = socket(AF_UNIX, SOCK_STREAM, 0);
Jun 17, 2012
Jun 17, 2012
723
724
725
if (fd < 0)
return -SYSTEM_ERROR;
Mar 3, 2013
Mar 3, 2013
726
727
728
729
if (connect(fd, (void *)&sa, sl)) {
close(fd);
return -SYSTEM_ERROR;
}
Jun 17, 2012
Jun 17, 2012
730
731
len = strlen(key);
buf[0] = 'g';
Jan 26, 2015
Jan 26, 2015
732
store_be16(buf + 1, len);
Jun 17, 2012
Jun 17, 2012
733
734
735
736
737
738
739
740
741
742
743
744
if (send(fd, buf, 3, 0) != 3 || send(fd, key, len, 0) != len ||
shutdown(fd, SHUT_WR) || recv(fd, buf, 1, 0) != 1)
goto out;
if (buf[0] != NO_ERROR) {
/* Should never be zero */
ret = buf[0] ? -buf[0] : -PROTOCOL_ERROR;
goto out;
}
if (recv(fd, buf, 2, 0) != 2)
goto out;
Jan 26, 2015
Jan 26, 2015
745
len = load_be16(buf);
Jun 17, 2012
Jun 17, 2012
746
747
748
749
750
751
752
753
754
755
756
757
758
759
760
761
762
763
764
765
766
767
768
data = malloc(len);
if (!data)
goto out;
p = data;
ret = len;
while (len) {
int got = recv(fd, p, len, 0);
if (got <= 0) {
free(data);
ret = -PROTOCOL_ERROR;
goto out;
}
len -= got;
p += got;
}
*result = data;
out:
close(fd);
return ret;
}
#endif
Jan 15, 2014
Jan 15, 2014
769
770
771
void cmd_fd_set(struct openconnect_info *vpninfo, fd_set *fds, int *maxfd)
{
Jan 15, 2014
Jan 15, 2014
772
773
774
775
if (vpninfo->cmd_fd != -1) {
FD_SET(vpninfo->cmd_fd, fds);
if (vpninfo->cmd_fd > *maxfd)
*maxfd = vpninfo->cmd_fd;
Jan 15, 2014
Jan 15, 2014
776
777
778
}
}
Jan 15, 2014
Jan 15, 2014
779
780
781
782
783
784
785
786
787
788
789
790
void check_cmd_fd(struct openconnect_info *vpninfo, fd_set *fds)
{
char cmd;
if (vpninfo->cmd_fd == -1 || !FD_ISSET(vpninfo->cmd_fd, fds))
return;
if (vpninfo->cmd_fd_write == -1) {
/* legacy openconnect_set_cancel_fd() users */
vpninfo->got_cancel_cmd = 1;
return;
}
Oct 22, 2014
Oct 22, 2014
791
#ifdef _WIN32
Sep 15, 2014
Sep 15, 2014
792
if (recv(vpninfo->cmd_fd, &cmd, 1, 0) != 1)
Jan 15, 2014
Jan 15, 2014
793
return;
Oct 22, 2014
Oct 22, 2014
794
795
796
797
#else
if (read(vpninfo->cmd_fd, &cmd, 1) != 1)
return;
#endif
Jan 15, 2014
Jan 15, 2014
798
799
switch (cmd) {
case OC_CMD_CANCEL:
Jun 13, 2014
Jun 13, 2014
800
case OC_CMD_DETACH:
Jan 15, 2014
Jan 15, 2014
801
vpninfo->got_cancel_cmd = 1;
Jun 13, 2014
Jun 13, 2014
802
vpninfo->cancel_type = cmd;
Jan 15, 2014
Jan 15, 2014
803
break;
Jan 15, 2014
Jan 15, 2014
804
805
806
case OC_CMD_PAUSE:
vpninfo->got_pause_cmd = 1;
break;
Jan 15, 2014
Jan 15, 2014
807
808
809
case OC_CMD_STATS:
if (vpninfo->stats_handler)
vpninfo->stats_handler(vpninfo->cbdata, &vpninfo->stats);
Jan 15, 2014
Jan 15, 2014
810
811
812
}
}
Jan 15, 2014
Jan 15, 2014
813
814
int is_cancel_pending(struct openconnect_info *vpninfo, fd_set *fds)
{
Jan 15, 2014
Jan 15, 2014
815
check_cmd_fd(vpninfo, fds);
May 6, 2016
May 6, 2016
816
return vpninfo->got_cancel_cmd || vpninfo->got_pause_cmd;
Jan 15, 2014
Jan 15, 2014
817
818
819
820
821
822
}
void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout)
{
fd_set rd_set;
int maxfd = 0;
Feb 17, 2014
Feb 17, 2014
823
time_t expiration = time(NULL) + timeout, now = 0;
Jan 15, 2014
Jan 15, 2014
824
Feb 17, 2014
Feb 17, 2014
825
while (now < expiration && !vpninfo->got_cancel_cmd && !vpninfo->got_pause_cmd) {
Mar 7, 2014
Mar 7, 2014
826
struct timeval tv;
Jan 15, 2014
Jan 15, 2014
827
828
829
now = time(NULL);
tv.tv_sec = now >= expiration ? 0 : expiration - now;
Mar 7, 2014
Mar 7, 2014
830
tv.tv_usec = 0;
Jan 15, 2014
Jan 15, 2014
831
Jan 15, 2014
Jan 15, 2014
832
833
834
835
FD_ZERO(&rd_set);
cmd_fd_set(vpninfo, &rd_set, &maxfd);
select(maxfd + 1, &rd_set, NULL, NULL, &tv);
check_cmd_fd(vpninfo, &rd_set);
Feb 17, 2014
Feb 17, 2014
836
}
Jan 15, 2014
Jan 15, 2014
837
}
Jul 31, 2014
Jul 31, 2014
838
839
#ifdef _WIN32
Aug 3, 2014
Aug 3, 2014
840
841
#include <io.h>
#include <sys/stat.h>
Aug 3, 2014
Aug 3, 2014
842
int openconnect_open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
Jul 31, 2014
Jul 31, 2014
843
844
845
846
847
848
849
850
851
852
853
854
855
856
857
858
{
wchar_t *fname_w;
int nr_chars = MultiByteToWideChar(CP_UTF8, 0, fname, -1, NULL, 0);
int fd;
if (!nr_chars) {
errno = EINVAL;
return -1;
}
fname_w = malloc(nr_chars * sizeof(wchar_t));
if (!fname_w) {
errno = ENOMEM;
return -1;
}
MultiByteToWideChar(CP_UTF8, 0, fname, -1, fname_w, nr_chars);
Aug 3, 2014
Aug 3, 2014
859
fd = _wopen(fname_w, mode, _S_IREAD | _S_IWRITE);
Jul 31, 2014
Jul 31, 2014
860
861
862
863
864
free(fname_w);
return fd;
}
#else
Aug 3, 2014
Aug 3, 2014
865
int openconnect_open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
Jul 31, 2014
Jul 31, 2014
866
867
868
869
{
char *legacy_fname = openconnect_utf8_to_legacy(vpninfo, fname);
int fd;
Aug 3, 2014
Aug 3, 2014
870
fd = open(legacy_fname, mode, 0644);
Jul 31, 2014
Jul 31, 2014
871
872
873
874
875
876
877
if (legacy_fname != fname)
free(legacy_fname);
return fd;
}
#endif
Aug 3, 2014
Aug 3, 2014
878
879
FILE *openconnect_fopen_utf8(struct openconnect_info *vpninfo, const char *fname,
const char *mode)
Jul 31, 2014
Jul 31, 2014
880
881
{
int fd;
Aug 3, 2014
Aug 3, 2014
882
883
884
885
886
887
888
889
890
891
892
893
894
int flags;
if (!strcmp(mode, "r"))
flags = O_RDONLY|O_CLOEXEC;
else if (!strcmp(mode, "rb"))
flags = O_RDONLY|O_CLOEXEC|O_BINARY;
else if (!strcmp(mode, "w"))
flags = O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC;
else if (!strcmp(mode, "wb"))
flags = O_WRONLY|O_CLOEXEC|O_CREAT|O_TRUNC|O_BINARY;
else {
/* This should never happen, but if we forget and start using other
modes without implementing proper mode->flags conversion, complain! */
Jul 31, 2014
Jul 31, 2014
895
vpn_progress(vpninfo, PRG_ERR,
Aug 3, 2014
Aug 3, 2014
896
_("openconnect_fopen_utf8() used with unsupported mode '%s'\n"),
Jul 31, 2014
Jul 31, 2014
897
898
899
900
mode);
return NULL;
}
Aug 3, 2014
Aug 3, 2014
901
fd = openconnect_open_utf8(vpninfo, fname, flags);
Jul 31, 2014
Jul 31, 2014
902
903
904
905
906
if (fd == -1)
return NULL;
return fdopen(fd, mode);
}
Jan 26, 2015
Jan 26, 2015
907
908
909
int udp_sockaddr(struct openconnect_info *vpninfo, int port)
{
Mar 14, 2015
Mar 14, 2015
910
free(vpninfo->dtls_addr);
Jan 26, 2015
Jan 26, 2015
911
912
913
914
915
916
917
918
919
vpninfo->dtls_addr = malloc(vpninfo->peer_addrlen);
if (!vpninfo->dtls_addr)
return -ENOMEM;
memcpy(vpninfo->dtls_addr, vpninfo->peer_addr, vpninfo->peer_addrlen);
if (vpninfo->peer_addr->sa_family == AF_INET) {
struct sockaddr_in *sin = (void *)vpninfo->dtls_addr;
sin->sin_port = htons(port);
Aug 25, 2016
Aug 25, 2016
920
921
vpninfo->dtls_tos_proto = IPPROTO_IP;
vpninfo->dtls_tos_optname = IP_TOS;
Jan 26, 2015
Jan 26, 2015
922
923
924
} else if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin = (void *)vpninfo->dtls_addr;
sin->sin6_port = htons(port);
Jan 10, 2019
Jan 10, 2019
925
#if defined(IPV6_TCLASS)
Aug 25, 2016
Aug 25, 2016
926
927
vpninfo->dtls_tos_proto = IPPROTO_IPV6;
vpninfo->dtls_tos_optname = IPV6_TCLASS;
Jan 10, 2019
Jan 10, 2019
928
#endif
Jan 26, 2015
Jan 26, 2015
929
930
931
932
933
934
935
} else {
vpn_progress(vpninfo, PRG_ERR,
_("Unknown protocol family %d. Cannot create UDP server address\n"),
vpninfo->peer_addr->sa_family);
return -EINVAL;
}
Aug 25, 2016
Aug 25, 2016
936
937
938
939
940
/* in case DTLS TOS copy is disabled, reset the optname value */
/* so that the copy won't be applied in dtls.c / dtls_mainloop() */
if (!vpninfo->dtls_pass_tos)
vpninfo->dtls_tos_optname = 0;
Jan 26, 2015
Jan 26, 2015
941
942
return 0;
}
Jan 26, 2015
Jan 26, 2015
943
944
945
946
947
948
949
950
951
952
953
954
955
956
957
958
959
960
961
962
963
964
965
966
967
968
969
970
971
972
973
974
975
976
977
978
979
980
981
982
983
984
985
986
987
988
989
990
991
992
993
994
995
996
997
998
999
1000
int udp_connect(struct openconnect_info *vpninfo)
{
int fd, sndbuf;
fd = socket(vpninfo->peer_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
if (fd < 0) {
vpn_perror(vpninfo, _("Open UDP socket"));
return -EINVAL;
}
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, fd);
sndbuf = vpninfo->ip_info.mtu * 2;
setsockopt(fd, SOL_SOCKET, SO_SNDBUF, (void *)&sndbuf, sizeof(sndbuf));
if (vpninfo->dtls_local_port) {
union {
struct sockaddr_in in;
struct sockaddr_in6 in6;
} dtls_bind_addr;
int dtls_bind_addrlen;
memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr));
if (vpninfo->peer_addr->sa_family == AF_INET) {
struct sockaddr_in *addr = &dtls_bind_addr.in;
dtls_bind_addrlen = sizeof(*addr);
addr->sin_family = AF_INET;
addr->sin_addr.s_addr = INADDR_ANY;
addr->sin_port = htons(vpninfo->dtls_local_port);
} else if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *addr = &dtls_bind_addr.in6;
dtls_bind_addrlen = sizeof(*addr);
addr->sin6_family = AF_INET6;
addr->sin6_addr = in6addr_any;
addr->sin6_port = htons(vpninfo->dtls_local_port);
} else {
vpn_progress(vpninfo, PRG_ERR,
_("Unknown protocol family %d. Cannot use UDP transport\n"),
vpninfo->peer_addr->sa_family);
vpninfo->dtls_attempt_period = 0;
closesocket(fd);
return -EINVAL;
}
if (bind(fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) {
vpn_perror(vpninfo, _("Bind UDP socket"));
closesocket(fd);
return -EINVAL;
}
}
if (connect(fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
vpn_perror(vpninfo, _("Connect UDP socket\n"));
closesocket(fd);
return -EINVAL;
}