1/* 2 Unix SMB/CIFS implementation. 3 4 transport layer security handling code 5 6 Copyright (C) Andrew Tridgell 2004-2005 7 Copyright (C) Stefan Metzmacher 2004 8 Copyright (C) Andrew Bartlett 2006 9 10 This program is free software; you can redistribute it and/or modify 11 it under the terms of the GNU General Public License as published by 12 the Free Software Foundation; either version 3 of the License, or 13 (at your option) any later version. 14 15 This program is distributed in the hope that it will be useful, 16 but WITHOUT ANY WARRANTY; without even the implied warranty of 17 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the 18 GNU General Public License for more details. 19 20 You should have received a copy of the GNU General Public License 21 along with this program. If not, see <http://www.gnu.org/licenses/>. 22*/ 23 24#include "includes.h" 25#include "lib/events/events.h" 26#include "lib/socket/socket.h" 27#include "lib/tls/tls.h" 28#include "param/param.h" 29 30#if ENABLE_GNUTLS 31#include "gnutls/gnutls.h" 32 33#define DH_BITS 1024 34 35#if defined(HAVE_GNUTLS_DATUM) && !defined(HAVE_GNUTLS_DATUM_T) 36typedef gnutls_datum gnutls_datum_t; 37#endif 38 39/* hold persistent tls data */ 40struct tls_params { 41 gnutls_certificate_credentials x509_cred; 42 gnutls_dh_params dh_params; 43 bool tls_enabled; 44}; 45#endif 46 47/* hold per connection tls data */ 48struct tls_context { 49 struct socket_context *socket; 50 struct tevent_fd *fde; 51 bool tls_enabled; 52#if ENABLE_GNUTLS 53 gnutls_session session; 54 bool done_handshake; 55 bool have_first_byte; 56 uint8_t first_byte; 57 bool tls_detect; 58 const char *plain_chars; 59 bool output_pending; 60 gnutls_certificate_credentials xcred; 61 bool interrupted; 62#endif 63}; 64 65bool tls_enabled(struct socket_context *sock) 66{ 67 struct tls_context *tls; 68 if (!sock) { 69 return false; 70 } 71 if (strcmp(sock->backend_name, "tls") != 0) { 72 return false; 73 } 74 tls = talloc_get_type(sock->private_data, struct tls_context); 75 if (!tls) { 76 return false; 77 } 78 return tls->tls_enabled; 79} 80 81 82#if ENABLE_GNUTLS 83 84static const struct socket_ops tls_socket_ops; 85 86static NTSTATUS tls_socket_init(struct socket_context *sock) 87{ 88 switch (sock->type) { 89 case SOCKET_TYPE_STREAM: 90 break; 91 default: 92 return NT_STATUS_INVALID_PARAMETER; 93 } 94 95 sock->backend_name = "tls"; 96 97 return NT_STATUS_OK; 98} 99 100#define TLSCHECK(call) do { \ 101 ret = call; \ 102 if (ret < 0) { \ 103 DEBUG(0,("TLS %s - %s\n", #call, gnutls_strerror(ret))); \ 104 goto failed; \ 105 } \ 106} while (0) 107 108 109/* 110 callback for reading from a socket 111*/ 112static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) 113{ 114 struct tls_context *tls = talloc_get_type(ptr, struct tls_context); 115 NTSTATUS status; 116 size_t nread; 117 118 if (tls->have_first_byte) { 119 *(uint8_t *)buf = tls->first_byte; 120 tls->have_first_byte = false; 121 return 1; 122 } 123 124 status = socket_recv(tls->socket, buf, size, &nread); 125 if (NT_STATUS_EQUAL(status, NT_STATUS_END_OF_FILE)) { 126 return 0; 127 } 128 if (NT_STATUS_IS_ERR(status)) { 129 EVENT_FD_NOT_READABLE(tls->fde); 130 EVENT_FD_NOT_WRITEABLE(tls->fde); 131 errno = EBADF; 132 return -1; 133 } 134 if (!NT_STATUS_IS_OK(status)) { 135 EVENT_FD_READABLE(tls->fde); 136 errno = EAGAIN; 137 return -1; 138 } 139 if (tls->output_pending) { 140 EVENT_FD_WRITEABLE(tls->fde); 141 } 142 if (size != nread) { 143 EVENT_FD_READABLE(tls->fde); 144 } 145 return nread; 146} 147 148/* 149 callback for writing to a socket 150*/ 151static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) 152{ 153 struct tls_context *tls = talloc_get_type(ptr, struct tls_context); 154 NTSTATUS status; 155 size_t nwritten; 156 DATA_BLOB b; 157 158 if (!tls->tls_enabled) { 159 return size; 160 } 161 162 b.data = discard_const(buf); 163 b.length = size; 164 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; 178} 179 180/* 181 destroy a tls session 182 */ 183static int tls_destructor(struct tls_context *tls) 184{ 185 int ret; 186 ret = gnutls_bye(tls->session, GNUTLS_SHUT_WR); 187 if (ret < 0) { 188 DEBUG(4,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret))); 189 } 190 return 0; 191} 192 193 194/* 195 possibly continue the handshake process 196*/ 197static NTSTATUS tls_handshake(struct tls_context *tls) 198{ 199 int ret; 200 201 if (tls->done_handshake) { 202 return NT_STATUS_OK; 203 } 204 205 ret = gnutls_handshake(tls->session); 206 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 207 if (gnutls_record_get_direction(tls->session) == 1) { 208 EVENT_FD_WRITEABLE(tls->fde); 209 } 210 return STATUS_MORE_ENTRIES; 211 } 212 if (ret < 0) { 213 DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret))); 214 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 215 } 216 tls->done_handshake = true; 217 return NT_STATUS_OK; 218} 219 220/* 221 possibly continue an interrupted operation 222*/ 223static NTSTATUS tls_interrupted(struct tls_context *tls) 224{ 225 int ret; 226 227 if (!tls->interrupted) { 228 return NT_STATUS_OK; 229 } 230 if (gnutls_record_get_direction(tls->session) == 1) { 231 ret = gnutls_record_send(tls->session, NULL, 0); 232 } else { 233 ret = gnutls_record_recv(tls->session, NULL, 0); 234 } 235 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 236 return STATUS_MORE_ENTRIES; 237 } 238 tls->interrupted = false; 239 return NT_STATUS_OK; 240} 241 242/* 243 see how many bytes are pending on the connection 244*/ 245static NTSTATUS tls_socket_pending(struct socket_context *sock, size_t *npending) 246{ 247 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 248 if (!tls->tls_enabled || tls->tls_detect) { 249 return socket_pending(tls->socket, npending); 250 } 251 *npending = gnutls_record_check_pending(tls->session); 252 if (*npending == 0) { 253 NTSTATUS status = socket_pending(tls->socket, npending); 254 if (*npending == 0) { 255 /* seems to be a gnutls bug */ 256 (*npending) = 100; 257 } 258 return status; 259 } 260 return NT_STATUS_OK; 261} 262 263/* 264 receive data either by tls or normal socket_recv 265*/ 266static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, 267 size_t wantlen, size_t *nread) 268{ 269 int ret; 270 NTSTATUS status; 271 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 272 273 if (tls->tls_enabled && tls->tls_detect) { 274 status = socket_recv(tls->socket, &tls->first_byte, 1, nread); 275 NT_STATUS_NOT_OK_RETURN(status); 276 if (*nread == 0) return NT_STATUS_OK; 277 tls->tls_detect = false; 278 /* look for the first byte of a valid HTTP operation */ 279 if (strchr(tls->plain_chars, tls->first_byte)) { 280 /* not a tls link */ 281 tls->tls_enabled = false; 282 *(uint8_t *)buf = tls->first_byte; 283 return NT_STATUS_OK; 284 } 285 tls->have_first_byte = true; 286 } 287 288 if (!tls->tls_enabled) { 289 return socket_recv(tls->socket, buf, wantlen, nread); 290 } 291 292 status = tls_handshake(tls); 293 NT_STATUS_NOT_OK_RETURN(status); 294 295 status = tls_interrupted(tls); 296 NT_STATUS_NOT_OK_RETURN(status); 297 298 ret = gnutls_record_recv(tls->session, buf, wantlen); 299 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 300 if (gnutls_record_get_direction(tls->session) == 1) { 301 EVENT_FD_WRITEABLE(tls->fde); 302 } 303 tls->interrupted = true; 304 return STATUS_MORE_ENTRIES; 305 } 306 if (ret < 0) { 307 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 308 } 309 *nread = ret; 310 return NT_STATUS_OK; 311} 312 313 314/* 315 send data either by tls or normal socket_recv 316*/ 317static NTSTATUS tls_socket_send(struct socket_context *sock, 318 const DATA_BLOB *blob, size_t *sendlen) 319{ 320 NTSTATUS status; 321 int ret; 322 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 323 324 if (!tls->tls_enabled) { 325 return socket_send(tls->socket, blob, sendlen); 326 } 327 328 status = tls_handshake(tls); 329 NT_STATUS_NOT_OK_RETURN(status); 330 331 status = tls_interrupted(tls); 332 NT_STATUS_NOT_OK_RETURN(status); 333 334 ret = gnutls_record_send(tls->session, blob->data, blob->length); 335 if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { 336 if (gnutls_record_get_direction(tls->session) == 1) { 337 EVENT_FD_WRITEABLE(tls->fde); 338 } 339 tls->interrupted = true; 340 return STATUS_MORE_ENTRIES; 341 } 342 if (ret < 0) { 343 DEBUG(0,("gnutls_record_send of %d failed - %s\n", (int)blob->length, gnutls_strerror(ret))); 344 return NT_STATUS_UNEXPECTED_NETWORK_ERROR; 345 } 346 *sendlen = ret; 347 tls->output_pending = (ret < blob->length); 348 return NT_STATUS_OK; 349} 350 351 352/* 353 initialise global tls state 354*/ 355struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 356{ 357 struct tls_params *params; 358 int ret; 359 TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); 360 const char *keyfile = lp_tls_keyfile(tmp_ctx, lp_ctx); 361 const char *certfile = lp_tls_certfile(tmp_ctx, lp_ctx); 362 const char *cafile = lp_tls_cafile(tmp_ctx, lp_ctx); 363 const char *crlfile = lp_tls_crlfile(tmp_ctx, lp_ctx); 364 const char *dhpfile = lp_tls_dhpfile(tmp_ctx, lp_ctx); 365 void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *); 366 params = talloc(mem_ctx, struct tls_params); 367 if (params == NULL) { 368 talloc_free(tmp_ctx); 369 return NULL; 370 } 371 372 if (!lp_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) { 373 params->tls_enabled = false; 374 talloc_free(tmp_ctx); 375 return params; 376 } 377 378 if (!file_exist(cafile)) { 379 char *hostname = talloc_asprintf(mem_ctx, "%s.%s", 380 lp_netbios_name(lp_ctx), lp_realm(lp_ctx)); 381 if (hostname == NULL) { 382 goto init_failed; 383 } 384 tls_cert_generate(params, hostname, keyfile, certfile, cafile); 385 talloc_free(hostname); 386 } 387 388 ret = gnutls_global_init(); 389 if (ret < 0) goto init_failed; 390 391 gnutls_certificate_allocate_credentials(¶ms->x509_cred); 392 if (ret < 0) goto init_failed; 393 394 if (cafile && *cafile) { 395 ret = gnutls_certificate_set_x509_trust_file(params->x509_cred, cafile, 396 GNUTLS_X509_FMT_PEM); 397 if (ret < 0) { 398 DEBUG(0,("TLS failed to initialise cafile %s\n", cafile)); 399 goto init_failed; 400 } 401 } 402 403 if (crlfile && *crlfile) { 404 ret = gnutls_certificate_set_x509_crl_file(params->x509_cred, 405 crlfile, 406 GNUTLS_X509_FMT_PEM); 407 if (ret < 0) { 408 DEBUG(0,("TLS failed to initialise crlfile %s\n", crlfile)); 409 goto init_failed; 410 } 411 } 412 413 ret = gnutls_certificate_set_x509_key_file(params->x509_cred, 414 certfile, keyfile, 415 GNUTLS_X509_FMT_PEM); 416 if (ret < 0) { 417 DEBUG(0,("TLS failed to initialise certfile %s and keyfile %s\n", 418 certfile, keyfile)); 419 goto init_failed; 420 } 421 422 423 ret = gnutls_dh_params_init(¶ms->dh_params); 424 if (ret < 0) goto init_failed; 425 426 if (dhpfile && *dhpfile) { 427 gnutls_datum_t dhparms; 428 size_t size; 429 dhparms.data = (uint8_t *)file_load(dhpfile, &size, 0, mem_ctx); 430 431 if (!dhparms.data) { 432 DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile)); 433 goto init_failed; 434 } 435 dhparms.size = size; 436 437 ret = gnutls_dh_params_import_pkcs3(params->dh_params, &dhparms, GNUTLS_X509_FMT_PEM); 438 if (ret < 0) goto init_failed; 439 } else { 440 ret = gnutls_dh_params_generate2(params->dh_params, DH_BITS); 441 if (ret < 0) goto init_failed; 442 } 443 444 gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params); 445 446 params->tls_enabled = true; 447 448 talloc_free(tmp_ctx); 449 return params; 450 451init_failed: 452 DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret))); 453 params->tls_enabled = false; 454 talloc_free(tmp_ctx); 455 return params; 456} 457 458 459/* 460 setup for a new connection 461*/ 462struct socket_context *tls_init_server(struct tls_params *params, 463 struct socket_context *socket_ctx, 464 struct tevent_fd *fde, 465 const char *plain_chars) 466{ 467 struct tls_context *tls; 468 int ret; 469 struct socket_context *new_sock; 470 NTSTATUS nt_status; 471 472 nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, 473 SOCKET_TYPE_STREAM, 474 socket_ctx->flags | SOCKET_FLAG_ENCRYPT); 475 if (!NT_STATUS_IS_OK(nt_status)) { 476 return NULL; 477 } 478 479 tls = talloc(new_sock, struct tls_context); 480 if (tls == NULL) { 481 return NULL; 482 } 483 484 tls->socket = socket_ctx; 485 talloc_steal(tls, socket_ctx); 486 tls->fde = fde; 487 488 new_sock->private_data = tls; 489 490 if (!params->tls_enabled) { 491 talloc_free(new_sock); 492 return NULL; 493 } 494 495 TLSCHECK(gnutls_init(&tls->session, GNUTLS_SERVER)); 496 497 talloc_set_destructor(tls, tls_destructor); 498 499 TLSCHECK(gnutls_set_default_priority(tls->session)); 500 TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, 501 params->x509_cred)); 502 gnutls_certificate_server_set_request(tls->session, GNUTLS_CERT_REQUEST); 503 gnutls_dh_set_prime_bits(tls->session, DH_BITS); 504 gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls); 505 gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); 506 gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); 507 gnutls_transport_set_lowat(tls->session, 0); 508 509 tls->plain_chars = plain_chars; 510 if (plain_chars) { 511 tls->tls_detect = true; 512 } else { 513 tls->tls_detect = false; 514 } 515 516 tls->output_pending = false; 517 tls->done_handshake = false; 518 tls->have_first_byte = false; 519 tls->tls_enabled = true; 520 tls->interrupted = false; 521 522 new_sock->state = SOCKET_STATE_SERVER_CONNECTED; 523 524 return new_sock; 525 526failed: 527 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); 528 talloc_free(new_sock); 529 return NULL; 530} 531 532 533/* 534 setup for a new client connection 535*/ 536struct socket_context *tls_init_client(struct socket_context *socket_ctx, 537 struct tevent_fd *fde, 538 const char *ca_path) 539{ 540 struct tls_context *tls; 541 int ret = 0; 542 const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; 543 struct socket_context *new_sock; 544 NTSTATUS nt_status; 545 546 nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, 547 SOCKET_TYPE_STREAM, 548 socket_ctx->flags | SOCKET_FLAG_ENCRYPT); 549 if (!NT_STATUS_IS_OK(nt_status)) { 550 return NULL; 551 } 552 553 tls = talloc(new_sock, struct tls_context); 554 if (tls == NULL) return NULL; 555 556 tls->socket = socket_ctx; 557 talloc_steal(tls, socket_ctx); 558 tls->fde = fde; 559 560 new_sock->private_data = tls; 561 562 gnutls_global_init(); 563 564 gnutls_certificate_allocate_credentials(&tls->xcred); 565 gnutls_certificate_set_x509_trust_file(tls->xcred, ca_path, GNUTLS_X509_FMT_PEM); 566 TLSCHECK(gnutls_init(&tls->session, GNUTLS_CLIENT)); 567 TLSCHECK(gnutls_set_default_priority(tls->session)); 568 gnutls_certificate_type_set_priority(tls->session, cert_type_priority); 569 TLSCHECK(gnutls_credentials_set(tls->session, GNUTLS_CRD_CERTIFICATE, tls->xcred)); 570 571 talloc_set_destructor(tls, tls_destructor); 572 573 gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls); 574 gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); 575 gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); 576 gnutls_transport_set_lowat(tls->session, 0); 577 tls->tls_detect = false; 578 579 tls->output_pending = false; 580 tls->done_handshake = false; 581 tls->have_first_byte = false; 582 tls->tls_enabled = true; 583 tls->interrupted = false; 584 585 new_sock->state = SOCKET_STATE_CLIENT_CONNECTED; 586 587 return new_sock; 588 589failed: 590 DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); 591 tls->tls_enabled = false; 592 return new_sock; 593} 594 595static NTSTATUS tls_socket_set_option(struct socket_context *sock, const char *option, const char *val) 596{ 597 set_socket_options(socket_get_fd(sock), option); 598 return NT_STATUS_OK; 599} 600 601static char *tls_socket_get_peer_name(struct socket_context *sock, TALLOC_CTX *mem_ctx) 602{ 603 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 604 return socket_get_peer_name(tls->socket, mem_ctx); 605} 606 607static struct socket_address *tls_socket_get_peer_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) 608{ 609 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 610 return socket_get_peer_addr(tls->socket, mem_ctx); 611} 612 613static struct socket_address *tls_socket_get_my_addr(struct socket_context *sock, TALLOC_CTX *mem_ctx) 614{ 615 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 616 return socket_get_my_addr(tls->socket, mem_ctx); 617} 618 619static int tls_socket_get_fd(struct socket_context *sock) 620{ 621 struct tls_context *tls = talloc_get_type(sock->private_data, struct tls_context); 622 return socket_get_fd(tls->socket); 623} 624 625static const struct socket_ops tls_socket_ops = { 626 .name = "tls", 627 .fn_init = tls_socket_init, 628 .fn_recv = tls_socket_recv, 629 .fn_send = tls_socket_send, 630 .fn_pending = tls_socket_pending, 631 632 .fn_set_option = tls_socket_set_option, 633 634 .fn_get_peer_name = tls_socket_get_peer_name, 635 .fn_get_peer_addr = tls_socket_get_peer_addr, 636 .fn_get_my_addr = tls_socket_get_my_addr, 637 .fn_get_fd = tls_socket_get_fd 638}; 639 640bool tls_support(struct tls_params *params) 641{ 642 return params->tls_enabled; 643} 644 645#else 646 647/* for systems without tls we just fail the operations, and the caller 648 * will retain the original socket */ 649 650struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) 651{ 652 return talloc_new(mem_ctx); 653} 654 655/* 656 setup for a new connection 657*/ 658struct socket_context *tls_init_server(struct tls_params *params, 659 struct socket_context *socket, 660 struct tevent_fd *fde, 661 const char *plain_chars) 662{ 663 return NULL; 664} 665 666 667/* 668 setup for a new client connection 669*/ 670struct socket_context *tls_init_client(struct socket_context *socket, 671 struct tevent_fd *fde, 672 const char *ca_path) 673{ 674 return NULL; 675} 676 677bool tls_support(struct tls_params *params) 678{ 679 return false; 680} 681 682#endif 683 684