s3:lib:tls: Use better priority lists for modern GnuTLS
[samba.git] / source4 / lib / tls / tls_tstream.c
1 /*
2    Unix SMB/CIFS implementation.
3
4    Copyright (C) Stefan Metzmacher 2010
5
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.
10
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.
15
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/>.
18 */
19
20 #include "includes.h"
21 #include "system/network.h"
22 #include "system/filesys.h"
23 #include "system/time.h"
24 #include "../util/tevent_unix.h"
25 #include "../lib/tsocket/tsocket.h"
26 #include "../lib/tsocket/tsocket_internal.h"
27 #include "../lib/util/util_net.h"
28 #include "lib/tls/tls.h"
29
30 #include <gnutls/gnutls.h>
31 #include <gnutls/x509.h>
32
33 #define DH_BITS 2048
34
35 const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer)
36 {
37         switch (verify_peer) {
38         case TLS_VERIFY_PEER_NO_CHECK:
39                 return TLS_VERIFY_PEER_NO_CHECK_STRING;
40
41         case TLS_VERIFY_PEER_CA_ONLY:
42                 return TLS_VERIFY_PEER_CA_ONLY_STRING;
43
44         case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE:
45                 return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING;
46
47         case TLS_VERIFY_PEER_CA_AND_NAME:
48                 return TLS_VERIFY_PEER_CA_AND_NAME_STRING;
49
50         case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE:
51                 return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING;
52         }
53
54         return "unknown tls_verify_peer_state";
55 }
56
57 static const struct tstream_context_ops tstream_tls_ops;
58
59 struct tstream_tls {
60         struct tstream_context *plain_stream;
61         int error;
62
63         gnutls_session_t tls_session;
64
65         enum tls_verify_peer_state verify_peer;
66         const char *peer_name;
67
68         struct tevent_context *current_ev;
69
70         struct tevent_immediate *retry_im;
71
72         struct {
73                 uint8_t *buf;
74                 off_t ofs;
75                 struct iovec iov;
76                 struct tevent_req *subreq;
77                 struct tevent_immediate *im;
78         } push;
79
80         struct {
81                 uint8_t *buf;
82                 struct iovec iov;
83                 struct tevent_req *subreq;
84         } pull;
85
86         struct {
87                 struct tevent_req *req;
88         } handshake;
89
90         struct {
91                 off_t ofs;
92                 size_t left;
93                 uint8_t buffer[1024];
94                 struct tevent_req *req;
95         } write;
96
97         struct {
98                 off_t ofs;
99                 size_t left;
100                 uint8_t buffer[1024];
101                 struct tevent_req *req;
102         } read;
103
104         struct {
105                 struct tevent_req *req;
106         } disconnect;
107 };
108
109 static void tstream_tls_retry_handshake(struct tstream_context *stream);
110 static void tstream_tls_retry_read(struct tstream_context *stream);
111 static void tstream_tls_retry_write(struct tstream_context *stream);
112 static void tstream_tls_retry_disconnect(struct tstream_context *stream);
113 static void tstream_tls_retry_trigger(struct tevent_context *ctx,
114                                       struct tevent_immediate *im,
115                                       void *private_data);
116
117 static void tstream_tls_retry(struct tstream_context *stream, bool deferred)
118 {
119
120         struct tstream_tls *tlss =
121                 tstream_context_data(stream,
122                 struct tstream_tls);
123
124         if (tlss->disconnect.req) {
125                 tstream_tls_retry_disconnect(stream);
126                 return;
127         }
128
129         if (tlss->handshake.req) {
130                 tstream_tls_retry_handshake(stream);
131                 return;
132         }
133
134         if (tlss->write.req && tlss->read.req && !deferred) {
135                 tevent_schedule_immediate(tlss->retry_im, tlss->current_ev,
136                                           tstream_tls_retry_trigger,
137                                           stream);
138         }
139
140         if (tlss->write.req) {
141                 tstream_tls_retry_write(stream);
142                 return;
143         }
144
145         if (tlss->read.req) {
146                 tstream_tls_retry_read(stream);
147                 return;
148         }
149 }
150
151 static void tstream_tls_retry_trigger(struct tevent_context *ctx,
152                                       struct tevent_immediate *im,
153                                       void *private_data)
154 {
155         struct tstream_context *stream =
156                 talloc_get_type_abort(private_data,
157                 struct tstream_context);
158
159         tstream_tls_retry(stream, true);
160 }
161
162 static void tstream_tls_push_trigger_write(struct tevent_context *ev,
163                                            struct tevent_immediate *im,
164                                            void *private_data);
165
166 static ssize_t tstream_tls_push_function(gnutls_transport_ptr_t ptr,
167                                          const void *buf, size_t size)
168 {
169         struct tstream_context *stream =
170                 talloc_get_type_abort(ptr,
171                 struct tstream_context);
172         struct tstream_tls *tlss =
173                 tstream_context_data(stream,
174                 struct tstream_tls);
175         uint8_t *nbuf;
176         size_t len;
177
178         if (tlss->error != 0) {
179                 errno = tlss->error;
180                 return -1;
181         }
182
183         if (tlss->push.subreq) {
184                 errno = EAGAIN;
185                 return -1;
186         }
187
188         len = MIN(size, UINT16_MAX - tlss->push.ofs);
189
190         if (len == 0) {
191                 errno = EAGAIN;
192                 return -1;
193         }
194
195         nbuf = talloc_realloc(tlss, tlss->push.buf,
196                               uint8_t, tlss->push.ofs + len);
197         if (nbuf == NULL) {
198                 if (tlss->push.buf) {
199                         errno = EAGAIN;
200                         return -1;
201                 }
202
203                 return -1;
204         }
205         tlss->push.buf = nbuf;
206
207         memcpy(tlss->push.buf + tlss->push.ofs, buf, len);
208
209         if (tlss->push.im == NULL) {
210                 tlss->push.im = tevent_create_immediate(tlss);
211                 if (tlss->push.im == NULL) {
212                         errno = ENOMEM;
213                         return -1;
214                 }
215         }
216
217         if (tlss->push.ofs == 0) {
218                 /*
219                  * We'll do start the tstream_writev
220                  * in the next event cycle.
221                  *
222                  * This way we can batch all push requests,
223                  * if they fit into a UINT16_MAX buffer.
224                  *
225                  * This is important as gnutls_handshake()
226                  * had a bug in some versions e.g. 2.4.1
227                  * and others (See bug #7218) and it doesn't
228                  * handle EAGAIN.
229                  */
230                 tevent_schedule_immediate(tlss->push.im,
231                                           tlss->current_ev,
232                                           tstream_tls_push_trigger_write,
233                                           stream);
234         }
235
236         tlss->push.ofs += len;
237         return len;
238 }
239
240 static void tstream_tls_push_done(struct tevent_req *subreq);
241
242 static void tstream_tls_push_trigger_write(struct tevent_context *ev,
243                                            struct tevent_immediate *im,
244                                            void *private_data)
245 {
246         struct tstream_context *stream =
247                 talloc_get_type_abort(private_data,
248                 struct tstream_context);
249         struct tstream_tls *tlss =
250                 tstream_context_data(stream,
251                 struct tstream_tls);
252         struct tevent_req *subreq;
253
254         if (tlss->push.subreq) {
255                 /* nothing todo */
256                 return;
257         }
258
259         tlss->push.iov.iov_base = (char *)tlss->push.buf;
260         tlss->push.iov.iov_len = tlss->push.ofs;
261
262         subreq = tstream_writev_send(tlss,
263                                      tlss->current_ev,
264                                      tlss->plain_stream,
265                                      &tlss->push.iov, 1);
266         if (subreq == NULL) {
267                 tlss->error = ENOMEM;
268                 tstream_tls_retry(stream, false);
269                 return;
270         }
271         tevent_req_set_callback(subreq, tstream_tls_push_done, stream);
272
273         tlss->push.subreq = subreq;
274 }
275
276 static void tstream_tls_push_done(struct tevent_req *subreq)
277 {
278         struct tstream_context *stream =
279                 tevent_req_callback_data(subreq,
280                 struct tstream_context);
281         struct tstream_tls *tlss =
282                 tstream_context_data(stream,
283                 struct tstream_tls);
284         int ret;
285         int sys_errno;
286
287         tlss->push.subreq = NULL;
288         ZERO_STRUCT(tlss->push.iov);
289         TALLOC_FREE(tlss->push.buf);
290         tlss->push.ofs = 0;
291
292         ret = tstream_writev_recv(subreq, &sys_errno);
293         TALLOC_FREE(subreq);
294         if (ret == -1) {
295                 tlss->error = sys_errno;
296                 tstream_tls_retry(stream, false);
297                 return;
298         }
299
300         tstream_tls_retry(stream, false);
301 }
302
303 static void tstream_tls_pull_done(struct tevent_req *subreq);
304
305 static ssize_t tstream_tls_pull_function(gnutls_transport_ptr_t ptr,
306                                          void *buf, size_t size)
307 {
308         struct tstream_context *stream =
309                 talloc_get_type_abort(ptr,
310                 struct tstream_context);
311         struct tstream_tls *tlss =
312                 tstream_context_data(stream,
313                 struct tstream_tls);
314         struct tevent_req *subreq;
315         size_t len;
316
317         if (tlss->error != 0) {
318                 errno = tlss->error;
319                 return -1;
320         }
321
322         if (tlss->pull.subreq) {
323                 errno = EAGAIN;
324                 return -1;
325         }
326
327         if (tlss->pull.iov.iov_base) {
328                 uint8_t *b;
329                 size_t n;
330
331                 b = (uint8_t *)tlss->pull.iov.iov_base;
332
333                 n = MIN(tlss->pull.iov.iov_len, size);
334                 memcpy(buf, b, n);
335
336                 tlss->pull.iov.iov_len -= n;
337                 b += n;
338                 tlss->pull.iov.iov_base = (char *)b;
339                 if (tlss->pull.iov.iov_len == 0) {
340                         tlss->pull.iov.iov_base = NULL;
341                         TALLOC_FREE(tlss->pull.buf);
342                 }
343
344                 return n;
345         }
346
347         if (size == 0) {
348                 return 0;
349         }
350
351         len = MIN(size, UINT16_MAX);
352
353         tlss->pull.buf = talloc_array(tlss, uint8_t, len);
354         if (tlss->pull.buf == NULL) {
355                 return -1;
356         }
357
358         tlss->pull.iov.iov_base = (char *)tlss->pull.buf;
359         tlss->pull.iov.iov_len = len;
360
361         subreq = tstream_readv_send(tlss,
362                                     tlss->current_ev,
363                                     tlss->plain_stream,
364                                     &tlss->pull.iov, 1);
365         if (subreq == NULL) {
366                 errno = ENOMEM;
367                 return -1;
368         }
369         tevent_req_set_callback(subreq, tstream_tls_pull_done, stream);
370
371         tlss->pull.subreq = subreq;
372         errno = EAGAIN;
373         return -1;
374 }
375
376 static void tstream_tls_pull_done(struct tevent_req *subreq)
377 {
378         struct tstream_context *stream =
379                 tevent_req_callback_data(subreq,
380                 struct tstream_context);
381         struct tstream_tls *tlss =
382                 tstream_context_data(stream,
383                 struct tstream_tls);
384         int ret;
385         int sys_errno;
386
387         tlss->pull.subreq = NULL;
388
389         ret = tstream_readv_recv(subreq, &sys_errno);
390         TALLOC_FREE(subreq);
391         if (ret == -1) {
392                 tlss->error = sys_errno;
393                 tstream_tls_retry(stream, false);
394                 return;
395         }
396
397         tstream_tls_retry(stream, false);
398 }
399
400 static int tstream_tls_destructor(struct tstream_tls *tlss)
401 {
402         if (tlss->tls_session) {
403                 gnutls_deinit(tlss->tls_session);
404                 tlss->tls_session = NULL;
405         }
406
407         return 0;
408 }
409
410 static ssize_t tstream_tls_pending_bytes(struct tstream_context *stream)
411 {
412         struct tstream_tls *tlss =
413                 tstream_context_data(stream,
414                 struct tstream_tls);
415         size_t ret;
416
417         if (tlss->error != 0) {
418                 errno = tlss->error;
419                 return -1;
420         }
421
422         ret = gnutls_record_check_pending(tlss->tls_session);
423         ret += tlss->read.left;
424
425         return ret;
426 }
427
428 struct tstream_tls_readv_state {
429         struct tstream_context *stream;
430
431         struct iovec *vector;
432         int count;
433
434         int ret;
435 };
436
437 static void tstream_tls_readv_crypt_next(struct tevent_req *req);
438
439 static struct tevent_req *tstream_tls_readv_send(TALLOC_CTX *mem_ctx,
440                                         struct tevent_context *ev,
441                                         struct tstream_context *stream,
442                                         struct iovec *vector,
443                                         size_t count)
444 {
445         struct tstream_tls *tlss =
446                 tstream_context_data(stream,
447                 struct tstream_tls);
448         struct tevent_req *req;
449         struct tstream_tls_readv_state *state;
450
451         tlss->read.req = NULL;
452         tlss->current_ev = ev;
453
454         req = tevent_req_create(mem_ctx, &state,
455                                 struct tstream_tls_readv_state);
456         if (req == NULL) {
457                 return NULL;
458         }
459
460         state->stream = stream;
461         state->ret = 0;
462
463         if (tlss->error != 0) {
464                 tevent_req_error(req, tlss->error);
465                 return tevent_req_post(req, ev);
466         }
467
468         /*
469          * we make a copy of the vector so we can change the structure
470          */
471         state->vector = talloc_array(state, struct iovec, count);
472         if (tevent_req_nomem(state->vector, req)) {
473                 return tevent_req_post(req, ev);
474         }
475         memcpy(state->vector, vector, sizeof(struct iovec) * count);
476         state->count = count;
477
478         tstream_tls_readv_crypt_next(req);
479         if (!tevent_req_is_in_progress(req)) {
480                 return tevent_req_post(req, ev);
481         }
482
483         return req;
484 }
485
486 static void tstream_tls_readv_crypt_next(struct tevent_req *req)
487 {
488         struct tstream_tls_readv_state *state =
489                 tevent_req_data(req,
490                 struct tstream_tls_readv_state);
491         struct tstream_tls *tlss =
492                 tstream_context_data(state->stream,
493                 struct tstream_tls);
494
495         /*
496          * copy the pending buffer first
497          */
498         while (tlss->read.left > 0 && state->count > 0) {
499                 uint8_t *base = (uint8_t *)state->vector[0].iov_base;
500                 size_t len = MIN(tlss->read.left, state->vector[0].iov_len);
501
502                 memcpy(base, tlss->read.buffer + tlss->read.ofs, len);
503
504                 base += len;
505                 state->vector[0].iov_base = (char *) base;
506                 state->vector[0].iov_len -= len;
507
508                 tlss->read.ofs += len;
509                 tlss->read.left -= len;
510
511                 if (state->vector[0].iov_len == 0) {
512                         state->vector += 1;
513                         state->count -= 1;
514                 }
515
516                 state->ret += len;
517         }
518
519         if (state->count == 0) {
520                 tevent_req_done(req);
521                 return;
522         }
523
524         tlss->read.req = req;
525         tstream_tls_retry_read(state->stream);
526 }
527
528 static void tstream_tls_retry_read(struct tstream_context *stream)
529 {
530         struct tstream_tls *tlss =
531                 tstream_context_data(stream,
532                 struct tstream_tls);
533         struct tevent_req *req = tlss->read.req;
534         int ret;
535
536         if (tlss->error != 0) {
537                 tevent_req_error(req, tlss->error);
538                 return;
539         }
540
541         tlss->read.left = 0;
542         tlss->read.ofs = 0;
543
544         ret = gnutls_record_recv(tlss->tls_session,
545                                  tlss->read.buffer,
546                                  sizeof(tlss->read.buffer));
547         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
548                 return;
549         }
550
551         tlss->read.req = NULL;
552
553         if (gnutls_error_is_fatal(ret) != 0) {
554                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
555                 tlss->error = EIO;
556                 tevent_req_error(req, tlss->error);
557                 return;
558         }
559
560         if (ret == 0) {
561                 tlss->error = EPIPE;
562                 tevent_req_error(req, tlss->error);
563                 return;
564         }
565
566         tlss->read.left = ret;
567         tstream_tls_readv_crypt_next(req);
568 }
569
570 static int tstream_tls_readv_recv(struct tevent_req *req,
571                                   int *perrno)
572 {
573         struct tstream_tls_readv_state *state =
574                 tevent_req_data(req,
575                 struct tstream_tls_readv_state);
576         struct tstream_tls *tlss =
577                 tstream_context_data(state->stream,
578                 struct tstream_tls);
579         int ret;
580
581         tlss->read.req = NULL;
582
583         ret = tsocket_simple_int_recv(req, perrno);
584         if (ret == 0) {
585                 ret = state->ret;
586         }
587
588         tevent_req_received(req);
589         return ret;
590 }
591
592 struct tstream_tls_writev_state {
593         struct tstream_context *stream;
594
595         struct iovec *vector;
596         int count;
597
598         int ret;
599 };
600
601 static void tstream_tls_writev_crypt_next(struct tevent_req *req);
602
603 static struct tevent_req *tstream_tls_writev_send(TALLOC_CTX *mem_ctx,
604                                         struct tevent_context *ev,
605                                         struct tstream_context *stream,
606                                         const struct iovec *vector,
607                                         size_t count)
608 {
609         struct tstream_tls *tlss =
610                 tstream_context_data(stream,
611                 struct tstream_tls);
612         struct tevent_req *req;
613         struct tstream_tls_writev_state *state;
614
615         tlss->write.req = NULL;
616         tlss->current_ev = ev;
617
618         req = tevent_req_create(mem_ctx, &state,
619                                 struct tstream_tls_writev_state);
620         if (req == NULL) {
621                 return NULL;
622         }
623
624         state->stream = stream;
625         state->ret = 0;
626
627         if (tlss->error != 0) {
628                 tevent_req_error(req, tlss->error);
629                 return tevent_req_post(req, ev);
630         }
631
632         /*
633          * we make a copy of the vector so we can change the structure
634          */
635         state->vector = talloc_array(state, struct iovec, count);
636         if (tevent_req_nomem(state->vector, req)) {
637                 return tevent_req_post(req, ev);
638         }
639         memcpy(state->vector, vector, sizeof(struct iovec) * count);
640         state->count = count;
641
642         tstream_tls_writev_crypt_next(req);
643         if (!tevent_req_is_in_progress(req)) {
644                 return tevent_req_post(req, ev);
645         }
646
647         return req;
648 }
649
650 static void tstream_tls_writev_crypt_next(struct tevent_req *req)
651 {
652         struct tstream_tls_writev_state *state =
653                 tevent_req_data(req,
654                 struct tstream_tls_writev_state);
655         struct tstream_tls *tlss =
656                 tstream_context_data(state->stream,
657                 struct tstream_tls);
658
659         tlss->write.left = sizeof(tlss->write.buffer);
660         tlss->write.ofs = 0;
661
662         /*
663          * first fill our buffer
664          */
665         while (tlss->write.left > 0 && state->count > 0) {
666                 uint8_t *base = (uint8_t *)state->vector[0].iov_base;
667                 size_t len = MIN(tlss->write.left, state->vector[0].iov_len);
668
669                 memcpy(tlss->write.buffer + tlss->write.ofs, base, len);
670
671                 base += len;
672                 state->vector[0].iov_base = (char *) base;
673                 state->vector[0].iov_len -= len;
674
675                 tlss->write.ofs += len;
676                 tlss->write.left -= len;
677
678                 if (state->vector[0].iov_len == 0) {
679                         state->vector += 1;
680                         state->count -= 1;
681                 }
682
683                 state->ret += len;
684         }
685
686         if (tlss->write.ofs == 0) {
687                 tevent_req_done(req);
688                 return;
689         }
690
691         tlss->write.left = tlss->write.ofs;
692         tlss->write.ofs = 0;
693
694         tlss->write.req = req;
695         tstream_tls_retry_write(state->stream);
696 }
697
698 static void tstream_tls_retry_write(struct tstream_context *stream)
699 {
700         struct tstream_tls *tlss =
701                 tstream_context_data(stream,
702                 struct tstream_tls);
703         struct tevent_req *req = tlss->write.req;
704         int ret;
705
706         if (tlss->error != 0) {
707                 tevent_req_error(req, tlss->error);
708                 return;
709         }
710
711         ret = gnutls_record_send(tlss->tls_session,
712                                  tlss->write.buffer + tlss->write.ofs,
713                                  tlss->write.left);
714         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
715                 return;
716         }
717
718         tlss->write.req = NULL;
719
720         if (gnutls_error_is_fatal(ret) != 0) {
721                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
722                 tlss->error = EIO;
723                 tevent_req_error(req, tlss->error);
724                 return;
725         }
726
727         if (ret == 0) {
728                 tlss->error = EPIPE;
729                 tevent_req_error(req, tlss->error);
730                 return;
731         }
732
733         tlss->write.ofs += ret;
734         tlss->write.left -= ret;
735
736         if (tlss->write.left > 0) {
737                 tlss->write.req = req;
738                 tstream_tls_retry_write(stream);
739                 return;
740         }
741
742         tstream_tls_writev_crypt_next(req);
743 }
744
745 static int tstream_tls_writev_recv(struct tevent_req *req,
746                                    int *perrno)
747 {
748         struct tstream_tls_writev_state *state =
749                 tevent_req_data(req,
750                 struct tstream_tls_writev_state);
751         struct tstream_tls *tlss =
752                 tstream_context_data(state->stream,
753                 struct tstream_tls);
754         int ret;
755
756         tlss->write.req = NULL;
757
758         ret = tsocket_simple_int_recv(req, perrno);
759         if (ret == 0) {
760                 ret = state->ret;
761         }
762
763         tevent_req_received(req);
764         return ret;
765 }
766
767 struct tstream_tls_disconnect_state {
768         uint8_t _dummy;
769 };
770
771 static struct tevent_req *tstream_tls_disconnect_send(TALLOC_CTX *mem_ctx,
772                                                 struct tevent_context *ev,
773                                                 struct tstream_context *stream)
774 {
775         struct tstream_tls *tlss =
776                 tstream_context_data(stream,
777                 struct tstream_tls);
778         struct tevent_req *req;
779         struct tstream_tls_disconnect_state *state;
780
781         tlss->disconnect.req = NULL;
782         tlss->current_ev = ev;
783
784         req = tevent_req_create(mem_ctx, &state,
785                                 struct tstream_tls_disconnect_state);
786         if (req == NULL) {
787                 return NULL;
788         }
789
790         if (tlss->error != 0) {
791                 tevent_req_error(req, tlss->error);
792                 return tevent_req_post(req, ev);
793         }
794
795         tlss->disconnect.req = req;
796         tstream_tls_retry_disconnect(stream);
797         if (!tevent_req_is_in_progress(req)) {
798                 return tevent_req_post(req, ev);
799         }
800
801         return req;
802 }
803
804 static void tstream_tls_retry_disconnect(struct tstream_context *stream)
805 {
806         struct tstream_tls *tlss =
807                 tstream_context_data(stream,
808                 struct tstream_tls);
809         struct tevent_req *req = tlss->disconnect.req;
810         int ret;
811
812         if (tlss->error != 0) {
813                 tevent_req_error(req, tlss->error);
814                 return;
815         }
816
817         ret = gnutls_bye(tlss->tls_session, GNUTLS_SHUT_WR);
818         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
819                 return;
820         }
821
822         tlss->disconnect.req = NULL;
823
824         if (gnutls_error_is_fatal(ret) != 0) {
825                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
826                 tlss->error = EIO;
827                 tevent_req_error(req, tlss->error);
828                 return;
829         }
830
831         if (ret != GNUTLS_E_SUCCESS) {
832                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
833                 tlss->error = EIO;
834                 tevent_req_error(req, tlss->error);
835                 return;
836         }
837
838         tevent_req_done(req);
839 }
840
841 static int tstream_tls_disconnect_recv(struct tevent_req *req,
842                                        int *perrno)
843 {
844         int ret;
845
846         ret = tsocket_simple_int_recv(req, perrno);
847
848         tevent_req_received(req);
849         return ret;
850 }
851
852 static const struct tstream_context_ops tstream_tls_ops = {
853         .name                   = "tls",
854
855         .pending_bytes          = tstream_tls_pending_bytes,
856
857         .readv_send             = tstream_tls_readv_send,
858         .readv_recv             = tstream_tls_readv_recv,
859
860         .writev_send            = tstream_tls_writev_send,
861         .writev_recv            = tstream_tls_writev_recv,
862
863         .disconnect_send        = tstream_tls_disconnect_send,
864         .disconnect_recv        = tstream_tls_disconnect_recv,
865 };
866
867 struct tstream_tls_params {
868         gnutls_certificate_credentials_t x509_cred;
869         gnutls_dh_params_t dh_params;
870         const char *tls_priority;
871         bool tls_enabled;
872         enum tls_verify_peer_state verify_peer;
873         const char *peer_name;
874 };
875
876 static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp)
877 {
878         if (tlsp->x509_cred) {
879                 gnutls_certificate_free_credentials(tlsp->x509_cred);
880                 tlsp->x509_cred = NULL;
881         }
882         if (tlsp->dh_params) {
883                 gnutls_dh_params_deinit(tlsp->dh_params);
884                 tlsp->dh_params = NULL;
885         }
886
887         return 0;
888 }
889
890 bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp)
891 {
892         return tlsp->tls_enabled;
893 }
894
895 NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx,
896                                    const char *ca_file,
897                                    const char *crl_file,
898                                    const char *tls_priority,
899                                    enum tls_verify_peer_state verify_peer,
900                                    const char *peer_name,
901                                    struct tstream_tls_params **_tlsp)
902 {
903         struct tstream_tls_params *tlsp;
904         int ret;
905
906         tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
907         NT_STATUS_HAVE_NO_MEMORY(tlsp);
908
909         talloc_set_destructor(tlsp, tstream_tls_params_destructor);
910
911         tlsp->verify_peer = verify_peer;
912         if (peer_name != NULL) {
913                 tlsp->peer_name = talloc_strdup(tlsp, peer_name);
914                 if (tlsp->peer_name == NULL) {
915                         talloc_free(tlsp);
916                         return NT_STATUS_NO_MEMORY;
917                 }
918         } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) {
919                 DEBUG(0,("TLS failed to missing peer_name - "
920                          "with 'tls verify peer = %s'\n",
921                          tls_verify_peer_string(tlsp->verify_peer)));
922                 talloc_free(tlsp);
923                 return NT_STATUS_INVALID_PARAMETER_MIX;
924         }
925
926         ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
927         if (ret != GNUTLS_E_SUCCESS) {
928                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
929                 talloc_free(tlsp);
930                 return NT_STATUS_NO_MEMORY;
931         }
932
933         if (ca_file && *ca_file && file_exist(ca_file)) {
934                 ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
935                                                              ca_file,
936                                                              GNUTLS_X509_FMT_PEM);
937                 if (ret < 0) {
938                         DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
939                                  ca_file, gnutls_strerror(ret)));
940                         talloc_free(tlsp);
941                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
942                 }
943         } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) {
944                 DEBUG(0,("TLS failed to missing cafile %s - "
945                          "with 'tls verify peer = %s'\n",
946                          ca_file,
947                          tls_verify_peer_string(tlsp->verify_peer)));
948                 talloc_free(tlsp);
949                 return NT_STATUS_INVALID_PARAMETER_MIX;
950         }
951
952         if (crl_file && *crl_file && file_exist(crl_file)) {
953                 ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
954                                                            crl_file, 
955                                                            GNUTLS_X509_FMT_PEM);
956                 if (ret < 0) {
957                         DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
958                                  crl_file, gnutls_strerror(ret)));
959                         talloc_free(tlsp);
960                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
961                 }
962         } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE) {
963                 DEBUG(0,("TLS failed to missing crlfile %s - "
964                          "with 'tls verify peer = %s'\n",
965                          crl_file,
966                          tls_verify_peer_string(tlsp->verify_peer)));
967                 talloc_free(tlsp);
968                 return NT_STATUS_INVALID_PARAMETER_MIX;
969         }
970
971         tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
972         if (tlsp->tls_priority == NULL) {
973                 talloc_free(tlsp);
974                 return NT_STATUS_NO_MEMORY;
975         }
976
977         tlsp->tls_enabled = true;
978
979         *_tlsp = tlsp;
980         return NT_STATUS_OK;
981 }
982
983 struct tstream_tls_connect_state {
984         struct tstream_context *tls_stream;
985 };
986
987 struct tevent_req *_tstream_tls_connect_send(TALLOC_CTX *mem_ctx,
988                                              struct tevent_context *ev,
989                                              struct tstream_context *plain_stream,
990                                              struct tstream_tls_params *tls_params,
991                                              const char *location)
992 {
993         struct tevent_req *req;
994         struct tstream_tls_connect_state *state;
995         const char *error_pos;
996         struct tstream_tls *tlss;
997         int ret;
998
999         req = tevent_req_create(mem_ctx, &state,
1000                                 struct tstream_tls_connect_state);
1001         if (req == NULL) {
1002                 return NULL;
1003         }
1004
1005         state->tls_stream = tstream_context_create(state,
1006                                                    &tstream_tls_ops,
1007                                                    &tlss,
1008                                                    struct tstream_tls,
1009                                                    location);
1010         if (tevent_req_nomem(state->tls_stream, req)) {
1011                 return tevent_req_post(req, ev);
1012         }
1013         ZERO_STRUCTP(tlss);
1014         talloc_set_destructor(tlss, tstream_tls_destructor);
1015
1016         tlss->plain_stream = plain_stream;
1017         tlss->verify_peer = tls_params->verify_peer;
1018         if (tls_params->peer_name != NULL) {
1019                 tlss->peer_name = talloc_strdup(tlss, tls_params->peer_name);
1020                 if (tevent_req_nomem(tlss->peer_name, req)) {
1021                         return tevent_req_post(req, ev);
1022                 }
1023         }
1024
1025         tlss->current_ev = ev;
1026         tlss->retry_im = tevent_create_immediate(tlss);
1027         if (tevent_req_nomem(tlss->retry_im, req)) {
1028                 return tevent_req_post(req, ev);
1029         }
1030
1031         ret = gnutls_init(&tlss->tls_session, GNUTLS_CLIENT);
1032         if (ret != GNUTLS_E_SUCCESS) {
1033                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1034                 tevent_req_error(req, EINVAL);
1035                 return tevent_req_post(req, ev);
1036         }
1037
1038         ret = gnutls_set_default_priority(tlss->tls_session);
1039         if (ret != GNUTLS_E_SUCCESS) {
1040                 DBG_ERR("TLS %s - %s. Failed to set default priorities\n",
1041                         __location__, gnutls_strerror(ret));
1042                 tevent_req_error(req, EINVAL);
1043                 return tevent_req_post(req, ev);
1044         }
1045
1046         if (strlen(tls_params->tls_priority) > 0) {
1047                 ret = gnutls_priority_set_direct(tlss->tls_session,
1048                                                  tls_params->tls_priority,
1049                                                  &error_pos);
1050                 if (ret != GNUTLS_E_SUCCESS) {
1051                         DEBUG(0,("TLS %s - %s.  Check 'tls priority' option at '%s'\n",
1052                                  __location__, gnutls_strerror(ret), error_pos));
1053                         tevent_req_error(req, EINVAL);
1054                         return tevent_req_post(req, ev);
1055                 }
1056         }
1057
1058         ret = gnutls_credentials_set(tlss->tls_session,
1059                                      GNUTLS_CRD_CERTIFICATE,
1060                                      tls_params->x509_cred);
1061         if (ret != GNUTLS_E_SUCCESS) {
1062                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1063                 tevent_req_error(req, EINVAL);
1064                 return tevent_req_post(req, ev);
1065         }
1066
1067         gnutls_transport_set_ptr(tlss->tls_session,
1068                                  (gnutls_transport_ptr_t)state->tls_stream);
1069         gnutls_transport_set_pull_function(tlss->tls_session,
1070                                            (gnutls_pull_func)tstream_tls_pull_function);
1071         gnutls_transport_set_push_function(tlss->tls_session,
1072                                            (gnutls_push_func)tstream_tls_push_function);
1073
1074         tlss->handshake.req = req;
1075         tstream_tls_retry_handshake(state->tls_stream);
1076         if (!tevent_req_is_in_progress(req)) {
1077                 return tevent_req_post(req, ev);
1078         }
1079
1080         return req;
1081 }
1082
1083 int tstream_tls_connect_recv(struct tevent_req *req,
1084                              int *perrno,
1085                              TALLOC_CTX *mem_ctx,
1086                              struct tstream_context **tls_stream)
1087 {
1088         struct tstream_tls_connect_state *state =
1089                 tevent_req_data(req,
1090                 struct tstream_tls_connect_state);
1091
1092         if (tevent_req_is_unix_error(req, perrno)) {
1093                 tevent_req_received(req);
1094                 return -1;
1095         }
1096
1097         *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
1098         tevent_req_received(req);
1099         return 0;
1100 }
1101
1102 /*
1103   initialise global tls state
1104 */
1105 NTSTATUS tstream_tls_params_server(TALLOC_CTX *mem_ctx,
1106                                    const char *dns_host_name,
1107                                    bool enabled,
1108                                    const char *key_file,
1109                                    const char *cert_file,
1110                                    const char *ca_file,
1111                                    const char *crl_file,
1112                                    const char *dhp_file,
1113                                    const char *tls_priority,
1114                                    struct tstream_tls_params **_tlsp)
1115 {
1116         struct tstream_tls_params *tlsp;
1117         int ret;
1118         struct stat st;
1119
1120         if (!enabled || key_file == NULL || *key_file == 0) {
1121                 tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
1122                 NT_STATUS_HAVE_NO_MEMORY(tlsp);
1123                 talloc_set_destructor(tlsp, tstream_tls_params_destructor);
1124                 tlsp->tls_enabled = false;
1125
1126                 *_tlsp = tlsp;
1127                 return NT_STATUS_OK;
1128         }
1129
1130         tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
1131         NT_STATUS_HAVE_NO_MEMORY(tlsp);
1132
1133         talloc_set_destructor(tlsp, tstream_tls_params_destructor);
1134
1135         if (!file_exist(ca_file)) {
1136                 tls_cert_generate(tlsp, dns_host_name,
1137                                   key_file, cert_file, ca_file);
1138         }
1139
1140         if (file_exist(key_file) &&
1141             !file_check_permissions(key_file, geteuid(), 0600, &st))
1142         {
1143                 DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n"
1144                           "owner uid %u should be %u, mode 0%o should be 0%o\n"
1145                           "This is known as CVE-2013-4476.\n"
1146                           "Removing all tls .pem files will cause an "
1147                           "auto-regeneration with the correct permissions.\n",
1148                           key_file,
1149                           (unsigned int)st.st_uid, geteuid(),
1150                           (unsigned int)(st.st_mode & 0777), 0600));
1151                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1152         }
1153
1154         ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
1155         if (ret != GNUTLS_E_SUCCESS) {
1156                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1157                 talloc_free(tlsp);
1158                 return NT_STATUS_NO_MEMORY;
1159         }
1160
1161         if (ca_file && *ca_file) {
1162                 ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
1163                                                              ca_file,
1164                                                              GNUTLS_X509_FMT_PEM);
1165                 if (ret < 0) {
1166                         DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
1167                                  ca_file, gnutls_strerror(ret)));
1168                         talloc_free(tlsp);
1169                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1170                 }
1171         }
1172
1173         if (crl_file && *crl_file) {
1174                 ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
1175                                                            crl_file, 
1176                                                            GNUTLS_X509_FMT_PEM);
1177                 if (ret < 0) {
1178                         DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
1179                                  crl_file, gnutls_strerror(ret)));
1180                         talloc_free(tlsp);
1181                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1182                 }
1183         }
1184
1185         ret = gnutls_certificate_set_x509_key_file(tlsp->x509_cred,
1186                                                    cert_file, key_file,
1187                                                    GNUTLS_X509_FMT_PEM);
1188         if (ret != GNUTLS_E_SUCCESS) {
1189                 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s - %s\n",
1190                          cert_file, key_file, gnutls_strerror(ret)));
1191                 talloc_free(tlsp);
1192                 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1193         }
1194
1195         ret = gnutls_dh_params_init(&tlsp->dh_params);
1196         if (ret != GNUTLS_E_SUCCESS) {
1197                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1198                 talloc_free(tlsp);
1199                 return NT_STATUS_NO_MEMORY;
1200         }
1201
1202         if (dhp_file && *dhp_file) {
1203                 gnutls_datum_t dhparms;
1204                 size_t size;
1205
1206                 dhparms.data = (uint8_t *)file_load(dhp_file, &size, 0, tlsp);
1207
1208                 if (!dhparms.data) {
1209                         DEBUG(0,("TLS failed to read DH Parms from %s - %d:%s\n",
1210                                  dhp_file, errno, strerror(errno)));
1211                         talloc_free(tlsp);
1212                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1213                 }
1214                 dhparms.size = size;
1215
1216                 ret = gnutls_dh_params_import_pkcs3(tlsp->dh_params,
1217                                                     &dhparms,
1218                                                     GNUTLS_X509_FMT_PEM);
1219                 if (ret != GNUTLS_E_SUCCESS) {
1220                         DEBUG(0,("TLS failed to import pkcs3 %s - %s\n",
1221                                  dhp_file, gnutls_strerror(ret)));
1222                         talloc_free(tlsp);
1223                         return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1224                 }
1225         } else {
1226                 ret = gnutls_dh_params_generate2(tlsp->dh_params, DH_BITS);
1227                 if (ret != GNUTLS_E_SUCCESS) {
1228                         DEBUG(0,("TLS failed to generate dh_params - %s\n",
1229                                  gnutls_strerror(ret)));
1230                         talloc_free(tlsp);
1231                         return NT_STATUS_INTERNAL_ERROR;
1232                 }
1233         }
1234
1235         gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params);
1236
1237         tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
1238         if (tlsp->tls_priority == NULL) {
1239                 talloc_free(tlsp);
1240                 return NT_STATUS_NO_MEMORY;
1241         }
1242
1243         tlsp->tls_enabled = true;
1244
1245         *_tlsp = tlsp;
1246         return NT_STATUS_OK;
1247 }
1248
1249 struct tstream_tls_accept_state {
1250         struct tstream_context *tls_stream;
1251 };
1252
1253 struct tevent_req *_tstream_tls_accept_send(TALLOC_CTX *mem_ctx,
1254                                             struct tevent_context *ev,
1255                                             struct tstream_context *plain_stream,
1256                                             struct tstream_tls_params *tlsp,
1257                                             const char *location)
1258 {
1259         struct tevent_req *req;
1260         struct tstream_tls_accept_state *state;
1261         struct tstream_tls *tlss;
1262         const char *error_pos;
1263         int ret;
1264
1265         req = tevent_req_create(mem_ctx, &state,
1266                                 struct tstream_tls_accept_state);
1267         if (req == NULL) {
1268                 return NULL;
1269         }
1270
1271         state->tls_stream = tstream_context_create(state,
1272                                                    &tstream_tls_ops,
1273                                                    &tlss,
1274                                                    struct tstream_tls,
1275                                                    location);
1276         if (tevent_req_nomem(state->tls_stream, req)) {
1277                 return tevent_req_post(req, ev);
1278         }
1279         ZERO_STRUCTP(tlss);
1280         talloc_set_destructor(tlss, tstream_tls_destructor);
1281
1282         tlss->plain_stream = plain_stream;
1283
1284         tlss->current_ev = ev;
1285         tlss->retry_im = tevent_create_immediate(tlss);
1286         if (tevent_req_nomem(tlss->retry_im, req)) {
1287                 return tevent_req_post(req, ev);
1288         }
1289
1290         ret = gnutls_init(&tlss->tls_session, GNUTLS_SERVER);
1291         if (ret != GNUTLS_E_SUCCESS) {
1292                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1293                 tevent_req_error(req, EINVAL);
1294                 return tevent_req_post(req, ev);
1295         }
1296
1297         ret = gnutls_set_default_priority(tlss->tls_session);
1298         if (ret != GNUTLS_E_SUCCESS) {
1299                 DBG_ERR("TLS %s - %s. Failed to set default priorities\n",
1300                         __location__, gnutls_strerror(ret));
1301                 tevent_req_error(req, EINVAL);
1302                 return tevent_req_post(req, ev);
1303         }
1304
1305         if (strlen(tlsp->tls_priority) > 0) {
1306                 ret = gnutls_priority_set_direct(tlss->tls_session,
1307                                                  tlsp->tls_priority,
1308                                                  &error_pos);
1309                 if (ret != GNUTLS_E_SUCCESS) {
1310                         DEBUG(0,("TLS %s - %s.  Check 'tls priority' option at '%s'\n",
1311                                  __location__, gnutls_strerror(ret), error_pos));
1312                         tevent_req_error(req, EINVAL);
1313                         return tevent_req_post(req, ev);
1314                 }
1315         }
1316
1317         ret = gnutls_credentials_set(tlss->tls_session, GNUTLS_CRD_CERTIFICATE,
1318                                      tlsp->x509_cred);
1319         if (ret != GNUTLS_E_SUCCESS) {
1320                 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1321                 tevent_req_error(req, EINVAL);
1322                 return tevent_req_post(req, ev);
1323         }
1324
1325         gnutls_certificate_server_set_request(tlss->tls_session,
1326                                               GNUTLS_CERT_REQUEST);
1327         gnutls_dh_set_prime_bits(tlss->tls_session, DH_BITS);
1328
1329         gnutls_transport_set_ptr(tlss->tls_session,
1330                                  (gnutls_transport_ptr_t)state->tls_stream);
1331         gnutls_transport_set_pull_function(tlss->tls_session,
1332                                            (gnutls_pull_func)tstream_tls_pull_function);
1333         gnutls_transport_set_push_function(tlss->tls_session,
1334                                            (gnutls_push_func)tstream_tls_push_function);
1335
1336         tlss->handshake.req = req;
1337         tstream_tls_retry_handshake(state->tls_stream);
1338         if (!tevent_req_is_in_progress(req)) {
1339                 return tevent_req_post(req, ev);
1340         }
1341
1342         return req;
1343 }
1344
1345 static void tstream_tls_retry_handshake(struct tstream_context *stream)
1346 {
1347         struct tstream_tls *tlss =
1348                 tstream_context_data(stream,
1349                 struct tstream_tls);
1350         struct tevent_req *req = tlss->handshake.req;
1351         int ret;
1352
1353         if (tlss->error != 0) {
1354                 tevent_req_error(req, tlss->error);
1355                 return;
1356         }
1357
1358         ret = gnutls_handshake(tlss->tls_session);
1359         if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
1360                 return;
1361         }
1362
1363         tlss->handshake.req = NULL;
1364
1365         if (gnutls_error_is_fatal(ret) != 0) {
1366                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1367                 tlss->error = EIO;
1368                 tevent_req_error(req, tlss->error);
1369                 return;
1370         }
1371
1372         if (ret != GNUTLS_E_SUCCESS) {
1373                 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1374                 tlss->error = EIO;
1375                 tevent_req_error(req, tlss->error);
1376                 return;
1377         }
1378
1379         if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) {
1380                 unsigned int status = UINT32_MAX;
1381                 bool ip = true;
1382                 const char *hostname = NULL;
1383
1384                 if (tlss->peer_name != NULL) {
1385                         ip = is_ipaddress(tlss->peer_name);
1386                 }
1387
1388                 if (!ip) {
1389                         hostname = tlss->peer_name;
1390                 }
1391
1392                 if (tlss->verify_peer == TLS_VERIFY_PEER_CA_ONLY) {
1393                         hostname = NULL;
1394                 }
1395
1396                 if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) {
1397                         if (hostname == NULL) {
1398                                 DEBUG(1,("TLS %s - no hostname available for "
1399                                          "verify_peer[%s] and peer_name[%s]\n",
1400                                          __location__,
1401                                          tls_verify_peer_string(tlss->verify_peer),
1402                                          tlss->peer_name));
1403                                 tlss->error = EINVAL;
1404                                 tevent_req_error(req, tlss->error);
1405                                 return;
1406                         }
1407                 }
1408
1409                 ret = gnutls_certificate_verify_peers3(tlss->tls_session,
1410                                                        hostname,
1411                                                        &status);
1412                 if (ret != GNUTLS_E_SUCCESS) {
1413                         DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1414                         tlss->error = EIO;
1415                         tevent_req_error(req, tlss->error);
1416                         return;
1417                 }
1418
1419                 if (status != 0) {
1420                         DEBUG(1,("TLS %s - check failed for "
1421                                  "verify_peer[%s] and peer_name[%s] "
1422                                  "status 0x%x (%s%s%s%s%s%s%s%s)\n",
1423                                  __location__,
1424                                  tls_verify_peer_string(tlss->verify_peer),
1425                                  tlss->peer_name,
1426                                  status,
1427                                  status & GNUTLS_CERT_INVALID ? "invalid " : "",
1428                                  status & GNUTLS_CERT_REVOKED ? "revoked " : "",
1429                                  status & GNUTLS_CERT_SIGNER_NOT_FOUND ?
1430                                         "signer_not_found " : "",
1431                                  status & GNUTLS_CERT_SIGNER_NOT_CA ?
1432                                         "signer_not_ca " : "",
1433                                  status & GNUTLS_CERT_INSECURE_ALGORITHM ?
1434                                         "insecure_algorithm " : "",
1435                                  status & GNUTLS_CERT_NOT_ACTIVATED ?
1436                                         "not_activated " : "",
1437                                  status & GNUTLS_CERT_EXPIRED ?
1438                                         "expired " : "",
1439                                  status & GNUTLS_CERT_UNEXPECTED_OWNER ?
1440                                         "unexptected_owner " : ""));
1441                         tlss->error = EINVAL;
1442                         tevent_req_error(req, tlss->error);
1443                         return;
1444                 }
1445         }
1446
1447         tevent_req_done(req);
1448 }
1449
1450 int tstream_tls_accept_recv(struct tevent_req *req,
1451                             int *perrno,
1452                             TALLOC_CTX *mem_ctx,
1453                             struct tstream_context **tls_stream)
1454 {
1455         struct tstream_tls_accept_state *state =
1456                 tevent_req_data(req,
1457                 struct tstream_tls_accept_state);
1458
1459         if (tevent_req_is_unix_error(req, perrno)) {
1460                 tevent_req_received(req);
1461                 return -1;
1462         }
1463
1464         *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
1465         tevent_req_received(req);
1466         return 0;
1467 }