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