Line data Source code
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 17 : const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer)
36 : {
37 17 : switch (verify_peer) {
38 0 : case TLS_VERIFY_PEER_NO_CHECK:
39 0 : return TLS_VERIFY_PEER_NO_CHECK_STRING;
40 :
41 0 : case TLS_VERIFY_PEER_CA_ONLY:
42 0 : return TLS_VERIFY_PEER_CA_ONLY_STRING;
43 :
44 3 : case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE:
45 3 : return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING;
46 :
47 6 : case TLS_VERIFY_PEER_CA_AND_NAME:
48 6 : return TLS_VERIFY_PEER_CA_AND_NAME_STRING;
49 :
50 8 : case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE:
51 8 : return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING;
52 : }
53 :
54 0 : 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 2310367 : static void tstream_tls_retry(struct tstream_context *stream, bool deferred)
118 : {
119 :
120 2309169 : struct tstream_tls *tlss =
121 2310367 : tstream_context_data(stream,
122 : struct tstream_tls);
123 :
124 2310367 : if (tlss->disconnect.req) {
125 0 : tstream_tls_retry_disconnect(stream);
126 0 : return;
127 : }
128 :
129 2310367 : if (tlss->handshake.req) {
130 10657 : tstream_tls_retry_handshake(stream);
131 10657 : return;
132 : }
133 :
134 2299710 : if (tlss->write.req && tlss->read.req && !deferred) {
135 0 : tevent_schedule_immediate(tlss->retry_im, tlss->current_ev,
136 : tstream_tls_retry_trigger,
137 : stream);
138 : }
139 :
140 2299710 : if (tlss->write.req) {
141 18050 : tstream_tls_retry_write(stream);
142 18050 : return;
143 : }
144 :
145 2281660 : if (tlss->read.req) {
146 2281660 : tstream_tls_retry_read(stream);
147 2281660 : return;
148 : }
149 : }
150 :
151 0 : static void tstream_tls_retry_trigger(struct tevent_context *ctx,
152 : struct tevent_immediate *im,
153 : void *private_data)
154 : {
155 0 : struct tstream_context *stream =
156 0 : talloc_get_type_abort(private_data,
157 : struct tstream_context);
158 :
159 0 : tstream_tls_retry(stream, true);
160 0 : }
161 :
162 : static void tstream_tls_push_trigger_write(struct tevent_context *ev,
163 : struct tevent_immediate *im,
164 : void *private_data);
165 :
166 1179714 : static ssize_t tstream_tls_push_function(gnutls_transport_ptr_t ptr,
167 : const void *buf, size_t size)
168 : {
169 1179240 : struct tstream_context *stream =
170 474 : talloc_get_type_abort(ptr,
171 : struct tstream_context);
172 1179240 : struct tstream_tls *tlss =
173 1179714 : tstream_context_data(stream,
174 : struct tstream_tls);
175 : uint8_t *nbuf;
176 : size_t len;
177 :
178 1179714 : if (tlss->error != 0) {
179 0 : errno = tlss->error;
180 0 : return -1;
181 : }
182 :
183 1179714 : if (tlss->push.subreq) {
184 0 : errno = EAGAIN;
185 0 : return -1;
186 : }
187 :
188 1179714 : len = MIN(size, UINT16_MAX - tlss->push.ofs);
189 :
190 1179714 : if (len == 0) {
191 18050 : errno = EAGAIN;
192 18050 : return -1;
193 : }
194 :
195 1161664 : nbuf = talloc_realloc(tlss, tlss->push.buf,
196 : uint8_t, tlss->push.ofs + len);
197 1161664 : if (nbuf == NULL) {
198 0 : if (tlss->push.buf) {
199 0 : errno = EAGAIN;
200 0 : return -1;
201 : }
202 :
203 0 : return -1;
204 : }
205 1161664 : tlss->push.buf = nbuf;
206 :
207 1161664 : memcpy(tlss->push.buf + tlss->push.ofs, buf, len);
208 :
209 1161664 : if (tlss->push.im == NULL) {
210 796 : tlss->push.im = tevent_create_immediate(tlss);
211 796 : if (tlss->push.im == NULL) {
212 0 : errno = ENOMEM;
213 0 : return -1;
214 : }
215 : }
216 :
217 1161664 : 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 22694 : tevent_schedule_immediate(tlss->push.im,
231 : tlss->current_ev,
232 : tstream_tls_push_trigger_write,
233 : stream);
234 : }
235 :
236 1161664 : tlss->push.ofs += len;
237 1161664 : return len;
238 : }
239 :
240 : static void tstream_tls_push_done(struct tevent_req *subreq);
241 :
242 22691 : static void tstream_tls_push_trigger_write(struct tevent_context *ev,
243 : struct tevent_immediate *im,
244 : void *private_data)
245 : {
246 22458 : struct tstream_context *stream =
247 233 : talloc_get_type_abort(private_data,
248 : struct tstream_context);
249 22458 : struct tstream_tls *tlss =
250 22691 : tstream_context_data(stream,
251 : struct tstream_tls);
252 : struct tevent_req *subreq;
253 :
254 22691 : if (tlss->push.subreq) {
255 : /* nothing todo */
256 0 : return;
257 : }
258 :
259 22691 : tlss->push.iov.iov_base = (char *)tlss->push.buf;
260 22691 : tlss->push.iov.iov_len = tlss->push.ofs;
261 :
262 22691 : subreq = tstream_writev_send(tlss,
263 : tlss->current_ev,
264 : tlss->plain_stream,
265 22691 : &tlss->push.iov, 1);
266 22691 : if (subreq == NULL) {
267 0 : tlss->error = ENOMEM;
268 0 : tstream_tls_retry(stream, false);
269 0 : return;
270 : }
271 22691 : tevent_req_set_callback(subreq, tstream_tls_push_done, stream);
272 :
273 22691 : tlss->push.subreq = subreq;
274 : }
275 :
276 22691 : static void tstream_tls_push_done(struct tevent_req *subreq)
277 : {
278 22458 : struct tstream_context *stream =
279 22691 : tevent_req_callback_data(subreq,
280 : struct tstream_context);
281 22458 : struct tstream_tls *tlss =
282 22691 : tstream_context_data(stream,
283 : struct tstream_tls);
284 : int ret;
285 : int sys_errno;
286 :
287 22691 : tlss->push.subreq = NULL;
288 22691 : ZERO_STRUCT(tlss->push.iov);
289 22691 : TALLOC_FREE(tlss->push.buf);
290 22691 : tlss->push.ofs = 0;
291 :
292 22691 : ret = tstream_writev_recv(subreq, &sys_errno);
293 22691 : TALLOC_FREE(subreq);
294 22691 : if (ret == -1) {
295 1 : tlss->error = sys_errno;
296 1 : tstream_tls_retry(stream, false);
297 1 : return;
298 : }
299 :
300 22690 : tstream_tls_retry(stream, false);
301 : }
302 :
303 : static void tstream_tls_pull_done(struct tevent_req *subreq);
304 :
305 4579599 : static ssize_t tstream_tls_pull_function(gnutls_transport_ptr_t ptr,
306 : void *buf, size_t size)
307 : {
308 4577465 : struct tstream_context *stream =
309 2134 : talloc_get_type_abort(ptr,
310 : struct tstream_context);
311 4577465 : struct tstream_tls *tlss =
312 4579599 : tstream_context_data(stream,
313 : struct tstream_tls);
314 : struct tevent_req *subreq;
315 : size_t len;
316 :
317 4579599 : if (tlss->error != 0) {
318 0 : errno = tlss->error;
319 0 : return -1;
320 : }
321 :
322 4579599 : if (tlss->pull.subreq) {
323 4640 : errno = EAGAIN;
324 4640 : return -1;
325 : }
326 :
327 4574959 : if (tlss->pull.iov.iov_base) {
328 : uint8_t *b;
329 : size_t n;
330 :
331 2287280 : b = (uint8_t *)tlss->pull.iov.iov_base;
332 :
333 2287280 : n = MIN(tlss->pull.iov.iov_len, size);
334 2287280 : memcpy(buf, b, n);
335 :
336 2287280 : tlss->pull.iov.iov_len -= n;
337 2287280 : b += n;
338 2287280 : tlss->pull.iov.iov_base = (char *)b;
339 2287280 : if (tlss->pull.iov.iov_len == 0) {
340 2287280 : tlss->pull.iov.iov_base = NULL;
341 2287280 : TALLOC_FREE(tlss->pull.buf);
342 : }
343 :
344 2287280 : return n;
345 : }
346 :
347 2287679 : if (size == 0) {
348 0 : return 0;
349 : }
350 :
351 2287679 : len = MIN(size, UINT16_MAX);
352 :
353 2287679 : tlss->pull.buf = talloc_array(tlss, uint8_t, len);
354 2287679 : if (tlss->pull.buf == NULL) {
355 0 : return -1;
356 : }
357 :
358 2287679 : tlss->pull.iov.iov_base = (char *)tlss->pull.buf;
359 2287679 : tlss->pull.iov.iov_len = len;
360 :
361 2287679 : subreq = tstream_readv_send(tlss,
362 : tlss->current_ev,
363 : tlss->plain_stream,
364 : &tlss->pull.iov, 1);
365 2287679 : if (subreq == NULL) {
366 0 : errno = ENOMEM;
367 0 : return -1;
368 : }
369 2287679 : tevent_req_set_callback(subreq, tstream_tls_pull_done, stream);
370 :
371 2287679 : tlss->pull.subreq = subreq;
372 2287679 : errno = EAGAIN;
373 2287679 : return -1;
374 : }
375 :
376 2287676 : static void tstream_tls_pull_done(struct tevent_req *subreq)
377 : {
378 2286711 : struct tstream_context *stream =
379 2287676 : tevent_req_callback_data(subreq,
380 : struct tstream_context);
381 2286711 : struct tstream_tls *tlss =
382 2287676 : tstream_context_data(stream,
383 : struct tstream_tls);
384 : int ret;
385 : int sys_errno;
386 :
387 2287676 : tlss->pull.subreq = NULL;
388 :
389 2287676 : ret = tstream_readv_recv(subreq, &sys_errno);
390 2287676 : TALLOC_FREE(subreq);
391 2287676 : if (ret == -1) {
392 396 : tlss->error = sys_errno;
393 396 : tstream_tls_retry(stream, false);
394 396 : return;
395 : }
396 :
397 2287280 : tstream_tls_retry(stream, false);
398 : }
399 :
400 797 : static int tstream_tls_destructor(struct tstream_tls *tlss)
401 : {
402 797 : if (tlss->tls_session) {
403 797 : gnutls_deinit(tlss->tls_session);
404 797 : tlss->tls_session = NULL;
405 : }
406 :
407 797 : return 0;
408 : }
409 :
410 0 : static ssize_t tstream_tls_pending_bytes(struct tstream_context *stream)
411 : {
412 0 : struct tstream_tls *tlss =
413 0 : tstream_context_data(stream,
414 : struct tstream_tls);
415 : size_t ret;
416 :
417 0 : if (tlss->error != 0) {
418 0 : errno = tlss->error;
419 0 : return -1;
420 : }
421 :
422 0 : ret = gnutls_record_check_pending(tlss->tls_session);
423 0 : ret += tlss->read.left;
424 :
425 0 : 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 10640 : 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 10230 : struct tstream_tls *tlss =
446 10640 : tstream_context_data(stream,
447 : struct tstream_tls);
448 : struct tevent_req *req;
449 : struct tstream_tls_readv_state *state;
450 :
451 10640 : tlss->read.req = NULL;
452 10640 : tlss->current_ev = ev;
453 :
454 10640 : req = tevent_req_create(mem_ctx, &state,
455 : struct tstream_tls_readv_state);
456 10640 : if (req == NULL) {
457 0 : return NULL;
458 : }
459 :
460 10640 : state->stream = stream;
461 10640 : state->ret = 0;
462 :
463 10640 : if (tlss->error != 0) {
464 0 : tevent_req_error(req, tlss->error);
465 0 : 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 10640 : state->vector = talloc_array(state, struct iovec, count);
472 10640 : if (tevent_req_nomem(state->vector, req)) {
473 0 : return tevent_req_post(req, ev);
474 : }
475 10640 : memcpy(state->vector, vector, sizeof(struct iovec) * count);
476 10640 : state->count = count;
477 :
478 10640 : tstream_tls_readv_crypt_next(req);
479 10640 : if (!tevent_req_is_in_progress(req)) {
480 5743 : return tevent_req_post(req, ev);
481 : }
482 :
483 4897 : return req;
484 : }
485 :
486 1149550 : static void tstream_tls_readv_crypt_next(struct tevent_req *req)
487 : {
488 1148985 : struct tstream_tls_readv_state *state =
489 1149550 : tevent_req_data(req,
490 : struct tstream_tls_readv_state);
491 1148985 : struct tstream_tls *tlss =
492 1149550 : tstream_context_data(state->stream,
493 : struct tstream_tls);
494 :
495 : /*
496 : * copy the pending buffer first
497 : */
498 3444571 : while (tlss->read.left > 0 && state->count > 0) {
499 1146036 : uint8_t *base = (uint8_t *)state->vector[0].iov_base;
500 1146036 : size_t len = MIN(tlss->read.left, state->vector[0].iov_len);
501 :
502 1146036 : memcpy(base, tlss->read.buffer + tlss->read.ofs, len);
503 :
504 1146036 : base += len;
505 1146036 : state->vector[0].iov_base = (char *) base;
506 1146036 : state->vector[0].iov_len -= len;
507 :
508 1146036 : tlss->read.ofs += len;
509 1146036 : tlss->read.left -= len;
510 :
511 1146036 : if (state->vector[0].iov_len == 0) {
512 10246 : state->vector += 1;
513 10246 : state->count -= 1;
514 : }
515 :
516 1146036 : state->ret += len;
517 : }
518 :
519 1149550 : if (state->count == 0) {
520 10246 : tevent_req_done(req);
521 10246 : return;
522 : }
523 :
524 1139304 : tlss->read.req = req;
525 1139304 : tstream_tls_retry_read(state->stream);
526 : }
527 :
528 3420964 : static void tstream_tls_retry_read(struct tstream_context *stream)
529 : {
530 3420301 : struct tstream_tls *tlss =
531 3420964 : tstream_context_data(stream,
532 : struct tstream_tls);
533 3420964 : struct tevent_req *req = tlss->read.req;
534 : int ret;
535 :
536 3420964 : if (tlss->error != 0) {
537 392 : tevent_req_error(req, tlss->error);
538 392 : return;
539 : }
540 :
541 3420572 : tlss->read.left = 0;
542 3420572 : tlss->read.ofs = 0;
543 :
544 3421209 : ret = gnutls_record_recv(tlss->tls_session,
545 3420572 : tlss->read.buffer,
546 : sizeof(tlss->read.buffer));
547 3420572 : if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
548 2281662 : return;
549 : }
550 :
551 1138910 : tlss->read.req = NULL;
552 :
553 1138910 : if (gnutls_error_is_fatal(ret) != 0) {
554 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
555 0 : tlss->error = EIO;
556 0 : tevent_req_error(req, tlss->error);
557 0 : return;
558 : }
559 :
560 1138910 : if (ret == 0) {
561 0 : tlss->error = EPIPE;
562 0 : tevent_req_error(req, tlss->error);
563 0 : return;
564 : }
565 :
566 1138910 : tlss->read.left = ret;
567 1138910 : tstream_tls_readv_crypt_next(req);
568 : }
569 :
570 10638 : static int tstream_tls_readv_recv(struct tevent_req *req,
571 : int *perrno)
572 : {
573 10228 : struct tstream_tls_readv_state *state =
574 10638 : tevent_req_data(req,
575 : struct tstream_tls_readv_state);
576 10228 : struct tstream_tls *tlss =
577 10638 : tstream_context_data(state->stream,
578 : struct tstream_tls);
579 : int ret;
580 :
581 10638 : tlss->read.req = NULL;
582 :
583 10638 : ret = tsocket_simple_int_recv(req, perrno);
584 10638 : if (ret == 0) {
585 10246 : ret = state->ret;
586 : }
587 :
588 10638 : tevent_req_received(req);
589 10638 : 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 3108 : 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 2962 : struct tstream_tls *tlss =
610 3108 : tstream_context_data(stream,
611 : struct tstream_tls);
612 : struct tevent_req *req;
613 : struct tstream_tls_writev_state *state;
614 :
615 3108 : tlss->write.req = NULL;
616 3108 : tlss->current_ev = ev;
617 :
618 3108 : req = tevent_req_create(mem_ctx, &state,
619 : struct tstream_tls_writev_state);
620 3108 : if (req == NULL) {
621 0 : return NULL;
622 : }
623 :
624 3108 : state->stream = stream;
625 3108 : state->ret = 0;
626 :
627 3108 : if (tlss->error != 0) {
628 0 : tevent_req_error(req, tlss->error);
629 0 : 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 3108 : state->vector = talloc_array(state, struct iovec, count);
636 3108 : if (tevent_req_nomem(state->vector, req)) {
637 0 : return tevent_req_post(req, ev);
638 : }
639 3108 : memcpy(state->vector, vector, sizeof(struct iovec) * count);
640 3108 : state->count = count;
641 :
642 3108 : tstream_tls_writev_crypt_next(req);
643 3108 : if (!tevent_req_is_in_progress(req)) {
644 2875 : return tevent_req_post(req, ev);
645 : }
646 :
647 233 : return req;
648 : }
649 :
650 1142018 : static void tstream_tls_writev_crypt_next(struct tevent_req *req)
651 : {
652 1141717 : struct tstream_tls_writev_state *state =
653 1142018 : tevent_req_data(req,
654 : struct tstream_tls_writev_state);
655 1141717 : struct tstream_tls *tlss =
656 1142018 : tstream_context_data(state->stream,
657 : struct tstream_tls);
658 :
659 1142018 : tlss->write.left = sizeof(tlss->write.buffer);
660 1142018 : tlss->write.ofs = 0;
661 :
662 : /*
663 : * first fill our buffer
664 : */
665 3424648 : while (tlss->write.left > 0 && state->count > 0) {
666 1140913 : uint8_t *base = (uint8_t *)state->vector[0].iov_base;
667 1140913 : size_t len = MIN(tlss->write.left, state->vector[0].iov_len);
668 :
669 1140913 : memcpy(tlss->write.buffer + tlss->write.ofs, base, len);
670 :
671 1140913 : base += len;
672 1140913 : state->vector[0].iov_base = (char *) base;
673 1140913 : state->vector[0].iov_len -= len;
674 :
675 1140913 : tlss->write.ofs += len;
676 1140913 : tlss->write.left -= len;
677 :
678 1140913 : if (state->vector[0].iov_len == 0) {
679 5123 : state->vector += 1;
680 5123 : state->count -= 1;
681 : }
682 :
683 1140913 : state->ret += len;
684 : }
685 :
686 1142018 : if (tlss->write.ofs == 0) {
687 3108 : tevent_req_done(req);
688 3108 : return;
689 : }
690 :
691 1138910 : tlss->write.left = tlss->write.ofs;
692 1138910 : tlss->write.ofs = 0;
693 :
694 1138910 : tlss->write.req = req;
695 1138910 : tstream_tls_retry_write(state->stream);
696 : }
697 :
698 1156960 : static void tstream_tls_retry_write(struct tstream_context *stream)
699 : {
700 1156805 : struct tstream_tls *tlss =
701 1156960 : tstream_context_data(stream,
702 : struct tstream_tls);
703 1156960 : struct tevent_req *req = tlss->write.req;
704 : int ret;
705 :
706 1156960 : if (tlss->error != 0) {
707 0 : tevent_req_error(req, tlss->error);
708 0 : return;
709 : }
710 :
711 2313920 : ret = gnutls_record_send(tlss->tls_session,
712 1156960 : tlss->write.buffer + tlss->write.ofs,
713 : tlss->write.left);
714 1156960 : if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
715 18050 : return;
716 : }
717 :
718 1138910 : tlss->write.req = NULL;
719 :
720 1138910 : if (gnutls_error_is_fatal(ret) != 0) {
721 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
722 0 : tlss->error = EIO;
723 0 : tevent_req_error(req, tlss->error);
724 0 : return;
725 : }
726 :
727 1138910 : if (ret == 0) {
728 0 : tlss->error = EPIPE;
729 0 : tevent_req_error(req, tlss->error);
730 0 : return;
731 : }
732 :
733 1138910 : tlss->write.ofs += ret;
734 1138910 : tlss->write.left -= ret;
735 :
736 1138910 : if (tlss->write.left > 0) {
737 0 : tlss->write.req = req;
738 0 : tstream_tls_retry_write(stream);
739 0 : return;
740 : }
741 :
742 1138910 : tstream_tls_writev_crypt_next(req);
743 : }
744 :
745 3108 : static int tstream_tls_writev_recv(struct tevent_req *req,
746 : int *perrno)
747 : {
748 2962 : struct tstream_tls_writev_state *state =
749 3108 : tevent_req_data(req,
750 : struct tstream_tls_writev_state);
751 2962 : struct tstream_tls *tlss =
752 3108 : tstream_context_data(state->stream,
753 : struct tstream_tls);
754 : int ret;
755 :
756 3108 : tlss->write.req = NULL;
757 :
758 3108 : ret = tsocket_simple_int_recv(req, perrno);
759 3108 : if (ret == 0) {
760 3108 : ret = state->ret;
761 : }
762 :
763 3108 : tevent_req_received(req);
764 3108 : return ret;
765 : }
766 :
767 : struct tstream_tls_disconnect_state {
768 : uint8_t _dummy;
769 : };
770 :
771 392 : static struct tevent_req *tstream_tls_disconnect_send(TALLOC_CTX *mem_ctx,
772 : struct tevent_context *ev,
773 : struct tstream_context *stream)
774 : {
775 366 : struct tstream_tls *tlss =
776 392 : tstream_context_data(stream,
777 : struct tstream_tls);
778 : struct tevent_req *req;
779 : struct tstream_tls_disconnect_state *state;
780 :
781 392 : tlss->disconnect.req = NULL;
782 392 : tlss->current_ev = ev;
783 :
784 392 : req = tevent_req_create(mem_ctx, &state,
785 : struct tstream_tls_disconnect_state);
786 392 : if (req == NULL) {
787 0 : return NULL;
788 : }
789 :
790 392 : if (tlss->error != 0) {
791 392 : tevent_req_error(req, tlss->error);
792 392 : return tevent_req_post(req, ev);
793 : }
794 :
795 0 : tlss->disconnect.req = req;
796 0 : tstream_tls_retry_disconnect(stream);
797 0 : if (!tevent_req_is_in_progress(req)) {
798 0 : return tevent_req_post(req, ev);
799 : }
800 :
801 0 : return req;
802 : }
803 :
804 0 : static void tstream_tls_retry_disconnect(struct tstream_context *stream)
805 : {
806 0 : struct tstream_tls *tlss =
807 0 : tstream_context_data(stream,
808 : struct tstream_tls);
809 0 : struct tevent_req *req = tlss->disconnect.req;
810 : int ret;
811 :
812 0 : if (tlss->error != 0) {
813 0 : tevent_req_error(req, tlss->error);
814 0 : return;
815 : }
816 :
817 0 : ret = gnutls_bye(tlss->tls_session, GNUTLS_SHUT_WR);
818 0 : if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
819 0 : return;
820 : }
821 :
822 0 : tlss->disconnect.req = NULL;
823 :
824 0 : if (gnutls_error_is_fatal(ret) != 0) {
825 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
826 0 : tlss->error = EIO;
827 0 : tevent_req_error(req, tlss->error);
828 0 : return;
829 : }
830 :
831 0 : if (ret != GNUTLS_E_SUCCESS) {
832 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
833 0 : tlss->error = EIO;
834 0 : tevent_req_error(req, tlss->error);
835 0 : return;
836 : }
837 :
838 0 : tevent_req_done(req);
839 : }
840 :
841 392 : static int tstream_tls_disconnect_recv(struct tevent_req *req,
842 : int *perrno)
843 : {
844 : int ret;
845 :
846 392 : ret = tsocket_simple_int_recv(req, perrno);
847 :
848 392 : tevent_req_received(req);
849 392 : 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 13037 : static int tstream_tls_params_destructor(struct tstream_tls_params *tlsp)
877 : {
878 13037 : if (tlsp->x509_cred) {
879 13037 : gnutls_certificate_free_credentials(tlsp->x509_cred);
880 13037 : tlsp->x509_cred = NULL;
881 : }
882 13037 : if (tlsp->dh_params) {
883 12632 : gnutls_dh_params_deinit(tlsp->dh_params);
884 12632 : tlsp->dh_params = NULL;
885 : }
886 :
887 13037 : return 0;
888 : }
889 :
890 192 : bool tstream_tls_params_enabled(struct tstream_tls_params *tlsp)
891 : {
892 192 : return tlsp->tls_enabled;
893 : }
894 :
895 405 : 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 405 : tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
907 405 : NT_STATUS_HAVE_NO_MEMORY(tlsp);
908 :
909 405 : talloc_set_destructor(tlsp, tstream_tls_params_destructor);
910 :
911 405 : tlsp->verify_peer = verify_peer;
912 405 : if (peer_name != NULL) {
913 405 : tlsp->peer_name = talloc_strdup(tlsp, peer_name);
914 405 : if (tlsp->peer_name == NULL) {
915 0 : talloc_free(tlsp);
916 0 : return NT_STATUS_NO_MEMORY;
917 : }
918 0 : } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) {
919 0 : DEBUG(0,("TLS failed to missing peer_name - "
920 : "with 'tls verify peer = %s'\n",
921 : tls_verify_peer_string(tlsp->verify_peer)));
922 0 : talloc_free(tlsp);
923 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
924 : }
925 :
926 405 : ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
927 405 : if (ret != GNUTLS_E_SUCCESS) {
928 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
929 0 : talloc_free(tlsp);
930 0 : return NT_STATUS_NO_MEMORY;
931 : }
932 :
933 405 : if (ca_file && *ca_file && file_exist(ca_file)) {
934 405 : ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
935 : ca_file,
936 : GNUTLS_X509_FMT_PEM);
937 778 : if (ret < 0) {
938 0 : DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
939 : ca_file, gnutls_strerror(ret)));
940 0 : talloc_free(tlsp);
941 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
942 : }
943 0 : } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) {
944 0 : 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 0 : talloc_free(tlsp);
949 0 : return NT_STATUS_INVALID_PARAMETER_MIX;
950 : }
951 :
952 405 : if (crl_file && *crl_file && file_exist(crl_file)) {
953 292 : ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
954 : crl_file,
955 : GNUTLS_X509_FMT_PEM);
956 567 : if (ret < 0) {
957 0 : DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
958 : crl_file, gnutls_strerror(ret)));
959 0 : talloc_free(tlsp);
960 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
961 : }
962 113 : } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE) {
963 6 : 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 6 : talloc_free(tlsp);
968 6 : return NT_STATUS_INVALID_PARAMETER_MIX;
969 : }
970 :
971 399 : tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
972 399 : if (tlsp->tls_priority == NULL) {
973 0 : talloc_free(tlsp);
974 0 : return NT_STATUS_NO_MEMORY;
975 : }
976 :
977 399 : tlsp->tls_enabled = true;
978 :
979 399 : *_tlsp = tlsp;
980 399 : return NT_STATUS_OK;
981 : }
982 :
983 : struct tstream_tls_connect_state {
984 : struct tstream_context *tls_stream;
985 : };
986 :
987 399 : 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 399 : req = tevent_req_create(mem_ctx, &state,
1000 : struct tstream_tls_connect_state);
1001 399 : if (req == NULL) {
1002 0 : return NULL;
1003 : }
1004 :
1005 399 : state->tls_stream = tstream_context_create(state,
1006 : &tstream_tls_ops,
1007 : &tlss,
1008 : struct tstream_tls,
1009 : location);
1010 399 : if (tevent_req_nomem(state->tls_stream, req)) {
1011 0 : return tevent_req_post(req, ev);
1012 : }
1013 399 : ZERO_STRUCTP(tlss);
1014 399 : talloc_set_destructor(tlss, tstream_tls_destructor);
1015 :
1016 399 : tlss->plain_stream = plain_stream;
1017 399 : tlss->verify_peer = tls_params->verify_peer;
1018 399 : if (tls_params->peer_name != NULL) {
1019 399 : tlss->peer_name = talloc_strdup(tlss, tls_params->peer_name);
1020 399 : if (tevent_req_nomem(tlss->peer_name, req)) {
1021 0 : return tevent_req_post(req, ev);
1022 : }
1023 : }
1024 :
1025 399 : tlss->current_ev = ev;
1026 399 : tlss->retry_im = tevent_create_immediate(tlss);
1027 399 : if (tevent_req_nomem(tlss->retry_im, req)) {
1028 0 : return tevent_req_post(req, ev);
1029 : }
1030 :
1031 399 : ret = gnutls_init(&tlss->tls_session, GNUTLS_CLIENT);
1032 399 : if (ret != GNUTLS_E_SUCCESS) {
1033 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1034 0 : tevent_req_error(req, EINVAL);
1035 0 : return tevent_req_post(req, ev);
1036 : }
1037 :
1038 399 : ret = gnutls_set_default_priority(tlss->tls_session);
1039 399 : if (ret != GNUTLS_E_SUCCESS) {
1040 0 : DBG_ERR("TLS %s - %s. Failed to set default priorities\n",
1041 : __location__, gnutls_strerror(ret));
1042 0 : tevent_req_error(req, EINVAL);
1043 0 : return tevent_req_post(req, ev);
1044 : }
1045 :
1046 399 : if (strlen(tls_params->tls_priority) > 0) {
1047 399 : ret = gnutls_priority_set_direct(tlss->tls_session,
1048 : tls_params->tls_priority,
1049 : &error_pos);
1050 399 : if (ret != GNUTLS_E_SUCCESS) {
1051 0 : DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n",
1052 : __location__, gnutls_strerror(ret), error_pos));
1053 0 : tevent_req_error(req, EINVAL);
1054 0 : return tevent_req_post(req, ev);
1055 : }
1056 : }
1057 :
1058 399 : ret = gnutls_credentials_set(tlss->tls_session,
1059 : GNUTLS_CRD_CERTIFICATE,
1060 399 : tls_params->x509_cred);
1061 399 : if (ret != GNUTLS_E_SUCCESS) {
1062 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1063 0 : tevent_req_error(req, EINVAL);
1064 0 : return tevent_req_post(req, ev);
1065 : }
1066 :
1067 399 : gnutls_transport_set_ptr(tlss->tls_session,
1068 399 : (gnutls_transport_ptr_t)state->tls_stream);
1069 399 : gnutls_transport_set_pull_function(tlss->tls_session,
1070 : (gnutls_pull_func)tstream_tls_pull_function);
1071 399 : gnutls_transport_set_push_function(tlss->tls_session,
1072 : (gnutls_push_func)tstream_tls_push_function);
1073 :
1074 399 : tlss->handshake.req = req;
1075 399 : tstream_tls_retry_handshake(state->tls_stream);
1076 399 : if (!tevent_req_is_in_progress(req)) {
1077 0 : return tevent_req_post(req, ev);
1078 : }
1079 :
1080 399 : return req;
1081 : }
1082 :
1083 399 : 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 370 : struct tstream_tls_connect_state *state =
1089 399 : tevent_req_data(req,
1090 : struct tstream_tls_connect_state);
1091 :
1092 399 : if (tevent_req_is_unix_error(req, perrno)) {
1093 13 : tevent_req_received(req);
1094 13 : return -1;
1095 : }
1096 :
1097 386 : *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
1098 386 : tevent_req_received(req);
1099 386 : return 0;
1100 : }
1101 :
1102 : /*
1103 : initialise global tls state
1104 : */
1105 48 : 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 48 : if (!enabled || key_file == NULL || *key_file == 0) {
1121 0 : tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
1122 0 : NT_STATUS_HAVE_NO_MEMORY(tlsp);
1123 0 : talloc_set_destructor(tlsp, tstream_tls_params_destructor);
1124 0 : tlsp->tls_enabled = false;
1125 :
1126 0 : *_tlsp = tlsp;
1127 0 : return NT_STATUS_OK;
1128 : }
1129 :
1130 48 : tlsp = talloc_zero(mem_ctx, struct tstream_tls_params);
1131 48 : NT_STATUS_HAVE_NO_MEMORY(tlsp);
1132 :
1133 48 : talloc_set_destructor(tlsp, tstream_tls_params_destructor);
1134 :
1135 48 : if (!file_exist(ca_file)) {
1136 25 : tls_cert_generate(tlsp, dns_host_name,
1137 : key_file, cert_file, ca_file);
1138 : }
1139 :
1140 84 : if (file_exist(key_file) &&
1141 48 : !file_check_permissions(key_file, geteuid(), 0600, &st))
1142 : {
1143 0 : 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 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1152 : }
1153 :
1154 48 : ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred);
1155 48 : if (ret != GNUTLS_E_SUCCESS) {
1156 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1157 0 : talloc_free(tlsp);
1158 0 : return NT_STATUS_NO_MEMORY;
1159 : }
1160 :
1161 48 : if (ca_file && *ca_file) {
1162 48 : ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred,
1163 : ca_file,
1164 : GNUTLS_X509_FMT_PEM);
1165 48 : if (ret < 0) {
1166 0 : DEBUG(0,("TLS failed to initialise cafile %s - %s\n",
1167 : ca_file, gnutls_strerror(ret)));
1168 0 : talloc_free(tlsp);
1169 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1170 : }
1171 : }
1172 :
1173 48 : if (crl_file && *crl_file) {
1174 21 : ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred,
1175 : crl_file,
1176 : GNUTLS_X509_FMT_PEM);
1177 21 : if (ret < 0) {
1178 0 : DEBUG(0,("TLS failed to initialise crlfile %s - %s\n",
1179 : crl_file, gnutls_strerror(ret)));
1180 0 : talloc_free(tlsp);
1181 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1182 : }
1183 : }
1184 :
1185 48 : ret = gnutls_certificate_set_x509_key_file(tlsp->x509_cred,
1186 : cert_file, key_file,
1187 : GNUTLS_X509_FMT_PEM);
1188 48 : if (ret != GNUTLS_E_SUCCESS) {
1189 0 : DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s - %s\n",
1190 : cert_file, key_file, gnutls_strerror(ret)));
1191 0 : talloc_free(tlsp);
1192 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1193 : }
1194 :
1195 48 : ret = gnutls_dh_params_init(&tlsp->dh_params);
1196 48 : if (ret != GNUTLS_E_SUCCESS) {
1197 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1198 0 : talloc_free(tlsp);
1199 0 : return NT_STATUS_NO_MEMORY;
1200 : }
1201 :
1202 96 : if (dhp_file && *dhp_file) {
1203 : gnutls_datum_t dhparms;
1204 : size_t size;
1205 :
1206 48 : dhparms.data = (uint8_t *)file_load(dhp_file, &size, 0, tlsp);
1207 :
1208 48 : if (!dhparms.data) {
1209 0 : DEBUG(0,("TLS failed to read DH Parms from %s - %d:%s\n",
1210 : dhp_file, errno, strerror(errno)));
1211 0 : talloc_free(tlsp);
1212 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1213 : }
1214 48 : dhparms.size = size;
1215 :
1216 48 : ret = gnutls_dh_params_import_pkcs3(tlsp->dh_params,
1217 : &dhparms,
1218 : GNUTLS_X509_FMT_PEM);
1219 48 : if (ret != GNUTLS_E_SUCCESS) {
1220 0 : DEBUG(0,("TLS failed to import pkcs3 %s - %s\n",
1221 : dhp_file, gnutls_strerror(ret)));
1222 0 : talloc_free(tlsp);
1223 0 : return NT_STATUS_CANT_ACCESS_DOMAIN_INFO;
1224 : }
1225 : } else {
1226 0 : ret = gnutls_dh_params_generate2(tlsp->dh_params, DH_BITS);
1227 0 : if (ret != GNUTLS_E_SUCCESS) {
1228 0 : DEBUG(0,("TLS failed to generate dh_params - %s\n",
1229 : gnutls_strerror(ret)));
1230 0 : talloc_free(tlsp);
1231 0 : return NT_STATUS_INTERNAL_ERROR;
1232 : }
1233 : }
1234 :
1235 48 : gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params);
1236 :
1237 48 : tlsp->tls_priority = talloc_strdup(tlsp, tls_priority);
1238 48 : if (tlsp->tls_priority == NULL) {
1239 0 : talloc_free(tlsp);
1240 0 : return NT_STATUS_NO_MEMORY;
1241 : }
1242 :
1243 48 : tlsp->tls_enabled = true;
1244 :
1245 48 : *_tlsp = tlsp;
1246 48 : return NT_STATUS_OK;
1247 : }
1248 :
1249 : struct tstream_tls_accept_state {
1250 : struct tstream_context *tls_stream;
1251 : };
1252 :
1253 398 : 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 398 : req = tevent_req_create(mem_ctx, &state,
1266 : struct tstream_tls_accept_state);
1267 398 : if (req == NULL) {
1268 0 : return NULL;
1269 : }
1270 :
1271 398 : state->tls_stream = tstream_context_create(state,
1272 : &tstream_tls_ops,
1273 : &tlss,
1274 : struct tstream_tls,
1275 : location);
1276 398 : if (tevent_req_nomem(state->tls_stream, req)) {
1277 0 : return tevent_req_post(req, ev);
1278 : }
1279 398 : ZERO_STRUCTP(tlss);
1280 398 : talloc_set_destructor(tlss, tstream_tls_destructor);
1281 :
1282 398 : tlss->plain_stream = plain_stream;
1283 :
1284 398 : tlss->current_ev = ev;
1285 398 : tlss->retry_im = tevent_create_immediate(tlss);
1286 398 : if (tevent_req_nomem(tlss->retry_im, req)) {
1287 0 : return tevent_req_post(req, ev);
1288 : }
1289 :
1290 398 : ret = gnutls_init(&tlss->tls_session, GNUTLS_SERVER);
1291 398 : if (ret != GNUTLS_E_SUCCESS) {
1292 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1293 0 : tevent_req_error(req, EINVAL);
1294 0 : return tevent_req_post(req, ev);
1295 : }
1296 :
1297 398 : ret = gnutls_set_default_priority(tlss->tls_session);
1298 398 : if (ret != GNUTLS_E_SUCCESS) {
1299 0 : DBG_ERR("TLS %s - %s. Failed to set default priorities\n",
1300 : __location__, gnutls_strerror(ret));
1301 0 : tevent_req_error(req, EINVAL);
1302 0 : return tevent_req_post(req, ev);
1303 : }
1304 :
1305 398 : if (strlen(tlsp->tls_priority) > 0) {
1306 398 : ret = gnutls_priority_set_direct(tlss->tls_session,
1307 : tlsp->tls_priority,
1308 : &error_pos);
1309 398 : if (ret != GNUTLS_E_SUCCESS) {
1310 0 : DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n",
1311 : __location__, gnutls_strerror(ret), error_pos));
1312 0 : tevent_req_error(req, EINVAL);
1313 0 : return tevent_req_post(req, ev);
1314 : }
1315 : }
1316 :
1317 398 : ret = gnutls_credentials_set(tlss->tls_session, GNUTLS_CRD_CERTIFICATE,
1318 398 : tlsp->x509_cred);
1319 398 : if (ret != GNUTLS_E_SUCCESS) {
1320 0 : DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1321 0 : tevent_req_error(req, EINVAL);
1322 0 : return tevent_req_post(req, ev);
1323 : }
1324 :
1325 398 : gnutls_certificate_server_set_request(tlss->tls_session,
1326 : GNUTLS_CERT_REQUEST);
1327 398 : gnutls_dh_set_prime_bits(tlss->tls_session, DH_BITS);
1328 :
1329 398 : gnutls_transport_set_ptr(tlss->tls_session,
1330 398 : (gnutls_transport_ptr_t)state->tls_stream);
1331 398 : gnutls_transport_set_pull_function(tlss->tls_session,
1332 : (gnutls_pull_func)tstream_tls_pull_function);
1333 398 : gnutls_transport_set_push_function(tlss->tls_session,
1334 : (gnutls_push_func)tstream_tls_push_function);
1335 :
1336 398 : tlss->handshake.req = req;
1337 398 : tstream_tls_retry_handshake(state->tls_stream);
1338 398 : if (!tevent_req_is_in_progress(req)) {
1339 0 : return tevent_req_post(req, ev);
1340 : }
1341 :
1342 398 : return req;
1343 : }
1344 :
1345 11454 : static void tstream_tls_retry_handshake(struct tstream_context *stream)
1346 : {
1347 10680 : struct tstream_tls *tlss =
1348 11454 : tstream_context_data(stream,
1349 : struct tstream_tls);
1350 11454 : struct tevent_req *req = tlss->handshake.req;
1351 : int ret;
1352 :
1353 11454 : if (tlss->error != 0) {
1354 5 : tevent_req_error(req, tlss->error);
1355 5 : return;
1356 : }
1357 :
1358 11449 : ret = gnutls_handshake(tlss->tls_session);
1359 11449 : if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) {
1360 10657 : return;
1361 : }
1362 :
1363 792 : tlss->handshake.req = NULL;
1364 :
1365 792 : if (gnutls_error_is_fatal(ret) != 0) {
1366 1 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1367 1 : tlss->error = EIO;
1368 1 : tevent_req_error(req, tlss->error);
1369 1 : return;
1370 : }
1371 :
1372 791 : if (ret != GNUTLS_E_SUCCESS) {
1373 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1374 0 : tlss->error = EIO;
1375 0 : tevent_req_error(req, tlss->error);
1376 0 : return;
1377 : }
1378 :
1379 791 : if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) {
1380 30 : unsigned int status = UINT32_MAX;
1381 30 : bool ip = true;
1382 30 : const char *hostname = NULL;
1383 :
1384 30 : if (tlss->peer_name != NULL) {
1385 30 : ip = is_ipaddress(tlss->peer_name);
1386 : }
1387 :
1388 30 : if (!ip) {
1389 20 : hostname = tlss->peer_name;
1390 : }
1391 :
1392 30 : if (tlss->verify_peer == TLS_VERIFY_PEER_CA_ONLY) {
1393 9 : hostname = NULL;
1394 : }
1395 :
1396 30 : if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) {
1397 12 : if (hostname == NULL) {
1398 4 : 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 4 : tlss->error = EINVAL;
1404 4 : tevent_req_error(req, tlss->error);
1405 6 : return;
1406 : }
1407 : }
1408 :
1409 26 : ret = gnutls_certificate_verify_peers3(tlss->tls_session,
1410 : hostname,
1411 : &status);
1412 26 : if (ret != GNUTLS_E_SUCCESS) {
1413 0 : DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret)));
1414 0 : tlss->error = EIO;
1415 0 : tevent_req_error(req, tlss->error);
1416 0 : return;
1417 : }
1418 :
1419 26 : if (status != 0) {
1420 7 : 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 7 : tlss->error = EINVAL;
1442 7 : tevent_req_error(req, tlss->error);
1443 7 : return;
1444 : }
1445 : }
1446 :
1447 780 : tevent_req_done(req);
1448 : }
1449 :
1450 398 : 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 369 : struct tstream_tls_accept_state *state =
1456 398 : tevent_req_data(req,
1457 : struct tstream_tls_accept_state);
1458 :
1459 398 : if (tevent_req_is_unix_error(req, perrno)) {
1460 4 : tevent_req_received(req);
1461 4 : return -1;
1462 : }
1463 :
1464 394 : *tls_stream = talloc_move(mem_ctx, &state->tls_stream);
1465 394 : tevent_req_received(req);
1466 394 : return 0;
1467 : }
|