On Mon, 11 Apr 2011 12:21:59 -0500 Shirish Pargaonkar <shirishpargaonkar@xxxxxxxxx> wrote: > On Sun, Mar 27, 2011 at 7:56 AM, 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 */); > > > >    Â/* 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; > > > > 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? -- Jeff Layton <jlayton@xxxxxxxxxx> -- 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