aboutsummaryrefslogtreecommitdiffstats
path: root/fs/cifs/sess.c
diff options
context:
space:
mode:
authorSteve French <sfrench@us.ibm.com>2006-06-01 15:20:10 -0400
committerSteve French <sfrench@us.ibm.com>2006-06-01 15:20:10 -0400
commit7c7b25bc8e392aea781324efa771bc191377b876 (patch)
treeddad1a91f948746dbef140994c615253a7f42e65 /fs/cifs/sess.c
parent9c53588ec96d85f82e9bf3fb1af7cca31056e940 (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.c97
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
34extern void SMBencrypt(unsigned char *passwd, unsigned char *c8,
35 unsigned char *p24);
36
37extern void SMBNTencrypt(unsigned char *passwd, unsigned char *c8, 33extern 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
83void unicode_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 79static 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
133void ascii_ssetup_strings(char ** pbcc_area, struct cifsSesInfo *ses, 129static 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
176int decode_unicode_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 172static 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
258int decode_ascii_ssetup(char ** pbcc_area, int bleft, struct cifsSesInfo *ses, 254static 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