0d9d3c986de6734e4756a9ab70e3f136933c4bf1
[abartlet/samba.git/.git] / source4 / lib / tls / tls.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    transport layer security handling code
5
6    Copyright (C) Andrew Tridgell 2004-2005
7    Copyright (C) Stefan Metzmacher 2004
8    Copyright (C) Andrew Bartlett 2006
9
10    This program is free software; you can redistribute it and/or modify
11    it under the terms of the GNU General Public License as published by
12    the Free Software Foundation; either version 3 of the License, or
13    (at your option) any later version.
14
15    This program is distributed in the hope that it will be useful,
16    but WITHOUT ANY WARRANTY; without even the implied warranty of
17    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
18    GNU General Public License for more details.
19
20    You should have received a copy of the GNU General Public License
21    along with this program.  If not, see <http://www.gnu.org/licenses/>.
22 */
23
24 #include "includes.h"
25 #include "system/filesys.h"
26 #include "lib/events/events.h"
27 #include "lib/socket/socket.h"
28 #include "lib/tls/tls.h"
29 #include "param/param.h"
30
31 #if ENABLE_GNUTLS
32 #include <gnutls/gnutls.h>
33
34 #define DH_BITS 1024
35
36 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T)
37 typedef gnutls_datum gnutls_datum_t;
38 #endif
39
40 /* hold persistent tls data */
41 struct tls_params {
42         gnutls_certificate_credentials x509_cred;
43         gnutls_dh_params dh_params;
44         bool tls_enabled;
45         const char *tls_priority;
46 };
47 #endif
48
49 /* hold per connection tls data */
50 struct tls_context {
51         struct socket_context *socket;
52         struct tevent_fd *fde;
53         bool tls_enabled;
54 #if ENABLE_GNUTLS
55         gnutls_session session;
56         bool done_handshake;
57         bool have_first_byte;
58         uint8_t first_byte;
59         bool tls_detect;
60         const char *plain_chars;
61         bool output_pending;
62         gnutls_certificate_credentials xcred;
63         bool interrupted;
64 #endif
65 };
66
67 bool tls_enabled(struct socket_context *sock)
68 {
69         struct tls_context *tls;
70         if (!sock) {
71                 return false;
72         }
73         if (strcmp(sock->backend_name, "tls") != 0) {
74                 return false;
75         }
76         tls = talloc_get_type(sock->private_data, struct tls_context);
77         if (!tls) {
78                 return false;
79         }
80         return tls->tls_enabled;
81 }
82
83
84 #if ENABLE_GNUTLS
85
86 static const struct socket_ops tls_socket_ops;
87
88 static NTSTATUS tls_socket_init(struct socket_context *sock)
89 {
90         switch (sock->type) {
91         case SOCKET_TYPE_STREAM:
92                 break;
93         default:
94                 return NT_STATUS_INVALID_PARAMETER;
95         }
96
97         sock->backend_name = "tls";
98
99         return NT_STATUS_OK;
100 }
101
102 #define TLSCHECK(call) do { \
103         ret = call; \
104         if (ret < 0) { \
105                 DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
106                 goto failed; \
107         } \
108 } while (0)
109
110
111 /*
112   callback for reading from a socket
113 */
114 static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size)
115 {
116         struct tls_context *tls = talloc_get_type(ptr, struct tls_context);
117         NTSTATUS status;
118         size_t nread;
119
120         if (tls->have_first_byte) {
121                 *(uint8_t *)buf = tls->first_byte;
122                 tls->have_first_byte = false;
123                 return 1;
124         }
125
126         status = socket_recv(tls->socket, buf, size, &nread);
127         if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) {
128                 return 0;
129         }
130         if (NT_STATUS_IS_ERR(status)) {
131                 TEVENT_FD_NOT_READABLE(tls->fde);
132                 TEVENT_FD_NOT_WRITEABLE(tls->fde);
133                 errno = EBADF;
134                 return -1;
135         }
136         if (!NT_STATUS_IS_OK(status)) {
137                 TEVENT_FD_READABLE(tls->fde);
138                 errno = EAGAIN;
139                 return -1;
140         }
141         if (tls->output_pending) {
142                 TEVENT_FD_WRITEABLE(tls->fde);
143         }
144         if (size != nread) {
145                 TEVENT_FD_READABLE(tls->fde);
146         }
147         return nread;
148 }
149
150 /*
151   callback for writing to a socket
152 */
153 static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size)
154 {
155         struct tls_context *tls = talloc_get_type(ptr, struct tls_context);
156         NTSTATUS status;
157         size_t nwritten, total_nwritten = 0;
158         DATA_BLOB b;
159
160         if (!tls->tls_enabled) {
161                 return size;
162         }
163
164         b.data = discard_const(buf);
165         b.length = size;
166
167         /* Cope with socket_wrapper 1500 byte chunking for PCAP */
168         do {
169                 status = socket_send(tls->socket, &b, &nwritten);
170
171                 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) {
172                         errno = EAGAIN;
173                         return -1;
174                 }
175                 if (!NT_STATUS_IS_OK(status)) {
176                         TEVENT_FD_WRITEABLE(tls->fde);
177                         return -1;
178                 }
179
180                 total_nwritten += nwritten;
181
182                 if (size == nwritten) {
183                         break;
184                 }
185
186                 b.data += nwritten;
187                 b.length -= nwritten;
188
189                 TEVENT_FD_WRITEABLE(tls->fde);
190         } while (b.length);
191
192         return total_nwritten;
193 }
194
195 /*
196   destroy a tls session
197  */
198 static int tls_destructor(struct tls_context *tls)
199 {
200         int ret;
201         ret = gnutls_bye(tls->session, GNUTLS_SHUT_WR);
202         if (ret < 0) {
203                 DEBUG(4,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret)));
204         }
205         return 0;
206 }
207
208
209 /*
210   possibly continue the handshake process
211 */
212 static NTSTATUS tls_handshake(struct tls_context *tls)
213 {
214         int ret;
215
216         if (tls->done_handshake) {
217                 return NT_STATUS_OK;
218         }
219
220         ret = gnutls_handshake(tls->session);
221         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
222                 if (gnutls_record_get_direction(tls->session) == 1) {
223                         TEVENT_FD_WRITEABLE(tls->fde);
224                 }
225                 return STATUS_MORE_ENTRIES;
226         }
227         if (ret < 0) {
228                 DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret)));
229                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
230         }
231         tls->done_handshake = true;
232         return NT_STATUS_OK;
233 }
234
235 /*
236   possibly continue an interrupted operation
237 */
238 static NTSTATUS tls_interrupted(struct tls_context *tls)
239 {
240         int ret;
241
242         if (!tls->interrupted) {
243                 return NT_STATUS_OK;
244         }
245         if (gnutls_record_get_direction(tls->session) == 1) {
246                 ret = gnutls_record_send(tls->session, NULL, 0);
247         } else {
248                 ret = gnutls_record_recv(tls->session, NULL, 0);
249         }
250         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
251                 return STATUS_MORE_ENTRIES;
252         }
253         tls->interrupted = false;
254         return NT_STATUS_OK;
255 }
256
257 /*
258   see how many bytes are pending on the connection
259 */
260 static NTSTATUS tls_socket_pending(struct socket_context *sock, size_t *npending)
261 {
262         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
263         if (!tls->tls_enabled || tls->tls_detect) {
264                 return socket_pending(tls->socket, npending);
265         }
266         *npending = gnutls_record_check_pending(tls->session);
267         if (*npending == 0) {
268                 NTSTATUS status = socket_pending(tls->socket, npending);
269                 if (*npending == 0) {
270                         /* seems to be a gnutls bug */
271                         (*npending) = 100;
272                 }
273                 return status;
274         }
275         return NT_STATUS_OK;
276 }
277
278 /*
279   receive data either by tls or normal socket_recv
280 */
281 static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf,
282                                 size_t wantlen, size_t *nread)
283 {
284         int ret;
285         NTSTATUS status;
286         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
287
288         if (tls->tls_enabled && tls->tls_detect) {
289                 status = socket_recv(tls->socket, &tls->first_byte, 1, nread);
290                 NT_STATUS_NOT_OK_RETURN(status);
291                 if (*nread == 0) return NT_STATUS_OK;
292                 tls->tls_detect = false;
293                 /* look for the first byte of a valid HTTP operation */
294                 if (strchr(tls->plain_chars, tls->first_byte)) {
295                         /* not a tls link */
296                         tls->tls_enabled = false;
297                         *(uint8_t *)buf = tls->first_byte;
298                         return NT_STATUS_OK;
299                 }
300                 tls->have_first_byte = true;
301         }
302
303         if (!tls->tls_enabled) {
304                 return socket_recv(tls->socket, buf, wantlen, nread);
305         }
306
307         status = tls_handshake(tls);
308         NT_STATUS_NOT_OK_RETURN(status);
309
310         status = tls_interrupted(tls);
311         NT_STATUS_NOT_OK_RETURN(status);
312
313         ret = gnutls_record_recv(tls->session, buf, wantlen);
314         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
315                 if (gnutls_record_get_direction(tls->session) == 1) {
316                         TEVENT_FD_WRITEABLE(tls->fde);
317                 }
318                 tls->interrupted = true;
319                 return STATUS_MORE_ENTRIES;
320         }
321         if (ret < 0) {
322                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
323         }
324         *nread = ret;
325         return NT_STATUS_OK;
326 }
327
328
329 /*
330   send data either by tls or normal socket_recv
331 */
332 static NTSTATUS tls_socket_send(struct socket_context *sock,
333                                 const DATA_BLOB *blob, size_t *sendlen)
334 {
335         NTSTATUS status;
336         int ret;
337         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
338
339         if (!tls->tls_enabled) {
340                 return socket_send(tls->socket, blob, sendlen);
341         }
342
343         status = tls_handshake(tls);
344         NT_STATUS_NOT_OK_RETURN(status);
345
346         status = tls_interrupted(tls);
347         NT_STATUS_NOT_OK_RETURN(status);
348
349         ret = gnutls_record_send(tls->session, blob->data, blob->length);
350         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
351                 if (gnutls_record_get_direction(tls->session) == 1) {
352                         TEVENT_FD_WRITEABLE(tls->fde);
353                 }
354                 tls->interrupted = true;
355                 return STATUS_MORE_ENTRIES;
356         }
357         if (ret < 0) {
358                 DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob->length, gnutls_strerror(ret)));
359                 return NT_STATUS_UNEXPECTED_NETWORK_ERROR;
360         }
361         *sendlen = ret;
362         tls->output_pending = (ret < blob->length);
363         return NT_STATUS_OK;
364 }
365
366
367 /*
368   initialise global tls state
369 */
370 struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
371 {
372         struct tls_params *params;
373         int ret;
374         struct stat st;
375         TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx);
376         const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx);
377         const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx);
378         const char *cafile = lpcfg_tls_cafile(tmp_ctx, lp_ctx);
379         const char *crlfile = lpcfg_tls_crlfile(tmp_ctx, lp_ctx);
380         const char *dhpfile = lpcfg_tls_dhpfile(tmp_ctx, lp_ctx);
381         void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *);
382         params = talloc(mem_ctx, struct tls_params);
383         if (params == NULL) {
384                 talloc_free(tmp_ctx);
385                 return NULL;
386         }
387
388         if (!lpcfg_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) {
389                 params->tls_enabled = false;
390                 talloc_free(tmp_ctx);
391                 return params;
392         }
393
394         params->tls_priority = lpcfg_tls_priority(lp_ctx);
395
396         if (!file_exist(cafile)) {
397                 char *hostname = talloc_asprintf(mem_ctx, "%s.%s",
398                                                  lpcfg_netbios_name(lp_ctx),
399                                                  lpcfg_dnsdomain(lp_ctx));
400                 if (hostname == NULL) {
401                         ret = GNUTLS_E_MEMORY_ERROR;
402                         goto init_failed;
403                 }
404                 tls_cert_generate(params, hostname, keyfile, certfile, cafile);
405                 talloc_free(hostname);
406         }
407
408         if (file_exist(keyfile) &&
409             !file_check_permissions(keyfile, geteuid(), 0600, &st))
410         {
411                 DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n"
412                           "owner uid %u should be %u, mode 0%o should be 0%o\n"
413                           "This is known as CVE-2013-4476.\n"
414                           "Removing all tls .pem files will cause an "
415                           "auto-regeneration with the correct permissions.\n",
416                           keyfile,
417                           (unsigned int)st.st_uid, geteuid(),
418                           (unsigned int)(st.st_mode & 0777), 0600));
419                 talloc_free(tmp_ctx);
420                 return NULL;
421         }
422
423         ret = gnutls_global_init();
424         if (ret < 0) goto init_failed;
425
426         gnutls_certificate_allocate_credentials(&params->x509_cred);
427         if (ret < 0) goto init_failed;
428
429         if (cafile && *cafile) {
430                 ret = gnutls_certificate_set_x509_trust_file(params->x509_cred, cafile,
431                                                              GNUTLS_X509_FMT_PEM);
432                 if (ret < 0) {
433                         DEBUG(0,("TLS failed to initialise cafile %s\n", cafile));
434                         goto init_failed;
435                 }
436         }
437
438         if (crlfile && *crlfile) {
439                 ret = gnutls_certificate_set_x509_crl_file(params->x509_cred,
440                                                            crlfile,
441                                                            GNUTLS_X509_FMT_PEM);
442                 if (ret < 0) {
443                         DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile));
444                         goto init_failed;
445                 }
446         }
447
448         ret = gnutls_certificate_set_x509_key_file(params->x509_cred,
449                                                    certfile, keyfile,
450                                                    GNUTLS_X509_FMT_PEM);
451         if (ret < 0) {
452                 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n",
453                          certfile, keyfile));
454                 goto init_failed;
455         }
456
457         ret = gnutls_dh_params_init(&params->dh_params);
458         if (ret < 0) goto init_failed;
459
460         if (dhpfile && *dhpfile) {
461                 gnutls_datum_t dhparms;
462                 size_t size;
463                 dhparms.data = (uint8_t *)file_load(dhpfile, &size, 0, mem_ctx);
464
465                 if (!dhparms.data) {
466                         DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile));
467                         goto init_failed;
468                 }
469                 dhparms.size = size;
470
471                 ret = gnutls_dh_params_import_pkcs3(params->dh_params, &dhparms, GNUTLS_X509_FMT_PEM);
472                 if (ret < 0) goto init_failed;
473         } else {
474                 ret = gnutls_dh_params_generate2(params->dh_params, DH_BITS);
475                 if (ret < 0) goto init_failed;
476         }
477
478         gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params);
479
480         params->tls_enabled = true;
481
482         talloc_free(tmp_ctx);
483         return params;
484
485 init_failed:
486         DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret)));
487         params->tls_enabled = false;
488         talloc_free(tmp_ctx);
489         return params;
490 }
491
492
493 /*
494   setup for a new connection
495 */
496 struct socket_context *tls_init_server(struct tls_params *params,
497                                        struct socket_context *socket_ctx,
498                                        struct tevent_fd *fde,
499                                        const char *plain_chars)
500 {
501         struct tls_context *tls;
502         int ret;
503         struct socket_context *new_sock;
504         NTSTATUS nt_status;
505         const char *error_pos;
506
507         nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock,
508                                            SOCKET_TYPE_STREAM,
509                                            socket_ctx->flags | SOCKET_FLAG_ENCRYPT);
510         if (!NT_STATUS_IS_OK(nt_status)) {
511                 return NULL;
512         }
513
514         tls = talloc(new_sock, struct tls_context);
515         if (tls == NULL) {
516                 return NULL;
517         }
518
519         tls->socket          = socket_ctx;
520         talloc_steal(tls, socket_ctx);
521         tls->fde             = fde;
522
523         new_sock->private_data    = tls;
524
525         if (!params->tls_enabled) {
526                 talloc_free(new_sock);
527                 return NULL;
528         }
529
530         TLSCHECK(gnutls_init(&tls->session, GNUTLS_SERVER));
531
532         talloc_set_destructor(tls, tls_destructor);
533
534         ret = gnutls_priority_set_direct(tls->session,
535                                          params->tls_priority,
536                                          &error_pos);
537         if (ret != GNUTLS_E_SUCCESS) {
538                 DEBUG(0,("TLS %s - %s.  Check 'tls priority' option at '%s'\n",
539                          __location__, gnutls_strerror(ret), error_pos));
540                 talloc_free(new_sock);
541                 return NULL;
542         }
543
544         TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE,
545                                         params->x509_cred));
546         gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_REQUEST);
547         gnutls_dh_set_prime_bits(tls->session, DH_BITS);
548         gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls);
549         gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull);
550         gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push);
551 #if GNUTLS_VERSION_MAJOR < 3
552         gnutls_transport_set_lowat(tls->session, 0);
553 #endif
554
555         tls->plain_chars = plain_chars;
556         if (plain_chars) {
557                 tls->tls_detect = true;
558         } else {
559                 tls->tls_detect = false;
560         }
561
562         tls->output_pending  = false;
563         tls->done_handshake  = false;
564         tls->have_first_byte = false;
565         tls->tls_enabled     = true;
566         tls->interrupted     = false;
567
568         new_sock->state = SOCKET_STATE_SERVER_CONNECTED;
569
570         return new_sock;
571
572 failed:
573         DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret)));
574         talloc_free(new_sock);
575         return NULL;
576 }
577
578
579 static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val)
580 {
581         set_socket_options(socket_get_fd(sock), option);
582         return NT_STATUS_OK;
583 }
584
585 static char *tls_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx)
586 {
587         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
588         return socket_get_peer_name(tls->socket, mem_ctx);
589 }
590
591 static struct socket_address *tls_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
592 {
593         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
594         return socket_get_peer_addr(tls->socket, mem_ctx);
595 }
596
597 static struct socket_address *tls_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx)
598 {
599         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
600         return socket_get_my_addr(tls->socket, mem_ctx);
601 }
602
603 static int tls_socket_get_fd(struct socket_context *sock)
604 {
605         struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context);
606         return socket_get_fd(tls->socket);
607 }
608
609 static const struct socket_ops tls_socket_ops = {
610         .name                   = "tls",
611         .fn_init                = tls_socket_init,
612         .fn_recv                = tls_socket_recv,
613         .fn_send                = tls_socket_send,
614         .fn_pending             = tls_socket_pending,
615
616         .fn_set_option          = tls_socket_set_option,
617
618         .fn_get_peer_name       = tls_socket_get_peer_name,
619         .fn_get_peer_addr       = tls_socket_get_peer_addr,
620         .fn_get_my_addr         = tls_socket_get_my_addr,
621         .fn_get_fd              = tls_socket_get_fd
622 };
623
624 #else
625
626 /* for systems without tls we just fail the operations, and the caller
627  * will retain the original socket */
628
629 struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx)
630 {
631         return talloc_new(mem_ctx);
632 }
633
634 /*
635   setup for a new connection
636 */
637 struct socket_context *tls_init_server(struct tls_params *params,
638                                     struct socket_context *socket,
639                                     struct tevent_fd *fde,
640                                     const char *plain_chars)
641 {
642         return NULL;
643 }
644
645
646 #endif
647