Update translations from Transifex
[platform/upstream/openconnect.git] / dtls.c
1 /*
2  * OpenConnect (SSL + DTLS) VPN client
3  *
4  * Copyright © 2008-2012 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  * You should have received a copy of the GNU Lesser General Public
18  * License along with this library; if not, write to:
19  *
20  *   Free Software Foundation, Inc.
21  *   51 Franklin Street, Fifth Floor,
22  *   Boston, MA 02110-1301 USA
23  */
24
25 #include <errno.h>
26 #include <sys/types.h>
27 #include <sys/socket.h>
28 #include <netdb.h>
29 #include <unistd.h>
30 #include <netinet/in.h>
31 #include <fcntl.h>
32 #include <string.h>
33 #include <errno.h>
34 #include <stdlib.h>
35 #include <stdio.h>
36
37 #include "openconnect-internal.h"
38
39 static unsigned char nybble(unsigned char n)
40 {
41         if      (n >= '0' && n <= '9') return n - '0';
42         else if (n >= 'A' && n <= 'F') return n - ('A' - 10);
43         else if (n >= 'a' && n <= 'f') return n - ('a' - 10);
44         return 0;
45 }
46
47 unsigned char unhex(const char *data)
48 {
49         return (nybble(data[0]) << 4) | nybble(data[1]);
50 }
51
52 #ifdef HAVE_DTLS
53
54 #if 0
55 /*
56  * Useful for catching test cases, where we want everything to be
57  * reproducible.  *NEVER* do this in the wild.
58  */
59 time_t time(time_t *t)
60 {
61         time_t x = 0x3ab2d948;
62         if (t) *t = x;
63         return x;
64 }
65
66 int RAND_pseudo_bytes(char *buf, int len)
67 {
68         memset(buf, 0x5a, len);
69         printf("FAKE PSEUDO RANDOM!\n");
70         return 1;
71
72 }
73 int RAND_bytes(char *buf, int len)
74 {
75         static int foo = 0x5b;
76         printf("FAKE RANDOM!\n");
77         memset(buf, foo, len);
78         return 1;
79 }
80 #endif
81
82 /*
83  * The master-secret is generated randomly by the client. The server
84  * responds with a DTLS Session-ID. These, done over the HTTPS
85  * connection, are enough to 'resume' a DTLS session, bypassing all
86  * the normal setup of a normal DTLS connection.
87  *
88  * Cisco use a version of the protocol which predates RFC4347, but
89  * isn't quite the same as the pre-RFC version of the protocol which
90  * was in OpenSSL 0.9.8e -- it includes backports of some later
91  * OpenSSL patches.
92  *
93  * The openssl/ directory of this source tree should contain both a
94  * small patch against OpenSSL 0.9.8e to make it support Cisco's
95  * snapshot of the protocol, and a larger patch against newer OpenSSL
96  * which gives us an option to use the old protocol again.
97  *
98  * Cisco's server also seems to respond to the official version of the
99  * protocol, with a change in the ChangeCipherSpec packet which implies
100  * that it does know the difference and isn't just repeating the version
101  * number seen in the ClientHello. But although I can make the handshake
102  * complete by hacking tls1_mac() to use the _old_ protocol version
103  * number when calculating the MAC, the server still seems to be ignoring
104  * my subsequent data packets. So we use the old protocol, which is what
105  * their clients use anyway.
106  */
107
108 #if defined (DTLS_OPENSSL)
109 #define DTLS_SEND SSL_write
110 #define DTLS_RECV SSL_read
111
112 #ifdef HAVE_DTLS1_STOP_TIMER
113 /* OpenSSL doesn't deliberately export this, but we need it to
114    workaround a DTLS bug in versions < 1.0.0e */
115 extern void dtls1_stop_timer (SSL *);
116 #endif
117
118 static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
119 {
120         STACK_OF(SSL_CIPHER) *ciphers;
121         method_const SSL_METHOD *dtls_method;
122         SSL_CIPHER *dtls_cipher;
123         SSL *dtls_ssl;
124         BIO *dtls_bio;
125
126         if (!vpninfo->dtls_ctx) {
127                 dtls_method = DTLSv1_client_method();
128                 vpninfo->dtls_ctx = SSL_CTX_new(dtls_method);
129                 if (!vpninfo->dtls_ctx) {
130                         vpn_progress(vpninfo, PRG_ERR,
131                                      _("Initialise DTLSv1 CTX failed\n"));
132                         openconnect_report_ssl_errors(vpninfo);
133                         vpninfo->dtls_attempt_period = 0;
134                         return -EINVAL;
135                 }
136
137                 /* If we don't readahead, then we do short reads and throw
138                    away the tail of data packets. */
139                 SSL_CTX_set_read_ahead(vpninfo->dtls_ctx, 1);
140
141                 if (!SSL_CTX_set_cipher_list(vpninfo->dtls_ctx, vpninfo->dtls_cipher)) {
142                         vpn_progress(vpninfo, PRG_ERR,
143                                      _("Set DTLS cipher list failed\n"));
144                         SSL_CTX_free(vpninfo->dtls_ctx);
145                         vpninfo->dtls_ctx = NULL;
146                         vpninfo->dtls_attempt_period = 0;
147                         return -EINVAL;
148                 }
149         }
150
151         if (!vpninfo->dtls_session) {
152                 /* We're going to "resume" a session which never existed. Fake it... */
153                 vpninfo->dtls_session = SSL_SESSION_new();
154                 if (!vpninfo->dtls_session) {
155                         vpn_progress(vpninfo, PRG_ERR,
156                                      _("Initialise DTLSv1 session failed\n"));
157                         vpninfo->dtls_attempt_period = 0;
158                         return -EINVAL;
159                 }
160                 vpninfo->dtls_session->ssl_version = 0x0100; /* DTLS1_BAD_VER */
161         }
162
163         /* Do this every time; it may have changed due to a rekey */
164         vpninfo->dtls_session->master_key_length = sizeof(vpninfo->dtls_secret);
165         memcpy(vpninfo->dtls_session->master_key, vpninfo->dtls_secret,
166                sizeof(vpninfo->dtls_secret));
167
168         vpninfo->dtls_session->session_id_length = sizeof(vpninfo->dtls_session_id);
169         memcpy(vpninfo->dtls_session->session_id, vpninfo->dtls_session_id,
170                sizeof(vpninfo->dtls_session_id));
171
172         dtls_ssl = SSL_new(vpninfo->dtls_ctx);
173         SSL_set_connect_state(dtls_ssl);
174
175         ciphers = SSL_get_ciphers(dtls_ssl);
176         if (sk_SSL_CIPHER_num(ciphers) != 1) {
177                 vpn_progress(vpninfo, PRG_ERR, _("Not precisely one DTLS cipher\n"));
178                 SSL_CTX_free(vpninfo->dtls_ctx);
179                 SSL_free(dtls_ssl);
180                 SSL_SESSION_free(vpninfo->dtls_session);
181                 vpninfo->dtls_ctx = NULL;
182                 vpninfo->dtls_session = NULL;
183                 vpninfo->dtls_attempt_period = 0;
184                 return -EINVAL;
185         }
186         dtls_cipher = sk_SSL_CIPHER_value(ciphers, 0);
187
188         /* Set the appropriate cipher on our session to be resumed */
189         vpninfo->dtls_session->cipher = dtls_cipher;
190         vpninfo->dtls_session->cipher_id = dtls_cipher->id;
191
192         /* Add the generated session to the SSL */
193         if (!SSL_set_session(dtls_ssl, vpninfo->dtls_session)) {
194                 vpn_progress(vpninfo, PRG_ERR,
195                              _("SSL_set_session() failed with old protocol version 0x%x\n"
196                                "Are you using a version of OpenSSL older than 0.9.8m?\n"
197                                "See http://rt.openssl.org/Ticket/Display.html?id=1751\n"
198                                "Use the --no-dtls command line option to avoid this message\n"),
199                              vpninfo->dtls_session->ssl_version);
200                 vpninfo->dtls_attempt_period = 0;
201                 return -EINVAL;
202         }
203
204         dtls_bio = BIO_new_socket(dtls_fd, BIO_NOCLOSE);
205         /* Set non-blocking */
206         BIO_set_nbio(dtls_bio, 1);
207         SSL_set_bio(dtls_ssl, dtls_bio, dtls_bio);
208
209         SSL_set_options(dtls_ssl, SSL_OP_CISCO_ANYCONNECT);
210
211         vpninfo->new_dtls_ssl = dtls_ssl;
212
213         return 0;
214 }
215
216 int dtls_try_handshake(struct openconnect_info *vpninfo)
217 {
218         int ret = SSL_do_handshake(vpninfo->new_dtls_ssl);
219
220         if (ret == 1) {
221                 vpn_progress(vpninfo, PRG_INFO, _("Established DTLS connection (using OpenSSL)\n"));
222
223                 if (vpninfo->dtls_ssl) {
224                         /* We are replacing an old connection */
225                         SSL_free(vpninfo->dtls_ssl);
226                         close(vpninfo->dtls_fd);
227                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
228                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
229                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
230                 }
231                 vpninfo->dtls_ssl = vpninfo->new_dtls_ssl;
232                 vpninfo->dtls_fd = vpninfo->new_dtls_fd;
233
234                 vpninfo->new_dtls_ssl = NULL;
235                 vpninfo->new_dtls_fd = -1;
236
237                 vpninfo->dtls_times.last_rx = vpninfo->dtls_times.last_tx = time(NULL);
238
239                 /* From about 8.4.1(11) onwards, the ASA seems to get
240                    very unhappy if we resend ChangeCipherSpec messages
241                    after the initial setup. This was "fixed" in OpenSSL
242                    1.0.0e for RT#2505, but it's not clear if that was
243                    the right fix. What happens if the original packet
244                    *does* get lost? Surely we *wanted* the retransmits,
245                    because without them the server will never be able
246                    to decrypt anything we send?
247                    Oh well, our retransmitted packets upset the server
248                    because we don't get the Cisco-compatibility right
249                    (this is one of the areas in which Cisco's DTLS differs
250                    from the RFC4347 spec), and DPD should help us notice
251                    if *nothing* is getting through. */
252 #if OPENSSL_VERSION_NUMBER >= 0x1000005fL
253                 /* OpenSSL 1.0.0e or above doesn't resend anyway; do nothing.
254                    However, if we were *built* against 1.0.0e or newer, but at
255                    runtime we find that we are being run against an older 
256                    version, warn about it. */
257                 if (SSLeay() < 0x1000005fL) {
258                         vpn_progress(vpninfo, PRG_ERR,
259                                      _("Your OpenSSL is older than the one you built against, so DTLS may fail!"));
260                 }
261 #elif defined (HAVE_DTLS1_STOP_TIMER)
262                 /*
263                  * This works for any normal OpenSSL that supports
264                  * Cisco DTLS compatibility (0.9.8m to 1.0.0d inclusive,
265                  * and even later versions although it isn't needed there.
266                  */
267                 dtls1_stop_timer(vpninfo->dtls_ssl);
268 #elif defined (BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT)
269                 /*
270                  * Debian restricts visibility of dtls1_stop_timer()
271                  * so do it manually. This version also works on all
272                  * sane versions of OpenSSL:
273                  */
274                 memset (&(vpninfo->dtls_ssl->d1->next_timeout), 0,
275                         sizeof((vpninfo->dtls_ssl->d1->next_timeout)));
276                 vpninfo->dtls_ssl->d1->timeout_duration = 1;
277                 BIO_ctrl(SSL_get_rbio(vpninfo->dtls_ssl),
278                          BIO_CTRL_DGRAM_SET_NEXT_TIMEOUT, 0,
279                          &(vpninfo->dtls_ssl->d1->next_timeout));
280 #elif defined (BIO_CTRL_DGRAM_SET_TIMEOUT)
281                 /*
282                  * OK, here it gets more fun... this shoul handle the case
283                  * of older OpenSSL which has the Cisco DTLS compatibility
284                  * backported, but *not* the fix for RT#1922.
285                  */
286                 BIO_ctrl(SSL_get_rbio(vpninfo->dtls_ssl),
287                          BIO_CTRL_DGRAM_SET_TIMEOUT, 0, NULL);
288 #else
289                 /*
290                  * And if they don't have any of the above, they probably
291                  * don't have RT#1829 fixed either, but that's OK because
292                  * that's the "fix" that *introduces* the timeout we're
293                  * trying to disable. So do nothing...
294                  */
295 #endif
296                 return 0;
297         }
298
299         ret = SSL_get_error(vpninfo->new_dtls_ssl, ret);
300         if (ret == SSL_ERROR_WANT_WRITE || ret == SSL_ERROR_WANT_READ) {
301                 if (time(NULL) < vpninfo->new_dtls_started + 5)
302                         return 0;
303                 vpn_progress(vpninfo, PRG_TRACE, _("DTLS handshake timed out\n"));
304         }
305
306         vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %d\n"), ret);
307         openconnect_report_ssl_errors(vpninfo);
308
309         /* Kill the new (failed) connection... */
310         SSL_free(vpninfo->new_dtls_ssl);
311         FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_rfds);
312         FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_efds);
313         close(vpninfo->new_dtls_fd);
314         vpninfo->new_dtls_ssl = NULL;
315         vpninfo->new_dtls_fd = -1;
316
317         /* ... and kill the old one too. The only time there'll be a valid
318            existing session is when it was a rekey, and in that case it's
319            time for the old one to die. */
320         if (vpninfo->dtls_ssl) {
321                 SSL_free(vpninfo->dtls_ssl);
322                 close(vpninfo->dtls_fd);
323                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
324                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
325                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
326                 vpninfo->dtls_ssl = NULL;
327                 vpninfo->dtls_fd = -1;
328         }
329
330         time(&vpninfo->new_dtls_started);
331         return -EINVAL;
332 }
333
334 #elif defined (DTLS_GNUTLS)
335 #include <gnutls/dtls.h>
336
337 struct {
338         const char *name;
339         gnutls_cipher_algorithm_t cipher;
340         gnutls_mac_algorithm_t mac;
341         const char *prio;
342 } gnutls_dtls_ciphers[] = {
343         { "AES128-SHA", GNUTLS_CIPHER_AES_128_CBC, GNUTLS_MAC_SHA1,
344           "NONE:+VERS-DTLS0.9:+COMP-NULL:+AES-128-CBC:+SHA1:+RSA:%COMPAT:%DISABLE_SAFE_RENEGOTIATION" },
345         { "DES-CBC3-SHA", GNUTLS_CIPHER_3DES_CBC, GNUTLS_MAC_SHA1,
346           "NONE:+VERS-DTLS0.9:+COMP-NULL:+3DES-CBC:+SHA1:+RSA:%COMPAT:%DISABLE_SAFE_RENEGOTIATION" },
347 };
348
349 #define DTLS_SEND gnutls_record_send
350 #define DTLS_RECV gnutls_record_recv
351 static int start_dtls_handshake(struct openconnect_info *vpninfo, int dtls_fd)
352 {
353         gnutls_session_t dtls_ssl;
354         gnutls_datum_t master_secret, session_id;
355         int err;
356         int cipher;
357
358         for (cipher = 0; cipher < sizeof(gnutls_dtls_ciphers)/sizeof(gnutls_dtls_ciphers[0]); cipher++) {
359                 if (!strcmp(vpninfo->dtls_cipher, gnutls_dtls_ciphers[cipher].name))
360                         goto found_cipher;
361         }
362         vpn_progress(vpninfo, PRG_ERR, _("Unknown DTLS parameters for requested CipherSuite '%s'\n"),
363                      vpninfo->dtls_cipher);
364         vpninfo->dtls_attempt_period = 0;
365
366         return -EINVAL;
367
368  found_cipher:
369         gnutls_init(&dtls_ssl, GNUTLS_CLIENT|GNUTLS_DATAGRAM|GNUTLS_NONBLOCK);
370         err = gnutls_priority_set_direct(dtls_ssl,
371                                          gnutls_dtls_ciphers[cipher].prio,
372                                          NULL);
373         if (err) {
374                 vpn_progress(vpninfo, PRG_ERR,
375                              _("Failed to set DTLS priority: %s\n"),
376                              gnutls_strerror(err));
377                 gnutls_deinit(dtls_ssl);
378                 vpninfo->dtls_attempt_period = 0;
379                 return -EINVAL;
380         }
381         gnutls_transport_set_ptr(dtls_ssl,
382                                  (gnutls_transport_ptr_t)(long) dtls_fd);
383         gnutls_record_disable_padding(dtls_ssl);
384         master_secret.data = vpninfo->dtls_secret;
385         master_secret.size = sizeof(vpninfo->dtls_secret);
386         session_id.data = vpninfo->dtls_session_id;
387         session_id.size = sizeof(vpninfo->dtls_session_id);
388         err = gnutls_session_set_premaster(dtls_ssl, GNUTLS_CLIENT, GNUTLS_DTLS0_9,
389                                            GNUTLS_KX_RSA, gnutls_dtls_ciphers[cipher].cipher,
390                                            gnutls_dtls_ciphers[cipher].mac, GNUTLS_COMP_NULL,
391                                            &master_secret, &session_id);
392         if (err) {
393                 vpn_progress(vpninfo, PRG_ERR,
394                              _("Failed to set DTLS session parameters: %s\n"),
395                              gnutls_strerror(err));
396                 gnutls_deinit(dtls_ssl);
397                 vpninfo->dtls_attempt_period = 0;
398                 return -EINVAL;
399         }
400
401         vpninfo->new_dtls_ssl = dtls_ssl;
402         return 0;
403 }
404
405 int dtls_try_handshake(struct openconnect_info *vpninfo)
406 {
407         int err = gnutls_handshake(vpninfo->new_dtls_ssl);
408
409         if (!err) {
410 #ifdef HAVE_GNUTLS_DTLS_SET_DATA_MTU
411                 /* Make sure GnuTLS's idea of the MTU is sufficient to take
412                    a full VPN MTU (with 1-byte header) in a data record. */
413                 err = gnutls_dtls_set_data_mtu(vpninfo->new_dtls_ssl, vpninfo->actual_mtu + 1);
414                 if (err) {
415                         vpn_progress(vpninfo, PRG_ERR,
416                                      _("Failed to set DTLS MTU: %s\n"),
417                                      gnutls_strerror(err));
418                         goto error;
419                 }
420 #else
421                 /* If we don't have gnutls_dtls_set_data_mtu() then make sure
422                    we leave enough headroom by adding the worst-case overhead.
423                    We only support AES128-CBC and DES-CBC3-SHA anyway, so
424                    working out the worst case isn't hard. */
425                 gnutls_dtls_set_mtu(vpninfo->new_dtls_ssl,
426                                     vpninfo->actual_mtu + 1 /* packet + header */
427                                     + 13 /* DTLS header */
428                                     + 20 /* biggest supported MAC (SHA1) */
429                                     + 16 /* biggest supported IV (AES-128) */
430                                     + 16 /* max padding */);
431 #endif
432
433                 vpn_progress(vpninfo, PRG_INFO, _("Established DTLS connection (using GnuTLS)\n"));
434
435                 if (vpninfo->dtls_ssl) {
436                         /* We are replacing an old connection */
437                         gnutls_deinit(vpninfo->dtls_ssl);
438                         close(vpninfo->dtls_fd);
439                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
440                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
441                         FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
442                 }
443                 vpninfo->dtls_ssl = vpninfo->new_dtls_ssl;
444                 vpninfo->dtls_fd = vpninfo->new_dtls_fd;
445
446                 vpninfo->new_dtls_ssl = NULL;
447                 vpninfo->new_dtls_fd = -1;
448
449                 vpninfo->dtls_times.last_rx = vpninfo->dtls_times.last_tx = time(NULL);
450
451                 /* XXX: For OpenSSL we explicitly prevent retransmits here. */
452                 return 0;
453         }
454
455         if (err == GNUTLS_E_AGAIN) {
456                 if (time(NULL) < vpninfo->new_dtls_started + 5)
457                         return 0;
458                 vpn_progress(vpninfo, PRG_TRACE, _("DTLS handshake timed out\n"));
459         }
460
461         vpn_progress(vpninfo, PRG_ERR, _("DTLS handshake failed: %s\n"),
462                      gnutls_strerror(err));
463
464         goto error;
465  error:
466         /* Kill the new (failed) connection... */
467         gnutls_deinit(vpninfo->new_dtls_ssl);
468         FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_rfds);
469         FD_CLR(vpninfo->new_dtls_fd, &vpninfo->select_efds);
470         close(vpninfo->new_dtls_fd);
471         vpninfo->new_dtls_ssl = NULL;
472         vpninfo->new_dtls_fd = -1;
473
474         /* ... and kill the old one too. The only time there'll be a valid
475            existing session is when it was a rekey, and in that case it's
476            time for the old one to die. */
477         if (vpninfo->dtls_ssl) {
478                 gnutls_deinit(vpninfo->dtls_ssl);
479                 close(vpninfo->dtls_fd);
480                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
481                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
482                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
483                 vpninfo->dtls_ssl = NULL;
484                 vpninfo->dtls_fd = -1;
485         }
486
487         time(&vpninfo->new_dtls_started);
488         return -EINVAL;
489 }
490 #endif
491
492 int connect_dtls_socket(struct openconnect_info *vpninfo)
493 {
494         int dtls_fd, ret;
495
496         if (!vpninfo->dtls_addr) {
497                 vpn_progress(vpninfo, PRG_ERR, _("No DTLS address\n"));
498                 vpninfo->dtls_attempt_period = 0;
499                 return -EINVAL;
500         }
501
502         if (!vpninfo->dtls_cipher) {
503                 /* We probably didn't offer it any ciphers it liked */
504                 vpn_progress(vpninfo, PRG_ERR, _("Server offered no DTLS cipher option\n"));
505                 vpninfo->dtls_attempt_period = 0;
506                 return -EINVAL;
507         }
508
509         if (vpninfo->proxy) {
510                 /* XXX: Theoretically, SOCKS5 proxies can do UDP too */
511                 vpn_progress(vpninfo, PRG_ERR, _("No DTLS when connected via proxy\n"));
512                 vpninfo->dtls_attempt_period = 0;
513                 return -EINVAL;
514         }
515
516         dtls_fd = socket(vpninfo->peer_addr->sa_family, SOCK_DGRAM, IPPROTO_UDP);
517         if (dtls_fd < 0) {
518                 perror(_("Open UDP socket for DTLS:"));
519                 return -EINVAL;
520         }
521
522         if (vpninfo->dtls_local_port) {
523                 union {
524                         struct sockaddr_in in;
525                         struct sockaddr_in6 in6;
526                 } dtls_bind_addr;
527                 int dtls_bind_addrlen;
528                 memset(&dtls_bind_addr, 0, sizeof(dtls_bind_addr));
529
530                 if (vpninfo->peer_addr->sa_family == AF_INET) {
531                         struct sockaddr_in *addr = &dtls_bind_addr.in;
532                         dtls_bind_addrlen = sizeof(*addr);
533                         addr->sin_family = AF_INET;
534                         addr->sin_addr.s_addr = INADDR_ANY;
535                         addr->sin_port = htons(vpninfo->dtls_local_port);
536                 } else if (vpninfo->peer_addr->sa_family == AF_INET6) {
537                         struct sockaddr_in6 *addr = &dtls_bind_addr.in6;
538                         dtls_bind_addrlen = sizeof(*addr);
539                         addr->sin6_family = AF_INET6;
540                         addr->sin6_addr = in6addr_any;
541                         addr->sin6_port = htons(vpninfo->dtls_local_port);
542                 } else {
543                         vpn_progress(vpninfo, PRG_ERR,
544                                      _("Unknown protocol family %d. Cannot do DTLS\n"),
545                                      vpninfo->peer_addr->sa_family);
546                         vpninfo->dtls_attempt_period = 0;
547                         return -EINVAL;
548                 }
549
550                 if (bind(dtls_fd, (struct sockaddr *)&dtls_bind_addr, dtls_bind_addrlen)) {
551                         perror(_("Bind UDP socket for DTLS"));
552                         return -EINVAL;
553                 }
554         }
555
556         if (connect(dtls_fd, vpninfo->dtls_addr, vpninfo->peer_addrlen)) {
557                 perror(_("UDP (DTLS) connect:\n"));
558                 close(dtls_fd);
559                 return -EINVAL;
560         }
561
562         fcntl(dtls_fd, F_SETFD, FD_CLOEXEC);
563         fcntl(dtls_fd, F_SETFL, fcntl(dtls_fd, F_GETFL) | O_NONBLOCK);
564
565         ret = start_dtls_handshake(vpninfo, dtls_fd);
566         if (ret) {
567                 close(dtls_fd);
568                 return ret;
569         }
570
571         vpninfo->new_dtls_fd = dtls_fd;
572         if (vpninfo->select_nfds <= dtls_fd)
573                 vpninfo->select_nfds = dtls_fd + 1;
574
575         FD_SET(dtls_fd, &vpninfo->select_rfds);
576         FD_SET(dtls_fd, &vpninfo->select_efds);
577
578         time(&vpninfo->new_dtls_started);
579
580         return dtls_try_handshake(vpninfo);
581 }
582
583 static int dtls_restart(struct openconnect_info *vpninfo)
584 {
585         if (vpninfo->dtls_ssl) {
586 #if defined (DTLS_OPENSSL)
587                 SSL_free(vpninfo->dtls_ssl);
588 #elif defined (DTLS_GNUTLS)
589                 gnutls_deinit(vpninfo->dtls_ssl);
590 #endif
591                 close(vpninfo->dtls_fd);
592                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_rfds);
593                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_wfds);
594                 FD_CLR(vpninfo->dtls_fd, &vpninfo->select_efds);
595                 vpninfo->dtls_ssl = NULL;
596                 vpninfo->dtls_fd = -1;
597         }
598
599         return connect_dtls_socket(vpninfo);
600 }
601
602
603 int setup_dtls(struct openconnect_info *vpninfo)
604 {
605         struct vpn_option *dtls_opt = vpninfo->dtls_options;
606         int dtls_port = 0;
607
608 #if defined (OPENCONNECT_GNUTLS) && defined (DTLS_OPENSSL)
609         /* If we're using GnuTLS for authentication but OpenSSL for DTLS,
610            we'll need to initialise OpenSSL now... */
611         SSL_library_init ();
612         ERR_clear_error ();
613         SSL_load_error_strings ();
614         OpenSSL_add_all_algorithms ();
615 #endif
616
617         while (dtls_opt) {
618                 vpn_progress(vpninfo, PRG_TRACE,
619                              _("DTLS option %s : %s\n"),
620                              dtls_opt->option, dtls_opt->value);
621
622                 if (!strcmp(dtls_opt->option + 7, "Port")) {
623                         dtls_port = atol(dtls_opt->value);
624                 } else if (!strcmp(dtls_opt->option + 7, "Keepalive")) {
625                         vpninfo->dtls_times.keepalive = atol(dtls_opt->value);
626                 } else if (!strcmp(dtls_opt->option + 7, "DPD")) {
627                         int j = atol(dtls_opt->value);
628                         if (j && (!vpninfo->dtls_times.dpd || j < vpninfo->dtls_times.dpd))
629                                 vpninfo->dtls_times.dpd = j;
630                 } else if (!strcmp(dtls_opt->option + 7, "Rekey-Time")) {
631                         vpninfo->dtls_times.rekey = atol(dtls_opt->value);
632                 } else if (!strcmp(dtls_opt->option + 7, "CipherSuite")) {
633                         vpninfo->dtls_cipher = strdup(dtls_opt->value);
634                 }
635
636                 dtls_opt = dtls_opt->next;
637         }
638         if (!dtls_port) {
639                 vpninfo->dtls_attempt_period = 0;
640                 return -EINVAL;
641         }
642
643         vpninfo->dtls_addr = malloc(vpninfo->peer_addrlen);
644         if (!vpninfo->dtls_addr) {
645                 vpninfo->dtls_attempt_period = 0;
646                 return -ENOMEM;
647         }
648         memcpy(vpninfo->dtls_addr, vpninfo->peer_addr, vpninfo->peer_addrlen);
649
650         if (vpninfo->peer_addr->sa_family == AF_INET) {
651                 struct sockaddr_in *sin = (void *)vpninfo->dtls_addr;
652                 sin->sin_port = htons(dtls_port);
653         } else if (vpninfo->peer_addr->sa_family == AF_INET6) {
654                 struct sockaddr_in6 *sin = (void *)vpninfo->dtls_addr;
655                 sin->sin6_port = htons(dtls_port);
656         } else {
657                 vpn_progress(vpninfo, PRG_ERR,
658                              _("Unknown protocol family %d. Cannot do DTLS\n"),
659                              vpninfo->peer_addr->sa_family);
660                 vpninfo->dtls_attempt_period = 0;
661                 return -EINVAL;
662         }
663
664         if (connect_dtls_socket(vpninfo))
665                 return -EINVAL;
666
667         vpn_progress(vpninfo, PRG_TRACE,
668                      _("DTLS connected. DPD %d, Keepalive %d\n"),
669                      vpninfo->dtls_times.dpd, vpninfo->dtls_times.keepalive);
670
671         return 0;
672 }
673
674 static struct pkt *dtls_pkt;
675
676 int dtls_mainloop(struct openconnect_info *vpninfo, int *timeout)
677 {
678         int work_done = 0;
679         char magic_pkt;
680
681         while (1) {
682                 int len = vpninfo->actual_mtu;
683                 unsigned char *buf;
684
685                 if (!dtls_pkt) {
686                         dtls_pkt = malloc(sizeof(struct pkt) + len);
687                         if (!dtls_pkt) {
688                                 vpn_progress(vpninfo, PRG_ERR, "Allocation failed\n");
689                                 break;
690                         }
691                 }
692
693                 buf = dtls_pkt->data - 1;
694                 len = DTLS_RECV(vpninfo->dtls_ssl, buf, len + 1);
695                 if (len <= 0)
696                         break;
697
698                 vpn_progress(vpninfo, PRG_TRACE,
699                              _("Received DTLS packet 0x%02x of %d bytes\n"),
700                              buf[0], len);
701
702                 vpninfo->dtls_times.last_rx = time(NULL);
703
704                 switch(buf[0]) {
705                 case AC_PKT_DATA:
706                         dtls_pkt->len = len - 1;
707                         queue_packet(&vpninfo->incoming_queue, dtls_pkt);
708                         dtls_pkt = NULL;
709                         work_done = 1;
710                         break;
711
712                 case AC_PKT_DPD_OUT:
713                         vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS DPD request\n"));
714
715                         /* FIXME: What if the packet doesn't get through? */
716                         magic_pkt = AC_PKT_DPD_RESP;
717                         if (DTLS_SEND(vpninfo->dtls_ssl, &magic_pkt, 1) != 1)
718                                 vpn_progress(vpninfo, PRG_ERR,
719                                              _("Failed to send DPD response. Expect disconnect\n"));
720                         continue;
721
722                 case AC_PKT_DPD_RESP:
723                         vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS DPD response\n"));
724                         break;
725
726                 case AC_PKT_KEEPALIVE:
727                         vpn_progress(vpninfo, PRG_TRACE, _("Got DTLS Keepalive\n"));
728                         break;
729
730                 default:
731                         vpn_progress(vpninfo, PRG_ERR,
732                                      _("Unknown DTLS packet type %02x, len %d\n"),
733                                      buf[0], len);
734                         if (1) {
735                                 /* Some versions of OpenSSL have bugs with receiving out-of-order
736                                  * packets. Not only do they wrongly decide to drop packets if
737                                  * two packets get swapped in transit, but they also _fail_ to
738                                  * drop the packet in non-blocking mode; instead they return
739                                  * the appropriate length of garbage. So don't abort... for now. */
740                                 break;
741                         } else {
742                                 vpninfo->quit_reason = "Unknown packet received";
743                                 return 1;
744                         }
745
746                 }
747         }
748
749         switch (keepalive_action(&vpninfo->dtls_times, timeout)) {
750         case KA_REKEY:
751                 vpn_progress(vpninfo, PRG_INFO, _("DTLS rekey due\n"));
752
753                 /* There ought to be a method of rekeying DTLS without tearing down
754                    the CSTP session and restarting, but we don't (yet) know it */
755                 if (cstp_reconnect(vpninfo)) {
756                         vpn_progress(vpninfo, PRG_ERR, _("Reconnect failed\n"));
757                         vpninfo->quit_reason = "CSTP reconnect failed";
758                         return 1;
759                 }
760
761                 if (dtls_restart(vpninfo)) {
762                         vpn_progress(vpninfo, PRG_ERR, _("DTLS rekey failed\n"));
763                         return 1;
764                 }
765                 work_done = 1;
766                 break;
767
768
769         case KA_DPD_DEAD:
770                 vpn_progress(vpninfo, PRG_ERR, _("DTLS Dead Peer Detection detected dead peer!\n"));
771                 /* Fall back to SSL, and start a new DTLS connection */
772                 dtls_restart(vpninfo);
773                 return 1;
774
775         case KA_DPD:
776                 vpn_progress(vpninfo, PRG_TRACE, _("Send DTLS DPD\n"));
777
778                 magic_pkt = AC_PKT_DPD_OUT;
779                 if (DTLS_SEND(vpninfo->dtls_ssl, &magic_pkt, 1) != 1)
780                         vpn_progress(vpninfo, PRG_ERR,
781                                      _("Failed to send DPD request. Expect disconnect\n"));
782
783                 /* last_dpd will just have been set */
784                 vpninfo->dtls_times.last_tx = vpninfo->dtls_times.last_dpd;
785                 work_done = 1;
786                 break;
787
788         case KA_KEEPALIVE:
789                 /* No need to send an explicit keepalive
790                    if we have real data to send */
791                 if (vpninfo->outgoing_queue)
792                         break;
793
794                 vpn_progress(vpninfo, PRG_TRACE, _("Send DTLS Keepalive\n"));
795
796                 magic_pkt = AC_PKT_KEEPALIVE;
797                 if (DTLS_SEND(vpninfo->dtls_ssl, &magic_pkt, 1) != 1)
798                         vpn_progress(vpninfo, PRG_ERR,
799                                      _("Failed to send keepalive request. Expect disconnect\n"));
800                 time(&vpninfo->dtls_times.last_tx);
801                 work_done = 1;
802                 break;
803
804         case KA_NONE:
805                 ;
806         }
807
808         /* Service outgoing packet queue */
809         while (vpninfo->outgoing_queue) {
810                 struct pkt *this = vpninfo->outgoing_queue;
811                 int ret;
812
813                 vpninfo->outgoing_queue = this->next;
814                 vpninfo->outgoing_qlen--;
815
816                 /* One byte of header */
817                 this->hdr[7] = AC_PKT_DATA;
818
819 #if defined(DTLS_OPENSSL)
820                 ret = SSL_write(vpninfo->dtls_ssl, &this->hdr[7], this->len + 1);
821                 if (ret <= 0) {
822                         ret = SSL_get_error(vpninfo->dtls_ssl, ret);
823
824                         /* If it's a real error, kill the DTLS connection and
825                            requeue the packet to be sent over SSL */
826                         if (ret != SSL_ERROR_WANT_READ && ret != SSL_ERROR_WANT_WRITE) {
827                                 vpn_progress(vpninfo, PRG_ERR,
828                                              _("DTLS got write error %d. Falling back to SSL\n"),
829                                              ret);
830                                 openconnect_report_ssl_errors(vpninfo);
831                                 dtls_restart(vpninfo);
832                                 vpninfo->outgoing_queue = this;
833                                 vpninfo->outgoing_qlen++;
834                         }
835                         return 1;
836                 }
837 #elif defined (DTLS_GNUTLS)
838                 ret = gnutls_record_send(vpninfo->dtls_ssl, &this->hdr[7], this->len + 1);
839                 if (ret <= 0) {
840                         if (ret != GNUTLS_E_AGAIN) {
841                                 vpn_progress(vpninfo, PRG_ERR,
842                                              _("DTLS got write error: %s. Falling back to SSL\n"),
843                                              gnutls_strerror(ret));
844                                 dtls_restart(vpninfo);
845                                 vpninfo->outgoing_queue = this;
846                                 vpninfo->outgoing_qlen++;
847                         }
848                         return 1;
849                 }
850 #endif
851                 time(&vpninfo->dtls_times.last_tx);
852                 vpn_progress(vpninfo, PRG_TRACE,
853                              _("Sent DTLS packet of %d bytes; DTLS send returned %d\n"),
854                              this->len, ret);
855                 free(this);
856         }
857
858         return work_done;
859 }
860 #else /* !HAVE_DTLS */
861 #warning Your SSL library does not seem to support Cisco DTLS compatibility
862  int setup_dtls(struct openconnect_info *vpninfo)
863 {
864         vpn_progress(vpninfo, PRG_ERR,
865                      _("Built against SSL library with no Cisco DTLS support\n"));
866         return -EINVAL;
867 }
868 #endif
869