#include "cifspdu.h"
#include "cifsglob.h"
#include "cifs_debug.h"
+#include "md5.h"
/* Calculate and return the CIFS signature based on the mac key and the smb pdu */
-/* the eight byte signature must be allocated by the caller. */
+/* the 16 byte signature must be allocated by the caller */
+/* 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 */
-static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * mac_key, char * signature)
+static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, const char * key, char * signature)
{
+ struct MD5Context context;
if((cifs_pdu == NULL) || (signature == NULL))
return -EINVAL;
- /* MD5(mac_key, text) */
- /* return 1st eight bytes in signature */
-
+ MD5Init(&context);
+ MD5Update(&context,key,CIFS_SESSION_KEY_SIZE);
+ MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
+ MD5Final(signature,&context);
+ cifs_dump_mem("signature: ",signature,16); /* BB remove BB */
return 0;
}
-int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses)
+int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct cifsSesInfo * ses,
+ __u32 * pexpected_response_sequence_number)
{
int rc = 0;
- char smb_signature[8];
+ char smb_signature[20];
/* BB remember to initialize sequence number elsewhere and initialize mac_signing key elsewhere BB */
/* BB remember to add code to save expected sequence number in midQ entry BB */
if((le32_to_cpu(cifs_pdu->Flags2) & SMBFLG2_SECURITY_SIGNATURE) == 0)
return rc;
+ write_lock(&GlobalMid_Lock);
cifs_pdu->Signature.Sequence.SequenceNumber = ses->sequence_number;
cifs_pdu->Signature.Sequence.Reserved = 0;
+
+ *pexpected_response_sequence_number = ses->sequence_number++;
+ ses->sequence_number++;
+ write_unlock(&GlobalMid_Lock);
+
rc = cifs_calculate_signature(cifs_pdu, ses->mac_signing_key,smb_signature);
if(rc)
memset(cifs_pdu->Signature.SecuritySignature, 0, 8);
/* 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 */
+
+ /* Do not need to verify session setups with signature "BSRSPYL " */
+ if(memcmp(cifs_pdu->Signature.SecuritySignature,"BSRSPYL ",8)==0)
+ cFYI(1,("dummy signature received for smb command 0x%x",cifs_pdu->Command));
return rc;
}
if (in_buf->smb_buf_length > 12)
in_buf->Flags2 = cpu_to_le16(in_buf->Flags2);
- rc = cifs_sign_smb(in_buf, ses);
+ rc = cifs_sign_smb(in_buf, ses, &midQ->sequence_number);
midQ->midState = MID_REQUEST_SUBMITTED;
rc = smb_send(ses->server->ssocket, in_buf, in_buf->smb_buf_length,
receive_len +
4 /* include 4 byte RFC1001 header */ );
-/* int cifs_verify_signature(out_buf, ses->mac_signing_key,
- __u32 expected_sequence_number); */
+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 =