1
0
mirror of https://github.com/samba-team/samba.git synced 2024-12-24 21:34:56 +03:00

r1521: Updates to our SMB signing code.

- This causes our client and server code to use the same core code,
  with the same debugs etc.
- In turn, this will allow the 'mandetory/fallback' signing algorithms
  to be shared, and only written once.

Updates to the SPNEGO code
- Don't wrap an empty token to the server, if we are actually already finished.

Andrew Bartlett
This commit is contained in:
Andrew Bartlett 2004-07-16 02:54:57 +00:00 committed by Gerald (Jerry) Carter
parent 446306f054
commit 35b83eb329
8 changed files with 185 additions and 249 deletions

View File

@ -215,6 +215,7 @@ struct cli_tree {
char *fs_type;
};
/* the context for a single SMB request. This is passed to any request-context
* functions (similar to context.h, the server version).
* This will allow requests to be multi-threaded. */
@ -249,37 +250,8 @@ struct cli_request {
/* the mid of this packet - used to match replies */
uint16_t mid;
struct {
/* the raw SMB buffer, including the 4 byte length header */
char *buffer;
/* the size of the raw buffer, including 4 byte header */
uint_t size;
/* how much has been allocated - on reply the buffer is over-allocated to
prevent too many realloc() calls
*/
uint_t allocated;
/* the start of the SMB header - this is always buffer+4 */
char *hdr;
/* the command words and command word count. vwv points
into the raw buffer */
char *vwv;
uint_t wct;
/* the data buffer and size. data points into the raw buffer */
char *data;
uint_t data_size;
/* ptr is used as a moving pointer into the data area
* of the packet. The reason its here and not a local
* variable in each function is that when a realloc of
* a send packet is done we need to move this
* pointer */
char *ptr;
} in, out;
struct request_buffer in;
struct request_buffer out;
/* information on what to do with a reply when it is received
asyncronously. If this is not setup when a reply is received then

View File

@ -671,6 +671,7 @@ extern int errno;
#include "smbd/server.h"
#include "smbd/service.h"
#include "rpc_server/dcerpc_server.h"
#include "request.h"
#include "smb_server/smb_server.h"
#include "ntvfs/ntvfs.h"
#include "cli_context.h"

View File

@ -304,6 +304,8 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL
DATA_BLOB unwrapped_in;
if (!gensec_gssapi_parse_krb5_wrap(out_mem_ctx, &in, &unwrapped_in, tok_id)) {
DEBUG(1,("gensec_gssapi_parse_krb5_wrap(mutual authentication) failed to parse\n"));
dump_data_pw("Mutual authentication message:\n", in.data, in.length);
return NT_STATUS_INVALID_PARAMETER;
}
/* TODO: check the tok_id */
@ -316,7 +318,7 @@ static NTSTATUS gensec_krb5_update(struct gensec_security *gensec_security, TALL
if (ret) {
DEBUG(1,("krb5_rd_rep (mutual authentication) failed (%s)\n",
error_message(ret)));
dump_data_pw("Mutual authentication message:\n", in.data, in.length);
dump_data_pw("Mutual authentication message:\n", inbuf.data, inbuf.length);
nt_status = NT_STATUS_ACCESS_DENIED;
} else {
*out = data_blob(NULL, 0);

View File

@ -41,7 +41,6 @@ struct spnego_state {
uint_t ref_count;
enum spnego_message_type expected_packet;
enum spnego_state_position state_position;
enum spnego_negResult result;
struct gensec_security *sub_sec_security;
};
@ -60,7 +59,6 @@ static NTSTATUS gensec_spnego_client_start(struct gensec_security *gensec_securi
spnego_state->expected_packet = SPNEGO_NEG_TOKEN_INIT;
spnego_state->state_position = SPNEGO_CLIENT_START;
spnego_state->result = SPNEGO_ACCEPT_INCOMPLETE;
spnego_state->mem_ctx = mem_ctx;
spnego_state->sub_sec_security = NULL;
@ -140,8 +138,7 @@ static NTSTATUS gensec_spnego_session_key(struct gensec_security *gensec_securit
DATA_BLOB *session_key)
{
struct spnego_state *spnego_state = gensec_security->private_data;
if (spnego_state->state_position != SPNEGO_DONE
&& spnego_state->state_position != SPNEGO_FALLBACK) {
if (!spnego_state->sub_sec_security) {
return NT_STATUS_INVALID_PARAMETER;
}
@ -450,7 +447,6 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
spnego.negTokenTarg.responseToken,
&unwrapped_out);
spnego_state->result = spnego.negTokenTarg.negResult;
spnego_free_data(&spnego);
/* compose reply */
@ -514,38 +510,45 @@ static NTSTATUS gensec_spnego_update(struct gensec_security *gensec_security, TA
spnego.negTokenTarg.responseToken,
&unwrapped_out);
if (NT_STATUS_IS_OK(nt_status)
&& (spnego.negTokenTarg.negResult != SPNEGO_ACCEPT_COMPLETED)) {
if ((spnego.negTokenTarg.negResult == SPNEGO_ACCEPT_COMPLETED)
&& !NT_STATUS_IS_OK(nt_status)) {
DEBUG(1,("gensec_update ok but not accepted\n"));
nt_status = NT_STATUS_INVALID_PARAMETER;
}
}
spnego_state->result = spnego.negTokenTarg.negResult;
spnego_free_data(&spnego);
spnego_out.type = SPNEGO_NEG_TOKEN_TARG;
spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT;
spnego_out.negTokenTarg.supportedMech = NULL;
spnego_out.negTokenTarg.responseToken = unwrapped_out;
spnego_out.negTokenTarg.mechListMIC = null_data_blob;
if (unwrapped_out.length) {
spnego_out.type = SPNEGO_NEG_TOKEN_TARG;
spnego_out.negTokenTarg.negResult = SPNEGO_NONE_RESULT;
spnego_out.negTokenTarg.supportedMech = NULL;
spnego_out.negTokenTarg.responseToken = unwrapped_out;
spnego_out.negTokenTarg.mechListMIC = null_data_blob;
if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {
DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n"));
return NT_STATUS_INVALID_PARAMETER;
}
} else {
*out = null_data_blob;
}
if (NT_STATUS_EQUAL(nt_status, NT_STATUS_MORE_PROCESSING_REQUIRED)) {
/* compose reply */
spnego_state->state_position = SPNEGO_CLIENT_TARG;
} else if (NT_STATUS_IS_OK(nt_status)) {
/* all done - server has accepted, and we agree */
spnego_state->state_position = SPNEGO_DONE;
return NT_STATUS_OK;
} else {
DEBUG(1, ("SPNEGO(%s) login failed: %s\n",
spnego_state->sub_sec_security->ops->name,
nt_errstr(nt_status)));
return nt_status;
}
if (spnego_write_data(out_mem_ctx, out, &spnego_out) == -1) {
DEBUG(1, ("Failed to write SPNEGO reply to NEG_TOKEN_TARG\n"));
return NT_STATUS_INVALID_PARAMETER;
}
return nt_status;
}
case SPNEGO_DONE:

View File

@ -260,7 +260,7 @@ static void use_nt1_session_keys(struct cli_session *session,
E_md4hash(password, nt_hash);
SMBsesskeygen_ntv1(nt_hash, session_key.data);
cli_transport_simple_set_signing(transport, session_key, *nt_response, 0);
cli_transport_simple_set_signing(transport, session_key, *nt_response);
cli_session_set_user_session_key(session, &session_key);
data_blob_free(&session_key);
@ -380,6 +380,7 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session
union smb_sesssetup *parms)
{
NTSTATUS status;
NTSTATUS session_key_err = NT_STATUS_NO_USER_SESSION_KEY;
union smb_sesssetup s2;
DATA_BLOB session_key = data_blob(NULL, 0);
DATA_BLOB null_data_blob = data_blob(NULL, 0);
@ -443,15 +444,20 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session
&s2.spnego.in.secblob);
while(1) {
if (NT_STATUS_IS_OK(status) && s2.spnego.in.secblob.length == 0) {
break;
}
if (!NT_STATUS_EQUAL(status, NT_STATUS_MORE_PROCESSING_REQUIRED) && !NT_STATUS_IS_OK(status)) {
break;
}
status = gensec_session_key(session->gensec, &session_key);
if (NT_STATUS_IS_OK(status)) {
cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 0);
if (!NT_STATUS_IS_OK(session_key_err)) {
session_key_err = gensec_session_key(session->gensec, &session_key);
}
if (NT_STATUS_IS_OK(session_key_err)) {
cli_transport_simple_set_signing(session->transport, session_key, null_data_blob);
}
session->vuid = s2.spnego.out.vuid;
status = smb_raw_session_setup(session, mem_ctx, &s2);
session->vuid = UID_FIELD_INVALID;
@ -464,19 +470,14 @@ static NTSTATUS smb_raw_session_setup_generic_spnego(struct cli_session *session
s2.spnego.out.secblob,
&s2.spnego.in.secblob);
if (NT_STATUS_IS_OK(status)) {
break;
}
}
done:
if (NT_STATUS_IS_OK(status)) {
status = gensec_session_key(session->gensec, &session_key);
if (!NT_STATUS_IS_OK(status)) {
return status;
if (!NT_STATUS_IS_OK(session_key_err)) {
DEBUG(1, ("Failed to get user session key: %s\n", nt_errstr(session_key_err)));
return session_key_err;
}
cli_transport_simple_set_signing(session->transport, session_key, null_data_blob, 2 /* two legs on last packet */);
cli_session_set_user_session_key(session, &session_key);
@ -484,6 +485,9 @@ done:
parms->generic.out.os = s2.spnego.out.os;
parms->generic.out.lanman = s2.spnego.out.lanman;
parms->generic.out.domain = s2.spnego.out.domain;
} else {
DEBUG(1, ("Failed to login with SPNEGO: %s\n", nt_errstr(status)));
return status;
}
return status;
@ -528,7 +532,18 @@ NTSTATUS smb_raw_session_setup(struct cli_session *session, TALLOC_CTX *mem_ctx,
struct cli_request *req;
if (parms->generic.level == RAW_SESSSETUP_GENERIC) {
return smb_raw_session_setup_generic(session, mem_ctx, parms);
NTSTATUS ret = smb_raw_session_setup_generic(session, mem_ctx, parms);
if (NT_STATUS_IS_OK(ret)
&& parms->generic.in.user
&& *parms->generic.in.user) {
if (!session->transport->negotiate.sign_info.doing_signing
&& session->transport->negotiate.sign_info.mandatory_signing) {
DEBUG(0, ("SMB signing required, but server does not support it\n"));
return NT_STATUS_ACCESS_DENIED;
}
}
return ret;
}
req = smb_raw_session_setup_send(session, parms);

View File

@ -69,15 +69,15 @@ static BOOL set_smb_signing_real_common(struct cli_transport *transport)
return True;
}
static void mark_packet_signed(struct cli_request *req)
static void mark_packet_signed(struct request_buffer *out)
{
uint16_t flags2;
flags2 = SVAL(req->out.hdr, HDR_FLG2);
flags2 = SVAL(out->hdr, HDR_FLG2);
flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
SSVAL(req->out.hdr, HDR_FLG2, flags2);
SSVAL(out->hdr, HDR_FLG2, flags2);
}
static BOOL signing_good(struct cli_request *req, int seq, BOOL good)
static BOOL signing_good(struct cli_request *req, unsigned int seq, BOOL good)
{
if (good) {
if (!req->transport->negotiate.sign_info.doing_signing) {
@ -87,9 +87,8 @@ static BOOL signing_good(struct cli_request *req, int seq, BOOL good)
req->transport->negotiate.sign_info.seen_valid = True;
}
} else {
if (!req->transport->negotiate.sign_info.mandatory_signing && !req->transport->negotiate.sign_info.seen_valid) {
/* Non-mandatory signing - just turn off if this is the first bad packet.. */
if (!req->transport->negotiate.sign_info.seen_valid) {
/* If we have never seen a good packet, just turn it off */
DEBUG(5, ("signing_good: signing negotiated but not required and peer\n"
"isn't sending correct signatures. Turning off.\n"));
req->transport->negotiate.sign_info.negotiated_smb_signing = False;
@ -100,22 +99,115 @@ static BOOL signing_good(struct cli_request *req, int seq, BOOL good)
cli_null_set_signing(req->transport);
return True;
} else {
/* Mandatory signing or bad packet after signing started - fail and disconnect. */
if (seq)
DEBUG(0, ("signing_good: BAD SIG: seq %u\n", (unsigned int)seq));
/* bad packet after signing started - fail and disconnect. */
DEBUG(0, ("signing_good: BAD SIG: seq %u\n", seq));
return False;
}
}
return True;
}
void sign_outgoing_message(struct request_buffer *out, DATA_BLOB *mac_key, uint_t seq_num)
{
uint8_t calc_md5_mac[16];
struct MD5Context md5_ctx;
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
*/
SIVAL(out->hdr, HDR_SS_FIELD, seq_num);
SIVAL(out->hdr, HDR_SS_FIELD + 4, 0);
/* mark the packet as signed - BEFORE we sign it...*/
mark_packet_signed(out);
/* Calculate the 16 byte MAC and place first 8 bytes into the field. */
MD5Init(&md5_ctx);
MD5Update(&md5_ctx, mac_key->data,
mac_key->length);
MD5Update(&md5_ctx,
out->buffer + NBT_HDR_SIZE,
out->size - NBT_HDR_SIZE);
MD5Final(calc_md5_mac, &md5_ctx);
memcpy(&out->hdr[HDR_SS_FIELD], calc_md5_mac, 8);
DEBUG(5, ("sign_outgoing_message: SENT SIG (seq: %d): sent SMB signature of\n",
seq_num));
dump_data(5, calc_md5_mac, 8);
/* req->out.hdr[HDR_SS_FIELD+2]=0;
Uncomment this to test if the remote server actually verifies signitures...*/
}
BOOL check_signed_incoming_message(struct request_buffer *in, DATA_BLOB *mac_key, uint_t seq_num)
{
BOOL good;
uint8_t calc_md5_mac[16];
uint8_t server_sent_mac[8];
uint8_t sequence_buf[8];
struct MD5Context md5_ctx;
const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
int i;
const int sign_range = 0;
/* room enough for the signature? */
if (in->size < NBT_HDR_SIZE + HDR_SS_FIELD + 8) {
return False;
}
/* its quite bogus to be guessing sequence numbers, but very useful
when debugging signing implementations */
for (i = 0-sign_range; i <= 0+sign_range; i++) {
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
*/
SIVAL(sequence_buf, 0, seq_num + i);
SIVAL(sequence_buf, 4, 0);
/* get a copy of the server-sent mac */
memcpy(server_sent_mac, &in->hdr[HDR_SS_FIELD], sizeof(server_sent_mac));
/* Calculate the 16 byte MAC and place first 8 bytes into the field. */
MD5Init(&md5_ctx);
MD5Update(&md5_ctx, mac_key->data,
mac_key->length);
MD5Update(&md5_ctx, in->hdr, HDR_SS_FIELD);
MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
MD5Update(&md5_ctx, in->hdr + offset_end_of_sig,
in->size - NBT_HDR_SIZE - (offset_end_of_sig));
MD5Final(calc_md5_mac, &md5_ctx);
good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
if (i == 0) {
if (!good) {
DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", seq_num + i));
dump_data(5, calc_md5_mac, 8);
DEBUG(5, ("check_signed_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", seq_num + i));
dump_data(5, server_sent_mac, 8);
} else {
DEBUG(15, ("check_signed_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", seq_num + i));
dump_data(5, server_sent_mac, 8);
}
}
if (good) break;
}
if (good && i != 0) {
DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, seq_num));
}
return good;
}
/***********************************************************
SMB signing - Simple implementation - calculate a MAC to send.
************************************************************/
static void cli_request_simple_sign_outgoing_message(struct cli_request *req)
{
uint8_t calc_md5_mac[16];
struct MD5Context md5_ctx;
struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context;
#if 0
@ -133,33 +225,8 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req)
} else {
data->next_seq_num += 2;
}
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
*/
SIVAL(req->out.hdr, HDR_SS_FIELD, req->seq_num);
SIVAL(req->out.hdr, HDR_SS_FIELD + 4, 0);
/* mark the packet as signed - BEFORE we sign it...*/
mark_packet_signed(req);
/* Calculate the 16 byte MAC and place first 8 bytes into the field. */
MD5Init(&md5_ctx);
MD5Update(&md5_ctx, data->mac_key.data,
data->mac_key.length);
MD5Update(&md5_ctx,
req->out.buffer + NBT_HDR_SIZE,
req->out.size - NBT_HDR_SIZE);
MD5Final(calc_md5_mac, &md5_ctx);
memcpy(&req->out.hdr[HDR_SS_FIELD], calc_md5_mac, 8);
DEBUG(5, ("cli_request_simple_sign_outgoing_message: SENT SIG (seq: %d, next %d): sent SMB signature of\n",
req->seq_num, data->next_seq_num));
dump_data(5, calc_md5_mac, 8);
/* req->out.hdr[HDR_SS_FIELD+2]=0;
Uncomment this to test if the remote server actually verifies signitures...*/
sign_outgoing_message(&req->out, &data->mac_key, req->seq_num);
}
@ -168,62 +235,13 @@ static void cli_request_simple_sign_outgoing_message(struct cli_request *req)
************************************************************/
static BOOL cli_request_simple_check_incoming_message(struct cli_request *req)
{
BOOL good;
uint8_t calc_md5_mac[16];
uint8_t server_sent_mac[8];
uint8_t sequence_buf[8];
struct MD5Context md5_ctx;
struct smb_basic_signing_context *data = req->transport->negotiate.sign_info.signing_context;
const size_t offset_end_of_sig = (HDR_SS_FIELD + 8);
int i;
const int sign_range = 0;
/* its quite bogus to be guessing sequence numbers, but very useful
when debugging signing implementations */
for (i = 1-sign_range; i <= 1+sign_range; i++) {
/*
* Firstly put the sequence number into the first 4 bytes.
* and zero out the next 4 bytes.
*/
SIVAL(sequence_buf, 0, req->seq_num+i);
SIVAL(sequence_buf, 4, 0);
/* get a copy of the server-sent mac */
memcpy(server_sent_mac, &req->in.hdr[HDR_SS_FIELD], sizeof(server_sent_mac));
/* Calculate the 16 byte MAC and place first 8 bytes into the field. */
MD5Init(&md5_ctx);
MD5Update(&md5_ctx, data->mac_key.data,
data->mac_key.length);
MD5Update(&md5_ctx, req->in.hdr, HDR_SS_FIELD);
MD5Update(&md5_ctx, sequence_buf, sizeof(sequence_buf));
MD5Update(&md5_ctx, req->in.hdr + offset_end_of_sig,
req->in.size - NBT_HDR_SIZE - (offset_end_of_sig));
MD5Final(calc_md5_mac, &md5_ctx);
good = (memcmp(server_sent_mac, calc_md5_mac, 8) == 0);
if (i == 1) {
if (!good) {
DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): wanted SMB signature of\n", req->seq_num + i));
dump_data(5, calc_md5_mac, 8);
DEBUG(5, ("cli_request_simple_check_incoming_message: BAD SIG (seq: %d): got SMB signature of\n", req->seq_num + i));
dump_data(5, server_sent_mac, 8);
} else {
DEBUG(15, ("cli_request_simple_check_incoming_message: GOOD SIG (seq: %d): got SMB signature of\n", req->seq_num + i));
dump_data(5, server_sent_mac, 8);
}
}
if (good) break;
}
if (good && i != 1) {
DEBUG(0,("SIGNING OFFSET %d (should be %d)\n", i, req->seq_num+1));
}
struct smb_basic_signing_context *data
= req->transport->negotiate.sign_info.signing_context;
BOOL good = check_signed_incoming_message(&req->in,
&data->mac_key,
req->seq_num+1);
return signing_good(req, req->seq_num+1, good);
}
@ -247,8 +265,7 @@ static void cli_transport_simple_free_signing_context(struct cli_transport *tran
************************************************************/
BOOL cli_transport_simple_set_signing(struct cli_transport *transport,
const DATA_BLOB user_session_key,
const DATA_BLOB response,
int seq_num)
const DATA_BLOB response)
{
struct smb_basic_signing_context *data;
@ -271,8 +288,10 @@ BOOL cli_transport_simple_set_signing(struct cli_transport *transport,
memcpy(&data->mac_key.data[user_session_key.length],response.data, response.length);
}
dump_data_pw("Started Signing with key:\n", data->mac_key.data, data->mac_key.length);
/* Initialise the sequence number */
data->next_seq_num = seq_num;
data->next_seq_num = 0;
transport->negotiate.sign_info.sign_outgoing_message = cli_request_simple_sign_outgoing_message;
transport->negotiate.sign_info.check_incoming_message = cli_request_simple_check_incoming_message;
@ -332,11 +351,12 @@ BOOL cli_null_set_signing(struct cli_transport *transport)
static void cli_request_temp_sign_outgoing_message(struct cli_request *req)
{
/* mark the packet as signed - BEFORE we sign it...*/
mark_packet_signed(req);
mark_packet_signed(&req->out);
/* I wonder what BSRSPYL stands for - but this is what MS
actually sends! */
memcpy((req->out.hdr + HDR_SS_FIELD), "BSRSPYL ", 8);
return;
}

View File

@ -20,34 +20,6 @@
#include "includes.h"
/*
mark the flags2 field in a packet as signed
*/
static void mark_packet_signed(struct smbsrv_request *req)
{
uint16_t flags2;
flags2 = SVAL(req->out.hdr, HDR_FLG2);
flags2 |= FLAGS2_SMB_SECURITY_SIGNATURES;
SSVAL(req->out.hdr, HDR_FLG2, flags2);
}
/*
calculate the signature for a message
*/
static void calc_signature(uint8_t *buffer, size_t length,
DATA_BLOB *mac_key, uint8_t signature[8])
{
uint8_t calc_md5_mac[16];
struct MD5Context md5_ctx;
MD5Init(&md5_ctx);
MD5Update(&md5_ctx, mac_key->data, mac_key->length);
MD5Update(&md5_ctx, buffer, length);
MD5Final(calc_md5_mac, &md5_ctx);
memcpy(signature, calc_md5_mac, 8);
}
/*
sign an outgoing packet
*/
@ -57,14 +29,9 @@ void req_sign_packet(struct smbsrv_request *req)
if (req->smb_conn->signing.signing_state != SMB_SIGNING_REQUIRED) {
return;
}
SBVAL(req->out.hdr, HDR_SS_FIELD, req->seq_num+1);
mark_packet_signed(req);
calc_signature(req->out.hdr, req->out.size - NBT_HDR_SIZE,
&req->smb_conn->signing.mac_key,
&req->out.hdr[HDR_SS_FIELD]);
sign_outgoing_message(&req->out,
&req->smb_conn->signing.mac_key,
req->seq_num+1);
}
@ -127,23 +94,8 @@ BOOL req_signing_check_incoming(struct smbsrv_request *req)
return True;
}
/* room enough for the signature? */
if (req->in.size < NBT_HDR_SIZE + HDR_SS_FIELD + 8) {
return False;
}
return check_signed_incoming_message(&req->in,
&req->smb_conn->signing.mac_key,
req->seq_num);
memcpy(client_md5_mac, req->in.hdr + HDR_SS_FIELD, 8);
SBVAL(req->in.hdr, HDR_SS_FIELD, req->seq_num);
calc_signature(req->in.hdr, req->in.size - NBT_HDR_SIZE,
&req->smb_conn->signing.mac_key,
signature);
if (memcmp(client_md5_mac, signature, 8) != 0) {
DEBUG(2,("Bad SMB signature seq_num=%d\n", (int)req->seq_num));
return False;
}
return True;
}

View File

@ -141,37 +141,8 @@ struct smbsrv_request {
NTSTATUS status;
} async;
struct {
/* the raw SMB buffer, including the 4 byte length header */
char *buffer;
/* the size of the raw buffer, including 4 byte header */
unsigned size;
/* how much has been allocated - on reply the buffer is over-allocated to
prevent too many realloc() calls
*/
unsigned allocated;
/* the start of the SMB header - this is always buffer+4 */
char *hdr;
/* the command words and command word count. vwv points
into the raw buffer */
char *vwv;
unsigned wct;
/* the data buffer and size. data points into the raw buffer */
char *data;
unsigned data_size;
/* ptr is used as a moving pointer into the data area
* of the packet. The reason its here and not a local
* variable in each function is that when a realloc of
* a reply packet is done we need to move this
* pointer */
char *ptr;
} in, out;
struct request_buffer in;
struct request_buffer out;
};
/* this contains variables that should be used in % substitutions for