Commit f1009949 authored by ROOL's avatar ROOL 🤖
Browse files

Add support for NTLM authenticated logins

SMB.c:
Line 875 don't free chain pB that early it is (and was being) used later on.
Fixes to correct which SMB_RxWords the Sesskey and bloblen are retrieved from, for each of the dialects supported.
Call the new auth code when the protocol flags require it.
Don't uppercase passwords all the time, the server may require case sensitivity.
md5c.c/md4c.c:
Verbatim copies of the RSA reference implementations of MD4 and MD5 from the respective RFC's.
Auth.c:
Implementation of the hash/mash/reply that Microsoft requires. Define AUTHTEST of this file to build a simple application that verifies the algorithms.

Tested against a Win7 install, inspecting in Wireshark that the passwords are no longer sent in the clear.
Implements ticket #332.
Submission from Colin Granville.

Version 2.52. Tagged as 'LanManFS-2_52'
parent 68b81856
...@@ -18,7 +18,7 @@ ...@@ -18,7 +18,7 @@
COMPONENT = LanManFS COMPONENT = LanManFS
OBJS = Xlate Transact Stats SMB RPC Printers Omni NetBIOS NBIP \ OBJS = Xlate Transact Stats SMB RPC Printers Omni NetBIOS NBIP \
NameCache Logon LLC LanMan CoreFn buflib Attr \ NameCache Logon LLC LanMan CoreFn buflib Attr \
Interface MyResObj Interface Auth md5c md4c MyResObj
CINCLUDES = -ITCPIPLibs:,C: CINCLUDES = -ITCPIPLibs:,C:
HDRS = HDRS =
CMHGFILE = Lanman_MH CMHGFILE = Lanman_MH
......
/* (2.51) /* (2.52)
* *
* This file is automatically maintained by srccommit, do not edit manually. * This file is automatically maintained by srccommit, do not edit manually.
* Last processed by srccommit version: 1.1. * Last processed by srccommit version: 1.1.
* *
*/ */
#define Module_MajorVersion_CMHG 2.51 #define Module_MajorVersion_CMHG 2.52
#define Module_MinorVersion_CMHG #define Module_MinorVersion_CMHG
#define Module_Date_CMHG 02 Aug 2015 #define Module_Date_CMHG 09 Aug 2015
#define Module_MajorVersion "2.51" #define Module_MajorVersion "2.52"
#define Module_Version 251 #define Module_Version 252
#define Module_MinorVersion "" #define Module_MinorVersion ""
#define Module_Date "02 Aug 2015" #define Module_Date "09 Aug 2015"
#define Module_ApplicationDate "02-Aug-15" #define Module_ApplicationDate "09-Aug-15"
#define Module_ComponentName "LanManFS" #define Module_ComponentName "LanManFS"
#define Module_ComponentPath "castle/RiscOS/Sources/Networking/Omni/Protocols/LanManFS" #define Module_ComponentPath "castle/RiscOS/Sources/Networking/Omni/Protocols/LanManFS"
#define Module_FullVersion "2.51" #define Module_FullVersion "2.52"
#define Module_HelpVersion "2.51 (02 Aug 2015)" #define Module_HelpVersion "2.52 (09 Aug 2015)"
#define Module_LibraryVersionInfo "2:51" #define Module_LibraryVersionInfo "2:52"
/*
* Copyright(c)2015, Colin Granville
* Allrightsreserved.
*
* Redistribution and use in source and binary forms, with or without
* modification, are permitted provided that the following conditions are met:
* * Redistributions of source code must retain the above copyright
* notice, this list of conditions and the following disclaimer.
* * Redistributions in binary form must reproduce the above copyright
* notice, this list of conditions and the following disclaimer in the
* documentation and/or other materials provided with the distribution.
* * Neither the name of RISC OS Open Ltd nor the names of its contributors
* may be used to endorse or promote products derived from this software
* without specific prior written permission.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS"
* AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
* IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
* ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE
* LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR
* CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF
* SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN
* CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE)
* ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE
* POSSIBILITY OF SUCH DAMAGE.
*/
#include <stdio.h>
#include <stdlib.h>
#include <ctype.h>
#include <time.h>
#include <string.h>
#include "DebugLib/DebugLib.h"
#include "Auth.h"
#include "global.h"
#include "md4.h"
#include "md5.h"
/* Based on code from RFC2104 */
typedef struct
{
MD5_CTX MD5ctx;
unsigned char k_opad[64];/* outer padding -
* key XORd with opad
*/
} HMAC_MD5_CTX;
static void HMAC_MD5Init( HMAC_MD5_CTX *ctx, unsigned char *key, int key_len )
{
unsigned char k_ipad[65]; /* inner padding -
* key XORd with ipad
*/
unsigned char tk[16];
int i;
/* if key is longer than 64 bytes reset it to key=MD5(key) */
if (key_len > 64) {
MD5_CTX tctx;
MD5Init( &tctx );
MD5Update( &tctx, key, key_len );
MD5Final( tk, &tctx );
key = tk;
key_len = 16;
}
/*
* the HMAC_MD5 transform looks like:
*
* MD5(K XOR opad, MD5(K XOR ipad, text))
*
* where K is an n byte key
* ipad is the byte 0x36 repeated 64 times
* opad is the byte 0x5c repeated 64 times
* and text is the data being protected
*/
/* start out by storing key in pads */
memset( k_ipad, 0, sizeof k_ipad );
memset( ctx->k_opad, 0, sizeof ctx->k_opad );
memcpy( k_ipad, key, key_len );
memcpy( ctx->k_opad, key, key_len );
/* XOR key with ipad and opad values */
for (i = 0; i < 64; i++) {
k_ipad[i] ^= 0x36;
ctx->k_opad[i] ^= 0x5c;
}
/* perform inner MD5 */
MD5Init( &ctx->MD5ctx ); /* init context for 1st pass */
MD5Update( &ctx->MD5ctx, k_ipad, 64 ); /* start with inner pad */
}
static void HMAC_MD5Update( HMAC_MD5_CTX *ctx, unsigned char *text, int text_len )
{
MD5Update( &ctx->MD5ctx, text, text_len ); /* then text of datagram */
}
static void HMAC_MD5Final( unsigned char digest[16], HMAC_MD5_CTX* ctx )
{
/* finish up 1st pass */
MD5Final( digest, &ctx->MD5ctx );
/* perform outer MD5 */
MD5Init( &ctx->MD5ctx ); /* init context for 2nd pass */
MD5Update( &ctx->MD5ctx, ctx->k_opad, 64 ); /* start with outer pad */
MD5Update( &ctx->MD5ctx, digest, 16 ); /* then results of 1st hash */
MD5Final( digest, &ctx->MD5ctx ); /* finish up 2nd pass */
}
/*
* Simplified RISCOS string to UTF16 conversion.
* sizeof out must be >= size * 2 or (size + 1) * 2 if
* US_ADD_ZERO flag used.
*/
#define US_UPPERCASE 1
#define US_ADD_ZERO 2
static void UnicodeString( unsigned int flags, const char *s, size_t size, unsigned short *out )
{
size_t i;
if (out == 0) return;
for (i = 0; i < size; i++) {
out[i] = (flags & US_UPPERCASE) ? toupper( s[i] ) : s[i];
}
if (flags & US_ADD_ZERO) out[i] = 0;
}
static void Auth_NTOWFv1( const char *password, size_t pass_size, unsigned char digestout[16] )
{
unsigned short ustr[pass_size + 1]; /* 1 added because 0 size causes crash */
MD4_CTX ctx;
MD4Init( &ctx );
UnicodeString( 0, password, pass_size, ustr );
if (pass_size)
{
MD4Update( &ctx, (void *)ustr, pass_size * sizeof(unsigned short) );
}
MD4Final(digestout,&ctx);
}
void Auth_LMOWFv2( const char *password, size_t pass_size,
const char *username, size_t user_size,
const char *userdomain, size_t dom_size,
unsigned char digestout[16] )
{
size_t max_size = user_size;
unsigned short ustr[max_size + 1]; /* 1 added because 0 size causes crash */
Auth_NTOWFv1( password, pass_size, digestout );
if (dom_size > max_size) max_size = dom_size;
HMAC_MD5_CTX ctx;
HMAC_MD5Init( &ctx, digestout, 16 );
UnicodeString( US_UPPERCASE, username, user_size, ustr );
HMAC_MD5Update( &ctx, (void *)ustr, user_size * sizeof(unsigned short) );
UnicodeString( 0, userdomain, dom_size, ustr );
HMAC_MD5Update( &ctx, (void *)ustr, dom_size * sizeof(unsigned short) );
HMAC_MD5Final( digestout, &ctx );
}
void Auth_LMv2ChallengeResponse( unsigned char lmowfv2digest[16],
unsigned char serverchallenge[8],
unsigned char responseout[24])
{
size_t i;
unsigned char *clientchallenge = responseout + 16;
HMAC_MD5_CTX ctx;
/* Create random clientchallenge */
srand( (unsigned int)time( NULL ) );
for (i = 0; i < 8; i++)
{
#ifdef AUTHTEST
clientchallenge[i] = 0xAA;
#else
clientchallenge[i] = (unsigned char)rand();
#endif
}
HMAC_MD5Init( &ctx, lmowfv2digest, 16 );
HMAC_MD5Update( &ctx, (void *)serverchallenge, 8 );
HMAC_MD5Update( &ctx, (void *)clientchallenge, 8 );
HMAC_MD5Final( responseout, &ctx );
}
static unsigned long long SMBTime( void )
{
unsigned long long tm = time( NULL );
tm = (tm + 11644473600ull -2*24*3600) * 10000000;
return tm;
}
void Auth_NTv2ChallengeResponse( unsigned char ntowfv2digest[16],
unsigned char serverchallenge[8],
const char *servername, /* ASCII */
const char *domain, /* ASCII */
unsigned char responseout[128],
unsigned short *responseoutsize )
{
unsigned char *clientchallenge = responseout + 16;
unsigned long long tm;
size_t i, size;
HMAC_MD5_CTX ctx;
*responseoutsize = 0;
*clientchallenge++ = 1;
*clientchallenge++ = 1;
memset( clientchallenge, 0, 6 );
clientchallenge += 6;
tm = SMBTime();
#ifdef AUTHTEST
memset( clientchallenge, 0, sizeof(tm) );
#else
memcpy( clientchallenge, &tm, sizeof(tm) );
#endif
clientchallenge += sizeof(tm);
/* Create random clientchallenge */
srand( (unsigned int)time( NULL ) );
for (i = 0; i < 8; i++)
{
#ifdef AUTHTEST
*clientchallenge++ = 0xaa;
#else
*clientchallenge++ = (unsigned char)rand();
#endif
}
memset( clientchallenge, 0, 4 );
clientchallenge += 4;
/* Set domain */
size = strlen( domain );
if (clientchallenge + size * 2 + 4 > responseout + 128 - 8) return;
*clientchallenge++ = 2;
*clientchallenge++ = 0;
*clientchallenge++ = size * 2;
*clientchallenge++ = 0;
UnicodeString( 0, domain, size, (unsigned short *)clientchallenge );
clientchallenge += size * 2;
/* Set server */
size = strlen( servername );
if (clientchallenge + size * 2 + 4 > responseout + 128 - 8) return;
*clientchallenge++ = 1;
*clientchallenge++ = 0;
*clientchallenge++ = size * 2;
*clientchallenge++ = 0;
UnicodeString( 0, servername, size, (unsigned short *)clientchallenge );
clientchallenge += size * 2;
/* End of list */
*clientchallenge++ = 0;
*clientchallenge++ = 0;
*clientchallenge++ = 0;
*clientchallenge++ = 0;
memset( clientchallenge, 0, 4 );
clientchallenge += 4;
*responseoutsize = clientchallenge - responseout;
HMAC_MD5Init( &ctx, ntowfv2digest, 16 );
HMAC_MD5Update( &ctx, (void *)serverchallenge, 8 );
HMAC_MD5Update( &ctx, (void *)(responseout + 16), *responseoutsize - 16 );
HMAC_MD5Final( responseout, &ctx );
}
#ifdef AUTHTEST
#define MDPrint(digest) PrintHex((digest),16)
static void PrintHex( void *d, size_t len )
{
size_t i;
unsigned char *data = (unsigned char *)d;
for (i = 0; i < len; i++) {
printf( "%02x", data[i] );
}
printf( "\n" );
}
int main( void )
{
unsigned char digest[16];
MD5_CTX context;
MD4_CTX context4;
HMAC_MD5_CTX hctx;
unsigned char lmv2response[24];
unsigned long long tm;
unsigned char ntv2response[128];
unsigned short ntsize;
MD5Init( &context );
MD5Update( &context, (void *)"test", 4 );
MD5Final( digest, &context );
MDPrint( digest );
MD5Init( &context );
MD5Update( &context, (void *)"te", 2 );
MD5Update( &context, (void *)"st", 2 );
MD5Final( digest, &context );
MDPrint( digest );
MD4Init( &context4 );
MD4Update( &context4, (void *)"test", 4 );
MD4Final( digest, &context4 );
MDPrint( digest );
MD4Init( &context4 );
MD4Update( &context4, (void *)"te", 2 );
MD4Update( &context4, (void *)"st", 2 );
MD4Final( digest, &context4 );
MDPrint( digest );
/* RFC2202 test cases */
HMAC_MD5Init( &hctx, (void *)"Jefe", 4 );
HMAC_MD5Update( &hctx, (void *)"what do ya want for nothing?", 28 );
HMAC_MD5Final( digest, &hctx );
MDPrint( digest );
HMAC_MD5Init( &hctx, (void *)"Jefe", 4 );
HMAC_MD5Update( &hctx, (void*)"what", 4 );
HMAC_MD5Update( &hctx, (void *)" do ya want for nothing?", 24 );
HMAC_MD5Final( digest, &hctx );
MDPrint( digest );
/* Value below verified from [MS-NLMP].pdf 4.2.4.1.1 */
Auth_NTOWFv2( "Password", 8, "User", 4, "Domain", 6, digest );
MDPrint( digest );
/* Value below verified from [MS-NLMP].pdf 4.2.2.1.2 */
Auth_NTOWFv1( "Password", 8, digest );
MDPrint( digest );
/* Value below verified from [MS-NLMP].pdf 4.2.4.1.1 */
Auth_LMOWFv2( "Password", 8, "User", 4, "Domain", 6, digest );
MDPrint( digest );
/* Value below verified from [MS-NLMP].pdf 4.2.4.2.1 */
Auth_LMv2ChallengeResponse( digest, (void *)"\x01\x23\x45\x67\x89\xab\xcd\xef", lmv2response );
printHex( lmv2response, 24 );
/* Value below verified from [MS-NLMP].pdf 4.2.4.2.2 */
tm = SMBTime();
printHex( &tm, 8 );
Auth_NTv2ChallengeResponse( digest, (void *)"\x01\x23\x45\x67\x89\xab\xcd\xef", "Server",
"Domain", ntv2response, &ntsize );
printHex( ntv2response, ntsize );
printf( "%d\n", ntsize );
return 0;
}
#endif
...@@ -94,6 +94,7 @@ ...@@ -94,6 +94,7 @@
#include "LMVars.h" #include "LMVars.h"
#include "Attr.h" /* For InvalidateDrive */ #include "Attr.h" /* For InvalidateDrive */
#include "Xlate.h" /* For string functions */ #include "Xlate.h" /* For string functions */
#include "Auth.h"
/* Definitions ===================================================== */ /* Definitions ===================================================== */
...@@ -858,28 +859,14 @@ static err_t SMB_Negotiate( hSHARE hS ) ...@@ -858,28 +859,14 @@ static err_t SMB_Negotiate( hSHARE hS )
if ( res != OK ) if ( res != OK )
return res; return res;
#ifdef DEBUG
debug1("Data length on negprot is %d\n", ChainLen(pB));
{
static char buf[4096];
void *ptr = SMB_RxWords;
int len = ChainLen(pB);
GetData(pB, buf, len);
DumpBuffer(buf, len);
DumpStruct(ptr, (SMB_RxWords[0] >= DIALECT_NT) ? dvs_NTnegprot : dvs_negprot);
}
#endif
FreeChain(pB);
debug1("Negotiated protocol `%s'\n", SMB_Dialect(SMB_RxWords[0])); debug1("Negotiated protocol `%s'\n", SMB_Dialect(SMB_RxWords[0]));
hS->hServer->prot = SMB_RxWords[0]; hS->hServer->prot = SMB_RxWords[0];
if ( SMB_RxWords[0] >= DIALECT_LM12X002 ) if ( SMB_RxWords[0] >= DIALECT_LM12X002 )
{ {
if (SMB_RxWords[0] >= DIALECT_NT) { if (SMB_RxWords[0] >= DIALECT_NT) {
unsigned char *buf = ((unsigned char *)SMB_RxWords) + 7;
/* grr - different response format */ /* grr - different response format */
hS->hServer->maxTxBufferSize = (buf[0] | (buf[1] << 8) | (buf[2] << 16) | (buf[3] << 24)); hS->hServer->maxTxBufferSize = (SMB_RxWords[3] >> 8) | (SMB_RxWords[4] << 8) | (SMB_RxWords[5] << 24);
hS->hServer->ProtFlags = PROT_RWMULTI + PROT_SETDATETIME + hS->hServer->ProtFlags = PROT_RWMULTI + PROT_SETDATETIME +
(SMB_RxWords[9] & 0x100 ? PROT_READRAW+PROT_WRITERAW : 0 ) + (SMB_RxWords[9] & 0x100 ? PROT_READRAW+PROT_WRITERAW : 0 ) +
(SMB_RxWords[1] & 1 ? PROT_USERLOGON : 0 ) + (SMB_RxWords[1] & 1 ? PROT_USERLOGON : 0 ) +
...@@ -895,15 +882,17 @@ static err_t SMB_Negotiate( hSHARE hS ) ...@@ -895,15 +882,17 @@ static err_t SMB_Negotiate( hSHARE hS )
debug0("No extended security - no GUID in the data block\n"); debug0("No extended security - no GUID in the data block\n");
} }
hS->hServer->bloblen = SMB_RxWords[16] >> 8; hS->hServer->bloblen = SMB_RxWords[16] >> 8;
hS->hServer->Sesskey = (SMB_RxWords[7] >> 8) | (SMB_RxWords[8] << 8) | (SMB_RxWords[9] << 24);
} }
else { else {
hS->hServer->bloblen = SMB_RxWords[11];
hS->hServer->maxTxBufferSize = SMB_RxWords[2]; hS->hServer->maxTxBufferSize = SMB_RxWords[2];
hS->hServer->ProtFlags = PROT_RWMULTI + PROT_SETDATETIME + hS->hServer->ProtFlags = PROT_RWMULTI + PROT_SETDATETIME +
(SMB_RxWords[1] & 1 ? PROT_USERLOGON : 0 ) + (SMB_RxWords[1] & 1 ? PROT_USERLOGON : 0 ) +
(SMB_RxWords[1] & 2 ? PROT_ENCRYPT : 0 ) + (SMB_RxWords[1] & 2 ? PROT_ENCRYPT : 0 ) +
(SMB_RxWords[5] & 1 ? PROT_READRAW : 0 ) + (SMB_RxWords[5] & 1 ? PROT_READRAW : 0 ) +
(SMB_RxWords[5] & 2 ? PROT_WRITERAW : 0 ); (SMB_RxWords[5] & 2 ? PROT_WRITERAW : 0 );
hS->hServer->bloblen = SMB_RxWords[11];
hS->hServer->Sesskey = SMB_RxWords[6] | (SMB_RxWords[7] << 16);
} }
hS->hServer->SMB_flg = SMB_CASELESS; hS->hServer->SMB_flg = SMB_CASELESS;
#ifdef LONGNAMES #ifdef LONGNAMES
...@@ -911,7 +900,6 @@ static err_t SMB_Negotiate( hSHARE hS ) ...@@ -911,7 +900,6 @@ static err_t SMB_Negotiate( hSHARE hS )
hS->hServer->SMB_flg2 = SMB_KNOWS_LONG_NAMES; /* | SMB_IS_LONG_NAME;*/ hS->hServer->SMB_flg2 = SMB_KNOWS_LONG_NAMES; /* | SMB_IS_LONG_NAME;*/
hS->hServer->t2flags = T2FLAGS_LONGNAMES; hS->hServer->t2flags = T2FLAGS_LONGNAMES;
#endif #endif
hS->hServer->Sesskey = SMB_RxWords[6] | (SMB_RxWords[7] << 16);
if (hS->hServer->bloblen > 0) { if (hS->hServer->bloblen > 0) {
free(hS->hServer->blob); free(hS->hServer->blob);
hS->hServer->blob = malloc(hS->hServer->bloblen); hS->hServer->blob = malloc(hS->hServer->bloblen);
...@@ -933,6 +921,7 @@ static err_t SMB_Negotiate( hSHARE hS ) ...@@ -933,6 +921,7 @@ static err_t SMB_Negotiate( hSHARE hS )
hS->hServer->SMB_flg2 = 0; hS->hServer->SMB_flg2 = 0;
#endif #endif
} }
FreeChain(pB);
debug1("%s-level security\n", hS->hServer->ProtFlags & PROT_USERLOGON ? "User" : "Share"); debug1("%s-level security\n", hS->hServer->ProtFlags & PROT_USERLOGON ? "User" : "Share");
return OK; return OK;
} }
...@@ -949,7 +938,7 @@ static err_t SMB_SessSetup ( hSHARE hS, char *userid, char *passwd ) ...@@ -949,7 +938,7 @@ static err_t SMB_SessSetup ( hSHARE hS, char *userid, char *passwd )
SMB_TxWords[0] = 0x00FF; /* No additional command */ SMB_TxWords[0] = 0x00FF; /* No additional command */
SMB_TxWords[1] = 0; /* Offset to next cmd */ SMB_TxWords[1] = 0; /* Offset to next cmd */
SMB_TxWords[2] = MAX_RX_BLOCK_SIZE; /* Maximum SMB message size we can receive */ SMB_TxWords[2] = MAX_RX_BLOCK_SIZE; /* Maximum SMB message size we can receive */
SMB_TxWords[3] = 0; /* Max pending requests */ SMB_TxWords[3] = 1; /* Max pending requests */
SMB_TxWords[4] = 0; /* First & only VC */ SMB_TxWords[4] = 0; /* First & only VC */
SMB_TxWords[5] = hS->hServer->Sesskey & 0xFFFF; SMB_TxWords[5] = hS->hServer->Sesskey & 0xFFFF;
SMB_TxWords[6] = hS->hServer->Sesskey >> 16; SMB_TxWords[6] = hS->hServer->Sesskey >> 16;
...@@ -980,17 +969,49 @@ static err_t SMB_SessSetup ( hSHARE hS, char *userid, char *passwd ) ...@@ -980,17 +969,49 @@ static err_t SMB_SessSetup ( hSHARE hS, char *userid, char *passwd )
} }
else { else {
/* Server does not support extended security */ /* Server does not support extended security */
SMB_TxWords[7] = strlen ( passwd ); if (hS->hServer->ProtFlags & PROT_ENCRYPT)
SMB_TxWords[8] = 0; {
SMB_TxWords[9] = SMB_TxWords[10] = 0; /* Reserved */ unsigned char lmowfv2digest[16];
SMB_TxWords[11] = SMB_TxWords[12] = 0; /* client capabilities */ unsigned char challengeResponse[24];
pB = AddChain(NULL, "CIFS", sizeof("CIFS"));
if (pB) pB = AddChain(pB, "\0RISCOS", sizeof("\0RISCOS")); if (strlen( passwd ) != 0)
if (pB) pB = AddChain(pB, userid, strlen(userid) + 1); {
if (pB) pB = AddChain(pB, passwd, strlen(passwd)); Auth_LMOWFv2( (const char *)passwd, strlen( passwd ),
if (pB) pB = DumpChain(pB); (const char *)userid, strlen( userid ),
if (pB == NULL) (const char *)userid, 0, /* no domain */
return EOUTOFMEM; lmowfv2digest );
Auth_LMv2ChallengeResponse( lmowfv2digest, (void *)hS->hServer->blob, challengeResponse );
SMB_TxWords[7] = sizeof(challengeResponse);
}
else
{
SMB_TxWords[7] = 0;
}
SMB_TxWords[8] = 0;
SMB_TxWords[9] = SMB_TxWords[10] = 0; /* Reserved */
SMB_TxWords[11] = SMB_TxWords[12] = 0; /* client capabilities */
pB = AddChain( NULL, "CIFS", sizeof("CIFS") );
if (pB) pB = AddChain( pB, "\0RISCOS", sizeof("\0RISCOS") );
if (pB) pB = AddChain( pB, userid, strlen(userid) + 1 );
if (pB && (SMB_TxWords[7] != 0)) pB = AddChain( pB, challengeResponse, sizeof(challengeResponse) );
if (pB) pB = DumpChain( pB );
if (pB == NULL)
return EOUTOFMEM;
}
else
{
SMB_TxWords[7] = strlen ( passwd );
SMB_TxWords[8] = 0;
SMB_TxWords[9] = SMB_TxWords[10] = 0; /* Reserved */
SMB_TxWords[11] = SMB_TxWords[12] = 0; /* client capabilities */
pB = AddChain( NULL, "CIFS", sizeof("CIFS") );
if (pB) pB = AddChain( pB, "\0RISCOS", sizeof("\0RISCOS") );
if (pB) pB = AddChain( pB, userid, strlen(userid) + 1 );
if (pB) pB = AddChain( pB, passwd, strlen(passwd) );
if (pB) pB = DumpChain( pB );
if (pB == NULL)
return EOUTOFMEM;
}
res = Do_SMB ( hS, SMBsesssetup, 13, pB, NULL ); res = Do_SMB ( hS, SMBsesssetup, 13, pB, NULL );
} }
if ( res != OK ) if ( res != OK )
...@@ -1598,7 +1619,7 @@ err_t SMB_CreateShare ( int sharetype_in, ...@@ -1598,7 +1619,7 @@ err_t SMB_CreateShare ( int sharetype_in,
hShare->hServer = hServ; hShare->hServer = hServ;
hShare->sharetype = sharetype_in; hShare->sharetype = sharetype_in;
strcpy ( hShare->sharename, uc_sharename ); strcpy ( hShare->sharename, uc_sharename );
strcpyn_upper ( hShare->password, password_in, NAME_LIMIT ); strcpyn ( hShare->password, password_in, NAME_LIMIT );
Xlt_Jumble(hShare->password); Xlt_Jumble(hShare->password);
done |= ALLOC_SHARE;