Author: sserapion Date: Thu May 26 02:35:38 2011 New Revision: 51918
URL: http://svn.reactos.org/svn/reactos?rev=51918&view=rev Log: WIP CODE - Implement basic algorithms defined by nlmp document including NTOWFv1 NTOWFv2 LMOWFv1 LMOWFv2 NONCE KXKEY SIGNKEY SEALKEY MAC - move all cipher implementations to a single file and header including CRC32 DES RC4 MD4 MD5 and HMACMD5 - Implement helper functions for AV_PAIRs - Implement a helper function to put UNICODE_STRINGs in NTLM_BLOBs and associated buffer and use it in GenerateNegoMessage - Free more memory in failure cases and termination. - remove wineism(trying to use credapi and wincred.h) - define more protocol flags and structures - special thanks to pidgin-sipe, and samba source code
Added: branches/sspi-bringup/reactos/dll/win32/ntlmssp/avl.c (with props) branches/sspi-bringup/reactos/dll/win32/ntlmssp/calculations.c (with props) branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.c (with props) branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.h - copied, changed from r51631, branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/base64_codec.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/hmac_md5.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.h Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/crypt.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/debug.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.rbuild branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h branches/sspi-bringup/reactos/dll/win32/ntlmssp/util.c
Added: branches/sspi-bringup/reactos/dll/win32/ntlmssp/avl.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/avl.c (added) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/avl.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -1,0 +1,93 @@ +/* + * Copyright 2011 Samuel Serapion + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +#include "ntlmssp.h" +#include "protocol.h" + +PMSV1_0_AV_PAIR +NtlmAvlInit(IN void * pAvList) +{ + PMSV1_0_AV_PAIR pAvPair = (PMSV1_0_AV_PAIR)pAvList; + pAvPair->AvId = MsvAvEOL; + pAvPair->AvLen = 0; + return pAvPair; +} + +PMSV1_0_AV_PAIR +NtlmAvlGet(IN PMSV1_0_AV_PAIR pAvList, + IN MSV1_0_AVID AvId, + IN LONG cAvList) +{ + PMSV1_0_AV_PAIR pAvPair = pAvList; + + do + { + if (pAvPair->AvId == AvId) + return pAvPair; + if (pAvPair->AvId == MsvAvEOL) + return NULL; + cAvList -= (pAvPair->AvLen + sizeof(MSV1_0_AV_PAIR)); + if (cAvList <= 0) + return NULL; + pAvPair = (PMSV1_0_AV_PAIR)((PUCHAR)pAvPair + pAvPair->AvLen + + sizeof(MSV1_0_AV_PAIR)); + }while(1); +} + +ULONG +NtlmAvlLen(IN PMSV1_0_AV_PAIR pAvList, + IN LONG cAvList) +{ + PMSV1_0_AV_PAIR pCurPair = NtlmAvlGet(pAvList, MsvAvEOL, cAvList); + + if(!pCurPair) + return 0; + return (ULONG)(((PUCHAR)pCurPair - (PUCHAR)pAvList) + sizeof(MSV1_0_AV_PAIR)); +} + +PMSV1_0_AV_PAIR +NtlmAvlAdd(IN PMSV1_0_AV_PAIR pAvList, + IN MSV1_0_AVID AvId, + IN PUNICODE_STRING pString, + IN LONG cAvList) +{ + PMSV1_0_AV_PAIR pCurPair = NtlmAvlGet(pAvList, MsvAvEOL, cAvList); + + if(!pCurPair) + return NULL; + + pCurPair->AvId = (USHORT)AvId; + pCurPair->AvLen = (USHORT)pString->Length; + memcpy(pCurPair+1, pString->Buffer, pCurPair->AvLen); + + pCurPair = (PMSV1_0_AV_PAIR)((PUCHAR)pCurPair + sizeof(MSV1_0_AV_PAIR) + pCurPair->AvLen); + pCurPair->AvId = MsvAvEOL; + pCurPair->AvLen = 0; + + return pCurPair; +} + +ULONG +NtlmAvlSize(IN ULONG Pairs, + IN ULONG PairsLen) +{ + return(Pairs * sizeof(MSV1_0_AV_PAIR) + + PairsLen + sizeof(MSV1_0_AV_PAIR)); +} +
Propchange: branches/sspi-bringup/reactos/dll/win32/ntlmssp/avl.c ------------------------------------------------------------------------------ svn:eol-style = native
Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/base64_codec.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/base64_codec.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/base64_codec.c (removed) @@ -1,189 +1,0 @@ -/* - * base64 encoder/decoder - * - * Copyright 2005 by Kai Blin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - */ - -#include "ntlm.h" - -WINE_DEFAULT_DEBUG_CHANNEL(ntlm); - -static const char b64[] = -"ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789+/"; - -SECURITY_STATUS encodeBase64(PBYTE in_buf, int in_len, char* out_buf, - int max_len, int *out_len) -{ - int div, i; - PBYTE d = in_buf; - int bytes = (in_len*8 + 5)/6, pad_bytes = (bytes % 4) ? 4 - (bytes % 4) : 0; - - TRACE("bytes is %d, pad bytes is %d\n", bytes, pad_bytes); - *out_len = bytes + pad_bytes; - - if(bytes + pad_bytes + 1 > max_len) - return SEC_E_BUFFER_TOO_SMALL; - - /* Three bytes of input give 4 chars of output */ - div = in_len / 3; - - i = 0; - while(div > 0) - { - /* first char is the first 6 bits of the first byte*/ - out_buf[i + 0] = b64[ ( d[0] >> 2) & 0x3f ]; - /* second char is the last 2 bits of the first byte and the first 4 - * bits of the second byte */ - out_buf[i + 1] = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; - /* third char is the last 4 bits of the second byte and the first 2 - * bits of the third byte */ - out_buf[i + 2] = b64[ ((d[1] << 2) & 0x3c) | (d[2] >> 6 & 0x03)]; - /* fourth char is the remaining 6 bits of the third byte */ - out_buf[i + 3] = b64[ d[2] & 0x3f]; - i += 4; - d += 3; - div--; - } - - switch(pad_bytes) - { - case 1: - /* first char is the first 6 bits of the first byte*/ - out_buf[i + 0] = b64[ ( d[0] >> 2) & 0x3f ]; - /* second char is the last 2 bits of the first byte and the first 4 - * bits of the second byte */ - out_buf[i + 1] = b64[ ((d[0] << 4) & 0x30) | (d[1] >> 4 & 0x0f)]; - /* third char is the last 4 bits of the second byte padded with - * two zeroes */ - out_buf[i + 2] = b64[ ((d[1] << 2) & 0x3c) ]; - /* fourth char is a = to indicate one byte of padding */ - out_buf[i + 3] = '='; - out_buf[i + 4] = 0; - break; - case 2: - /* first char is the first 6 bits of the first byte*/ - out_buf[i + 0] = b64[ ( d[0] >> 2) & 0x3f ]; - /* second char is the last 2 bits of the first byte padded with - * four zeroes*/ - out_buf[i + 1] = b64[ ((d[0] << 4) & 0x30)]; - /* third char is = to indicate padding */ - out_buf[i + 2] = '='; - /* fourth char is = to indicate padding */ - out_buf[i + 3] = '='; - out_buf[i + 4] = 0; - break; - default: - out_buf[i] = 0; - } - - return SEC_E_OK; -} - -static inline BYTE decode(char c) -{ - if( c >= 'A' && c <= 'Z') - return c - 'A'; - if( c >= 'a' && c <= 'z') - return c - 'a' + 26; - if( c >= '0' && c <= '9') - return c - '0' + 52; - if( c == '+') - return 62; - if( c == '/') - return 63; - else - return 64; -} - -SECURITY_STATUS decodeBase64(char *in_buf, int in_len, PBYTE out_buf, - int max_len, int *out_len) -{ - int len = in_len, i; - char *d = in_buf; - int ip0, ip1, ip2, ip3; - - TRACE("in_len: %d\n", in_len); - - if((in_len % 4) != 0) - return SEC_E_INVALID_TOKEN; - - if(in_len > max_len) - return SEC_E_BUFFER_TOO_SMALL; - - i = 0; - while(len > 4) - { - if((ip0 = decode(d[0])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip1 = decode(d[1])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip2 = decode(d[2])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip3 = decode(d[3])) > 63) - return SEC_E_INVALID_TOKEN; - - out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4); - out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2); - out_buf[i + 2] = (ip2 << 6) | ip3; - len -= 4; - i += 3; - d += 4; - } - - if(d[2] == '=') - { - if((ip0 = decode(d[0])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip1 = decode(d[1])) > 63) - return SEC_E_INVALID_TOKEN; - - out_buf[i] = (ip0 << 2) | (ip1 >> 4); - i++; - } - else if(d[3] == '=') - { - if((ip0 = decode(d[0])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip1 = decode(d[1])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip2 = decode(d[2])) > 63) - return SEC_E_INVALID_TOKEN; - - out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4); - out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2); - i += 2; - } - else - { - if((ip0 = decode(d[0])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip1 = decode(d[1])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip2 = decode(d[2])) > 63) - return SEC_E_INVALID_TOKEN; - if((ip3 = decode(d[3])) > 63) - return SEC_E_INVALID_TOKEN; - - - out_buf[i + 0] = (ip0 << 2) | (ip1 >> 4); - out_buf[i + 1] = (ip1 << 4) | (ip2 >> 2); - out_buf[i + 2] = (ip2 << 6) | ip3; - i += 3; - } - *out_len = i; - return SEC_E_OK; -}
Added: branches/sspi-bringup/reactos/dll/win32/ntlmssp/calculations.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/calculations.c (added) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/calculations.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -1,0 +1,370 @@ +/* + * Copyright 2011 Samuel Serapión + * + * This library is free software; you can redistribute it and/or + * modify it under the terms of the GNU Lesser General Public + * License as published by the Free Software Foundation; either + * version 2.1 of the License, or (at your option) any later version. + * + * This library is distributed in the hope that it will be useful, + * but WITHOUT ANY WARRANTY; without even the implied warranty of + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU + * Lesser General Public License for more details. + * + * You should have received a copy of the GNU Lesser General Public + * License along with this library; if not, write to the Free Software + * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA + * + */ + +/* this file contains algorithms defined in the MS-NLMP document */ + +#include "ntlmssp.h" +#include "protocol.h" +#include "ciphers.h" + +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(ntlm); + +VOID +NTOWFv1(const PWCHAR password, + PUCHAR result) +{ + ULONG i, len = wcslen(password); + + for(i = len; i<14; i++) + { + password[i] = L'0'; + } + + MD4((PUCHAR)password, len, result); +} + +VOID +NTOWFv2(const PWCHAR password, const PWCHAR user, const PWCHAR domain, PUCHAR result) +{ + UCHAR response_key_nt_v1 [16]; + ULONG len_user = user ? wcslen(user) : 0; + ULONG len_domain = domain ? wcslen(domain) : 0; + WCHAR user_upper[len_user + 1]; + ULONG len_user_u = len_user * sizeof(WCHAR); + ULONG len_domain_u = len_domain * sizeof(WCHAR); + WCHAR buff[(len_user + len_domain)*sizeof(WCHAR)]; + ULONG i; + + /* Uppercase user */ + for (i = 0; i < len_user; i++) { + user_upper[i] = toupper(user[i]); + } + user_upper[len_user] = 0; + + len_user_u = swprintf(buff, user_upper, len_user_u); + len_domain_u = swprintf(buff+len_user_u, domain ? domain : L"", len_domain_u); + + NTOWFv1(password, response_key_nt_v1); + HMAC_MD5(response_key_nt_v1, 16, (PUCHAR)buff, len_user_u + len_domain_u, result); +} + +VOID +LMOWFv1(PCCHAR password, PUCHAR result) +{ +#if 0 + SystemFunction006(password, result); +#else + /* "KGS!@#$%" */ + UCHAR magic[] = { 0x4B, 0x47, 0x53, 0x21, 0x40, 0x23, 0x24, 0x25 }; + UCHAR uppercase_password[14]; + ULONG i; + + ULONG len = strlen(password); + if (len > 14) { + len = 14; + } + + // Uppercase password + for (i = 0; i < len; i++) { + uppercase_password[i] = toupper(password[i]); + } + + // Zero the rest + for (; i < 14; i++) { + uppercase_password[i] = 0; + } + + DES(uppercase_password, magic, result); + DES(uppercase_password + 7, magic, result + 8); +#endif +} + +VOID +LMOWFv2(PWCHAR password, PWCHAR user, PWCHAR domain, PUCHAR result) +{ + NTOWFv2(password, user, domain, result); +} + +VOID +NONCE(PUCHAR buffer, ULONG num) +{ + NtlmGenerateRandomBits(buffer, num); +} + +VOID +KXKEY(ULONG flags, + const PUCHAR session_base_key, + const PUCHAR lm_challenge_resonse, + const PUCHAR server_challenge, + PUCHAR key_exchange_key) +{ + /* fix me */ + memcpy(key_exchange_key, session_base_key, 16); +} + +VOID +SIGNKEY(const PUCHAR RandomSessionKey, BOOLEAN IsClient, PUCHAR Result) +{ + PCHAR magic = IsClient + ? "session key to client-to-server signing key magic constant" + : "session key to server-to-client signing key magic constant"; + + ULONG len = strlen(magic); + UCHAR md5_input [16 + len]; + memcpy(md5_input, RandomSessionKey, 16); + memcpy(md5_input + 16, magic, len); + MD5(md5_input, len + 16, Result); +} + +VOID +SEALKEY(ULONG flags, const PUCHAR RandomSessionKey, BOOLEAN client, PUCHAR result) +{ + if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) + { + PCHAR magic = client + ? "session key to client-to-server sealing key magic constant" + : "session key to server-to-client sealing key magic constant"; + + ULONG len = strlen(magic) + 1; + UCHAR md5_input [16 + len]; + ULONG key_len; + + if (flags & NTLMSSP_NEGOTIATE_128) { + TRACE("NTLM SEALKEY(): 128-bit key (Extended session security)\n"); + key_len = 16; + } else if (flags & NTLMSSP_NEGOTIATE_56) { + TRACE("NTLM SEALKEY(): 56-bit key (Extended session security)\n"); + key_len = 7; + } else { + TRACE("NTLM SEALKEY(): 40-bit key (Extended session security)\n"); + key_len = 5; + } + + memcpy(md5_input, RandomSessionKey, key_len); + memcpy(md5_input + key_len, magic, len); + + MD5 (md5_input, key_len + len, result); + } + else if (flags & NTLMSSP_NEGOTIATE_LM_KEY) { + if (flags & NTLMSSP_NEGOTIATE_56) { + TRACE("NTLM SEALKEY(): 56-bit key\n"); + memcpy(result, RandomSessionKey, 7); + result[7] = 0xA0; + } else { + TRACE("NTLM SEALKEY(): 40-bit key\n"); + memcpy(result, RandomSessionKey, 5); + result[5] = 0xE5; + result[6] = 0x38; + result[7] = 0xB0; + } + } + else + { + TRACE("NTLM SEALKEY(): 128-bit key\n"); + memcpy(result, RandomSessionKey, 16); + } +} + +VOID +MAC(ULONG flags, + PCCHAR buf, + ULONG buf_len, + PUCHAR sign_key, + ULONG sign_key_len, + PUCHAR seal_key, + ULONG seal_key_len, + ULONG random_pad, + ULONG sequence, + PUCHAR result) +{ + ULONG *res_ptr; + + if (flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) { + UCHAR seal_key_ [16]; + UCHAR hmac[16]; + UCHAR tmp[4 + buf_len]; + + /* SealingKey' = MD5(ConcatenationOf(SealingKey, SequenceNumber)) + RC4Init(Handle, SealingKey') + + */ + if (flags & NTLMSSP_NEGOTIATE_DATAGRAM) { + UCHAR tmp2 [16+4]; + memcpy(tmp2, seal_key, seal_key_len); + *((ULONG *)(tmp2+16)) = sequence; + MD5 (tmp2, 16+4, seal_key_); + } else { + memcpy(seal_key_, seal_key, seal_key_len); + } + + TRACE("NTLM MAC(): Extented Session Security\n"); + + res_ptr = (ULONG *)result; + res_ptr[0] = 0x00000001L; + res_ptr[3] = sequence; + + res_ptr = (ULONG *)tmp; + res_ptr[0] = sequence; + memcpy(tmp+4, buf, buf_len); + + HMAC_MD5(sign_key, sign_key_len, tmp, 4 + buf_len, hmac); + + if (flags & NTLMSSP_NEGOTIATE_KEY_EXCH) { + TRACE("NTLM MAC(): Key Exchange\n"); + RC4K(seal_key_, seal_key_len, hmac, 8, result+4); + } else { + TRACE("NTLM MAC(): *NO* Key Exchange\n"); + memcpy(result+4, hmac, 8); + } + } else { + /* The content of the first 4 bytes is irrelevant */ + ULONG crc = CRC32(buf, strlen(buf)); + ULONG plaintext [] = { 0, crc, sequence }; + + TRACE("NTLM MAC(): *NO* Extented Session Security\n"); + + RC4K(seal_key, seal_key_len, (const PUCHAR )plaintext, 12, result+4); + + res_ptr = (ULONG *)result; + // Highest four bytes are the Version + res_ptr[0] = 0x00000001; // 4 bytes + + // Replace the first four bytes of the ciphertext with the random_pad + res_ptr[1] = random_pad; // 4 bytes + } +} + +VOID +NtlmLmResponse(IN PUNICODE_STRING pUserName, + IN PUNICODE_STRING pPassword, + IN PUNICODE_STRING pDomainName, + IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH], + IN PLM2_RESPONSE pLm2Response, + OUT UCHAR Response[MSV1_0_NTLM3_RESPONSE_LENGTH]) +{ + HMAC_MD5_CTX ctx; + UCHAR NtlmOwf[MSV1_0_NTLM3_OWF_LENGTH]; + + NTOWFv2(pPassword->Buffer, + pUserName->Buffer, + pDomainName->Buffer, + NtlmOwf); + + HMACMD5Init(&ctx, NtlmOwf, MSV1_0_NTLM3_OWF_LENGTH); + HMACMD5Update(&ctx, ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); + HMACMD5Update(&ctx, (PUCHAR)pLm2Response->ChallengeFromClient, MSV1_0_CHALLENGE_LENGTH); + HMACMD5Final(&ctx, Response); + + return; +} + +VOID +NtlmNtResponse(IN PUNICODE_STRING pUserName, + IN PUNICODE_STRING pPassword, + IN PUNICODE_STRING pDomainName, + IN ULONG ServerNameLength, + IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH], + IN PMSV1_0_NTLM3_RESPONSE pNtResponse, + OUT UCHAR Response[MSV1_0_NTLM3_RESPONSE_LENGTH], + OUT PUSER_SESSION_KEY pUserSessionKey, + OUT PLM_SESSION_KEY pLmSessionKey) +{ + HMAC_MD5_CTX ctx; + UCHAR NtlmOwf[MSV1_0_NTLM3_OWF_LENGTH]; + + NTOWFv2(pPassword->Buffer, + pUserName->Buffer, + pDomainName->Buffer, + NtlmOwf); + + HMACMD5Init(&ctx, NtlmOwf, MSV1_0_NTLM3_OWF_LENGTH); + HMACMD5Update(&ctx, ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); + HMACMD5Update(&ctx, &pNtResponse->RespType, + MSV1_0_NTLM3_INPUT_LENGTH + ServerNameLength); + HMACMD5Final(&ctx, Response); + + /* session keys */ + HMAC_MD5(NtlmOwf, MSV1_0_NTLM3_OWF_LENGTH, + Response, MSV1_0_NTLM3_RESPONSE_LENGTH, (PUCHAR)pUserSessionKey); + + //*pLmSessionKey = pUserSessionKey; + memcpy(pLmSessionKey, pUserSessionKey, MSV1_0_LANMAN_SESSION_KEY_LENGTH); + return; +} + +VOID +NtlmChallengeResponse(IN PUNICODE_STRING pUserName, + IN PUNICODE_STRING pPassword, + IN PUNICODE_STRING pDomainName, + IN PUNICODE_STRING pServerName, + IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH], + OUT PMSV1_0_NTLM3_RESPONSE pNtResponse, + OUT PLM2_RESPONSE pLm2Response, + OUT PUSER_SESSION_KEY pUserSessionKey, + OUT PLM_SESSION_KEY pLmSessionKey) +{ + pNtResponse->RespType = 1; + pNtResponse->HiRespType = 1; + pNtResponse->Flags = 0; + pNtResponse->MsgWord = 0; + + NtQuerySystemTime((PLARGE_INTEGER)&pNtResponse->TimeStamp); + NtlmGenerateRandomBits(pNtResponse->ChallengeFromClient, MSV1_0_CHALLENGE_LENGTH); + + memcpy(pNtResponse->Buffer, pServerName->Buffer, pServerName->Length); + + NtlmNtResponse(pUserName, + pPassword, + pDomainName, + pServerName->Length, + ChallengeToClient, + pNtResponse, + pNtResponse->Response, + pUserSessionKey, + pLmSessionKey); + + /* Use same challenge to compute the LM3 response */ + memcpy(pLm2Response->ChallengeFromClient, + pNtResponse->ChallengeFromClient, + MSV1_0_CHALLENGE_LENGTH); + + NtlmLmResponse(pUserName, + pPassword, + pDomainName, + ChallengeToClient, + pLm2Response, + pLm2Response->Response); +} + +VOID +NtpLmSessionKeys(IN PUSER_SESSION_KEY NtpUserSessionKey, + IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH], + IN UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH], + OUT PUSER_SESSION_KEY pUserSessionKey, + OUT PLM_SESSION_KEY pLmSessionKey) +{ + HMAC_MD5_CTX ctx; + + HMACMD5Init(&ctx, (PUCHAR)NtpUserSessionKey, sizeof(*NtpUserSessionKey)); + HMACMD5Update(&ctx, ChallengeToClient, MSV1_0_CHALLENGE_LENGTH); + HMACMD5Update(&ctx, ChallengeFromClient, MSV1_0_CHALLENGE_LENGTH); + HMACMD5Final(&ctx, (PUCHAR)pUserSessionKey); + memcpy(pLmSessionKey, pUserSessionKey, sizeof(*pLmSessionKey)); +}
Propchange: branches/sspi-bringup/reactos/dll/win32/ntlmssp/calculations.c ------------------------------------------------------------------------------ svn:eol-style = native
Added: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.c (added) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -1,0 +1,235 @@ + +#include "ntlmssp.h" +#include "ciphers.h" + +#include "wine/debug.h" +WINE_DEFAULT_DEBUG_CHANNEL(ntlm); + +/* not in any header, DES HASH! */ +LONG +WINAPI SystemFunction001(const BYTE *data, const BYTE *key, LPBYTE output); + +static UINT32 crc32_table[256]; +static int crc32_initialized = 0; + +//CRC-32-IEEE 802.3 +static void +crc32_make_table() +{ + UINT32 h = 1; + unsigned int i, j; + + memset(crc32_table, 0, sizeof(crc32_table)); + + for (i = 128; i; i >>= 1) + { + h = (h >> 1) ^ ((h & 1) ? 0xedb88320L : 0); + + for (j = 0; j < 256; j += 2 * i) + crc32_table[i + j] = crc32_table[j] ^ h; + } + + crc32_initialized = 1; +} + +static UINT32 +crc32(UINT32 crc, const unsigned char *buf, int len) +{ + if (!crc32_initialized) + crc32_make_table(); + + if (!buf || len < 0) + return crc; + + crc ^= 0xffffffffL; + + while (len--) + crc = (crc >> 8) ^ crc32_table[(crc ^ *buf++) & 0xff]; + + return crc ^ 0xffffffffL; +} + +static inline void +swap_bytes(unsigned char *a, unsigned char *b) +{ + unsigned char swapByte; + + swapByte = *a; + *a = *b; + *b = swapByte; +} + +void +rc4_init(rc4_key *const state, const unsigned char *key, int keylen) +{ + unsigned char j; + int i; + + /* Initialize state with identity permutation */ + for (i = 0; i < 256; i++) + state->perm[i] = (unsigned char)i; + state->index1 = 0; + state->index2 = 0; + + /* Randomize the permutation using key data */ + for (j = i = 0; i < 256; i++) { + j += state->perm[i] + key[i % keylen]; + swap_bytes(&state->perm[i], &state->perm[j]); + } +} + +void +rc4_crypt(rc4_key *const state, const unsigned char *inbuf, unsigned char *outbuf, int buflen) +{ + int i; + unsigned char j; + + for (i = 0; i < buflen; i++) + { + /* Update modification indicies */ + state->index1++; + state->index2 += state->perm[state->index1]; + + /* Modify permutation */ + swap_bytes(&state->perm[state->index1], + &state->perm[state->index2]); + + /* Encrypt/decrypt next byte */ + j = state->perm[state->index1] + state->perm[state->index2]; + outbuf[i] = inbuf[i] ^ state->perm[j]; + } +} + +void +HMACMD5Init(HMAC_MD5_CTX *ctx, const unsigned char *key, unsigned int key_len) +{ + int i; + unsigned char inner_padding[64]; + unsigned char temp_key[16]; + + if(key_len > 64) + { + MD5_CTX temp_ctx; + + MD5Init(&temp_ctx); + MD5Update(&temp_ctx, key, key_len); + MD5Final(&temp_ctx); + memcpy(temp_key, temp_ctx.digest, 16); + + key = temp_key; + key_len = 16; + } + + memset(inner_padding, 0, 64); + memset(ctx->outer_padding, 0, 64); + memcpy(inner_padding, key, key_len); + memcpy(ctx->outer_padding, key, key_len); + + for(i = 0; i < 64; ++i) + { + inner_padding[i] ^= 0x36; + ctx->outer_padding[i] ^= 0x5c; + } + + MD5Init(&(ctx->ctx)); + MD5Update(&(ctx->ctx), inner_padding, 64); +} + +void +HMACMD5Update(HMAC_MD5_CTX *ctx, const unsigned char *data, unsigned int data_len) +{ + MD5Update(&(ctx->ctx), data, data_len); +} + +void +HMACMD5Final(HMAC_MD5_CTX *ctx, unsigned char *digest) +{ + MD5_CTX outer_ctx; + unsigned char inner_digest[16]; + + MD5Final(&(ctx->ctx)); + memcpy(inner_digest, ctx->ctx.digest, 16); + + MD5Init(&outer_ctx); + MD5Update(&outer_ctx, ctx->outer_padding, 64); + MD5Update(&outer_ctx, inner_digest, 16); + MD5Final(&outer_ctx); + + memcpy(digest, outer_ctx.digest, 16); +} + +/* high level */ + +void +RC4K (const unsigned char * k, unsigned long key_len, const unsigned char * d, int len, unsigned char * result) +{ + rc4_key rc4key; + + rc4_init(&rc4key, k, key_len); + rc4_crypt(&rc4key, d, result, len); +} + +UINT32 +CRC32(const char *msg, int len) +{ + UINT32 crc = 0L; + crc = crc32(crc, (unsigned char *) msg, len); + return crc; +} + +// (k = 7 byte key, d = 8 byte data) returns 8 bytes in results +void +DES(const unsigned char *k, const unsigned char *d, unsigned char * results) +{ + SystemFunction001(d, k, (LPBYTE)results); +} + +// (K = 21 byte key, D = 8 bytes of data) returns 24 bytes in results: +void +DESL(unsigned char *k, const unsigned char *d, unsigned char * results) +{ + unsigned char keys[21]; + + /* copy the first 16 bytes */ + memcpy(keys, k, 16); + + /* zero out the last 5 bytes of the key */ + memset(keys + 16, 0, 5); + + DES(keys, d, results); + DES(keys + 7, d, results + 8); + DES(keys + 14, d, results + 16); +} + +void +MD4(const unsigned char * d, int len, unsigned char * result) +{ + MD4_CTX ctx; + + MD4Init(&ctx); + MD4Update(&ctx, d, len); + MD4Final(&ctx); + memcpy(result, ctx.digest, len); +} + +void +MD5(const unsigned char * d, int len, unsigned char * result) +{ + MD5_CTX ctx; + + MD5Init(&ctx); + MD5Update(&ctx, d, len); + MD5Final(&ctx); + memcpy(result, ctx.digest, 0x10); +} + +void +HMAC_MD5(const unsigned char *key, int key_len, const unsigned char *data, int data_len, unsigned char *result) +{ + HMAC_MD5_CTX ctx; + + HMACMD5Init(&ctx, key, key_len); + HMACMD5Update(&ctx, data, data_len); + HMACMD5Final(&ctx, result); +} +
Propchange: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.c ------------------------------------------------------------------------------ svn:eol-style = native
Copied: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.h (from r51631, branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h) URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ciphers.h [iso-8859-1] Thu May 26 02:35:38 2011 @@ -1,5 +1,5 @@ /* - * Copyright 2011 + * Copyright 2011 Samuel Serapión * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public @@ -16,12 +16,21 @@ * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA * */ - -#ifndef _HMAC_MD5_H_ -#define _HMAC_MD5_H_ +#ifndef _CYPHERS_H_ +#define _CYPHERS_H_
#include <string.h> #include "windef.h" + +typedef struct _rc4_key +{ + unsigned char perm[256]; + unsigned char index1; + unsigned char index2; +}rc4_key; + +void rc4_init(rc4_key *const state, const unsigned char *key, int keylen); +void rc4_crypt(rc4_key *const state, const unsigned char *inbuf, unsigned char *outbuf, int buflen);
typedef struct { @@ -29,7 +38,12 @@ unsigned int i[2]; unsigned char in[64]; unsigned char digest[16]; -} MD4_CTX; +}MD4_CTX; + +/* advapi32 */ +void WINAPI MD4Init(MD4_CTX *ctx); +void WINAPI MD4Update(MD4_CTX *ctx, const unsigned char *buf, unsigned int len); +void WINAPI MD4Final(MD4_CTX *ctx);
typedef struct { @@ -37,7 +51,12 @@ unsigned int buf[4]; unsigned char in[64]; unsigned char digest[16]; -} MD5_CTX; +}MD5_CTX; + +/* advapi32 */ +void WINAPI MD5Init( MD5_CTX *ctx); +void WINAPI MD5Update(MD5_CTX *ctx, const unsigned char *buf, unsigned int len); +void WINAPI MD5Final(MD5_CTX *ctx);
typedef struct { @@ -45,14 +64,29 @@ unsigned char outer_padding[64]; } HMAC_MD5_CTX;
-VOID WINAPI MD4Init( MD4_CTX *ctx ); -VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len ); -VOID WINAPI MD4Final( MD4_CTX *ctx ); -void WINAPI MD5Init( MD5_CTX *ctx ); -void WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len ); -void WINAPI MD5Final( MD5_CTX *ctx ); - void HMACMD5Init(HMAC_MD5_CTX *ctx, const unsigned char *key, unsigned int key_len); void HMACMD5Update(HMAC_MD5_CTX *ctx, const unsigned char *data, unsigned int data_len); void HMACMD5Final(HMAC_MD5_CTX *ctx, unsigned char *digest); -#endif /*_HMAC_MD5_H_*/ + +/* high level api */ +UINT32 +CRC32 (const char *msg, int len); + +void +RC4K (const unsigned char * k, unsigned long key_len, const unsigned char * d, int len, unsigned char * result); + +void +DES(const unsigned char *k, const unsigned char *d, unsigned char * results); + +void +DESL(unsigned char *k, const unsigned char *d, unsigned char * results); + +void +MD4(const unsigned char * d, int len, unsigned char * result); + +void +MD5(const unsigned char * d, int len, unsigned char * result); + +void +HMAC_MD5(const unsigned char *key, int key_len, const unsigned char *data, int data_len, unsigned char *result); +#endif
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/context.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -19,7 +19,6 @@
#include "ntlmssp.h" #include "protocol.h" -#include <lm.h>
#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ntlm); @@ -36,7 +35,7 @@ return STATUS_SUCCESS; }
-VOID +PNTLMSSP_CONTEXT NtlmReferenceContext(IN ULONG_PTR Handle) { PNTLMSSP_CONTEXT context; @@ -66,6 +65,7 @@ #endif context->RefCount++; LeaveCriticalSection(&ContextCritSect); + return context; }
VOID @@ -160,51 +160,6 @@ LeaveCriticalSection(&ContextCritSect);
TRACE("added context %p\n",ret); - return ret; -} - -BOOL -NtlmGetCachedCredential(const SEC_WCHAR *pszTargetName, - PCREDENTIALW *cred) -{ - LPCWSTR p; - LPCWSTR pszHost; - LPWSTR pszHostOnly; - BOOL ret; - - if (!pszTargetName) - return FALSE; - - /* try to get the start of the hostname from service principal name (SPN) */ - pszHost = strchrW(pszTargetName, '/'); - if (pszHost) - { - /* skip slash character */ - pszHost++; - - /* find fail of host by detecting start of instance port or start of referrer */ - p = strchrW(pszHost, ':'); - if (!p) - p = strchrW(pszHost, '/'); - if (!p) - p = pszHost + strlenW(pszHost); - } - else /* otherwise not an SPN, just a host */ - { - pszHost = pszTargetName; - p = pszHost + strlenW(pszHost); - } - - pszHostOnly = HeapAlloc(GetProcessHeap(), 0, (p - pszHost + 1) * sizeof(WCHAR)); - if (!pszHostOnly) - return FALSE; - - memcpy(pszHostOnly, pszHost, (p - pszHost) * sizeof(WCHAR)); - pszHostOnly[p - pszHost] = '\0'; - - ret = CredReadW(pszHostOnly, CRED_TYPE_DOMAIN_PASSWORD, 0, cred); - - HeapFree(GetProcessHeap(), 0, pszHostOnly); return ret; }
@@ -246,7 +201,7 @@ context->NegotiateFlags = NTLMSSP_NEGOTIATE_UNICODE | NTLMSSP_NEGOTIATE_OEM | NTLMSSP_NEGOTIATE_NTLM | - NTLMSSP_NEGOTIATE_NTLM2 | //if supported + NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY | //if supported NTLMSSP_REQUEST_TARGET | NTLMSSP_NEGOTIATE_ALWAYS_SIGN | NTLMSSP_NEGOTIATE_56 | @@ -278,8 +233,8 @@ { context->NegotiateFlags |= NTLMSSP_NEGOTIATE_SEAL | NTLMSSP_NEGOTIATE_LM_KEY | - NTLMSSP_NEGOTIATE_KEY_EXCH; - //NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY; + NTLMSSP_NEGOTIATE_KEY_EXCH | + NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY;
*pfContextAttr |= ISC_RET_CONFIDENTIALITY; context->ContextFlags |= ISC_RET_CONFIDENTIALITY; @@ -299,7 +254,7 @@
if(fContextReq & ISC_REQ_IDENTIFY) { - context->NegotiateFlags |= NTLMSSP_NEGOTIATE_IDENTIFY; + context->NegotiateFlags |= NTLMSSP_REQUEST_INIT_RESP; *pfContextAttr |= ISC_RET_IDENTIFY; context->ContextFlags |= ISC_RET_IDENTIFY; } @@ -311,7 +266,6 @@ context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_NT_ONLY; context->ContextFlags |= ISC_RET_DATAGRAM; *pfContextAttr |= ISC_RET_DATAGRAM; - //*pfNegotiateFlags |= NTLMSSP_APP_SEQ; app provided sequence numbers
/* generate session key */ if(context->NegotiateFlags & (NTLMSSP_NEGOTIATE_SIGN | @@ -327,47 +281,6 @@ } }
- /* local connection */ - if((!cred->DomainName.Buffer && - !cred->UserName.Buffer && - !cred->Password.Buffer) && - cred->SecToken) - { - LPWKSTA_USER_INFO_1 ui = NULL; - NET_API_STATUS status; - PCREDENTIALW credW; - context->isLocal = TRUE; - - TRACE("try use local cached credentials\n"); - - /* get local credentials */ - if(pszTargetName && NtlmGetCachedCredential(pszTargetName, &credW)) - { - LPWSTR p; - p = strchrW(credW->UserName, '\'); - if(p) - { - TRACE("%s\n",debugstr_w(credW->UserName)); - TRACE("%s\n", debugstr_w((WCHAR*)(p - credW->UserName))); - } - if(credW->CredentialBlobSize != 0) - { - TRACE("%s\n", debugstr_w((WCHAR*)credW->CredentialBlob)); - } - CredFree(credW); - } - else - { - status = NetWkstaUserGetInfo(NULL, 1, (LPBYTE *)&ui); - if (status != NERR_Success || ui == NULL) - { - ret = SEC_E_NO_CREDENTIALS; - goto fail; - } - TRACE("%s",debugstr_w(ui->wkui1_username)); - NetApiBufferFree(ui); - } - } }//end is datagram
/* generate session key */ @@ -390,12 +303,11 @@ //*ptsExpiry = *phNewContext = (ULONG_PTR)context;
- TRACE("context %p context->NegotiateFlags:\n",context); - NtlmPrintNegotiateFlags(*pfNegotiateFlags); - return ret;
fail: + /* free resources */ + NtlmDereferenceContext((ULONG_PTR)context); return ret; }
@@ -470,9 +382,6 @@ &sessionKey, &NegotiateFlags);
- phCredential->dwUpper = NegotiateFlags; - phNewContext->dwLower = newContext; - if(!newContext || !NT_SUCCESS(ret)) { ERR("NtlmCreateNegoContext failed with %lx\n", ret); @@ -481,7 +390,6 @@
ret = NtlmGenerateNegotiateMessage(newContext, fContextReq, - NegotiateFlags, InputToken1, &OutputToken1);
@@ -490,6 +398,10 @@ ERR("NtlmGenerateNegotiateMessage failed with %lx\n", ret); goto fail; } + + /* set results */ + phNewContext->dwUpper = NegotiateFlags; + phNewContext->dwLower = newContext;
/* build blob with the nego message */ SecBufferDesc BufferDesc; @@ -505,8 +417,7 @@ } else /* challenge! */ { - ERR("challenge message unimplemented!!!\n"); - ERR("phNewContext %p phContext %x!!!\n",phNewContext, *phContext); + TRACE("ISC challenged!\n"); *phNewContext = *phContext; if (fContextReq & ISC_REQ_USE_SUPPLIED_CREDS) { @@ -529,14 +440,37 @@ TRUE); if(!ret) { + /* not fatal, aparently */ ERR("Failed to get output token!\n"); - return SEC_E_INVALID_TOKEN; - } - - } + } + + TRACE("phContext->dwLower %lx\n", phContext->dwLower); + NtlmHandleChallengeMessage(phContext->dwLower, + fContextReq, + InputToken1, + InputToken2, + &OutputToken1, + &OutputToken2, + pfContextAttr, + ptsExpiry, + &NegotiateFlags); + } + return ret;
fail: + /* free resources */ + if(newContext) + NtlmDereferenceContext(newContext); + + if(fContextReq & ISC_REQ_ALLOCATE_MEMORY) + { + if(OutputToken1 && OutputToken1->pvBuffer) + NtlmFree(OutputToken1->pvBuffer); + if(OutputToken2 && OutputToken2->pvBuffer) + NtlmFree(OutputToken1->pvBuffer); + } + return ret; }
@@ -657,7 +591,6 @@ return SEC_E_BUFFER_TOO_SMALL; }
- ERR("here!"); /* first call */ if(!phContext && !InputToken2->cbBuffer) { @@ -692,9 +625,7 @@ DeleteSecurityContext(PCtxtHandle phContext) { if (!phContext) - { return SEC_E_INVALID_HANDLE; - }
NtlmDereferenceContext((ULONG_PTR)phContext->dwLower); phContext = NULL;
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/credentials.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -438,7 +438,7 @@ { TRACE("FreeCredentialsHandle %x %x\n", phCredential, phCredential->dwLower);
- if(!phCredential) /* fixme: more handle validation */ + if(!phCredential) return SEC_E_INVALID_HANDLE;
NtlmDereferenceCredential((ULONG_PTR)phCredential->dwLower);
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/crypt.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/crypt.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/crypt.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -17,7 +17,7 @@ */ #include "ntlmssp.h" #include <wincrypt.h> -#include "rc4.h" +#include "ciphers.h"
#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ntlm);
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/debug.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/debug.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/debug.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -40,8 +40,8 @@ TRACE("\tNTLMSSP_NEGOTIATE_TARGET_INFO\n"); if (Flags & NTLMSSP_REQUEST_NON_NT_SESSION_KEY) TRACE("\tNTLMSSP_REQUEST_NON_NT_SESSION_KEY\n"); - if (Flags & NTLMSSP_NEGOTIATE_IDENTIFY) - TRACE("\tNTLMSSP_NEGOTIATE_IDENTIFY\n"); + if (Flags & NTLMSSP_REQUEST_INIT_RESP) + TRACE("\tNTLMSSP_REQUEST_INIT_RESP\n"); if (Flags & NTLMSSP_TARGET_TYPE_SHARE) TRACE("\tNTLMSSP_TARGET_TYPE_SHARE\n"); if (Flags & NTLMSSP_TARGET_TYPE_SERVER) @@ -56,8 +56,8 @@ TRACE("\tNTLMSSP_NEGOTIATE_DOMAIN_SUPPLIED\n"); if (Flags & NTLMSSP_NEGOTIATE_NTLM) TRACE("\tNTLMSSP_NEGOTIATE_NTLM\n"); - if (Flags & NTLMSSP_NEGOTIATE_NTLM2) - TRACE("\tNTLMSSP_NEGOTIATE_NTLM2\n"); + if (Flags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) + TRACE("\tNTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY\n"); if (Flags & NTLMSSP_NEGOTIATE_LM_KEY) TRACE("\tNTLMSSP_NEGOTIATE_LM_KEY\n"); if (Flags & NTLMSSP_NEGOTIATE_DATAGRAM) @@ -76,3 +76,94 @@ TRACE("\tNTLMSSP_NEGOTIATE_NT_ONLY\n"); TRACE("}\n"); } + +void NtlmPrintHexDump(PBYTE buffer, DWORD length) +{ + unsigned int i,count,index; + CHAR rgbDigits[]="0123456789abcdef"; + CHAR rgbLine[100]; + char cbLine; + + for(index = 0; length; + length -= count, buffer += count, index += count) + { + count = (length > 16) ? 16:length; + + sprintf(rgbLine, "%4.4x ", index); + cbLine = 6; + for(i=0;i<count;i++) + { + rgbLine[cbLine++] = rgbDigits[buffer[i] >> 4]; + rgbLine[cbLine++] = rgbDigits[buffer[i] & 0x0f]; + if(i == 7) + rgbLine[cbLine++] = ':'; + else + rgbLine[cbLine++] = ' '; + } + for(; i < 16; i++) + { + rgbLine[cbLine++] = ' '; + rgbLine[cbLine++] = ' '; + rgbLine[cbLine++] = ' '; + } + rgbLine[cbLine++] = ' '; + + for(i = 0; i < count; i++) + { + if(buffer[i] < 32 || buffer[i] > 126) + rgbLine[cbLine++] = '.'; + else + rgbLine[cbLine++] = buffer[i]; + } + rgbLine[cbLine++] = 0; + TRACE("%s\n", rgbLine); + } +} // end PrintHexDump + +void +NtlmPrintAvPairs(const PVOID Buffer) +{ + PMSV1_0_AV_PAIR pAvPair = (PMSV1_0_AV_PAIR)Buffer; + + /* warning: the string buffers are not null terminated! */ +#define AV_DESC(av_name) TRACE("%s: len: %xl value: %S\n", av_name, pAvPair->AvLen, av_value); + do + { + WCHAR *av_value = (WCHAR*)((PCHAR)pAvPair + sizeof(MSV1_0_AV_PAIR)); + switch(pAvPair->AvId) + { + case MsvAvNbComputerName: + AV_DESC("MsvAvNbComputerName"); + break; + case MsvAvNbDomainName: + AV_DESC("MsvAvNbDomainName"); + break; + case MsvAvDnsComputerName: + AV_DESC("MsvAvDnsComputerName"); + break; + case MsvAvDnsDomainName: + AV_DESC("MsvAvDnsDomainName"); + break; + case MsvAvDnsTreeName: + AV_DESC("MsvAvDnsTreeName"); + break; + case MsvAvFlags: + AV_DESC("MsvAvFlags"); + break; + case MsvAvTimestamp: + TRACE("MsvAvTimestamp"); + break; + case MsvAvRestrictions: + TRACE("MsAvRestrictions"); + break; + case MsvAvTargetName: + AV_DESC("MsvAvTargetName"); + break; + case MsvAvChannelBindings: + TRACE("MsvChannelBindings"); + break; + } + pAvPair = (PMSV1_0_AV_PAIR)((PUCHAR)pAvPair + pAvPair->AvLen + + sizeof(MSV1_0_AV_PAIR)); + }while(pAvPair->AvId != MsvAvEOL); +}
Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/hmac_md5.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/hmac_md5.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/hmac_md5.c (removed) @@ -1,77 +1,0 @@ -/* - * Copyright 2006 Kai Blin - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - * This file implements RFC 2104 (HMAC) for the MD5 provider. - * It is needed for NTLM2 signing and sealing. - */ - -#include "md4-5.h" - -void HMACMD5Init(HMAC_MD5_CTX *ctx, const unsigned char *key, unsigned int key_len) -{ - int i; - unsigned char inner_padding[64]; - unsigned char temp_key[16]; - - if(key_len > 64) - { - MD5_CTX temp_ctx; - - MD5Init(&temp_ctx); - MD5Update(&temp_ctx, key, key_len); - MD5Final(&temp_ctx); - memcpy(temp_key, temp_ctx.digest, 16); - - key = temp_key; - key_len = 16; - } - - memset(inner_padding, 0, 64); - memset(ctx->outer_padding, 0, 64); - memcpy(inner_padding, key, key_len); - memcpy(ctx->outer_padding, key, key_len); - - for(i = 0; i < 64; ++i) - { - inner_padding[i] ^= 0x36; - ctx->outer_padding[i] ^= 0x5c; - } - - MD5Init(&(ctx->ctx)); - MD5Update(&(ctx->ctx), inner_padding, 64); -} - -void HMACMD5Update(HMAC_MD5_CTX *ctx, const unsigned char *data, unsigned int data_len) -{ - MD5Update(&(ctx->ctx), data, data_len); -} - -void HMACMD5Final(HMAC_MD5_CTX *ctx, unsigned char *digest) -{ - MD5_CTX outer_ctx; - unsigned char inner_digest[16]; - - MD5Final(&(ctx->ctx)); - memcpy(inner_digest, ctx->ctx.digest, 16); - - MD5Init(&outer_ctx); - MD5Update(&outer_ctx, ctx->outer_padding, 64); - MD5Update(&outer_ctx, inner_digest, 16); - MD5Final(&outer_ctx); - - memcpy(digest, outer_ctx.digest, 16); -}
Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/md4-5.h (removed) @@ -1,58 +1,0 @@ -/* - * Copyright 2011 - * - * This library is free software; you can redistribute it and/or - * modify it under the terms of the GNU Lesser General Public - * License as published by the Free Software Foundation; either - * version 2.1 of the License, or (at your option) any later version. - * - * This library is distributed in the hope that it will be useful, - * but WITHOUT ANY WARRANTY; without even the implied warranty of - * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU - * Lesser General Public License for more details. - * - * You should have received a copy of the GNU Lesser General Public - * License along with this library; if not, write to the Free Software - * Foundation, Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA - * - */ - -#ifndef _HMAC_MD5_H_ -#define _HMAC_MD5_H_ - -#include <string.h> -#include "windef.h" - -typedef struct -{ - unsigned int buf[4]; - unsigned int i[2]; - unsigned char in[64]; - unsigned char digest[16]; -} MD4_CTX; - -typedef struct -{ - unsigned int i[2]; - unsigned int buf[4]; - unsigned char in[64]; - unsigned char digest[16]; -} MD5_CTX; - -typedef struct -{ - MD5_CTX ctx; - unsigned char outer_padding[64]; -} HMAC_MD5_CTX; - -VOID WINAPI MD4Init( MD4_CTX *ctx ); -VOID WINAPI MD4Update( MD4_CTX *ctx, const unsigned char *buf, unsigned int len ); -VOID WINAPI MD4Final( MD4_CTX *ctx ); -void WINAPI MD5Init( MD5_CTX *ctx ); -void WINAPI MD5Update( MD5_CTX *ctx, const unsigned char *buf, unsigned int len ); -void WINAPI MD5Final( MD5_CTX *ctx ); - -void HMACMD5Init(HMAC_MD5_CTX *ctx, const unsigned char *key, unsigned int key_len); -void HMACMD5Update(HMAC_MD5_CTX *ctx, const unsigned char *data, unsigned int data_len); -void HMACMD5Final(HMAC_MD5_CTX *ctx, unsigned char *digest); -#endif /*_HMAC_MD5_H_*/
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -17,21 +17,22 @@ * */ #include "ntlmssp.h" +#include "protocol.h"
#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ntlm);
/* globals */ - -/* use (sparingly) to read/write global state */ -CRITICAL_SECTION GlobalCritSect; +CRITICAL_SECTION GlobalCritSect; /* use to read/write global state */
NTLM_MODE NtlmMode = NtlmUserMode; /* FIXME */ -BOOLEAN Inited = FALSE; UNICODE_STRING NtlmComputerNameString; UNICODE_STRING NtlmDomainNameString; +UNICODE_STRING NtlmDnsNameString; +UNICODE_STRING NtlmAvTargetInfo; // contains AV pairs with local info OEM_STRING NtlmOemComputerNameString; OEM_STRING NtlmOemDomainNameString; +OEM_STRING NtlmOemDnsNameString; HANDLE NtlmSystemSecurityToken;
/* private functions */ @@ -40,24 +41,44 @@ NtlmInitializeGlobals(VOID) { NTSTATUS status = STATUS_SUCCESS; - WCHAR compName[CNLEN + 1], domName[DNLEN+1]; - ULONG compNamelen = sizeof(compName), domNamelen = sizeof(domName); - + //LPWKSTA_USER_INFO_1 pBuf = NULL; + WCHAR compName[CNLEN + 1], domName[DNLEN+1], dnsName[256]; + ULONG compNamelen = sizeof(compName), dnsNamelen = sizeof(dnsName); + PMSV1_0_AV_PAIR pAvPairs; + ULONG AvPairsLen; InitializeCriticalSection(&GlobalCritSect);
- if (!GetComputerNameW(compName, &compNamelen)) + if(!GetComputerNameW(compName, &compNamelen)) { compName[0] = L'\0'; ERR("could not get computer name!\n"); } + TRACE("%s\n",debugstr_w(compName)); + + if (!GetComputerNameExW(ComputerNameDnsFullyQualified, dnsName, &dnsNamelen)) + { + dnsName[0] = L'\0'; + ERR("could not get domain name!\n"); + } + TRACE("%s\n",debugstr_w(dnsName)); + + /* FIXME: this still does not match what msv1_0 returns */ + // if (!(NERR_Success == NetWkstaUserGetInfo(0, 1, (LPBYTE*)&pBuf))) + //{ + wcscpy(domName, L"WORKGROUP\0"); + FIXME("how to get domain name!?\n"); + //} + //else + //{ + // wcscpy(domName, pBuf->wkui1_logon_domain); + //} + + //if (pBuf != NULL) + // NetApiBufferFree(pBuf); + TRACE("%s\n",debugstr_w(domName)); + RtlCreateUnicodeString(&NtlmComputerNameString, compName); - - if (!GetComputerNameExW(ComputerNameDnsFullyQualified, domName, &domNamelen)) - { - domName[0] = L'\0'; - ERR("could not get domain name!\n"); - } - + RtlCreateUnicodeString(&NtlmDnsNameString, dnsName); RtlCreateUnicodeString(&NtlmDomainNameString, domName);
RtlUnicodeStringToOemString(&NtlmOemComputerNameString, @@ -68,6 +89,10 @@ &NtlmDomainNameString, TRUE);
+ RtlUnicodeStringToOemString(&NtlmOemDnsNameString, + &NtlmDnsNameString, + TRUE); + status = NtOpenProcessToken(NtCurrentProcess(), TOKEN_QUERY | TOKEN_DUPLICATE, &NtlmSystemSecurityToken); @@ -76,13 +101,45 @@ { ERR("could not get process token!!\n"); } + + /* init global target AV pairs */ + + RtlInitUnicodeString(&NtlmAvTargetInfo, NULL); + AvPairsLen = NtlmDomainNameString.Length + //fix me: domain controller name + NtlmComputerNameString.Length + //computer name + NtlmDnsNameString.Length + //dns computer name + NtlmDnsNameString.Length + //fix me: dns domain name + sizeof(MSV1_0_AV_PAIR)*4; + + NtlmAvTargetInfo.Buffer = (PWSTR)NtlmAllocate(AvPairsLen); + + if(!NtlmAvTargetInfo.Buffer) + { + ERR("failed to allocate NtlmAvTargetInfo\n"); + return STATUS_INSUFFICIENT_RESOURCES; + } + + pAvPairs = NtlmAvlInit(NtlmAvTargetInfo.Buffer); + NtlmAvlAdd(pAvPairs, MsvAvNbDomainName, &NtlmDomainNameString, AvPairsLen); + NtlmAvlAdd(pAvPairs, MsvAvNbComputerName, &NtlmComputerNameString, AvPairsLen); + NtlmAvlAdd(pAvPairs, MsvAvDnsDomainName, &NtlmDnsNameString, AvPairsLen); + NtlmAvlAdd(pAvPairs, MsvAvDnsComputerName, &NtlmDnsNameString, AvPairsLen); + NtlmAvTargetInfo.Length = (USHORT)NtlmAvlLen(pAvPairs, AvPairsLen); + return status; }
VOID NtlmTerminateGlobals(VOID) { - + NtlmFree(NtlmComputerNameString.Buffer); + NtlmFree(NtlmDomainNameString.Buffer); + NtlmFree(NtlmDnsNameString.Buffer); + NtlmFree(NtlmOemComputerNameString.Buffer); + NtlmFree(NtlmOemDomainNameString.Buffer); + NtlmFree(NtlmOemDnsNameString.Buffer); + NtlmFree(NtlmAvTargetInfo.Buffer); + NtClose(NtlmSystemSecurityToken); }
/* public functions */
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.h [iso-8859-1] Thu May 26 02:35:38 2011 @@ -26,8 +26,6 @@ #include <ntstatus.h> #define WIN32_NO_STATUS #include <windows.h> -#include <wincred.h> - #include <ndk/ntndk.h> #define SECURITY_WIN32 #define _NO_KSECDD_IMPORT_ @@ -35,7 +33,9 @@ #include <sspi.h> #include <ntsecapi.h> #include <ntsecpkg.h> -#include <lmcons.h> +#include <ntmsv1_0.h> +#include <lm.h> + #include "wine/unicode.h"
/* globals */ @@ -87,9 +87,9 @@ LIST_ENTRY Entry; ULONG RefCount; ULONG UseFlags; - UNICODE_STRING DomainName; UNICODE_STRING UserName; UNICODE_STRING Password; + UNICODE_STRING DomainName; ULONG ProcId; HANDLE SecToken; LUID LogonId; @@ -115,7 +115,7 @@ ULONG NegotiateFlags; ULONG ContextFlags; NTLMSSP_CONTEXT_STATE State; - PNTLMSSP_CREDENTIAL Credential; //creator + PNTLMSSP_CREDENTIAL Credential; UCHAR Challenge[MSV1_0_CHALLENGE_LENGTH]; //ChallengeSent UCHAR SessionKey[MSV1_0_USER_SESSION_KEY_LENGTH]; //LSA HANDLE ClientToken; @@ -154,6 +154,12 @@
PNTLMSSP_CONTEXT NtlmAllocateContext(VOID); + +PNTLMSSP_CONTEXT +NtlmReferenceContext(IN ULONG_PTR Handle); + +VOID +NtlmDereferenceContext(IN ULONG_PTR Handle);
/* crypt.c */ BOOL @@ -208,4 +214,10 @@ void NtlmPrintNegotiateFlags(ULONG Flags);
+void +NtlmPrintHexDump(PBYTE buffer, DWORD length); + +void +NtlmPrintAvPairs(const PVOID av); + #endif
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.rbuild URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.rbuild [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/ntlmssp.rbuild [iso-8859-1] Thu May 26 02:35:38 2011 @@ -1,25 +1,27 @@ <?xml version="1.0"?> <!DOCTYPE module SYSTEM "../../../tools/rbuild/project.dtd"> -<module name="ntlmssp" type="win32dll" baseaddress="${BASEADDRESS_SCHANNEL}" installbase="system32" installname="ntlmssp.dll" allowwarnings="true"> +<module name="ntlmssp" type="win32dll" baseaddress="${BASEADDRESS_NTLMSSP}" installbase="system32" installname="ntlmssp.dll" allowwarnings="true"> <importlibrary definition="ntlmssp.spec" /> <include base="ntlmssp">.</include> - <library>wine</library> <library>advapi32</library> <library>crypt32</library> + <library>netapi32</library> <library>ntdll</library> - <library>netapi32</library> + <library>wine</library> + <file>avl.c</file> + <file>calculations.c</file> + <file>ciphers.c</file> <file>context.c</file> <file>credentials.c</file> <file>crypt.c</file> - <file>rc4.c</file> - <file>stubs.c</file> + <file>debug.c</file> + <file>dllmain.c</file> <file>messages.c</file> <file>ntlmssp.c</file> + <file>protocol.c</file> + <file>stubs.c</file> <file>sign.c</file> <file>util.c</file> - <file>dllmain.c</file> - <file>debug.c</file> - <file>protocol.c</file> </module>
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -25,16 +25,15 @@ SECURITY_STATUS NtlmGenerateNegotiateMessage(IN ULONG_PTR Context, IN ULONG ContextReq, - IN ULONG NegotiateFlags, IN PSecBuffer InputToken, OUT PSecBuffer *OutputToken) { PNTLMSSP_CONTEXT context = (PNTLMSSP_CONTEXT)Context; + PNTLMSSP_CREDENTIAL cred = context->Credential; PNEGOTIATE_MESSAGE message; - ULONG messageSize = 0, offset; + ULONG messageSize = 0; + ULONG_PTR offset; NTLM_BLOB blobBuffer[2]; //nego contains 2 blobs - - TRACE("NtlmGenerateNegotiateMessage %lx flags %lx\n", Context, NegotiateFlags);
if(!*OutputToken) { @@ -81,32 +80,27 @@ message->MsgType = NtlmNegotiate; message->NegotiateFlags = context->NegotiateFlags;
- offset = PtrToUlong(message+1); - - TRACE("message %p size %lu offset1 %lu offset2 %lu\n", - message, messageSize, offset, offset+1); - - /* generate payload */ - if(context->isLocal) - { + TRACE("nego message %p size %lu\n", message, messageSize); + + offset = (ULONG_PTR)(message+1); + + /* local connection */ + if((!cred->DomainName.Buffer && !cred->UserName.Buffer && + !cred->Password.Buffer) && cred->SecToken) + { + FIXME("try use local cached credentials?\n"); + message->NegotiateFlags |= (NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED | - NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED); - - /* blob1 */ - blobBuffer[0].Length = blobBuffer[0].MaxLength = NtlmOemDomainNameString.Length; - blobBuffer[0].Offset = offset; - message->OemDomainName = blobBuffer[0]; - - /* copy data to the end of the message */ - memcpy((PVOID)offset, NtlmOemDomainNameString.Buffer, NtlmOemDomainNameString.Length); - - /* blob2 */ - blobBuffer[1].Length = blobBuffer[1].MaxLength = NtlmOemComputerNameString.Length; - blobBuffer[1].Offset = offset + blobBuffer[0].Length; - message->OemWorkstationName = blobBuffer[0]; - - /* copy data to the end of the message */ - memcpy((PVOID)offset, NtlmOemComputerNameString.Buffer, NtlmOemComputerNameString.Length); + NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED | NTLMSSP_NEGOTIATE_LOCAL_CALL); + + NtlmUnicodeStringToBlob((PVOID)message, + (PUNICODE_STRING)&NtlmOemComputerNameString, + &message->OemWorkstationName, + &offset); + NtlmUnicodeStringToBlob((PVOID)message, + (PUNICODE_STRING)&NtlmOemDomainNameString, + &message->OemDomainName, + &offset); } else { @@ -123,21 +117,364 @@ (*OutputToken)->cbBuffer = messageSize; context->State = NegotiateSent;
+ TRACE("context %p context->NegotiateFlags:\n",context); + NtlmPrintNegotiateFlags(message->NegotiateFlags); + + /* free resources */ + NtlmFree(message); + return SEC_I_CONTINUE_NEEDED; }
SECURITY_STATUS NtlmHandleNegotiateMessage(IN ULONG_PTR hCredential, - IN OUT PULONG_PTR Context, + IN OUT PULONG_PTR phContext, IN ULONG ContextReq, IN PSecBuffer InputToken, OUT PSecBuffer *pOutputToken, - OUT PULONG fContextAttributes, + OUT PULONG pContextAttr, OUT PTimeStamp ptsExpiry) { + SECURITY_STATUS ret = SEC_E_OK; + PNEGOTIATE_MESSAGE negoMessage = NULL; + PNTLMSSP_CREDENTIAL cred = NULL; + PNTLMSSP_CONTEXT newContext = NULL;
ERR("NtlmHandleNegotiateMessage called!\n");
- return SEC_E_UNSUPPORTED_FUNCTION; + /* InputToken should contain a negotiate message*/ + if(InputToken->cbBuffer > NTLM_MAX_BUF || + InputToken->cbBuffer < sizeof(NEGOTIATE_MESSAGE)) + { + ERR("Input token too big!!\n"); + ret = SEC_E_INVALID_TOKEN; + goto exit; + } + + /* allocate a buffer for it */ + negoMessage = NtlmAllocate(InputToken->cbBuffer); + + if(!negoMessage) + { + ret = SEC_E_INSUFFICIENT_MEMORY; + goto exit; + } + + /* copy it */ + memcpy(negoMessage, InputToken->pvBuffer, InputToken->cbBuffer); + + /* validate it */ + if(strncmp(negoMessage->Signature, NTLMSSP_SIGNATURE, 8) && + negoMessage->MsgType == NtlmNegotiate) + { + ERR("Input message not valid!\n"); + ret = SEC_E_INVALID_TOKEN; + goto exit; + } + + TRACE("Got valid nego message! with flags:\n"); + NtlmPrintNegotiateFlags(negoMessage->NegotiateFlags); + + /* get credentials */ + cred = NtlmReferenceCredential(hCredential); + if(!cred) + goto exit; + + /* must be an incomming request */ + if(!(cred->UseFlags & SECPKG_CRED_INBOUND)) + { + ret = SEC_E_UNSUPPORTED_FUNCTION; + goto exit; + } + + /* create new context */ + newContext = NtlmAllocateContext(); + if(!newContext) + { + ret = SEC_E_INSUFFICIENT_MEMORY; + goto exit; + } + + *phContext = (ULONG_PTR)newContext; + + if(ContextReq & ASC_REQ_IDENTIFY) + { + *pContextAttr |= ASC_RET_IDENTIFY; + newContext->ContextFlags |= ASC_RET_IDENTIFY; + } + + if(ContextReq & ASC_REQ_DATAGRAM) + { + *pContextAttr |= ASC_RET_DATAGRAM; + newContext->ContextFlags |= ASC_RET_DATAGRAM; + } + + if(ContextReq & ASC_REQ_CONNECTION) + { + *pContextAttr |= ASC_RET_CONNECTION; + newContext->ContextFlags |= ASC_RET_CONNECTION; + } + + if(ContextReq & ASC_REQ_INTEGRITY) + { + *pContextAttr |= ASC_RET_INTEGRITY; + newContext->ContextFlags |= ASC_RET_INTEGRITY; + } + + if(ContextReq & ASC_REQ_REPLAY_DETECT) + { + *pContextAttr |= ASC_RET_REPLAY_DETECT; + newContext->ContextFlags |= ASC_RET_REPLAY_DETECT; + } + + if(ContextReq & ASC_REQ_SEQUENCE_DETECT) + { + *pContextAttr |= ASC_RET_SEQUENCE_DETECT; + newContext->ContextFlags |= ASC_RET_SEQUENCE_DETECT; + } + + if(ContextReq & ASC_REQ_ALLOW_NULL_SESSION) + { + newContext->ContextFlags |= ASC_REQ_ALLOW_NULL_SESSION; + } + + if(ContextReq & ASC_REQ_ALLOW_NON_USER_LOGONS) + { + *pContextAttr |= ASC_RET_ALLOW_NON_USER_LOGONS; + newContext->ContextFlags |= ASC_RET_ALLOW_NON_USER_LOGONS; + } + + /* encryption */ + if(ContextReq & ASC_REQ_CONFIDENTIALITY) + { + *pContextAttr |= ASC_RET_CONFIDENTIALITY; + newContext->ContextFlags |= ASC_RET_CONFIDENTIALITY; + } + +exit: + ERR("FIXME: HERE!!!!!!!!!!!!!!!"); + return ret; }
+SECURITY_STATUS +NtlmHandleChallengeMessage(IN ULONG_PTR hContext, + IN ULONG ContextReq, + IN PSecBuffer InputToken1, + IN PSecBuffer InputToken2, + IN OUT PSecBuffer *OutputToken1, + IN OUT PSecBuffer *OutputToken2, + OUT PULONG pContextAttr, + OUT PTimeStamp ptsExpiry, + OUT PULONG NegotiateFlags) +{ + SECURITY_STATUS ret = SEC_E_OK; + PNTLMSSP_CONTEXT context; + PCHALLENGE_MESSAGE challenge; + BOOLEAN isUnicode; + + /* get context */ + context = NtlmReferenceContext(hContext); + if(!context || !context->Credential) + { + ERR("NtlmHandleChallengeMessage invalid handle!\n"); + ret = SEC_E_INVALID_HANDLE; + goto exit; + } + + /* re-authenticate call */ + if(context->State == AuthenticateSent) + { + UNIMPLEMENTED; + } + else if(context->State != NegotiateSent) + { + ERR("Context not in negotiate sent state!\n"); + ret = SEC_E_OUT_OF_SEQUENCE; + goto exit; + } + + /* InputToken1 should contain a challenge message */ + TRACE("input token size %lx\n", InputToken1->cbBuffer); + if(InputToken1->cbBuffer > NTLM_MAX_BUF || + InputToken1->cbBuffer < sizeof(CHALLENGE_MESSAGE)) + { + ERR("Input token invalid!\n"); + ret = SEC_E_INVALID_TOKEN; + goto exit; + } + + /* allocate a buffer for it */ + challenge = NtlmAllocate(InputToken1->cbBuffer); + if(!challenge) + { + ERR("failed to allocate challenge buffer!\n"); + ret = SEC_E_INSUFFICIENT_MEMORY; + goto exit; + } + + /* copy it */ + memcpy(challenge, InputToken1->pvBuffer, InputToken1->cbBuffer); + + /* validate it */ + if(strncmp(challenge->Signature, NTLMSSP_SIGNATURE, 8) && + challenge->MsgType == NtlmChallenge) + { + ERR("Input message not valid!\n"); + ret = SEC_E_INVALID_TOKEN; + goto exit; + } + + TRACE("Got valid challege message! with flags:\n"); + NtlmPrintNegotiateFlags(challenge->NegotiateFlags); + + /* print challenge message and payloads */ + NtlmPrintHexDump((PBYTE)challenge, InputToken1->cbBuffer); + + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM) + { + /* take out bad flags */ + challenge->NegotiateFlags &= + (context->NegotiateFlags | + NTLMSSP_NEGOTIATE_TARGET_INFO | + NTLMSSP_TARGET_TYPE_SERVER | + NTLMSSP_TARGET_TYPE_DOMAIN | + NTLMSSP_NEGOTIATE_LOCAL_CALL); + } + + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO) + context->NegotiateFlags |= NTLMSSP_NEGOTIATE_TARGET_INFO; + else + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_TARGET_INFO); + + /* if caller supports unicode prefer it over oem */ + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_UNICODE) + { + context->NegotiateFlags |= NTLMSSP_NEGOTIATE_UNICODE; + context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_OEM; + isUnicode = TRUE; + } + else if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_OEM) + { + context->NegotiateFlags |= NTLMSSP_NEGOTIATE_OEM; + context->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_UNICODE; + isUnicode = FALSE; + } + else + { + /* these flags must be bad! */ + ERR("challenge flags did not specify unicode or oem!\n"); + ret = SEC_E_INVALID_TOKEN; + goto exit; + } + + /* support ntlm2 */ + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY) + { + challenge->NegotiateFlags &= ~NTLMSSP_NEGOTIATE_LM_KEY; + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_LM_KEY); + } + else + { + /* did not support ntlm2 */ + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY); + + /* did not support ntlm */ + if(!(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_NTLM)) + { + ERR("netware authentication not supported!!!\n"); + ret = SEC_E_UNSUPPORTED_FUNCTION; + goto exit; + } + } + + /* did not support 128bit encryption */ + if(!(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_128)) + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_128); + + /* did not support 56bit encryption */ + if(!(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_56)) + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_56); + + /* did not support lm key */ + if(!(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_LM_KEY)) + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_LM_KEY); + + /* did not support key exchange */ + if(!(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_KEY_EXCH)) + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_KEY_EXCH); + + /* should sign */ + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN) + context->NegotiateFlags |= NTLMSSP_NEGOTIATE_ALWAYS_SIGN; + else + context->NegotiateFlags &= ~(NTLMSSP_NEGOTIATE_ALWAYS_SIGN); + + /* obligatory key exchange */ + if((context->NegotiateFlags & NTLMSSP_NEGOTIATE_DATAGRAM) && + (context->NegotiateFlags & (NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL))) + context->NegotiateFlags |= NTLMSSP_NEGOTIATE_KEY_EXCH; + + /* unimplemented */ + if(challenge->NegotiateFlags & NTLMSSP_NEGOTIATE_LOCAL_CALL) + ERR("NTLMSSP_NEGOTIATE_LOCAL_CALL set!\n"); + + /* extract target info */ + UNICODE_STRING ServerName; + + if(context->NegotiateFlags & NTLMSSP_NEGOTIATE_TARGET_INFO) + { + /* wtf? shouldnt this contain AV pairs? */ + ret = NtlmBlobToUnicodeString(InputToken1, + challenge->TargetInfo, + &ServerName); + if(!NT_SUCCESS(ret)) + { + ERR("could not get target info!\n"); + goto exit; + } + } + else + { + /* spec: "A server that is a member of a domain returns the domain of which it + * is a member, and a server that is not a member of a domain returns + * the server name." how to tell?? */ + ret = NtlmBlobToUnicodeString(InputToken1, + challenge->TargetName, + &ServerName); + if(!NT_SUCCESS(ret)) + { + ERR("could not get target info!\n"); + goto exit; + } + if(isUnicode) + FIXME("convert to unicode!\n"); + } + TRACE("ServerName %s\n", debugstr_w(ServerName.Buffer)); + + PNTLMSSP_CREDENTIAL cred = NtlmReferenceCredential((ULONG_PTR)context->Credential); + MSV1_0_NTLM3_RESPONSE NtResponse; + LM2_RESPONSE Lm2Response; + USER_SESSION_KEY UserSessionKey; + LM_SESSION_KEY LmSessionKey; + + NtlmUnProtectMemory(cred->Password.Buffer, cred->Password.Length * sizeof(WCHAR)); + + TRACE("cred: %s %s %s\n", debugstr_w(cred->UserName.Buffer), + debugstr_w(cred->Password.Buffer), debugstr_w(cred->DomainName.Buffer)); + + NtlmChallengeResponse(&cred->UserName, + &cred->Password, + &cred->DomainName, + &ServerName, + challenge->ServerChallenge, + &NtResponse, + &Lm2Response, + &UserSessionKey, + &LmSessionKey); + +exit: + ERR("handle challenge end\n"); + + return ret; +} +
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/protocol.h [iso-8859-1] Thu May 26 02:35:38 2011 @@ -37,20 +37,20 @@ #define NTLMSSP_NEGOTIATE_SEAL 0x00000020 #define NTLMSSP_NEGOTIATE_DATAGRAM 0x00000040 #define NTLMSSP_NEGOTIATE_LM_KEY 0x00000080 -#define NTLMSSP_RESERVED_8 0x00000100 +#define NTLMSSP_NEGOTIATE_NETWARE 0x00000100 //forget about it #define NTLMSSP_NEGOTIATE_NTLM 0x00000200 #define NTLMSSP_NEGOTIATE_NT_ONLY 0x00000400 -#define NTLMSSP_RESERVED_7 0x00000800 +#define NTLMSSP_NEGOTIATE_NULL_SESSION 0x00000800 #define NTLMSSP_NEGOTIATE_OEM_DOMAIN_SUPPLIED 0x00001000 #define NTLMSSP_NEGOTIATE_OEM_WORKSTATION_SUPPLIED 0x00002000 -#define NTLMSSP_RESERVED_6 0x00004000 +#define NTLMSSP_NEGOTIATE_LOCAL_CALL 0x00004000 #define NTLMSSP_NEGOTIATE_ALWAYS_SIGN 0x00008000 #define NTLMSSP_TARGET_TYPE_DOMAIN 0x00010000 #define NTLMSSP_TARGET_TYPE_SERVER 0x00020000 #define NTLMSSP_TARGET_TYPE_SHARE 0x00040000 -#define NTLMSSP_NEGOTIATE_NTLM2 0x00080000 -#define NTLMSSP_NEGOTIATE_IDENTIFY 0x00100000 -#define NTLMSSP_RESERVED_5 0x00200000 +#define NTLMSSP_NEGOTIATE_EXTENDED_SESSIONSECURITY 0x00080000 +#define NTLMSSP_REQUEST_INIT_RESP 0x00100000 +#define NTLMSSP_REQUEST_ACCEPT_RESP 0x00200000 //get session key and luid #define NTLMSSP_REQUEST_NON_NT_SESSION_KEY 0x00400000 #define NTLMSSP_NEGOTIATE_TARGET_INFO 0x00800000 #define NTLMSSP_RESERVED_4 0x01000000 @@ -63,6 +63,41 @@ #define NTLMSSP_NEGOTIATE_56 0x80000000
#define NTLMSSP_REVISION_W2K3 0x0F + +/* basic types */ +typedef struct _CYPHER_BLOCK +{ + CHAR data[8]; +}CYPHER_BLOCK, *PCYPHER_BLOCK; + +typedef struct _USER_SESSION_KEY +{ + CYPHER_BLOCK data[2]; +}USER_SESSION_KEY, *PUSER_SESSION_KEY; + +typedef struct _NT_OWF_PASSWORD +{ + CYPHER_BLOCK data[2]; +}NT_OWF_PASSWORD, *PNT_OWF_PASSWORD; + +typedef struct _LM_OWF_PASSWORD +{ + CYPHER_BLOCK data[2]; +}LM_OWF_PASSWORD, *PLM_OWF_PASSWORD; + +/* where to put? correct ?*/ +typedef struct _LM_SESSION_KEY +{ + UCHAR data[MSV1_0_LANMAN_SESSION_KEY_LENGTH]; +} LM_SESSION_KEY, *PLM_SESSION_KEY; + +typedef struct _LM2_RESPONSE +{ + UCHAR Response[MSV1_0_NTLM3_RESPONSE_LENGTH]; + UCHAR ChallengeFromClient[MSV1_0_CHALLENGE_LENGTH]; +} LM2_RESPONSE, *PLM2_RESPONSE; + +/* message types */
//only filled if NTLMSSP_NEGOTIATE_VERSION is present //ignored on retail builds @@ -129,11 +164,116 @@ /* payload */ }AUTHENTICATE_MESSAGE, *PAUTHENTICATE_MESSAGE;
+/* basic functions */ + +VOID +NTOWFv1( + const PWCHAR password, + PUCHAR result); + +VOID +NTOWFv2( + PWCHAR password, + PWCHAR user, + PWCHAR domain, + PUCHAR result); + +VOID +LMOWFv1( + PCCHAR password, + PUCHAR result); + +VOID +LMOWFv2( + const PWCHAR password, + const PWCHAR user, + const PWCHAR domain, + PUCHAR result); + +VOID +NONCE( + PUCHAR buffer, + ULONG num); + +VOID +KXKEY( + ULONG flags, + const PUCHAR session_base_key, + const PUCHAR lm_challenge_resonse, + const PUCHAR server_challenge, + PUCHAR key_exchange_key); + +VOID +SIGNKEY( + const PUCHAR RandomSessionKey, + BOOLEAN IsClient, + PUCHAR Result); + +VOID +SEALKEY( + ULONG flags, + const PUCHAR RandomSessionKey, + BOOLEAN client, + PUCHAR result); + +VOID +MAC(ULONG flags, + PCCHAR buf, + ULONG buf_len, + PUCHAR sign_key, + ULONG sign_key_len, + PUCHAR seal_key, + ULONG seal_key_len, + ULONG random_pad, + ULONG sequence, + PUCHAR result); + +VOID +NtlmChallengeResponse( + IN PUNICODE_STRING pUserName, + IN PUNICODE_STRING pPassword, + IN PUNICODE_STRING pDomainName, + IN PUNICODE_STRING pServerName, + IN UCHAR ChallengeToClient[MSV1_0_CHALLENGE_LENGTH], + OUT PMSV1_0_NTLM3_RESPONSE pNtResponse, + OUT PLM2_RESPONSE pLm2Response, + OUT PUSER_SESSION_KEY UserSessionKey, + OUT PLM_SESSION_KEY LmSessionKey); + +/* avl functions */ + +PMSV1_0_AV_PAIR +NtlmAvlInit( + IN void * pAvList); + +PMSV1_0_AV_PAIR +NtlmAvlGet( + IN PMSV1_0_AV_PAIR pAvList, + IN MSV1_0_AVID AvId, + IN LONG cAvList); + +ULONG +NtlmAvlLen( + IN PMSV1_0_AV_PAIR pAvList, + IN LONG cAvList); + +PMSV1_0_AV_PAIR +NtlmAvlAdd( + IN PMSV1_0_AV_PAIR pAvList, + IN MSV1_0_AVID AvId, + IN PUNICODE_STRING pString, + IN LONG cAvList); + +ULONG +NtlmAvlSize( + IN ULONG Pairs, + IN ULONG PairsLen); + +/* message functions */ SECURITY_STATUS NtlmGenerateNegotiateMessage( IN ULONG_PTR hContext, IN ULONG ContextReq, - IN ULONG NegotiateFlags, IN PSecBuffer InputToken, OUT PSecBuffer *OutputToken);
@@ -144,17 +284,28 @@ IN ULONG fContextReq, IN PSecBuffer InputToken, OUT PSecBuffer *OutputToken, - OUT PULONG fContextAttributes, + OUT PULONG pContextAttr, OUT PTimeStamp ptsExpiry);
SECURITY_STATUS +NtlmHandleChallengeMessage( + IN ULONG_PTR hContext, + IN ULONG ContextReq, + IN PSecBuffer InputToken1, + IN PSecBuffer InputToken2, + IN OUT PSecBuffer *OutputToken1, + IN OUT PSecBuffer *OutputToken2, + OUT PULONG ContextAttr, + OUT PTimeStamp ptsExpiry, + OUT PULONG NegotiateFlags); + +SECURITY_STATUS NtlmHandleAuthenticateMessage( - IN ULONG_PTR hCredential, - IN OUT PULONG_PTR phContext, + IN ULONG_PTR hContext, IN ULONG fContextReq, IN PSecBuffer *pInputTokens, OUT PSecBuffer OutputToken, - OUT PULONG fContextAttributes, + OUT PULONG pContextAttr, OUT PTimeStamp ptsExpiry, OUT PUCHAR pSessionKey, OUT PULONG pfNegotiateFlags, @@ -163,3 +314,18 @@ OUT PTimeStamp ptsPasswordExpiry, OUT PULONG pfUserFlags);
+/* helper functions */ + +SECURITY_STATUS +NtlmBlobToUnicodeString( + IN PSecBuffer InputBuffer, + IN NTLM_BLOB Blob, + IN OUT PUNICODE_STRING OutputStr); + +VOID +NtlmUnicodeStringToBlob( + IN PVOID OutputBuffer, + IN PUNICODE_STRING InStr, + IN OUT PNTLM_BLOB OutputBlob, + IN OUT PULONG_PTR OffSet); +
Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.c (removed) @@ -1,98 +1,0 @@ -/* - * rc4.c - * - * Copyright (c) 1996-2000 Whistle Communications, Inc. - * All rights reserved. - * - * Subject to the following obligations and disclaimer of warranty, use and - * redistribution of this software, in source or object code forms, with or - * without modifications are expressly permitted by Whistle Communications; - * provided, however, that: - * 1. Any and all reproductions of the source or object code must include the - * copyright notice above and the following disclaimer of warranties; and - * 2. No rights are granted, in any manner or form, to use Whistle - * Communications, Inc. trademarks, including the mark "WHISTLE - * COMMUNICATIONS" on advertising, endorsements, or otherwise except as - * such appears in the above copyright notice or in the software. - * - * THIS SOFTWARE IS BEING PROVIDED BY WHISTLE COMMUNICATIONS "AS IS", AND - * TO THE MAXIMUM EXTENT PERMITTED BY LAW, WHISTLE COMMUNICATIONS MAKES NO - * REPRESENTATIONS OR WARRANTIES, EXPRESS OR IMPLIED, REGARDING THIS SOFTWARE, - * INCLUDING WITHOUT LIMITATION, ANY AND ALL IMPLIED WARRANTIES OF - * MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, OR NON-INFRINGEMENT. - * WHISTLE COMMUNICATIONS DOES NOT WARRANT, GUARANTEE, OR MAKE ANY - * REPRESENTATIONS REGARDING THE USE OF, OR THE RESULTS OF THE USE OF THIS - * SOFTWARE IN TERMS OF ITS CORRECTNESS, ACCURACY, RELIABILITY OR OTHERWISE. - * IN NO EVENT SHALL WHISTLE COMMUNICATIONS BE LIABLE FOR ANY DAMAGES - * RESULTING FROM OR ARISING OUT OF ANY USE OF THIS SOFTWARE, INCLUDING - * WITHOUT LIMITATION, ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, - * PUNITIVE, OR CONSEQUENTIAL DAMAGES, PROCUREMENT OF SUBSTITUTE GOODS OR - * SERVICES, LOSS OF USE, DATA OR PROFITS, HOWEVER CAUSED AND UNDER 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 WHISTLE COMMUNICATIONS IS ADVISED OF THE POSSIBILITY - * OF SUCH DAMAGE. - * - * $FreeBSD: src/sys/crypto/rc4/rc4.c,v 1.2.2.1 2000/04/18 04:48:31 archie Exp $ - */ -#include "rc4.h" - -static inline void swap_bytes(unsigned char *a, unsigned char *b) -{ - unsigned char swapByte; - - swapByte = *a; - *a = *b; - *b = swapByte; -} - -/* - * Initialize an RC4 state buffer using the supplied key, - * which can have arbitrary length. - */ -void -rc4_init(rc4_key *const state, const unsigned char *key, int keylen) -{ - unsigned char j; - int i; - - /* Initialize state with identity permutation */ - for (i = 0; i < 256; i++) - state->perm[i] = (unsigned char)i; - state->index1 = 0; - state->index2 = 0; - - /* Randomize the permutation using key data */ - for (j = i = 0; i < 256; i++) { - j += state->perm[i] + key[i % keylen]; - swap_bytes(&state->perm[i], &state->perm[j]); - } -} - -/* - * Encrypt some data using the supplied RC4 state buffer. - * The input and output buffers may be the same buffer. - * Since RC4 is a stream cypher, this function is used - * for both encryption and decryption. - */ -void -rc4_crypt(rc4_key *const state, const unsigned char *inbuf, unsigned char *outbuf, int buflen) -{ - int i; - unsigned char j; - - for (i = 0; i < buflen; i++) - { - /* Update modification indicies */ - state->index1++; - state->index2 += state->perm[state->index1]; - - /* Modify permutation */ - swap_bytes(&state->perm[state->index1], - &state->perm[state->index2]); - - /* Encrypt/decrypt next byte */ - j = state->perm[state->index1] + state->perm[state->index2]; - outbuf[i] = inbuf[i] ^ state->perm[j]; - } -}
Removed: branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.h URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.h [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/rc4.h (removed) @@ -1,10 +1,0 @@ - -typedef struct _rc4_key -{ - unsigned char perm[256]; - unsigned char index1; - unsigned char index2; -}rc4_key; - -void rc4_init(rc4_key *const state, const unsigned char *key, int keylen); -void rc4_crypt(rc4_key *const state, const unsigned char *inbuf, unsigned char *outbuf, int buflen);
Modified: branches/sspi-bringup/reactos/dll/win32/ntlmssp/util.c URL: http://svn.reactos.org/svn/reactos/branches/sspi-bringup/reactos/dll/win32/n... ============================================================================== --- branches/sspi-bringup/reactos/dll/win32/ntlmssp/util.c [iso-8859-1] (original) +++ branches/sspi-bringup/reactos/dll/win32/ntlmssp/util.c [iso-8859-1] Thu May 26 02:35:38 2011 @@ -18,6 +18,7 @@ */
#include "ntlmssp.h" +#include "protocol.h"
#include "wine/debug.h" WINE_DEFAULT_DEBUG_CHANNEL(ntlm); @@ -176,3 +177,43 @@ } return FALSE; } + +SECURITY_STATUS +NtlmBlobToUnicodeString(IN PSecBuffer InputBuffer, + IN NTLM_BLOB Blob, + IN OUT PUNICODE_STRING OutputStr) +{ + ULONG offset = Blob.Offset; + + /* check blob is not beyond the bounds of the input buffer */ + if(offset >= InputBuffer->cbBuffer || + offset + Blob.Length > InputBuffer->cbBuffer) + { + ERR("blob points beyond buffer bounds!\n"); + return SEC_E_INVALID_TOKEN; + } + + /* convert blob into a string */ + OutputStr->MaximumLength = OutputStr->Length = Blob.Length; + OutputStr->Buffer = (PWSTR)((PCHAR)InputBuffer->pvBuffer) + offset; + + return SEC_E_OK; +} + +VOID +NtlmUnicodeStringToBlob(IN PVOID OutputBuffer, + IN PUNICODE_STRING InStr, + IN OUT PNTLM_BLOB OutputBlob, + IN OUT PULONG_PTR OffSet) +{ + /* copy string to target location */ + if(InStr->Buffer) + memcpy((PVOID)*OffSet, InStr->Buffer, InStr->Length); + + /* set blob fields */ + OutputBlob->Length = OutputBlob->MaxLength = InStr->Length; + OutputBlob->Offset = (ULONG)(*OffSet - (ULONG_PTR)OutputBuffer); + + /* move the offset to the end of the string we just copied */ + *OffSet += InStr->Length; +}