@@ -1014,6 +1014,9 @@ cifs_parse_mount_options(char *options, const char *devname,
/* BB is there a better way to do this? */
vol->secFlg |= CIFSSEC_MAY_NTLMV2;
#ifdef CONFIG_CIFS_WEAK_PW_HASH
+ } else if (strnicmp(value, "lanmani", 7) == 0) {
+ vol->secFlg |= CIFSSEC_MAY_LANMAN |
+ CIFSSEC_MUST_SIGN;
} else if (strnicmp(value, "lanman", 6) == 0) {
vol->secFlg |= CIFSSEC_MAY_LANMAN;
#endif
@@ -656,13 +656,13 @@ ssetup_ntlmssp_authenticate:
if (type == LANMAN) {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
- char lnm_session_key[CIFS_SESS_KEY_SIZE];
+ char lnm_session_key[CIFS_AUTH_RESP_SIZE];
pSMB->req.hdr.Flags2 &= ~SMBFLG2_UNICODE;
/* no capabilities flags in old lanman negotiation */
- pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
+ pSMB->old_req.PasswordLength = cpu_to_le16(CIFS_AUTH_RESP_SIZE);
/* Calculate hash with password and copy into bcc_ptr.
* Encryption Key (stored as in cryptkey) gets used if the
@@ -675,8 +675,8 @@ ssetup_ntlmssp_authenticate:
true : false, lnm_session_key);
ses->flags |= CIFS_SES_LANMAN;
- memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE);
- bcc_ptr += CIFS_SESS_KEY_SIZE;
+ memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_AUTH_RESP_SIZE);
+ bcc_ptr += CIFS_AUTH_RESP_SIZE;
/* can not sign if LANMAN negotiated so no need
to calculate signing key? but what if server
@@ -299,6 +299,20 @@ dohash(char *out, char *in, char *key, int forw)
kfree(ki);
}
+static int
+odd_parity(unsigned char c)
+{
+ int i;
+ int val = 0x80;
+ int count = 0;
+
+ for (i = 0; i < 7; ++i)
+ if (c & (val >> i))
+ ++count;
+
+ return count % 2;
+}
+
static void
str_to_key(unsigned char *str, unsigned char *key)
{
@@ -312,8 +326,11 @@ str_to_key(unsigned char *str, unsigned char *key)
key[5] = ((str[4] & 0x1F) << 2) | (str[5] >> 6);
key[6] = ((str[5] & 0x3F) << 1) | (str[6] >> 7);
key[7] = str[6] & 0x7F;
- for (i = 0; i < 8; i++)
+ for (i = 0; i < 8; i++) {
key[i] = (key[i] << 1);
+ if (!odd_parity(key[i]))
+ key[i] |= 0x1; /* add odd parity bit */
+ }
}
static void