[SCM] Samba Shared Repository - branch master updated
Stefan Metzmacher
metze at samba.org
Sat Aug 4 03:10:02 MDT 2012
The branch, master has been updated
via 49d0432 s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session setups
via 2265e46 s3:smbd: setup session->global->signing_/application_key during old SMB1 session setups
via 3d63e4d s3:smbd: keep the "application session key" during SMB1 reauth
via ba864b8 s4:torture: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
via 67767de s4:libcli: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
via c32120b s3:libsmb: add EXTENDED_SIGNATURE support in cli_tcon_andx*()
via 97be49c libcli/smb: add smb1cli_session_protect_session_key()
via dbefd7d libcli/smb: add smb_key_derivation() for TREE_CONNECT_ANDX_EXTENDED_SIGNATURES support
via b1a0fda libcli/smb: pass hdr/len to smb_signing_check/sign_pdu() and skip the nbt header
via b1c5efb s3:smbd: skip nbt header in srv_check_sign_mac()
via d88a6c1 libcli/smb: change smb_signing to skip the NBT_HEADER_SIZE internally
via e8f4868 auth/ntlmssp: avoid talloc_tos() in ntlmssp_client_initial()
from 764f2f9 s3-ctdb: return proper exit code
http://gitweb.samba.org/?p=samba.git;a=shortlog;h=master
- Log -----------------------------------------------------------------
commit 49d0432efd84ef2e4bcaa85d4aad11c18d947db1
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 2 18:47:48 2012 +0200
s3:smbd: setup session->global->signing_/application_key during SPNEGO SMB1 session setups
metze
Autobuild-User(master): Stefan Metzmacher <metze at samba.org>
Autobuild-Date(master): Sat Aug 4 11:09:42 CEST 2012 on sn-devel-104
commit 2265e4633a5b37ded755f6c964cb4d3a6f67a350
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 2 18:47:48 2012 +0200
s3:smbd: setup session->global->signing_/application_key during old SMB1 session setups
metze
commit 3d63e4da170881f4d0381bf9e01e0ceab10c2a90
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 2 18:46:09 2012 +0200
s3:smbd: keep the "application session key" during SMB1 reauth
metze
commit ba864b83fa43062a684204cbaf9bf1b0c2074533
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 2 08:51:13 2012 +0200
s4:torture: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
metze
commit 67767de4e9e4a3a2cac1f28b590398bd587467da
Author: Stefan Metzmacher <metze at samba.org>
Date: Thu Aug 2 08:51:13 2012 +0200
s4:libcli: add support for SMB_EXTENDED_SIGNATURES during SMBtconX
metze
commit c32120b4e93a565c12534b7614becdf573672586
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 1 11:47:07 2012 +0200
s3:libsmb: add EXTENDED_SIGNATURE support in cli_tcon_andx*()
metze
commit 97be49c4d42bbc84a85383db0d5c6cf14fd077da
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 1 09:01:25 2012 +0200
libcli/smb: add smb1cli_session_protect_session_key()
metze
commit dbefd7d194cc05a793a480740e9e29558ff95ad3
Author: Stefan Metzmacher <metze at samba.org>
Date: Wed Aug 1 09:28:06 2012 +0200
libcli/smb: add smb_key_derivation() for TREE_CONNECT_ANDX_EXTENDED_SIGNATURES support
metze
commit b1a0fda73d13587fd63682bc8e47f6862289f66d
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Aug 3 09:58:29 2012 +0200
libcli/smb: pass hdr/len to smb_signing_check/sign_pdu() and skip the nbt header
metze
commit b1c5efbfeab2b597d8b7878fbe47afb2d9786f10
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Aug 3 09:57:19 2012 +0200
s3:smbd: skip nbt header in srv_check_sign_mac()
metze
commit d88a6c1dc3bb90b5ac82e09eb1c96df434f6ce69
Author: Stefan Metzmacher <metze at samba.org>
Date: Fri Aug 3 09:29:20 2012 +0200
libcli/smb: change smb_signing to skip the NBT_HEADER_SIZE internally
metze
commit e8f486883fb13c1e5bb9cb63196f798370b4abb8
Author: Stefan Metzmacher <metze at samba.org>
Date: Sat Aug 4 09:07:24 2012 +0200
auth/ntlmssp: avoid talloc_tos() in ntlmssp_client_initial()
This avoids a smb_panic at log level = 10.
If we don't have a talloc stackframe yet.
metze
-----------------------------------------------------------------------
Summary of changes:
auth/ntlmssp/ntlmssp_client.c | 2 +-
libcli/smb/smbXcli_base.c | 50 ++++++++++--
libcli/smb/smbXcli_base.h | 1 +
libcli/smb/smb_signing.c | 93 +++++++++++++++++-----
libcli/smb/smb_signing.h | 8 ++-
source3/libsmb/cliconnect.c | 5 +
source3/smbd/sesssetup.c | 135 ++++++++++++++++++++++++++++++--
source3/smbd/signing.c | 24 ++++--
source4/libcli/cliconnect.c | 6 ++
source4/libcli/smb_composite/connect.c | 6 ++
source4/libcli/util/clilsa.c | 6 ++
source4/torture/rpc/samba3rpc.c | 7 ++
source4/torture/util_smb.c | 8 ++-
13 files changed, 304 insertions(+), 47 deletions(-)
Changeset truncated at 500 lines:
diff --git a/auth/ntlmssp/ntlmssp_client.c b/auth/ntlmssp/ntlmssp_client.c
index f51a1ed..fc66a8d 100644
--- a/auth/ntlmssp/ntlmssp_client.c
+++ b/auth/ntlmssp/ntlmssp_client.c
@@ -96,7 +96,7 @@ NTSTATUS ntlmssp_client_initial(struct gensec_security *gensec_security,
if (DEBUGLEVEL >= 10) {
struct NEGOTIATE_MESSAGE *negotiate = talloc(
- talloc_tos(), struct NEGOTIATE_MESSAGE);
+ ntlmssp_state, struct NEGOTIATE_MESSAGE);
if (negotiate != NULL) {
status = ntlmssp_pull_NEGOTIATE_MESSAGE(
out, negotiate, negotiate);
diff --git a/libcli/smb/smbXcli_base.c b/libcli/smb/smbXcli_base.c
index 37c738e..c6e3b2a 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;
@@ -633,7 +634,10 @@ bool smb1cli_conn_activate_signing(struct smbXcli_conn *conn,
bool smb1cli_conn_check_signing(struct smbXcli_conn *conn,
const uint8_t *buf, uint32_t seqnum)
{
- return smb_signing_check_pdu(conn->smb1.signing, buf, seqnum);
+ const uint8_t *hdr = buf + NBT_HDR_SIZE;
+ size_t len = smb_len_nbt(buf);
+
+ return smb_signing_check_pdu(conn->smb1.signing, hdr, len, seqnum);
}
bool smb1cli_conn_signing_is_active(struct smbXcli_conn *conn)
@@ -1339,15 +1343,17 @@ static NTSTATUS smb1cli_conn_signv(struct smbXcli_conn *conn,
frame = talloc_stackframe();
- buf = smbXcli_iov_concat(frame, iov, iov_count);
+ buf = smbXcli_iov_concat(frame, &iov[1], iov_count - 1);
if (buf == NULL) {
return NT_STATUS_NO_MEMORY;
}
*seqnum = smb_signing_next_seqnum(conn->smb1.signing,
one_way_seqnum);
- smb_signing_sign_pdu(conn->smb1.signing, buf, *seqnum);
- memcpy(iov[1].iov_base, buf+4, iov[1].iov_len);
+ smb_signing_sign_pdu(conn->smb1.signing,
+ buf, talloc_get_size(buf),
+ *seqnum);
+ memcpy(iov[1].iov_base, buf, iov[1].iov_len);
TALLOC_FREE(frame);
return NT_STATUS_OK;
@@ -1776,7 +1782,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
uint8_t cmd;
uint16_t mid;
bool oplock_break;
- const uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+ uint8_t *inhdr = inbuf + NBT_HDR_SIZE;
+ size_t len = smb_len_nbt(inbuf);
struct iovec *iov = NULL;
int num_iov = 0;
struct tevent_req **chain = NULL;
@@ -1804,8 +1811,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
}
}
- state->smb1.recv_iov[0].iov_base = (void *)(inbuf + NBT_HDR_SIZE);
- state->smb1.recv_iov[0].iov_len = smb_len_nbt(inbuf);
+ state->smb1.recv_iov[0].iov_base = (void *)(inhdr);
+ state->smb1.recv_iov[0].iov_len = len;
ZERO_STRUCT(state->smb1.recv_iov[1]);
ZERO_STRUCT(state->smb1.recv_iov[2]);
@@ -1852,6 +1859,8 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
nt_errstr(status)));
return status;
}
+ inhdr = inbuf + NBT_HDR_SIZE;
+ len = smb_len_nbt(inbuf);
}
mid = SVAL(inhdr, HDR_MID);
@@ -1873,7 +1882,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
/*
* Paranoia checks that this is really an oplock break request.
*/
- oplock_break = (smb_len_nbt(inbuf) == 51); /* hdr + 8 words */
+ oplock_break = (len == 51); /* hdr + 8 words */
oplock_break &= ((CVAL(inhdr, HDR_FLG) & FLAG_REPLY) == 0);
oplock_break &= (CVAL(inhdr, HDR_COM) == SMBlockingX);
oplock_break &= (SVAL(inhdr, HDR_VWV+VWV(6)) == 0);
@@ -1890,7 +1899,7 @@ static NTSTATUS smb1cli_conn_dispatch_incoming(struct smbXcli_conn *conn,
if (!oplock_break /* oplock breaks are not signed */
&& !smb_signing_check_pdu(conn->smb1.signing,
- inbuf, state->smb1.seqnum+1)) {
+ inhdr, len, state->smb1.seqnum+1)) {
DEBUG(10, ("cli_check_sign_mac failed\n"));
return NT_STATUS_ACCESS_DENIED;
}
@@ -4352,6 +4361,7 @@ NTSTATUS smb1cli_session_set_session_key(struct smbXcli_session *session,
* return NT_STATUS_INVALID_PARAMETER_MIX;
*/
data_blob_clear_free(&session->smb1.application_key);
+ session->smb1.protected_key = false;
}
if (_session_key.length == 0) {
@@ -4370,6 +4380,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);
diff --git a/libcli/smb/smb_signing.c b/libcli/smb/smb_signing.c
index a72760b..95c9c27 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"
@@ -140,10 +140,11 @@ static bool smb_signing_good(struct smb_signing_state *si,
}
static void smb_signing_md5(const DATA_BLOB *mac_key,
- const uint8_t *buf, uint32_t seq_number,
+ const uint8_t *hdr, size_t len,
+ uint32_t seq_number,
uint8_t calc_md5_mac[16])
{
- const size_t offset_end_of_sig = (NBT_HDR_SIZE + HDR_SS_FIELD + 8);
+ const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
uint8_t sequence_buf[8];
struct MD5Context md5_ctx;
@@ -170,14 +171,14 @@ static void smb_signing_md5(const DATA_BLOB *mac_key,
MD5Update(&md5_ctx, mac_key->data, mac_key->length);
/* copy in the first bit of the SMB header */
- MD5Update(&md5_ctx, buf + NBT_HDR_SIZE, HDR_SS_FIELD);
+ MD5Update(&md5_ctx, hdr, HDR_SS_FIELD);
/* copy in the sequence number, instead of the signature */
MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
/* copy in the rest of the packet in, skipping the signature */
- MD5Update(&md5_ctx, buf + offset_end_of_sig,
- smb_len_nbt(buf) - (offset_end_of_sig - 4));
+ MD5Update(&md5_ctx, hdr + offset_end_of_sig,
+ len - (offset_end_of_sig));
/* calculate the MD5 sig */
MD5Final(calc_md5_mac, &md5_ctx);
@@ -215,7 +216,8 @@ void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway)
}
void smb_signing_sign_pdu(struct smb_signing_state *si,
- uint8_t *outbuf, uint32_t seqnum)
+ uint8_t *outhdr, size_t len,
+ uint32_t seqnum)
{
uint8_t calc_md5_mac[16];
uint8_t com;
@@ -228,18 +230,18 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
}
/* JRA Paranioa test - we should be able to get rid of this... */
- if (smb_len_nbt(outbuf) < (HDR_SS_FIELD + 8)) {
+ if (len < (HDR_SS_FIELD + 8)) {
DEBUG(1,("smb_signing_sign_pdu: Logic error. "
"Can't check signature on short packet! smb_len = %u\n",
- smb_len_nbt(outbuf)));
+ (unsigned)len));
abort();
}
- com = SVAL(outbuf,NBT_HDR_SIZE+HDR_COM);
- flags = SVAL(outbuf,NBT_HDR_SIZE+HDR_FLG);
+ com = SVAL(outhdr, HDR_COM);
+ flags = SVAL(outhdr, HDR_FLG);
if (!(flags & FLAG_REPLY)) {
- uint16_t flags2 = SVAL(outbuf,NBT_HDR_SIZE+HDR_FLG2);
+ uint16_t flags2 = SVAL(outhdr, HDR_FLG2);
/*
* If this is a request, specify what is
* supported or required by the client
@@ -250,7 +252,7 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
if (si->negotiated && si->mandatory) {
flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES_REQUIRED;
}
- SSVAL(outbuf, NBT_HDR_SIZE+HDR_FLG2, flags2);
+ SSVAL(outhdr, HDR_FLG2, flags2);
}
if (si->mac_key.length == 0) {
@@ -262,21 +264,22 @@ void smb_signing_sign_pdu(struct smb_signing_state *si,
memset(calc_md5_mac, 0, 8);
}
} else {
- smb_signing_md5(&si->mac_key, outbuf,
+ smb_signing_md5(&si->mac_key, outhdr, len,
seqnum, calc_md5_mac);
}
DEBUG(10, ("smb_signing_sign_pdu: sent SMB signature of\n"));
dump_data(10, calc_md5_mac, 8);
- memcpy(&outbuf[NBT_HDR_SIZE+HDR_SS_FIELD], calc_md5_mac, 8);
+ memcpy(&outhdr[HDR_SS_FIELD], calc_md5_mac, 8);
-/* outbuf[NBT_HDR_SIZE+HDR_SS_FIELD+2]=0;
+/* outhdr[HDR_SS_FIELD+2]=0;
Uncomment this to test if the remote server actually verifies signatures...*/
}
bool smb_signing_check_pdu(struct smb_signing_state *si,
- const uint8_t *inbuf, uint32_t seqnum)
+ const uint8_t *inhdr, size_t len,
+ uint32_t seqnum)
{
bool good;
uint8_t calc_md5_mac[16];
@@ -286,17 +289,17 @@ bool smb_signing_check_pdu(struct smb_signing_state *si,
return true;
}
- if (smb_len_nbt(inbuf) < (HDR_SS_FIELD + 8)) {
+ if (len < (HDR_SS_FIELD + 8)) {
DEBUG(1,("smb_signing_check_pdu: Can't check signature "
"on short packet! smb_len = %u\n",
- smb_len_nbt(inbuf)));
+ (unsigned)len));
return false;
}
- smb_signing_md5(&si->mac_key, inbuf,
+ smb_signing_md5(&si->mac_key, inhdr, len,
seqnum, calc_md5_mac);
- reply_sent_mac = &inbuf[NBT_HDR_SIZE+HDR_SS_FIELD];
+ reply_sent_mac = &inhdr[HDR_SS_FIELD];
good = (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0);
if (!good) {
@@ -310,7 +313,7 @@ bool smb_signing_check_pdu(struct smb_signing_state *si,
dump_data(5, reply_sent_mac, 8);
for (i = -sign_range; i < sign_range; i++) {
- smb_signing_md5(&si->mac_key, inbuf,
+ smb_signing_md5(&si->mac_key, inhdr, len,
seqnum+i, calc_md5_mac);
if (memcmp(reply_sent_mac, calc_md5_mac, 8) == 0) {
DEBUG(0,("smb_signing_check_pdu: "
@@ -452,3 +455,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..7427ada 100644
--- a/libcli/smb/smb_signing.h
+++ b/libcli/smb/smb_signing.h
@@ -37,9 +37,11 @@ struct smb_signing_state *smb_signing_init_ex(TALLOC_CTX *mem_ctx,
uint32_t smb_signing_next_seqnum(struct smb_signing_state *si, bool oneway);
void smb_signing_cancel_reply(struct smb_signing_state *si, bool oneway);
void smb_signing_sign_pdu(struct smb_signing_state *si,
- uint8_t *outbuf, uint32_t seqnum);
+ uint8_t *outhdr, size_t len,
+ uint32_t seqnum);
bool smb_signing_check_pdu(struct smb_signing_state *si,
- const uint8_t *inbuf, uint32_t seqnum);
+ const uint8_t *inhdr, size_t len,
+ uint32_t seqnum);
bool smb_signing_activate(struct smb_signing_state *si,
const DATA_BLOB user_session_key,
const DATA_BLOB response);
@@ -49,5 +51,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_ */
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);
}
diff --git a/source3/smbd/sesssetup.c b/source3/smbd/sesssetup.c
index dc3e254..cf9c2e7 100644
--- a/source3/smbd/sesssetup.c
+++ b/source3/smbd/sesssetup.c
@@ -283,6 +283,58 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
action = 1;
}
+ if (session_info->session_key.length > 0) {
+ struct smbXsrv_session *x = session;
+ uint8_t session_key[16];
+
+ /*
+ * Note: the SMB1 signing key is not truncated to 16 byte!
+ */
+ x->global->signing_key =
+ data_blob_dup_talloc(x->global,
+ session_info->session_key);
+ if (x->global->signing_key.data == NULL) {
+ data_blob_free(&out_blob);
+ TALLOC_FREE(session);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+
+ /*
+ * The application key is truncated/padded to 16 bytes
+ */
+ ZERO_STRUCT(session_key);
+ memcpy(session_key, x->global->signing_key.data,
+ MIN(x->global->signing_key.length,
+ sizeof(session_key)));
+ x->global->application_key =
+ data_blob_talloc(x->global,
+ session_key,
+ sizeof(session_key));
+ ZERO_STRUCT(session_key);
+ if (x->global->application_key.data == NULL) {
+ data_blob_free(&out_blob);
+ TALLOC_FREE(session);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+
+ /*
+ * Place the application key into the session_info
+ */
+ data_blob_clear_free(&session_info->session_key);
+ session_info->session_key =
+ data_blob_dup_talloc(session_info,
+ x->global->application_key);
+ if (session_info->session_key.data == NULL) {
+ data_blob_clear_free(&x->global->application_key);
+ data_blob_free(&out_blob);
+ TALLOC_FREE(session);
+ reply_nterror(req, NT_STATUS_NO_MEMORY);
+ return;
+ }
+ }
+
session->compat = talloc_zero(session, struct user_struct);
if (session->compat == NULL) {
data_blob_free(&out_blob);
@@ -312,13 +364,16 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
return;
}
- if (srv_is_signing_negotiated(sconn) && action == 0) {
+ if (srv_is_signing_negotiated(sconn) &&
+ action == 0 &&
+ session->global->signing_key.length > 0)
+ {
/*
* Try and turn on server signing on the first non-guest
* sessionsetup.
*/
srv_set_signing(sconn,
- session_info->session_key,
+ session->global->signing_key,
data_blob_null);
}
@@ -373,7 +428,17 @@ static void reply_sesssetup_and_X_spnego(struct smb_request *req)
action = 1;
}
+ /*
+ * Keep the application key
+ */
+ data_blob_clear_free(&session_info->session_key);
+ session_info->session_key =
+ session->global->auth_session_info->session_key;
+ talloc_steal(session_info, session_info->session_key.data);
+ TALLOC_FREE(session->global->auth_session_info);
+
session->compat->session_info = session_info;
+
session->compat->vuid = session->global->session_wire_id;
if (security_session_user_level(session_info, NULL) >= SECURITY_USER) {
--
Samba Shared Repository
More information about the samba-cvs
mailing list