Skip to content

Latest commit

 

History

History
1040 lines (918 loc) · 26.7 KB

ssl.c

File metadata and controls

1040 lines (918 loc) · 26.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
Feb 10, 2014
Feb 10, 2014
52
53
54
55
56
57
58
59
static inline int connect_pending()
{
#ifdef _WIN32
return WSAGetLastError() == WSAEWOULDBLOCK;
#else
return errno == EINPROGRESS;
#endif
}
Mar 26, 2015
Mar 26, 2015
60
61
62
63
64
65
66
/* 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
67
68
69
70
71
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
72
fd_set wr_set, rd_set, ex_set;
May 12, 2012
May 12, 2012
73
int maxfd = sockfd;
Mar 26, 2015
Mar 26, 2015
74
int err;
May 12, 2012
May 12, 2012
75
Feb 6, 2014
Feb 6, 2014
76
set_sock_nonblock(sockfd);
Jan 15, 2014
Jan 15, 2014
77
78
if (vpninfo->protect_socket)
vpninfo->protect_socket(vpninfo->cbdata, sockfd);
May 12, 2012
May 12, 2012
79
Mar 26, 2015
Mar 26, 2015
80
81
82
83
84
85
86
if (connect(sockfd, addr, addrlen) < 0 && !connect_pending()) {
#ifdef _WIN32
return WSAGetLastError();
#else
return -errno;
#endif
}
May 12, 2012
May 12, 2012
87
Jan 15, 2014
Jan 15, 2014
88
89
90
do {
FD_ZERO(&wr_set);
FD_ZERO(&rd_set);
Mar 26, 2015
Mar 26, 2015
91
FD_ZERO(&ex_set);
Jan 15, 2014
Jan 15, 2014
92
FD_SET(sockfd, &wr_set);
Mar 26, 2015
Mar 26, 2015
93
94
95
#ifdef _WIN32 /* Windows indicates failure this way, not in wr_set */
FD_SET(sockfd, &ex_set);
#endif
Jan 15, 2014
Jan 15, 2014
96
cmd_fd_set(vpninfo, &rd_set, &maxfd);
Mar 26, 2015
Mar 26, 2015
97
select(maxfd + 1, &rd_set, &wr_set, &ex_set, NULL);
Jan 15, 2014
Jan 15, 2014
98
99
if (is_cancel_pending(vpninfo, &rd_set)) {
vpn_progress(vpninfo, PRG_ERR, _("Socket connect cancelled\n"));
Mar 26, 2015
Mar 26, 2015
100
return -EINTR;
Jan 15, 2014
Jan 15, 2014
101
}
Mar 26, 2015
Mar 26, 2015
102
103
} while (!FD_ISSET(sockfd, &wr_set) && !FD_ISSET(sockfd, &ex_set) &&
!vpninfo->got_pause_cmd);
Mar 10, 2013
Mar 10, 2013
104
May 12, 2012
May 12, 2012
105
106
/* Check whether connect() succeeded or failed by using
getpeername(). See http://cr.yp.to/docs/connect.html */
Mar 26, 2015
Mar 26, 2015
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
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
129
}
Mar 26, 2015
Mar 26, 2015
130
131
#endif
return err;
May 12, 2012
May 12, 2012
132
133
}
Mar 3, 2014
Mar 3, 2014
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
/* 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
149
150
151
152
153
154
155
156
157
158
159
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
160
161
return !memcmp(&a6->sin6_addr, &b6->sin6_addr, sizeof(a6->sin6_addr)) &&
a6->sin6_port == b6->sin6_port;
Dec 5, 2014
Dec 5, 2014
162
163
164
165
} else
return 0;
}
May 29, 2012
May 29, 2012
166
int connect_https_socket(struct openconnect_info *vpninfo)
Sep 22, 2008
Sep 22, 2008
167
{
Jun 3, 2009
Jun 3, 2009
168
int ssl_sock = -1;
Sep 22, 2008
Sep 22, 2008
169
170
int err;
Dec 23, 2009
Dec 23, 2009
171
172
173
if (!vpninfo->port)
vpninfo->port = 443;
Dec 5, 2014
Dec 5, 2014
174
175
176
177
178
/* 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
179
reconnect:
May 17, 2012
May 17, 2012
180
181
182
183
184
185
#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
186
187
188
189
190
191
if (ssl_sock < 0) {
#ifdef _WIN32
err = WSAGetLastError();
#else
err = -errno;
#endif
May 17, 2012
May 17, 2012
192
goto reconn_err;
Mar 26, 2015
Mar 26, 2015
193
}
Feb 6, 2014
Feb 6, 2014
194
set_fd_cloexec(ssl_sock);
May 17, 2012
May 17, 2012
195
}
Mar 26, 2015
Mar 26, 2015
196
197
198
err = cancellable_connect(vpninfo, ssl_sock, vpninfo->peer_addr, vpninfo->peer_addrlen);
if (err) {
char *errstr;
Dec 7, 2009
Dec 7, 2009
199
reconn_err:
Mar 26, 2015
Mar 26, 2015
200
201
202
203
204
205
#ifdef _WIN32
if (err > 0)
errstr = openconnect__win32_strerror(err);
else
#endif
errstr = strerror(-err);
Sep 22, 2011
Sep 22, 2011
206
if (vpninfo->proxy) {
Sep 26, 2012
Sep 26, 2012
207
vpn_progress(vpninfo, PRG_ERR,
Mar 26, 2015
Mar 26, 2015
208
_("Failed to reconnect to proxy %s: %s\n"),
Mar 26, 2015
Mar 26, 2015
209
vpninfo->proxy, errstr);
Sep 22, 2011
Sep 22, 2011
210
} else {
Sep 26, 2012
Sep 26, 2012
211
vpn_progress(vpninfo, PRG_ERR,
Mar 26, 2015
Mar 26, 2015
212
_("Failed to reconnect to host %s: %s\n"),
Mar 26, 2015
Mar 26, 2015
213
vpninfo->hostname, errstr);
Sep 22, 2011
Sep 22, 2011
214
}
Mar 26, 2015
Mar 26, 2015
215
216
217
218
#ifdef _WIN32
if (err > 0)
free(errstr);
#endif
Sep 26, 2012
Sep 26, 2012
219
if (ssl_sock >= 0)
Feb 6, 2014
Feb 6, 2014
220
closesocket(ssl_sock);
Jul 21, 2014
Jul 21, 2014
221
222
ssl_sock = -EINVAL;
goto out;
Sep 22, 2008
Sep 22, 2008
223
}
Dec 7, 2009
Dec 7, 2009
224
225
} else {
struct addrinfo hints, *result, *rp;
Jan 1, 2010
Jan 1, 2010
226
char *hostname;
Dec 23, 2009
Dec 23, 2009
227
char port[6];
Dec 7, 2009
Dec 7, 2009
228
229
230
231
232
233
234
235
236
237
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
238
239
240
241
/* 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
242
#ifdef LIBPROXY_HDR
Jan 2, 2010
Jan 2, 2010
243
if (vpninfo->proxy_factory) {
Aug 25, 2016
Aug 25, 2016
244
struct oc_text_buf *url_buf = buf_alloc();
Jan 2, 2010
Jan 2, 2010
245
246
247
char **proxies;
int i = 0;
Jan 2, 2010
Jan 2, 2010
248
249
free(vpninfo->proxy_type);
vpninfo->proxy_type = NULL;
Jan 2, 2010
Jan 2, 2010
250
251
252
free(vpninfo->proxy);
vpninfo->proxy = NULL;
Aug 25, 2016
Aug 25, 2016
253
254
255
256
257
258
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
259
260
261
ssl_sock = -ENOMEM;
goto out;
}
Jan 2, 2010
Jan 2, 2010
262
263
proxies = px_proxy_factory_get_proxies(vpninfo->proxy_factory,
Aug 25, 2016
Aug 25, 2016
264
url_buf->data);
Dec 3, 2011
Dec 3, 2011
265
i = 0;
Jan 2, 2010
Jan 2, 2010
266
while (proxies && proxies[i]) {
Jan 2, 2010
Jan 2, 2010
267
268
269
270
if (!vpninfo->proxy &&
(!strncmp(proxies[i], "http://", 7) ||
!strncmp(proxies[i], "socks://", 8) ||
!strncmp(proxies[i], "socks5://", 9)))
Mar 9, 2011
Mar 9, 2011
271
internal_parse_url(proxies[i], &vpninfo->proxy_type,
Jan 2, 2010
Jan 2, 2010
272
273
&vpninfo->proxy, &vpninfo->proxy_port,
NULL, 0);
Jan 2, 2010
Jan 2, 2010
274
275
i++;
}
Aug 25, 2016
Aug 25, 2016
276
buf_free(url_buf);
Jan 2, 2010
Jan 2, 2010
277
278
free(proxies);
if (vpninfo->proxy)
Jun 13, 2014
Jun 13, 2014
279
vpn_progress(vpninfo, PRG_DEBUG,
Sep 22, 2011
Sep 22, 2011
280
281
_("Proxy from libproxy: %s://%s:%d/\n"),
vpninfo->proxy_type, vpninfo->proxy, vpninfo->port);
Jan 2, 2010
Jan 2, 2010
282
283
}
#endif
Jan 1, 2010
Jan 1, 2010
284
285
if (vpninfo->proxy) {
hostname = vpninfo->proxy;
Feb 22, 2010
Feb 22, 2010
286
snprintf(port, 6, "%d", vpninfo->proxy_port);
Jan 1, 2010
Jan 1, 2010
287
288
} else {
hostname = vpninfo->hostname;
Feb 22, 2010
Feb 22, 2010
289
snprintf(port, 6, "%d", vpninfo->port);
Jan 1, 2010
Jan 1, 2010
290
291
}
Jan 1, 2010
Jan 1, 2010
292
if (hostname[0] == '[' && hostname[strlen(hostname)-1] == ']') {
Jul 3, 2014
Jul 3, 2014
293
hostname = strndup(hostname + 1, strlen(hostname) - 2);
Jul 21, 2014
Jul 21, 2014
294
295
296
297
if (!hostname) {
ssl_sock = -ENOMEM;
goto out;
}
Jan 1, 2010
Jan 1, 2010
298
299
300
hints.ai_flags |= AI_NUMERICHOST;
}
Mar 26, 2015
Mar 26, 2015
301
302
303
304
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
305
Dec 7, 2009
Dec 7, 2009
306
if (err) {
Sep 22, 2011
Sep 22, 2011
307
308
309
vpn_progress(vpninfo, PRG_ERR,
_("getaddrinfo failed for host '%s': %s\n"),
hostname, gai_strerror(err));
Sep 26, 2012
Sep 26, 2012
310
311
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
Jul 21, 2014
Jul 21, 2014
312
ssl_sock = -EINVAL;
Dec 5, 2014
Dec 5, 2014
313
314
315
316
317
318
319
/* 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
320
goto out;
Dec 7, 2009
Dec 7, 2009
321
}
Sep 26, 2012
Sep 26, 2012
322
323
if (hints.ai_flags & AI_NUMERICHOST)
free(hostname);
Dec 7, 2009
Dec 7, 2009
324
325
for (rp = result; rp ; rp = rp->ai_next) {
Jan 1, 2010
Jan 1, 2010
326
327
char host[80];
Feb 4, 2013
Feb 4, 2013
328
host[0] = 0;
Jan 1, 2010
Jan 1, 2010
329
330
if (!getnameinfo(rp->ai_addr, rp->ai_addrlen, host,
sizeof(host), NULL, 0, NI_NUMERICHOST))
Mar 26, 2015
Mar 26, 2015
331
vpn_progress(vpninfo, PRG_DEBUG, vpninfo->proxy_type ?
Mar 10, 2013
Mar 10, 2013
332
_("Attempting to connect to proxy %s%s%s:%s\n") :
Sep 23, 2012
Sep 23, 2012
333
_("Attempting to connect to server %s%s%s:%s\n"),
Mar 10, 2013
Mar 10, 2013
334
rp->ai_family == AF_INET6 ? "[" : "",
Sep 22, 2011
Sep 22, 2011
335
host,
Mar 10, 2013
Mar 10, 2013
336
rp->ai_family == AF_INET6 ? "]" : "",
Sep 22, 2011
Sep 22, 2011
337
port);
Sep 23, 2012
Sep 23, 2012
338
Dec 7, 2009
Dec 7, 2009
339
340
341
342
ssl_sock = socket(rp->ai_family, rp->ai_socktype,
rp->ai_protocol);
if (ssl_sock < 0)
continue;
Feb 6, 2014
Feb 6, 2014
343
set_fd_cloexec(ssl_sock);
Mar 26, 2015
Mar 26, 2015
344
345
err = cancellable_connect(vpninfo, ssl_sock, rp->ai_addr, rp->ai_addrlen);
if (!err) {
Dec 7, 2009
Dec 7, 2009
346
347
/* Store the peer address we actually used, so that DTLS can
use it again later */
Mar 8, 2016
Mar 8, 2016
348
349
350
351
352
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
353
354
355
356
357
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
358
}
Mar 26, 2015
Mar 26, 2015
359
Dec 5, 2014
Dec 5, 2014
360
361
free(vpninfo->peer_addr);
vpninfo->peer_addrlen = 0;
Dec 7, 2009
Dec 7, 2009
362
363
vpninfo->peer_addr = malloc(rp->ai_addrlen);
if (!vpninfo->peer_addr) {
Sep 22, 2011
Sep 22, 2011
364
365
vpn_progress(vpninfo, PRG_ERR,
_("Failed to allocate sockaddr storage\n"));
Feb 6, 2014
Feb 6, 2014
366
closesocket(ssl_sock);
Jul 21, 2014
Jul 21, 2014
367
368
ssl_sock = -ENOMEM;
goto out;
Dec 7, 2009
Dec 7, 2009
369
370
371
}
vpninfo->peer_addrlen = rp->ai_addrlen;
memcpy(vpninfo->peer_addr, rp->ai_addr, rp->ai_addrlen);
Jan 7, 2015
Jan 7, 2015
372
373
374
375
376
377
378
379
380
381
382
/* 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
383
char *p = malloc(strlen(host) + 3);
Feb 4, 2013
Feb 4, 2013
384
if (p) {
Feb 22, 2013
Feb 22, 2013
385
386
free(vpninfo->unique_hostname);
vpninfo->unique_hostname = p;
Feb 4, 2013
Feb 4, 2013
387
388
389
390
391
392
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
393
*p = 0;
Feb 4, 2013
Feb 4, 2013
394
395
}
}
Dec 7, 2009
Dec 7, 2009
396
397
break;
}
Mar 26, 2015
Mar 26, 2015
398
399
400
401
402
403
404
405
406
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
407
408
409
410
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
411
412
413
414
415
416
port, errstr);
#ifdef _WIN32
if (err > 0)
free(errstr);
#endif
}
Feb 6, 2014
Feb 6, 2014
417
closesocket(ssl_sock);
Dec 7, 2009
Dec 7, 2009
418
ssl_sock = -1;
Dec 5, 2014
Dec 5, 2014
419
420
421
422
423
424
425
426
427
428
/* 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
429
430
free(vpninfo->ip_info.gateway_addr);
vpninfo->ip_info.gateway_addr = NULL;
Dec 5, 2014
Dec 5, 2014
431
}
Dec 7, 2009
Dec 7, 2009
432
433
}
freeaddrinfo(result);
Mar 10, 2013
Mar 10, 2013
434
Dec 7, 2009
Dec 7, 2009
435
if (ssl_sock < 0) {
Sep 22, 2011
Sep 22, 2011
436
437
438
vpn_progress(vpninfo, PRG_ERR,
_("Failed to connect to host %s\n"),
vpninfo->proxy?:vpninfo->hostname);
Jul 21, 2014
Jul 21, 2014
439
ssl_sock = -EINVAL;
Dec 5, 2014
Dec 5, 2014
440
441
442
443
444
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
445
goto out;
Dec 7, 2009
Dec 7, 2009
446
}
Sep 22, 2008
Sep 22, 2008
447
448
}
Jan 1, 2010
Jan 1, 2010
449
if (vpninfo->proxy) {
Jan 2, 2010
Jan 2, 2010
450
err = process_proxy(vpninfo, ssl_sock);
Jan 1, 2010
Jan 1, 2010
451
if (err) {
Feb 6, 2014
Feb 6, 2014
452
closesocket(ssl_sock);
Jun 20, 2014
Jun 20, 2014
453
454
455
456
457
458
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
459
ssl_sock = err;
Jan 1, 2010
Jan 1, 2010
460
461
}
}
Jul 21, 2014
Jul 21, 2014
462
463
464
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
465
clear_auth_states(vpninfo, vpninfo->proxy_auth, 1);
May 29, 2012
May 29, 2012
466
467
468
return ssl_sock;
}
May 31, 2012
May 31, 2012
469
470
471
472
473
474
475
476
477
478
479
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
480
return vpninfo->ssl_write(vpninfo, buf, strlen(buf));
May 31, 2012
May 31, 2012
481
482
483
}
Oct 29, 2014
Oct 29, 2014
484
485
int __attribute__ ((format(printf, 4, 5)))
request_passphrase(struct openconnect_info *vpninfo, const char *label,
Jun 4, 2012
Jun 4, 2012
486
487
488
489
490
491
492
493
494
495
496
497
498
499
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
500
f.auth_id = (char *)label;
Jun 4, 2012
Jun 4, 2012
501
502
503
504
f.opts = &o;
o.next = NULL;
o.type = OC_FORM_OPT_PASSWORD;
Jun 13, 2012
Jun 13, 2012
505
o.name = (char *)label;
Jun 4, 2012
Jun 4, 2012
506
o.label = buf;
Oct 9, 2014
Oct 9, 2014
507
o._value = NULL;
Jun 4, 2012
Jun 4, 2012
508
Jan 15, 2014
Jan 15, 2014
509
ret = process_auth_form(vpninfo, &f);
Jun 4, 2012
Jun 4, 2012
510
if (!ret) {
Oct 9, 2014
Oct 9, 2014
511
*response = o._value;
Jun 4, 2012
Jun 4, 2012
512
513
514
515
516
517
return 0;
}
return -EIO;
}
May 7, 2010
May 7, 2010
518
#if defined(__sun__) || defined(__NetBSD__) || defined(__DragonFly__)
Nov 16, 2010
Nov 16, 2010
519
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
Nov 3, 2009
Nov 3, 2009
520
521
{
struct statvfs buf;
Jul 31, 2014
Jul 31, 2014
522
523
char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey);
int err = 0;
Nov 3, 2009
Nov 3, 2009
524
Jul 31, 2014
Jul 31, 2014
525
526
if (statvfs(sslkey, &buf)) {
err = -errno;
Sep 22, 2011
Sep 22, 2011
527
528
vpn_progress(vpninfo, PRG_ERR, _("statvfs: %s\n"),
strerror(errno));
Jul 31, 2014
Jul 31, 2014
529
} else if (asprintf(&vpninfo->cert_password, "%lx", buf.f_fsid) == -1)
Jul 31, 2014
Jul 31, 2014
530
531
532
533
534
err = -ENOMEM;
if (sslkey != vpninfo->sslkey)
free(sslkey);
return err;
Nov 3, 2009
Nov 3, 2009
535
}
Feb 6, 2014
Feb 6, 2014
536
537
#elif defined(_WIN32)
#include <fileapi.h>
Jul 25, 2014
Jul 25, 2014
538
539
typedef BOOL WINAPI (*GVIBH)(HANDLE, LPWSTR, DWORD, LPDWORD, LPDWORD, LPDWORD, LPWSTR, DWORD);
Feb 6, 2014
Feb 6, 2014
540
541
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
{
Feb 12, 2014
Feb 12, 2014
542
HANDLE h;
Feb 6, 2014
Feb 6, 2014
543
DWORD serial;
Jul 25, 2014
Jul 25, 2014
544
545
HINSTANCE kernlib;
GVIBH func = NULL;
Feb 12, 2014
Feb 12, 2014
546
int success;
Jul 31, 2014
Jul 31, 2014
547
int fd;
Feb 6, 2014
Feb 6, 2014
548
Jul 25, 2014
Jul 25, 2014
549
550
551
552
553
554
555
556
557
558
559
560
561
562
/* 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
563
fd = openconnect_open_utf8(vpninfo, vpninfo->sslkey, O_RDONLY);
Jul 31, 2014
Jul 31, 2014
564
565
566
567
568
569
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
570
Jul 31, 2014
Jul 31, 2014
571
h = (HANDLE)_get_osfhandle(fd);
Jul 25, 2014
Jul 25, 2014
572
success = func(h, NULL, 0, &serial, NULL, NULL, NULL, 0);
Jul 31, 2014
Jul 31, 2014
573
close(fd);
Feb 12, 2014
Feb 12, 2014
574
575
if (!success)
Feb 6, 2014
Feb 6, 2014
576
577
return -EIO;
Jul 31, 2014
Jul 31, 2014
578
if (asprintf(&vpninfo->cert_password, "%lx", serial) == -1)
Feb 6, 2014
Feb 6, 2014
579
580
return -ENOMEM;
Feb 12, 2014
Feb 12, 2014
581
return 0;
Feb 6, 2014
Feb 6, 2014
582
}
Mar 8, 2016
Mar 8, 2016
583
#elif defined(HAVE_STATFS)
Nov 16, 2010
Nov 16, 2010
584
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
May 28, 2009
May 28, 2009
585
{
Jul 31, 2014
Jul 31, 2014
586
char *sslkey = openconnect_utf8_to_legacy(vpninfo, vpninfo->sslkey);
May 28, 2009
May 28, 2009
587
588
589
struct statfs buf;
unsigned *fsid = (unsigned *)&buf.f_fsid;
unsigned long long fsid64;
Jul 31, 2014
Jul 31, 2014
590
int err = 0;
May 28, 2009
May 28, 2009
591
Jul 31, 2014
Jul 31, 2014
592
593
if (statfs(sslkey, &buf)) {
err = -errno;
Sep 22, 2011
Sep 22, 2011
594
595
vpn_progress(vpninfo, PRG_ERR, _("statfs: %s\n"),
strerror(errno));
May 28, 2009
May 28, 2009
596
return -err;
Jul 31, 2014
Jul 31, 2014
597
598
599
} else {
fsid64 = ((unsigned long long)fsid[0] << 32) | fsid[1];
Jul 31, 2014
Jul 31, 2014
600
if (asprintf(&vpninfo->cert_password, "%llx", fsid64) == -1)
Jul 31, 2014
Jul 31, 2014
601
err = -ENOMEM;
May 28, 2009
May 28, 2009
602
}
Nov 6, 2009
Nov 6, 2009
603
Jul 31, 2014
Jul 31, 2014
604
605
606
607
if (sslkey != vpninfo->sslkey)
free(sslkey);
return err;
May 28, 2009
May 28, 2009
608
}
Mar 8, 2016
Mar 8, 2016
609
610
611
612
613
#else
int openconnect_passphrase_from_fsid(struct openconnect_info *vpninfo)
{
return -EOPNOTSUPP;
}
Nov 3, 2009
Nov 3, 2009
614
#endif
Jun 11, 2012
Jun 11, 2012
615
Sep 10, 2016
Sep 10, 2016
616
#if defined(OPENCONNECT_OPENSSL)
Jun 11, 2012
Jun 11, 2012
617
618
/* 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
619
int openconnect_print_err_cb(const char *str, size_t len, void *ptr)
Jun 11, 2012
Jun 11, 2012
620
621
622
623
624
625
626
{
struct openconnect_info *vpninfo = ptr;
vpn_progress(vpninfo, PRG_ERR, "%s", str);
return 0;
}
#endif
Jun 17, 2012
Jun 17, 2012
627
628
629
630
631
632
633
634
635
636
637
638
639
640
641
642
643
644
645
646
647
648
649
#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
650
data = malloc(st.st_size + 1);
Jun 17, 2012
Jun 17, 2012
651
652
653
654
655
656
657
658
659
660
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
661
662
data[st.st_size] = 0;
Jun 17, 2012
Jun 17, 2012
663
664
665
666
667
668
*result = data;
ret = st.st_size;
out_fd:
close(fd);
return ret;
}
Mar 10, 2013
Mar 10, 2013
669
#elif defined(ANDROID_KEYSTORE)
Mar 3, 2013
Mar 3, 2013
670
671
672
673
674
675
676
677
678
679
680
681
682
/* 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
683
684
685
{
switch (-err) {
case NO_ERROR: return _("No error");
Oct 17, 2012
Oct 17, 2012
686
case LOCKED: return _("Keystore locked");
Jun 17, 2012
Jun 17, 2012
687
688
689
690
691
692
693
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
694
695
696
697
case WRONG_PASSWORD:
case WRONG_PASSWORD+1:
case WRONG_PASSWORD+2:
case WRONG_PASSWORD+3: return _("Wrong password");
Jun 17, 2012
Jun 17, 2012
698
699
700
701
702
703
704
705
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
706
707
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
708
709
unsigned char *data, *p;
unsigned char buf[3];
Mar 6, 2013
Mar 6, 2013
710
int len, fd;
Jun 17, 2012
Jun 17, 2012
711
712
int ret = -SYSTEM_ERROR;
Mar 3, 2013
Mar 3, 2013
713
fd = socket(AF_UNIX, SOCK_STREAM, 0);
Jun 17, 2012
Jun 17, 2012
714
715
716
if (fd < 0)
return -SYSTEM_ERROR;
Mar 3, 2013
Mar 3, 2013
717
718
719
720
if (connect(fd, (void *)&sa, sl)) {
close(fd);
return -SYSTEM_ERROR;
}
Jun 17, 2012
Jun 17, 2012
721
722
len = strlen(key);
buf[0] = 'g';
Jan 26, 2015
Jan 26, 2015
723
store_be16(buf + 1, len);
Jun 17, 2012
Jun 17, 2012
724
725
726
727
728
729
730
731
732
733
734
735
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
736
len = load_be16(buf);
Jun 17, 2012
Jun 17, 2012
737
738
739
740
741
742
743
744
745
746
747
748
749
750
751
752
753
754
755
756
757
758
759
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
760
761
762
void cmd_fd_set(struct openconnect_info *vpninfo, fd_set *fds, int *maxfd)
{
Jan 15, 2014
Jan 15, 2014
763
764
765
766
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
767
768
769
}
}
Jan 15, 2014
Jan 15, 2014
770
771
772
773
774
775
776
777
778
779
780
781
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
782
#ifdef _WIN32
Sep 15, 2014
Sep 15, 2014
783
if (recv(vpninfo->cmd_fd, &cmd, 1, 0) != 1)
Jan 15, 2014
Jan 15, 2014
784
return;
Oct 22, 2014
Oct 22, 2014
785
786
787
788
#else
if (read(vpninfo->cmd_fd, &cmd, 1) != 1)
return;
#endif
Jan 15, 2014
Jan 15, 2014
789
790
switch (cmd) {
case OC_CMD_CANCEL:
Jun 13, 2014
Jun 13, 2014
791
case OC_CMD_DETACH:
Jan 15, 2014
Jan 15, 2014
792
vpninfo->got_cancel_cmd = 1;
Jun 13, 2014
Jun 13, 2014
793
vpninfo->cancel_type = cmd;
Jan 15, 2014
Jan 15, 2014
794
break;
Jan 15, 2014
Jan 15, 2014
795
796
797
case OC_CMD_PAUSE:
vpninfo->got_pause_cmd = 1;
break;
Jan 15, 2014
Jan 15, 2014
798
799
800
case OC_CMD_STATS:
if (vpninfo->stats_handler)
vpninfo->stats_handler(vpninfo->cbdata, &vpninfo->stats);
Jan 15, 2014
Jan 15, 2014
801
802
803
}
}
Jan 15, 2014
Jan 15, 2014
804
805
int is_cancel_pending(struct openconnect_info *vpninfo, fd_set *fds)
{
Jan 15, 2014
Jan 15, 2014
806
check_cmd_fd(vpninfo, fds);
May 6, 2016
May 6, 2016
807
return vpninfo->got_cancel_cmd || vpninfo->got_pause_cmd;
Jan 15, 2014
Jan 15, 2014
808
809
810
811
812
813
}
void poll_cmd_fd(struct openconnect_info *vpninfo, int timeout)
{
fd_set rd_set;
int maxfd = 0;
Feb 17, 2014
Feb 17, 2014
814
time_t expiration = time(NULL) + timeout, now = 0;
Jan 15, 2014
Jan 15, 2014
815
Feb 17, 2014
Feb 17, 2014
816
while (now < expiration && !vpninfo->got_cancel_cmd && !vpninfo->got_pause_cmd) {
Mar 7, 2014
Mar 7, 2014
817
struct timeval tv;
Jan 15, 2014
Jan 15, 2014
818
819
820
now = time(NULL);
tv.tv_sec = now >= expiration ? 0 : expiration - now;
Mar 7, 2014
Mar 7, 2014
821
tv.tv_usec = 0;
Jan 15, 2014
Jan 15, 2014
822
Jan 15, 2014
Jan 15, 2014
823
824
825
826
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
827
}
Jan 15, 2014
Jan 15, 2014
828
}
Jul 31, 2014
Jul 31, 2014
829
830
#ifdef _WIN32
Aug 3, 2014
Aug 3, 2014
831
832
#include <io.h>
#include <sys/stat.h>
Aug 3, 2014
Aug 3, 2014
833
int openconnect_open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
Jul 31, 2014
Jul 31, 2014
834
835
836
837
838
839
840
841
842
843
844
845
846
847
848
849
{
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
850
fd = _wopen(fname_w, mode, _S_IREAD | _S_IWRITE);
Jul 31, 2014
Jul 31, 2014
851
852
853
854
855
free(fname_w);
return fd;
}
#else
Aug 3, 2014
Aug 3, 2014
856
int openconnect_open_utf8(struct openconnect_info *vpninfo, const char *fname, int mode)
Jul 31, 2014
Jul 31, 2014
857
858
859
860
{
char *legacy_fname = openconnect_utf8_to_legacy(vpninfo, fname);
int fd;
Aug 3, 2014
Aug 3, 2014
861
fd = open(legacy_fname, mode, 0644);
Jul 31, 2014
Jul 31, 2014
862
863
864
865
866
867
868
if (legacy_fname != fname)
free(legacy_fname);
return fd;
}
#endif
Aug 3, 2014
Aug 3, 2014
869
870
FILE *openconnect_fopen_utf8(struct openconnect_info *vpninfo, const char *fname,
const char *mode)
Jul 31, 2014
Jul 31, 2014
871
872
{
int fd;
Aug 3, 2014
Aug 3, 2014
873
874
875
876
877
878
879
880
881
882
883
884
885
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
886
vpn_progress(vpninfo, PRG_ERR,
Aug 3, 2014
Aug 3, 2014
887
_("openconnect_fopen_utf8() used with unsupported mode '%s'\n"),
Jul 31, 2014
Jul 31, 2014
888
889
890
891
mode);
return NULL;
}
Aug 3, 2014
Aug 3, 2014
892
fd = openconnect_open_utf8(vpninfo, fname, flags);
Jul 31, 2014
Jul 31, 2014
893
894
895
896
897
if (fd == -1)
return NULL;
return fdopen(fd, mode);
}
Jan 26, 2015
Jan 26, 2015
898
899
900
int udp_sockaddr(struct openconnect_info *vpninfo, int port)
{
Mar 14, 2015
Mar 14, 2015
901
free(vpninfo->dtls_addr);
Jan 26, 2015
Jan 26, 2015
902
903
904
905
906
907
908
909
910
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
911
912
vpninfo->dtls_tos_proto = IPPROTO_IP;
vpninfo->dtls_tos_optname = IP_TOS;
Jan 26, 2015
Jan 26, 2015
913
914
915
} else if (vpninfo->peer_addr->sa_family == AF_INET6) {
struct sockaddr_in6 *sin = (void *)vpninfo->dtls_addr;
sin->sin6_port = htons(port);
Aug 25, 2016
Aug 25, 2016
916
917
vpninfo->dtls_tos_proto = IPPROTO_IPV6;
vpninfo->dtls_tos_optname = IPV6_TCLASS;
Jan 26, 2015
Jan 26, 2015
918
919
920
921
922
923
924
} 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
925
926
927
928
929
/* 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
930
931
return 0;
}
Jan 26, 2015
Jan 26, 2015
932
933
934
935
936
937
938
939
940
941
942
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
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;
}
set_fd_cloexec(fd);
set_sock_nonblock(fd);
return fd;
}
Feb 2, 2015
Feb 2, 2015
995
996
997
998
999
1000
int ssl_reconnect(struct openconnect_info *vpninfo)
{
int ret;
int timeout;
int interval;