Skip to content

Commit

Permalink
---
Browse files Browse the repository at this point in the history
yaml
---
r: 30871
b: refs/heads/master
c: 7c7b25b
h: refs/heads/master
i:
  30869: 39ae18b
  30867: c5b0942
  30863: 299500b
v: v3
  • Loading branch information
Steve French committed Jun 1, 2006
1 parent f33f678 commit 7505e57
Show file tree
Hide file tree
Showing 10 changed files with 151 additions and 76 deletions.
2 changes: 1 addition & 1 deletion [refs]
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
---
refs/heads/master: 9c53588ec96d85f82e9bf3fb1af7cca31056e940
refs/heads/master: 7c7b25bc8e392aea781324efa771bc191377b876
4 changes: 2 additions & 2 deletions trunk/fs/cifs/cifs_debug.c
Original file line number Diff line number Diff line change
Expand Up @@ -508,7 +508,7 @@ cifs_proc_init(void)
pde->write_proc = multiuser_mount_write;

pde =
create_proc_read_entry("ExtendedSecurity", 0, proc_fs_cifs,
create_proc_read_entry("SecurityFlags", 0, proc_fs_cifs,
extended_security_read, NULL);
if (pde)
pde->write_proc = extended_security_write;
Expand Down Expand Up @@ -547,7 +547,7 @@ cifs_proc_clean(void)
remove_proc_entry("MultiuserMount", proc_fs_cifs);
remove_proc_entry("OplockEnabled", proc_fs_cifs);
/* remove_proc_entry("NTLMV2Enabled",proc_fs_cifs); */
remove_proc_entry("ExtendedSecurity",proc_fs_cifs);
remove_proc_entry("SecurityFlags",proc_fs_cifs);
/* remove_proc_entry("PacketSigningEnabled",proc_fs_cifs); */
remove_proc_entry("LinuxExtensionsEnabled",proc_fs_cifs);
remove_proc_entry("Experimental",proc_fs_cifs);
Expand Down
40 changes: 37 additions & 3 deletions trunk/fs/cifs/cifsencrypt.c
Original file line number Diff line number Diff line change
Expand Up @@ -26,6 +26,7 @@
#include "md5.h"
#include "cifs_unicode.h"
#include "cifsproto.h"
#include <linux/ctype.h>

/* Calculate and return the CIFS signature based on the mac key and the smb pdu */
/* the 16 byte signature must be allocated by the caller */
Expand All @@ -35,6 +36,8 @@

extern void mdfour(unsigned char *out, unsigned char *in, int n);
extern void E_md4hash(const unsigned char *passwd, unsigned char *p16);
extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
unsigned char *p24);

static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu,
const char * key, char * signature)
Expand All @@ -45,7 +48,7 @@ static int cifs_calculate_signature(const struct smb_hdr * cifs_pdu,
return -EINVAL;

MD5Init(&context);
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16);
MD5Update(&context,cifs_pdu->Protocol,cifs_pdu->smb_buf_length);
MD5Final(signature,&context);
return 0;
Expand Down Expand Up @@ -90,7 +93,7 @@ static int cifs_calc_signature2(const struct kvec * iov, int n_vec,
return -EINVAL;

MD5Init(&context);
MD5Update(&context,key,CIFS_SESSION_KEY_SIZE+16);
MD5Update(&context,key,CIFS_SESS_KEY_SIZE+16);
for(i=0;i<n_vec;i++) {
if(iov[i].iov_base == NULL) {
cERROR(1,("null iovec entry"));
Expand Down Expand Up @@ -204,7 +207,7 @@ int cifs_calculate_mac_key(char * key, const char * rn, const char * password)

E_md4hash(password, temp_key);
mdfour(key,temp_key,16);
memcpy(key+16,rn, CIFS_SESSION_KEY_SIZE);
memcpy(key+16,rn, CIFS_SESS_KEY_SIZE);
return 0;
}

Expand Down Expand Up @@ -261,6 +264,37 @@ int CalcNTLMv2_partial_mac_key(struct cifsSesInfo * ses, struct nls_table * nls_
kfree(unicode_buf);
return 0;
}

#ifdef CONFIG_CIFS_WEAK_PW_HASH
void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key)
{
int i;
char password_with_pad[CIFS_ENCPWD_SIZE];

memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE);

/* calculate old style session key */
/* calling toupper is less broken than repeatedly
calling nls_toupper would be since that will never
work for UTF8, but neither handles multibyte code pages
but the only alternative would be converting to UCS-16 (Unicode)
(using a routine something like UniStrupr) then
uppercasing and then converting back from Unicode - which
would only worth doing it if we knew it were utf8. Basically
utf8 and other multibyte codepages each need their own strupper
function since a byte at a time will ont work. */

for(i = 0; i < CIFS_ENCPWD_SIZE; i++) {
password_with_pad[i] = toupper(password_with_pad[i]);
}

SMBencrypt(password_with_pad, ses->server->cryptKey, lnm_session_key);
/* clear password before we return/free memory */
memset(password_with_pad, 0, CIFS_ENCPWD_SIZE);
}
#endif /* CIFS_WEAK_PW_HASH */

void CalcNTLMv2_response(const struct cifsSesInfo * ses,char * v2_session_response)
{
struct HMACMD5Context context;
Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/cifs/cifsglob.h
Original file line number Diff line number Diff line change
Expand Up @@ -158,7 +158,7 @@ struct TCP_Server_Info {
/* 16th byte of RFC1001 workstation name is always null */
char workstation_RFC1001_name[SERVER_NAME_LEN_WITH_NULL];
__u32 sequence_number; /* needed for CIFS PDU signature */
char mac_signing_key[CIFS_SESSION_KEY_SIZE + 16];
char mac_signing_key[CIFS_SESS_KEY_SIZE + 16];
};

/*
Expand Down
3 changes: 2 additions & 1 deletion trunk/fs/cifs/cifspdu.h
Original file line number Diff line number Diff line change
Expand Up @@ -116,7 +116,8 @@
/*
* Size of the session key (crypto key encrypted with the password
*/
#define CIFS_SESSION_KEY_SIZE (24)
#define CIFS_SESS_KEY_SIZE (24)
#define V2_SESS_KEY_SIZE (86)

/*
* Maximum user name length
Expand Down
3 changes: 3 additions & 0 deletions trunk/fs/cifs/cifsproto.h
Original file line number Diff line number Diff line change
Expand Up @@ -287,6 +287,9 @@ extern int cifs_verify_signature(struct smb_hdr *, const char * mac_key,
extern int cifs_calculate_mac_key(char * key,const char * rn,const char * pass);
extern int CalcNTLMv2_partial_mac_key(struct cifsSesInfo *, struct nls_table *);
extern void CalcNTLMv2_response(const struct cifsSesInfo *,char * );
#ifdef CONFIG_CIFS_WEAK_PW_HASH
extern void calc_lanman_hash(struct cifsSesInfo * ses, char * lnm_session_key);
#endif /* CIFS_WEAK_PW_HASH */
extern int CIFSSMBCopy(int xid,
struct cifsTconInfo *source_tcon,
const char *fromName,
Expand Down
27 changes: 22 additions & 5 deletions trunk/fs/cifs/cifssmb.c
Original file line number Diff line number Diff line change
Expand Up @@ -438,12 +438,19 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
goto neg_err_exit;
} else if((pSMBr->hdr.WordCount == 13) &&
(pSMBr->DialectIndex == LANMAN_PROT)) {
#ifdef CONFIG_CIFS_WEAK_PW_HASH
struct lanman_neg_rsp * rsp =
(struct lanman_neg_rsp *)pSMBr;


/* BB Mark ses struct as negotiated lanman level BB */
server->secType = LANMAN;
if((extended_security & CIFSSEC_MAY_LANMAN) ||
(extended_security & CIFSSEC_MAY_PLNTXT))
server->secType = LANMAN;
else {
cERROR(1, ("mount failed weak security disabled"
" in /proc/fs/cifs/SecurityFlags"));
rc = -EOPNOTSUPP;
goto neg_err_exit;
}
server->secMode = (__u8)le16_to_cpu(rsp->SecurityMode);
server->maxReq = le16_to_cpu(rsp->MaxMpxCount);
server->maxBuf = min((__u32)le16_to_cpu(rsp->MaxBufSize),
Expand All @@ -469,6 +476,11 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
}

cFYI(1,("LANMAN negotiated")); /* BB removeme BB */
#else /* weak security disabled */
cERROR(1,("mount failed, cifs module not built with "
"CIFS_WEAK_PW_HASH support"));
rc = -EOPNOTSUPP;
#endif /* WEAK_PW_HASH */
goto neg_err_exit;
} else if(pSMBr->hdr.WordCount != 17) {
/* unknown wct */
Expand All @@ -479,8 +491,13 @@ CIFSSMBNegotiate(unsigned int xid, struct cifsSesInfo *ses)
server->secMode = pSMBr->SecurityMode;
if((server->secMode & SECMODE_USER) == 0)
cFYI(1,("share mode security"));
server->secType = NTLM; /* BB override default for
NTLMv2 or kerberos v5 */

if(extended_security & CIFSSEC_MUST_NTLMV2)
server->secType = NTLMv2;
else
server->secType = NTLM;
/* else krb5 ... */

/* one byte - no need to convert this or EncryptionKeyLen
from little endian */
server->maxReq = le16_to_cpu(pSMBr->MaxMpxCount);
Expand Down
47 changes: 29 additions & 18 deletions trunk/fs/cifs/connect.c
Original file line number Diff line number Diff line change
Expand Up @@ -1990,7 +1990,7 @@ cifs_mount(struct super_block *sb, struct cifs_sb_info *cifs_sb,

static int
CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
char session_key[CIFS_SESSION_KEY_SIZE],
char session_key[CIFS_SESS_KEY_SIZE],
const struct nls_table *nls_codepage)
{
struct smb_hdr *smb_buffer;
Expand Down Expand Up @@ -2048,15 +2048,15 @@ CIFSSessSetup(unsigned int xid, struct cifsSesInfo *ses,
pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities);

pSMB->req_no_secext.CaseInsensitivePasswordLength =
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
cpu_to_le16(CIFS_SESS_KEY_SIZE);

pSMB->req_no_secext.CaseSensitivePasswordLength =
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
cpu_to_le16(CIFS_SESS_KEY_SIZE);
bcc_ptr = pByteArea(smb_buffer);
memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
bcc_ptr += CIFS_SESSION_KEY_SIZE;
memcpy(bcc_ptr, (char *) session_key, CIFS_SESSION_KEY_SIZE);
bcc_ptr += CIFS_SESSION_KEY_SIZE;
memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
bcc_ptr += CIFS_SESS_KEY_SIZE;
memcpy(bcc_ptr, (char *) session_key, CIFS_SESS_KEY_SIZE);
bcc_ptr += CIFS_SESS_KEY_SIZE;

if (ses->capabilities & CAP_UNICODE) {
if ((long) bcc_ptr % 2) { /* must be word aligned for Unicode */
Expand Down Expand Up @@ -3004,14 +3004,14 @@ CIFSNTLMSSPAuthSessSetup(unsigned int xid, struct cifsSesInfo *ses,
SecurityBlob->LmChallengeResponse.Buffer = 0;

SecurityBlob->NtChallengeResponse.Length =
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
cpu_to_le16(CIFS_SESS_KEY_SIZE);
SecurityBlob->NtChallengeResponse.MaximumLength =
cpu_to_le16(CIFS_SESSION_KEY_SIZE);
memcpy(bcc_ptr, ntlm_session_key, CIFS_SESSION_KEY_SIZE);
cpu_to_le16(CIFS_SESS_KEY_SIZE);
memcpy(bcc_ptr, ntlm_session_key, CIFS_SESS_KEY_SIZE);
SecurityBlob->NtChallengeResponse.Buffer =
cpu_to_le32(SecurityBlobLength);
SecurityBlobLength += CIFS_SESSION_KEY_SIZE;
bcc_ptr += CIFS_SESSION_KEY_SIZE;
SecurityBlobLength += CIFS_SESS_KEY_SIZE;
bcc_ptr += CIFS_SESS_KEY_SIZE;

if (ses->capabilities & CAP_UNICODE) {
if (domain == NULL) {
Expand Down Expand Up @@ -3350,22 +3350,33 @@ CIFSTCon(unsigned int xid, struct cifsSesInfo *ses,
bcc_ptr = &pSMB->Password[0];
if((ses->server->secMode) & SECMODE_USER) {
pSMB->PasswordLength = cpu_to_le16(1); /* minimum */
*bcc_ptr = 0; /* password is null byte */
bcc_ptr++; /* skip password */
/* already aligned so no need to do it below */
} else {
pSMB->PasswordLength = cpu_to_le16(CIFS_SESSION_KEY_SIZE);
pSMB->PasswordLength = cpu_to_le16(CIFS_SESS_KEY_SIZE);
/* BB FIXME add code to fail this if NTLMv2 or Kerberos
specified as required (when that support is added to
the vfs in the future) as only NTLM or the much
weaker LANMAN (which we do not send) is accepted
weaker LANMAN (which we do not send by default) is accepted
by Samba (not sure whether other servers allow
NTLMv2 password here) */
#ifdef CONFIG_CIFS_WEAK_PW_HASH
if((extended_security & CIFSSEC_MAY_LANMAN) &&
(ses->server->secType == LANMAN))
calc_lanman_hash(ses, bcc_ptr);
else
#endif /* CIFS_WEAK_PW_HASH */
SMBNTencrypt(ses->password,
ses->server->cryptKey,
bcc_ptr);

bcc_ptr += CIFS_SESSION_KEY_SIZE;
*bcc_ptr = 0;
bcc_ptr++; /* align */
bcc_ptr += CIFS_SESS_KEY_SIZE;
if(ses->capabilities & CAP_UNICODE) {
/* must align unicode strings */
*bcc_ptr = 0; /* null byte password */
bcc_ptr++;
}
}

if(ses->server->secMode &
Expand Down Expand Up @@ -3507,7 +3518,7 @@ int cifs_setup_session(unsigned int xid, struct cifsSesInfo *pSesInfo,
struct nls_table * nls_info)
{
int rc = 0;
char ntlm_session_key[CIFS_SESSION_KEY_SIZE];
char ntlm_session_key[CIFS_SESS_KEY_SIZE];
int ntlmv2_flag = FALSE;
int first_time = 0;

Expand Down
2 changes: 1 addition & 1 deletion trunk/fs/cifs/netmisc.c
Original file line number Diff line number Diff line change
Expand Up @@ -84,7 +84,7 @@ static const struct smb_to_posix_error mapping_table_ERRDOS[] = {

static const struct smb_to_posix_error mapping_table_ERRSRV[] = {
{ERRerror, -EIO},
{ERRbadpw, -EPERM},
{ERRbadpw, -EACCES}, /* was EPERM */
{ERRbadtype, -EREMOTE},
{ERRaccess, -EACCES},
{ERRinvtid, -ENXIO},
Expand Down
Loading

0 comments on commit 7505e57

Please sign in to comment.