From c3cb672d3810cb2fb0076fac3b949df5f2462451 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:53:30 +0200 Subject: [PATCH 01/24] libcli/smb: add smb1cli_session_set_session_key() metze --- libcli/smb/smbXcli_base.c | 34 ++++++++++++++++++++++++++++++++++ libcli/smb/smbXcli_base.h | 2 ++ 2 files changed, 36 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index a363b44..66cb873 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -148,6 +148,7 @@ struct smbXcli_session { struct { uint16_t session_id; + DATA_BLOB application_key; } smb1; struct smb2cli_session *smb2; @@ -4304,6 +4305,39 @@ void smb1cli_session_set_id(struct smbXcli_session *session, session->smb1.session_id = session_id; } +NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session, + const DATA_BLOB _session_key) +{ + struct smbXcli_conn *conn = session->conn; + uint8_t session_key[16]; + + if (conn == NULL) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + if (session->smb1.application_key.length != 0) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + if (_session_key.length == 0) { + return NT_STATUS_OK; + } + + ZERO_STRUCT(session_key); + memcpy(session_key, _session_key.data, + MIN(_session_key.length, sizeof(session_key))); + + session->smb1.application_key = data_blob_talloc(session, + session_key, + sizeof(session_key)); + ZERO_STRUCT(session_key); + if (session->smb1.application_key.data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + uint8_t smb2cli_session_security_mode(struct smbXcli_session *session) { struct smbXcli_conn *conn = session->conn; diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index c55bf53..2f78247 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -251,6 +251,8 @@ struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx, uint16_t smb1cli_session_current_id(struct smbXcli_session* session); void smb1cli_session_set_id(struct smbXcli_session* session, uint16_t session_id); +NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session, + const DATA_BLOB _session_key); uint8_t smb2cli_session_security_mode(struct smbXcli_session *session); uint64_t smb2cli_session_current_id(struct smbXcli_session *session); uint16_t smb2cli_session_get_flags(struct smbXcli_session *session); -- 1.7.9.5 From 77807571a2dec8cacf27ba98b8fa1a30fdcd811a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:54:51 +0200 Subject: [PATCH 02/24] s3:libsmb: make use of smb1cli_session_set_session_key() metze --- source3/libsmb/cliconnect.c | 24 ++++++++++++++++++++++++ 1 file changed, 24 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 17b5af6..ea7ddfe 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -1092,8 +1092,16 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq) return; } if (state->session_key.data) { + struct smbXcli_session *session = state->cli->smb1.session; + /* Have plaintext orginal */ cli_set_session_key(cli, state->session_key); + + status = smb1cli_session_set_session_key(session, + state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } } tevent_req_done(req); } @@ -1528,6 +1536,14 @@ static void cli_session_setup_kerberos_done(struct tevent_req *subreq) return; } } else { + struct smbXcli_session *session = state->cli->smb1.session; + + status = smb1cli_session_set_session_key(session, + state->session_key_krb5); + if (tevent_req_nterror(req, status)) { + return; + } + if (smb1cli_conn_activate_signing(state->cli->conn, state->session_key_krb5, data_blob_null) && !smb1cli_conn_check_signing(state->cli->conn, inbuf, 1)) { @@ -1739,6 +1755,14 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } } else { + struct smbXcli_session *session = state->cli->smb1.session; + + status = smb1cli_session_set_session_key(session, + state->ntlmssp_state->session_key); + if (tevent_req_nterror(req, status)) { + return; + } + if (smb1cli_conn_activate_signing( state->cli->conn, state->ntlmssp_state->session_key, data_blob_null) -- 1.7.9.5 From 8d4259b912c087f28703a7acf03cad389ebf6ba5 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:55:49 +0200 Subject: [PATCH 03/24] s4:libcli/smb_composite: always use set_user_session_key() helper metze --- source4/libcli/smb_composite/sesssetup.c | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index 63f3a8e..a69d300 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -195,16 +195,20 @@ static void request_handler(struct smbcli_request *req) } if (NT_STATUS_IS_OK(state->remote_status)) { + DATA_BLOB session_key; + if (state->setup.spnego.in.secblob.length) { c->status = NT_STATUS_INTERNAL_ERROR; break; } - session_key_err = gensec_session_key(session->gensec, session, &session->user_session_key); + session_key_err = gensec_session_key(session->gensec, session, &session_key); if (NT_STATUS_IS_OK(session_key_err)) { smb1cli_conn_activate_signing(session->transport->conn, - session->user_session_key, + session_key, null_data_blob); } + set_user_session_key(session, &session_key); + data_blob_free(&session_key); } if (state->setup.spnego.in.secblob.length) { -- 1.7.9.5 From 06eaa6980cbf571e7cf871db7a1e9ab6bcb9b17b Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:57:40 +0200 Subject: [PATCH 04/24] s4:libcli/smb_composite: make use of smb1cli_session_set_session_key() metze --- source4/libcli/smb_composite/sesssetup.c | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index a69d300..fab2ce9 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -208,7 +208,13 @@ static void request_handler(struct smbcli_request *req) null_data_blob); } set_user_session_key(session, &session_key); + + c->status = smb1cli_session_set_session_key(session->smbXcli, + session_key); data_blob_free(&session_key); + if (!NT_STATUS_IS_OK(c->status)) { + break; + } } if (state->setup.spnego.in.secblob.length) { @@ -346,7 +352,12 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, state->setup.nt1.in.password2); set_user_session_key(session, &session_key); + nt_status = smb1cli_session_set_session_key(session->smbXcli, + session_key); data_blob_free(&session_key); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } } return (*req)->status; @@ -405,8 +416,13 @@ static NTSTATUS session_setup_old(struct composite_context *c, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); set_user_session_key(session, &session_key); - + + nt_status = smb1cli_session_set_session_key(session->smbXcli, + session_key); data_blob_free(&session_key); + if (!NT_STATUS_IS_OK(nt_status)) { + return nt_status; + } } else if (session->options.plaintext_auth) { state->setup.old.in.password = data_blob_talloc(state, password, strlen(password)); } else { -- 1.7.9.5 From dcb6cbfa194f3879a0138d8f3d9982e031eda5ab Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:59:01 +0200 Subject: [PATCH 05/24] libcli/smb: add smbXcli_session_application_key() metze --- libcli/smb/smbXcli_base.c | 30 ++++++++++++++++++++++++++++++ libcli/smb/smbXcli_base.h | 3 +++ 2 files changed, 33 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 66cb873..320dee1 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -4294,6 +4294,36 @@ struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx, return session; } +NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session, + TALLOC_CTX *mem_ctx, + DATA_BLOB *key) +{ + const DATA_BLOB *application_key; + + *key = data_blob_null; + + if (session->conn == NULL) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + if (session->conn->protocol >= PROTOCOL_SMB2_02) { + application_key = &session->smb2->application_key; + } else { + application_key = &session->smb1.application_key; + } + + if (application_key->length == 0) { + return NT_STATUS_NO_USER_SESSION_KEY; + } + + *key = data_blob_dup_talloc(mem_ctx, *application_key); + if (key->data == NULL) { + return NT_STATUS_NO_MEMORY; + } + + return NT_STATUS_OK; +} + uint16_t smb1cli_session_current_id(struct smbXcli_session *session) { return session->smb1.session_id; diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 2f78247..c35811a 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -248,6 +248,9 @@ NTSTATUS smbXcli_negprot(struct smbXcli_conn *conn, struct smbXcli_session *smbXcli_session_create(TALLOC_CTX *mem_ctx, struct smbXcli_conn *conn); +NTSTATUS smbXcli_session_application_key(struct smbXcli_session *session, + TALLOC_CTX *mem_ctx, + DATA_BLOB *key); uint16_t smb1cli_session_current_id(struct smbXcli_session* session); void smb1cli_session_set_id(struct smbXcli_session* session, uint16_t session_id); -- 1.7.9.5 From 05c9296e00a5d4b3327cc87ce235b45cd2c2847e Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 08:59:57 +0200 Subject: [PATCH 06/24] s4:librpc/dcerpc_smb2: make use of smbXcli_session_application_key() metze --- source4/librpc/rpc/dcerpc_smb2.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source4/librpc/rpc/dcerpc_smb2.c b/source4/librpc/rpc/dcerpc_smb2.c index 30f94a4..2877525 100644 --- a/source4/librpc/rpc/dcerpc_smb2.c +++ b/source4/librpc/rpc/dcerpc_smb2.c @@ -511,7 +511,7 @@ static void pipe_open_recv(struct smb2_request *req) if (composite_nomem(smb->server_name, ctx)) return; smb->dead = false; - ctx->status = smb2cli_session_application_key(tree->session->smbXcli, + ctx->status = smbXcli_session_application_key(tree->session->smbXcli, smb, &smb->session_key); if (NT_STATUS_EQUAL(ctx->status, NT_STATUS_NO_USER_SESSION_KEY)) { smb->session_key = data_blob_null; -- 1.7.9.5 From 757d1ec84aee496c0b249d74afc633f46ac0a742 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:01:01 +0200 Subject: [PATCH 07/24] libcli/smb: remove unused smb2cli_session_application_key() metze --- libcli/smb/smbXcli_base.c | 18 ------------------ libcli/smb/smbXcli_base.h | 3 --- 2 files changed, 21 deletions(-) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index 320dee1..d6fbafc 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -4395,24 +4395,6 @@ uint16_t smb2cli_session_get_flags(struct smbXcli_session *session) return session->smb2->session_flags; } -NTSTATUS smb2cli_session_application_key(struct smbXcli_session *session, - TALLOC_CTX *mem_ctx, - DATA_BLOB *key) -{ - *key = data_blob_null; - - if (session->smb2->application_key.length == 0) { - return NT_STATUS_NO_USER_SESSION_KEY; - } - - *key = data_blob_dup_talloc(mem_ctx, session->smb2->application_key); - if (key->data == NULL) { - return NT_STATUS_NO_MEMORY; - } - - return NT_STATUS_OK; -} - void smb2cli_session_set_id_and_flags(struct smbXcli_session *session, uint64_t session_id, uint16_t session_flags) diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index c35811a..3f78cd5 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -259,9 +259,6 @@ NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session, uint8_t smb2cli_session_security_mode(struct smbXcli_session *session); uint64_t smb2cli_session_current_id(struct smbXcli_session *session); uint16_t smb2cli_session_get_flags(struct smbXcli_session *session); -NTSTATUS smb2cli_session_application_key(struct smbXcli_session *session, - TALLOC_CTX *mem_ctx, - DATA_BLOB *key); void smb2cli_session_set_id_and_flags(struct smbXcli_session *session, uint64_t session_id, uint16_t session_flags); -- 1.7.9.5 From 28f3d4339c20c9f1df6ca7fb41ca2a8568449794 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:09:34 +0200 Subject: [PATCH 08/24] s4:librpc/dcerpc_smb: make use of smbXcli_session_application_key() metze --- source4/librpc/rpc/dcerpc_smb.c | 19 +++++++++++++++---- 1 file changed, 15 insertions(+), 4 deletions(-) diff --git a/source4/librpc/rpc/dcerpc_smb.c b/source4/librpc/rpc/dcerpc_smb.c index f4f4457..e718725 100644 --- a/source4/librpc/rpc/dcerpc_smb.c +++ b/source4/librpc/rpc/dcerpc_smb.c @@ -32,6 +32,7 @@ struct smb_private { uint16_t fnum; struct smbcli_tree *tree; + DATA_BLOB session_key; const char *server_name; bool dead; }; @@ -429,11 +430,13 @@ static NTSTATUS smb_session_key(struct dcecli_connection *c, DATA_BLOB *session_ struct smb_private *smb = (struct smb_private *)c->transport.private_data; if (smb == NULL) return NT_STATUS_CONNECTION_DISCONNECTED; - if (smb->tree->session->user_session_key.data) { - *session_key = smb->tree->session->user_session_key; - return NT_STATUS_OK; + + if (smb->session_key.length == 0) { + return NT_STATUS_NO_USER_SESSION_KEY; } - return NT_STATUS_NO_USER_SESSION_KEY; + + *session_key = smb->session_key; + return NT_STATUS_OK; } struct pipe_open_smb_state { @@ -555,6 +558,14 @@ static void pipe_open_recv(struct smbcli_request *req) if (composite_nomem(smb->server_name, ctx)) return; smb->dead = false; + ctx->status = smbXcli_session_application_key(state->tree->session->smbXcli, + smb, &smb->session_key); + if (NT_STATUS_EQUAL(ctx->status, NT_STATUS_NO_USER_SESSION_KEY)) { + smb->session_key = data_blob_null; + ctx->status = NT_STATUS_OK; + } + if (!composite_is_ok(ctx)) return; + c->transport.private_data = smb; composite_done(ctx); -- 1.7.9.5 From 315c0462551131e3f5b7bc484d5e37a66628d98d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:10:09 +0200 Subject: [PATCH 09/24] s4:librpc/dcerpc_smb2: sync smb2_session_key() with smb_session_key() metze --- source4/librpc/rpc/dcerpc_smb2.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/source4/librpc/rpc/dcerpc_smb2.c b/source4/librpc/rpc/dcerpc_smb2.c index 2877525..473ca78 100644 --- a/source4/librpc/rpc/dcerpc_smb2.c +++ b/source4/librpc/rpc/dcerpc_smb2.c @@ -390,6 +390,8 @@ static NTSTATUS smb2_session_key(struct dcecli_connection *c, DATA_BLOB *session struct smb2_private *smb = talloc_get_type(c->transport.private_data, struct smb2_private); + if (smb == NULL) return NT_STATUS_CONNECTION_DISCONNECTED; + if (smb->session_key.length == 0) { return NT_STATUS_NO_USER_SESSION_KEY; } -- 1.7.9.5 From 053c371b43d473004db13f0748f2f902183e463d Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:41:53 +0200 Subject: [PATCH 10/24] s4:libcli/raw: remove unused smbcli_session->user_session_key metze --- source4/libcli/raw/libcliraw.h | 2 -- source4/libcli/smb_composite/connect.c | 1 - source4/libcli/smb_composite/sesssetup.c | 14 -------------- 3 files changed, 17 deletions(-) diff --git a/source4/libcli/raw/libcliraw.h b/source4/libcli/raw/libcliraw.h index b269471..a246ade 100644 --- a/source4/libcli/raw/libcliraw.h +++ b/source4/libcli/raw/libcliraw.h @@ -166,8 +166,6 @@ struct smbcli_session { the user to control these for torture testing */ uint16_t flags2; - DATA_BLOB user_session_key; - /* the spnego context if we use extented security */ struct gensec_security *gensec; diff --git a/source4/libcli/smb_composite/connect.c b/source4/libcli/smb_composite/connect.c index 0688684..80ce556 100644 --- a/source4/libcli/smb_composite/connect.c +++ b/source4/libcli/smb_composite/connect.c @@ -163,7 +163,6 @@ static NTSTATUS connect_session_setup(struct composite_context *c, * have been given a uid in the NTLMSSP_CHALLENGE reply. This * would lead to an invalid uid in the anonymous fallback */ state->session->vuid = 0; - data_blob_free(&state->session->user_session_key); talloc_free(state->session->gensec); state->session->gensec = NULL; diff --git a/source4/libcli/smb_composite/sesssetup.c b/source4/libcli/smb_composite/sesssetup.c index fab2ce9..0023013 100644 --- a/source4/libcli/smb_composite/sesssetup.c +++ b/source4/libcli/smb_composite/sesssetup.c @@ -65,17 +65,6 @@ static NTSTATUS session_setup_spnego(struct composite_context *c, struct smbcli_request **req); /* - store the user session key for a transport -*/ -static void set_user_session_key(struct smbcli_session *session, - const DATA_BLOB *session_key) -{ - session->user_session_key = data_blob_talloc(session, - session_key->data, - session_key->length); -} - -/* handler for completion of a smbcli_request sub-request */ static void request_handler(struct smbcli_request *req) @@ -207,7 +196,6 @@ static void request_handler(struct smbcli_request *req) session_key, null_data_blob); } - set_user_session_key(session, &session_key); c->status = smb1cli_session_set_session_key(session->smbXcli, session_key); @@ -350,7 +338,6 @@ static NTSTATUS session_setup_nt1(struct composite_context *c, smb1cli_conn_activate_signing(session->transport->conn, session_key, state->setup.nt1.in.password2); - set_user_session_key(session, &session_key); nt_status = smb1cli_session_set_session_key(session->smbXcli, session_key); @@ -415,7 +402,6 @@ static NTSTATUS session_setup_old(struct composite_context *c, NULL, NULL, &session_key); NT_STATUS_NOT_OK_RETURN(nt_status); - set_user_session_key(session, &session_key); nt_status = smb1cli_session_set_session_key(session->smbXcli, session_key); -- 1.7.9.5 From 4a2efb074e40118f122ee1ee2497ede94c632512 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 10:18:22 +0200 Subject: [PATCH 11/24] s3:rpc_client: make use of smbXcli_session_application_key() metze --- source3/rpc_client/cli_pipe.c | 19 ++++++++++++++++--- 1 file changed, 16 insertions(+), 3 deletions(-) diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index 8b9e513..bd49813 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2862,9 +2862,22 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli, auth->user_name = talloc_strdup(auth, cli->user_name); auth->domain = talloc_strdup(auth, cli->domain); - auth->user_session_key = data_blob_talloc(auth, - cli->user_session_key.data, - cli->user_session_key.length); + + if (transport == NCACN_NP) { + struct smbXcli_session *session; + + if (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_SMB2_02) { + session = cli->smb2.session; + } else { + session = cli->smb1.session; + } + + status = smbXcli_session_application_key(session, auth, + &auth->user_session_key); + if (!NT_STATUS_IS_OK(status)) { + auth->user_session_key = data_blob_null; + } + } if ((auth->user_name == NULL) || (auth->domain == NULL)) { TALLOC_FREE(result); -- 1.7.9.5 From 216186d7f895e9f38c948fab0d4bea0235c85fb9 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 10:30:06 +0200 Subject: [PATCH 12/24] s3:libnet_join: make use of cli_get_session_key() in libnet_join_joindomain_rpc() metze --- source3/libnet/libnet_join.c | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/source3/libnet/libnet_join.c b/source3/libnet/libnet_join.c index c9b2282..399c13a 100644 --- a/source3/libnet/libnet_join.c +++ b/source3/libnet/libnet_join.c @@ -853,6 +853,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, union samr_UserInfo user_info; struct dcerpc_binding_handle *b = NULL; + DATA_BLOB session_key = data_blob_null; struct samr_CryptPassword crypt_pwd; struct samr_CryptPasswordEx crypt_pwd_ex; @@ -888,6 +889,13 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, b = pipe_hnd->binding_handle; + status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", + nt_errstr(status))); + goto done; + } + status = dcerpc_samr_Connect2(b, mem_ctx, pipe_hnd->desthost, SAMR_ACCESS_ENUM_DOMAINS @@ -1064,7 +1072,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, /* Set password on machine account - first try level 26 */ init_samr_CryptPasswordEx(r->in.machine_password, - &cli->user_session_key, + &session_key, &crypt_pwd_ex); user_info.info26.password = crypt_pwd_ex; @@ -1081,7 +1089,7 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, /* retry with level 24 */ init_samr_CryptPassword(r->in.machine_password, - &cli->user_session_key, + &session_key, &crypt_pwd); user_info.info24.password = crypt_pwd; @@ -1125,6 +1133,8 @@ static NTSTATUS libnet_join_joindomain_rpc(TALLOC_CTX *mem_ctx, return status; } + data_blob_clear_free(&session_key); + if (is_valid_policy_hnd(&sam_pol)) { dcerpc_samr_Close(b, mem_ctx, &sam_pol, &result); } -- 1.7.9.5 From f63ecf58d746750048fb295be35473e1be64b41c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 10:48:53 +0200 Subject: [PATCH 13/24] s3:utils/net_rpc*: make use of cli_get_session_key() metze --- source3/utils/net_rpc.c | 11 ++++++++++- source3/utils/net_rpc_join.c | 11 ++++++++++- source3/utils/net_rpc_trust.c | 24 +++++++++++++++++++----- 3 files changed, 39 insertions(+), 7 deletions(-) diff --git a/source3/utils/net_rpc.c b/source3/utils/net_rpc.c index 49b405f..46c3c91 100644 --- a/source3/utils/net_rpc.c +++ b/source3/utils/net_rpc.c @@ -5776,6 +5776,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, union samr_UserInfo info; unsigned int orig_timeout; struct dcerpc_binding_handle *b = pipe_hnd->binding_handle; + DATA_BLOB session_key = data_blob_null; if (argc != 2) { d_printf("%s\n%s", @@ -5797,6 +5798,13 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, init_lsa_String(&lsa_acct_name, acct_name); + status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", + nt_errstr(status))); + goto done; + } + /* Get samr policy handle */ status = dcerpc_samr_Connect2(b, mem_ctx, pipe_hnd->desthost, @@ -5867,7 +5875,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, ZERO_STRUCT(info.info23); init_samr_CryptPassword(argv[1], - &cli->user_session_key, + &session_key, &crypt_pwd); info.info23.info.fields_present = SAMR_FIELD_ACCT_FLAGS | @@ -5894,6 +5902,7 @@ static NTSTATUS rpc_trustdom_add_internals(struct net_context *c, done: SAFE_FREE(acct_name); + data_blob_clear_free(&session_key); return status; } diff --git a/source3/utils/net_rpc_join.c b/source3/utils/net_rpc_join.c index f89ffb8..2e3e240 100644 --- a/source3/utils/net_rpc_join.c +++ b/source3/utils/net_rpc_join.c @@ -186,6 +186,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv) /* Password stuff */ + DATA_BLOB session_key = data_blob_null; char *clear_trust_password = NULL; struct samr_CryptPassword crypt_pwd; uchar md4_trust_password[16]; @@ -289,6 +290,13 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv) b = pipe_hnd->binding_handle; + status = cli_get_session_key(mem_ctx, pipe_hnd, &session_key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Error getting session_key of SAM pipe. Error was %s\n", + nt_errstr(status))); + goto done; + } + CHECK_DCERPC_ERR(dcerpc_samr_Connect2(b, mem_ctx, pipe_hnd->desthost, SAMR_ACCESS_ENUM_DOMAINS @@ -396,7 +404,7 @@ int net_rpc_join_newstyle(struct net_context *c, int argc, const char **argv) /* Set password on machine account */ init_samr_CryptPassword(clear_trust_password, - &cli->user_session_key, + &session_key, &crypt_pwd); set_info.info24.password = crypt_pwd; @@ -532,6 +540,7 @@ done: cli_shutdown(cli); TALLOC_FREE(clear_trust_password); + data_blob_clear_free(&session_key); return retval; } diff --git a/source3/utils/net_rpc_trust.c b/source3/utils/net_rpc_trust.c index 82cc8a5..d15d10c 100644 --- a/source3/utils/net_rpc_trust.c +++ b/source3/utils/net_rpc_trust.c @@ -196,7 +196,8 @@ static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx, struct cli_state **cli, struct rpc_pipe_client **pipe_hnd, struct policy_handle *pol_hnd, - struct dom_data *dom_data) + struct dom_data *dom_data, + DATA_BLOB *session_key) { NTSTATUS status; NTSTATUS result; @@ -244,6 +245,13 @@ static NTSTATUS connect_and_get_info(TALLOC_CTX *mem_ctx, return status; } + status = cli_get_session_key(mem_ctx, *pipe_hnd, session_key); + if (!NT_STATUS_IS_OK(status)) { + DEBUG(0,("Error getting session_key of LSA pipe. Error was %s\n", + nt_errstr(status))); + return status; + } + return NT_STATUS_OK; } @@ -412,6 +420,7 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, int success = -1; struct cli_state *cli[2] = {NULL, NULL}; struct rpc_pipe_client *pipe_hnd[2] = {NULL, NULL}; + DATA_BLOB session_key[2]; struct policy_handle pol_hnd[2]; struct lsa_TrustDomainInfoAuthInfoInternal authinfo; DATA_BLOB auth_blob; @@ -421,6 +430,8 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, struct dom_data dom_data[2]; void (*usage)(void); + ZERO_STRUCT(session_key); + switch (op) { case TRUST_CREATE: usage = print_trust_usage; @@ -480,7 +491,7 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, } status = connect_and_get_info(mem_ctx, net_ctx, &cli[0], &pipe_hnd[0], - &pol_hnd[0], &dom_data[0]); + &pol_hnd[0], &dom_data[0], &session_key[0]); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("connect_and_get_info failed with error [%s]\n", nt_errstr(status))); @@ -490,7 +501,8 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, if (other_net_ctx != NULL) { status = connect_and_get_info(mem_ctx, other_net_ctx, &cli[1], &pipe_hnd[1], - &pol_hnd[1], &dom_data[1]); + &pol_hnd[1], &dom_data[1], + &session_key[1]); if (!NT_STATUS_IS_OK(status)) { DEBUG(0, ("connect_and_get_info failed with error [%s]\n", nt_errstr(status))); @@ -534,7 +546,7 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, arcfour_crypt_blob(authinfo.auth_blob.data, authinfo.auth_blob.size, - &cli[0]->user_session_key); + &session_key[0]); status = create_trust(mem_ctx, pipe_hnd[0]->binding_handle, &pol_hnd[0], @@ -561,7 +573,7 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, arcfour_crypt_blob(authinfo.auth_blob.data, authinfo.auth_blob.size, - &cli[1]->user_session_key); + &session_key[1]); status = create_trust(mem_ctx, pipe_hnd[1]->binding_handle, @@ -617,6 +629,8 @@ static int rpc_trust_common(struct net_context *net_ctx, int argc, success = 0; done: + data_blob_clear_free(&session_key[0]); + data_blob_clear_free(&session_key[1]); cli_shutdown(cli[0]); cli_shutdown(cli[1]); talloc_destroy(mem_ctx); -- 1.7.9.5 From 07ae57493c9588686e2cb81db79365ab434a7a21 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 10:50:30 +0200 Subject: [PATCH 14/24] s3:libsmb: remove unused cli_state->user_session_key metze --- source3/include/client.h | 4 ---- source3/libsmb/cliconnect.c | 19 ------------------- source3/libsmb/clientgen.c | 2 -- 3 files changed, 25 deletions(-) diff --git a/source3/include/client.h b/source3/include/client.h index 748f78e..f6aacea 100644 --- a/source3/include/client.h +++ b/source3/include/client.h @@ -77,10 +77,6 @@ struct cli_state { bool dfsroot; bool backup_intent; - /* the session key for this CLI, outside - any per-pipe authenticaion */ - DATA_BLOB user_session_key; - /* The list of pipes currently open on this connection. */ struct rpc_pipe_client *pipe_list; diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index ea7ddfe..85f7fd9 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -72,18 +72,6 @@ static NTSTATUS smb_bytes_talloc_string(TALLOC_CTX *mem_ctx, return NT_STATUS_OK; } -/** - * Set the user session key for a connection - * @param cli The cli structure to add it too - * @param session_key The session key used. (A copy of this is taken for the cli struct) - * - */ - -static void cli_set_session_key (struct cli_state *cli, const DATA_BLOB session_key) -{ - cli->user_session_key = data_blob(session_key.data, session_key.length); -} - /**************************************************************************** Do an old lanman2 style session setup. ****************************************************************************/ @@ -1094,9 +1082,6 @@ static void cli_session_setup_nt1_done(struct tevent_req *subreq) if (state->session_key.data) { struct smbXcli_session *session = state->cli->smb1.session; - /* Have plaintext orginal */ - cli_set_session_key(cli, state->session_key); - status = smb1cli_session_set_session_key(session, state->session_key); if (tevent_req_nterror(req, status)) { @@ -1525,8 +1510,6 @@ static void cli_session_setup_kerberos_done(struct tevent_req *subreq) return; } - cli_set_session_key(state->cli, state->session_key_krb5); - if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { struct smbXcli_session *session = state->cli->smb2.session; status = smb2cli_session_set_session_key(session, @@ -1727,8 +1710,6 @@ static void cli_session_setup_ntlmssp_done(struct tevent_req *subreq) return; } } - cli_set_session_key( - state->cli, state->ntlmssp_state->session_key); if (smbXcli_conn_protocol(state->cli->conn) >= PROTOCOL_SMB2_02) { struct smbXcli_session *session = state->cli->smb2.session; diff --git a/source3/libsmb/clientgen.c b/source3/libsmb/clientgen.c index ae0350b..31af1e7 100644 --- a/source3/libsmb/clientgen.c +++ b/source3/libsmb/clientgen.c @@ -325,8 +325,6 @@ static void _cli_shutdown(struct cli_state *cli) if (cli_state_has_tcon(cli)) { cli_tdis(cli); } - - data_blob_free(&cli->user_session_key); smbXcli_conn_disconnect(cli->conn, NT_STATUS_OK); -- 1.7.9.5 From 478e9123e55fbf90b39bfb74f10b50c8a4ad04a2 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:00:02 +0200 Subject: [PATCH 15/24] s3:rpc_client: rename pipe_auth_data->user_session_key to transport_session_key metze --- source3/librpc/rpc/dcerpc.h | 2 +- source3/rpc_client/cli_pipe.c | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/source3/librpc/rpc/dcerpc.h b/source3/librpc/rpc/dcerpc.h index a91b06e..b3ae3b4 100644 --- a/source3/librpc/rpc/dcerpc.h +++ b/source3/librpc/rpc/dcerpc.h @@ -45,7 +45,7 @@ struct pipe_auth_data { /* Only the client code uses these 3 for now */ char *domain; char *user_name; - DATA_BLOB user_session_key; + DATA_BLOB transport_session_key; }; /* The following definitions come from librpc/rpc/dcerpc_helpers.c */ diff --git a/source3/rpc_client/cli_pipe.c b/source3/rpc_client/cli_pipe.c index bd49813..edb3876 100644 --- a/source3/rpc_client/cli_pipe.c +++ b/source3/rpc_client/cli_pipe.c @@ -2873,9 +2873,9 @@ NTSTATUS cli_rpc_pipe_open_noauth_transport(struct cli_state *cli, } status = smbXcli_session_application_key(session, auth, - &auth->user_session_key); + &auth->transport_session_key); if (!NT_STATUS_IS_OK(status)) { - auth->user_session_key = data_blob_null; + auth->transport_session_key = data_blob_null; } } @@ -3147,8 +3147,8 @@ NTSTATUS cli_get_session_key(TALLOC_CTX *mem_ctx, break; case DCERPC_AUTH_TYPE_NCALRPC_AS_SYSTEM: case DCERPC_AUTH_TYPE_NONE: - sk = data_blob_const(a->user_session_key.data, - a->user_session_key.length); + sk = data_blob_const(a->transport_session_key.data, + a->transport_session_key.length); make_dup = true; break; default: -- 1.7.9.5 From 7a86a711fd9270ab95d24a2388b6aa01a7337b05 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:33:27 +0200 Subject: [PATCH 16/24] libcli/smb: move some TCON related defines to smb_constants.h metze --- libcli/smb/smb_constants.h | 13 +++++++++++++ source3/include/smb.h | 9 --------- source4/libcli/raw/smb.h | 4 ---- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/libcli/smb/smb_constants.h b/libcli/smb/smb_constants.h index aaf87c1..8cb3b6e 100644 --- a/libcli/smb/smb_constants.h +++ b/libcli/smb/smb_constants.h @@ -262,6 +262,19 @@ enum csc_policy { CSC_POLICY_DISABLE=3 }; +/* TCONX Flag (smb_vwv2). [MS-SMB] 2.2.4.7.1 */ +#define TCONX_FLAG_DISCONNECT_TID 0x0001 +#define TCONX_FLAG_EXTENDED_SIGNATURES 0x0004 +#define TCONX_FLAG_EXTENDED_RESPONSE 0x0008 + +/* this is used on a TConX. [MS-SMB] 2.2.4.7.2 */ +#define SMB_SUPPORT_SEARCH_BITS 0x0001 +#define SMB_SHARE_IN_DFS 0x0002 +#define SMB_CSC_MASK 0x000C +#define SMB_CSC_POLICY_SHIFT 2 +#define SMB_UNIQUE_FILE_NAME 0x0010 +#define SMB_EXTENDED_SIGNATURES 0x0020 + /* NT Flags2 bits - cifs6.txt section 3.1.2 */ #define FLAGS2_LONG_PATH_COMPONENTS 0x0001 #define FLAGS2_EXTENDED_ATTRIBUTES 0x0002 diff --git a/source3/include/smb.h b/source3/include/smb.h index 310cbbb..c6e6fb3 100644 --- a/source3/include/smb.h +++ b/source3/include/smb.h @@ -399,10 +399,6 @@ Offset Data length. #define smb_ntcreate_ImpersonationLevel (smb_vwv0 + 43) #define smb_ntcreate_SecurityFlags (smb_vwv0 + 47) -/* this is used on a TConX. I'm not sure the name is very helpful though */ -#define SMB_SUPPORT_SEARCH_BITS 0x0001 -#define SMB_SHARE_IN_DFS 0x0002 - /* Named pipe write mode flags. Used in writeX calls. */ #define PIPE_RAW_MODE 0x4 #define PIPE_START_MESSAGE 0x8 @@ -621,11 +617,6 @@ char *strdup(char *s); #define BROWSER_ELECTION_VERSION 0x010f #define BROWSER_CONSTANT 0xaa55 -/* TCONX Flag (smb_vwv2). */ -#define TCONX_FLAG_EXTENDED_RESPONSE 0x8 -#define TCONX_FLAG_EXTENDED_SIGNATURES 0x4 -#define SMB_EXTENDED_SIGNATURES 0x20 - /* File Status Flags. See: http://msdn.microsoft.com/en-us/library/cc246334(PROT.13).aspx diff --git a/source4/libcli/raw/smb.h b/source4/libcli/raw/smb.h index be1bfdb..279ada1 100644 --- a/source4/libcli/raw/smb.h +++ b/source4/libcli/raw/smb.h @@ -219,10 +219,6 @@ #define NT_TRANSACT_RENAME 5 #define NT_TRANSACT_QUERY_SECURITY_DESC 6 -/* this is used on a TConX. I'm not sure the name is very helpful though */ -#define SMB_SUPPORT_SEARCH_BITS 0x0001 -#define SMB_SHARE_IN_DFS 0x0002 - /* Named pipe write mode flags. Used in writeX calls. */ #define PIPE_RAW_MODE 0x4 #define PIPE_START_MESSAGE 0x8 -- 1.7.9.5 From 4f9528edbd6ccacbf5917649d1e55c5be0300586 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:45:36 +0200 Subject: [PATCH 17/24] s3:libsmb: add a tcon_flags helper variable metze --- source3/libsmb/cliconnect.c | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 85f7fd9..2b32529 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2255,6 +2255,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, char *tmp = NULL; uint8_t *bytes; uint16_t sec_mode = smb1cli_conn_server_security_mode(cli->conn); + uint16_t tcon_flags = 0; *psmbreq = NULL; @@ -2330,10 +2331,12 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, } } + tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE; + SCVAL(vwv+0, 0, 0xFF); SCVAL(vwv+0, 1, 0); SSVAL(vwv+1, 0, 0); - SSVAL(vwv+2, 0, TCONX_FLAG_EXTENDED_RESPONSE); + SSVAL(vwv+2, 0, tcon_flags); SSVAL(vwv+3, 0, passlen); if (passlen && pass) { -- 1.7.9.5 From 44118a6a920bb4b7f5c2ca7bcc80f0d7beb21a12 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:46:22 +0200 Subject: [PATCH 18/24] s3:libsmb: add a optional_support helper variable metze --- source3/libsmb/cliconnect.c | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 2b32529..9850511 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2431,6 +2431,7 @@ static void cli_tcon_andx_done(struct tevent_req *subreq) uint32_t num_bytes; uint8_t *bytes; NTSTATUS status; + uint16_t optional_support = 0; status = cli_smb_recv(subreq, state, &in, 0, &wct, &vwv, &num_bytes, &bytes); @@ -2474,7 +2475,11 @@ static void cli_tcon_andx_done(struct tevent_req *subreq) cli->dfsroot = false; if ((wct > 2) && (smbXcli_conn_protocol(cli->conn) >= PROTOCOL_LANMAN2)) { - cli->dfsroot = ((SVAL(vwv+2, 0) & SMB_SHARE_IN_DFS) != 0); + optional_support = SVAL(vwv+2, 0); + } + + if (optional_support & SMB_SHARE_IN_DFS) { + cli->dfsroot = true; } cli_state_set_tid(cli, SVAL(inhdr, HDR_TID)); -- 1.7.9.5 From b9aac97680738d6646977986720e7012dfc0e091 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:48:30 +0200 Subject: [PATCH 19/24] s3:smbd: make use of TCONX_FLAG_DISCONNECT_TID define metze --- source3/smbd/reply.c | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index c043bb6..dfb279d 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -736,7 +736,7 @@ void reply_tcon_and_X(struct smb_request *req) tcon_flags = SVAL(req->vwv+2, 0); /* we might have to close an old one */ - if ((tcon_flags & 0x1) && conn) { + if ((tcon_flags & TCONX_FLAG_DISCONNECT_TID) && conn) { struct smbXsrv_tcon *tcon; NTSTATUS status; -- 1.7.9.5 From 72aab2dceb6eba6c781bb751f759ea6b7f823e2a Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 12:01:07 +0200 Subject: [PATCH 20/24] s3:smbd: add a optional_support helper variable to reply_tcon_and_X() metze --- source3/smbd/reply.c | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index dfb279d..a893380 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -840,6 +840,7 @@ void reply_tcon_and_X(struct smb_request *req) } else { /* NT sets the fstype of IPC$ to the null string */ const char *fstype = IS_IPC(conn) ? "" : lp_fstype(ctx, SNUM(conn)); + uint16_t optional_support = 0; if (tcon_flags & TCONX_FLAG_EXTENDED_RESPONSE) { /* Return permissions. */ @@ -872,15 +873,17 @@ void reply_tcon_and_X(struct smb_request *req) /* what does setting this bit do? It is set by NT4 and may affect the ability to autorun mounted cdroms */ - SSVAL(req->outbuf, smb_vwv2, SMB_SUPPORT_SEARCH_BITS| - (lp_csc_policy(SNUM(conn)) << 2)); + optional_support |= SMB_SUPPORT_SEARCH_BITS; + optional_support |= + (lp_csc_policy(SNUM(conn)) << SMB_CSC_POLICY_SHIFT); if (lp_msdfs_root(SNUM(conn)) && lp_host_msdfs()) { DEBUG(2,("Serving %s as a Dfs root\n", lp_servicename(ctx, SNUM(conn)) )); - SSVAL(req->outbuf, smb_vwv2, - SMB_SHARE_IN_DFS | SVAL(req->outbuf, smb_vwv2)); + optional_support |= SMB_SHARE_IN_DFS; } + + SSVAL(req->outbuf, smb_vwv2, optional_support); } SSVAL(req->outbuf, smb_vwv0, 0xff); /* andx chain ends */ -- 1.7.9.5 From f4c02681fc3a5f7bc7c3b9782d4871a3a2182742 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:28:06 +0200 Subject: [PATCH 21/24] TODO testing libcli/smb: add smb_key_derivation() for TREE_CONNECT_ANDX_EXTENDED_SIGNATURES support metze --- libcli/smb/smb_signing.c | 48 +++++++++++++++++++++++++++++++++++++++++++++- libcli/smb/smb_signing.h | 2 ++ 2 files changed, 49 insertions(+), 1 deletion(-) diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c index a72760b..2565c29 100644 --- a/libcli/smb/smb_signing.c +++ b/libcli/smb/smb_signing.c @@ -20,7 +20,7 @@ */ #include "includes.h" -#include "../lib/crypto/md5.h" +#include "../lib/crypto/crypto.h" #include "smb_common.h" #include "smb_signing.h" @@ -452,3 +452,49 @@ bool smb_signing_is_negotiated(struct smb_signing_state *si) { return si->negotiated; } + +void smb_key_derivation(const uint8_t *KI, size_t KI_len, + uint8_t KO[16]) +{ + static const uint8_t SSKeyHash[256] = { + 0x53, 0x65, 0x63, 0x75, 0x72, 0x69, 0x74, 0x79, + 0x20, 0x53, 0x69, 0x67, 0x6e, 0x61, 0x74, 0x75, + 0x72, 0x65, 0x20, 0x4b, 0x65, 0x79, 0x20, 0x55, + 0x70, 0x67, 0x72, 0x61, 0x64, 0x65, 0x79, 0x07, + 0x6e, 0x28, 0x2e, 0x69, 0x88, 0x10, 0xb3, 0xdb, + 0x01, 0x55, 0x72, 0xfb, 0x74, 0x14, 0xfb, 0xc4, + 0xc5, 0xaf, 0x3b, 0x41, 0x65, 0x32, 0x17, 0xba, + 0xa3, 0x29, 0x08, 0xc1, 0xde, 0x16, 0x61, 0x7e, + 0x66, 0x98, 0xa4, 0x0b, 0xfe, 0x06, 0x83, 0x53, + 0x4d, 0x05, 0xdf, 0x6d, 0xa7, 0x51, 0x10, 0x73, + 0xc5, 0x50, 0xdc, 0x5e, 0xf8, 0x21, 0x46, 0xaa, + 0x96, 0x14, 0x33, 0xd7, 0x52, 0xeb, 0xaf, 0x1f, + 0xbf, 0x36, 0x6c, 0xfc, 0xb7, 0x1d, 0x21, 0x19, + 0x81, 0xd0, 0x6b, 0xfa, 0x77, 0xad, 0xbe, 0x18, + 0x78, 0xcf, 0x10, 0xbd, 0xd8, 0x78, 0xf7, 0xd3, + 0xc6, 0xdf, 0x43, 0x32, 0x19, 0xd3, 0x9b, 0xa8, + 0x4d, 0x9e, 0xaa, 0x41, 0xaf, 0xcb, 0xc6, 0xb9, + 0x34, 0xe7, 0x48, 0x25, 0xd4, 0x88, 0xc4, 0x51, + 0x60, 0x38, 0xd9, 0x62, 0xe8, 0x8d, 0x5b, 0x83, + 0x92, 0x7f, 0xb5, 0x0e, 0x1c, 0x2d, 0x06, 0x91, + 0xc3, 0x75, 0xb3, 0xcc, 0xf8, 0xf7, 0x92, 0x91, + 0x0b, 0x3d, 0xa1, 0x10, 0x5b, 0xd5, 0x0f, 0xa8, + 0x3f, 0x5d, 0x13, 0x83, 0x0a, 0x6b, 0x72, 0x93, + 0x14, 0x59, 0xd5, 0xab, 0xde, 0x26, 0x15, 0x6d, + 0x60, 0x67, 0x71, 0x06, 0x6e, 0x3d, 0x0d, 0xa7, + 0xcb, 0x70, 0xe9, 0x08, 0x5c, 0x99, 0xfa, 0x0a, + 0x5f, 0x3d, 0x44, 0xa3, 0x8b, 0xc0, 0x8d, 0xda, + 0xe2, 0x68, 0xd0, 0x0d, 0xcd, 0x7f, 0x3d, 0xf8, + 0x73, 0x7e, 0x35, 0x7f, 0x07, 0x02, 0x0a, 0xb5, + 0xe9, 0xb7, 0x87, 0xfb, 0xa1, 0xbf, 0xcb, 0x32, + 0x31, 0x66, 0x09, 0x48, 0x88, 0xcc, 0x18, 0xa3, + 0xb2, 0x1f, 0x1f, 0x1b, 0x90, 0x4e, 0xd7, 0xe1 + }; + HMACMD5Context ctx; + + hmac_md5_init_limK_to_64(KI, KI_len, &ctx); + hmac_md5_update(SSKeyHash, sizeof(SSKeyHash), &ctx); + hmac_md5_final(KO, &ctx); + + ZERO_STRUCT(ctx); +} diff --git a/libcli/smb/smb_signing.h b/libcli/smb/smb_signing.h index b5deec6..6c01ae6 100644 --- a/libcli/smb/smb_signing.h +++ b/libcli/smb/smb_signing.h @@ -49,5 +49,7 @@ bool smb_signing_is_mandatory(struct smb_signing_state *si); bool smb_signing_set_negotiated(struct smb_signing_state *si, bool allowed, bool mandatory); bool smb_signing_is_negotiated(struct smb_signing_state *si); +void smb_key_derivation(const uint8_t *KI, size_t KI_len, + uint8_t KO[16]); #endif /* _SMB_SIGNING_H_ */ -- 1.7.9.5 From 6900741fa3fcc37b0336b3f50bae9bca1c0d893c Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 09:01:25 +0200 Subject: [PATCH 22/24] TODO testing libcli/smb: add smb1cli_session_protect_session_key() metze --- libcli/smb/smbXcli_base.c | 23 +++++++++++++++++++++++ libcli/smb/smbXcli_base.h | 1 + 2 files changed, 24 insertions(+) diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c index d6fbafc..ebfb81a 100644 --- a/libcli/smb/smbXcli_base.c +++ b/libcli/smb/smbXcli_base.c @@ -149,6 +149,7 @@ struct smbXcli_session { struct { uint16_t session_id; DATA_BLOB application_key; + bool protected_key; } smb1; struct smb2cli_session *smb2; @@ -4365,6 +4366,28 @@ NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session, return NT_STATUS_NO_MEMORY; } + session->smb1.protected_key = false; + + return NT_STATUS_OK; +} + +NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session) +{ + if (session->smb1.protected_key) { + /* already protected */ + return NT_STATUS_OK; + } + + if (session->smb1.application_key.length != 16) { + return NT_STATUS_INVALID_PARAMETER_MIX; + } + + smb_key_derivation(session->smb1.application_key.data, + session->smb1.application_key.length, + session->smb1.application_key.data); + + session->smb1.protected_key = true; + return NT_STATUS_OK; } diff --git a/libcli/smb/smbXcli_base.h b/libcli/smb/smbXcli_base.h index 3f78cd5..689369e 100644 --- a/libcli/smb/smbXcli_base.h +++ b/libcli/smb/smbXcli_base.h @@ -256,6 +256,7 @@ void smb1cli_session_set_id(struct smbXcli_session* session, uint16_t session_id); NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session, const DATA_BLOB _session_key); +NTSTATUS smb1cli_session_protect_session_key(struct smbXcli_session *session); uint8_t smb2cli_session_security_mode(struct smbXcli_session *session); uint64_t smb2cli_session_current_id(struct smbXcli_session *session); uint16_t smb2cli_session_get_flags(struct smbXcli_session *session); -- 1.7.9.5 From 69e976624a2c7f037a42b5ebeedc11b787d06e61 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 11:47:07 +0200 Subject: [PATCH 23/24] TODO testing s3:libsmb: add EXTENDED_SIGNATURE support in cli_tcon_andx*() metze --- source3/libsmb/cliconnect.c | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/source3/libsmb/cliconnect.c b/source3/libsmb/cliconnect.c index 9850511..cd914bf 100644 --- a/source3/libsmb/cliconnect.c +++ b/source3/libsmb/cliconnect.c @@ -2332,6 +2332,7 @@ struct tevent_req *cli_tcon_andx_create(TALLOC_CTX *mem_ctx, } tcon_flags |= TCONX_FLAG_EXTENDED_RESPONSE; + tcon_flags |= TCONX_FLAG_EXTENDED_SIGNATURES; SCVAL(vwv+0, 0, 0xFF); SCVAL(vwv+0, 1, 0); @@ -2482,6 +2483,10 @@ static void cli_tcon_andx_done(struct tevent_req *subreq) cli->dfsroot = true; } + if (optional_support & SMB_EXTENDED_SIGNATURES) { + smb1cli_session_protect_session_key(cli->smb1.session); + } + cli_state_set_tid(cli, SVAL(inhdr, HDR_TID)); tevent_req_done(req); } -- 1.7.9.5 From dee705fa856ebd06b23ac4ace20cc0805f65e256 Mon Sep 17 00:00:00 2001 From: Stefan Metzmacher Date: Wed, 1 Aug 2012 12:03:12 +0200 Subject: [PATCH 24/24] TODO: s3:smbd: implement SMB_EXTENDED_SIGNATURES in reply_tcon_and_X() metze --- source3/smbd/reply.c | 19 +++++++++++++++++++ 1 file changed, 19 insertions(+) diff --git a/source3/smbd/reply.c b/source3/smbd/reply.c index a893380..c8df73f 100644 --- a/source3/smbd/reply.c +++ b/source3/smbd/reply.c @@ -883,6 +883,25 @@ void reply_tcon_and_X(struct smb_request *req) optional_support |= SMB_SHARE_IN_DFS; } + if (tcon_flags & TCONX_FLAG_EXTENDED_SIGNATURES) { + // DATA_BLOB *application_key = NULL; + // TODO: protect application key + // + // We have a key in a lot of places... + // (This is a mess...) + // + // req->conn->session_info + // in the vuid cache of the connection_struct + // and in smbXsrv_session->global->auth_session_info + // and later maybe in + // smbXsrv_session->global->application_key + // + // smb_key_derivation(application_key->data, + // application_key->length, + // application_key->data); + // optional_support |= SMB_EXTENDED_SIGNATURES; + } + SSVAL(req->outbuf, smb_vwv2, optional_support); } -- 1.7.9.5