X-Git-Url: http://git.samba.org/samba.git/?a=blobdiff_plain;f=source4%2Flib%2Ftls%2Ftls.c;h=3a49e2f2e8c4619bf022c1d5b24e044c05647a58;hb=0d33383b0dcef2bfc805432798e1f46097ee1f15;hp=d2f6d6f740606c052bca205aa8ec9bfcdd1b6aad;hpb=2f3551ca7cee59d4d053cceb87abdf1da1b3a1ad;p=mdw%2Fsamba.git diff --git a/source4/lib/tls/tls.c b/source4/lib/tls/tls.c index d2f6d6f740..3a49e2f2e8 100644 --- a/source4/lib/tls/tls.c +++ b/source4/lib/tls/tls.c @@ -40,40 +40,40 @@ typedef gnutls_datum gnutls_datum_t; struct tls_params { gnutls_certificate_credentials x509_cred; gnutls_dh_params dh_params; - BOOL tls_enabled; + bool tls_enabled; }; #endif /* hold per connection tls data */ struct tls_context { struct socket_context *socket; - struct fd_event *fde; - BOOL tls_enabled; + struct tevent_fd *fde; + bool tls_enabled; #if ENABLE_GNUTLS gnutls_session session; - BOOL done_handshake; - BOOL have_first_byte; + bool done_handshake; + bool have_first_byte; uint8_t first_byte; - BOOL tls_detect; + bool tls_detect; const char *plain_chars; - BOOL output_pending; + bool output_pending; gnutls_certificate_credentials xcred; - BOOL interrupted; + bool interrupted; #endif }; -BOOL tls_enabled(struct socket_context *sock) +bool tls_enabled(struct socket_context *sock) { struct tls_context *tls; if (!sock) { - return False; + return false; } if (strcmp(sock->backend_name, "tls") != 0) { - return False; + return false; } tls = talloc_get_type(sock->private_data, struct tls_context); if (!tls) { - return False; + return false; } return tls->tls_enabled; } @@ -117,7 +117,7 @@ static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) if (tls->have_first_byte) { *(uint8_t *)buf = tls->first_byte; - tls->have_first_byte = False; + tls->have_first_byte = false; return 1; } @@ -126,21 +126,21 @@ static ssize_t tls_pull(gnutls_transport_ptr ptr, void *buf, size_t size) return 0; } if (NT_STATUS_IS_ERR(status)) { - EVENT_FD_NOT_READABLE(tls->fde); - EVENT_FD_NOT_WRITEABLE(tls->fde); + TEVENT_FD_NOT_READABLE(tls->fde); + TEVENT_FD_NOT_WRITEABLE(tls->fde); errno = EBADF; return -1; } if (!NT_STATUS_IS_OK(status)) { - EVENT_FD_READABLE(tls->fde); + TEVENT_FD_READABLE(tls->fde); errno = EAGAIN; return -1; } if (tls->output_pending) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); } if (size != nread) { - EVENT_FD_READABLE(tls->fde); + TEVENT_FD_READABLE(tls->fde); } return nread; } @@ -168,11 +168,11 @@ static ssize_t tls_push(gnutls_transport_ptr ptr, const void *buf, size_t size) return -1; } if (!NT_STATUS_IS_OK(status)) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); return -1; } if (size != nwritten) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); } return nwritten; } @@ -185,7 +185,7 @@ static int tls_destructor(struct tls_context *tls) int ret; ret = gnutls_bye(tls->session, GNUTLS_SHUT_WR); if (ret < 0) { - DEBUG(0,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret))); + DEBUG(4,("TLS gnutls_bye failed - %s\n", gnutls_strerror(ret))); } return 0; } @@ -205,7 +205,7 @@ static NTSTATUS tls_handshake(struct tls_context *tls) ret = gnutls_handshake(tls->session); if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(tls->session) == 1) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); } return STATUS_MORE_ENTRIES; } @@ -213,7 +213,7 @@ static NTSTATUS tls_handshake(struct tls_context *tls) DEBUG(0,("TLS gnutls_handshake failed - %s\n", gnutls_strerror(ret))); return NT_STATUS_UNEXPECTED_NETWORK_ERROR; } - tls->done_handshake = True; + tls->done_handshake = true; return NT_STATUS_OK; } @@ -235,7 +235,7 @@ static NTSTATUS tls_interrupted(struct tls_context *tls) if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { return STATUS_MORE_ENTRIES; } - tls->interrupted = False; + tls->interrupted = false; return NT_STATUS_OK; } @@ -274,15 +274,15 @@ static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, status = socket_recv(tls->socket, &tls->first_byte, 1, nread); NT_STATUS_NOT_OK_RETURN(status); if (*nread == 0) return NT_STATUS_OK; - tls->tls_detect = False; + tls->tls_detect = false; /* look for the first byte of a valid HTTP operation */ if (strchr(tls->plain_chars, tls->first_byte)) { /* not a tls link */ - tls->tls_enabled = False; + tls->tls_enabled = false; *(uint8_t *)buf = tls->first_byte; return NT_STATUS_OK; } - tls->have_first_byte = True; + tls->have_first_byte = true; } if (!tls->tls_enabled) { @@ -298,9 +298,9 @@ static NTSTATUS tls_socket_recv(struct socket_context *sock, void *buf, ret = gnutls_record_recv(tls->session, buf, wantlen); if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(tls->session) == 1) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); } - tls->interrupted = True; + tls->interrupted = true; return STATUS_MORE_ENTRIES; } if (ret < 0) { @@ -334,9 +334,9 @@ static NTSTATUS tls_socket_send(struct socket_context *sock, ret = gnutls_record_send(tls->session, blob->data, blob->length); if (ret == GNUTLS_E_INTERRUPTED || ret == GNUTLS_E_AGAIN) { if (gnutls_record_get_direction(tls->session) == 1) { - EVENT_FD_WRITEABLE(tls->fde); + TEVENT_FD_WRITEABLE(tls->fde); } - tls->interrupted = True; + tls->interrupted = true; return STATUS_MORE_ENTRIES; } if (ret < 0) { @@ -352,32 +352,38 @@ static NTSTATUS tls_socket_send(struct socket_context *sock, /* initialise global tls state */ -struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) +struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { struct tls_params *params; int ret; TALLOC_CTX *tmp_ctx = talloc_new(mem_ctx); - const char *keyfile = private_path(tmp_ctx, global_loadparm, lp_tls_keyfile(global_loadparm)); - const char *certfile = private_path(tmp_ctx, global_loadparm, lp_tls_certfile(global_loadparm)); - const char *cafile = private_path(tmp_ctx, global_loadparm, lp_tls_cafile(global_loadparm)); - const char *crlfile = private_path(tmp_ctx, global_loadparm, lp_tls_crlfile(global_loadparm)); - const char *dhpfile = private_path(tmp_ctx, global_loadparm, lp_tls_dhpfile(global_loadparm)); - void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *); - + const char *keyfile = lpcfg_tls_keyfile(tmp_ctx, lp_ctx); + const char *certfile = lpcfg_tls_certfile(tmp_ctx, lp_ctx); + const char *cafile = lpcfg_tls_cafile(tmp_ctx, lp_ctx); + const char *crlfile = lpcfg_tls_crlfile(tmp_ctx, lp_ctx); + const char *dhpfile = lpcfg_tls_dhpfile(tmp_ctx, lp_ctx); + void tls_cert_generate(TALLOC_CTX *, const char *, const char *, const char *, const char *); params = talloc(mem_ctx, struct tls_params); if (params == NULL) { talloc_free(tmp_ctx); return NULL; } - if (!lp_tls_enabled(global_loadparm) || keyfile == NULL || *keyfile == 0) { - params->tls_enabled = False; + if (!lpcfg_tls_enabled(lp_ctx) || keyfile == NULL || *keyfile == 0) { + params->tls_enabled = false; talloc_free(tmp_ctx); return params; } if (!file_exist(cafile)) { - tls_cert_generate(params, keyfile, certfile, cafile); + char *hostname = talloc_asprintf(mem_ctx, "%s.%s", + lpcfg_netbios_name(lp_ctx), + lpcfg_dnsdomain(lp_ctx)); + if (hostname == NULL) { + goto init_failed; + } + tls_cert_generate(params, hostname, keyfile, certfile, cafile); + talloc_free(hostname); } ret = gnutls_global_init(); @@ -421,7 +427,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) if (dhpfile && *dhpfile) { gnutls_datum_t dhparms; size_t size; - dhparms.data = (uint8_t *)file_load(dhpfile, &size, mem_ctx); + dhparms.data = (uint8_t *)file_load(dhpfile, &size, 0, mem_ctx); if (!dhparms.data) { DEBUG(0,("Failed to read DH Parms from %s\n", dhpfile)); @@ -438,14 +444,14 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) gnutls_certificate_set_dh_params(params->x509_cred, params->dh_params); - params->tls_enabled = True; + params->tls_enabled = true; talloc_free(tmp_ctx); return params; init_failed: DEBUG(0,("GNUTLS failed to initialise - %s\n", gnutls_strerror(ret))); - params->tls_enabled = False; + params->tls_enabled = false; talloc_free(tmp_ctx); return params; } @@ -455,8 +461,8 @@ init_failed: setup for a new connection */ struct socket_context *tls_init_server(struct tls_params *params, - struct socket_context *socket, - struct fd_event *fde, + struct socket_context *socket_ctx, + struct tevent_fd *fde, const char *plain_chars) { struct tls_context *tls; @@ -464,9 +470,9 @@ struct socket_context *tls_init_server(struct tls_params *params, struct socket_context *new_sock; NTSTATUS nt_status; - nt_status = socket_create_with_ops(socket, &tls_socket_ops, &new_sock, + nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, SOCKET_TYPE_STREAM, - socket->flags | SOCKET_FLAG_ENCRYPT); + socket_ctx->flags | SOCKET_FLAG_ENCRYPT); if (!NT_STATUS_IS_OK(nt_status)) { return NULL; } @@ -476,16 +482,9 @@ struct socket_context *tls_init_server(struct tls_params *params, return NULL; } - tls->socket = socket; + tls->socket = socket_ctx; + talloc_steal(tls, socket_ctx); tls->fde = fde; - if (talloc_reference(tls, fde) == NULL) { - talloc_free(new_sock); - return NULL; - } - if (talloc_reference(tls, socket) == NULL) { - talloc_free(new_sock); - return NULL; - } new_sock->private_data = tls; @@ -506,20 +505,22 @@ struct socket_context *tls_init_server(struct tls_params *params, gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls); gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); +#if GNUTLS_VERSION_MAJOR < 3 gnutls_transport_set_lowat(tls->session, 0); +#endif tls->plain_chars = plain_chars; if (plain_chars) { - tls->tls_detect = True; + tls->tls_detect = true; } else { - tls->tls_detect = False; + tls->tls_detect = false; } - tls->output_pending = False; - tls->done_handshake = False; - tls->have_first_byte = False; - tls->tls_enabled = True; - tls->interrupted = False; + tls->output_pending = false; + tls->done_handshake = false; + tls->have_first_byte = false; + tls->tls_enabled = true; + tls->interrupted = false; new_sock->state = SOCKET_STATE_SERVER_CONNECTED; @@ -535,19 +536,19 @@ failed: /* setup for a new client connection */ -struct socket_context *tls_init_client(struct socket_context *socket, - struct fd_event *fde) +struct socket_context *tls_init_client(struct socket_context *socket_ctx, + struct tevent_fd *fde, + const char *ca_path) { struct tls_context *tls; int ret = 0; const int cert_type_priority[] = { GNUTLS_CRT_X509, GNUTLS_CRT_OPENPGP, 0 }; - char *cafile; struct socket_context *new_sock; NTSTATUS nt_status; - nt_status = socket_create_with_ops(socket, &tls_socket_ops, &new_sock, + nt_status = socket_create_with_ops(socket_ctx, &tls_socket_ops, &new_sock, SOCKET_TYPE_STREAM, - socket->flags | SOCKET_FLAG_ENCRYPT); + socket_ctx->flags | SOCKET_FLAG_ENCRYPT); if (!NT_STATUS_IS_OK(nt_status)) { return NULL; } @@ -555,26 +556,16 @@ struct socket_context *tls_init_client(struct socket_context *socket, tls = talloc(new_sock, struct tls_context); if (tls == NULL) return NULL; - tls->socket = socket; + tls->socket = socket_ctx; + talloc_steal(tls, socket_ctx); tls->fde = fde; - if (talloc_reference(tls, fde) == NULL) { - return NULL; - } - if (talloc_reference(tls, socket) == NULL) { - return NULL; - } - new_sock->private_data = tls; - cafile = private_path(tls, global_loadparm, lp_tls_cafile(global_loadparm)); - if (!cafile || !*cafile) { - goto failed; - } + new_sock->private_data = tls; gnutls_global_init(); gnutls_certificate_allocate_credentials(&tls->xcred); - gnutls_certificate_set_x509_trust_file(tls->xcred, cafile, GNUTLS_X509_FMT_PEM); - talloc_free(cafile); + gnutls_certificate_set_x509_trust_file(tls->xcred, ca_path, GNUTLS_X509_FMT_PEM); TLSCHECK(gnutls_init(&tls->session, GNUTLS_CLIENT)); TLSCHECK(gnutls_set_default_priority(tls->session)); gnutls_certificate_type_set_priority(tls->session, cert_type_priority); @@ -585,14 +576,16 @@ struct socket_context *tls_init_client(struct socket_context *socket, gnutls_transport_set_ptr(tls->session, (gnutls_transport_ptr)tls); gnutls_transport_set_pull_function(tls->session, (gnutls_pull_func)tls_pull); gnutls_transport_set_push_function(tls->session, (gnutls_push_func)tls_push); +#if GNUTLS_VERSION_MAJOR < 3 gnutls_transport_set_lowat(tls->session, 0); - tls->tls_detect = False; +#endif + tls->tls_detect = false; - tls->output_pending = False; - tls->done_handshake = False; - tls->have_first_byte = False; - tls->tls_enabled = True; - tls->interrupted = False; + tls->output_pending = false; + tls->done_handshake = false; + tls->have_first_byte = false; + tls->tls_enabled = true; + tls->interrupted = false; new_sock->state = SOCKET_STATE_CLIENT_CONNECTED; @@ -600,7 +593,7 @@ struct socket_context *tls_init_client(struct socket_context *socket, failed: DEBUG(0,("TLS init connection failed - %s\n", gnutls_strerror(ret))); - tls->tls_enabled = False; + tls->tls_enabled = false; return new_sock; } @@ -649,7 +642,7 @@ static const struct socket_ops tls_socket_ops = { .fn_get_fd = tls_socket_get_fd }; -BOOL tls_support(struct tls_params *params) +bool tls_support(struct tls_params *params) { return params->tls_enabled; } @@ -659,7 +652,7 @@ BOOL tls_support(struct tls_params *params) /* for systems without tls we just fail the operations, and the caller * will retain the original socket */ -struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) +struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx, struct loadparm_context *lp_ctx) { return talloc_new(mem_ctx); } @@ -669,7 +662,7 @@ struct tls_params *tls_initialise(TALLOC_CTX *mem_ctx) */ struct socket_context *tls_init_server(struct tls_params *params, struct socket_context *socket, - struct fd_event *fde, + struct tevent_fd *fde, const char *plain_chars) { return NULL; @@ -680,14 +673,15 @@ struct socket_context *tls_init_server(struct tls_params *params, setup for a new client connection */ struct socket_context *tls_init_client(struct socket_context *socket, - struct fd_event *fde) + struct tevent_fd *fde, + const char *ca_path) { return NULL; } -BOOL tls_support(struct tls_params *params) +bool tls_support(struct tls_params *params) { - return False; + return false; } #endif