2 Unix SMB/CIFS implementation.
4 transport layer security handling code
6 Copyright (C) Andrew Tridgell 2004-2005
7 Copyright (C) Stefan Metzmacher 2004
8 Copyright (C) Andrew Bartlett 2006
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.
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.
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/>.
25 #include "lib/events/events.h"
26 #include "lib/socket/socket.h"
27 #include "lib/tls/tls.h"
28 #include "param/param.h"
31 #include <gnutls/gnutls.h>
35 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T)
36 typedef gnutls_datum gnutls_datum_t
;
39 /* hold persistent tls data */
41 gnutls_certificate_credentials x509_cred
;
42 gnutls_dh_params dh_params
;
47 /* hold per connection tls data */
49 struct socket_context
*socket
;
50 struct tevent_fd
*fde
;
53 gnutls_session session
;
58 const char *plain_chars
;
60 gnutls_certificate_credentials xcred
;
65 bool tls_enabled(struct socket_context
*sock
)
67 struct tls_context
*tls
;
71 if (strcmp(sock
->backend_name
, "tls") != 0) {
74 tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
78 return tls
->tls_enabled
;
84 static const struct socket_ops tls_socket_ops
;
86 static NTSTATUS
tls_socket_init(struct socket_context
*sock
)
89 case SOCKET_TYPE_STREAM
:
92 return NT_STATUS_INVALID_PARAMETER
;
95 sock
->backend_name
= "tls";
100 #define TLSCHECK(call) do { \
103 DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \
110 callback for reading from a socket
112 static ssize_t
tls_pull(gnutls_transport_ptr ptr
, void *buf
, size_t size
)
114 struct tls_context
*tls
= talloc_get_type(ptr
, struct tls_context
);
118 if (tls
->have_first_byte
) {
119 *(uint8_t *)buf
= tls
->first_byte
;
120 tls
->have_first_byte
= false;
124 status
= socket_recv(tls
->socket
, buf
, size
, &nread
);
125 if (NT_STATUS_EQUAL(status
, NT_STATUS_END_OF_FILE
)) {
128 if (NT_STATUS_IS_ERR(status
)) {
129 TEVENT_FD_NOT_READABLE(tls
->fde
);
130 TEVENT_FD_NOT_WRITEABLE(tls
->fde
);
134 if (!NT_STATUS_IS_OK(status
)) {
135 TEVENT_FD_READABLE(tls
->fde
);
139 if (tls
->output_pending
) {
140 TEVENT_FD_WRITEABLE(tls
->fde
);
143 TEVENT_FD_READABLE(tls
->fde
);
149 callback for writing to a socket
151 static ssize_t
tls_push(gnutls_transport_ptr ptr
, const void *buf
, size_t size
)
153 struct tls_context
*tls
= talloc_get_type(ptr
, struct tls_context
);
155 size_t nwritten
, total_nwritten
= 0;
158 if (!tls
->tls_enabled
) {
162 b
.data
= discard_const(buf
);
165 /* Cope with socket_wrapper 1500 byte chunking for PCAP */
167 status
= socket_send(tls
->socket
, &b
, &nwritten
);
169 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
173 if (!NT_STATUS_IS_OK(status
)) {
174 TEVENT_FD_WRITEABLE(tls
->fde
);
178 total_nwritten
+= nwritten
;
180 if (size
== nwritten
) {
185 b
.length
-= nwritten
;
187 TEVENT_FD_WRITEABLE(tls
->fde
);
190 return total_nwritten
;
194 destroy a tls session
196 static int tls_destructor(struct tls_context
*tls
)
199 ret
= gnutls_bye(tls
->session
, GNUTLS_SHUT_WR
);
201 DEBUG(4,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret
)));
208 possibly continue the handshake process
210 static NTSTATUS
tls_handshake(struct tls_context
*tls
)
214 if (tls
->done_handshake
) {
218 ret
= gnutls_handshake(tls
->session
);
219 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
220 if (gnutls_record_get_direction(tls
->session
) == 1) {
221 TEVENT_FD_WRITEABLE(tls
->fde
);
223 return STATUS_MORE_ENTRIES
;
226 DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret
)));
227 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
229 tls
->done_handshake
= true;
234 possibly continue an interrupted operation
236 static NTSTATUS
tls_interrupted(struct tls_context
*tls
)
240 if (!tls
->interrupted
) {
243 if (gnutls_record_get_direction(tls
->session
) == 1) {
244 ret
= gnutls_record_send(tls
->session
, NULL
, 0);
246 ret
= gnutls_record_recv(tls
->session
, NULL
, 0);
248 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
249 return STATUS_MORE_ENTRIES
;
251 tls
->interrupted
= false;
256 see how many bytes are pending on the connection
258 static NTSTATUS
tls_socket_pending(struct socket_context
*sock
, size_t *npending
)
260 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
261 if (!tls
->tls_enabled
|| tls
->tls_detect
) {
262 return socket_pending(tls
->socket
, npending
);
264 *npending
= gnutls_record_check_pending(tls
->session
);
265 if (*npending
== 0) {
266 NTSTATUS status
= socket_pending(tls
->socket
, npending
);
267 if (*npending
== 0) {
268 /* seems to be a gnutls bug */
277 receive data either by tls or normal socket_recv
279 static NTSTATUS
tls_socket_recv(struct socket_context
*sock
, void *buf
,
280 size_t wantlen
, size_t *nread
)
284 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
286 if (tls
->tls_enabled
&& tls
->tls_detect
) {
287 status
= socket_recv(tls
->socket
, &tls
->first_byte
, 1, nread
);
288 NT_STATUS_NOT_OK_RETURN(status
);
289 if (*nread
== 0) return NT_STATUS_OK
;
290 tls
->tls_detect
= false;
291 /* look for the first byte of a valid HTTP operation */
292 if (strchr(tls
->plain_chars
, tls
->first_byte
)) {
294 tls
->tls_enabled
= false;
295 *(uint8_t *)buf
= tls
->first_byte
;
298 tls
->have_first_byte
= true;
301 if (!tls
->tls_enabled
) {
302 return socket_recv(tls
->socket
, buf
, wantlen
, nread
);
305 status
= tls_handshake(tls
);
306 NT_STATUS_NOT_OK_RETURN(status
);
308 status
= tls_interrupted(tls
);
309 NT_STATUS_NOT_OK_RETURN(status
);
311 ret
= gnutls_record_recv(tls
->session
, buf
, wantlen
);
312 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
313 if (gnutls_record_get_direction(tls
->session
) == 1) {
314 TEVENT_FD_WRITEABLE(tls
->fde
);
316 tls
->interrupted
= true;
317 return STATUS_MORE_ENTRIES
;
320 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
328 send data either by tls or normal socket_recv
330 static NTSTATUS
tls_socket_send(struct socket_context
*sock
,
331 const DATA_BLOB
*blob
, size_t *sendlen
)
335 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
337 if (!tls
->tls_enabled
) {
338 return socket_send(tls
->socket
, blob
, sendlen
);
341 status
= tls_handshake(tls
);
342 NT_STATUS_NOT_OK_RETURN(status
);
344 status
= tls_interrupted(tls
);
345 NT_STATUS_NOT_OK_RETURN(status
);
347 ret
= gnutls_record_send(tls
->session
, blob
->data
, blob
->length
);
348 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
349 if (gnutls_record_get_direction(tls
->session
) == 1) {
350 TEVENT_FD_WRITEABLE(tls
->fde
);
352 tls
->interrupted
= true;
353 return STATUS_MORE_ENTRIES
;
356 DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob
->length
, gnutls_strerror(ret
)));
357 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
360 tls
->output_pending
= (ret
< blob
->length
);
366 initialise global tls state
368 struct tls_params
*tls_initialise(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
)
370 struct tls_params
*params
;
372 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
373 const char *keyfile
= lpcfg_tls_keyfile(tmp_ctx
, lp_ctx
);
374 const char *certfile
= lpcfg_tls_certfile(tmp_ctx
, lp_ctx
);
375 const char *cafile
= lpcfg_tls_cafile(tmp_ctx
, lp_ctx
);
376 const char *crlfile
= lpcfg_tls_crlfile(tmp_ctx
, lp_ctx
);
377 const char *dhpfile
= lpcfg_tls_dhpfile(tmp_ctx
, lp_ctx
);
378 void tls_cert_generate(TALLOC_CTX
*, const char *, const char *, const char *, const char *);
379 params
= talloc(mem_ctx
, struct tls_params
);
380 if (params
== NULL
) {
381 talloc_free(tmp_ctx
);
385 if (!lpcfg_tls_enabled(lp_ctx
) || keyfile
== NULL
|| *keyfile
== 0) {
386 params
->tls_enabled
= false;
387 talloc_free(tmp_ctx
);
391 if (!file_exist(cafile
)) {
392 char *hostname
= talloc_asprintf(mem_ctx
, "%s.%s",
393 lpcfg_netbios_name(lp_ctx
),
394 lpcfg_dnsdomain(lp_ctx
));
395 if (hostname
== NULL
) {
398 tls_cert_generate(params
, hostname
, keyfile
, certfile
, cafile
);
399 talloc_free(hostname
);
402 ret
= gnutls_global_init();
403 if (ret
< 0) goto init_failed
;
405 gnutls_certificate_allocate_credentials(¶ms
->x509_cred
);
406 if (ret
< 0) goto init_failed
;
408 if (cafile
&& *cafile
) {
409 ret
= gnutls_certificate_set_x509_trust_file(params
->x509_cred
, cafile
,
410 GNUTLS_X509_FMT_PEM
);
412 DEBUG(0,("TLS failed to initialise cafile %s\n", cafile
));
417 if (crlfile
&& *crlfile
) {
418 ret
= gnutls_certificate_set_x509_crl_file(params
->x509_cred
,
420 GNUTLS_X509_FMT_PEM
);
422 DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile
));
427 ret
= gnutls_certificate_set_x509_key_file(params
->x509_cred
,
429 GNUTLS_X509_FMT_PEM
);
431 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n",
437 ret
= gnutls_dh_params_init(¶ms
->dh_params
);
438 if (ret
< 0) goto init_failed
;
440 if (dhpfile
&& *dhpfile
) {
441 gnutls_datum_t dhparms
;
443 dhparms
.data
= (uint8_t *)file_load(dhpfile
, &size
, 0, mem_ctx
);
446 DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile
));
451 ret
= gnutls_dh_params_import_pkcs3(params
->dh_params
, &dhparms
, GNUTLS_X509_FMT_PEM
);
452 if (ret
< 0) goto init_failed
;
454 ret
= gnutls_dh_params_generate2(params
->dh_params
, DH_BITS
);
455 if (ret
< 0) goto init_failed
;
458 gnutls_certificate_set_dh_params(params
->x509_cred
, params
->dh_params
);
460 params
->tls_enabled
= true;
462 talloc_free(tmp_ctx
);
466 DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret
)));
467 params
->tls_enabled
= false;
468 talloc_free(tmp_ctx
);
474 setup for a new connection
476 struct socket_context
*tls_init_server(struct tls_params
*params
,
477 struct socket_context
*socket_ctx
,
478 struct tevent_fd
*fde
,
479 const char *plain_chars
)
481 struct tls_context
*tls
;
483 struct socket_context
*new_sock
;
486 nt_status
= socket_create_with_ops(socket_ctx
, &tls_socket_ops
, &new_sock
,
488 socket_ctx
->flags
| SOCKET_FLAG_ENCRYPT
);
489 if (!NT_STATUS_IS_OK(nt_status
)) {
493 tls
= talloc(new_sock
, struct tls_context
);
498 tls
->socket
= socket_ctx
;
499 talloc_steal(tls
, socket_ctx
);
502 new_sock
->private_data
= tls
;
504 if (!params
->tls_enabled
) {
505 talloc_free(new_sock
);
509 TLSCHECK(gnutls_init(&tls
->session
, GNUTLS_SERVER
));
511 talloc_set_destructor(tls
, tls_destructor
);
513 TLSCHECK(gnutls_set_default_priority(tls
->session
));
514 TLSCHECK(gnutls_credentials_set(tls
->session
, GNUTLS_CRD_CERTIFICATE
,
516 gnutls_certificate_server_set_request(tls
->session
, GNUTLS_CERT_REQUEST
);
517 gnutls_dh_set_prime_bits(tls
->session
, DH_BITS
);
518 gnutls_transport_set_ptr(tls
->session
, (gnutls_transport_ptr
)tls
);
519 gnutls_transport_set_pull_function(tls
->session
, (gnutls_pull_func
)tls_pull
);
520 gnutls_transport_set_push_function(tls
->session
, (gnutls_push_func
)tls_push
);
521 #if GNUTLS_VERSION_MAJOR < 3
522 gnutls_transport_set_lowat(tls
->session
, 0);
525 tls
->plain_chars
= plain_chars
;
527 tls
->tls_detect
= true;
529 tls
->tls_detect
= false;
532 tls
->output_pending
= false;
533 tls
->done_handshake
= false;
534 tls
->have_first_byte
= false;
535 tls
->tls_enabled
= true;
536 tls
->interrupted
= false;
538 new_sock
->state
= SOCKET_STATE_SERVER_CONNECTED
;
543 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret
)));
544 talloc_free(new_sock
);
550 setup for a new client connection
552 struct socket_context
*tls_init_client(struct socket_context
*socket_ctx
,
553 struct tevent_fd
*fde
,
556 struct tls_context
*tls
;
558 const int cert_type_priority
[] = { GNUTLS_CRT_X509
, GNUTLS_CRT_OPENPGP
, 0 };
559 struct socket_context
*new_sock
;
562 nt_status
= socket_create_with_ops(socket_ctx
, &tls_socket_ops
, &new_sock
,
564 socket_ctx
->flags
| SOCKET_FLAG_ENCRYPT
);
565 if (!NT_STATUS_IS_OK(nt_status
)) {
569 tls
= talloc(new_sock
, struct tls_context
);
570 if (tls
== NULL
) return NULL
;
572 tls
->socket
= socket_ctx
;
573 talloc_steal(tls
, socket_ctx
);
576 new_sock
->private_data
= tls
;
578 gnutls_global_init();
580 gnutls_certificate_allocate_credentials(&tls
->xcred
);
581 gnutls_certificate_set_x509_trust_file(tls
->xcred
, ca_path
, GNUTLS_X509_FMT_PEM
);
582 TLSCHECK(gnutls_init(&tls
->session
, GNUTLS_CLIENT
));
583 TLSCHECK(gnutls_set_default_priority(tls
->session
));
584 gnutls_certificate_type_set_priority(tls
->session
, cert_type_priority
);
585 TLSCHECK(gnutls_credentials_set(tls
->session
, GNUTLS_CRD_CERTIFICATE
, tls
->xcred
));
587 talloc_set_destructor(tls
, tls_destructor
);
589 gnutls_transport_set_ptr(tls
->session
, (gnutls_transport_ptr
)tls
);
590 gnutls_transport_set_pull_function(tls
->session
, (gnutls_pull_func
)tls_pull
);
591 gnutls_transport_set_push_function(tls
->session
, (gnutls_push_func
)tls_push
);
592 #if GNUTLS_VERSION_MAJOR < 3
593 gnutls_transport_set_lowat(tls
->session
, 0);
595 tls
->tls_detect
= false;
597 tls
->output_pending
= false;
598 tls
->done_handshake
= false;
599 tls
->have_first_byte
= false;
600 tls
->tls_enabled
= true;
601 tls
->interrupted
= false;
603 new_sock
->state
= SOCKET_STATE_CLIENT_CONNECTED
;
608 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret
)));
609 tls
->tls_enabled
= false;
613 static NTSTATUS
tls_socket_set_option(struct socket_context
*sock
, const char *option
, const char *val
)
615 set_socket_options(socket_get_fd(sock
), option
);
619 static char *tls_socket_get_peer_name(struct socket_context
*sock
, TALLOC_CTX
*mem_ctx
)
621 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
622 return socket_get_peer_name(tls
->socket
, mem_ctx
);
625 static struct socket_address
*tls_socket_get_peer_addr(struct socket_context
*sock
, TALLOC_CTX
*mem_ctx
)
627 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
628 return socket_get_peer_addr(tls
->socket
, mem_ctx
);
631 static struct socket_address
*tls_socket_get_my_addr(struct socket_context
*sock
, TALLOC_CTX
*mem_ctx
)
633 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
634 return socket_get_my_addr(tls
->socket
, mem_ctx
);
637 static int tls_socket_get_fd(struct socket_context
*sock
)
639 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
640 return socket_get_fd(tls
->socket
);
643 static const struct socket_ops tls_socket_ops
= {
645 .fn_init
= tls_socket_init
,
646 .fn_recv
= tls_socket_recv
,
647 .fn_send
= tls_socket_send
,
648 .fn_pending
= tls_socket_pending
,
650 .fn_set_option
= tls_socket_set_option
,
652 .fn_get_peer_name
= tls_socket_get_peer_name
,
653 .fn_get_peer_addr
= tls_socket_get_peer_addr
,
654 .fn_get_my_addr
= tls_socket_get_my_addr
,
655 .fn_get_fd
= tls_socket_get_fd
660 /* for systems without tls we just fail the operations, and the caller
661 * will retain the original socket */
663 struct tls_params
*tls_initialise(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
)
665 return talloc_new(mem_ctx
);
669 setup for a new connection
671 struct socket_context
*tls_init_server(struct tls_params
*params
,
672 struct socket_context
*socket
,
673 struct tevent_fd
*fde
,
674 const char *plain_chars
)
681 setup for a new client connection
683 struct socket_context
*tls_init_client(struct socket_context
*socket
,
684 struct tevent_fd
*fde
,