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 EVENT_FD_NOT_READABLE(tls
->fde
);
130 EVENT_FD_NOT_WRITEABLE(tls
->fde
);
134 if (!NT_STATUS_IS_OK(status
)) {
135 EVENT_FD_READABLE(tls
->fde
);
139 if (tls
->output_pending
) {
140 EVENT_FD_WRITEABLE(tls
->fde
);
143 EVENT_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
);
158 if (!tls
->tls_enabled
) {
162 b
.data
= discard_const(buf
);
165 status
= socket_send(tls
->socket
, &b
, &nwritten
);
166 if (NT_STATUS_EQUAL(status
, STATUS_MORE_ENTRIES
)) {
170 if (!NT_STATUS_IS_OK(status
)) {
171 EVENT_FD_WRITEABLE(tls
->fde
);
174 if (size
!= nwritten
) {
175 EVENT_FD_WRITEABLE(tls
->fde
);
181 destroy a tls session
183 static int tls_destructor(struct tls_context
*tls
)
186 ret
= gnutls_bye(tls
->session
, GNUTLS_SHUT_WR
);
188 DEBUG(0,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret
)));
195 possibly continue the handshake process
197 static NTSTATUS
tls_handshake(struct tls_context
*tls
)
201 if (tls
->done_handshake
) {
205 ret
= gnutls_handshake(tls
->session
);
206 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
207 if (gnutls_record_get_direction(tls
->session
) == 1) {
208 EVENT_FD_WRITEABLE(tls
->fde
);
210 return STATUS_MORE_ENTRIES
;
213 DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret
)));
214 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
216 tls
->done_handshake
= true;
221 possibly continue an interrupted operation
223 static NTSTATUS
tls_interrupted(struct tls_context
*tls
)
227 if (!tls
->interrupted
) {
230 if (gnutls_record_get_direction(tls
->session
) == 1) {
231 ret
= gnutls_record_send(tls
->session
, NULL
, 0);
233 ret
= gnutls_record_recv(tls
->session
, NULL
, 0);
235 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
236 return STATUS_MORE_ENTRIES
;
238 tls
->interrupted
= false;
243 see how many bytes are pending on the connection
245 static NTSTATUS
tls_socket_pending(struct socket_context
*sock
, size_t *npending
)
247 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
248 if (!tls
->tls_enabled
|| tls
->tls_detect
) {
249 return socket_pending(tls
->socket
, npending
);
251 *npending
= gnutls_record_check_pending(tls
->session
);
252 if (*npending
== 0) {
253 NTSTATUS status
= socket_pending(tls
->socket
, npending
);
254 if (*npending
== 0) {
255 /* seems to be a gnutls bug */
264 receive data either by tls or normal socket_recv
266 static NTSTATUS
tls_socket_recv(struct socket_context
*sock
, void *buf
,
267 size_t wantlen
, size_t *nread
)
271 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
273 if (tls
->tls_enabled
&& tls
->tls_detect
) {
274 status
= socket_recv(tls
->socket
, &tls
->first_byte
, 1, nread
);
275 NT_STATUS_NOT_OK_RETURN(status
);
276 if (*nread
== 0) return NT_STATUS_OK
;
277 tls
->tls_detect
= false;
278 /* look for the first byte of a valid HTTP operation */
279 if (strchr(tls
->plain_chars
, tls
->first_byte
)) {
281 tls
->tls_enabled
= false;
282 *(uint8_t *)buf
= tls
->first_byte
;
285 tls
->have_first_byte
= true;
288 if (!tls
->tls_enabled
) {
289 return socket_recv(tls
->socket
, buf
, wantlen
, nread
);
292 status
= tls_handshake(tls
);
293 NT_STATUS_NOT_OK_RETURN(status
);
295 status
= tls_interrupted(tls
);
296 NT_STATUS_NOT_OK_RETURN(status
);
298 ret
= gnutls_record_recv(tls
->session
, buf
, wantlen
);
299 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
300 if (gnutls_record_get_direction(tls
->session
) == 1) {
301 EVENT_FD_WRITEABLE(tls
->fde
);
303 tls
->interrupted
= true;
304 return STATUS_MORE_ENTRIES
;
307 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
315 send data either by tls or normal socket_recv
317 static NTSTATUS
tls_socket_send(struct socket_context
*sock
,
318 const DATA_BLOB
*blob
, size_t *sendlen
)
322 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
324 if (!tls
->tls_enabled
) {
325 return socket_send(tls
->socket
, blob
, sendlen
);
328 status
= tls_handshake(tls
);
329 NT_STATUS_NOT_OK_RETURN(status
);
331 status
= tls_interrupted(tls
);
332 NT_STATUS_NOT_OK_RETURN(status
);
334 ret
= gnutls_record_send(tls
->session
, blob
->data
, blob
->length
);
335 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
336 if (gnutls_record_get_direction(tls
->session
) == 1) {
337 EVENT_FD_WRITEABLE(tls
->fde
);
339 tls
->interrupted
= true;
340 return STATUS_MORE_ENTRIES
;
343 DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob
->length
, gnutls_strerror(ret
)));
344 return NT_STATUS_UNEXPECTED_NETWORK_ERROR
;
347 tls
->output_pending
= (ret
< blob
->length
);
353 initialise global tls state
355 struct tls_params
*tls_initialise(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
)
357 struct tls_params
*params
;
359 TALLOC_CTX
*tmp_ctx
= talloc_new(mem_ctx
);
360 const char *keyfile
= lp_tls_keyfile(tmp_ctx
, lp_ctx
);
361 const char *certfile
= lp_tls_certfile(tmp_ctx
, lp_ctx
);
362 const char *cafile
= lp_tls_cafile(tmp_ctx
, lp_ctx
);
363 const char *crlfile
= lp_tls_crlfile(tmp_ctx
, lp_ctx
);
364 const char *dhpfile
= lp_tls_dhpfile(tmp_ctx
, lp_ctx
);
365 void tls_cert_generate(TALLOC_CTX
*, const char *, const char *, const char *, const char *);
366 params
= talloc(mem_ctx
, struct tls_params
);
367 if (params
== NULL
) {
368 talloc_free(tmp_ctx
);
372 if (!lp_tls_enabled(lp_ctx
) || keyfile
== NULL
|| *keyfile
== 0) {
373 params
->tls_enabled
= false;
374 talloc_free(tmp_ctx
);
378 if (!file_exist(cafile
)) {
379 char *hostname
= talloc_asprintf(mem_ctx
, "%s.%s",
380 lp_netbios_name(lp_ctx
), lp_realm(lp_ctx
));
381 if (hostname
== NULL
) {
384 tls_cert_generate(params
, hostname
, keyfile
, certfile
, cafile
);
385 talloc_free(hostname
);
388 ret
= gnutls_global_init();
389 if (ret
< 0) goto init_failed
;
391 gnutls_certificate_allocate_credentials(¶ms
->x509_cred
);
392 if (ret
< 0) goto init_failed
;
394 if (cafile
&& *cafile
) {
395 ret
= gnutls_certificate_set_x509_trust_file(params
->x509_cred
, cafile
,
396 GNUTLS_X509_FMT_PEM
);
398 DEBUG(0,("TLS failed to initialise cafile %s\n", cafile
));
403 if (crlfile
&& *crlfile
) {
404 ret
= gnutls_certificate_set_x509_crl_file(params
->x509_cred
,
406 GNUTLS_X509_FMT_PEM
);
408 DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile
));
413 ret
= gnutls_certificate_set_x509_key_file(params
->x509_cred
,
415 GNUTLS_X509_FMT_PEM
);
417 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n",
423 ret
= gnutls_dh_params_init(¶ms
->dh_params
);
424 if (ret
< 0) goto init_failed
;
426 if (dhpfile
&& *dhpfile
) {
427 gnutls_datum_t dhparms
;
429 dhparms
.data
= (uint8_t *)file_load(dhpfile
, &size
, 0, mem_ctx
);
432 DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile
));
437 ret
= gnutls_dh_params_import_pkcs3(params
->dh_params
, &dhparms
, GNUTLS_X509_FMT_PEM
);
438 if (ret
< 0) goto init_failed
;
440 ret
= gnutls_dh_params_generate2(params
->dh_params
, DH_BITS
);
441 if (ret
< 0) goto init_failed
;
444 gnutls_certificate_set_dh_params(params
->x509_cred
, params
->dh_params
);
446 params
->tls_enabled
= true;
448 talloc_free(tmp_ctx
);
452 DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret
)));
453 params
->tls_enabled
= false;
454 talloc_free(tmp_ctx
);
460 setup for a new connection
462 struct socket_context
*tls_init_server(struct tls_params
*params
,
463 struct socket_context
*socket_ctx
,
464 struct tevent_fd
*fde
,
465 const char *plain_chars
)
467 struct tls_context
*tls
;
469 struct socket_context
*new_sock
;
472 nt_status
= socket_create_with_ops(socket_ctx
, &tls_socket_ops
, &new_sock
,
474 socket_ctx
->flags
| SOCKET_FLAG_ENCRYPT
);
475 if (!NT_STATUS_IS_OK(nt_status
)) {
479 tls
= talloc(new_sock
, struct tls_context
);
484 tls
->socket
= socket_ctx
;
486 if (talloc_reference(tls
, fde
) == NULL
) {
487 talloc_free(new_sock
);
490 if (talloc_reference(tls
, socket_ctx
) == NULL
) {
491 talloc_free(new_sock
);
495 new_sock
->private_data
= tls
;
497 if (!params
->tls_enabled
) {
498 talloc_free(new_sock
);
502 TLSCHECK(gnutls_init(&tls
->session
, GNUTLS_SERVER
));
504 talloc_set_destructor(tls
, tls_destructor
);
506 TLSCHECK(gnutls_set_default_priority(tls
->session
));
507 TLSCHECK(gnutls_credentials_set(tls
->session
, GNUTLS_CRD_CERTIFICATE
,
509 gnutls_certificate_server_set_request(tls
->session
, GNUTLS_CERT_REQUEST
);
510 gnutls_dh_set_prime_bits(tls
->session
, DH_BITS
);
511 gnutls_transport_set_ptr(tls
->session
, (gnutls_transport_ptr
)tls
);
512 gnutls_transport_set_pull_function(tls
->session
, (gnutls_pull_func
)tls_pull
);
513 gnutls_transport_set_push_function(tls
->session
, (gnutls_push_func
)tls_push
);
514 gnutls_transport_set_lowat(tls
->session
, 0);
516 tls
->plain_chars
= plain_chars
;
518 tls
->tls_detect
= true;
520 tls
->tls_detect
= false;
523 tls
->output_pending
= false;
524 tls
->done_handshake
= false;
525 tls
->have_first_byte
= false;
526 tls
->tls_enabled
= true;
527 tls
->interrupted
= false;
529 new_sock
->state
= SOCKET_STATE_SERVER_CONNECTED
;
534 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret
)));
535 talloc_free(new_sock
);
541 setup for a new client connection
543 struct socket_context
*tls_init_client(struct socket_context
*socket_ctx
,
544 struct tevent_fd
*fde
,
547 struct tls_context
*tls
;
549 const int cert_type_priority
[] = { GNUTLS_CRT_X509
, GNUTLS_CRT_OPENPGP
, 0 };
551 struct socket_context
*new_sock
;
554 nt_status
= socket_create_with_ops(socket_ctx
, &tls_socket_ops
, &new_sock
,
556 socket_ctx
->flags
| SOCKET_FLAG_ENCRYPT
);
557 if (!NT_STATUS_IS_OK(nt_status
)) {
561 tls
= talloc(new_sock
, struct tls_context
);
562 if (tls
== NULL
) return NULL
;
564 tls
->socket
= socket_ctx
;
566 if (talloc_reference(tls
, fde
) == NULL
) {
569 if (talloc_reference(tls
, socket_ctx
) == NULL
) {
572 new_sock
->private_data
= tls
;
574 gnutls_global_init();
576 gnutls_certificate_allocate_credentials(&tls
->xcred
);
577 gnutls_certificate_set_x509_trust_file(tls
->xcred
, cafile
, GNUTLS_X509_FMT_PEM
);
578 TLSCHECK(gnutls_init(&tls
->session
, GNUTLS_CLIENT
));
579 TLSCHECK(gnutls_set_default_priority(tls
->session
));
580 gnutls_certificate_type_set_priority(tls
->session
, cert_type_priority
);
581 TLSCHECK(gnutls_credentials_set(tls
->session
, GNUTLS_CRD_CERTIFICATE
, tls
->xcred
));
583 talloc_set_destructor(tls
, tls_destructor
);
585 gnutls_transport_set_ptr(tls
->session
, (gnutls_transport_ptr
)tls
);
586 gnutls_transport_set_pull_function(tls
->session
, (gnutls_pull_func
)tls_pull
);
587 gnutls_transport_set_push_function(tls
->session
, (gnutls_push_func
)tls_push
);
588 gnutls_transport_set_lowat(tls
->session
, 0);
589 tls
->tls_detect
= false;
591 tls
->output_pending
= false;
592 tls
->done_handshake
= false;
593 tls
->have_first_byte
= false;
594 tls
->tls_enabled
= true;
595 tls
->interrupted
= false;
597 new_sock
->state
= SOCKET_STATE_CLIENT_CONNECTED
;
602 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret
)));
603 tls
->tls_enabled
= false;
607 static NTSTATUS
tls_socket_set_option(struct socket_context
*sock
, const char *option
, const char *val
)
609 set_socket_options(socket_get_fd(sock
), option
);
613 static char *tls_socket_get_peer_name(struct socket_context
*sock
, TALLOC_CTX
*mem_ctx
)
615 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
616 return socket_get_peer_name(tls
->socket
, mem_ctx
);
619 static struct socket_address
*tls_socket_get_peer_addr(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_addr(tls
->socket
, mem_ctx
);
625 static struct socket_address
*tls_socket_get_my_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_my_addr(tls
->socket
, mem_ctx
);
631 static int tls_socket_get_fd(struct socket_context
*sock
)
633 struct tls_context
*tls
= talloc_get_type(sock
->private_data
, struct tls_context
);
634 return socket_get_fd(tls
->socket
);
637 static const struct socket_ops tls_socket_ops
= {
639 .fn_init
= tls_socket_init
,
640 .fn_recv
= tls_socket_recv
,
641 .fn_send
= tls_socket_send
,
642 .fn_pending
= tls_socket_pending
,
644 .fn_set_option
= tls_socket_set_option
,
646 .fn_get_peer_name
= tls_socket_get_peer_name
,
647 .fn_get_peer_addr
= tls_socket_get_peer_addr
,
648 .fn_get_my_addr
= tls_socket_get_my_addr
,
649 .fn_get_fd
= tls_socket_get_fd
652 bool tls_support(struct tls_params
*params
)
654 return params
->tls_enabled
;
659 /* for systems without tls we just fail the operations, and the caller
660 * will retain the original socket */
662 struct tls_params
*tls_initialise(TALLOC_CTX
*mem_ctx
, struct loadparm_context
*lp_ctx
)
664 return talloc_new(mem_ctx
);
668 setup for a new connection
670 struct socket_context
*tls_init_server(struct tls_params
*params
,
671 struct socket_context
*socket
,
672 struct tevent_fd
*fde
,
673 const char *plain_chars
)
680 setup for a new client connection
682 struct socket_context
*tls_init_client(struct socket_context
*socket
,
683 struct tevent_fd
*fde
,
689 bool tls_support(struct tls_params
*params
)