2 Unix SMB/CIFS implementation.
4 Copyright (C) Stefan Metzmacher 2010
6 This program is free software; you can redistribute it and/or modify
7 it under the terms of the GNU General Public License as published by
8 the Free Software Foundation; either version 3 of the License, or
9 (at your option) any later version.
11 This program is distributed in the hope that it will be useful,
12 but WITHOUT ANY WARRANTY; without even the implied warranty of
13 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 GNU General Public License for more details.
16 You should have received a copy of the GNU General Public License
17 along with this program. If not, see <http://www.gnu.org/licenses/>.
21 #include "system/network.h"
22 #include "system/filesys.h"
23 #include "system/time.h"
24 #include "lib/util/util_file.h"
25 #include "../util/tevent_unix.h"
26 #include "../lib/tsocket/tsocket.h"
27 #include "../lib/tsocket/tsocket_internal.h"
28 #include "../lib/util/util_net.h"
29 #include "lib/tls/tls.h"
30 #include "lib/param/param.h"
32 #include <gnutls/gnutls.h>
33 #include <gnutls/x509.h>
34 #include "lib/crypto/gnutls_helpers.h"
38 const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer
)
40 switch (verify_peer
) {
41 case TLS_VERIFY_PEER_NO_CHECK
:
42 return TLS_VERIFY_PEER_NO_CHECK_STRING
;
44 case TLS_VERIFY_PEER_CA_ONLY
:
45 return TLS_VERIFY_PEER_CA_ONLY_STRING
;
47 case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE
:
48 return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING
;
50 case TLS_VERIFY_PEER_CA_AND_NAME
:
51 return TLS_VERIFY_PEER_CA_AND_NAME_STRING
;
53 case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE
:
54 return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING
;
57 return "unknown tls_verify_peer_state";
60 static const struct tstream_context_ops tstream_tls_ops
;
63 struct tstream_context
*plain_stream
;
66 gnutls_session_t tls_session
;
70 enum tls_verify_peer_state verify_peer
;
71 const char *peer_name
;
73 DATA_BLOB channel_bindings
;
75 struct tevent_context
*current_ev
;
77 struct tevent_immediate
*retry_im
;
80 struct tevent_req
*mgmt_req
;
87 struct tevent_req
*subreq
;
93 struct tevent_req
*subreq
;
97 struct tevent_req
*req
;
103 uint8_t buffer
[1024];
104 struct tevent_req
*req
;
110 uint8_t buffer
[1024];
111 struct tevent_req
*req
;
115 struct tevent_req
*req
;
119 static void tstream_tls_retry_handshake(struct tstream_context
*stream
);
120 static void tstream_tls_retry_read(struct tstream_context
*stream
);
121 static void tstream_tls_retry_write(struct tstream_context
*stream
);
122 static void tstream_tls_retry_disconnect(struct tstream_context
*stream
);
123 static void tstream_tls_retry_trigger(struct tevent_context
*ctx
,
124 struct tevent_immediate
*im
,
127 static void tstream_tls_retry(struct tstream_context
*stream
, bool deferred
)
130 struct tstream_tls
*tlss
=
131 tstream_context_data(stream
,
134 if (tlss
->push
.subreq
== NULL
&& tlss
->pull
.subreq
== NULL
) {
135 if (tlss
->waiting_flush
.mgmt_req
!= NULL
) {
136 struct tevent_req
*req
= tlss
->waiting_flush
.mgmt_req
;
138 tlss
->waiting_flush
.mgmt_req
= NULL
;
140 tevent_req_done(req
);
145 if (tlss
->disconnect
.req
) {
146 tstream_tls_retry_disconnect(stream
);
150 if (tlss
->handshake
.req
) {
151 tstream_tls_retry_handshake(stream
);
155 if (tlss
->write
.req
&& tlss
->read
.req
&& !deferred
) {
156 tevent_schedule_immediate(tlss
->retry_im
, tlss
->current_ev
,
157 tstream_tls_retry_trigger
,
161 if (tlss
->write
.req
) {
162 tstream_tls_retry_write(stream
);
166 if (tlss
->read
.req
) {
167 tstream_tls_retry_read(stream
);
172 static void tstream_tls_retry_trigger(struct tevent_context
*ctx
,
173 struct tevent_immediate
*im
,
176 struct tstream_context
*stream
=
177 talloc_get_type_abort(private_data
,
178 struct tstream_context
);
180 tstream_tls_retry(stream
, true);
183 static void tstream_tls_push_done(struct tevent_req
*subreq
);
185 static ssize_t
tstream_tls_push_function(gnutls_transport_ptr_t ptr
,
186 const void *buf
, size_t size
)
188 struct tstream_context
*stream
=
189 talloc_get_type_abort(ptr
,
190 struct tstream_context
);
191 struct tstream_tls
*tlss
=
192 tstream_context_data(stream
,
194 struct tevent_req
*subreq
= NULL
;
198 if (tlss
->error
!= 0) {
203 if (tlss
->push
.subreq
) {
208 len
= MIN(size
, UINT16_MAX
- tlss
->push
.ofs
);
215 nbuf
= talloc_realloc(tlss
, tlss
->push
.buf
,
216 uint8_t, tlss
->push
.ofs
+ len
);
218 if (tlss
->push
.buf
) {
225 tlss
->push
.buf
= nbuf
;
227 memcpy(tlss
->push
.buf
+ tlss
->push
.ofs
, buf
, len
);
228 tlss
->push
.ofs
+= len
;
230 tlss
->push
.iov
.iov_base
= (char *)tlss
->push
.buf
;
231 tlss
->push
.iov
.iov_len
= tlss
->push
.ofs
;
233 subreq
= tstream_writev_send(tlss
,
237 if (subreq
== NULL
) {
241 tevent_req_set_callback(subreq
, tstream_tls_push_done
, stream
);
243 tlss
->push
.subreq
= subreq
;
247 static void tstream_tls_push_done(struct tevent_req
*subreq
)
249 struct tstream_context
*stream
=
250 tevent_req_callback_data(subreq
,
251 struct tstream_context
);
252 struct tstream_tls
*tlss
=
253 tstream_context_data(stream
,
258 tlss
->push
.subreq
= NULL
;
259 ZERO_STRUCT(tlss
->push
.iov
);
260 TALLOC_FREE(tlss
->push
.buf
);
263 ret
= tstream_writev_recv(subreq
, &sys_errno
);
266 tlss
->error
= sys_errno
;
267 tstream_tls_retry(stream
, false);
271 tstream_tls_retry(stream
, false);
274 static void tstream_tls_pull_done(struct tevent_req
*subreq
);
276 static ssize_t
tstream_tls_pull_function(gnutls_transport_ptr_t ptr
,
277 void *buf
, size_t size
)
279 struct tstream_context
*stream
=
280 talloc_get_type_abort(ptr
,
281 struct tstream_context
);
282 struct tstream_tls
*tlss
=
283 tstream_context_data(stream
,
285 struct tevent_req
*subreq
;
288 if (tlss
->error
!= 0) {
293 if (tlss
->pull
.subreq
) {
298 if (tlss
->pull
.iov
.iov_base
) {
302 b
= (uint8_t *)tlss
->pull
.iov
.iov_base
;
304 n
= MIN(tlss
->pull
.iov
.iov_len
, size
);
307 tlss
->pull
.iov
.iov_len
-= n
;
309 tlss
->pull
.iov
.iov_base
= (char *)b
;
310 if (tlss
->pull
.iov
.iov_len
== 0) {
311 tlss
->pull
.iov
.iov_base
= NULL
;
312 TALLOC_FREE(tlss
->pull
.buf
);
322 len
= MIN(size
, UINT16_MAX
);
324 tlss
->pull
.buf
= talloc_array(tlss
, uint8_t, len
);
325 if (tlss
->pull
.buf
== NULL
) {
329 tlss
->pull
.iov
.iov_base
= (char *)tlss
->pull
.buf
;
330 tlss
->pull
.iov
.iov_len
= len
;
332 subreq
= tstream_readv_send(tlss
,
336 if (subreq
== NULL
) {
340 tevent_req_set_callback(subreq
, tstream_tls_pull_done
, stream
);
342 tlss
->pull
.subreq
= subreq
;
347 static void tstream_tls_pull_done(struct tevent_req
*subreq
)
349 struct tstream_context
*stream
=
350 tevent_req_callback_data(subreq
,
351 struct tstream_context
);
352 struct tstream_tls
*tlss
=
353 tstream_context_data(stream
,
358 tlss
->pull
.subreq
= NULL
;
360 ret
= tstream_readv_recv(subreq
, &sys_errno
);
363 tlss
->error
= sys_errno
;
364 tstream_tls_retry(stream
, false);
368 tstream_tls_retry(stream
, false);
371 static int tstream_tls_destructor(struct tstream_tls
*tlss
)
373 if (tlss
->tls_session
) {
374 gnutls_deinit(tlss
->tls_session
);
375 tlss
->tls_session
= NULL
;
381 static ssize_t
tstream_tls_pending_bytes(struct tstream_context
*stream
)
383 struct tstream_tls
*tlss
=
384 tstream_context_data(stream
,
388 if (tlss
->error
!= 0) {
393 ret
= gnutls_record_check_pending(tlss
->tls_session
);
394 ret
+= tlss
->read
.left
;
399 struct tstream_tls_readv_state
{
400 struct tstream_context
*stream
;
402 struct iovec
*vector
;
408 static void tstream_tls_readv_crypt_next(struct tevent_req
*req
);
410 static struct tevent_req
*tstream_tls_readv_send(TALLOC_CTX
*mem_ctx
,
411 struct tevent_context
*ev
,
412 struct tstream_context
*stream
,
413 struct iovec
*vector
,
416 struct tstream_tls
*tlss
=
417 tstream_context_data(stream
,
419 struct tevent_req
*req
;
420 struct tstream_tls_readv_state
*state
;
422 tlss
->read
.req
= NULL
;
424 if (tlss
->current_ev
!= ev
) {
425 SMB_ASSERT(tlss
->push
.subreq
== NULL
);
426 SMB_ASSERT(tlss
->pull
.subreq
== NULL
);
429 tlss
->current_ev
= ev
;
431 req
= tevent_req_create(mem_ctx
, &state
,
432 struct tstream_tls_readv_state
);
437 state
->stream
= stream
;
440 if (tlss
->error
!= 0) {
441 tevent_req_error(req
, tlss
->error
);
442 return tevent_req_post(req
, ev
);
446 * we make a copy of the vector so we can change the structure
448 state
->vector
= talloc_array(state
, struct iovec
, count
);
449 if (tevent_req_nomem(state
->vector
, req
)) {
450 return tevent_req_post(req
, ev
);
452 memcpy(state
->vector
, vector
, sizeof(struct iovec
) * count
);
453 state
->count
= count
;
455 tstream_tls_readv_crypt_next(req
);
456 if (!tevent_req_is_in_progress(req
)) {
457 return tevent_req_post(req
, ev
);
463 static void tstream_tls_readv_crypt_next(struct tevent_req
*req
)
465 struct tstream_tls_readv_state
*state
=
467 struct tstream_tls_readv_state
);
468 struct tstream_tls
*tlss
=
469 tstream_context_data(state
->stream
,
473 * copy the pending buffer first
475 while (tlss
->read
.left
> 0 && state
->count
> 0) {
476 uint8_t *base
= (uint8_t *)state
->vector
[0].iov_base
;
477 size_t len
= MIN(tlss
->read
.left
, state
->vector
[0].iov_len
);
479 memcpy(base
, tlss
->read
.buffer
+ tlss
->read
.ofs
, len
);
482 state
->vector
[0].iov_base
= (char *) base
;
483 state
->vector
[0].iov_len
-= len
;
485 tlss
->read
.ofs
+= len
;
486 tlss
->read
.left
-= len
;
488 if (state
->vector
[0].iov_len
== 0) {
496 if (state
->count
== 0) {
497 tevent_req_done(req
);
501 tlss
->read
.req
= req
;
502 tstream_tls_retry_read(state
->stream
);
505 static void tstream_tls_retry_read(struct tstream_context
*stream
)
507 struct tstream_tls
*tlss
=
508 tstream_context_data(stream
,
510 struct tevent_req
*req
= tlss
->read
.req
;
513 if (tlss
->error
!= 0) {
514 tevent_req_error(req
, tlss
->error
);
521 ret
= gnutls_record_recv(tlss
->tls_session
,
523 sizeof(tlss
->read
.buffer
));
524 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
528 tlss
->read
.req
= NULL
;
530 if (gnutls_error_is_fatal(ret
) != 0) {
531 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
533 tevent_req_error(req
, tlss
->error
);
539 tevent_req_error(req
, tlss
->error
);
543 tlss
->read
.left
= ret
;
544 tstream_tls_readv_crypt_next(req
);
547 static int tstream_tls_readv_recv(struct tevent_req
*req
,
550 struct tstream_tls_readv_state
*state
=
552 struct tstream_tls_readv_state
);
553 struct tstream_tls
*tlss
=
554 tstream_context_data(state
->stream
,
558 tlss
->read
.req
= NULL
;
560 ret
= tsocket_simple_int_recv(req
, perrno
);
565 tevent_req_received(req
);
569 struct tstream_tls_writev_state
{
570 struct tstream_context
*stream
;
572 struct iovec
*vector
;
578 static void tstream_tls_writev_crypt_next(struct tevent_req
*req
);
580 static struct tevent_req
*tstream_tls_writev_send(TALLOC_CTX
*mem_ctx
,
581 struct tevent_context
*ev
,
582 struct tstream_context
*stream
,
583 const struct iovec
*vector
,
586 struct tstream_tls
*tlss
=
587 tstream_context_data(stream
,
589 struct tevent_req
*req
;
590 struct tstream_tls_writev_state
*state
;
592 tlss
->write
.req
= NULL
;
594 if (tlss
->current_ev
!= ev
) {
595 SMB_ASSERT(tlss
->push
.subreq
== NULL
);
596 SMB_ASSERT(tlss
->pull
.subreq
== NULL
);
599 tlss
->current_ev
= ev
;
601 req
= tevent_req_create(mem_ctx
, &state
,
602 struct tstream_tls_writev_state
);
607 state
->stream
= stream
;
610 if (tlss
->error
!= 0) {
611 tevent_req_error(req
, tlss
->error
);
612 return tevent_req_post(req
, ev
);
616 * we make a copy of the vector so we can change the structure
618 state
->vector
= talloc_array(state
, struct iovec
, count
);
619 if (tevent_req_nomem(state
->vector
, req
)) {
620 return tevent_req_post(req
, ev
);
622 memcpy(state
->vector
, vector
, sizeof(struct iovec
) * count
);
623 state
->count
= count
;
625 tstream_tls_writev_crypt_next(req
);
626 if (!tevent_req_is_in_progress(req
)) {
627 return tevent_req_post(req
, ev
);
633 static void tstream_tls_writev_crypt_next(struct tevent_req
*req
)
635 struct tstream_tls_writev_state
*state
=
637 struct tstream_tls_writev_state
);
638 struct tstream_tls
*tlss
=
639 tstream_context_data(state
->stream
,
642 tlss
->write
.left
= sizeof(tlss
->write
.buffer
);
646 * first fill our buffer
648 while (tlss
->write
.left
> 0 && state
->count
> 0) {
649 uint8_t *base
= (uint8_t *)state
->vector
[0].iov_base
;
650 size_t len
= MIN(tlss
->write
.left
, state
->vector
[0].iov_len
);
652 memcpy(tlss
->write
.buffer
+ tlss
->write
.ofs
, base
, len
);
655 state
->vector
[0].iov_base
= (char *) base
;
656 state
->vector
[0].iov_len
-= len
;
658 tlss
->write
.ofs
+= len
;
659 tlss
->write
.left
-= len
;
661 if (state
->vector
[0].iov_len
== 0) {
669 if (tlss
->write
.ofs
== 0) {
670 tevent_req_done(req
);
674 tlss
->write
.left
= tlss
->write
.ofs
;
677 tlss
->write
.req
= req
;
678 tstream_tls_retry_write(state
->stream
);
681 static void tstream_tls_retry_write(struct tstream_context
*stream
)
683 struct tstream_tls
*tlss
=
684 tstream_context_data(stream
,
686 struct tevent_req
*req
= tlss
->write
.req
;
689 if (tlss
->error
!= 0) {
690 tevent_req_error(req
, tlss
->error
);
694 ret
= gnutls_record_send(tlss
->tls_session
,
695 tlss
->write
.buffer
+ tlss
->write
.ofs
,
697 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
701 tlss
->write
.req
= NULL
;
703 if (gnutls_error_is_fatal(ret
) != 0) {
704 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
706 tevent_req_error(req
, tlss
->error
);
712 tevent_req_error(req
, tlss
->error
);
716 tlss
->write
.ofs
+= ret
;
717 tlss
->write
.left
-= ret
;
719 if (tlss
->write
.left
> 0) {
720 tlss
->write
.req
= req
;
721 tstream_tls_retry_write(stream
);
725 tstream_tls_writev_crypt_next(req
);
728 static int tstream_tls_writev_recv(struct tevent_req
*req
,
731 struct tstream_tls_writev_state
*state
=
733 struct tstream_tls_writev_state
);
734 struct tstream_tls
*tlss
=
735 tstream_context_data(state
->stream
,
739 tlss
->write
.req
= NULL
;
741 ret
= tsocket_simple_int_recv(req
, perrno
);
746 tevent_req_received(req
);
750 struct tstream_tls_disconnect_state
{
754 static struct tevent_req
*tstream_tls_disconnect_send(TALLOC_CTX
*mem_ctx
,
755 struct tevent_context
*ev
,
756 struct tstream_context
*stream
)
758 struct tstream_tls
*tlss
=
759 tstream_context_data(stream
,
761 struct tevent_req
*req
;
762 struct tstream_tls_disconnect_state
*state
;
764 tlss
->disconnect
.req
= NULL
;
766 if (tlss
->current_ev
!= ev
) {
767 SMB_ASSERT(tlss
->push
.subreq
== NULL
);
768 SMB_ASSERT(tlss
->pull
.subreq
== NULL
);
771 tlss
->current_ev
= ev
;
773 req
= tevent_req_create(mem_ctx
, &state
,
774 struct tstream_tls_disconnect_state
);
779 if (tlss
->error
!= 0) {
780 tevent_req_error(req
, tlss
->error
);
781 return tevent_req_post(req
, ev
);
784 tlss
->disconnect
.req
= req
;
785 tstream_tls_retry_disconnect(stream
);
786 if (!tevent_req_is_in_progress(req
)) {
787 return tevent_req_post(req
, ev
);
793 static void tstream_tls_retry_disconnect(struct tstream_context
*stream
)
795 struct tstream_tls
*tlss
=
796 tstream_context_data(stream
,
798 struct tevent_req
*req
= tlss
->disconnect
.req
;
801 if (tlss
->error
!= 0) {
802 tevent_req_error(req
, tlss
->error
);
806 ret
= gnutls_bye(tlss
->tls_session
, GNUTLS_SHUT_WR
);
807 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
811 tlss
->disconnect
.req
= NULL
;
813 if (gnutls_error_is_fatal(ret
) != 0) {
814 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
816 tevent_req_error(req
, tlss
->error
);
820 if (ret
!= GNUTLS_E_SUCCESS
) {
821 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
823 tevent_req_error(req
, tlss
->error
);
827 if (tlss
->push
.subreq
!= NULL
|| tlss
->pull
.subreq
!= NULL
) {
828 tlss
->waiting_flush
.mgmt_req
= req
;
832 tevent_req_done(req
);
835 static int tstream_tls_disconnect_recv(struct tevent_req
*req
,
840 ret
= tsocket_simple_int_recv(req
, perrno
);
842 tevent_req_received(req
);
846 static const struct tstream_context_ops tstream_tls_ops
= {
849 .pending_bytes
= tstream_tls_pending_bytes
,
851 .readv_send
= tstream_tls_readv_send
,
852 .readv_recv
= tstream_tls_readv_recv
,
854 .writev_send
= tstream_tls_writev_send
,
855 .writev_recv
= tstream_tls_writev_recv
,
857 .disconnect_send
= tstream_tls_disconnect_send
,
858 .disconnect_recv
= tstream_tls_disconnect_recv
,
861 struct tstream_tls_params_internal
{
862 gnutls_certificate_credentials_t x509_cred
;
863 gnutls_dh_params_t dh_params
;
864 const char *tls_priority
;
866 enum tls_verify_peer_state verify_peer
;
867 const char *peer_name
;
870 struct tstream_tls_params
{
871 struct tstream_tls_params_internal
*internal
;
874 static int tstream_tls_params_internal_destructor(struct tstream_tls_params_internal
*tlsp
)
876 if (tlsp
->x509_cred
) {
877 gnutls_certificate_free_credentials(tlsp
->x509_cred
);
878 tlsp
->x509_cred
= NULL
;
880 if (tlsp
->dh_params
) {
881 gnutls_dh_params_deinit(tlsp
->dh_params
);
882 tlsp
->dh_params
= NULL
;
888 bool tstream_tls_params_enabled(struct tstream_tls_params
*tls_params
)
890 struct tstream_tls_params_internal
*tlsp
= tls_params
->internal
;
892 return tlsp
->tls_enabled
;
895 static NTSTATUS
tstream_tls_setup_channel_bindings(struct tstream_tls
*tlss
)
897 gnutls_datum_t cb
= { .size
= 0 };
900 #ifdef HAVE_GNUTLS_CB_TLS_SERVER_END_POINT
901 ret
= gnutls_session_channel_binding(tlss
->tls_session
,
902 GNUTLS_CB_TLS_SERVER_END_POINT
,
904 #else /* not HAVE_GNUTLS_CB_TLS_SERVER_END_POINT */
905 ret
= legacy_gnutls_server_end_point_cb(tlss
->tls_session
,
908 #endif /* not HAVE_GNUTLS_CB_TLS_SERVER_END_POINT */
909 if (ret
!= GNUTLS_E_SUCCESS
) {
910 return gnutls_error_to_ntstatus(ret
,
911 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
916 * Looking at the OpenLDAP implementation
917 * for LDAP_OPT_X_SASL_CBINDING_TLS_ENDPOINT
918 * revealed that we need to prefix it with
919 * 'tls-server-end-point:'
921 const char endpoint_prefix
[] = "tls-server-end-point:";
922 size_t prefix_size
= strlen(endpoint_prefix
);
923 size_t size
= prefix_size
+ cb
.size
;
925 tlss
->channel_bindings
= data_blob_talloc_named(tlss
, NULL
, size
,
926 "tls_channel_bindings");
927 if (tlss
->channel_bindings
.data
== NULL
) {
928 gnutls_free(cb
.data
);
929 return NT_STATUS_NO_MEMORY
;
931 memcpy(tlss
->channel_bindings
.data
, endpoint_prefix
, prefix_size
);
932 memcpy(tlss
->channel_bindings
.data
+ prefix_size
, cb
.data
, cb
.size
);
933 gnutls_free(cb
.data
);
939 const DATA_BLOB
*tstream_tls_channel_bindings(struct tstream_context
*tls_tstream
)
941 struct tstream_tls
*tlss
=
942 talloc_get_type(_tstream_context_data(tls_tstream
),
949 return &tlss
->channel_bindings
;
952 NTSTATUS
tstream_tls_params_client(TALLOC_CTX
*mem_ctx
,
954 const char * const *ca_dirs
,
956 const char *crl_file
,
957 const char *tls_priority
,
958 enum tls_verify_peer_state verify_peer
,
959 const char *peer_name
,
960 struct tstream_tls_params
**_tlsp
)
962 struct tstream_tls_params
*__tlsp
= NULL
;
963 struct tstream_tls_params_internal
*tlsp
= NULL
;
968 __tlsp
= talloc_zero(mem_ctx
, struct tstream_tls_params
);
969 if (__tlsp
== NULL
) {
970 return NT_STATUS_NO_MEMORY
;
973 tlsp
= talloc_zero(__tlsp
, struct tstream_tls_params_internal
);
976 return NT_STATUS_NO_MEMORY
;
978 talloc_set_destructor(tlsp
, tstream_tls_params_internal_destructor
);
979 __tlsp
->internal
= tlsp
;
981 tlsp
->verify_peer
= verify_peer
;
982 if (peer_name
!= NULL
) {
983 tlsp
->peer_name
= talloc_strdup(tlsp
, peer_name
);
984 if (tlsp
->peer_name
== NULL
) {
986 return NT_STATUS_NO_MEMORY
;
988 } else if (tlsp
->verify_peer
>= TLS_VERIFY_PEER_CA_AND_NAME
) {
989 DEBUG(0,("TLS failed to missing peer_name - "
990 "with 'tls verify peer = %s'\n",
991 tls_verify_peer_string(tlsp
->verify_peer
)));
993 return NT_STATUS_INVALID_PARAMETER_MIX
;
996 ret
= gnutls_certificate_allocate_credentials(&tlsp
->x509_cred
);
997 if (ret
!= GNUTLS_E_SUCCESS
) {
998 DEBUG(0,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
1000 return NT_STATUS_NO_MEMORY
;
1004 ret
= gnutls_certificate_set_x509_system_trust(tlsp
->x509_cred
);
1006 DBG_ERR("gnutls_certificate_set_x509_system_trust() - %s\n",
1007 gnutls_strerror(ret
));
1008 TALLOC_FREE(__tlsp
);
1009 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1016 for (i
= 0; ca_dirs
!= NULL
&& ca_dirs
[i
] != NULL
; i
++) {
1017 const char *ca_dir
= ca_dirs
[i
];
1019 if (!directory_exist(ca_dir
)) {
1023 ret
= gnutls_certificate_set_x509_trust_dir(tlsp
->x509_cred
,
1025 GNUTLS_X509_FMT_PEM
);
1027 DBG_ERR("gnutls_certificate_set_x509_trust_dir(%s) - %s\n",
1028 ca_dir
, gnutls_strerror(ret
));
1029 TALLOC_FREE(__tlsp
);
1030 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1037 if (ca_file
&& *ca_file
&& file_exist(ca_file
)) {
1038 ret
= gnutls_certificate_set_x509_trust_file(tlsp
->x509_cred
,
1040 GNUTLS_X509_FMT_PEM
);
1042 DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
1043 ca_file
, gnutls_strerror(ret
)));
1044 TALLOC_FREE(__tlsp
);
1045 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1052 if (!got_ca
&& tlsp
->verify_peer
>= TLS_VERIFY_PEER_CA_ONLY
) {
1053 D_ERR("TLS: 'tls verify peer = %s' requires "
1054 "'tls trust system cas', "
1055 "'tls ca directories' or "
1057 tls_verify_peer_string(tlsp
->verify_peer
));
1058 TALLOC_FREE(__tlsp
);
1059 return NT_STATUS_INVALID_PARAMETER_MIX
;
1062 if (crl_file
&& *crl_file
&& file_exist(crl_file
)) {
1063 ret
= gnutls_certificate_set_x509_crl_file(tlsp
->x509_cred
,
1065 GNUTLS_X509_FMT_PEM
);
1067 DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
1068 crl_file
, gnutls_strerror(ret
)));
1069 TALLOC_FREE(__tlsp
);
1070 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1072 } else if (tlsp
->verify_peer
>= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE
) {
1073 DEBUG(0,("TLS failed to missing crlfile %s - "
1074 "with 'tls verify peer = %s'\n",
1076 tls_verify_peer_string(tlsp
->verify_peer
)));
1077 TALLOC_FREE(__tlsp
);
1078 return NT_STATUS_INVALID_PARAMETER_MIX
;
1081 tlsp
->tls_priority
= talloc_strdup(tlsp
, tls_priority
);
1082 if (tlsp
->tls_priority
== NULL
) {
1083 TALLOC_FREE(__tlsp
);
1084 return NT_STATUS_NO_MEMORY
;
1087 tlsp
->tls_enabled
= true;
1090 return NT_STATUS_OK
;
1093 NTSTATUS
tstream_tls_params_client_lpcfg(TALLOC_CTX
*mem_ctx
,
1094 struct loadparm_context
*lp_ctx
,
1095 const char *peer_name
,
1096 struct tstream_tls_params
**tlsp
)
1098 TALLOC_CTX
*frame
= talloc_stackframe();
1099 bool system_cas
= false;
1100 const char * const *ca_dirs
= NULL
;
1101 const char *ptr
= NULL
;
1102 char *ca_file
= NULL
;
1103 char *crl_file
= NULL
;
1104 const char *tls_priority
= NULL
;
1105 enum tls_verify_peer_state verify_peer
=
1106 TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE
;
1109 system_cas
= lpcfg_tls_trust_system_cas(lp_ctx
);
1110 ca_dirs
= lpcfg_tls_ca_directories(lp_ctx
);
1112 ptr
= lpcfg__tls_cafile(lp_ctx
);
1114 ca_file
= lpcfg_tls_cafile(frame
, lp_ctx
);
1115 if (ca_file
== NULL
) {
1117 return NT_STATUS_NO_MEMORY
;
1121 ptr
= lpcfg__tls_crlfile(lp_ctx
);
1123 crl_file
= lpcfg_tls_crlfile(frame
, lp_ctx
);
1124 if (crl_file
== NULL
) {
1126 return NT_STATUS_NO_MEMORY
;
1130 tls_priority
= lpcfg_tls_priority(lp_ctx
);
1131 verify_peer
= lpcfg_tls_verify_peer(lp_ctx
);
1133 status
= tstream_tls_params_client(mem_ctx
,
1146 static NTSTATUS
tstream_tls_prepare_gnutls(struct tstream_tls_params
*_tlsp
,
1147 struct tstream_tls
*tlss
)
1149 struct tstream_tls_params_internal
*tlsp
= NULL
;
1152 const char *hostname
= NULL
;
1154 if (tlss
->is_server
) {
1155 flags
= GNUTLS_SERVER
;
1157 flags
= GNUTLS_CLIENT
;
1159 * tls_tstream can't properly handle 'New Session Ticket'
1160 * messages sent 'after' the client sends the 'Finished'
1161 * message. GNUTLS_NO_TICKETS was introduced in GnuTLS 3.5.6.
1162 * This flag is to indicate the session Flag session should not
1163 * use resumption with session tickets.
1165 flags
|= GNUTLS_NO_TICKETS
;
1169 * Note we need to make sure x509_cred and dh_params
1170 * from tstream_tls_params_internal stay alive for
1171 * the whole lifetime of this session!
1173 * See 'man gnutls_credentials_set' and
1174 * 'man gnutls_certificate_set_dh_params'.
1176 * Note: here we use talloc_reference() in a way
1177 * that does not expose it to the caller.
1179 tlsp
= talloc_reference(tlss
, _tlsp
->internal
);
1181 return NT_STATUS_NO_MEMORY
;
1184 tlss
->verify_peer
= tlsp
->verify_peer
;
1185 if (tlsp
->peer_name
!= NULL
) {
1186 bool ip
= is_ipaddress(tlsp
->peer_name
);
1188 tlss
->peer_name
= talloc_strdup(tlss
, tlsp
->peer_name
);
1189 if (tlss
->peer_name
== NULL
) {
1190 return NT_STATUS_NO_MEMORY
;
1194 hostname
= tlss
->peer_name
;
1197 if (tlss
->verify_peer
< TLS_VERIFY_PEER_CA_AND_NAME
) {
1202 if (tlss
->current_ev
!= NULL
) {
1203 tlss
->retry_im
= tevent_create_immediate(tlss
);
1204 if (tlss
->retry_im
== NULL
) {
1205 return NT_STATUS_NO_MEMORY
;
1209 ret
= gnutls_init(&tlss
->tls_session
, flags
);
1210 if (ret
!= GNUTLS_E_SUCCESS
) {
1211 return gnutls_error_to_ntstatus(ret
,
1212 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1215 ret
= gnutls_set_default_priority(tlss
->tls_session
);
1216 if (ret
!= GNUTLS_E_SUCCESS
) {
1217 return gnutls_error_to_ntstatus(ret
,
1218 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1221 if (strlen(tlsp
->tls_priority
) > 0) {
1222 const char *error_pos
= NULL
;
1224 ret
= gnutls_priority_set_direct(tlss
->tls_session
,
1227 if (ret
!= GNUTLS_E_SUCCESS
) {
1228 return gnutls_error_to_ntstatus(ret
,
1229 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1233 ret
= gnutls_credentials_set(tlss
->tls_session
,
1234 GNUTLS_CRD_CERTIFICATE
,
1236 if (ret
!= GNUTLS_E_SUCCESS
) {
1237 return gnutls_error_to_ntstatus(ret
,
1238 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1241 if (hostname
!= NULL
) {
1242 ret
= gnutls_server_name_set(tlss
->tls_session
,
1246 if (ret
!= GNUTLS_E_SUCCESS
) {
1247 return gnutls_error_to_ntstatus(ret
,
1248 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1252 if (tlss
->is_server
) {
1253 gnutls_certificate_server_set_request(tlss
->tls_session
,
1254 GNUTLS_CERT_REQUEST
);
1255 gnutls_dh_set_prime_bits(tlss
->tls_session
, DH_BITS
);
1258 return NT_STATUS_OK
;
1261 static NTSTATUS
tstream_tls_verify_peer(struct tstream_tls
*tlss
)
1263 unsigned int status
= UINT32_MAX
;
1265 const char *hostname
= NULL
;
1268 if (tlss
->verify_peer
== TLS_VERIFY_PEER_NO_CHECK
) {
1269 return NT_STATUS_OK
;
1272 if (tlss
->peer_name
!= NULL
) {
1273 ip
= is_ipaddress(tlss
->peer_name
);
1277 hostname
= tlss
->peer_name
;
1280 if (tlss
->verify_peer
== TLS_VERIFY_PEER_CA_ONLY
) {
1284 if (tlss
->verify_peer
>= TLS_VERIFY_PEER_CA_AND_NAME
) {
1285 if (hostname
== NULL
) {
1286 DEBUG(1,("TLS %s - no hostname available for "
1287 "verify_peer[%s] and peer_name[%s]\n",
1289 tls_verify_peer_string(tlss
->verify_peer
),
1291 return NT_STATUS_IMAGE_CERT_REVOKED
;
1295 ret
= gnutls_certificate_verify_peers3(tlss
->tls_session
,
1298 if (ret
!= GNUTLS_E_SUCCESS
) {
1299 return gnutls_error_to_ntstatus(ret
,
1300 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1304 DEBUG(1,("TLS %s - check failed for "
1305 "verify_peer[%s] and peer_name[%s] "
1306 "status 0x%x (%s%s%s%s%s%s%s%s)\n",
1308 tls_verify_peer_string(tlss
->verify_peer
),
1311 status
& GNUTLS_CERT_INVALID
? "invalid " : "",
1312 status
& GNUTLS_CERT_REVOKED
? "revoked " : "",
1313 status
& GNUTLS_CERT_SIGNER_NOT_FOUND
?
1314 "signer_not_found " : "",
1315 status
& GNUTLS_CERT_SIGNER_NOT_CA
?
1316 "signer_not_ca " : "",
1317 status
& GNUTLS_CERT_INSECURE_ALGORITHM
?
1318 "insecure_algorithm " : "",
1319 status
& GNUTLS_CERT_NOT_ACTIVATED
?
1320 "not_activated " : "",
1321 status
& GNUTLS_CERT_EXPIRED
?
1323 status
& GNUTLS_CERT_UNEXPECTED_OWNER
?
1324 "unexpected_owner " : ""));
1325 return NT_STATUS_IMAGE_CERT_REVOKED
;
1328 return NT_STATUS_OK
;
1331 struct tstream_tls_connect_state
{
1332 struct tstream_context
*tls_stream
;
1335 struct tevent_req
*_tstream_tls_connect_send(TALLOC_CTX
*mem_ctx
,
1336 struct tevent_context
*ev
,
1337 struct tstream_context
*plain_stream
,
1338 struct tstream_tls_params
*_tls_params
,
1339 const char *location
)
1341 struct tevent_req
*req
;
1342 struct tstream_tls_connect_state
*state
;
1343 struct tstream_tls
*tlss
;
1346 req
= tevent_req_create(mem_ctx
, &state
,
1347 struct tstream_tls_connect_state
);
1352 state
->tls_stream
= tstream_context_create(state
,
1357 if (tevent_req_nomem(state
->tls_stream
, req
)) {
1358 return tevent_req_post(req
, ev
);
1361 talloc_set_destructor(tlss
, tstream_tls_destructor
);
1362 tlss
->plain_stream
= plain_stream
;
1363 tlss
->is_server
= false;
1364 tlss
->current_ev
= ev
;
1366 status
= tstream_tls_prepare_gnutls(_tls_params
, tlss
);
1367 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_MEMORY
)) {
1368 tevent_req_oom(req
);
1369 return tevent_req_post(req
, ev
);
1371 if (!NT_STATUS_IS_OK(status
)) {
1372 tevent_req_error(req
, EINVAL
);
1373 return tevent_req_post(req
, ev
);
1376 gnutls_transport_set_ptr(tlss
->tls_session
,
1377 (gnutls_transport_ptr_t
)state
->tls_stream
);
1378 gnutls_transport_set_pull_function(tlss
->tls_session
,
1379 (gnutls_pull_func
)tstream_tls_pull_function
);
1380 gnutls_transport_set_push_function(tlss
->tls_session
,
1381 (gnutls_push_func
)tstream_tls_push_function
);
1383 tlss
->handshake
.req
= req
;
1384 tstream_tls_retry_handshake(state
->tls_stream
);
1385 if (!tevent_req_is_in_progress(req
)) {
1386 return tevent_req_post(req
, ev
);
1392 int tstream_tls_connect_recv(struct tevent_req
*req
,
1394 TALLOC_CTX
*mem_ctx
,
1395 struct tstream_context
**tls_stream
)
1397 struct tstream_tls_connect_state
*state
=
1398 tevent_req_data(req
,
1399 struct tstream_tls_connect_state
);
1401 if (tevent_req_is_unix_error(req
, perrno
)) {
1402 tevent_req_received(req
);
1406 *tls_stream
= talloc_move(mem_ctx
, &state
->tls_stream
);
1407 tevent_req_received(req
);
1412 initialise global tls state
1414 NTSTATUS
tstream_tls_params_server(TALLOC_CTX
*mem_ctx
,
1415 const char *dns_host_name
,
1417 const char *key_file
,
1418 const char *cert_file
,
1419 const char *ca_file
,
1420 const char *crl_file
,
1421 const char *dhp_file
,
1422 const char *tls_priority
,
1423 struct tstream_tls_params
**_tlsp
)
1425 struct tstream_tls_params
*__tlsp
= NULL
;
1426 struct tstream_tls_params_internal
*tlsp
= NULL
;
1430 if (!enabled
|| key_file
== NULL
|| *key_file
== 0) {
1431 __tlsp
= talloc_zero(mem_ctx
, struct tstream_tls_params
);
1432 if (__tlsp
== NULL
) {
1433 return NT_STATUS_NO_MEMORY
;
1436 tlsp
= talloc_zero(__tlsp
, struct tstream_tls_params_internal
);
1438 TALLOC_FREE(__tlsp
);
1439 return NT_STATUS_NO_MEMORY
;
1442 talloc_set_destructor(tlsp
, tstream_tls_params_internal_destructor
);
1443 __tlsp
->internal
= tlsp
;
1444 tlsp
->tls_enabled
= false;
1447 return NT_STATUS_OK
;
1450 __tlsp
= talloc_zero(mem_ctx
, struct tstream_tls_params
);
1451 if (__tlsp
== NULL
) {
1452 return NT_STATUS_NO_MEMORY
;
1455 tlsp
= talloc_zero(__tlsp
, struct tstream_tls_params_internal
);
1457 TALLOC_FREE(__tlsp
);
1458 return NT_STATUS_NO_MEMORY
;
1461 talloc_set_destructor(tlsp
, tstream_tls_params_internal_destructor
);
1462 __tlsp
->internal
= tlsp
;
1464 if (!file_exist(ca_file
)) {
1465 tls_cert_generate(tlsp
, dns_host_name
,
1466 key_file
, cert_file
, ca_file
);
1469 if (file_exist(key_file
) &&
1470 !file_check_permissions(key_file
, geteuid(), 0600, &st
))
1472 DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n"
1473 "owner uid %u should be %u, mode 0%o should be 0%o\n"
1474 "This is known as CVE-2013-4476.\n"
1475 "Removing all tls .pem files will cause an "
1476 "auto-regeneration with the correct permissions.\n",
1478 (unsigned int)st
.st_uid
, geteuid(),
1479 (unsigned int)(st
.st_mode
& 0777), 0600));
1480 TALLOC_FREE(__tlsp
);
1481 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1484 ret
= gnutls_certificate_allocate_credentials(&tlsp
->x509_cred
);
1485 if (ret
!= GNUTLS_E_SUCCESS
) {
1486 DEBUG(0,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
1487 TALLOC_FREE(__tlsp
);
1488 return NT_STATUS_NO_MEMORY
;
1491 if (ca_file
&& *ca_file
) {
1492 ret
= gnutls_certificate_set_x509_trust_file(tlsp
->x509_cred
,
1494 GNUTLS_X509_FMT_PEM
);
1496 DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
1497 ca_file
, gnutls_strerror(ret
)));
1498 TALLOC_FREE(__tlsp
);
1499 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1503 if (crl_file
&& *crl_file
) {
1504 ret
= gnutls_certificate_set_x509_crl_file(tlsp
->x509_cred
,
1506 GNUTLS_X509_FMT_PEM
);
1508 DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
1509 crl_file
, gnutls_strerror(ret
)));
1510 TALLOC_FREE(__tlsp
);
1511 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1515 ret
= gnutls_certificate_set_x509_key_file(tlsp
->x509_cred
,
1516 cert_file
, key_file
,
1517 GNUTLS_X509_FMT_PEM
);
1518 if (ret
!= GNUTLS_E_SUCCESS
) {
1519 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s - %s\n",
1520 cert_file
, key_file
, gnutls_strerror(ret
)));
1521 TALLOC_FREE(__tlsp
);
1522 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1525 ret
= gnutls_dh_params_init(&tlsp
->dh_params
);
1526 if (ret
!= GNUTLS_E_SUCCESS
) {
1527 DEBUG(0,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
1528 TALLOC_FREE(__tlsp
);
1529 return NT_STATUS_NO_MEMORY
;
1532 if (dhp_file
&& *dhp_file
) {
1533 gnutls_datum_t dhparms
;
1536 dhparms
.data
= (uint8_t *)file_load(dhp_file
, &size
, 0, tlsp
);
1538 if (!dhparms
.data
) {
1539 DEBUG(0,("TLS failed to read DH Parms from %s - %d:%s\n",
1540 dhp_file
, errno
, strerror(errno
)));
1541 TALLOC_FREE(__tlsp
);
1542 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1544 dhparms
.size
= size
;
1546 ret
= gnutls_dh_params_import_pkcs3(tlsp
->dh_params
,
1548 GNUTLS_X509_FMT_PEM
);
1549 if (ret
!= GNUTLS_E_SUCCESS
) {
1550 DEBUG(0,("TLS failed to import pkcs3 %s - %s\n",
1551 dhp_file
, gnutls_strerror(ret
)));
1552 TALLOC_FREE(__tlsp
);
1553 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO
;
1556 ret
= gnutls_dh_params_generate2(tlsp
->dh_params
, DH_BITS
);
1557 if (ret
!= GNUTLS_E_SUCCESS
) {
1558 DEBUG(0,("TLS failed to generate dh_params - %s\n",
1559 gnutls_strerror(ret
)));
1560 TALLOC_FREE(__tlsp
);
1561 return NT_STATUS_INTERNAL_ERROR
;
1565 gnutls_certificate_set_dh_params(tlsp
->x509_cred
, tlsp
->dh_params
);
1567 tlsp
->tls_priority
= talloc_strdup(tlsp
, tls_priority
);
1568 if (tlsp
->tls_priority
== NULL
) {
1569 TALLOC_FREE(__tlsp
);
1570 return NT_STATUS_NO_MEMORY
;
1573 tlsp
->tls_enabled
= true;
1576 return NT_STATUS_OK
;
1579 struct tstream_tls_accept_state
{
1580 struct tstream_context
*tls_stream
;
1583 struct tevent_req
*_tstream_tls_accept_send(TALLOC_CTX
*mem_ctx
,
1584 struct tevent_context
*ev
,
1585 struct tstream_context
*plain_stream
,
1586 struct tstream_tls_params
*_tlsp
,
1587 const char *location
)
1589 struct tevent_req
*req
;
1590 struct tstream_tls_accept_state
*state
;
1591 struct tstream_tls
*tlss
;
1594 req
= tevent_req_create(mem_ctx
, &state
,
1595 struct tstream_tls_accept_state
);
1600 state
->tls_stream
= tstream_context_create(state
,
1605 if (tevent_req_nomem(state
->tls_stream
, req
)) {
1606 return tevent_req_post(req
, ev
);
1609 talloc_set_destructor(tlss
, tstream_tls_destructor
);
1610 tlss
->plain_stream
= plain_stream
;
1611 tlss
->is_server
= true;
1612 tlss
->current_ev
= ev
;
1614 status
= tstream_tls_prepare_gnutls(_tlsp
, tlss
);
1615 if (NT_STATUS_EQUAL(status
, NT_STATUS_NO_MEMORY
)) {
1616 tevent_req_oom(req
);
1617 return tevent_req_post(req
, ev
);
1619 if (!NT_STATUS_IS_OK(status
)) {
1620 tevent_req_error(req
, EINVAL
);
1621 return tevent_req_post(req
, ev
);
1624 gnutls_transport_set_ptr(tlss
->tls_session
,
1625 (gnutls_transport_ptr_t
)state
->tls_stream
);
1626 gnutls_transport_set_pull_function(tlss
->tls_session
,
1627 (gnutls_pull_func
)tstream_tls_pull_function
);
1628 gnutls_transport_set_push_function(tlss
->tls_session
,
1629 (gnutls_push_func
)tstream_tls_push_function
);
1631 tlss
->handshake
.req
= req
;
1632 tstream_tls_retry_handshake(state
->tls_stream
);
1633 if (!tevent_req_is_in_progress(req
)) {
1634 return tevent_req_post(req
, ev
);
1640 static void tstream_tls_retry_handshake(struct tstream_context
*stream
)
1642 struct tstream_tls
*tlss
=
1643 tstream_context_data(stream
,
1644 struct tstream_tls
);
1645 struct tevent_req
*req
= tlss
->handshake
.req
;
1649 if (tlss
->error
!= 0) {
1650 tevent_req_error(req
, tlss
->error
);
1654 ret
= gnutls_handshake(tlss
->tls_session
);
1655 if (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
) {
1659 tlss
->handshake
.req
= NULL
;
1661 if (gnutls_error_is_fatal(ret
) != 0) {
1662 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
1664 tevent_req_error(req
, tlss
->error
);
1668 if (ret
!= GNUTLS_E_SUCCESS
) {
1669 DEBUG(1,("TLS %s - %s\n", __location__
, gnutls_strerror(ret
)));
1671 tevent_req_error(req
, tlss
->error
);
1675 status
= tstream_tls_verify_peer(tlss
);
1676 if (NT_STATUS_EQUAL(status
, NT_STATUS_IMAGE_CERT_REVOKED
)) {
1677 tlss
->error
= EINVAL
;
1678 tevent_req_error(req
, tlss
->error
);
1681 if (!NT_STATUS_IS_OK(status
)) {
1683 tevent_req_error(req
, tlss
->error
);
1687 status
= tstream_tls_setup_channel_bindings(tlss
);
1688 if (!NT_STATUS_IS_OK(status
)) {
1690 tevent_req_error(req
, tlss
->error
);
1694 if (tlss
->push
.subreq
!= NULL
|| tlss
->pull
.subreq
!= NULL
) {
1695 tlss
->waiting_flush
.mgmt_req
= req
;
1699 tevent_req_done(req
);
1702 int tstream_tls_accept_recv(struct tevent_req
*req
,
1704 TALLOC_CTX
*mem_ctx
,
1705 struct tstream_context
**tls_stream
)
1707 struct tstream_tls_accept_state
*state
=
1708 tevent_req_data(req
,
1709 struct tstream_tls_accept_state
);
1711 if (tevent_req_is_unix_error(req
, perrno
)) {
1712 tevent_req_received(req
);
1716 *tls_stream
= talloc_move(mem_ctx
, &state
->tls_stream
);
1717 tevent_req_received(req
);
1721 struct tstream_tls_sync
{
1722 struct tstream_tls
*tlss
;
1724 ssize_t (*io_send_fn
)(void *io_private
,
1727 ssize_t (*io_recv_fn
)(void *io_private
,
1732 const DATA_BLOB
*tstream_tls_sync_channel_bindings(struct tstream_tls_sync
*tlsss
)
1734 return &tlsss
->tlss
->channel_bindings
;
1737 static ssize_t
tstream_tls_sync_push_function(gnutls_transport_ptr_t ptr
,
1738 const void *buf
, size_t size
)
1740 struct tstream_tls_sync
*tlsss
=
1741 talloc_get_type_abort(ptr
,
1742 struct tstream_tls_sync
);
1744 return tlsss
->io_send_fn(tlsss
->io_private
, buf
, size
);
1747 static ssize_t
tstream_tls_sync_pull_function(gnutls_transport_ptr_t ptr
,
1748 void *buf
, size_t size
)
1750 struct tstream_tls_sync
*tlsss
=
1751 talloc_get_type_abort(ptr
,
1752 struct tstream_tls_sync
);
1754 return tlsss
->io_recv_fn(tlsss
->io_private
, buf
, size
);
1757 ssize_t
tstream_tls_sync_read(struct tstream_tls_sync
*tlsss
,
1758 void *buf
, size_t len
)
1762 ret
= gnutls_record_recv(tlsss
->tlss
->tls_session
, buf
, len
);
1763 if (ret
== GNUTLS_E_INTERRUPTED
) {
1767 if (ret
== GNUTLS_E_AGAIN
) {
1773 DBG_WARNING("TLS gnutls_record_recv(%zu) - %s\n",
1774 (size_t)len
, gnutls_strerror(ret
));
1782 ssize_t
tstream_tls_sync_write(struct tstream_tls_sync
*tlsss
,
1783 const void *buf
, size_t len
)
1787 ret
= gnutls_record_send(tlsss
->tlss
->tls_session
, buf
, len
);
1788 if (ret
== GNUTLS_E_INTERRUPTED
) {
1792 if (ret
== GNUTLS_E_AGAIN
) {
1798 DBG_WARNING("TLS gnutls_record_send(%zu) - %s\n",
1799 (size_t)len
, gnutls_strerror(ret
));
1807 size_t tstream_tls_sync_pending(struct tstream_tls_sync
*tlsss
)
1809 return gnutls_record_check_pending(tlsss
->tlss
->tls_session
);
1812 NTSTATUS
tstream_tls_sync_setup(struct tstream_tls_params
*_tls_params
,
1814 ssize_t (*io_send_fn
)(void *io_private
,
1817 ssize_t (*io_recv_fn
)(void *io_private
,
1820 TALLOC_CTX
*mem_ctx
,
1821 struct tstream_tls_sync
**_tlsss
)
1823 struct tstream_tls_sync
*tlsss
= NULL
;
1824 struct tstream_tls
*tlss
= NULL
;
1828 tlsss
= talloc_zero(mem_ctx
, struct tstream_tls_sync
);
1829 if (tlsss
== NULL
) {
1830 return NT_STATUS_NO_MEMORY
;
1833 tlsss
->io_private
= io_private
;
1834 tlsss
->io_send_fn
= io_send_fn
;
1835 tlsss
->io_recv_fn
= io_recv_fn
;
1837 tlss
= talloc_zero(tlsss
, struct tstream_tls
);
1840 return NT_STATUS_NO_MEMORY
;
1842 talloc_set_destructor(tlss
, tstream_tls_destructor
);
1843 tlss
->is_server
= false;
1847 status
= tstream_tls_prepare_gnutls(_tls_params
, tlss
);
1848 if (!NT_STATUS_IS_OK(status
)) {
1853 gnutls_transport_set_ptr(tlss
->tls_session
,
1854 (gnutls_transport_ptr_t
)tlsss
);
1855 gnutls_transport_set_pull_function(tlss
->tls_session
,
1856 (gnutls_pull_func
)tstream_tls_sync_pull_function
);
1857 gnutls_transport_set_push_function(tlss
->tls_session
,
1858 (gnutls_push_func
)tstream_tls_sync_push_function
);
1862 * The caller should have the socket blocking
1863 * and do the timeout handling in the
1866 ret
= gnutls_handshake(tlss
->tls_session
);
1867 } while (ret
== GNUTLS_E_INTERRUPTED
|| ret
== GNUTLS_E_AGAIN
);
1869 if (gnutls_error_is_fatal(ret
) != 0) {
1871 return gnutls_error_to_ntstatus(ret
,
1872 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1875 if (ret
!= GNUTLS_E_SUCCESS
) {
1877 return gnutls_error_to_ntstatus(ret
,
1878 NT_STATUS_CRYPTO_SYSTEM_INVALID
);
1881 status
= tstream_tls_verify_peer(tlss
);
1882 if (!NT_STATUS_IS_OK(status
)) {
1887 status
= tstream_tls_setup_channel_bindings(tlss
);
1888 if (!NT_STATUS_IS_OK(status
)) {
1894 return NT_STATUS_OK
;