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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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/…
==============================================================================
--- 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;
+}