Login
[x]
Log in using an account from:
Fedora Account System
Red Hat Associate
Red Hat Customer
Or login using a Red Hat Bugzilla account
Forgot Password
Login:
Hide Forgot
Create an Account
Red Hat Bugzilla – Attachment 279861 Details for
Bug 414151
CRM #1757328 mounting windows 2003 share with ntlm version 2, resulting access denied
[?]
New
Simple Search
Advanced Search
My Links
Browse
Requests
Reports
Current State
Search
Tabular reports
Graphical reports
Duplicates
Other Reports
User Changes
Plotly Reports
Bug Status
Bug Severity
Non-Defaults
|
Product Dashboard
Help
Page Help!
Bug Writing Guidelines
What's new
Browser Support Policy
5.0.4.rh83 Release notes
FAQ
Guides index
User guide
Web Services
Contact
Legal
This site requires JavaScript to be enabled to function correctly, please enable it.
[patch]
patch -- backported patch to fix ntlmv2 packet signatures
0001-CIFS-Fix-packet-signatures-for-NTLMv2-case.patch (text/plain), 12.04 KB, created by
Jeff Layton
on 2007-12-06 16:25:26 UTC
(
hide
)
Description:
patch -- backported patch to fix ntlmv2 packet signatures
Filename:
MIME Type:
Creator:
Jeff Layton
Created:
2007-12-06 16:25:26 UTC
Size:
12.04 KB
patch
obsolete
>From 5aa54fd30c73138a285e2b75ca51cf6087d1bd7a Mon Sep 17 00:00:00 2001 >From: Jeff Layton <jlayton@redhat.com> >Date: Thu, 6 Dec 2007 10:50:21 -0500 >Subject: [PATCH] [CIFS] Fix packet signatures for NTLMv2 case > >Signed-off-by: Yehuda Sadeh Weinraub <Yehuda.Sadeh@expand.com> >Signed-off-by: Steve French <sfrench@us.ibm.com> >--- > fs/cifs/cifsencrypt.c | 68 +++++++++++++++++++++++++++++++------------------ > fs/cifs/cifsglob.h | 14 +++++++++- > fs/cifs/cifsproto.h | 8 +++-- > fs/cifs/connect.c | 4 +- > fs/cifs/sess.c | 2 +- > fs/cifs/transport.c | 6 ++-- > 6 files changed, 67 insertions(+), 35 deletions(-) > >diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c >index fdeda51..65624de 100644 >--- a/fs/cifs/cifsencrypt.c >+++ b/fs/cifs/cifsencrypt.c >@@ -41,16 +41,17 @@ extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, > unsigned char *p24); > > static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu, >- const char * key, char * signature) >+ const struct mac_key *key, char *signature) > { > struct MD5Context context; > >- if((cifs_pdu == NULL) || (signature == NULL)) >+ if((cifs_pdu == NULL) || (signature == NULL) || (key == NULL)) > return -EINVAL; > > MD5Init(&context); >- MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); >+ MD5Update(&context, (char *)&key->data, key->len); > MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length); >+ > MD5Final(signature,&context); > return 0; > } >@@ -75,7 +76,8 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, > server->sequence_number++; > spin_unlock(&GlobalMid_Lock); > >- rc = cifs_calculate_signature(cifs_pdu, server->mac_signing_key,smb_signature); >+ rc = cifs_calculate_signature(cifs_pdu, &server->mac_signing_key, >+ smb_signature); > if(rc) > memset(cifs_pdu->Signature.SecuritySignature, 0, 8); > else >@@ -84,17 +86,17 @@ int cifs_sign_smb(struct smb_hdr * cifs_pdu, struct TCP_Server_Info * server, > return rc; > } > >-static int cifs_calc_signature2(const struct kvec * iov, int n_vec, >- const char * key, char * signature) >+static int cifs_calc_signature2(const struct kvec *iov, int n_vec, >+ const struct mac_key *key, char *signature) > { > struct MD5Context context; > int i; > >- if((iov == NULL) || (signature == NULL)) >+ if((iov == NULL) || (signature == NULL) || (key == NULL)) > return -EINVAL; > > MD5Init(&context); >- MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16); >+ MD5Update(&context, (char *)&key->data, key->len); > for(i=0;i<n_vec;i++) { > if(iov[i].iov_base == NULL) { > cERROR(1,("null iovec entry")); >@@ -139,7 +141,7 @@ int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, > server->sequence_number++; > spin_unlock(&GlobalMid_Lock); > >- rc = cifs_calc_signature2(iov, n_vec, server->mac_signing_key, >+ rc = cifs_calc_signature2(iov, n_vec, &server->mac_signing_key, > smb_signature); > if(rc) > memset(cifs_pdu->Signature.SecuritySignature, 0, 8); >@@ -150,8 +152,9 @@ int cifs_sign_smb2(struct kvec * iov, int n_vec, struct TCP_Server_Info *server, > > } > >-int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, >- __u32 expected_sequence_number) >+int cifs_verify_signature(struct smb_hdr * cifs_pdu, >+ const struct mac_key *mac_key, >+ __u32 expected_sequence_number) > { > unsigned int rc; > char server_response_sig[8]; >@@ -200,15 +203,17 @@ int cifs_verify_signature(struct smb_hdr * cifs_pdu, const char * mac_key, > } > > /* 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) >+int cifs_calculate_mac_key(struct mac_key *key, const char *rn, >+ const char *password) > { > char temp_key[16]; > if ((key == NULL) || (rn == NULL)) > return -EINVAL; > > E_md4hash(password, temp_key); >- mdfour(key,temp_key,16); >- memcpy(key+16,rn, CIFS_SESS_KEY_SIZE); >+ mdfour(key->data.ntlm, temp_key, 16); >+ memcpy(key->data.ntlm+16, rn, CIFS_SESS_KEY_SIZE); >+ key->len = 40; > return 0; > } > >@@ -233,35 +238,35 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, > if(ses->domainName == NULL) > return -EINVAL; /* BB should we use CIFS_LINUX_DOM */ > dom_name_len = strlen(ses->domainName); >- if(dom_name_len > MAX_USERNAME_SIZE) >+ if (dom_name_len > MAX_USERNAME_SIZE) > return -EINVAL; > > ucase_buf = kmalloc((MAX_USERNAME_SIZE+1), GFP_KERNEL); >- if(ucase_buf == NULL) >+ if (ucase_buf == NULL) > return -ENOMEM; > unicode_buf = kmalloc((MAX_USERNAME_SIZE+1)*4, GFP_KERNEL); >- if(unicode_buf == NULL) { >+ if (unicode_buf == NULL) { > kfree(ucase_buf); > return -ENOMEM; > } > >- for(i=0;i<user_name_len;i++) >+ for (i = 0;i < user_name_len; i++) > ucase_buf[i] = nls_info->charset2upper[(int)ses->userName[i]]; > ucase_buf[i] = 0; > user_name_len = cifs_strtoUCS(unicode_buf, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); > unicode_buf[user_name_len] = 0; > user_name_len++; > >- for(i=0;i<dom_name_len;i++) >+ for (i = 0; i < dom_name_len; i++) > ucase_buf[i] = nls_info->charset2upper[(int)ses->domainName[i]]; > ucase_buf[i] = 0; > dom_name_len = cifs_strtoUCS(unicode_buf+user_name_len, ucase_buf, MAX_USERNAME_SIZE*2, nls_info); > > unicode_buf[user_name_len + dom_name_len] = 0; > hmac_md5_update((const unsigned char *) unicode_buf, >- (user_name_len+dom_name_len)*2,&ctx); >+ (user_name_len+dom_name_len)*2, &ctx); > >- hmac_md5_final(ses->server->mac_signing_key,&ctx); >+ hmac_md5_final(ses->server->ntlmv2_hash, &ctx); > kfree(ucase_buf); > kfree(unicode_buf); > return 0; >@@ -345,7 +350,10 @@ static int calc_ntlmv2_hash(struct cifsSesInfo *ses, > if(domain == NULL) > goto calc_exit_1; > len = cifs_strtoUCS(domain, ses->domainName, len, nls_cp); >- UniStrupr(domain); >+ /* the following line was removed since it didn't work well >+ with lower cased domain name that passed as an option. >+ Maybe converting the domain name earlier makes sense */ >+ /* UniStrupr(domain); */ > > hmac_md5_update((char *)domain, 2*len, pctxt); > >@@ -356,7 +364,7 @@ calc_exit_1: > calc_exit_2: > /* BB FIXME what about bytes 24 through 40 of the signing key? > compare with the NTLM example */ >- hmac_md5_final(ses->server->mac_signing_key, pctxt); >+ hmac_md5_final(ses->server->ntlmv2_hash, pctxt); > > return rc; > } >@@ -366,6 +374,7 @@ void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, > { > int rc; > struct ntlmv2_resp * buf = (struct ntlmv2_resp *)resp_buf; >+ struct HMACMD5Context context; > > buf->blob_signature = cpu_to_le32(0x00000101); > buf->reserved = 0; >@@ -382,6 +391,15 @@ void setup_ntlmv2_rsp(struct cifsSesInfo * ses, char * resp_buf, > if(rc) > cERROR(1,("could not get v2 hash rc %d",rc)); > CalcNTLMv2_response(ses, resp_buf); >+ >+ /* now calculate the MAC key for NTLMv2 */ >+ hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); >+ hmac_md5_update(resp_buf, 16, &context); >+ hmac_md5_final(ses->server->mac_signing_key.data.ntlmv2.key, &context); >+ >+ memcpy(&ses->server->mac_signing_key.data.ntlmv2.resp, resp_buf, >+ sizeof(struct ntlmv2_resp)); >+ ses->server->mac_signing_key.len = 16 + sizeof(struct ntlmv2_resp); > } > > void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_response) >@@ -389,9 +407,9 @@ void CalcNTLMv2_response(const struct cifsSesInfo * ses, char * v2_session_respo > struct HMACMD5Context context; > /* rest of v2 struct already generated */ > memcpy(v2_session_response + 8, ses->server->cryptKey,8); >- hmac_md5_init_limK_to_64(ses->server->mac_signing_key, 16, &context); >+ hmac_md5_init_limK_to_64(ses->server->ntlmv2_hash, 16, &context); > >- hmac_md5_update(v2_session_response+8, >+ hmac_md5_update(v2_session_response+8, > sizeof(struct ntlmv2_resp) - 8, &context); > > hmac_md5_final(v2_session_response,&context); >diff --git a/fs/cifs/cifsglob.h b/fs/cifs/cifsglob.h >index 85ebf97..30c5cf6 100644 >--- a/fs/cifs/cifsglob.h >+++ b/fs/cifs/cifsglob.h >@@ -113,6 +113,17 @@ enum protocolEnum { > /* Netbios frames protocol not supported at this time */ > }; > >+struct mac_key { >+ unsigned int len; >+ union { >+ char ntlm[CIFS_SESS_KEY_SIZE + 16]; >+ struct { >+ char key[16]; >+ struct ntlmv2_resp resp; >+ } ntlmv2; >+ } data; >+}; >+ > /* > ***************************************************************** > * Except the CIFS PDUs themselves all the >@@ -168,7 +179,8 @@ struct TCP_Server_Info { > /* 16th byte of RFC1001 workstation name is always null */ > char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL]; > __u32 sequence_number; /* needed for CIFS PDU signature */ >- char mac_signing_key[CIFS_SESS_KEY_SIZE + 16]; >+ struct mac_key mac_signing_key; >+ char ntlmv2_hash[16]; > unsigned long lstrp; /* when we got last response from this server */ > }; > >diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >index 9332204..5193d10 100644 >--- a/fs/cifs/cifsproto.h >+++ b/fs/cifs/cifsproto.h >@@ -320,9 +320,11 @@ extern int cifs_reconnect(struct TCP_Server_Info *server); > extern int cifs_sign_smb(struct smb_hdr *, struct TCP_Server_Info *,__u32 *); > extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, > __u32 *); >-extern int cifs_verify_signature(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); >+extern int cifs_verify_signature(struct smb_hdr *, >+ const struct mac_key *mac_key, >+ __u32 expected_sequence_number); >+extern int cifs_calculate_mac_key(struct mac_key *key,const char *rn, >+ const char *pass); > extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, > const struct nls_table *); > extern void CalcNTLMv2_response(const struct cifsSesInfo *, char * ); >diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c >index 3828922..8f6c83b 100644 >--- a/fs/cifs/connect.c >+++ b/fs/cifs/connect.c >@@ -3504,7 +3504,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > > if(first_time) > cifs_calculate_mac_key( >- pSesInfo->server->mac_signing_key, >+ &pSesInfo->server->mac_signing_key, > ntlm_session_key, > pSesInfo->password); > } >@@ -3524,7 +3524,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo, > > if(first_time) > cifs_calculate_mac_key( >- pSesInfo->server->mac_signing_key, >+ &pSesInfo->server->mac_signing_key, > ntlm_session_key, pSesInfo->password); > > rc = CIFSSessSetup(xid, pSesInfo, >diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c >index a99c40d..b41bfd8 100644 >--- a/fs/cifs/sess.c >+++ b/fs/cifs/sess.c >@@ -427,7 +427,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, > > if(first_time) /* should this be moved into common code > with similar ntlmv2 path? */ >- cifs_calculate_mac_key(ses->server->mac_signing_key, >+ cifs_calculate_mac_key(&ses->server->mac_signing_key, > ntlm_session_key, ses->password); > /* copy session key */ > >diff --git a/fs/cifs/transport.c b/fs/cifs/transport.c >index 1423e98..db2d214 100644 >--- a/fs/cifs/transport.c >+++ b/fs/cifs/transport.c >@@ -651,7 +651,7 @@ SendReceive2(const unsigned int xid, struct cifsSesInfo *ses, > (ses->server->secMode & (SECMODE_SIGN_REQUIRED | > SECMODE_SIGN_ENABLED))) { > rc = cifs_verify_signature(midQ->resp_buf, >- ses->server->mac_signing_key, >+ &ses->server->mac_signing_key, > midQ->sequence_number+1); > if(rc) { > cERROR(1,("Unexpected SMB signature")); >@@ -840,7 +840,7 @@ SendReceive(const unsigned int xid, struct cifsSesInfo *ses, > (ses->server->secMode & (SECMODE_SIGN_REQUIRED | > SECMODE_SIGN_ENABLED))) { > rc = cifs_verify_signature(out_buf, >- ses->server->mac_signing_key, >+ &ses->server->mac_signing_key, > midQ->sequence_number+1); > if(rc) { > cERROR(1,("Unexpected SMB signature")); >@@ -1084,7 +1084,7 @@ SendReceiveBlockingLock(const unsigned int xid, struct cifsTconInfo *tcon, > (ses->server->secMode & (SECMODE_SIGN_REQUIRED | > SECMODE_SIGN_ENABLED))) { > rc = cifs_verify_signature(out_buf, >- ses->server->mac_signing_key, >+ &ses->server->mac_signing_key, > midQ->sequence_number+1); > if(rc) { > cERROR(1,("Unexpected SMB signature")); >-- >1.5.3.3 >
You cannot view the attachment while viewing its details because your browser does not support IFRAMEs.
View the attachment on a separate page
.
View Attachment As Diff
View Attachment As Raw
Actions:
View
|
Diff
Attachments on
bug 414151
: 279861