From 9e16adff08c5bd14e5e2e8f528fc44ad22f3cfd2 Mon Sep 17 00:00:00 2001 From: Andreas Schneider Date: Wed, 13 Mar 2019 18:07:17 +0100 Subject: [PATCH] s3:smbd: Start to use the smb2_signing_key structure Signed-off-by: Andreas Schneider Reviewed-by: Andrew Bartlett --- source3/smbd/reply.c | 6 ++-- source3/smbd/sesssetup.c | 48 ++++++++++++++++++------- source3/smbd/smb2_server.c | 4 +-- source3/smbd/smb2_sesssetup.c | 68 +++++++++++++++++++++++++---------- 4 files changed, 91 insertions(+), 35 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index 86be7313524..2cef4d01a01 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -1013,7 +1013,7 @@ void reply_tcon_and_X(struct smb_request *req) * change any more. */ if (session->global->application_key.length == 0 && - session->global->signing_key_blob.length > 0) + smb2_signing_key_valid(session->global->signing_key)) { struct smbXsrv_session *x = session; struct auth_session_info *session_info = @@ -1021,8 +1021,8 @@ void reply_tcon_and_X(struct smb_request *req) uint8_t session_key[16]; ZERO_STRUCT(session_key); - memcpy(session_key, x->global->signing_key_blob.data, - MIN(x->global->signing_key_blob.length, sizeof(session_key))); + memcpy(session_key, x->global->signing_key->blob.data, + MIN(x->global->signing_key->blob.length, sizeof(session_key))); /* * The application key is truncated/padded to 16 bytes diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c index e66e5d31bbc..d359ef3607a 100644 --- a/source3/smbd/sesssetup.c +++ b/source3/smbd/sesssetup.c @@ -273,15 +273,27 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) /* * Note: the SMB1 signing key is not truncated to 16 byte! */ - x->global->signing_key_blob = - data_blob_dup_talloc(x->global, + x->global->signing_key = + talloc_zero(x->global, struct smb2_signing_key); + if (x->global->signing_key == NULL) { + data_blob_free(&out_blob); + TALLOC_FREE(session); + reply_nterror(req, NT_STATUS_NO_MEMORY); + return; + } + /* TODO: setup destructor once we cache the hmac handle */ + + x->global->signing_key->blob = + x->global->signing_key_blob = + data_blob_dup_talloc(x->global->signing_key, session_info->session_key); - if (x->global->signing_key_blob.data == NULL) { + if (!smb2_signing_key_valid(x->global->signing_key)) { data_blob_free(&out_blob); TALLOC_FREE(session); reply_nterror(req, NT_STATUS_NO_MEMORY); return; } + talloc_keep_secret(x->global->signing_key->blob.data); /* * clear the session key @@ -313,14 +325,14 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req) if (srv_is_signing_negotiated(xconn) && is_authenticated && - session->global->signing_key_blob.length > 0) + smb2_signing_key_valid(session->global->signing_key)) { /* * Try and turn on server signing on the first non-guest * sessionsetup. */ srv_set_signing(xconn, - session->global->signing_key_blob, + session->global->signing_key->blob, data_blob_null); } @@ -997,22 +1009,34 @@ void reply_sesssetup_and_X(struct smb_request *req) /* * Note: the SMB1 signing key is not truncated to 16 byte! */ - session->global->signing_key_blob = - data_blob_dup_talloc(session->global, + session->global->signing_key = + talloc_zero(session->global, struct smb2_signing_key); + if (session->global->signing_key == NULL) { + TALLOC_FREE(session); + reply_nterror(req, NT_STATUS_NO_MEMORY); + END_PROFILE(SMBsesssetupX); + return; + } + /* TODO: setup destructor once we cache the hmac handle */ + + session->global->signing_key->blob = + session->global->signing_key_blob = + data_blob_dup_talloc(session->global->signing_key, session_info->session_key); - if (session->global->signing_key_blob.data == NULL) { + if (!smb2_signing_key_valid(session->global->signing_key)) { TALLOC_FREE(session); reply_nterror(req, NT_STATUS_NO_MEMORY); END_PROFILE(SMBsesssetupX); return; } + talloc_keep_secret(session->global->signing_key->blob.data); /* * The application key is truncated/padded to 16 bytes */ ZERO_STRUCT(session_key); - memcpy(session_key, session->global->signing_key_blob.data, - MIN(session->global->signing_key_blob.length, + memcpy(session_key, session->global->signing_key->blob.data, + MIN(session->global->signing_key->blob.length, sizeof(session_key))); session->global->application_key = data_blob_talloc(session->global, @@ -1063,14 +1087,14 @@ void reply_sesssetup_and_X(struct smb_request *req) if (srv_is_signing_negotiated(xconn) && is_authenticated && - session->global->signing_key_blob.length > 0) + smb2_signing_key_valid(session->global->signing_key)) { /* * Try and turn on server signing on the first non-guest * sessionsetup. */ srv_set_signing(xconn, - session->global->signing_key_blob, + session->global->signing_key->blob, state->nt_resp.data ? state->nt_resp : state->lm_resp); } diff --git a/source3/smbd/smb2_server.c b/source3/smbd/smb2_server.c index 7e225fa2b67..4331e672911 100644 --- a/source3/smbd/smb2_server.c +++ b/source3/smbd/smb2_server.c @@ -1517,11 +1517,11 @@ static DATA_BLOB smbd_smb2_signing_key(struct smbXsrv_session *session, status = smbXsrv_session_find_channel(session, xconn, &c); if (NT_STATUS_IS_OK(status)) { - key = c->signing_key_blob; + key = c->signing_key->blob; } if (key.length == 0) { - key = session->global->signing_key_blob; + key = session->global->signing_key->blob; } return key; diff --git a/source3/smbd/smb2_sesssetup.c b/source3/smbd/smb2_sesssetup.c index 9e5e8c59322..a395774c320 100644 --- a/source3/smbd/smb2_sesssetup.c +++ b/source3/smbd/smb2_sesssetup.c @@ -323,10 +323,20 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, memcpy(session_key, session_info->session_key.data, MIN(session_info->session_key.length, sizeof(session_key))); - x->global->signing_key_blob = data_blob_talloc(x->global, - session_key, - sizeof(session_key)); - if (x->global->signing_key_blob.data == NULL) { + x->global->signing_key = talloc_zero(x->global, + struct smb2_signing_key); + if (x->global->signing_key == NULL) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } + /* TODO: setup destructor once we cache the hmac handle */ + + x->global->signing_key->blob = + x->global->signing_key_blob = + data_blob_talloc(x->global, + session_key, + sizeof(session_key)); + if (!smb2_signing_key_valid(x->global->signing_key)) { ZERO_STRUCT(session_key); return NT_STATUS_NO_MEMORY; } @@ -337,7 +347,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, smb2_key_derivation(session_key, sizeof(session_key), d->label.data, d->label.length, d->context.data, d->context.length, - x->global->signing_key_blob.data); + x->global->signing_key->blob.data); } if (xconn->protocol >= PROTOCOL_SMB2_24) { @@ -402,11 +412,12 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, } x->global->application_key = - data_blob_dup_talloc(x->global, x->global->signing_key_blob); + data_blob_dup_talloc(x->global, x->global->signing_key->blob); if (x->global->application_key.data == NULL) { ZERO_STRUCT(session_key); return NT_STATUS_NO_MEMORY; } + talloc_keep_secret(x->global->application_key.data); if (xconn->protocol >= PROTOCOL_SMB2_24) { struct _derivation *d = &derivation.application; @@ -425,8 +436,8 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, DEBUGADD(0, ("Session Key ")); dump_data(0, session_key, sizeof(session_key)); DEBUGADD(0, ("Signing Key ")); - dump_data(0, x->global->signing_key_blob.data, - x->global->signing_key_blob.length); + dump_data(0, x->global->signing_key->blob.data, + x->global->signing_key->blob.length); DEBUGADD(0, ("App Key ")); dump_data(0, x->global->application_key.data, x->global->application_key.length); @@ -443,12 +454,21 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, ZERO_STRUCT(session_key); - x->global->channels[0].signing_key_blob = - data_blob_dup_talloc(x->global->channels, - x->global->signing_key_blob); - if (x->global->channels[0].signing_key_blob.data == NULL) { + x->global->channels[0].signing_key = + talloc_zero(x->global->channels, struct smb2_signing_key); + if (x->global->channels[0].signing_key == NULL) { return NT_STATUS_NO_MEMORY; } + /* TODO: setup destructor once we cache the hmac handle */ + + x->global->channels[0].signing_key->blob = + x->global->channels[0].signing_key_blob = + data_blob_dup_talloc(x->global->channels[0].signing_key, + x->global->signing_key->blob); + if (!smb2_signing_key_valid(x->global->channels[0].signing_key)) { + return NT_STATUS_NO_MEMORY; + } + talloc_keep_secret(x->global->channels[0].signing_key->blob.data); data_blob_clear_free(&session_info->session_key); session_info->session_key = data_blob_dup_talloc(session_info, @@ -456,6 +476,7 @@ static NTSTATUS smbd_smb2_auth_generic_return(struct smbXsrv_session *session, if (session_info->session_key.data == NULL) { return NT_STATUS_NO_MEMORY; } + talloc_keep_secret(session_info->session_key.data); session->compat = talloc_zero(session, struct user_struct); if (session->compat == NULL) { @@ -547,6 +568,7 @@ static NTSTATUS smbd_smb2_reauth_generic_return(struct smbXsrv_session *session, if (session_info->session_key.data == NULL) { return NT_STATUS_NO_MEMORY; } + talloc_keep_secret(session_info->session_key.data); session->compat->session_info = session_info; session->compat->vuid = session->global->session_wire_id; @@ -673,13 +695,23 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session, memcpy(session_key, session_info->session_key.data, MIN(session_info->session_key.length, sizeof(session_key))); - c->signing_key_blob = data_blob_talloc(x->global, - session_key, - sizeof(session_key)); - if (c->signing_key_blob.data == NULL) { + c->signing_key = talloc_zero(x->global, struct smb2_signing_key); + if (c->signing_key == NULL) { + ZERO_STRUCT(session_key); + return NT_STATUS_NO_MEMORY; + } + /* TODO: setup destructor once we cache the hmac handle */ + + c->signing_key->blob = + c->signing_key_blob = + data_blob_talloc(c->signing_key, + session_key, + sizeof(session_key)); + if (!smb2_signing_key_valid(c->signing_key)) { ZERO_STRUCT(session_key); return NT_STATUS_NO_MEMORY; } + talloc_keep_secret(c->signing_key->blob.data); if (xconn->protocol >= PROTOCOL_SMB2_24) { struct _derivation *d = &derivation.signing; @@ -687,7 +719,7 @@ static NTSTATUS smbd_smb2_bind_auth_return(struct smbXsrv_session *session, smb2_key_derivation(session_key, sizeof(session_key), d->label.data, d->label.length, d->context.data, d->context.length, - c->signing_key_blob.data); + c->signing_key->blob.data); } ZERO_STRUCT(session_key); @@ -785,7 +817,7 @@ static struct tevent_req *smbd_smb2_session_setup_send(TALLOC_CTX *mem_ctx, smb2req->xconn, &c); if (NT_STATUS_IS_OK(status)) { - if (c->signing_key_blob.length == 0) { + if (!smb2_signing_key_valid(c->signing_key)) { goto auth; } tevent_req_nterror(req, NT_STATUS_REQUEST_NOT_ACCEPTED); -- 2.47.3