Commit bd792b17 authored by Steve French's avatar Steve French Committed by Steve French

Signing fixes part 4 of 4

parent b5d16cb5
......@@ -30,6 +30,9 @@
/* Note we only use the 1st eight bytes */
/* Note that the smb header signature field on input contains the
sequence number before this function is called */
extern void mdfour(unsigned char *out, unsigned char *in, int n);
extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
{
......@@ -39,10 +42,9 @@ static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char
return -EINVAL;
MD5Init(&context);
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE);
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
MD5Final(signature,&context);
cifs_dump_mem("signature: ",signature,16); /* BB remove BB */
return 0;
}
......@@ -62,7 +64,7 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
return rc;
write_lock(&GlobalMid_Lock);
cifs_pdu->Signature.Sequence.SequenceNumber = ses->sequence_number;
cifs_pdu->Signature.Sequence.SequenceNumber = cpu_to_le32(ses->sequence_number);
cifs_pdu->Signature.Sequence.Reserved = 0;
*pexpected_response_sequence_number = ses->sequence_number++;
......@@ -78,15 +80,19 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
return rc;
}
int cifs_verify_signature(const struct smb_hdr * cifs_pdu, const char * mac_key,
int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key,
__u32 expected_sequence_number)
{
unsigned int rc = 0;
unsigned int rc;
char server_response_sig[8];
char what_we_think_sig_should_be[20];
if((cifs_pdu == NULL) || (mac_key == NULL))
return -EINVAL;
/* BB no need to verify negprot or if flag is not on for session (or for frame?? */
if (cifs_pdu->Command == SMB_COM_NEGOTIATE)
return 0;
/* BB what if signatures are supposed to be on for session but server does not
send one? BB */
/* BB also do not verify oplock breaks for signature */
......@@ -95,5 +101,40 @@ int cifs_verify_signature(const struct smb_hdr * cifs_pdu, const char * mac_key,
if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0)
cFYI(1,("dummy signature received for smb command 0x%x",cifs_pdu->Command));
return rc;
expected_sequence_number = cpu_to_le32(expected_sequence_number);
/* save off the origiginal signature so we can modify the smb and check
its signature against what the server sent */
memcpy(server_response_sig,cifs_pdu->Signature.SecuritySignature,8);
cifs_pdu->Signature.Sequence.SequenceNumber = expected_sequence_number;
cifs_pdu->Signature.Sequence.Reserved = 0;
rc = cifs_calculate_signature(cifs_pdu, mac_key,
what_we_think_sig_should_be);
if(rc)
return rc;
/* cifs_dump_mem("what we think it should be: ",what_we_think_sig_should_be,16); */
if(memcmp(server_response_sig, what_we_think_sig_should_be, 8))
return -EACCES;
else
return 0;
}
/* We fill in key by putting in 40 byte array which was allocated by caller */
int cifs_calculate_mac_key(char * key, const char * rn, const char * password)
{
char temp_key[16];
if ((key == NULL) || (rn == NULL) || (password == NULL))
return -EINVAL;
E_md4hash(password, temp_key); /* BB may have to do another md4 of it */
mdfour(key,temp_key,16);
memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE);
return 0;
}
......@@ -151,7 +151,7 @@ struct cifsSesInfo {
enum statusEnum status;
__u32 sequence_number; /* needed for CIFS PDU signature */
__u16 ipc_tid; /* special tid for connection to IPC share */
char mac_signing_key[CIFS_SESSION_KEY_SIZE];
char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
char *serverOS; /* name of operating system underlying the server */
char *serverNOS; /* name of network operating system that the server is running */
char *serverDomain; /* security realm of server */
......
......@@ -228,6 +228,7 @@ extern int cifs_reconnect(struct TCP_Server_Info *server);
extern int cifs_sign_smb(struct smb_hdr *, struct cifsSesInfo *,__u32 *);
extern int cifs_verify_signature(const struct smb_hdr *, const char * mac_key,
__u32 expected_sequence_number);
extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
/* BB routines below not implemented yet BB */
......
......@@ -200,7 +200,7 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
continue;
}
pdu_length = 4 + ntohl(smb_buffer->smb_buf_length);
cFYI(1, ("Peek length rcvd: %d with smb length: %d", length, pdu_length)); /* BB */
cFYI(1, ("Peek length rcvd: %d with smb length: %d", length, pdu_length));
temp = (char *) smb_buffer;
if (length > 3) {
......@@ -332,8 +332,9 @@ cifs_demultiplex_thread(struct TCP_Server_Info *server)
kfree(server);
} else /* BB need to more gracefully handle the rare negative session
response case because response will be still outstanding */
cERROR(1, ("There are still active MIDs in queue and we are exiting but we can not delete mid_q_entries or TCP_Server_Info structure due to pending requests MEMORY LEAK!!")); /* BB wake up waitors, and/or wait and/or free stale mids and try again? BB */
/* BB Need to fix bug in error path above - perhaps wait until smb requests
cERROR(1, ("Active MIDs in queue while exiting - can not delete mid_q_entries or TCP_Server_Info structure due to pending requests MEMORY LEAK!!"));
/* BB wake up waitors, and/or wait and/or free stale mids and try again? BB */
/* BB Need to fix bug in error path above - perhaps wait until smb requests
time out and then free the tcp per server struct BB */
read_unlock(&GlobalSMBSeslock);
......@@ -672,6 +673,8 @@ int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, struct nls_tab
SMBNTencrypt(pSesInfo->password_with_pad,
pSesInfo->server->cryptKey,ntlm_session_key);
/* BB add call to save MAC key here BB */
/* for better security the weaker lanman hash not sent
in AuthSessSetup so why bother calculating it */
/* toUpper(nls_info,
......@@ -690,6 +693,8 @@ int setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, struct nls_tab
SMBNTencrypt(pSesInfo->password_with_pad,
pSesInfo->server->cryptKey,
ntlm_session_key);
cifs_calculate_mac_key(pSesInfo->mac_signing_key, ntlm_session_key, pSesInfo->password_with_pad);
rc = CIFSSessSetup(xid, pSesInfo,
ntlm_session_key, nls_info);
}
......
......@@ -250,12 +250,17 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses,
receive_len +
4 /* include 4 byte RFC1001 header */ );
rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
dump_smb(out_buf, 92);
/* convert the length into a more usable form */
out_buf->smb_buf_length =
be32_to_cpu(out_buf->smb_buf_length);
if((out_buf->smb_buf_length > 24) &&
(ses->server->secMode & (SECMODE_SIGN_REQUIRED | SECMODE_SIGN_ENABLED))) {
rc = cifs_verify_signature(out_buf, ses->mac_signing_key,midQ->sequence_number); /* BB fix BB */
if(rc)
cFYI(1,("Unexpected signature received from server"));
}
if (out_buf->smb_buf_length > 12)
out_buf->Flags2 = le16_to_cpu(out_buf->Flags2);
if (out_buf->smb_buf_length > 28)
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment