diff options
author | Steve French <sfrench@us.ibm.com> | 2006-06-01 15:20:10 -0400 |
---|---|---|
committer | Steve French <sfrench@us.ibm.com> | 2006-06-01 15:20:10 -0400 |
commit | 7c7b25bc8e392aea781324efa771bc191377b876 (patch) | |
tree | ddad1a91f948746dbef140994c615253a7f42e65 /fs/cifs/sess.c | |
parent | 9c53588ec96d85f82e9bf3fb1af7cca31056e940 (diff) |
[CIFS] Support for setting up SMB sessions to legacy lanman servers part 2
Diffstat (limited to 'fs/cifs/sess.c')
-rw-r--r-- | fs/cifs/sess.c | 97 |
1 files changed, 53 insertions, 44 deletions
diff --git a/fs/cifs/sess.c b/fs/cifs/sess.c index fdc248fffa0a..a52aacb3feff 100644 --- a/fs/cifs/sess.c +++ b/fs/cifs/sess.c | |||
@@ -28,12 +28,8 @@ | |||
28 | #include "cifs_debug.h" | 28 | #include "cifs_debug.h" |
29 | #include "ntlmssp.h" | 29 | #include "ntlmssp.h" |
30 | #include "nterr.h" | 30 | #include "nterr.h" |
31 | #include <linux/ctype.h> | ||
32 | #include <linux/utsname.h> | 31 | #include <linux/utsname.h> |
33 | 32 | ||
34 | extern void SMBencrypt(unsigned char *passwd, unsigned char *c8, | ||
35 | unsigned char *p24); | ||
36 | |||
37 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, | 33 | extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, |
38 | unsigned char *p24); | 34 | unsigned char *p24); |
39 | 35 | ||
@@ -80,7 +76,7 @@ static __u32 cifs_ssetup_hdr(struct cifsSesInfo *ses, SESSION_SETUP_ANDX *pSMB) | |||
80 | return capabilities; | 76 | return capabilities; |
81 | } | 77 | } |
82 | 78 | ||
83 | void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | 79 | static void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, |
84 | const struct nls_table * nls_cp) | 80 | const struct nls_table * nls_cp) |
85 | { | 81 | { |
86 | char * bcc_ptr = *pbcc_area; | 82 | char * bcc_ptr = *pbcc_area; |
@@ -130,7 +126,7 @@ void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
130 | *pbcc_area = bcc_ptr; | 126 | *pbcc_area = bcc_ptr; |
131 | } | 127 | } |
132 | 128 | ||
133 | void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | 129 | static void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, |
134 | const struct nls_table * nls_cp) | 130 | const struct nls_table * nls_cp) |
135 | { | 131 | { |
136 | char * bcc_ptr = *pbcc_area; | 132 | char * bcc_ptr = *pbcc_area; |
@@ -173,7 +169,7 @@ void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, | |||
173 | *pbcc_area = bcc_ptr; | 169 | *pbcc_area = bcc_ptr; |
174 | } | 170 | } |
175 | 171 | ||
176 | int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, | 172 | static int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, |
177 | const struct nls_table * nls_cp) | 173 | const struct nls_table * nls_cp) |
178 | { | 174 | { |
179 | int rc = 0; | 175 | int rc = 0; |
@@ -255,7 +251,7 @@ int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, | |||
255 | return rc; | 251 | return rc; |
256 | } | 252 | } |
257 | 253 | ||
258 | int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, | 254 | static int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, |
259 | const struct nls_table * nls_cp) | 255 | const struct nls_table * nls_cp) |
260 | { | 256 | { |
261 | int rc = 0; | 257 | int rc = 0; |
@@ -317,7 +313,6 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
317 | { | 313 | { |
318 | int rc = 0; | 314 | int rc = 0; |
319 | int wct; | 315 | int wct; |
320 | int i; | ||
321 | struct smb_hdr *smb_buf; | 316 | struct smb_hdr *smb_buf; |
322 | char *bcc_ptr; | 317 | char *bcc_ptr; |
323 | SESSION_SETUP_ANDX *pSMB; | 318 | SESSION_SETUP_ANDX *pSMB; |
@@ -343,7 +338,7 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
343 | return -EOPNOTSUPP; | 338 | return -EOPNOTSUPP; |
344 | #endif | 339 | #endif |
345 | wct = 10; /* lanman 2 style sessionsetup */ | 340 | wct = 10; /* lanman 2 style sessionsetup */ |
346 | } else if(type == NTLM) /* NTLMv2 may retry NTLM */ | 341 | } else if((type == NTLM) || (type == NTLMv2)) /* NTLMv2 may retry NTLM */ |
347 | wct = 13; /* old style NTLM sessionsetup */ | 342 | wct = 13; /* old style NTLM sessionsetup */ |
348 | else /* same size for negotiate or auth, NTLMSSP or extended security */ | 343 | else /* same size for negotiate or auth, NTLMSSP or extended security */ |
349 | wct = 12; | 344 | wct = 12; |
@@ -360,41 +355,22 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
360 | 355 | ||
361 | if(type == LANMAN) { | 356 | if(type == LANMAN) { |
362 | #ifdef CONFIG_CIFS_WEAK_PW_HASH | 357 | #ifdef CONFIG_CIFS_WEAK_PW_HASH |
363 | char lnm_session_key[CIFS_SESSION_KEY_SIZE]; | 358 | char lnm_session_key[CIFS_SESS_KEY_SIZE]; |
364 | char password_with_pad[CIFS_ENCPWD_SIZE]; | ||
365 | 359 | ||
366 | /* no capabilities flags in old lanman negotiation */ | 360 | /* no capabilities flags in old lanman negotiation */ |
367 | 361 | ||
368 | pSMB->old_req.PasswordLength = CIFS_SESSION_KEY_SIZE; | 362 | pSMB->old_req.PasswordLength = CIFS_SESS_KEY_SIZE; |
369 | /* BB calculate hash with password */ | 363 | /* BB calculate hash with password */ |
370 | /* and copy into bcc */ | 364 | /* and copy into bcc */ |
371 | 365 | ||
372 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | 366 | calc_lanman_hash(ses, lnm_session_key); |
373 | strncpy(password_with_pad, ses->password, CIFS_ENCPWD_SIZE); | ||
374 | |||
375 | /* calculate old style session key */ | ||
376 | /* toupper may be less broken then repeatedly calling | ||
377 | nls_toupper would be, but neither handles multibyte code pages | ||
378 | but the only alternative would be converting to UCS-16 (Unicode) | ||
379 | uppercasing and converting back which is only worth doing if | ||
380 | we knew it were utf8. utf8 code page needs its own | ||
381 | toupper and tolower and strnicmp functions */ | ||
382 | |||
383 | for(i = 0; i< CIFS_ENCPWD_SIZE; i++) { | ||
384 | password_with_pad[i] = toupper(password_with_pad[i]); | ||
385 | } | ||
386 | |||
387 | SMBencrypt(password_with_pad, ses->server->cryptKey, | ||
388 | lnm_session_key); | ||
389 | 367 | ||
390 | #ifdef CONFIG_CIFS_DEBUG2 | 368 | #ifdef CONFIG_CIFS_DEBUG2 |
391 | cifs_dump_mem("cryptkey: ",ses->server->cryptKey, | 369 | cifs_dump_mem("cryptkey: ",ses->server->cryptKey, |
392 | CIFS_SESSION_KEY_SIZE); | 370 | CIFS_SESS_KEY_SIZE); |
393 | #endif | 371 | #endif |
394 | /* clear password before we return/free memory */ | 372 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESS_KEY_SIZE); |
395 | memset(password_with_pad, 0, CIFS_ENCPWD_SIZE); | 373 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
396 | memcpy(bcc_ptr, (char *)lnm_session_key, CIFS_SESSION_KEY_SIZE); | ||
397 | bcc_ptr += CIFS_SESSION_KEY_SIZE; | ||
398 | 374 | ||
399 | /* can not sign if LANMAN negotiated so no need | 375 | /* can not sign if LANMAN negotiated so no need |
400 | to calculate signing key? but what if server | 376 | to calculate signing key? but what if server |
@@ -406,13 +382,13 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
406 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | 382 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); |
407 | #endif | 383 | #endif |
408 | } else if (type == NTLM) { | 384 | } else if (type == NTLM) { |
409 | char ntlm_session_key[CIFS_SESSION_KEY_SIZE]; | 385 | char ntlm_session_key[CIFS_SESS_KEY_SIZE]; |
410 | 386 | ||
411 | pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); | 387 | pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); |
412 | pSMB->req_no_secext.CaseInsensitivePasswordLength = | 388 | pSMB->req_no_secext.CaseInsensitivePasswordLength = |
413 | cpu_to_le16(CIFS_SESSION_KEY_SIZE); | 389 | cpu_to_le16(CIFS_SESS_KEY_SIZE); |
414 | pSMB->req_no_secext.CaseSensitivePasswordLength = | 390 | pSMB->req_no_secext.CaseSensitivePasswordLength = |
415 | cpu_to_le16(CIFS_SESSION_KEY_SIZE); | 391 | cpu_to_le16(CIFS_SESS_KEY_SIZE); |
416 | 392 | ||
417 | /* calculate session key */ | 393 | /* calculate session key */ |
418 | SMBNTencrypt(ses->password, ses->server->cryptKey, | 394 | SMBNTencrypt(ses->password, ses->server->cryptKey, |
@@ -420,15 +396,48 @@ CIFS_SessSetup(unsigned int xid, struct cifsSesInfo *ses, int first_time, | |||
420 | 396 | ||
421 | if(first_time) /* should this be moved into common code | 397 | if(first_time) /* should this be moved into common code |
422 | with similar ntlmv2 path? */ | 398 | with similar ntlmv2 path? */ |
423 | cifs_calculate_mac_key( | 399 | cifs_calculate_mac_key( ses->server->mac_signing_key, |
424 | ses->server->mac_signing_key, | ||
425 | ntlm_session_key, ses->password); | 400 | ntlm_session_key, ses->password); |
426 | /* copy session key */ | 401 | /* copy session key */ |
427 | 402 | ||
428 | memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESSION_KEY_SIZE); | 403 | memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); |
429 | bcc_ptr += CIFS_SESSION_KEY_SIZE; | 404 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
430 | memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESSION_KEY_SIZE); | 405 | memcpy(bcc_ptr, (char *)ntlm_session_key,CIFS_SESS_KEY_SIZE); |
431 | bcc_ptr += CIFS_SESSION_KEY_SIZE; | 406 | bcc_ptr += CIFS_SESS_KEY_SIZE; |
407 | if(ses->capabilities & CAP_UNICODE) | ||
408 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); | ||
409 | else | ||
410 | ascii_ssetup_strings(&bcc_ptr, ses, nls_cp); | ||
411 | } else if (type == NTLMv2) { | ||
412 | char * v2_sess_key = kmalloc(V2_SESS_KEY_SIZE, GFP_KERNEL); | ||
413 | |||
414 | if(v2_sess_key == NULL) { | ||
415 | cifs_small_buf_release(smb_buf); | ||
416 | return -ENOMEM; | ||
417 | } | ||
418 | |||
419 | pSMB->req_no_secext.Capabilities = cpu_to_le32(capabilities); | ||
420 | |||
421 | /* LM2 password would be here if we supported it */ | ||
422 | pSMB->req_no_secext.CaseInsensitivePasswordLength = 0; | ||
423 | /* cpu_to_le16(LM2_SESS_KEY_SIZE); */ | ||
424 | |||
425 | pSMB->req_no_secext.CaseSensitivePasswordLength = | ||
426 | cpu_to_le16(V2_SESS_KEY_SIZE); | ||
427 | |||
428 | /* calculate session key */ | ||
429 | CalcNTLMv2_response(ses, v2_sess_key); | ||
430 | if(first_time) /* should this be moved into common code | ||
431 | with similar ntlmv2 path? */ | ||
432 | /* cifs_calculate_ntlmv2_mac_key(ses->server->mac_signing_key, | ||
433 | response BB FIXME, v2_sess_key); */ | ||
434 | |||
435 | /* copy session key */ | ||
436 | |||
437 | /* memcpy(bcc_ptr, (char *)ntlm_session_key,LM2_SESS_KEY_SIZE); | ||
438 | bcc_ptr += LM2_SESS_KEY_SIZE; */ | ||
439 | memcpy(bcc_ptr, (char *)v2_sess_key, V2_SESS_KEY_SIZE); | ||
440 | bcc_ptr += V2_SESS_KEY_SIZE; | ||
432 | if(ses->capabilities & CAP_UNICODE) | 441 | if(ses->capabilities & CAP_UNICODE) |
433 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); | 442 | unicode_ssetup_strings(&bcc_ptr, ses, nls_cp); |
434 | else | 443 | else |