On Fri, Apr 8, 2011 at 8:31 AM, Jeff Layton <jlayton@xxxxxxxxxxxxxxx> wrote: > On Sun, 27 Mar 2011 14:56:48 +0200 > Oskar Liljeblad <oskar@xxxxxxxxxxx> wrote: > >> 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.) >> >> Signed-off-by: Oskar Liljeblad <oskar@xxxxxxxxxxx> >> --- >> 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(-) >> >> diff --git a/fs/cifs/cifsencrypt.c b/fs/cifs/cifsencrypt.c >> index 5bb4b09..3c1306d 100644 >> --- a/fs/cifs/cifsencrypt.c >> +++ b/fs/cifs/cifsencrypt.c >> @@ -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); >> diff --git a/fs/cifs/cifsproto.h b/fs/cifs/cifsproto.h >> index e42dc82..fd6d873 100644 >> --- a/fs/cifs/cifsproto.h >> +++ b/fs/cifs/cifsproto.h >> @@ -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 */ >> diff --git a/fs/cifs/connect.c b/fs/cifs/connect.c >> index 96544a4..3c0190f 100644 >> --- a/fs/cifs/connect.c >> +++ b/fs/cifs/connect.c >> @@ -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) { >> diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c >> index 6b140e1..17ae0db 100644 >> --- a/fs/cifs/sess.c >> +++ b/fs/cifs/sess.c >> @@ -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; >> diff --git a/fs/cifs/smbencrypt.c b/fs/cifs/smbencrypt.c >> index 1525d5e..92291c1 100644 >> --- a/fs/cifs/smbencrypt.c >> +++ b/fs/cifs/smbencrypt.c >> @@ -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; >> @@ -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? >> >> /* 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 majordomo@xxxxxxxxxxxxxxx >> More majordomo info at http://vger.kernel.org/majordomo-info.html > > > -- > Jeff Layton <jlayton@xxxxxxxxxxxxxxx> > Indeed, missed that. -- To unsubscribe from this list: send the line "unsubscribe linux-cifs" in the body of a message to majordomo@xxxxxxxxxxxxxxx More majordomo info at http://vger.kernel.org/majordomo-info.html