CIFS: Assume passwords are encoded according to iocharset
Subsystems (2)
PATCH 1/1 CIFS: Assume passwords are encoded according to iocharset
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters > 0xFF).
The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode < 0x100 basically is ISO 8859-1. Software which relies on that will no longer support password chars > 0x7F unless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)
--- fs/cifs/cifsencrypt.c | 8 +++--- fs/cifs/cifsproto.h | 8 ++++-- fs/cifs/connect.c | 2 +- fs/cifs/sess.c | 2 +- fs/cifs/smbencrypt.c | 60 +++++++++---------------------------------------- 5 files changed, 22 insertions(+), 58 deletions(-)
fs/cifs/cifsencrypt.c +4 -4
@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, }/* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) {int rc =0 ;unsigned int temp_len =CIFS_SESS_KEY_SIZE +CIFS_AUTH_RESP_SIZE ;
@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc =SMBNTencrypt (ses->password, ses->server->cryptkey, - ses->auth_key.response +CIFS_SESS_KEY_SIZE ); + ses->auth_key.response +CIFS_SESS_KEY_SIZE , nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NTLM response, error: %d" , __func__, rc);return rc; } - rc =E_md4hash (ses->password, temp_key); + rc =E_md4hash (ses->password, temp_key, nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NT hash, error: %d" , __func__, rc);return rc;
@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, }/* calculate md4 hash of password */ -E_md4hash (ses->password, nt_hash); +E_md4hash (ses->password, nt_hash, nls_cp);crypto_shash_setkey (ses->server->secmech.hmacmd5, nt_hash,CIFS_NTHASH_SIZE );
fs/cifs/cifsproto.h +5 -3
@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,extern int cifs_verify_signature (struct smb_hdr *,struct TCP_Server_Info *server,__u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, +const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *);extern int setup_ntlmv2_rsp (struct cifs_ses *,const struct nls_table *);extern int cifs_crypto_shash_allocate (struct TCP_Server_Info *);extern void cifs_crypto_shash_release (struct TCP_Server_Info *);
@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid);extern int mdfour (unsigned char *,unsigned char *,int ); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage);extern int SMBencrypt (unsigned char *passwd,const unsigned char *c8,unsigned char *p24);#endif /* _CIFSPROTO_H */
fs/cifs/connect.c +1 -1
@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, else#endif /* CIFS_WEAK_PW_HASH */ rc =SMBNTencrypt (tcon->password, ses->server->cryptkey, - bcc_ptr); + bcc_ptr, nls_codepage); bcc_ptr +=CIFS_AUTH_RESP_SIZE ;if (ses->capabilities &CAP_UNICODE ) {
fs/cifs/sess.c +1 -1
@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate:cpu_to_le16 (CIFS_AUTH_RESP_SIZE );/* calculate ntlm response and session key */ - rc =setup_ntlm_response (ses); + rc =setup_ntlm_response (ses, nls_cp);if (rc) {cERROR (1 ,"Error %d during NTLM authentication" , rc); goto ssetup_exit;
fs/cifs/smbencrypt.c +11 -49
98 lines not on this page · raw message
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 143 lines · Oskar Liljeblad
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);bcc_ptr +=
CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-24@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) {
fs/cifs/smbencrypt.c SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) · line 231
Quoted 10 lines
fs/cifs/smbencrypt.c +0
-10- val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} -
Good clean-up of these functions.
Quoted 16 lines
fs/cifs/smbencrypt.c +0
-0/** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +0
-1@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd);
fs/cifs/smbencrypt.c E_md4hash(const unsigned char *passwd, unsigned char *p16) · line 216
Quoted 10 lines
fs/cifs/smbencrypt.c +3
-5- if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */
Perhaps we can use some minor clean-up of this function! I think we should return an error if passwd is NULL. There is no point in doing further processing if password is NULL, auth will fail.
fs/cifs/smbencrypt.c E_md4hash(const unsigned char *passwd, unsigned char *p16) · line 220
Quoted 9 lines
fs/cifs/smbencrypt.c +2
-5+ } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * ); memset(wpwd, 0, 129 * 2);
Perhaps we should use sizeof(__u16) instead of 2!
Quoted 31 lines
fs/cifs/smbencrypt.c +1
-1return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];fs/cifs/smbencrypt.c +1
-1@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21); - rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;
Shirish Pargaonkar
Reviewed-byQuoted 211 lines · Oskar Liljeblad
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);bcc_ptr +=
CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +6
-12@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); memset(wpwd, 0, 129 * 2); return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];
fs/cifs/smbencrypt.c SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) · line 324
Quoted 8 lines
fs/cifs/smbencrypt.c +1
-1@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21); - rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;
But for really minor nits, looks correct.
Quoted 191 lines · On Sun, 27 Mar 2011 14:56:48 +0200 Oskar Liljeblad…
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>--- fs/cifs/cifsencrypt.c | 8 +++--- fs/cifs/cifsproto.h | 8 ++++-- fs/cifs/connect.c | 2 +- fs/cifs/sess.c | 2 +- fs/cifs/smbencrypt.c | 60 +++++++++---------------------------------------- 5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, }/* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) {int rc =0 ;unsigned int temp_len =CIFS_SESS_KEY_SIZE +CIFS_AUTH_RESP_SIZE ;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc =SMBNTencrypt (ses->password, ses->server->cryptkey, - ses->auth_key.response +CIFS_SESS_KEY_SIZE ); + ses->auth_key.response +CIFS_SESS_KEY_SIZE , nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NTLM response, error: %d" , __func__, rc);return rc; } - rc =E_md4hash (ses->password, temp_key); + rc =E_md4hash (ses->password, temp_key, nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NT hash, error: %d" , __func__, rc);return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, }/* calculate md4 hash of password */ -E_md4hash (ses->password, nt_hash); +E_md4hash (ses->password, nt_hash, nls_cp);crypto_shash_setkey (ses->server->secmech.hmacmd5, nt_hash,CIFS_NTHASH_SIZE );fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,extern int cifs_verify_signature (struct smb_hdr *,struct TCP_Server_Info *server,__u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, +const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *);extern int setup_ntlmv2_rsp (struct cifs_ses *,const struct nls_table *);extern int cifs_crypto_shash_allocate (struct TCP_Server_Info *);extern void cifs_crypto_shash_release (struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid);extern int mdfour (unsigned char *,unsigned char *,int ); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage);extern int SMBencrypt (unsigned char *passwd,const unsigned char *c8,unsigned char *p24);#endif /* _CIFSPROTO_H */ fs/cifs/connect.c +1
-1@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, else#endif /* CIFS_WEAK_PW_HASH */ rc =SMBNTencrypt (tcon->password, ses->server->cryptkey, - bcc_ptr); + bcc_ptr, nls_codepage); bcc_ptr +=CIFS_AUTH_RESP_SIZE ;if (ses->capabilities &CAP_UNICODE ) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate:cpu_to_le16 (CIFS_AUTH_RESP_SIZE );/* calculate ntlm response and session key */ - rc =setup_ntlm_response (ses); + rc =setup_ntlm_response (ses, nls_cp);if (rc) {cERROR (1 ,"Error %d during NTLM authentication" , rc); goto ssetup_exit;fs/cifs/smbencrypt.c +7
-46@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ -int len =0 ; -while (*str++ !=0 ) - len++; -return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{/* BB not a very good conversion routine - change/fix */ -int i; -__u16 val; - -for (i =0 ; i < len; i++) { - val = *src; -SSVAL (dst,0 , val); - dst++; - src++; -if (val ==0 ) -break ; - } -return i; -} -/* * Creates the MD4 Hash of the users password in NT UNICODE. */ int -E_md4hash (const unsigned char *passwd,unsigned char *p16) +E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage) {int rc;int len;@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)/* Password cannot be longer than 128 characters */ if (passwd) { - len =strlen ((char *) passwd); -if (len >128 ) - len =128 ; -/* Password must be converted to NT unicode */ -_my_mbstowcs (wpwd, passwd, len); - }else + len =cifs_strtoUCS (wpwd, passwd,128 , codepage); + }else { len =0 ; + *wpwd =0 ;/* Ensure string is null terminated */ + } - wpwd[len] =0 ;/* Ensure string is null terminated */ -/* Calculate length in bytes */ - len =_my_wcslen (wpwd) *sizeof (__u16); - - rc =mdfour (p16, (unsigned char *) wpwd, len); + rc =mdfour (p16, (unsigned char *) wpwd, len *sizeof (__u16));memset (wpwd,0 ,129 *2 );return rc;
fs/cifs/smbencrypt.c nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) · line 239
Quoted 5 lines
fs/cifs/smbencrypt.c +1
-1@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])memcpy (passwd, pwd,512 );/* Calculate the MD4 hash (NT compatible) of the password */ memset (nt_p16,'\0' ,16 ); -E_md4hash (passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */);
^^^^^^^^^^^^^ Won't this fail to compile?
Quoted 26 lines
fs/cifs/smbencrypt.c +3
-3/* Mangle the passwords into Lanman format */ passwd[14 ] ='\0' ;@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8],/* Does the NT MD4 hash then des encryption. */ int -SMBNTencrypt (unsigned char *passwd,unsigned char *c8,unsigned char *p24) +SMBNTencrypt (unsigned char *passwd,unsigned char *c8,unsigned char *p24, +const struct nls_table *codepage) {int rc;unsigned char p16[16 ], p21[21 ];@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24)memset (p16,'\0' ,16 );memset (p21,'\0' ,21 ); - rc =E_md4hash (passwd, p16); + rc =E_md4hash (passwd, p16, codepage);if (rc) {cFYI (1 ,"%s Can't generate NT hash, error: %d" , __func__, rc);return rc; --To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
Signature · 1 line
Jeff Layton <[email protected]>
A message that is not in the archive (sent off-list or not yet received): 20110408093148.748eda25-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org
Quoted 218 lines · Jeff Layton
Quoted 191 lines · On Sun, 27 Mar 2011 14:56:48 +0200 Oskar Liljeblad…
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);
bcc_ptr+=CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +5
-11@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); memset(wpwd, 0, 129 * 2); return rc;fs/cifs/smbencrypt.c nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) · line 239
Quoted 5 lines
fs/cifs/smbencrypt.c +1
-1@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */);^^^^^^^^^^^^^
Won't this fail to compile?Quoted 17 lines
fs/cifs/smbencrypt.c +0
-0/* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];fs/cifs/smbencrypt.c +0
-0@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21);
Quoted 14 lines
Quoted 9 lines
fs/cifs/smbencrypt.c +1
-2- rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc; --To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to [email protected] More majordomo info at http://vger.kernel.org/majordomo-info.html
--
Jeff Layton <[email protected]>
Indeed, missed that.
Quoted 192 lines · Jeff Layton
Quoted 189 lines · On Sun, 27 Mar 2011 14:56:48 +0200 Oskar Liljeblad…
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>--- fs/cifs/cifsencrypt.c | 8 +++--- fs/cifs/cifsproto.h | 8 ++++-- fs/cifs/connect.c | 2 +- fs/cifs/sess.c | 2 +- fs/cifs/smbencrypt.c | 60 +++++++++---------------------------------------- 5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, }/* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) {int rc =0 ;unsigned int temp_len =CIFS_SESS_KEY_SIZE +CIFS_AUTH_RESP_SIZE ;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc =SMBNTencrypt (ses->password, ses->server->cryptkey, - ses->auth_key.response +CIFS_SESS_KEY_SIZE ); + ses->auth_key.response +CIFS_SESS_KEY_SIZE , nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NTLM response, error: %d" , __func__, rc);return rc; } - rc =E_md4hash (ses->password, temp_key); + rc =E_md4hash (ses->password, temp_key, nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NT hash, error: %d" , __func__, rc);return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, }/* calculate md4 hash of password */ -E_md4hash (ses->password, nt_hash); +E_md4hash (ses->password, nt_hash, nls_cp);crypto_shash_setkey (ses->server->secmech.hmacmd5, nt_hash,CIFS_NTHASH_SIZE );fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,extern int cifs_verify_signature (struct smb_hdr *,struct TCP_Server_Info *server,__u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, +const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *);extern int setup_ntlmv2_rsp (struct cifs_ses *,const struct nls_table *);extern int cifs_crypto_shash_allocate (struct TCP_Server_Info *);extern void cifs_crypto_shash_release (struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid);extern int mdfour (unsigned char *,unsigned char *,int ); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage);extern int SMBencrypt (unsigned char *passwd,const unsigned char *c8,unsigned char *p24);#endif /* _CIFSPROTO_H */ fs/cifs/connect.c +1
-1@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, else#endif /* CIFS_WEAK_PW_HASH */ rc =SMBNTencrypt (tcon->password, ses->server->cryptkey, - bcc_ptr); + bcc_ptr, nls_codepage); bcc_ptr +=CIFS_AUTH_RESP_SIZE ;if (ses->capabilities &CAP_UNICODE ) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate:cpu_to_le16 (CIFS_AUTH_RESP_SIZE );/* calculate ntlm response and session key */ - rc =setup_ntlm_response (ses); + rc =setup_ntlm_response (ses, nls_cp);if (rc) {cERROR (1 ,"Error %d during NTLM authentication" , rc); goto ssetup_exit;fs/cifs/smbencrypt.c +7
-46@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ -int len =0 ; -while (*str++ !=0 ) - len++; -return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{/* BB not a very good conversion routine - change/fix */ -int i; -__u16 val; - -for (i =0 ; i < len; i++) { - val = *src; -SSVAL (dst,0 , val); - dst++; - src++; -if (val ==0 ) -break ; - } -return i; -} -/* * Creates the MD4 Hash of the users password in NT UNICODE. */ int -E_md4hash (const unsigned char *passwd,unsigned char *p16) +E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage) {int rc;int len;@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)/* Password cannot be longer than 128 characters */ if (passwd) { - len =strlen ((char *) passwd); -if (len >128 ) - len =128 ; -/* Password must be converted to NT unicode */ -_my_mbstowcs (wpwd, passwd, len); - }else + len =cifs_strtoUCS (wpwd, passwd,128 , codepage); + }else { len =0 ; + *wpwd =0 ;/* Ensure string is null terminated */ + } - wpwd[len] =0 ;/* Ensure string is null terminated */ -/* Calculate length in bytes */ - len =_my_wcslen (wpwd) *sizeof (__u16); - - rc =mdfour (p16, (unsigned char *) wpwd, len); + rc =mdfour (p16, (unsigned char *) wpwd, len *sizeof (__u16));memset (wpwd,0 ,129 *2 );
Quoted 9 lines
fs/cifs/smbencrypt.c nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) · line 239
Quoted 7 lines
fs/cifs/smbencrypt.c +1
-1return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])memcpy (passwd, pwd,512 );/* Calculate the MD4 hash (NT compatible) of the password */ memset (nt_p16,'\0' ,16 ); -E_md4hash (passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */);^^^^^^^^^^^^^ Won't this fail to compile?
Yes, but it's inside a function which is commented out and not compiled. Instead of adding an extra parameter to the function (which would be required) I decided just to put a reminder there if that function is ever used in the future.
#if 0 /* currently unused */
/* Does both the NT and LM owfs of a user's password */ static voidnt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])
{
char passwd[514];
memset(passwd, '\0', 514);
if (strlen(pwd) < 513)
strcpy(passwd, pwd);
else
memcpy(passwd, pwd, 512);
/* Calculate the MD4 hash (NT compatible) of the password */
memset(nt_p16, '\0', 16);
E_md4hash(passwd, nt_p16, /* put nls codepage here */);
/* Mangle the passwords into Lanman format */
passwd[14] = '\0';/* strupper(passwd); */
/* Calculate the SMB (lanman) hash functions of the password */
memset(p16, '\0', 16);
E_P16((unsigned char *) passwd, (unsigned char *) p16);
/* clear out local copy of user's password (just being paranoid). */
memset(passwd, '\0', sizeof(passwd));
}#endif
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 236 lines · On Fri, 8 Apr 2011 16:11:12 +0200 Oskar Liljeblad…
Quoted 192 lines · Jeff Layton
Quoted 189 lines · On Sun, 27 Mar 2011 14:56:48 +0200 Oskar Liljeblad…
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>--- fs/cifs/cifsencrypt.c | 8 +++--- fs/cifs/cifsproto.h | 8 ++++-- fs/cifs/connect.c | 2 +- fs/cifs/sess.c | 2 +- fs/cifs/smbencrypt.c | 60 +++++++++---------------------------------------- 5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, }/* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) {int rc =0 ;unsigned int temp_len =CIFS_SESS_KEY_SIZE +CIFS_AUTH_RESP_SIZE ;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc =SMBNTencrypt (ses->password, ses->server->cryptkey, - ses->auth_key.response +CIFS_SESS_KEY_SIZE ); + ses->auth_key.response +CIFS_SESS_KEY_SIZE , nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NTLM response, error: %d" , __func__, rc);return rc; } - rc =E_md4hash (ses->password, temp_key); + rc =E_md4hash (ses->password, temp_key, nls_cp);if (rc) {cFYI (1 ,"%s Can't generate NT hash, error: %d" , __func__, rc);return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, }/* calculate md4 hash of password */ -E_md4hash (ses->password, nt_hash); +E_md4hash (ses->password, nt_hash, nls_cp);crypto_shash_setkey (ses->server->secmech.hmacmd5, nt_hash,CIFS_NTHASH_SIZE );fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *,extern int cifs_verify_signature (struct smb_hdr *,struct TCP_Server_Info *server,__u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, +const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *);extern int setup_ntlmv2_rsp (struct cifs_ses *,const struct nls_table *);extern int cifs_crypto_shash_allocate (struct TCP_Server_Info *);extern void cifs_crypto_shash_release (struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr,const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid);extern int mdfour (unsigned char *,unsigned char *,int ); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage);extern int SMBencrypt (unsigned char *passwd,const unsigned char *c8,unsigned char *p24);#endif /* _CIFSPROTO_H */ fs/cifs/connect.c +1
-1@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses, else#endif /* CIFS_WEAK_PW_HASH */ rc =SMBNTencrypt (tcon->password, ses->server->cryptkey, - bcc_ptr); + bcc_ptr, nls_codepage); bcc_ptr +=CIFS_AUTH_RESP_SIZE ;if (ses->capabilities &CAP_UNICODE ) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate:cpu_to_le16 (CIFS_AUTH_RESP_SIZE );/* calculate ntlm response and session key */ - rc =setup_ntlm_response (ses); + rc =setup_ntlm_response (ses, nls_cp);if (rc) {cERROR (1 ,"Error %d during NTLM authentication" , rc); goto ssetup_exit;fs/cifs/smbencrypt.c +7
-46@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24)return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ -int len =0 ; -while (*str++ !=0 ) - len++; -return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{/* BB not a very good conversion routine - change/fix */ -int i; -__u16 val; - -for (i =0 ; i < len; i++) { - val = *src; -SSVAL (dst,0 , val); - dst++; - src++; -if (val ==0 ) -break ; - } -return i; -} -/* * Creates the MD4 Hash of the users password in NT UNICODE. */ int -E_md4hash (const unsigned char *passwd,unsigned char *p16) +E_md4hash (const unsigned char *passwd,unsigned char *p16, +const struct nls_table *codepage) {int rc;int len;@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16)/* Password cannot be longer than 128 characters */ if (passwd) { - len =strlen ((char *) passwd); -if (len >128 ) - len =128 ; -/* Password must be converted to NT unicode */ -_my_mbstowcs (wpwd, passwd, len); - }else + len =cifs_strtoUCS (wpwd, passwd,128 , codepage); + }else { len =0 ; + *wpwd =0 ;/* Ensure string is null terminated */ + } - wpwd[len] =0 ;/* Ensure string is null terminated */ -/* Calculate length in bytes */ - len =_my_wcslen (wpwd) *sizeof (__u16); - - rc =mdfour (p16, (unsigned char *) wpwd, len); + rc =mdfour (p16, (unsigned char *) wpwd, len *sizeof (__u16));memset (wpwd,0 ,129 *2 );Quoted 9 lines
fs/cifs/smbencrypt.c nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) · line 239
Quoted 7 lines
fs/cifs/smbencrypt.c +1
-1return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16])memcpy (passwd, pwd,512 );/* Calculate the MD4 hash (NT compatible) of the password */ memset (nt_p16,'\0' ,16 ); -E_md4hash (passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */);^^^^^^^^^^^^^ Won't this fail to compile?Yes, but it's inside a function which is commented out and not compiled. Instead of adding an extra parameter to the function (which would be required) I decided just to put a reminder there if that function is ever used in the future.
#if 0 /* currently unused */
/* Does both the NT and LM owfs of a user's password */ static voidnt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]){ char passwd[514]; memset(passwd, '\0', 514); if (strlen(pwd) < 513) strcpy(passwd, pwd); else memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';/* strupper(passwd); */
/* Calculate the SMB (lanman) hash functions of the password */ memset(p16, '\0', 16); E_P16((unsigned char *) passwd, (unsigned char *) p16); /* clear out local copy of user's password (just being paranoid). */ memset(passwd, '\0', sizeof(passwd)); }
Quoted 1 line
#endif
Ahh, ok. A perfect case to demonstrate why leaving unused crap lying around like this is a bad idea. Perhaps a better scheme would be a separate patch to just remove this function and then rebase your patch on top of that?
Signature · 1 line
Jeff Layton <[email protected]>
A message that is not in the archive (sent off-list or not yet received): 20110408103118.0f1b2e8b-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org
Quoted 241 lines · Jeff Layton
Quoted 230 lines · On Fri, 8 Apr 2011 16:11:12 +0200 Oskar Liljeblad…
Quoted 192 lines · Jeff Layton
Quoted 189 lines · On Sun, 27 Mar 2011 14:56:48 +0200 Oskar Liljeblad…
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc =E_md4hash (ses->password, temp_key); + rc =E_md4hash (ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ -E_md4hash (ses->password, nt_hash); +E_md4hash (ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);
bcc_ptr+=CIFS_AUTH_RESP_SIZE;
if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ -int len =0 ; -while (*str++ !=0 ) - len++; -return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ -int i; -__u16 val; - -for (i =0 ; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } -return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +5
-11@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - }else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + }else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ -/* Calculate length in bytes */ - len =_my_wcslen (wpwd) *sizeof (__u16); - - rc =mdfour (p16, (unsigned char *) wpwd, len); + rc =mdfour (p16, (unsigned char *) wpwd, len *sizeof (__u16)); memset(wpwd, 0, 129 * 2);Quoted 9 lines
fs/cifs/smbencrypt.c nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) · line 239
Quoted 7 lines
fs/cifs/smbencrypt.c +1
-1return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); -E_md4hash (passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */);^^^^^^^^^^^^^
Won't this fail to compile?Yes, but it's inside a function which is commented out and not compiled. Instead of adding an extra parameter to the function (which would be required) I decided just to put a reminder there if that function is ever used in the future.
#if 0 /* currently unused */
/* Does both the NT and LM owfs of a user's password */ static voidnt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]){
char passwd[514];
memset(passwd, '\0', 514);
if (strlen(pwd) < 513)
strcpy(passwd, pwd);
else
memcpy(passwd, pwd, 512);
/* Calculate the MD4 hash (NT compatible) of the password */memset(nt_p16, '\0', 16);
E_md4hash(passwd, nt_p16, /* put nls codepage here */);/* Mangle the passwords into Lanman format */ passwd[14] = '\0';
/* strupper(passwd); *//* Calculate the SMB (lanman) hash functions of the password */
Quoted 7 lines
memset(p16, '\0', 16);
E_P16((unsigned char *) passwd, (unsigned char *) p16);/* clear out local copy of user's password (just being paranoid). */
memset(passwd, '\0', sizeof(passwd));
}
#endif
Quoted 8 lines
Ahh, ok. A perfect case to demonstrate why leaving unused crap lying around like this is a bad idea. Perhaps a better scheme would be a separate patch to just remove this function and then rebase your patch on top of that?
--
Jeff Layton <[email protected]>
I will resubmit this patch in a day to two with Jeff's comments incorporated. It fixes bug 7386 on Samba bugzilla.
Quoted 211 lines · Oskar Liljeblad
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);bcc_ptr +=
CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +6
-12@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); memset(wpwd, 0, 129 * 2); return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];
fs/cifs/smbencrypt.c SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) · line 324
Quoted 8 lines
fs/cifs/smbencrypt.c +1
-1@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21); - rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;
With this patch, I am unable to mount a share if user's password happens to contain characters like $ e.g. aa$a.
A Windows client can.
A message that is not in the archive (sent off-list or not yet received): BANLkTimEhsjo2vfSE1w-D888hWn72H7Y3A-JsoAwUIsXosN+BqQ9rBEUg@public.gmane.org
Quoted 12 lines · Shirish Pargaonkar
Quoted 12 lines
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>
[..]
Quoted 3 lines
With this patch, I am unable to mount a share if user's password happens to contain characters like $ e.g. aa$a.
A Windows client can.
Hmm, strange, I was not able to reproduce this problem with domain accounts on Windows 2008 R2. For me $ worked. (That is with locale utf-8 at least.)
REgards,
OSkar
A message that is not in the archive (sent off-list or not yet received): [email protected]
Quoted 12 lines · Oskar Liljeblad
Quoted 11 lines · Shirish Pargaonkar
Quoted 11 lines
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)
Quoted 8 lines
Quoted 1 line
Quoted 1 line
Signed-off-by Oskar Liljeblad <[email protected]>[..]
Quoted 3 lines
With this patch, I am unable to mount a share if user's password happens to contain characters like $ e.g. aa$a.
A Windows client can.Hmm, strange, I was not able to reproduce this problem with domain accounts on Windows 2008 R2. For me $ worked. (That is with locale utf-8 at least.)
I'm sorry, please disregard my comment. I tested with the wrong kernel. I will try again.
Regards,
Oskar
Quoted 214 lines · On Mon, 11 Apr 2011 12:21:59 -0500 Shirish Pargaonkar…
Quoted 213 lines · Oskar Liljeblad
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);bcc_ptr +=
CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +6
-12@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); memset(wpwd, 0, 129 * 2); return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];fs/cifs/smbencrypt.c +0
-0@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21);
Quoted 10 lines
fs/cifs/smbencrypt.c SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) · line 324
Quoted 6 lines
fs/cifs/smbencrypt.c +1
-1- rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;With this patch, I am unable to mount a share if user's password happens to contain characters like $ e.g. aa$a.
A Windows client can.
If you compare traces in wireshark, are there differences in how the username is encoded?
Signature · 1 line
Jeff Layton <[email protected]>
A message that is not in the archive (sent off-list or not yet received): 20110411151637.640495a5-4QP7MXygkU+dMjc06nkz3ljfA9RmPOcC@public.gmane.org
Quoted 228 lines · Jeff Layton
Quoted 214 lines · On Mon, 11 Apr 2011 12:21:59 -0500 Shirish Pargaonkar…
Quoted 213 lines · Oskar Liljeblad
Modify cifs to assume that the supplied password is encoded according to iocharset. Before this patch passwords would be treated as raw 8-bit data, which made authentication with Unicode passwords impossible (at least passwords with characters >
0xFF).The previous code would as a side effect accept passwords encoded with ISO 8859-1, since Unicode <
0x100basically is ISO 8859-1. Software which relies on that will no longer support password chars >0x7Funless it also uses iocharset=iso8859-1. (mount.cifs does not care about the encoding so it will work as expected.)Signed-off-by Oskar Liljeblad <[email protected]>---
fs/cifs/cifsencrypt.c | 8 +++---
fs/cifs/cifsproto.h | 8 ++++--
fs/cifs/connect.c | 2 +-
fs/cifs/sess.c | 2 +-
fs/cifs/smbencrypt.c | 60 +++++++++----------------------------------------5 files changed, 22 insertions(+), 58 deletions(-)fs/cifs/cifsencrypt.c +4
-4@@ -226,7 +226,7 @@ int cifs_verify_signature(struct smb_hdr *cifs_pdu, } /* first calculate 24 bytes ntlm response and then 16 byte session key */ -int setup_ntlm_response (struct cifs_ses *ses) +int setup_ntlm_response (struct cifs_ses *ses,const struct nls_table *nls_cp) { int rc = 0; unsigned int temp_len = CIFS_SESS_KEY_SIZE + CIFS_AUTH_RESP_SIZE;@@ -243,14 +243,14 @@ int setup_ntlm_response(struct cifs_ses *ses) ses->auth_key.len = temp_len; rc = SMBNTencrypt(ses->password, ses->server->cryptkey, - ses->auth_key.response + CIFS_SESS_KEY_SIZE); + ses->auth_key.response + CIFS_SESS_KEY_SIZE, nls_cp); if (rc) { cFYI(1, "%s Can't generate NTLM response, error: %d", __func__, rc); return rc; } - rc = E_md4hash(ses->password, temp_key); + rc = E_md4hash(ses->password, temp_key, nls_cp); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;@@ -458,7 +458,7 @@ static int calc_ntlmv2_hash(struct cifs_ses *ses, char *ntlmv2_hash, } /* calculate md4 hash of password */ - E_md4hash(ses->password, nt_hash); + E_md4hash(ses->password, nt_hash, nls_cp); crypto_shash_setkey(ses->server->secmech.hmacmd5, nt_hash, CIFS_NTHASH_SIZE);fs/cifs/cifsproto.h +5
-3@@ -376,8 +376,9 @@ extern int cifs_sign_smb2(struct kvec *iov, int n_vec, struct TCP_Server_Info *, extern int cifs_verify_signature(struct smb_hdr *, struct TCP_Server_Info *server, __u32 expected_sequence_number); -extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *); -extern int setup_ntlm_response (struct cifs_ses *); +extern int SMBNTencrypt (unsigned char *,unsigned char *,unsigned char *, + const struct nls_table *); +extern int setup_ntlm_response (struct cifs_ses *,const struct nls_table *); extern int setup_ntlmv2_rsp(struct cifs_ses *, const struct nls_table *); extern int cifs_crypto_shash_allocate(struct TCP_Server_Info *); extern void cifs_crypto_shash_release(struct TCP_Server_Info *);@@ -429,7 +430,8 @@ extern int CIFSCheckMFSymlink(struct cifs_fattr *fattr, const unsigned char *path, struct cifs_sb_info *cifs_sb, int xid); extern int mdfour(unsigned char *, unsigned char *, int); -extern int E_md4hash (const unsigned char *passwd,unsigned char *p16); +extern int E_md4hash (const unsigned char *passwd,unsigned char *p16, + const struct nls_table *codepage); extern int SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24); #endif /* _CIFSPROTO_H */fs/cifs/connect.c +0
-0@@ -3060,7 +3060,7 @@ CIFSTCon(unsigned int xid, struct cifs_ses *ses,else
#endif /*CIFS_WEAK_PW_HASH*/
rc = SMBNTencrypt(tcon->password,ses->server->cryptkey,
-bcc_ptr);
+bcc_ptr,nls_codepage);bcc_ptr +=
CIFS_AUTH_RESP_SIZE; if (ses->capabilities&CAP_UNICODE) {fs/cifs/sess.c +1
-1@@ -694,7 +694,7 @@ ssetup_ntlmssp_authenticate: cpu_to_le16(CIFS_AUTH_RESP_SIZE); /* calculate ntlm response and session key */ - rc = setup_ntlm_response(ses); + rc = setup_ntlm_response(ses, nls_cp); if (rc) { cERROR(1, "Error %d during NTLM authentication", rc); goto ssetup_exit;fs/cifs/smbencrypt.c +0
-34@@ -195,46 +195,13 @@ SMBencrypt(unsigned char *passwd, const unsigned char *c8, unsigned char *p24) return rc; } -/* Routines for Windows NT MD4 Hash functions. */ -static int -_my_wcslen (__u16 *str) -{ - int len = 0; - while (*str++ != 0) - len++; - return len; -} - -/* -* Convert a string into an NT UNICODE string. -* Note that regardless of processor type -* this must be in intel (little-endian) -* format. -*/ - -static int -_my_mbstowcs (__u16 *dst,const unsigned char *src,int len) -{ /* BB not a very good conversion routine - change/fix */ - int i; - __u16 val; - - for (i = 0; i < len; i++) { - val = *src; - SSVAL(dst, 0, val); - dst++; - src++; - if (val == 0) - break; - } - return i; -} - /** Creates the MD4 Hash of the users password in NT UNICODE. */ int
fs/cifs/smbencrypt.c +2
-1-E_md4hash(const unsigned char *passwd, unsigned char *p16) +E_md4hash(const unsigned char *passwd, unsigned char *p16, + const struct nls_table *codepage){
int rc;
int len;fs/cifs/smbencrypt.c +6
-12@@ -242,20 +209,14 @@ E_md4hash(const unsigned char *passwd, unsigned char *p16) /* Password cannot be longer than 128 characters */ if (passwd) { - len = strlen((char *) passwd); - if (len > 128) - len = 128; - /* Password must be converted to NT unicode */ - _my_mbstowcs(wpwd, passwd, len); - } else + len = cifs_strtoUCS(wpwd, passwd, 128, codepage); + } else { len = 0; + *wpwd = 0; /* Ensure string is null terminated */ + } - wpwd[len] = 0; /* Ensure string is null terminated */ - /* Calculate length in bytes */ - len = _my_wcslen(wpwd) * sizeof(__u16); - - rc = mdfour(p16, (unsigned char *) wpwd, len); + rc = mdfour(p16, (unsigned char *) wpwd, len * sizeof(__u16)); memset(wpwd, 0, 129 * 2); return rc;@@ -275,7 +236,7 @@ nt_lm_owf_gen(char *pwd, unsigned char nt_p16[16], unsigned char p16[16]) memcpy(passwd, pwd, 512); /* Calculate the MD4 hash (NT compatible) of the password */ memset(nt_p16, '\0', 16); - E_md4hash(passwd, nt_p16); + E_md4hash(passwd, nt_p16, /* put nls codepage here */); /* Mangle the passwords into Lanman format */ passwd[14] = '\0';@@ -348,7 +309,8 @@ NTLMSSPOWFencrypt(unsigned char passwd[8], /* Does the NT MD4 hash then des encryption. */int
fs/cifs/smbencrypt.c +2
-1-SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) +SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24, + const struct nls_table *codepage){
int rc;
unsigned char p16[16], p21[21];fs/cifs/smbencrypt.c +0
-0@@ -356,7 +318,7 @@ SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) memset(p16, '\0', 16); memset(p21, '\0', 21);Quoted 10 lines
fs/cifs/smbencrypt.c SMBNTencrypt(unsigned char *passwd, unsigned char *c8, unsigned char *p24) · line 324
Quoted 6 lines
fs/cifs/smbencrypt.c +1
-1- rc = E_md4hash(passwd, p16); + rc = E_md4hash(passwd, p16, codepage); if (rc) { cFYI(1, "%s Can't generate NT hash, error: %d", __func__, rc); return rc;With this patch, I am unable to mount a share if user's password happens to contain characters like $ e.g. aa$a.
A Windows client can.
Quoted 5 lines
If you compare traces in wireshark, are there differences in how the username is encoded?
--
Jeff Layton <[email protected]>
No differences. It is purely password that is making the difference. I compared traces when both cifs and Windows clients were using ntlmssp auth mech.