Changeset 988 for vendor/current/source4/lib/tls
- Timestamp:
- Nov 24, 2016, 1:14:11 PM (9 years ago)
- Location:
- vendor/current/source4/lib/tls
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
vendor/current/source4/lib/tls/tls.c
r740 r988 1 /* 1 /* 2 2 Unix SMB/CIFS implementation. 3 3 … … 7 7 Copyright (C) Stefan Metzmacher 2004 8 8 Copyright (C) Andrew Bartlett 2006 9 9 10 10 This program is free software; you can redistribute it and/or modify 11 11 it under the terms of the GNU General Public License as published by 12 12 the Free Software Foundation; either version 3 of the License, or 13 13 (at your option) any later version. 14 14 15 15 This program is distributed in the hope that it will be useful, 16 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 18 GNU General Public License for more details. 19 19 20 20 You should have received a copy of the GNU General Public License 21 21 along with this program. If not, see <http://www.gnu.org/licenses/>. … … 23 23 24 24 #include "includes.h" 25 #include "system/filesys.h" 25 26 #include "lib/events/events.h" 26 27 #include "lib/socket/socket.h" … … 29 30 30 31 #if ENABLE_GNUTLS 31 #include "gnutls/gnutls.h"32 33 #define DH_BITS 102432 #include <gnutls/gnutls.h> 33 34 #define DH_BITS 2048 34 35 35 36 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T) … … 42 43 gnutls_dh_params dh_params; 43 44 bool tls_enabled; 45 const char *tls_priority; 44 46 }; 45 47 #endif … … 115 117 NTSTATUS status; 116 118 size_t nread; 117 119 118 120 if (tls->have_first_byte) { 119 121 *(uint8_t *)buf = tls->first_byte; … … 127 129 } 128 130 if (NT_STATUS_IS_ERR(status)) { 129 EVENT_FD_NOT_READABLE(tls->fde);130 EVENT_FD_NOT_WRITEABLE(tls->fde);131 TEVENT_FD_NOT_READABLE(tls->fde); 132 TEVENT_FD_NOT_WRITEABLE(tls->fde); 131 133 errno = EBADF; 132 134 return -1; 133 135 } 134 136 if (!NT_STATUS_IS_OK(status)) { 135 EVENT_FD_READABLE(tls->fde);137 TEVENT_FD_READABLE(tls->fde); 136 138 errno = EAGAIN; 137 139 return -1; 138 140 } 139 141 if (tls->output_pending) { 140 EVENT_FD_WRITEABLE(tls->fde);142 TEVENT_FD_WRITEABLE(tls->fde); 141 143 } 142 144 if (size != nread) { 143 EVENT_FD_READABLE(tls->fde);145 TEVENT_FD_READABLE(tls->fde); 144 146 } 145 147 return nread; … … 153 155 struct tls_context *tls = talloc_get_type(ptr, struct tls_context); 154 156 NTSTATUS status; 155 size_t nwritten ;157 size_t nwritten, total_nwritten = 0; 156 158 DATA_BLOB b; 157 159 … … 163 165 b.length = size; 164 166 165 status = socket_send(tls->socket, &b, &nwritten); 166 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 167 errno = EAGAIN; 168 return -1; 169 } 170 if (!NT_STATUS_IS_OK(status)) { 171 EVENT_FD_WRITEABLE(tls->fde); 172 return -1; 173 } 174 if (size != nwritten) { 175 EVENT_FD_WRITEABLE(tls->fde); 176 } 177 return nwritten; 167 /* Cope with socket_wrapper 1500 byte chunking for PCAP */ 168 do { 169 status = socket_send(tls->socket, &b, &nwritten); 170 171 if (NT_STATUS_EQUAL(status, STATUS_MORE_ENTRIES)) { 172 errno = EAGAIN; 173 return -1; 174 } 175 if (!NT_STATUS_IS_OK(status)) { 176 TEVENT_FD_WRITEABLE(tls->fde); 177 return -1; 178 } 179 180 total_nwritten += nwritten; 181 182 if (size == nwritten) { 183 break; 184 } 185 186 b.data += nwritten; 187 b.length -= nwritten; 188 189 TEVENT_FD_WRITEABLE(tls->fde); 190 } while (b.length); 191 192 return total_nwritten; 178 193 } 179 194 … … 202 217 return NT_STATUS_OK; 203 218 } 204 219 205 220 ret = gnutls_handshake(tls->session); 206 221 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 207 222 if (gnutls_record_get_direction(tls->session) == 1) { 208 EVENT_FD_WRITEABLE(tls->fde);223 TEVENT_FD_WRITEABLE(tls->fde); 209 224 } 210 225 return STATUS_MORE_ENTRIES; … … 264 279 receive data either by tls or normal socket_recv 265 280 */ 266 static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, 281 static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, 267 282 size_t wantlen, size_t *nread) 268 283 { … … 299 314 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 300 315 if (gnutls_record_get_direction(tls->session) == 1) { 301 EVENT_FD_WRITEABLE(tls->fde);316 TEVENT_FD_WRITEABLE(tls->fde); 302 317 } 303 318 tls->interrupted = true; … … 315 330 send data either by tls or normal socket_recv 316 331 */ 317 static NTSTATUS tls_socket_send(struct socket_context *sock, 332 static NTSTATUS tls_socket_send(struct socket_context *sock, 318 333 const DATA_BLOB *blob, size_t *sendlen) 319 334 { … … 335 350 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 336 351 if (gnutls_record_get_direction(tls->session) == 1) { 337 EVENT_FD_WRITEABLE(tls->fde);352 TEVENT_FD_WRITEABLE(tls->fde); 338 353 } 339 354 tls->interrupted = true; … … 357 372 struct tls_params *params; 358 373 int ret; 374 struct stat st; 359 375 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 360 376 const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx); … … 376 392 } 377 393 394 params->tls_priority = lpcfg_tls_priority(lp_ctx); 395 378 396 if (!file_exist(cafile)) { 379 397 char *hostname = talloc_asprintf(mem_ctx, "%s.%s", … … 381 399 lpcfg_dnsdomain(lp_ctx)); 382 400 if (hostname == NULL) { 401 ret = GNUTLS_E_MEMORY_ERROR; 383 402 goto init_failed; 384 403 } … … 387 406 } 388 407 408 if (file_exist(keyfile) && 409 !file_check_permissions(keyfile, geteuid(), 0600, &st)) 410 { 411 DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n" 412 "owner uid %u should be %u, mode 0%o should be 0%o\n" 413 "This is known as CVE-2013-4476.\n" 414 "Removing all tls .pem files will cause an " 415 "auto-regeneration with the correct permissions.\n", 416 keyfile, 417 (unsigned int)st.st_uid, geteuid(), 418 (unsigned int)(st.st_mode & 0777), 0600)); 419 talloc_free(tmp_ctx); 420 return NULL; 421 } 422 389 423 ret = gnutls_global_init(); 390 424 if (ret < 0) goto init_failed; … … 394 428 395 429 if (cafile && *cafile) { 396 ret = gnutls_certificate_set_x509_trust_file(params->x509_cred, cafile, 397 GNUTLS_X509_FMT_PEM); 430 ret = gnutls_certificate_set_x509_trust_file(params->x509_cred, cafile, 431 GNUTLS_X509_FMT_PEM); 398 432 if (ret < 0) { 399 433 DEBUG(0,("TLS failed to initialise cafile %s\n", cafile)); … … 403 437 404 438 if (crlfile && *crlfile) { 405 ret = gnutls_certificate_set_x509_crl_file(params->x509_cred, 406 crlfile, 439 ret = gnutls_certificate_set_x509_crl_file(params->x509_cred, 440 crlfile, 407 441 GNUTLS_X509_FMT_PEM); 408 442 if (ret < 0) { … … 411 445 } 412 446 } 413 414 ret = gnutls_certificate_set_x509_key_file(params->x509_cred, 447 448 ret = gnutls_certificate_set_x509_key_file(params->x509_cred, 415 449 certfile, keyfile, 416 450 GNUTLS_X509_FMT_PEM); 417 451 if (ret < 0) { 418 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n", 452 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n", 419 453 certfile, keyfile)); 420 454 goto init_failed; 421 455 } 422 423 456 424 457 ret = gnutls_dh_params_init(¶ms->dh_params); 425 458 if (ret < 0) goto init_failed; … … 435 468 } 436 469 dhparms.size = size; 437 470 438 471 ret = gnutls_dh_params_import_pkcs3(params->dh_params, &dhparms, GNUTLS_X509_FMT_PEM); 439 472 if (ret < 0) goto init_failed; … … 442 475 if (ret < 0) goto init_failed; 443 476 } 444 477 445 478 gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params); 446 479 … … 461 494 setup for a new connection 462 495 */ 463 struct socket_context *tls_init_server(struct tls_params *params, 496 struct socket_context *tls_init_server(struct tls_params *params, 464 497 struct socket_context *socket_ctx, 465 struct tevent_fd *fde, 498 struct tevent_fd *fde, 466 499 const char *plain_chars) 467 500 { … … 470 503 struct socket_context *new_sock; 471 504 NTSTATUS nt_status; 472 473 nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, 474 SOCKET_TYPE_STREAM, 505 const char *error_pos; 506 507 nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, 508 SOCKET_TYPE_STREAM, 475 509 socket_ctx->flags | SOCKET_FLAG_ENCRYPT); 476 510 if (!NT_STATUS_IS_OK(nt_status)) { … … 498 532 talloc_set_destructor(tls, tls_destructor); 499 533 500 TLSCHECK(gnutls_set_default_priority(tls->session)); 501 TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, 534 ret = gnutls_priority_set_direct(tls->session, 535 params->tls_priority, 536 &error_pos); 537 if (ret != GNUTLS_E_SUCCESS) { 538 DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", 539 __location__, gnutls_strerror(ret), error_pos)); 540 talloc_free(new_sock); 541 return NULL; 542 } 543 544 TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, 502 545 params->x509_cred)); 503 546 gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_REQUEST); … … 506 549 gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); 507 550 gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); 551 #if GNUTLS_VERSION_MAJOR < 3 508 552 gnutls_transport_set_lowat(tls->session, 0); 553 #endif 509 554 510 555 tls->plain_chars = plain_chars; … … 520 565 tls->tls_enabled = true; 521 566 tls->interrupted = false; 522 567 523 568 new_sock->state = SOCKET_STATE_SERVER_CONNECTED; 524 569 … … 531 576 } 532 577 533 534 /*535 setup for a new client connection536 */537 struct socket_context *tls_init_client(struct socket_context *socket_ctx,538 struct tevent_fd *fde,539 const char *ca_path)540 {541 struct tls_context *tls;542 int ret = 0;543 const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 };544 struct socket_context *new_sock;545 NTSTATUS nt_status;546 547 nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock,548 SOCKET_TYPE_STREAM,549 socket_ctx->flags | SOCKET_FLAG_ENCRYPT);550 if (!NT_STATUS_IS_OK(nt_status)) {551 return NULL;552 }553 554 tls = talloc(new_sock, struct tls_context);555 if (tls == NULL) return NULL;556 557 tls->socket = socket_ctx;558 talloc_steal(tls, socket_ctx);559 tls->fde = fde;560 561 new_sock->private_data = tls;562 563 gnutls_global_init();564 565 gnutls_certificate_allocate_credentials(&tls->xcred);566 gnutls_certificate_set_x509_trust_file(tls->xcred, ca_path, GNUTLS_X509_FMT_PEM);567 TLSCHECK(gnutls_init(&tls->session, GNUTLS_CLIENT));568 TLSCHECK(gnutls_set_default_priority(tls->session));569 gnutls_certificate_type_set_priority(tls->session, cert_type_priority);570 TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, tls->xcred));571 572 talloc_set_destructor(tls, tls_destructor);573 574 gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls);575 gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull);576 gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push);577 gnutls_transport_set_lowat(tls->session, 0);578 tls->tls_detect = false;579 580 tls->output_pending = false;581 tls->done_handshake = false;582 tls->have_first_byte = false;583 tls->tls_enabled = true;584 tls->interrupted = false;585 586 new_sock->state = SOCKET_STATE_CLIENT_CONNECTED;587 588 return new_sock;589 590 failed:591 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret)));592 tls->tls_enabled = false;593 return new_sock;594 }595 578 596 579 static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val) … … 639 622 }; 640 623 641 bool tls_support(struct tls_params *params)642 {643 return params->tls_enabled;644 }645 646 624 #else 647 625 … … 657 635 setup for a new connection 658 636 */ 659 struct socket_context *tls_init_server(struct tls_params *params, 637 struct socket_context *tls_init_server(struct tls_params *params, 660 638 struct socket_context *socket, 661 struct tevent_fd *fde, 639 struct tevent_fd *fde, 662 640 const char *plain_chars) 663 641 { … … 666 644 667 645 668 /*669 setup for a new client connection670 */671 struct socket_context *tls_init_client(struct socket_context *socket,672 struct tevent_fd *fde,673 const char *ca_path)674 {675 return NULL;676 }677 678 bool tls_support(struct tls_params *params)679 {680 return false;681 }682 683 646 #endif 684 647 -
vendor/current/source4/lib/tls/tls.h
r740 r988 46 46 const char *plain_chars); 47 47 48 /* 49 call tls_init_client() on each new client connection 50 */ 51 struct socket_context *tls_init_client(struct socket_context *sock, 52 struct tevent_fd *fde, 53 const char *cafile); 48 void tls_cert_generate(TALLOC_CTX *mem_ctx, 49 const char *hostname, 50 const char *keyfile, const char *certfile, 51 const char *cafile); 54 52 55 53 /* … … 59 57 60 58 61 /*62 true if tls support is compiled in63 */64 bool tls_support(struct tls_params *parms);65 66 59 const struct socket_ops *socket_tls_ops(enum socket_type type); 67 60 … … 69 62 struct tstream_tls_params; 70 63 64 enum tls_verify_peer_state { 65 TLS_VERIFY_PEER_NO_CHECK = 0, 66 #define TLS_VERIFY_PEER_NO_CHECK_STRING "no_check" 67 68 TLS_VERIFY_PEER_CA_ONLY = 10, 69 #define TLS_VERIFY_PEER_CA_ONLY_STRING "ca_only" 70 71 TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE = 20, 72 #define TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING \ 73 "ca_and_name_if_available" 74 75 TLS_VERIFY_PEER_CA_AND_NAME = 30, 76 #define TLS_VERIFY_PEER_CA_AND_NAME_STRING "ca_and_name" 77 78 TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE = 9999, 79 #define TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING \ 80 "as_strict_as_possible" 81 }; 82 83 const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer); 84 71 85 NTSTATUS tstream_tls_params_client(TALLOC_CTX *mem_ctx, 72 86 const char *ca_file, 73 87 const char *crl_file, 88 const char *tls_priority, 89 enum tls_verify_peer_state verify_peer, 90 const char *peer_name, 74 91 struct tstream_tls_params **_tlsp); 75 92 … … 82 99 const char *crl_file, 83 100 const char *dhp_file, 101 const char *tls_priority, 84 102 struct tstream_tls_params **_params); 85 103 … … 91 109 struct tstream_tls_params *tls_params, 92 110 const char *location); 93 #define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params) ;\111 #define tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params) \ 94 112 _tstream_tls_connect_send(mem_ctx, ev, plain_stream, tls_params, __location__) 95 113 -
vendor/current/source4/lib/tls/tls_tstream.c
r740 r988 20 20 #include "includes.h" 21 21 #include "system/network.h" 22 #include "system/filesys.h" 23 #include "system/time.h" 22 24 #include "../util/tevent_unix.h" 23 25 #include "../lib/tsocket/tsocket.h" 24 26 #include "../lib/tsocket/tsocket_internal.h" 27 #include "../lib/util/util_net.h" 25 28 #include "lib/tls/tls.h" 26 29 27 30 #if ENABLE_GNUTLS 28 #include "gnutls/gnutls.h" 29 30 #define DH_BITS 1024 31 #include <gnutls/gnutls.h> 32 #include <gnutls/x509.h> 33 34 #define DH_BITS 2048 31 35 32 36 #if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T) … … 34 38 #endif 35 39 40 /* 41 * define our own values in a high range 42 */ 43 #ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED 44 #define GNUTLS_CERT_EXPIRED 0x10000000 45 #define REQUIRE_CERT_TIME_CHECKS 1 46 #endif 47 #ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED 48 #define GNUTLS_CERT_NOT_ACTIVATED 0x20000000 49 #ifndef REQUIRE_CERT_TIME_CHECKS 50 #define REQUIRE_CERT_TIME_CHECKS 1 51 #endif 52 #endif 53 #ifndef HAVE_DECL_GNUTLS_CERT_UNEXPECTED_OWNER 54 #define GNUTLS_CERT_UNEXPECTED_OWNER 0x40000000 55 #endif 56 36 57 #endif /* ENABLE_GNUTLS */ 58 59 const char *tls_verify_peer_string(enum tls_verify_peer_state verify_peer) 60 { 61 switch (verify_peer) { 62 case TLS_VERIFY_PEER_NO_CHECK: 63 return TLS_VERIFY_PEER_NO_CHECK_STRING; 64 65 case TLS_VERIFY_PEER_CA_ONLY: 66 return TLS_VERIFY_PEER_CA_ONLY_STRING; 67 68 case TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE: 69 return TLS_VERIFY_PEER_CA_AND_NAME_IF_AVAILABLE_STRING; 70 71 case TLS_VERIFY_PEER_CA_AND_NAME: 72 return TLS_VERIFY_PEER_CA_AND_NAME_STRING; 73 74 case TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE: 75 return TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE_STRING; 76 } 77 78 return "unknown tls_verify_peer_state"; 79 } 37 80 38 81 static const struct tstream_context_ops tstream_tls_ops; … … 45 88 gnutls_session tls_session; 46 89 #endif /* ENABLE_GNUTLS */ 90 91 enum tls_verify_peer_state verify_peer; 92 const char *peer_name; 47 93 48 94 struct tevent_context *current_ev; … … 868 914 gnutls_certificate_credentials x509_cred; 869 915 gnutls_dh_params dh_params; 916 const char *tls_priority; 870 917 #endif /* ENABLE_GNUTLS */ 871 918 bool tls_enabled; 919 enum tls_verify_peer_state verify_peer; 920 const char *peer_name; 872 921 }; 873 922 … … 895 944 const char *ca_file, 896 945 const char *crl_file, 946 const char *tls_priority, 947 enum tls_verify_peer_state verify_peer, 948 const char *peer_name, 897 949 struct tstream_tls_params **_tlsp) 898 950 { … … 911 963 912 964 talloc_set_destructor(tlsp, tstream_tls_params_destructor); 965 966 tlsp->verify_peer = verify_peer; 967 if (peer_name != NULL) { 968 tlsp->peer_name = talloc_strdup(tlsp, peer_name); 969 if (tlsp->peer_name == NULL) { 970 talloc_free(tlsp); 971 return NT_STATUS_NO_MEMORY; 972 } 973 } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { 974 DEBUG(0,("TLS failed to missing peer_name - " 975 "with 'tls verify peer = %s'\n", 976 tls_verify_peer_string(tlsp->verify_peer))); 977 talloc_free(tlsp); 978 return NT_STATUS_INVALID_PARAMETER_MIX; 979 } 913 980 914 981 ret = gnutls_certificate_allocate_credentials(&tlsp->x509_cred); … … 919 986 } 920 987 921 if (ca_file && *ca_file ) {988 if (ca_file && *ca_file && file_exist(ca_file)) { 922 989 ret = gnutls_certificate_set_x509_trust_file(tlsp->x509_cred, 923 990 ca_file, … … 929 996 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 930 997 } 931 } 932 933 if (crl_file && *crl_file) { 998 } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { 999 DEBUG(0,("TLS failed to missing cafile %s - " 1000 "with 'tls verify peer = %s'\n", 1001 ca_file, 1002 tls_verify_peer_string(tlsp->verify_peer))); 1003 talloc_free(tlsp); 1004 return NT_STATUS_INVALID_PARAMETER_MIX; 1005 } 1006 1007 if (crl_file && *crl_file && file_exist(crl_file)) { 934 1008 ret = gnutls_certificate_set_x509_crl_file(tlsp->x509_cred, 935 1009 crl_file, … … 941 1015 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 942 1016 } 1017 } else if (tlsp->verify_peer >= TLS_VERIFY_PEER_AS_STRICT_AS_POSSIBLE) { 1018 DEBUG(0,("TLS failed to missing crlfile %s - " 1019 "with 'tls verify peer = %s'\n", 1020 crl_file, 1021 tls_verify_peer_string(tlsp->verify_peer))); 1022 talloc_free(tlsp); 1023 return NT_STATUS_INVALID_PARAMETER_MIX; 1024 } 1025 1026 tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); 1027 if (tlsp->tls_priority == NULL) { 1028 talloc_free(tlsp); 1029 return NT_STATUS_NO_MEMORY; 943 1030 } 944 1031 … … 964 1051 struct tevent_req *req; 965 1052 struct tstream_tls_connect_state *state; 1053 const char *error_pos; 966 1054 #if ENABLE_GNUTLS 967 1055 struct tstream_tls *tlss; 968 1056 int ret; 969 static const int cert_type_priority[] = {970 GNUTLS_CRT_X509,971 GNUTLS_CRT_OPENPGP,972 0973 };974 1057 #endif /* ENABLE_GNUTLS */ 975 1058 … … 993 1076 994 1077 tlss->plain_stream = plain_stream; 1078 tlss->verify_peer = tls_params->verify_peer; 1079 if (tls_params->peer_name != NULL) { 1080 tlss->peer_name = talloc_strdup(tlss, tls_params->peer_name); 1081 if (tevent_req_nomem(tlss->peer_name, req)) { 1082 return tevent_req_post(req, ev); 1083 } 1084 } 995 1085 996 1086 tlss->current_ev = ev; … … 1007 1097 } 1008 1098 1009 ret = gnutls_set_default_priority(tlss->tls_session); 1099 ret = gnutls_priority_set_direct(tlss->tls_session, 1100 tls_params->tls_priority, 1101 &error_pos); 1010 1102 if (ret != GNUTLS_E_SUCCESS) { 1011 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); 1103 DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", 1104 __location__, gnutls_strerror(ret), error_pos)); 1012 1105 tevent_req_error(req, EINVAL); 1013 1106 return tevent_req_post(req, ev); 1014 1107 } 1015 1016 gnutls_certificate_type_set_priority(tlss->tls_session, cert_type_priority);1017 1108 1018 1109 ret = gnutls_credentials_set(tlss->tls_session, … … 1030 1121 gnutls_transport_set_push_function(tlss->tls_session, 1031 1122 (gnutls_push_func)tstream_tls_push_function); 1123 #if GNUTLS_VERSION_MAJOR < 3 1032 1124 gnutls_transport_set_lowat(tlss->tls_session, 0); 1125 #endif 1033 1126 1034 1127 tlss->handshake.req = req; … … 1063 1156 return 0; 1064 1157 } 1065 1066 extern void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *);1067 1158 1068 1159 /* … … 1077 1168 const char *crl_file, 1078 1169 const char *dhp_file, 1170 const char *tls_priority, 1079 1171 struct tstream_tls_params **_tlsp) 1080 1172 { … … 1082 1174 #if ENABLE_GNUTLS 1083 1175 int ret; 1176 struct stat st; 1084 1177 1085 1178 if (!enabled || key_file == NULL || *key_file == 0) { … … 1107 1200 tls_cert_generate(tlsp, dns_host_name, 1108 1201 key_file, cert_file, ca_file); 1202 } 1203 1204 if (file_exist(key_file) && 1205 !file_check_permissions(key_file, geteuid(), 0600, &st)) 1206 { 1207 DEBUG(0, ("Invalid permissions on TLS private key file '%s':\n" 1208 "owner uid %u should be %u, mode 0%o should be 0%o\n" 1209 "This is known as CVE-2013-4476.\n" 1210 "Removing all tls .pem files will cause an " 1211 "auto-regeneration with the correct permissions.\n", 1212 key_file, 1213 (unsigned int)st.st_uid, geteuid(), 1214 (unsigned int)(st.st_mode & 0777), 0600)); 1215 return NT_STATUS_CANT_ACCESS_DOMAIN_INFO; 1109 1216 } 1110 1217 … … 1192 1299 gnutls_certificate_set_dh_params(tlsp->x509_cred, tlsp->dh_params); 1193 1300 1301 tlsp->tls_priority = talloc_strdup(tlsp, tls_priority); 1302 if (tlsp->tls_priority == NULL) { 1303 talloc_free(tlsp); 1304 return NT_STATUS_NO_MEMORY; 1305 } 1306 1194 1307 tlsp->tls_enabled = true; 1195 1308 … … 1218 1331 struct tstream_tls_accept_state *state; 1219 1332 struct tstream_tls *tlss; 1333 const char *error_pos; 1220 1334 #if ENABLE_GNUTLS 1221 1335 int ret; … … 1255 1369 } 1256 1370 1257 ret = gnutls_set_default_priority(tlss->tls_session); 1371 ret = gnutls_priority_set_direct(tlss->tls_session, 1372 tlsp->tls_priority, 1373 &error_pos); 1258 1374 if (ret != GNUTLS_E_SUCCESS) { 1259 DEBUG(0,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); 1375 DEBUG(0,("TLS %s - %s. Check 'tls priority' option at '%s'\n", 1376 __location__, gnutls_strerror(ret), error_pos)); 1260 1377 tevent_req_error(req, EINVAL); 1261 1378 return tevent_req_post(req, ev); … … 1279 1396 gnutls_transport_set_push_function(tlss->tls_session, 1280 1397 (gnutls_push_func)tstream_tls_push_function); 1398 #if GNUTLS_VERSION_MAJOR < 3 1281 1399 gnutls_transport_set_lowat(tlss->tls_session, 0); 1400 #endif 1282 1401 1283 1402 tlss->handshake.req = req; … … 1329 1448 } 1330 1449 1450 if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_ONLY) { 1451 unsigned int status = UINT32_MAX; 1452 bool ip = true; 1453 const char *hostname = NULL; 1454 #ifndef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 1455 bool need_crt_checks = false; 1456 #endif 1457 1458 if (tlss->peer_name != NULL) { 1459 ip = is_ipaddress(tlss->peer_name); 1460 } 1461 1462 if (!ip) { 1463 hostname = tlss->peer_name; 1464 } 1465 1466 if (tlss->verify_peer == TLS_VERIFY_PEER_CA_ONLY) { 1467 hostname = NULL; 1468 } 1469 1470 if (tlss->verify_peer >= TLS_VERIFY_PEER_CA_AND_NAME) { 1471 if (hostname == NULL) { 1472 DEBUG(1,("TLS %s - no hostname available for " 1473 "verify_peer[%s] and peer_name[%s]\n", 1474 __location__, 1475 tls_verify_peer_string(tlss->verify_peer), 1476 tlss->peer_name)); 1477 tlss->error = EINVAL; 1478 tevent_req_error(req, tlss->error); 1479 return; 1480 } 1481 } 1482 1483 #ifdef HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 1484 ret = gnutls_certificate_verify_peers3(tlss->tls_session, 1485 hostname, 1486 &status); 1487 if (ret != GNUTLS_E_SUCCESS) { 1488 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); 1489 tlss->error = EIO; 1490 tevent_req_error(req, tlss->error); 1491 return; 1492 } 1493 #else /* not HAVE_GNUTLS_CERTIFICATE_VERIFY_PEERS3 */ 1494 ret = gnutls_certificate_verify_peers2(tlss->tls_session, &status); 1495 if (ret != GNUTLS_E_SUCCESS) { 1496 DEBUG(1,("TLS %s - %s\n", __location__, gnutls_strerror(ret))); 1497 tlss->error = EIO; 1498 tevent_req_error(req, tlss->error); 1499 return; 1500 } 1501 1502 if (status == 0) { 1503 if (hostname != NULL) { 1504 need_crt_checks = true; 1505 } 1506 #ifdef REQUIRE_CERT_TIME_CHECKS 1507 need_crt_checks = true; 1508 #endif 1509 } 1510 1511 if (need_crt_checks) { 1512 gnutls_x509_crt crt; 1513 const gnutls_datum *cert_list; 1514 unsigned int cert_list_size = 0; 1515 #ifdef REQUIRE_CERT_TIME_CHECKS 1516 time_t now = time(NULL); 1517 time_t tret = -1; 1518 #endif 1519 1520 cert_list = gnutls_certificate_get_peers(tlss->tls_session, 1521 &cert_list_size); 1522 if (cert_list == NULL) { 1523 cert_list_size = 0; 1524 } 1525 if (cert_list_size == 0) { 1526 DEBUG(1,("TLS %s - cert_list_size == 0\n", 1527 __location__)); 1528 tlss->error = EIO; 1529 tevent_req_error(req, tlss->error); 1530 return; 1531 } 1532 1533 ret = gnutls_x509_crt_init(&crt); 1534 if (ret != GNUTLS_E_SUCCESS) { 1535 DEBUG(1,("TLS %s - %s\n", __location__, 1536 gnutls_strerror(ret))); 1537 tlss->error = EIO; 1538 tevent_req_error(req, tlss->error); 1539 return; 1540 } 1541 ret = gnutls_x509_crt_import(crt, 1542 &cert_list[0], 1543 GNUTLS_X509_FMT_DER); 1544 if (ret != GNUTLS_E_SUCCESS) { 1545 DEBUG(1,("TLS %s - %s\n", __location__, 1546 gnutls_strerror(ret))); 1547 gnutls_x509_crt_deinit(crt); 1548 tlss->error = EIO; 1549 tevent_req_error(req, tlss->error); 1550 return; 1551 } 1552 1553 if (hostname != NULL) { 1554 ret = gnutls_x509_crt_check_hostname(crt, 1555 hostname); 1556 if (ret == 0) { 1557 status |= GNUTLS_CERT_INVALID; 1558 status |= GNUTLS_CERT_UNEXPECTED_OWNER; 1559 } 1560 } 1561 1562 #ifndef HAVE_DECL_GNUTLS_CERT_NOT_ACTIVATED 1563 /* 1564 * GNUTLS_CERT_NOT_ACTIVATED is defined by ourself 1565 */ 1566 tret = gnutls_x509_crt_get_activation_time(crt); 1567 if ((tret == -1) || (now > tret)) { 1568 status |= GNUTLS_CERT_INVALID; 1569 status |= GNUTLS_CERT_NOT_ACTIVATED; 1570 } 1571 #endif 1572 #ifndef HAVE_DECL_GNUTLS_CERT_EXPIRED 1573 /* 1574 * GNUTLS_CERT_EXPIRED is defined by ourself 1575 */ 1576 tret = gnutls_certificate_expiration_time_peers(tlss->tls_session); 1577 if ((tret == -1) || (now > tret)) { 1578 status |= GNUTLS_CERT_INVALID; 1579 status |= GNUTLS_CERT_EXPIRED; 1580 } 1581 #endif 1582 gnutls_x509_crt_deinit(crt); 1583 } 1584 #endif 1585 1586 if (status != 0) { 1587 DEBUG(1,("TLS %s - check failed for " 1588 "verify_peer[%s] and peer_name[%s] " 1589 "status 0x%x (%s%s%s%s%s%s%s%s)\n", 1590 __location__, 1591 tls_verify_peer_string(tlss->verify_peer), 1592 tlss->peer_name, 1593 status, 1594 status & GNUTLS_CERT_INVALID ? "invalid " : "", 1595 status & GNUTLS_CERT_REVOKED ? "revoked " : "", 1596 status & GNUTLS_CERT_SIGNER_NOT_FOUND ? 1597 "signer_not_found " : "", 1598 status & GNUTLS_CERT_SIGNER_NOT_CA ? 1599 "signer_not_ca " : "", 1600 status & GNUTLS_CERT_INSECURE_ALGORITHM ? 1601 "insecure_algorithm " : "", 1602 status & GNUTLS_CERT_NOT_ACTIVATED ? 1603 "not_activated " : "", 1604 status & GNUTLS_CERT_EXPIRED ? 1605 "expired " : "", 1606 status & GNUTLS_CERT_UNEXPECTED_OWNER ? 1607 "unexptected_owner " : "")); 1608 tlss->error = EINVAL; 1609 tevent_req_error(req, tlss->error); 1610 return; 1611 } 1612 } 1613 1331 1614 tevent_req_done(req); 1332 1615 #else /* ENABLE_GNUTLS */ -
vendor/current/source4/lib/tls/tlscert.c
r740 r988 21 21 22 22 #include "includes.h" 23 #include "lib/tls/tls.h" 23 24 24 25 #if ENABLE_GNUTLS 25 #include "gnutls/gnutls.h"26 #include "gnutls/x509.h"27 #if HAVE_GCRYPT_H26 #include <gnutls/gnutls.h> 27 #include <gnutls/x509.h> 28 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3) 28 29 #include <gcrypt.h> 29 30 #endif 30 31 31 32 #define ORGANISATION_NAME "Samba Administration" 32 #define UNIT_NAME "Samba - temporary autogenerated certificate" 33 #define CA_NAME "Samba - temporary autogenerated CA certificate" 34 #define UNIT_NAME "Samba - temporary autogenerated HOST certificate" 33 35 #define LIFETIME 700*24*60*60 34 #define DH_BITS 102436 #define RSA_BITS 4096 35 37 36 38 /* … … 70 72 hostname)); 71 73 72 #if def HAVE_GCRYPT_H74 #if defined(HAVE_GCRYPT_H) && !defined(HAVE_GNUTLS3) 73 75 DEBUG(3,("Enabling QUICK mode in gcrypt\n")); 74 76 gcry_control(GCRYCTL_ENABLE_QUICK_RANDOM, 0); … … 77 79 DEBUG(3,("Generating private key\n")); 78 80 TLSCHECK(gnutls_x509_privkey_init(&key)); 79 TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, DH_BITS, 0));81 TLSCHECK(gnutls_x509_privkey_generate(key, GNUTLS_PK_RSA, RSA_BITS, 0)); 80 82 81 83 DEBUG(3,("Generating CA private key\n")); 82 84 TLSCHECK(gnutls_x509_privkey_init(&cakey)); 83 TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, DH_BITS, 0));85 TLSCHECK(gnutls_x509_privkey_generate(cakey, GNUTLS_PK_RSA, RSA_BITS, 0)); 84 86 85 87 DEBUG(3,("Generating CA certificate\n")); … … 90 92 TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 91 93 GNUTLS_OID_X520_ORGANIZATIONAL_UNIT_NAME, 0, 92 UNIT_NAME, strlen(UNIT_NAME)));94 CA_NAME, strlen(CA_NAME))); 93 95 TLSCHECK(gnutls_x509_crt_set_dn_by_oid(cacrt, 94 96 GNUTLS_OID_X520_COMMON_NAME, 0, … … 98 100 TLSCHECK(gnutls_x509_crt_set_activation_time(cacrt, activation)); 99 101 TLSCHECK(gnutls_x509_crt_set_expiration_time(cacrt, expiry)); 100 TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 0)); 101 #ifdef GNUTLS_KP_TLS_WWW_SERVER 102 TLSCHECK(gnutls_x509_crt_set_key_purpose_oid(cacrt, GNUTLS_KP_TLS_WWW_SERVER, 0)); 103 #endif 102 TLSCHECK(gnutls_x509_crt_set_ca_status(cacrt, 1)); 103 TLSCHECK(gnutls_x509_crt_set_key_usage(cacrt, GNUTLS_KEY_KEY_CERT_SIGN | GNUTLS_KEY_CRL_SIGN)); 104 104 TLSCHECK(gnutls_x509_crt_set_version(cacrt, 3)); 105 105 TLSCHECK(gnutls_x509_crt_get_key_id(cacrt, 0, keyid, &keyidsize)); … … 134 134 #endif 135 135 TLSCHECK(gnutls_x509_crt_sign(crt, crt, key)); 136 TLSCHECK(gnutls_x509_crt_sign(crt, cacrt, cakey)); 136 137 137 138 DEBUG(3,("Exporting TLS keys\n")); … … 153 154 bufsize = sizeof(buf); 154 155 TLSCHECK(gnutls_x509_privkey_export(key, GNUTLS_X509_FMT_PEM, buf, &bufsize)); 155 if (!file_save (keyfile, buf, bufsize)) {156 if (!file_save_mode(keyfile, buf, bufsize, 0600)) { 156 157 DEBUG(0,("Unable to save privatekey in %s parent dir exists ?\n", keyfile)); 157 158 goto failed; -
vendor/current/source4/lib/tls/wscript
r740 r988 18 18 conf.SET_TARGET_TYPE('gcrypt', 'DISABLED') 19 19 conf.SET_TARGET_TYPE('gpg-error', 'DISABLED') 20 if 'AD_DC_BUILD_IS_ENABLED' in conf.env: 21 conf.fatal("--disable-gnutls given: Building the AD DC requires GnuTLS (eg libgnutls-dev, gnutls-devel) for ldaps:// support and for the BackupKey protocol") 20 22 return 21 23 22 conf.check_cfg(package='gnutls', 23 args='"gnutls >= 1.4.0 gnutls != 2.2.4 gnutls != 2.8.0 gnutls != 2.8.1" --cflags --libs', 24 msg='Checking for gnutls >= 1.4.0 and broken versions', mandatory=False) 24 if Options.options.with_system_mitkrb5 and conf.env.AD_DC_BUILD_IS_ENABLED: 25 conf.CHECK_CFG(package='gnutls', 26 args='"gnutls >= 3.4.7" --cflags --libs', 27 msg='Checking for gnutls >= 3.4.7', 28 mandatory=True) 29 conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) 30 conf.DEFINE('HAVE_GNUTLS3', 1) 31 else: 32 if conf.CHECK_CFG(package='gnutls', 33 args='"gnutls >= 3.4.7" --cflags --libs', 34 msg='Checking for gnutls >= 3.4.7', 35 mandatory=False): 36 conf.DEFINE('HAVE_GNUTLS_3_4_7', 1) 37 conf.DEFINE('HAVE_GNUTLS3', 1) 38 elif conf.CHECK_CFG(package='gnutls', 39 args='"gnutls >= 3.0.0" --cflags --libs', 40 msg='Checking for gnutls >= 3.0.0s', mandatory=False): 41 conf.DEFINE('HAVE_GNUTLS3', 1) 42 else: 43 conf.CHECK_CFG(package='gnutls', 44 args='"gnutls >= 1.4.0 gnutls != 2.2.4 gnutls != 2.8.0 gnutls != 2.8.1" --cflags --libs', 45 msg='Checking for gnutls >= 1.4.0 and broken versions', mandatory=False) 25 46 26 47 if 'HAVE_GNUTLS' in conf.env: 27 48 conf.DEFINE('ENABLE_GNUTLS', 1) 49 else: 50 if 'AD_DC_BUILD_IS_ENABLED' in conf.env: 51 conf.fatal("Building the AD DC requires GnuTLS (eg libgnutls-dev, gnutls-devel) for ldaps:// support and for the BackupKey protocol") 28 52 29 53 conf.CHECK_FUNCS_IN('gnutls_global_init', 'gnutls', 30 54 headers='gnutls/gnutls.h') 55 56 conf.CHECK_FUNCS_IN('gnutls_certificate_verify_peers3', 'gnutls', 57 headers='gnutls/gnutls.h') 58 conf.CHECK_DECLS('GNUTLS_CERT_EXPIRED GNUTLS_CERT_NOT_ACTIVATED GNUTLS_CERT_UNEXPECTED_OWNER', 59 headers='gnutls/gnutls.h gnutls/x509.h') 31 60 32 61 conf.CHECK_VARIABLE('gnutls_x509_crt_set_version', … … 43 72 headers='gnutls/gnutls.h', lib='gnutls') 44 73 45 conf.CHECK_FUNCS_IN('gcry_control', 'gcrypt', headers='gcrypt.h') 46 conf.CHECK_FUNCS_IN('gpg_err_code_from_errno', 'gpg-error') 74 # GnuTLS3 moved to libnettle, so only do this in the < 3.0 case 75 if not 'HAVE_GNUTLS3' in conf.env: 76 conf.CHECK_FUNCS_IN('gcry_control', 'gcrypt', headers='gcrypt.h') 77 conf.CHECK_FUNCS_IN('gpg_err_code_from_errno', 'gpg-error') 78 else: 79 conf.SET_TARGET_TYPE('gcrypt', 'DISABLED') 80 conf.SET_TARGET_TYPE('gpg-error', 'DISABLED') 47 81 48 82 … … 50 84 bld.SAMBA_SUBSYSTEM('LIBTLS', 51 85 source='tls.c tlscert.c tls_tstream.c', 52 public_deps='talloc gnutls gcrypt samba-hostconfig samba_socket LIBTSOCKET tevent UTIL_TEVENT'86 public_deps='talloc gnutls gcrypt samba-hostconfig samba_socket LIBTSOCKET tevent tevent-util' 53 87 )
Note:
See TracChangeset
for help on using the changeset viewer.