ReactOS 0.4.15-dev-8096-ga0eec98
ntlm.c File Reference
#include "precomp.h"
#include <assert.h>
#include <stdio.h>
#include <wincred.h>
#include <lm.h>
#include "hmac_md5.h"
#include <wine/unicode.h>
#include <wine/debug.h>
Include dependency graph for ntlm.c:

Go to the source code of this file.

Macros

#define NTLM_MAX_BUF   1904
 
#define MIN_NTLM_AUTH_MAJOR_VERSION   3
 
#define MIN_NTLM_AUTH_MINOR_VERSION   0
 
#define MIN_NTLM_AUTH_MICRO_VERSION   25
 
#define _x(x)   case (x) : FIXME(#x" stub\n"); break
 
#define NTLM_COMMENT
 
#define NTLM_NAME   {'N', 'T', 'L', 'M', 0}
 
#define CAPS
 

Functions

 WINE_DEFAULT_DEBUG_CHANNEL (ntlm)
 
 WINE_DECLARE_DEBUG_CHANNEL (winediag)
 
static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA (PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
 
static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW (PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
 
static charntlm_GetUsernameArg (LPCWSTR userW, INT userW_length)
 
static charntlm_GetDomainArg (LPCWSTR domainW, INT domainW_length)
 
SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW (SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
 
static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA (SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
 
static int ntlm_GetTokenBufferIndex (PSecBufferDesc pMessage)
 
static int ntlm_GetDataBufferIndex (PSecBufferDesc pMessage)
 
static BOOL ntlm_GetCachedCredential (const SEC_WCHAR *pszTargetName, PCREDENTIALW *cred)
 
SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW (PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
 
static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA (PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
 
SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext (PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
 
static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken (PCtxtHandle phContext, PSecBufferDesc pToken)
 
SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext (PCtxtHandle phContext)
 
SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW (PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
 
SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA (PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
 
static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext (PCtxtHandle phContext)
 
static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext (PCtxtHandle phContext)
 
static SECURITY_STATUS ntlm_CreateSignature (PNegoHelper helper, PSecBufferDesc pMessage, int token_idx, SignDirection direction, BOOL encrypt_sig)
 
SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature (PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
 
SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature (PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
 
SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle (PCredHandle phCredential)
 
SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage (PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
 
SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage (PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
 
void SECUR32_initNTLMSP (void)
 

Variables

static CHAR ntlm_auth [] = "ntlm_auth"
 
static const SecurityFunctionTableA ntlmTableA
 
static const SecurityFunctionTableW ntlmTableW
 
static CHAR ntlm_comment_A [] = NTLM_COMMENT
 
static WCHAR ntlm_comment_W [] = NTLM_COMMENT
 
static char ntlm_name_A [] = NTLM_NAME
 
static WCHAR ntlm_name_W [] = NTLM_NAME
 
static const SecPkgInfoW infoW
 
static const SecPkgInfoA infoA
 
SecPkgInfoAntlm_package_infoA = (SecPkgInfoA *)&infoA
 
SecPkgInfoWntlm_package_infoW = (SecPkgInfoW *)&infoW
 

Macro Definition Documentation

◆ _x

#define _x (   x)    case (x) : FIXME(#x" stub\n"); break

◆ CAPS

#define CAPS
Value:
( \
#define SECPKG_FLAG_TOKEN_ONLY
Definition: sspi.h:128
#define SECPKG_FLAG_IMPERSONATION
Definition: sspi.h:134
#define SECPKG_FLAG_PRIVACY
Definition: sspi.h:127
#define SECPKG_FLAG_RESTRICTED_TOKENS
Definition: sspi.h:145
#define SECPKG_FLAG_MULTI_REQUIRED
Definition: sspi.h:131
#define SECPKG_FLAG_CONNECTION
Definition: sspi.h:130
#define SECPKG_FLAG_NEGOTIABLE
Definition: sspi.h:137
#define SECPKG_FLAG_INTEGRITY
Definition: sspi.h:126
#define SECPKG_FLAG_LOGON
Definition: sspi.h:139
#define SECPKG_FLAG_ACCEPT_WIN32_NAME
Definition: sspi.h:135

Definition at line 1993 of file ntlm.c.

◆ MIN_NTLM_AUTH_MAJOR_VERSION

#define MIN_NTLM_AUTH_MAJOR_VERSION   3

Definition at line 36 of file ntlm.c.

◆ MIN_NTLM_AUTH_MICRO_VERSION

#define MIN_NTLM_AUTH_MICRO_VERSION   25

Definition at line 39 of file ntlm.c.

◆ MIN_NTLM_AUTH_MINOR_VERSION

#define MIN_NTLM_AUTH_MINOR_VERSION   0

Definition at line 37 of file ntlm.c.

◆ NTLM_COMMENT

#define NTLM_COMMENT
Value:
{ 'N', 'T', 'L', 'M', ' ', \
'S', 'e', 'c', 'u', 'r', 'i', 't', 'y', ' ', \
'P', 'a', 'c', 'k', 'a', 'g', 'e', 0}

Definition at line 1979 of file ntlm.c.

◆ NTLM_MAX_BUF

#define NTLM_MAX_BUF   1904

Definition at line 35 of file ntlm.c.

◆ NTLM_NAME

#define NTLM_NAME   {'N', 'T', 'L', 'M', 0}

Definition at line 1987 of file ntlm.c.

Function Documentation

◆ ntlm_AcceptSecurityContext()

SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext ( PCredHandle  phCredential,
PCtxtHandle  phContext,
PSecBufferDesc  pInput,
ULONG  fContextReq,
ULONG  TargetDataRep,
PCtxtHandle  phNewContext,
PSecBufferDesc  pOutput,
ULONG pfContextAttr,
PTimeStamp  ptsExpiry 
)

Definition at line 1029 of file ntlm.c.

1033{
1035 char *buffer, *want_flags = NULL;
1036 PBYTE bin;
1037 int buffer_len, bin_len, max_len = NTLM_MAX_BUF;
1038 ULONG ctxt_attr = 0;
1039 PNegoHelper helper;
1040 PNtlmCredentials ntlm_cred;
1041
1042 TRACE("%p %p %p %d %d %p %p %p %p\n", phCredential, phContext, pInput,
1043 fContextReq, TargetDataRep, phNewContext, pOutput, pfContextAttr,
1044 ptsExpiry);
1045
1046 buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char) * NTLM_MAX_BUF);
1047 bin = HeapAlloc(GetProcessHeap(),0, sizeof(BYTE) * NTLM_MAX_BUF);
1048
1049 if(TargetDataRep == SECURITY_NETWORK_DREP){
1050 TRACE("Using SECURITY_NETWORK_DREP\n");
1051 }
1052
1053 if(phContext == NULL)
1054 {
1055 static CHAR server_helper_protocol[] = "--helper-protocol=squid-2.5-ntlmssp";
1056 SEC_CHAR *server_argv[] = { ntlm_auth,
1057 server_helper_protocol,
1058 NULL };
1059
1060 if (!phCredential)
1061 {
1063 goto asc_end;
1064 }
1065
1066 ntlm_cred = (PNtlmCredentials)phCredential->dwLower;
1067
1068 if(ntlm_cred->mode != NTLM_SERVER)
1069 {
1071 goto asc_end;
1072 }
1073
1074 /* This is the first call to AcceptSecurityHandle */
1075 if(pInput == NULL)
1076 {
1078 goto asc_end;
1079 }
1080
1081 if(pInput->cBuffers < 1)
1082 {
1084 goto asc_end;
1085 }
1086
1087 if(pInput->pBuffers[0].cbBuffer > max_len)
1088 {
1090 goto asc_end;
1091 }
1092 else
1093 bin_len = pInput->pBuffers[0].cbBuffer;
1094
1095 if( (ret = fork_helper(&helper, ntlm_auth, server_argv)) !=
1096 SEC_E_OK)
1097 {
1099 goto asc_end;
1100 }
1101 helper->mode = NTLM_SERVER;
1102
1103 /* Handle all the flags */
1104 want_flags = HeapAlloc(GetProcessHeap(), 0, 73);
1105 if(want_flags == NULL)
1106 {
1107 TRACE("Failed to allocate memory for the want_flags!\n");
1109 cleanup_helper(helper);
1110 goto asc_end;
1111 }
1112 lstrcpyA(want_flags, "SF");
1113 if(fContextReq & ASC_REQ_ALLOCATE_MEMORY)
1114 {
1115 FIXME("ASC_REQ_ALLOCATE_MEMORY stub\n");
1116 }
1117 if(fContextReq & ASC_REQ_CONFIDENTIALITY)
1118 {
1119 lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
1120 }
1121 if(fContextReq & ASC_REQ_CONNECTION)
1122 {
1123 /* This is default, so we'll enable it */
1124 lstrcatA(want_flags, " NTLMSSP_FEATURE_SESSION_KEY");
1125 ctxt_attr |= ASC_RET_CONNECTION;
1126 }
1127 if(fContextReq & ASC_REQ_EXTENDED_ERROR)
1128 {
1129 FIXME("ASC_REQ_EXTENDED_ERROR stub\n");
1130 }
1131 if(fContextReq & ASC_REQ_INTEGRITY)
1132 {
1133 lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
1134 }
1135 if(fContextReq & ASC_REQ_MUTUAL_AUTH)
1136 {
1137 FIXME("ASC_REQ_MUTUAL_AUTH stub\n");
1138 }
1139 if(fContextReq & ASC_REQ_REPLAY_DETECT)
1140 {
1141 FIXME("ASC_REQ_REPLAY_DETECT stub\n");
1142 }
1143 if(fContextReq & ISC_REQ_SEQUENCE_DETECT)
1144 {
1145 FIXME("ASC_REQ_SEQUENCE_DETECT stub\n");
1146 }
1147 if(fContextReq & ISC_REQ_STREAM)
1148 {
1149 FIXME("ASC_REQ_STREAM stub\n");
1150 }
1151 /* Done with the flags */
1152
1153 if(lstrlenA(want_flags) > 3)
1154 {
1155 TRACE("Server set want_flags: %s\n", debugstr_a(want_flags));
1156 lstrcpynA(buffer, want_flags, max_len - 1);
1157 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
1158 SEC_E_OK)
1159 {
1160 cleanup_helper(helper);
1161 goto asc_end;
1162 }
1163 if(!strncmp(buffer, "BH", 2))
1164 TRACE("Helper doesn't understand new command set\n");
1165 }
1166
1167 /* This is the YR request from the client, encode to base64 */
1168
1169 memcpy(bin, pInput->pBuffers[0].pvBuffer, bin_len);
1170
1171 lstrcpynA(buffer, "YR ", max_len-1);
1172
1173 if((ret = encodeBase64(bin, bin_len, buffer+3, max_len-3,
1174 &buffer_len)) != SEC_E_OK)
1175 {
1176 cleanup_helper(helper);
1177 goto asc_end;
1178 }
1179
1180 TRACE("Client sent: %s\n", debugstr_a(buffer));
1181
1182 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
1183 SEC_E_OK)
1184 {
1185 cleanup_helper(helper);
1186 goto asc_end;
1187 }
1188
1189 TRACE("Reply from ntlm_auth: %s\n", debugstr_a(buffer));
1190 /* The expected answer is TT <base64 blob> */
1191
1192 if(strncmp(buffer, "TT ", 3) != 0)
1193 {
1195 cleanup_helper(helper);
1196 goto asc_end;
1197 }
1198
1199 if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
1200 &bin_len)) != SEC_E_OK)
1201 {
1202 cleanup_helper(helper);
1203 goto asc_end;
1204 }
1205
1206 /* send this to the client */
1207 if(pOutput == NULL)
1208 {
1210 cleanup_helper(helper);
1211 goto asc_end;
1212 }
1213
1214 if(pOutput->cBuffers < 1)
1215 {
1217 cleanup_helper(helper);
1218 goto asc_end;
1219 }
1220
1221 pOutput->pBuffers[0].cbBuffer = bin_len;
1222 pOutput->pBuffers[0].BufferType = SECBUFFER_DATA;
1223 memcpy(pOutput->pBuffers[0].pvBuffer, bin, bin_len);
1225
1226 }
1227 else
1228 {
1229 /* we expect a KK request from client */
1230 if(pInput == NULL)
1231 {
1233 goto asc_end;
1234 }
1235
1236 if(pInput->cBuffers < 1)
1237 {
1239 goto asc_end;
1240 }
1241
1242 helper = (PNegoHelper)phContext->dwLower;
1243
1244 if(helper->mode != NTLM_SERVER)
1245 {
1247 goto asc_end;
1248 }
1249
1250 if(pInput->pBuffers[0].cbBuffer > max_len)
1251 {
1253 goto asc_end;
1254 }
1255 else
1256 bin_len = pInput->pBuffers[0].cbBuffer;
1257
1258 memcpy(bin, pInput->pBuffers[0].pvBuffer, bin_len);
1259
1260 lstrcpynA(buffer, "KK ", max_len-1);
1261
1262 if((ret = encodeBase64(bin, bin_len, buffer+3, max_len-3,
1263 &buffer_len)) != SEC_E_OK)
1264 {
1265 goto asc_end;
1266 }
1267
1268 TRACE("Client sent: %s\n", debugstr_a(buffer));
1269
1270 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) !=
1271 SEC_E_OK)
1272 {
1273 goto asc_end;
1274 }
1275
1276 TRACE("Reply from ntlm_auth: %s\n", debugstr_a(buffer));
1277
1278 /* At this point, we get a NA if the user didn't authenticate, but a BH
1279 * if ntlm_auth could not connect to winbindd. Apart from running Wine
1280 * as root, there is no way to fix this for now, so just handle this as
1281 * a failed login. */
1282 if(strncmp(buffer, "AF ", 3) != 0)
1283 {
1284 if(strncmp(buffer, "NA ", 3) == 0)
1285 {
1287 goto asc_end;
1288 }
1289 else
1290 {
1291 size_t ntlm_pipe_err_v3_len = strlen("BH NT_STATUS_ACCESS_DENIED");
1292 size_t ntlm_pipe_err_v4_len = strlen("BH NT_STATUS_UNSUCCESSFUL");
1293
1294 if( (buffer_len >= ntlm_pipe_err_v3_len &&
1295 strncmp(buffer, "BH NT_STATUS_ACCESS_DENIED", ntlm_pipe_err_v3_len) == 0) ||
1296 (buffer_len >= ntlm_pipe_err_v4_len &&
1297 strncmp(buffer, "BH NT_STATUS_UNSUCCESSFUL", ntlm_pipe_err_v4_len) == 0) )
1298 {
1299 TRACE("Connection to winbindd failed\n");
1301 }
1302 else
1304
1305 goto asc_end;
1306 }
1307 }
1308 pOutput->pBuffers[0].cbBuffer = 0;
1309
1310 TRACE("Getting negotiated flags\n");
1311 lstrcpynA(buffer, "GF", max_len - 1);
1312 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
1313 goto asc_end;
1314
1315 if(buffer_len < 3)
1316 {
1317 TRACE("No flags negotiated, or helper does not support GF command\n");
1318 }
1319 else
1320 {
1321 TRACE("Negotiated %s\n", debugstr_a(buffer));
1322 sscanf(buffer + 3, "%lx", &(helper->neg_flags));
1323 TRACE("Stored 0x%08x as flags\n", helper->neg_flags);
1324 }
1325
1326 TRACE("Getting session key\n");
1327 lstrcpynA(buffer, "GK", max_len - 1);
1328 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
1329 goto asc_end;
1330
1331 if(buffer_len < 3)
1332 TRACE("Helper does not support GK command\n");
1333 else
1334 {
1335 if(strncmp(buffer, "BH ", 3) == 0)
1336 {
1337 TRACE("Helper sent %s\n", debugstr_a(buffer+3));
1338 HeapFree(GetProcessHeap(), 0, helper->session_key);
1339 helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
1340 if (!helper->session_key)
1341 {
1343 goto asc_end;
1344 }
1345 /*FIXME: Generate the dummy session key = MD4(MD4(password))*/
1346 memset(helper->session_key, 0 , 16);
1347 }
1348 else if(strncmp(buffer, "GK ", 3) == 0)
1349 {
1350 if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
1351 &bin_len)) != SEC_E_OK)
1352 {
1353 TRACE("Failed to decode session key\n");
1354 }
1355 TRACE("Session key is %s\n", debugstr_a(buffer+3));
1356 HeapFree(GetProcessHeap(), 0, helper->session_key);
1357 helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
1358 if(!helper->session_key)
1359 {
1361 goto asc_end;
1362 }
1363 memcpy(helper->session_key, bin, 16);
1364 }
1365 }
1366 helper->crypt.ntlm.a4i = SECUR32_arc4Alloc();
1367 SECUR32_arc4Init(helper->crypt.ntlm.a4i, helper->session_key, 16);
1368 helper->crypt.ntlm.seq_num = 0l;
1369 }
1370
1371 phNewContext->dwUpper = ctxt_attr;
1372 phNewContext->dwLower = (ULONG_PTR)helper;
1373
1374asc_end:
1375 HeapFree(GetProcessHeap(), 0, want_flags);
1378 return ret;
1379}
ACPI_SIZE strlen(const char *String)
Definition: utclib.c:269
int strncmp(const char *String1, const char *String2, ACPI_SIZE Count)
Definition: utclib.c:534
SECURITY_STATUS decodeBase64(char *in_buf, int in_len, PBYTE out_buf, int max_len, int *out_len)
Definition: base64_codec.c:113
SECURITY_STATUS encodeBase64(PBYTE in_buf, int in_len, char *out_buf, int max_len, int *out_len)
Definition: base64_codec.c:29
#define FIXME(fmt,...)
Definition: debug.h:114
r l[0]
Definition: byte_order.h:168
#define NULL
Definition: types.h:112
#define GetProcessHeap()
Definition: compat.h:736
#define lstrcpynA
Definition: compat.h:751
#define HeapAlloc
Definition: compat.h:733
#define HeapFree(x, y, z)
Definition: compat.h:735
SECURITY_STATUS fork_helper(PNegoHelper *new_helper, const char *prog, char *const argv[])
Definition: dispatcher.c:76
SECURITY_STATUS run_helper(PNegoHelper helper, char *buffer, unsigned int max_buflen, int *buflen)
Definition: dispatcher.c:331
void cleanup_helper(PNegoHelper helper)
Definition: dispatcher.c:377
#define NTLM_MAX_BUF
Definition: ntlm.c:35
static CHAR ntlm_auth[]
Definition: ntlm.c:44
void SECUR32_arc4Init(arc4_info *a4i, const BYTE *key, unsigned int keyLen)
Definition: util.c:199
arc4_info * SECUR32_arc4Alloc(void)
Definition: util.c:189
#define ULONG_PTR
Definition: config.h:101
GLuint buffer
Definition: glext.h:5915
_Check_return_ _CRTIMP int __cdecl sscanf(_In_z_ const char *_Src, _In_z_ _Scanf_format_string_ const char *_Format,...)
#define debugstr_a
Definition: kernel32.h:31
LPSTR WINAPI lstrcpyA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:100
LPSTR WINAPI lstrcatA(LPSTR lpString1, LPCSTR lpString2)
Definition: lstring.c:123
int WINAPI lstrlenA(LPCSTR lpString)
Definition: lstring.c:145
#define memcpy(s1, s2, n)
Definition: mkisofs.h:878
static struct _PeImage bin
struct _NtlmCredentials * PNtlmCredentials
@ NTLM_SERVER
Definition: ntlm.h:11
struct _NegoHelper * PNegoHelper
BYTE * PBYTE
Definition: pedump.c:66
LONG SECURITY_STATUS
Definition: sspi.h:34
#define ASC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:432
#define ISC_REQ_STREAM
Definition: sspi.h:377
#define ASC_REQ_CONNECTION
Definition: sspi.h:435
#define ASC_REQ_CONFIDENTIALITY
Definition: sspi.h:430
#define ASC_RET_CONNECTION
Definition: sspi.h:458
#define SECURITY_NETWORK_DREP
Definition: sspi.h:474
#define ISC_REQ_SEQUENCE_DETECT
Definition: sspi.h:365
CHAR SEC_CHAR
Definition: sspi.h:30
#define ASC_REQ_REPLAY_DETECT
Definition: sspi.h:428
#define ASC_REQ_EXTENDED_ERROR
Definition: sspi.h:438
#define SECBUFFER_DATA
Definition: sspi.h:160
#define ASC_REQ_INTEGRITY
Definition: sspi.h:440
#define ASC_REQ_MUTUAL_AUTH
Definition: sspi.h:427
#define memset(x, y, z)
Definition: compat.h:39
#define TRACE(s)
Definition: solgame.cpp:4
struct _NegoHelper::@552 crypt
BYTE * session_key
Definition: ntlm.h:36
ULONG neg_flags
Definition: ntlm.h:37
HelperMode mode
Definition: ntlm.h:27
HelperMode mode
Definition: ntlm.h:58
ULONG cBuffers
Definition: sspi.h:182
ULONG_PTR dwLower
Definition: sspi.h:53
ULONG_PTR dwUpper
Definition: sspi.h:54
uint32_t ULONG
Definition: typedefs.h:59
int ret
#define SEC_E_OK
Definition: winerror.h:2356
#define SEC_E_INVALID_HANDLE
Definition: winerror.h:2910
#define SEC_E_LOGON_DENIED
Definition: winerror.h:2921
#define SEC_E_INTERNAL_ERROR
Definition: winerror.h:2913
#define SEC_E_INVALID_TOKEN
Definition: winerror.h:2917
#define SEC_E_INSUFFICIENT_MEMORY
Definition: winerror.h:2909
#define SEC_I_CONTINUE_NEEDED
Definition: winerror.h:2927
#define SEC_E_INCOMPLETE_MESSAGE
Definition: winerror.h:2934
char CHAR
Definition: xmlstorage.h:175
unsigned char BYTE
Definition: xxhash.c:193

Referenced by nego_AcceptSecurityContext().

◆ ntlm_AcquireCredentialsHandleA()

static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA ( SEC_CHAR pszPrincipal,
SEC_CHAR pszPackage,
ULONG  fCredentialUse,
PLUID  pLogonID,
PVOID  pAuthData,
SEC_GET_KEY_FN  pGetKeyFn,
PVOID  pGetKeyArgument,
PCredHandle  phCredential,
PTimeStamp  ptsExpiry 
)
static

Definition at line 290 of file ntlm.c.

294{
296 int user_sizeW, domain_sizeW, passwd_sizeW;
297
298 SEC_WCHAR *user = NULL, *domain = NULL, *passwd = NULL, *package = NULL;
299
300 PSEC_WINNT_AUTH_IDENTITY_W pAuthDataW = NULL;
302
303 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
304 debugstr_a(pszPrincipal), debugstr_a(pszPackage), fCredentialUse,
305 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
306
307 if(pszPackage != NULL)
308 {
309 int package_sizeW = MultiByteToWideChar(CP_ACP, 0, pszPackage, -1,
310 NULL, 0);
311
312 package = HeapAlloc(GetProcessHeap(), 0, package_sizeW *
313 sizeof(SEC_WCHAR));
314 MultiByteToWideChar(CP_ACP, 0, pszPackage, -1, package, package_sizeW);
315 }
316
317
318 if(pAuthData != NULL)
319 {
320 identity = pAuthData;
321
323 {
324 pAuthDataW = HeapAlloc(GetProcessHeap(), 0,
326
327 if(identity->UserLength != 0)
328 {
329 user_sizeW = MultiByteToWideChar(CP_ACP, 0,
330 (LPCSTR)identity->User, identity->UserLength, NULL, 0);
331 user = HeapAlloc(GetProcessHeap(), 0, user_sizeW *
332 sizeof(SEC_WCHAR));
334 identity->UserLength, user, user_sizeW);
335 }
336 else
337 {
338 user_sizeW = 0;
339 }
340
341 if(identity->DomainLength != 0)
342 {
343 domain_sizeW = MultiByteToWideChar(CP_ACP, 0,
344 (LPCSTR)identity->Domain, identity->DomainLength, NULL, 0);
345 domain = HeapAlloc(GetProcessHeap(), 0, domain_sizeW
346 * sizeof(SEC_WCHAR));
348 identity->DomainLength, domain, domain_sizeW);
349 }
350 else
351 {
352 domain_sizeW = 0;
353 }
354
355 if(identity->PasswordLength != 0)
356 {
357 passwd_sizeW = MultiByteToWideChar(CP_ACP, 0,
358 (LPCSTR)identity->Password, identity->PasswordLength,
359 NULL, 0);
360 passwd = HeapAlloc(GetProcessHeap(), 0, passwd_sizeW
361 * sizeof(SEC_WCHAR));
363 identity->PasswordLength, passwd, passwd_sizeW);
364 }
365 else
366 {
367 passwd_sizeW = 0;
368 }
369
370 pAuthDataW->Flags = SEC_WINNT_AUTH_IDENTITY_UNICODE;
371 pAuthDataW->User = user;
372 pAuthDataW->UserLength = user_sizeW;
373 pAuthDataW->Domain = domain;
374 pAuthDataW->DomainLength = domain_sizeW;
375 pAuthDataW->Password = passwd;
376 pAuthDataW->PasswordLength = passwd_sizeW;
377 }
378 else
379 {
381 }
382 }
383
384 ret = ntlm_AcquireCredentialsHandleW(NULL, package, fCredentialUse,
385 pLogonID, pAuthDataW, pGetKeyFn, pGetKeyArgument, phCredential,
386 ptsExpiry);
387
388 HeapFree(GetProcessHeap(), 0, package);
391 HeapFree(GetProcessHeap(), 0, passwd);
392 if(pAuthDataW != (PSEC_WINNT_AUTH_IDENTITY_W)identity)
393 HeapFree(GetProcessHeap(), 0, pAuthDataW);
394
395 return ret;
396}
void user(int argc, const char *argv[])
Definition: cmds.c:1350
#define CP_ACP
Definition: compat.h:109
#define MultiByteToWideChar
Definition: compat.h:110
SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW(SEC_WCHAR *pszPrincipal, SEC_WCHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: ntlm.c:127
WCHAR SEC_WCHAR
Definition: sspi.h:29
struct _SEC_WINNT_AUTH_IDENTITY_W * PSEC_WINNT_AUTH_IDENTITY_W
#define SEC_WINNT_AUTH_IDENTITY_UNICODE
Definition: rpcdce.h:310
#define SEC_WINNT_AUTH_IDENTITY_ANSI
Definition: rpcdce.h:309
Definition: cookie.c:42
const char * LPCSTR
Definition: xmlstorage.h:183

◆ ntlm_AcquireCredentialsHandleW()

SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleW ( SEC_WCHAR pszPrincipal,
SEC_WCHAR pszPackage,
ULONG  fCredentialUse,
PLUID  pLogonID,
PVOID  pAuthData,
SEC_GET_KEY_FN  pGetKeyFn,
PVOID  pGetKeyArgument,
PCredHandle  phCredential,
PTimeStamp  ptsExpiry 
)

Definition at line 127 of file ntlm.c.

131{
133 PNtlmCredentials ntlm_cred;
136
137 TRACE("(%s, %s, 0x%08x, %p, %p, %p, %p, %p, %p)\n",
138 debugstr_w(pszPrincipal), debugstr_w(pszPackage), fCredentialUse,
139 pLogonID, pAuthData, pGetKeyFn, pGetKeyArgument, phCredential, ptsExpiry);
140
141 switch(fCredentialUse)
142 {
144 ntlm_cred = HeapAlloc(GetProcessHeap(), 0, sizeof(*ntlm_cred));
145 if (!ntlm_cred)
147 else
148 {
149 ntlm_cred->mode = NTLM_SERVER;
150 ntlm_cred->username_arg = NULL;
151 ntlm_cred->domain_arg = NULL;
152 ntlm_cred->password = NULL;
153 ntlm_cred->pwlen = 0;
154 ntlm_cred->no_cached_credentials = 0;
155
156 phCredential->dwUpper = fCredentialUse;
157 phCredential->dwLower = (ULONG_PTR)ntlm_cred;
158 ret = SEC_E_OK;
159 }
160 break;
162 {
163 auth_data = pAuthData;
164 ntlm_cred = HeapAlloc(GetProcessHeap(), 0, sizeof(*ntlm_cred));
165 if (!ntlm_cred)
166 {
168 break;
169 }
170 ntlm_cred->mode = NTLM_CLIENT;
171 ntlm_cred->username_arg = NULL;
172 ntlm_cred->domain_arg = NULL;
173 ntlm_cred->password = NULL;
174 ntlm_cred->pwlen = 0;
175 ntlm_cred->no_cached_credentials = 0;
176
177 if(pAuthData != NULL)
178 {
179 int domain_len = 0, user_len = 0, password_len = 0;
180
181 if (auth_data->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
182 {
183 if (auth_data->DomainLength)
184 {
185 domain_len = MultiByteToWideChar(CP_ACP, 0, (char *)auth_data->Domain,
186 auth_data->DomainLength, NULL, 0);
187 domain = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * domain_len);
188 if(!domain)
189 {
191 break;
192 }
193 MultiByteToWideChar(CP_ACP, 0, (char *)auth_data->Domain, auth_data->DomainLength,
194 domain, domain_len);
195 }
196
197 if (auth_data->UserLength)
198 {
199 user_len = MultiByteToWideChar(CP_ACP, 0, (char *)auth_data->User,
200 auth_data->UserLength, NULL, 0);
201 user = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * user_len);
202 if(!user)
203 {
205 break;
206 }
207 MultiByteToWideChar(CP_ACP, 0, (char *)auth_data->User, auth_data->UserLength,
208 user, user_len);
209 }
210
211 if (auth_data->PasswordLength)
212 {
213 password_len = MultiByteToWideChar(CP_ACP, 0,(char *)auth_data->Password,
214 auth_data->PasswordLength, NULL, 0);
215 password = HeapAlloc(GetProcessHeap(), 0, sizeof(WCHAR) * password_len);
216 if(!password)
217 {
219 break;
220 }
221 MultiByteToWideChar(CP_ACP, 0, (char *)auth_data->Password, auth_data->PasswordLength,
222 password, password_len);
223 }
224 }
225 else
226 {
227 domain = auth_data->Domain;
228 domain_len = auth_data->DomainLength;
229
230 user = auth_data->User;
231 user_len = auth_data->UserLength;
232
233 password = auth_data->Password;
234 password_len = auth_data->PasswordLength;
235 }
236
237 TRACE("Username is %s\n", debugstr_wn(user, user_len));
238 TRACE("Domain name is %s\n", debugstr_wn(domain, domain_len));
239
240 ntlm_cred->username_arg = ntlm_GetUsernameArg(user, user_len);
241 ntlm_cred->domain_arg = ntlm_GetDomainArg(domain, domain_len);
242
243 if(password_len != 0)
244 {
246 password_len, NULL, 0, NULL, NULL);
247
248 ntlm_cred->password = HeapAlloc(GetProcessHeap(), 0,
249 ntlm_cred->pwlen);
250 if(!ntlm_cred->password)
251 {
253 break;
254 }
255
257 ntlm_cred->password, ntlm_cred->pwlen, NULL, NULL);
258 }
259 }
260
261 phCredential->dwUpper = fCredentialUse;
262 phCredential->dwLower = (ULONG_PTR)ntlm_cred;
263 TRACE("ACH phCredential->dwUpper: 0x%08lx, dwLower: 0x%08lx\n",
264 phCredential->dwUpper, phCredential->dwLower);
265 ret = SEC_E_OK;
266 break;
267 }
268 case SECPKG_CRED_BOTH:
269 FIXME("AcquireCredentialsHandle: SECPKG_CRED_BOTH stub\n");
271 phCredential = NULL;
272 break;
273 default:
274 phCredential = NULL;
276 }
277
278 if (auth_data && auth_data->Flags & SEC_WINNT_AUTH_IDENTITY_ANSI)
279 {
283 }
284 return ret;
285}
#define CP_UNIXCP
Definition: compat.h:79
#define WideCharToMultiByte
Definition: compat.h:111
static char * ntlm_GetDomainArg(LPCWSTR domainW, INT domainW_length)
Definition: ntlm.c:106
static char * ntlm_GetUsernameArg(LPCWSTR userW, INT userW_length)
Definition: ntlm.c:88
#define WC_NO_BEST_FIT_CHARS
Definition: unicode.h:46
#define debugstr_wn
Definition: kernel32.h:33
#define debugstr_w
Definition: kernel32.h:32
static WCHAR password[]
Definition: url.c:33
@ NTLM_CLIENT
Definition: ntlm.h:12
#define SECPKG_CRED_BOTH
Definition: sspi.h:292
#define SECPKG_CRED_OUTBOUND
Definition: sspi.h:291
#define SECPKG_CRED_INBOUND
Definition: sspi.h:290
char * domain_arg
Definition: ntlm.h:62
char * username_arg
Definition: ntlm.h:61
char * password
Definition: ntlm.h:63
int no_cached_credentials
Definition: ntlm.h:65
unsigned short * Domain
Definition: rpcdce.h:225
unsigned short * User
Definition: rpcdce.h:223
unsigned short * Password
Definition: rpcdce.h:227
#define SEC_E_UNKNOWN_CREDENTIALS
Definition: winerror.h:2922
#define SEC_E_UNSUPPORTED_FUNCTION
Definition: winerror.h:2911
__wchar_t WCHAR
Definition: xmlstorage.h:180
WCHAR * LPWSTR
Definition: xmlstorage.h:184

Referenced by nego_AcquireCredentialsHandleW(), and ntlm_AcquireCredentialsHandleA().

◆ ntlm_CompleteAuthToken()

static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken ( PCtxtHandle  phContext,
PSecBufferDesc  pToken 
)
static

Definition at line 1384 of file ntlm.c.

1386{
1387 /* We never need to call CompleteAuthToken anyway */
1388 TRACE("%p %p\n", phContext, pToken);
1389 if (!phContext)
1390 return SEC_E_INVALID_HANDLE;
1391
1392 return SEC_E_OK;
1393}

◆ ntlm_CreateSignature()

static SECURITY_STATUS ntlm_CreateSignature ( PNegoHelper  helper,
PSecBufferDesc  pMessage,
int  token_idx,
SignDirection  direction,
BOOL  encrypt_sig 
)
static

Definition at line 1536 of file ntlm.c.

1538{
1539 ULONG sign_version = 1;
1540 UINT i;
1541 PBYTE sig;
1542 TRACE("%p, %p, %d, %d, %d\n", helper, pMessage, token_idx, direction,
1543 encrypt_sig);
1544
1545 sig = pMessage->pBuffers[token_idx].pvBuffer;
1546
1547 if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 &&
1549 {
1550 BYTE digest[16];
1551 BYTE seq_no[4];
1552 HMAC_MD5_CTX hmac_md5_ctx;
1553
1554 TRACE("Signing NTLM2 style\n");
1555
1556 if(direction == NTLM_SEND)
1557 {
1558 seq_no[0] = (helper->crypt.ntlm2.send_seq_no >> 0) & 0xff;
1559 seq_no[1] = (helper->crypt.ntlm2.send_seq_no >> 8) & 0xff;
1560 seq_no[2] = (helper->crypt.ntlm2.send_seq_no >> 16) & 0xff;
1561 seq_no[3] = (helper->crypt.ntlm2.send_seq_no >> 24) & 0xff;
1562
1563 ++(helper->crypt.ntlm2.send_seq_no);
1564
1565 HMACMD5Init(&hmac_md5_ctx, helper->crypt.ntlm2.send_sign_key, 16);
1566 }
1567 else
1568 {
1569 seq_no[0] = (helper->crypt.ntlm2.recv_seq_no >> 0) & 0xff;
1570 seq_no[1] = (helper->crypt.ntlm2.recv_seq_no >> 8) & 0xff;
1571 seq_no[2] = (helper->crypt.ntlm2.recv_seq_no >> 16) & 0xff;
1572 seq_no[3] = (helper->crypt.ntlm2.recv_seq_no >> 24) & 0xff;
1573
1574 ++(helper->crypt.ntlm2.recv_seq_no);
1575
1576 HMACMD5Init(&hmac_md5_ctx, helper->crypt.ntlm2.recv_sign_key, 16);
1577 }
1578
1579 HMACMD5Update(&hmac_md5_ctx, seq_no, 4);
1580 for( i = 0; i < pMessage->cBuffers; ++i )
1581 {
1582 if(pMessage->pBuffers[i].BufferType & SECBUFFER_DATA)
1583 HMACMD5Update(&hmac_md5_ctx, pMessage->pBuffers[i].pvBuffer,
1584 pMessage->pBuffers[i].cbBuffer);
1585 }
1586
1587 HMACMD5Final(&hmac_md5_ctx, digest);
1588
1589 if(encrypt_sig && helper->neg_flags & NTLMSSP_NEGOTIATE_KEY_EXCHANGE)
1590 {
1591 if(direction == NTLM_SEND)
1592 SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i, digest, 8);
1593 else
1594 SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i, digest, 8);
1595 }
1596
1597 /* The NTLM2 signature is the sign version */
1598 sig[ 0] = (sign_version >> 0) & 0xff;
1599 sig[ 1] = (sign_version >> 8) & 0xff;
1600 sig[ 2] = (sign_version >> 16) & 0xff;
1601 sig[ 3] = (sign_version >> 24) & 0xff;
1602 /* The first 8 bytes of the digest */
1603 memcpy(sig+4, digest, 8);
1604 /* And the sequence number */
1605 memcpy(sig+12, seq_no, 4);
1606
1607 pMessage->pBuffers[token_idx].cbBuffer = 16;
1608
1609 return SEC_E_OK;
1610 }
1611 if(helper->neg_flags & NTLMSSP_NEGOTIATE_SIGN)
1612 {
1613 ULONG crc = 0U;
1614 TRACE("Signing NTLM1 style\n");
1615
1616 for(i=0; i < pMessage->cBuffers; ++i)
1617 {
1618 if(pMessage->pBuffers[i].BufferType & SECBUFFER_DATA)
1619 {
1620 crc = ComputeCrc32(pMessage->pBuffers[i].pvBuffer,
1621 pMessage->pBuffers[i].cbBuffer, crc);
1622 }
1623 }
1624
1625 sig[ 0] = (sign_version >> 0) & 0xff;
1626 sig[ 1] = (sign_version >> 8) & 0xff;
1627 sig[ 2] = (sign_version >> 16) & 0xff;
1628 sig[ 3] = (sign_version >> 24) & 0xff;
1629 memset(sig+4, 0, 4);
1630 sig[ 8] = (crc >> 0) & 0xff;
1631 sig[ 9] = (crc >> 8) & 0xff;
1632 sig[10] = (crc >> 16) & 0xff;
1633 sig[11] = (crc >> 24) & 0xff;
1634 sig[12] = (helper->crypt.ntlm.seq_num >> 0) & 0xff;
1635 sig[13] = (helper->crypt.ntlm.seq_num >> 8) & 0xff;
1636 sig[14] = (helper->crypt.ntlm.seq_num >> 16) & 0xff;
1637 sig[15] = (helper->crypt.ntlm.seq_num >> 24) & 0xff;
1638
1639 ++(helper->crypt.ntlm.seq_num);
1640
1641 if(encrypt_sig)
1642 SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12);
1643 return SEC_E_OK;
1644 }
1645
1646 if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0)
1647 {
1648 TRACE("Creating a dummy signature.\n");
1649 /* A dummy signature is 0x01 followed by 15 bytes of 0x00 */
1650 memset(pMessage->pBuffers[token_idx].pvBuffer, 0, 16);
1651 memset(pMessage->pBuffers[token_idx].pvBuffer, 0x01, 1);
1652 pMessage->pBuffers[token_idx].cbBuffer = 16;
1653 return SEC_E_OK;
1654 }
1655
1657}
#define U(x)
Definition: wordpad.c:45
ULONG ComputeCrc32(const BYTE *pData, INT iLen, ULONG initial_crc)
Definition: util.c:109
void SECUR32_arc4Process(arc4_info *a4i, BYTE *inoutString, unsigned int length)
Definition: util.c:224
GLsizei GLenum const GLvoid GLsizei GLenum GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLint GLint GLint GLshort GLshort GLshort GLubyte GLubyte GLubyte GLuint GLuint GLuint GLushort GLushort GLushort GLbyte GLbyte GLbyte GLbyte GLdouble GLdouble GLdouble GLdouble GLfloat GLfloat GLfloat GLfloat GLint GLint GLint GLint GLshort GLshort GLshort GLshort GLubyte GLubyte GLubyte GLubyte GLuint GLuint GLuint GLuint GLushort GLushort GLushort GLushort GLboolean const GLdouble const GLfloat const GLint const GLshort const GLbyte const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLdouble const GLfloat const GLfloat const GLint const GLint const GLshort const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort const GLdouble const GLfloat const GLint const GLshort GLenum GLenum GLenum GLfloat GLenum GLint GLenum GLenum GLenum GLfloat GLenum GLenum GLint GLenum GLfloat GLenum GLint GLint GLushort GLenum GLenum GLfloat GLenum GLenum GLint GLfloat const GLubyte GLenum GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLint GLint GLsizei GLsizei GLint GLenum GLenum const GLvoid GLenum GLenum const GLfloat GLenum GLenum const GLint GLenum GLenum const GLdouble GLenum GLenum const GLfloat GLenum GLenum const GLint GLsizei GLuint GLfloat GLuint GLbitfield GLfloat GLint GLuint GLboolean GLenum GLfloat GLenum GLbitfield GLenum GLfloat GLfloat GLint GLint const GLfloat GLenum GLfloat GLfloat GLint GLint GLfloat GLfloat GLint GLint const GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat GLint GLfloat GLfloat const GLdouble const GLfloat const GLdouble const GLfloat GLint i
Definition: glfuncs.h:248
void HMACMD5Final(HMAC_MD5_CTX *ctx, unsigned char *digest)
Definition: hmac_md5.c:63
void HMACMD5Update(HMAC_MD5_CTX *ctx, const unsigned char *data, unsigned int data_len)
Definition: hmac_md5.c:58
void HMACMD5Init(HMAC_MD5_CTX *ctx, const unsigned char *key, unsigned int key_len)
Definition: hmac_md5.c:24
unsigned int UINT
Definition: ndis.h:50
#define NTLMSSP_NEGOTIATE_NTLM2
Definition: ntlm.h:91
#define NTLMSSP_NEGOTIATE_SIGN
Definition: ntlm.h:80
#define NTLMSSP_NEGOTIATE_KEY_EXCHANGE
Definition: ntlm.h:94
@ NTLM_SEND
Definition: ntlm.h:69
#define NTLMSSP_NEGOTIATE_ALWAYS_SIGN
Definition: ntlm.h:88

Referenced by ntlm_EncryptMessage(), ntlm_MakeSignature(), and ntlm_VerifySignature().

◆ ntlm_DecryptMessage()

SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage ( PCtxtHandle  phContext,
PSecBufferDesc  pMessage,
ULONG  MessageSeqNo,
PULONG  pfQOP 
)

Definition at line 1863 of file ntlm.c.

1865{
1867 ULONG ntlmssp_flags_save;
1868 PNegoHelper helper;
1869 int token_idx, data_idx;
1870 TRACE("(%p %p %d %p)\n", phContext, pMessage, MessageSeqNo, pfQOP);
1871
1872 if(!phContext)
1873 return SEC_E_INVALID_HANDLE;
1874
1875 if(MessageSeqNo)
1876 FIXME("Ignoring MessageSeqNo\n");
1877
1878 if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
1879 return SEC_E_INVALID_TOKEN;
1880
1881 if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
1882 return SEC_E_INVALID_TOKEN;
1883
1884 if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1)
1885 return SEC_E_INVALID_TOKEN;
1886
1887 if(pMessage->pBuffers[token_idx].cbBuffer < 16)
1889
1890 helper = (PNegoHelper) phContext->dwLower;
1891
1893 {
1894 SECUR32_arc4Process(helper->crypt.ntlm2.recv_a4i,
1895 pMessage->pBuffers[data_idx].pvBuffer,
1896 pMessage->pBuffers[data_idx].cbBuffer);
1897 }
1898 else
1899 {
1900 SECUR32_arc4Process(helper->crypt.ntlm.a4i,
1901 pMessage->pBuffers[data_idx].pvBuffer,
1902 pMessage->pBuffers[data_idx].cbBuffer);
1903 }
1904
1905 /* Make sure we use a session key for the signature check, EncryptMessage
1906 * always does that, even in the dummy case */
1907 ntlmssp_flags_save = helper->neg_flags;
1908
1910 ret = ntlm_VerifySignature(phContext, pMessage, MessageSeqNo, pfQOP);
1911
1912 helper->neg_flags = ntlmssp_flags_save;
1913
1914 return ret;
1915}
SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: ntlm.c:1697
static int ntlm_GetTokenBufferIndex(PSecBufferDesc pMessage)
Definition: ntlm.c:403
static int ntlm_GetDataBufferIndex(PSecBufferDesc pMessage)
Definition: ntlm.c:423
#define NTLMSSP_NEGOTIATE_SEAL
Definition: ntlm.h:81
#define SEC_E_BUFFER_TOO_SMALL
Definition: winerror.h:2937

Referenced by nego_DecryptMessage().

◆ ntlm_DeleteSecurityContext()

SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext ( PCtxtHandle  phContext)

Definition at line 1398 of file ntlm.c.

1399{
1400 PNegoHelper helper;
1401
1402 TRACE("%p\n", phContext);
1403 if (!phContext)
1404 return SEC_E_INVALID_HANDLE;
1405
1406 helper = (PNegoHelper)phContext->dwLower;
1407
1408 phContext->dwUpper = 0;
1409 phContext->dwLower = 0;
1410
1411 SECUR32_arc4Cleanup(helper->crypt.ntlm.a4i);
1412 SECUR32_arc4Cleanup(helper->crypt.ntlm2.send_a4i);
1413 SECUR32_arc4Cleanup(helper->crypt.ntlm2.recv_a4i);
1414 HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.send_sign_key);
1415 HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.send_seal_key);
1416 HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.recv_sign_key);
1417 HeapFree(GetProcessHeap(), 0, helper->crypt.ntlm2.recv_seal_key);
1418
1419 cleanup_helper(helper);
1420
1421 return SEC_E_OK;
1422}
void SECUR32_arc4Cleanup(arc4_info *a4i)
Definition: util.c:246

Referenced by nego_DeleteSecurityContext().

◆ ntlm_EncryptMessage()

SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage ( PCtxtHandle  phContext,
ULONG  fQOP,
PSecBufferDesc  pMessage,
ULONG  MessageSeqNo 
)

Definition at line 1792 of file ntlm.c.

1794{
1795 PNegoHelper helper;
1796 int token_idx, data_idx;
1797
1798 TRACE("(%p %d %p %d)\n", phContext, fQOP, pMessage, MessageSeqNo);
1799
1800 if(!phContext)
1801 return SEC_E_INVALID_HANDLE;
1802
1803 if(fQOP)
1804 FIXME("Ignoring fQOP\n");
1805
1806 if(MessageSeqNo)
1807 FIXME("Ignoring MessageSeqNo\n");
1808
1809 if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
1810 return SEC_E_INVALID_TOKEN;
1811
1812 if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
1813 return SEC_E_INVALID_TOKEN;
1814
1815 if((data_idx = ntlm_GetDataBufferIndex(pMessage)) ==-1 )
1816 return SEC_E_INVALID_TOKEN;
1817
1818 if(pMessage->pBuffers[token_idx].cbBuffer < 16)
1820
1821 helper = (PNegoHelper) phContext->dwLower;
1822
1823 if(helper->neg_flags & NTLMSSP_NEGOTIATE_NTLM2 &&
1825 {
1826 ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE);
1827 SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i,
1828 pMessage->pBuffers[data_idx].pvBuffer,
1829 pMessage->pBuffers[data_idx].cbBuffer);
1830
1832 SECUR32_arc4Process(helper->crypt.ntlm2.send_a4i,
1833 ((BYTE *)pMessage->pBuffers[token_idx].pvBuffer)+4, 8);
1834 }
1835 else
1836 {
1837 PBYTE sig;
1838 ULONG save_flags;
1839
1840 /* EncryptMessage always produces real signatures, so make sure
1841 * NTLMSSP_NEGOTIATE_SIGN is set*/
1842 save_flags = helper->neg_flags;
1844 ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, FALSE);
1845 helper->neg_flags = save_flags;
1846
1847 sig = pMessage->pBuffers[token_idx].pvBuffer;
1848
1849 SECUR32_arc4Process(helper->crypt.ntlm.a4i,
1850 pMessage->pBuffers[data_idx].pvBuffer,
1851 pMessage->pBuffers[data_idx].cbBuffer);
1852 SECUR32_arc4Process(helper->crypt.ntlm.a4i, sig+4, 12);
1853
1854 if(helper->neg_flags & NTLMSSP_NEGOTIATE_ALWAYS_SIGN || helper->neg_flags == 0)
1855 memset(sig+4, 0, 4);
1856 }
1857 return SEC_E_OK;
1858}
#define FALSE
Definition: types.h:117
static SECURITY_STATUS ntlm_CreateSignature(PNegoHelper helper, PSecBufferDesc pMessage, int token_idx, SignDirection direction, BOOL encrypt_sig)
Definition: ntlm.c:1536

Referenced by nego_EncryptMessage().

◆ ntlm_FreeCredentialsHandle()

SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle ( PCredHandle  phCredential)

Definition at line 1767 of file ntlm.c.

1768{
1770
1771 if(phCredential){
1772 PNtlmCredentials ntlm_cred = (PNtlmCredentials) phCredential->dwLower;
1773 phCredential->dwUpper = 0;
1774 phCredential->dwLower = 0;
1775 if (ntlm_cred->password)
1776 memset(ntlm_cred->password, 0, ntlm_cred->pwlen);
1777 HeapFree(GetProcessHeap(), 0, ntlm_cred->password);
1778 HeapFree(GetProcessHeap(), 0, ntlm_cred->username_arg);
1779 HeapFree(GetProcessHeap(), 0, ntlm_cred->domain_arg);
1780 HeapFree(GetProcessHeap(), 0, ntlm_cred);
1781 ret = SEC_E_OK;
1782 }
1783 else
1784 ret = SEC_E_OK;
1785
1786 return ret;
1787}
if(dx< 0)
Definition: linetemp.h:194

Referenced by nego_FreeCredentialsHandle().

◆ ntlm_GetCachedCredential()

static BOOL ntlm_GetCachedCredential ( const SEC_WCHAR pszTargetName,
PCREDENTIALW cred 
)
static

Definition at line 438 of file ntlm.c.

439{
440 LPCWSTR p;
441 LPCWSTR pszHost;
442 LPWSTR pszHostOnly;
443 BOOL ret;
444
445 if (!pszTargetName)
446 return FALSE;
447
448 /* try to get the start of the hostname from service principal name (SPN) */
449 pszHost = strchrW(pszTargetName, '/');
450 if (pszHost)
451 {
452 /* skip slash character */
453 pszHost++;
454
455 /* find end of host by detecting start of instance port or start of referrer */
456 p = strchrW(pszHost, ':');
457 if (!p)
458 p = strchrW(pszHost, '/');
459 if (!p)
460 p = pszHost + strlenW(pszHost);
461 }
462 else /* otherwise not an SPN, just a host */
463 {
464 pszHost = pszTargetName;
465 p = pszHost + strlenW(pszHost);
466 }
467
468 pszHostOnly = HeapAlloc(GetProcessHeap(), 0, (p - pszHost + 1) * sizeof(WCHAR));
469 if (!pszHostOnly)
470 return FALSE;
471
472 memcpy(pszHostOnly, pszHost, (p - pszHost) * sizeof(WCHAR));
473 pszHostOnly[p - pszHost] = '\0';
474
475 ret = CredReadW(pszHostOnly, CRED_TYPE_DOMAIN_PASSWORD, 0, cred);
476
477 HeapFree(GetProcessHeap(), 0, pszHostOnly);
478 return ret;
479}
BOOL WINAPI CredReadW(LPCWSTR TargetName, DWORD Type, DWORD Flags, PCREDENTIALW *Credential)
Definition: cred.c:1450
unsigned int BOOL
Definition: ntddk_ex.h:94
GLfloat GLfloat p
Definition: glext.h:8902
#define strchrW(s, c)
Definition: unicode.h:40
#define strlenW(s)
Definition: unicode.h:34
#define CRED_TYPE_DOMAIN_PASSWORD
Definition: wincred.h:205
const WCHAR * LPCWSTR
Definition: xmlstorage.h:185

Referenced by ntlm_InitializeSecurityContextW().

◆ ntlm_GetDataBufferIndex()

static int ntlm_GetDataBufferIndex ( PSecBufferDesc  pMessage)
static

Definition at line 423 of file ntlm.c.

424{
425 UINT i;
426
427 TRACE("%p\n", pMessage);
428
429 for( i = 0; i < pMessage->cBuffers; ++i )
430 {
431 if(pMessage->pBuffers[i].BufferType == SECBUFFER_DATA)
432 return i;
433 }
434
435 return -1;
436}

Referenced by ntlm_DecryptMessage(), and ntlm_EncryptMessage().

◆ ntlm_GetDomainArg()

static char * ntlm_GetDomainArg ( LPCWSTR  domainW,
INT  domainW_length 
)
static

Definition at line 106 of file ntlm.c.

107{
108 static const char domain_arg[] = "--domain=";
109 char *domain;
110 int unixcp_size;
111
113 domainW, domainW_length, NULL, 0, NULL, NULL) + sizeof(domain_arg);
114 domain = HeapAlloc(GetProcessHeap(), 0, unixcp_size);
115 if (!domain) return NULL;
116 memcpy(domain, domain_arg, sizeof(domain_arg) - 1);
118 domainW_length, domain + sizeof(domain_arg) - 1,
119 unixcp_size - sizeof(domain) + 1, NULL, NULL);
120 domain[unixcp_size - 1] = '\0';
121 return domain;
122}

Referenced by ntlm_AcquireCredentialsHandleW(), and ntlm_InitializeSecurityContextW().

◆ ntlm_GetTokenBufferIndex()

static int ntlm_GetTokenBufferIndex ( PSecBufferDesc  pMessage)
static

Definition at line 403 of file ntlm.c.

404{
405 UINT i;
406
407 TRACE("%p\n", pMessage);
408
409 for( i = 0; i < pMessage->cBuffers; ++i )
410 {
411 if(pMessage->pBuffers[i].BufferType == SECBUFFER_TOKEN)
412 return i;
413 }
414
415 return -1;
416}
#define SECBUFFER_TOKEN
Definition: sspi.h:161

Referenced by ntlm_DecryptMessage(), ntlm_EncryptMessage(), ntlm_InitializeSecurityContextW(), ntlm_MakeSignature(), and ntlm_VerifySignature().

◆ ntlm_GetUsernameArg()

static char * ntlm_GetUsernameArg ( LPCWSTR  userW,
INT  userW_length 
)
static

Definition at line 88 of file ntlm.c.

89{
90 static const char username_arg[] = "--username=";
91 char *user;
92 int unixcp_size;
93
95 userW, userW_length, NULL, 0, NULL, NULL) + sizeof(username_arg);
96 user = HeapAlloc(GetProcessHeap(), 0, unixcp_size);
97 if (!user) return NULL;
98 memcpy(user, username_arg, sizeof(username_arg) - 1);
100 user + sizeof(username_arg) - 1,
101 unixcp_size - sizeof(username_arg) + 1, NULL, NULL);
102 user[unixcp_size - 1] = '\0';
103 return user;
104}

Referenced by ntlm_AcquireCredentialsHandleW(), and ntlm_InitializeSecurityContextW().

◆ ntlm_ImpersonateSecurityContext()

static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext ( PCtxtHandle  phContext)
static

Definition at line 1491 of file ntlm.c.

1492{
1494
1495 TRACE("%p\n", phContext);
1496 if (phContext)
1497 {
1499 }
1500 else
1501 {
1503 }
1504 return ret;
1505}

◆ ntlm_InitializeSecurityContextA()

static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA ( PCredHandle  phCredential,
PCtxtHandle  phContext,
SEC_CHAR pszTargetName,
ULONG  fContextReq,
ULONG  Reserved1,
ULONG  TargetDataRep,
PSecBufferDesc  pInput,
ULONG  Reserved2,
PCtxtHandle  phNewContext,
PSecBufferDesc  pOutput,
ULONG pfContextAttr,
PTimeStamp  ptsExpiry 
)
static

Definition at line 995 of file ntlm.c.

1000{
1003
1004 TRACE("%p %p %s %d %d %d %p %d %p %p %p %p\n", phCredential, phContext,
1005 debugstr_a(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
1006 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
1007
1008 if(pszTargetName != NULL)
1009 {
1010 int target_size = MultiByteToWideChar(CP_ACP, 0, pszTargetName,
1011 strlen(pszTargetName)+1, NULL, 0);
1012 target = HeapAlloc(GetProcessHeap(), 0, target_size *
1013 sizeof(SEC_WCHAR));
1014 MultiByteToWideChar(CP_ACP, 0, pszTargetName, strlen(pszTargetName)+1,
1015 target, target_size);
1016 }
1017
1018 ret = ntlm_InitializeSecurityContextW(phCredential, phContext, target,
1019 fContextReq, Reserved1, TargetDataRep, pInput, Reserved2,
1020 phNewContext, pOutput, pfContextAttr, ptsExpiry);
1021
1023 return ret;
1024}
@ Reserved2
Definition: bcd.h:202
@ Reserved1
Definition: bcd.h:201
SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(PCredHandle phCredential, PCtxtHandle phContext, SEC_WCHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: ntlm.c:484
GLenum target
Definition: glext.h:7315

◆ ntlm_InitializeSecurityContextW()

SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW ( PCredHandle  phCredential,
PCtxtHandle  phContext,
SEC_WCHAR pszTargetName,
ULONG  fContextReq,
ULONG  Reserved1,
ULONG  TargetDataRep,
PSecBufferDesc  pInput,
ULONG  Reserved2,
PCtxtHandle  phNewContext,
PSecBufferDesc  pOutput,
ULONG pfContextAttr,
PTimeStamp  ptsExpiry 
)

Definition at line 484 of file ntlm.c.

489{
491 PNtlmCredentials ntlm_cred;
492 PNegoHelper helper = NULL;
493 ULONG ctxt_attr = 0;
494 char* buffer, *want_flags = NULL;
495 PBYTE bin;
496 int buffer_len, bin_len, max_len = NTLM_MAX_BUF;
497 int token_idx;
501
502 TRACE("%p %p %s 0x%08x %d %d %p %d %p %p %p %p\n", phCredential, phContext,
503 debugstr_w(pszTargetName), fContextReq, Reserved1, TargetDataRep, pInput,
504 Reserved1, phNewContext, pOutput, pfContextAttr, ptsExpiry);
505
506 /****************************************
507 * When communicating with the client, there can be the
508 * following reply packets:
509 * YR <base64 blob> should be sent to the server
510 * PW should be sent back to helper with
511 * base64 encoded password
512 * AF <base64 blob> client is done, blob should be
513 * sent to server with KK prefixed
514 * GF <string list> A string list of negotiated flags
515 * GK <base64 blob> base64 encoded session key
516 * BH <char reason> something broke
517 */
518 /* The squid cache size is 2010 chars, and that's what ntlm_auth uses */
519
520 if(TargetDataRep == SECURITY_NETWORK_DREP){
521 TRACE("Setting SECURITY_NETWORK_DREP\n");
522 }
523
524 buffer = HeapAlloc(GetProcessHeap(), 0, sizeof(char) * NTLM_MAX_BUF);
525 bin = HeapAlloc(GetProcessHeap(), 0, sizeof(BYTE) * NTLM_MAX_BUF);
526
527 if((phContext == NULL) && (pInput == NULL))
528 {
529 static char helper_protocol[] = "--helper-protocol=ntlmssp-client-1";
530 static CHAR credentials_argv[] = "--use-cached-creds";
531 SEC_CHAR *client_argv[5];
532 int pwlen = 0;
533
534 TRACE("First time in ISC()\n");
535
536 if(!phCredential)
537 {
539 goto isc_end;
540 }
541
542 /* As the server side of sspi never calls this, make sure that
543 * the handler is a client handler.
544 */
545 ntlm_cred = (PNtlmCredentials)phCredential->dwLower;
546 if(ntlm_cred->mode != NTLM_CLIENT)
547 {
548 TRACE("Cred mode = %d\n", ntlm_cred->mode);
550 goto isc_end;
551 }
552
553 client_argv[0] = ntlm_auth;
554 client_argv[1] = helper_protocol;
555 if (!ntlm_cred->username_arg && !ntlm_cred->domain_arg)
556 {
559 PCREDENTIALW cred;
560
561 if (ntlm_GetCachedCredential(pszTargetName, &cred))
562 {
563 LPWSTR p;
564 p = strchrW(cred->UserName, '\\');
565 if (p)
566 {
567 domain = ntlm_GetDomainArg(cred->UserName, p - cred->UserName);
568 p++;
569 }
570 else
571 {
573 p = cred->UserName;
574 }
575
577
578 if(cred->CredentialBlobSize != 0)
579 {
582 cred->CredentialBlobSize / sizeof(WCHAR), NULL, 0,
583 NULL, NULL);
584
585 password = HeapAlloc(GetProcessHeap(), 0, pwlen);
586
588 (LPWSTR)cred->CredentialBlob,
589 cred->CredentialBlobSize / sizeof(WCHAR),
590 password, pwlen, NULL, NULL);
591 }
592
593 CredFree(cred);
594
595 client_argv[2] = username;
596 client_argv[3] = domain;
597 client_argv[4] = NULL;
598 }
599 else
600 {
602 if (status != NERR_Success || ui == NULL || ntlm_cred->no_cached_credentials)
603 {
605 goto isc_end;
606 }
607 username = ntlm_GetUsernameArg(ui->wkui1_username, -1);
609
610 TRACE("using cached credentials\n");
611
612 client_argv[2] = username;
613 client_argv[3] = credentials_argv;
614 client_argv[4] = NULL;
615 }
616 }
617 else
618 {
619 client_argv[2] = ntlm_cred->username_arg;
620 client_argv[3] = ntlm_cred->domain_arg;
621 client_argv[4] = NULL;
622 }
623
624 if((ret = fork_helper(&helper, ntlm_auth, client_argv)) != SEC_E_OK)
625 goto isc_end;
626
627 helper->mode = NTLM_CLIENT;
628 helper->session_key = HeapAlloc(GetProcessHeap(), 0, 16);
629 if (!helper->session_key)
630 {
631 cleanup_helper(helper);
633 goto isc_end;
634 }
635
636 /* Generate the dummy session key = MD4(MD4(password))*/
637 if(password || ntlm_cred->password)
638 {
639 SEC_WCHAR *unicode_password;
640 int passwd_lenW;
641
642 TRACE("Converting password to unicode.\n");
643 passwd_lenW = MultiByteToWideChar(CP_ACP, 0,
644 password ? password : ntlm_cred->password,
645 password ? pwlen : ntlm_cred->pwlen,
646 NULL, 0);
647 unicode_password = HeapAlloc(GetProcessHeap(), 0,
648 passwd_lenW * sizeof(SEC_WCHAR));
650 password ? pwlen : ntlm_cred->pwlen, unicode_password, passwd_lenW);
651
652 SECUR32_CreateNTLM1SessionKey((PBYTE)unicode_password,
653 passwd_lenW * sizeof(SEC_WCHAR), helper->session_key);
654
655 HeapFree(GetProcessHeap(), 0, unicode_password);
656 }
657 else
658 memset(helper->session_key, 0, 16);
659
660 /* Allocate space for a maximal string of
661 * "SF NTLMSSP_FEATURE_SIGN NTLMSSP_FEATURE_SEAL
662 * NTLMSSP_FEATURE_SESSION_KEY"
663 */
664 want_flags = HeapAlloc(GetProcessHeap(), 0, 73);
665 if(want_flags == NULL)
666 {
667 cleanup_helper(helper);
669 goto isc_end;
670 }
671 lstrcpyA(want_flags, "SF");
672 if(fContextReq & ISC_REQ_CONFIDENTIALITY)
673 {
674 if(strstr(want_flags, "NTLMSSP_FEATURE_SEAL") == NULL)
675 lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
676 }
677 if(fContextReq & ISC_REQ_CONNECTION)
678 ctxt_attr |= ISC_RET_CONNECTION;
679 if(fContextReq & ISC_REQ_EXTENDED_ERROR)
680 ctxt_attr |= ISC_RET_EXTENDED_ERROR;
681 if(fContextReq & ISC_REQ_INTEGRITY)
682 {
683 if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
684 lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
685 }
686 if(fContextReq & ISC_REQ_MUTUAL_AUTH)
687 ctxt_attr |= ISC_RET_MUTUAL_AUTH;
688 if(fContextReq & ISC_REQ_REPLAY_DETECT)
689 {
690 if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
691 lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
692 }
693 if(fContextReq & ISC_REQ_SEQUENCE_DETECT)
694 {
695 if(strstr(want_flags, "NTLMSSP_FEATURE_SIGN") == NULL)
696 lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
697 }
698 if(fContextReq & ISC_REQ_STREAM)
699 FIXME("ISC_REQ_STREAM\n");
700 if(fContextReq & ISC_REQ_USE_DCE_STYLE)
701 ctxt_attr |= ISC_RET_USED_DCE_STYLE;
702 if(fContextReq & ISC_REQ_DELEGATE)
703 ctxt_attr |= ISC_RET_DELEGATE;
704
705 /* If no password is given, try to use cached credentials. Fall back to an empty
706 * password if this failed. */
707 if(!password && !ntlm_cred->password)
708 {
709 lstrcpynA(buffer, "OK", max_len-1);
710 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
711 {
712 cleanup_helper(helper);
713 goto isc_end;
714 }
715 /* If the helper replied with "PW", using cached credentials failed */
716 if(!strncmp(buffer, "PW", 2))
717 {
718 TRACE("Using cached credentials failed.\n");
719 lstrcpynA(buffer, "PW AA==", max_len-1);
720 }
721 else /* Just do a noop on the next run */
722 lstrcpynA(buffer, "OK", max_len-1);
723 }
724 else
725 {
726 lstrcpynA(buffer, "PW ", max_len-1);
727 if((ret = encodeBase64(password ? (unsigned char *)password : (unsigned char *)ntlm_cred->password,
728 password ? pwlen : ntlm_cred->pwlen, buffer+3,
729 max_len-3, &buffer_len)) != SEC_E_OK)
730 {
731 cleanup_helper(helper);
732 goto isc_end;
733 }
734
735 }
736
737 TRACE("Sending to helper: %s\n", debugstr_a(buffer));
738 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
739 {
740 cleanup_helper(helper);
741 goto isc_end;
742 }
743
744 TRACE("Helper returned %s\n", debugstr_a(buffer));
745
746 if(lstrlenA(want_flags) > 2)
747 {
748 TRACE("Want flags are %s\n", debugstr_a(want_flags));
749 lstrcpynA(buffer, want_flags, max_len-1);
750 if((ret = run_helper(helper, buffer, max_len, &buffer_len))
751 != SEC_E_OK)
752 {
753 cleanup_helper(helper);
754 goto isc_end;
755 }
756 if(!strncmp(buffer, "BH", 2))
757 ERR("Helper doesn't understand new command set. Expect more things to fail.\n");
758 }
759
760 lstrcpynA(buffer, "YR", max_len-1);
761
762 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
763 {
764 cleanup_helper(helper);
765 goto isc_end;
766 }
767
768 TRACE("%s\n", buffer);
769
770 if(strncmp(buffer, "YR ", 3) != 0)
771 {
772 /* Something borked */
773 TRACE("Helper returned %c%c\n", buffer[0], buffer[1]);
775 cleanup_helper(helper);
776 goto isc_end;
777 }
778 if((ret = decodeBase64(buffer+3, buffer_len-3, bin,
779 max_len-1, &bin_len)) != SEC_E_OK)
780 {
781 cleanup_helper(helper);
782 goto isc_end;
783 }
784
785 /* put the decoded client blob into the out buffer */
786
787 phNewContext->dwUpper = ctxt_attr;
788 phNewContext->dwLower = (ULONG_PTR)helper;
789
791 }
792 else
793 {
794 int input_token_idx;
795
796 /* handle second call here */
797 /* encode server data to base64 */
798 if (!pInput || ((input_token_idx = ntlm_GetTokenBufferIndex(pInput)) == -1))
799 {
801 goto isc_end;
802 }
803
804 if(!phContext)
805 {
807 goto isc_end;
808 }
809
810 /* As the server side of sspi never calls this, make sure that
811 * the handler is a client handler.
812 */
813 helper = (PNegoHelper)phContext->dwLower;
814 if(helper->mode != NTLM_CLIENT)
815 {
816 TRACE("Helper mode = %d\n", helper->mode);
818 goto isc_end;
819 }
820
821 if (!pInput->pBuffers[input_token_idx].pvBuffer)
822 {
824 goto isc_end;
825 }
826
827 if(pInput->pBuffers[input_token_idx].cbBuffer > max_len)
828 {
829 TRACE("pInput->pBuffers[%d].cbBuffer is: %d\n",
830 input_token_idx,
831 pInput->pBuffers[input_token_idx].cbBuffer);
833 goto isc_end;
834 }
835 else
836 bin_len = pInput->pBuffers[input_token_idx].cbBuffer;
837
838 memcpy(bin, pInput->pBuffers[input_token_idx].pvBuffer, bin_len);
839
840 lstrcpynA(buffer, "TT ", max_len-1);
841
842 if((ret = encodeBase64(bin, bin_len, buffer+3,
843 max_len-3, &buffer_len)) != SEC_E_OK)
844 goto isc_end;
845
846 TRACE("Server sent: %s\n", debugstr_a(buffer));
847
848 /* send TT base64 blob to ntlm_auth */
849 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
850 goto isc_end;
851
852 TRACE("Helper replied: %s\n", debugstr_a(buffer));
853
854 if( (strncmp(buffer, "KK ", 3) != 0) &&
855 (strncmp(buffer, "AF ", 3) !=0))
856 {
857 TRACE("Helper returned %c%c\n", buffer[0], buffer[1]);
859 goto isc_end;
860 }
861
862 /* decode the blob and send it to server */
863 if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
864 &bin_len)) != SEC_E_OK)
865 {
866 goto isc_end;
867 }
868
869 phNewContext->dwUpper = ctxt_attr;
870 phNewContext->dwLower = (ULONG_PTR)helper;
871
872 ret = SEC_E_OK;
873 }
874
875 /* put the decoded client blob into the out buffer */
876
877 if (!pOutput || ((token_idx = ntlm_GetTokenBufferIndex(pOutput)) == -1))
878 {
879 TRACE("no SECBUFFER_TOKEN buffer could be found\n");
881 if ((phContext == NULL) && (pInput == NULL))
882 {
883 cleanup_helper(helper);
884 phNewContext->dwUpper = 0;
885 phNewContext->dwLower = 0;
886 }
887 goto isc_end;
888 }
889
890 if (fContextReq & ISC_REQ_ALLOCATE_MEMORY)
891 {
892 pOutput->pBuffers[token_idx].pvBuffer = HeapAlloc(GetProcessHeap(), 0, bin_len);
893 pOutput->pBuffers[token_idx].cbBuffer = bin_len;
894 }
895 else if (pOutput->pBuffers[token_idx].cbBuffer < bin_len)
896 {
897 TRACE("out buffer is NULL or has not enough space\n");
899 if ((phContext == NULL) && (pInput == NULL))
900 {
901 cleanup_helper(helper);
902 phNewContext->dwUpper = 0;
903 phNewContext->dwLower = 0;
904 }
905 goto isc_end;
906 }
907
908 if (!pOutput->pBuffers[token_idx].pvBuffer)
909 {
910 TRACE("out buffer is NULL\n");
912 if ((phContext == NULL) && (pInput == NULL))
913 {
914 cleanup_helper(helper);
915 phNewContext->dwUpper = 0;
916 phNewContext->dwLower = 0;
917 }
918 goto isc_end;
919 }
920
921 pOutput->pBuffers[token_idx].cbBuffer = bin_len;
922 memcpy(pOutput->pBuffers[token_idx].pvBuffer, bin, bin_len);
923
924 if(ret == SEC_E_OK)
925 {
926 TRACE("Getting negotiated flags\n");
927 lstrcpynA(buffer, "GF", max_len - 1);
928 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
929 goto isc_end;
930
931 if(buffer_len < 3)
932 {
933 TRACE("No flags negotiated.\n");
934 helper->neg_flags = 0l;
935 }
936 else
937 {
938 TRACE("Negotiated %s\n", debugstr_a(buffer));
939 sscanf(buffer + 3, "%lx", &(helper->neg_flags));
940 TRACE("Stored 0x%08x as flags\n", helper->neg_flags);
941 }
942
943 TRACE("Getting session key\n");
944 lstrcpynA(buffer, "GK", max_len - 1);
945 if((ret = run_helper(helper, buffer, max_len, &buffer_len)) != SEC_E_OK)
946 goto isc_end;
947
948 if(strncmp(buffer, "BH", 2) == 0)
949 TRACE("No key negotiated.\n");
950 else if(strncmp(buffer, "GK ", 3) == 0)
951 {
952 if((ret = decodeBase64(buffer+3, buffer_len-3, bin, max_len,
953 &bin_len)) != SEC_E_OK)
954 {
955 TRACE("Failed to decode session key\n");
956 }
957 TRACE("Session key is %s\n", debugstr_a(buffer+3));
958 HeapFree(GetProcessHeap(), 0, helper->session_key);
959 helper->session_key = HeapAlloc(GetProcessHeap(), 0, bin_len);
960 if(!helper->session_key)
961 {
963 goto isc_end;
964 }
965 memcpy(helper->session_key, bin, bin_len);
966 }
967
968 helper->crypt.ntlm.a4i = SECUR32_arc4Alloc();
969 SECUR32_arc4Init(helper->crypt.ntlm.a4i, helper->session_key, 16);
970 helper->crypt.ntlm.seq_num = 0l;
972 helper->crypt.ntlm2.send_a4i = SECUR32_arc4Alloc();
973 helper->crypt.ntlm2.recv_a4i = SECUR32_arc4Alloc();
974 SECUR32_arc4Init(helper->crypt.ntlm2.send_a4i,
975 helper->crypt.ntlm2.send_seal_key, 16);
976 SECUR32_arc4Init(helper->crypt.ntlm2.recv_a4i,
977 helper->crypt.ntlm2.recv_seal_key, 16);
978 helper->crypt.ntlm2.send_seq_no = 0l;
979 helper->crypt.ntlm2.recv_seq_no = 0l;
980 }
981
982isc_end:
986 HeapFree(GetProcessHeap(), 0, want_flags);
989 return ret;
990}
char * strstr(char *String1, char *String2)
Definition: utclib.c:653
#define ERR(fmt,...)
Definition: debug.h:113
VOID WINAPI CredFree(PVOID Buffer)
Definition: cred.c:1395
NET_API_STATUS WINAPI NetApiBufferFree(LPVOID Buffer)
Definition: apibuf.c:43
NET_API_STATUS WINAPI NetWkstaUserGetInfo(LMSTR reserved, DWORD level, PBYTE *bufptr)
Definition: wksta.c:279
static BOOL ntlm_GetCachedCredential(const SEC_WCHAR *pszTargetName, PCREDENTIALW *cred)
Definition: ntlm.c:438
#define NERR_Success
Definition: lmerr.h:5
static WCHAR username[]
Definition: url.c:32
DWORD NET_API_STATUS
Definition: ms-dtyp.idl:91
SECURITY_STATUS SECUR32_CreateNTLM2SubKeys(PNegoHelper helper) DECLSPEC_HIDDEN
Definition: util.c:156
SECURITY_STATUS SECUR32_CreateNTLM1SessionKey(PBYTE password, int len, PBYTE session_key) DECLSPEC_HIDDEN
Definition: util.c:122
UINT ui
Definition: oleauto.h:49
#define ISC_RET_DELEGATE
Definition: sspi.h:385
#define ISC_REQ_CONFIDENTIALITY
Definition: sspi.h:366
#define ISC_RET_EXTENDED_ERROR
Definition: sspi.h:399
#define ISC_REQ_ALLOCATE_MEMORY
Definition: sspi.h:370
#define ISC_REQ_EXTENDED_ERROR
Definition: sspi.h:376
#define ISC_RET_USED_DCE_STYLE
Definition: sspi.h:394
#define ISC_REQ_REPLAY_DETECT
Definition: sspi.h:364
#define ISC_REQ_INTEGRITY
Definition: sspi.h:378
#define ISC_REQ_DELEGATE
Definition: sspi.h:362
#define ISC_REQ_MUTUAL_AUTH
Definition: sspi.h:363
#define ISC_RET_MUTUAL_AUTH
Definition: sspi.h:386
#define ISC_REQ_CONNECTION
Definition: sspi.h:373
#define ISC_RET_CONNECTION
Definition: sspi.h:396
#define ISC_REQ_USE_DCE_STYLE
Definition: sspi.h:371
LPBYTE CredentialBlob
Definition: wincred.h:90
LPWSTR UserName
Definition: wincred.h:95
DWORD CredentialBlobSize
Definition: wincred.h:89
Definition: ps.c:97
unsigned char * LPBYTE
Definition: typedefs.h:53
#define SEC_E_NO_CREDENTIALS
Definition: winerror.h:2923

Referenced by nego_InitializeSecurityContextW(), and ntlm_InitializeSecurityContextA().

◆ ntlm_MakeSignature()

SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature ( PCtxtHandle  phContext,
ULONG  fQOP,
PSecBufferDesc  pMessage,
ULONG  MessageSeqNo 
)

Definition at line 1662 of file ntlm.c.

1664{
1665 PNegoHelper helper;
1666 int token_idx;
1667
1668 TRACE("%p %d %p %d\n", phContext, fQOP, pMessage, MessageSeqNo);
1669 if (!phContext)
1670 return SEC_E_INVALID_HANDLE;
1671
1672 if(fQOP)
1673 FIXME("Ignoring fQOP 0x%08x\n", fQOP);
1674
1675 if(MessageSeqNo)
1676 FIXME("Ignoring MessageSeqNo\n");
1677
1678 if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
1679 return SEC_E_INVALID_TOKEN;
1680
1681 /* If we didn't find a SECBUFFER_TOKEN type buffer */
1682 if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
1683 return SEC_E_INVALID_TOKEN;
1684
1685 if(pMessage->pBuffers[token_idx].cbBuffer < 16)
1687
1688 helper = (PNegoHelper)phContext->dwLower;
1689 TRACE("Negotiated flags are: 0x%08x\n", helper->neg_flags);
1690
1691 return ntlm_CreateSignature(helper, pMessage, token_idx, NTLM_SEND, TRUE);
1692}
#define TRUE
Definition: types.h:120

Referenced by nego_MakeSignature().

◆ ntlm_QueryContextAttributesA()

SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA ( PCtxtHandle  phContext,
ULONG  ulAttribute,
void pBuffer 
)

Definition at line 1482 of file ntlm.c.

1484{
1485 return ntlm_QueryContextAttributesW(phContext, ulAttribute, pBuffer);
1486}
SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: ntlm.c:1427
PVOID pBuffer

Referenced by nego_QueryContextAttributesA().

◆ ntlm_QueryContextAttributesW()

SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesW ( PCtxtHandle  phContext,
ULONG  ulAttribute,
void pBuffer 
)

Definition at line 1427 of file ntlm.c.

1429{
1430 TRACE("%p %d %p\n", phContext, ulAttribute, pBuffer);
1431 if (!phContext)
1432 return SEC_E_INVALID_HANDLE;
1433
1434 switch(ulAttribute)
1435 {
1436#define _x(x) case (x) : FIXME(#x" stub\n"); break
1440 case SECPKG_ATTR_FLAGS:
1441 {
1443 PNegoHelper helper = (PNegoHelper)phContext->dwLower;
1444
1445 spcf->Flags = 0;
1446 if(helper->neg_flags & NTLMSSP_NEGOTIATE_SIGN)
1447 spcf->Flags |= ISC_RET_INTEGRITY;
1448 if(helper->neg_flags & NTLMSSP_NEGOTIATE_SEAL)
1450 return SEC_E_OK;
1451 }
1460 case SECPKG_ATTR_SIZES:
1461 {
1463 spcs->cbMaxToken = NTLM_MAX_BUF;
1464 spcs->cbMaxSignature = 16;
1465 spcs->cbBlockSize = 0;
1466 spcs->cbSecurityTrailer = 16;
1467 return SEC_E_OK;
1468 }
1471#undef _x
1472 default:
1473 TRACE("Unknown value %d passed for ulAttribute\n", ulAttribute);
1474 }
1475
1477}
#define _x(x)
#define SECPKG_ATTR_ACCESS_TOKEN
Definition: sspi.h:539
struct _SecPkgContext_Flags * PSecPkgContext_Flags
#define SECPKG_ATTR_SESSION_KEY
Definition: sspi.h:530
#define SECPKG_ATTR_AUTHORITY
Definition: sspi.h:527
#define SECPKG_ATTR_KEY_INFO
Definition: sspi.h:526
#define SECPKG_ATTR_PACKAGE_INFO
Definition: sspi.h:531
#define SECPKG_ATTR_NEGOTIATION_INFO
Definition: sspi.h:533
struct _SecPkgContext_Sizes * PSecPkgContext_Sizes
#define ISC_RET_CONFIDENTIALITY
Definition: sspi.h:389
#define SECPKG_ATTR_TARGET_INFORMATION
Definition: sspi.h:538
#define SECPKG_ATTR_PASSWORD_EXPIRY
Definition: sspi.h:529
#define SECPKG_ATTR_LIFESPAN
Definition: sspi.h:523
#define SECPKG_ATTR_SIZES
Definition: sspi.h:521
#define ISC_RET_INTEGRITY
Definition: sspi.h:401
#define SECPKG_ATTR_STREAM_SIZES
Definition: sspi.h:525
#define SECPKG_ATTR_FLAGS
Definition: sspi.h:535
#define SECPKG_ATTR_NAMES
Definition: sspi.h:522
#define SECPKG_ATTR_DCE_INFO
Definition: sspi.h:524
#define SECPKG_ATTR_NATIVE_NAMES
Definition: sspi.h:534
ULONG cbBlockSize
Definition: sspi.h:563
ULONG cbSecurityTrailer
Definition: sspi.h:564
ULONG cbMaxSignature
Definition: sspi.h:562
ULONG cbMaxToken
Definition: sspi.h:561

Referenced by nego_QueryContextAttributesW(), and ntlm_QueryContextAttributesA().

◆ ntlm_QueryCredentialsAttributesA()

static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA ( PCredHandle  phCredential,
ULONG  ulAttribute,
PVOID  pBuffer 
)
static

Definition at line 49 of file ntlm.c.

51{
53
54 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
55
56 if(ulAttribute == SECPKG_ATTR_NAMES)
57 {
58 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
60 }
61 else
63
64 return ret;
65}

◆ ntlm_QueryCredentialsAttributesW()

static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesW ( PCredHandle  phCredential,
ULONG  ulAttribute,
PVOID  pBuffer 
)
static

Definition at line 70 of file ntlm.c.

72{
74
75 TRACE("(%p, %d, %p)\n", phCredential, ulAttribute, pBuffer);
76
77 if(ulAttribute == SECPKG_ATTR_NAMES)
78 {
79 FIXME("SECPKG_CRED_ATTR_NAMES: stub\n");
81 }
82 else
84
85 return ret;
86}

◆ ntlm_RevertSecurityContext()

static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext ( PCtxtHandle  phContext)
static

Definition at line 1510 of file ntlm.c.

1511{
1513
1514 TRACE("%p\n", phContext);
1515 if (phContext)
1516 {
1518 }
1519 else
1520 {
1522 }
1523 return ret;
1524}

◆ ntlm_VerifySignature()

SECURITY_STATUS SEC_ENTRY ntlm_VerifySignature ( PCtxtHandle  phContext,
PSecBufferDesc  pMessage,
ULONG  MessageSeqNo,
PULONG  pfQOP 
)

Definition at line 1697 of file ntlm.c.

1699{
1700 PNegoHelper helper;
1701 UINT i;
1702 int token_idx;
1704 SecBufferDesc local_desc;
1705 PSecBuffer local_buff;
1706 BYTE local_sig[16];
1707
1708 TRACE("%p %p %d %p\n", phContext, pMessage, MessageSeqNo, pfQOP);
1709 if(!phContext)
1710 return SEC_E_INVALID_HANDLE;
1711
1712 if(!pMessage || !pMessage->pBuffers || pMessage->cBuffers < 2)
1713 return SEC_E_INVALID_TOKEN;
1714
1715 if((token_idx = ntlm_GetTokenBufferIndex(pMessage)) == -1)
1716 return SEC_E_INVALID_TOKEN;
1717
1718 if(pMessage->pBuffers[token_idx].cbBuffer < 16)
1720
1721 if(MessageSeqNo)
1722 FIXME("Ignoring MessageSeqNo\n");
1723
1724 helper = (PNegoHelper)phContext->dwLower;
1725 TRACE("Negotiated flags: 0x%08x\n", helper->neg_flags);
1726
1727 local_buff = HeapAlloc(GetProcessHeap(), 0, pMessage->cBuffers * sizeof(SecBuffer));
1728
1729 local_desc.ulVersion = SECBUFFER_VERSION;
1730 local_desc.cBuffers = pMessage->cBuffers;
1731 local_desc.pBuffers = local_buff;
1732
1733 for(i=0; i < pMessage->cBuffers; ++i)
1734 {
1735 if(pMessage->pBuffers[i].BufferType == SECBUFFER_TOKEN)
1736 {
1737 local_buff[i].BufferType = SECBUFFER_TOKEN;
1738 local_buff[i].cbBuffer = 16;
1739 local_buff[i].pvBuffer = local_sig;
1740 }
1741 else
1742 {
1743 local_buff[i].BufferType = pMessage->pBuffers[i].BufferType;
1744 local_buff[i].cbBuffer = pMessage->pBuffers[i].cbBuffer;
1745 local_buff[i].pvBuffer = pMessage->pBuffers[i].pvBuffer;
1746 }
1747 }
1748
1749 if((ret = ntlm_CreateSignature(helper, &local_desc, token_idx, NTLM_RECV, TRUE)) != SEC_E_OK)
1750 return ret;
1751
1752 if(memcmp(((PBYTE)local_buff[token_idx].pvBuffer) + 8,
1753 ((PBYTE)pMessage->pBuffers[token_idx].pvBuffer) + 8, 8))
1755 else
1756 ret = SEC_E_OK;
1757
1758 HeapFree(GetProcessHeap(), 0, local_buff);
1759
1760 return ret;
1761
1762}
int memcmp(void *Buffer1, void *Buffer2, ACPI_SIZE Count)
Definition: utclib.c:112
@ NTLM_RECV
Definition: ntlm.h:70
PVOID *typedef PSecBuffer
Definition: ntsecpkg.h:440
#define SECBUFFER_VERSION
Definition: sspi.h:187
ULONG ulVersion
Definition: sspi.h:181
#define SEC_E_MESSAGE_ALTERED
Definition: winerror.h:2924

Referenced by nego_VerifySignature(), and ntlm_DecryptMessage().

◆ SECUR32_initNTLMSP()

void SECUR32_initNTLMSP ( void  )

Definition at line 2026 of file ntlm.c.

2027{
2028 PNegoHelper helper;
2029 static CHAR version[] = "--version";
2030
2031 SEC_CHAR *args[] = {
2032 ntlm_auth,
2033 version,
2034 NULL };
2035
2036 if(fork_helper(&helper, ntlm_auth, args) != SEC_E_OK)
2037 helper = NULL;
2038 else
2039 check_version(helper);
2040
2041 if( helper &&
2042 ((helper->major > MIN_NTLM_AUTH_MAJOR_VERSION) ||
2043 (helper->major == MIN_NTLM_AUTH_MAJOR_VERSION &&
2045 (helper->major == MIN_NTLM_AUTH_MAJOR_VERSION &&
2047 helper->micro >= MIN_NTLM_AUTH_MICRO_VERSION)) )
2048 {
2051 }
2052 else
2053 {
2054 ERR_(winediag)("%s was not found or is outdated. "
2055 "Make sure that ntlm_auth >= %d.%d.%d is in your path. "
2056 "Usually, you can find it in the winbind package of your distribution.\n",
2057 ntlm_auth,
2061
2062 }
2063 cleanup_helper(helper);
2064}
static const WCHAR version[]
Definition: asmname.c:66
static const SecurityFunctionTableW ntlmTableW
Definition: ntlm.c:1948
#define MIN_NTLM_AUTH_MICRO_VERSION
Definition: ntlm.c:39
SecPkgInfoW * ntlm_package_infoW
Definition: ntlm.c:2024
static const SecurityFunctionTableA ntlmTableA
Definition: ntlm.c:1917
#define MIN_NTLM_AUTH_MINOR_VERSION
Definition: ntlm.c:37
#define MIN_NTLM_AUTH_MAJOR_VERSION
Definition: ntlm.c:36
SecPkgInfoA * ntlm_package_infoA
Definition: ntlm.c:2023
static BOOL check_version(LPCWSTR gre_path, const char *version_string)
Definition: nsembed.c:521
SecureProvider * SECUR32_addProvider(const SecurityFunctionTableA *fnTableA, const SecurityFunctionTableW *fnTableW, PCWSTR moduleName) DECLSPEC_HIDDEN
Definition: secur32_wine.c:314
void SECUR32_addPackages(SecureProvider *provider, ULONG toAdd, const SecPkgInfoA *infoA, const SecPkgInfoW *infoW) DECLSPEC_HIDDEN
Definition: secur32_wine.c:362
#define ERR_(ch,...)
Definition: debug.h:156
int minor
Definition: ntlm.h:31
int major
Definition: ntlm.h:30
int micro
Definition: ntlm.h:32
Definition: match.c:390

Referenced by SECUR32_initializeProviders().

◆ WINE_DECLARE_DEBUG_CHANNEL()

WINE_DECLARE_DEBUG_CHANNEL ( winediag  )

◆ WINE_DEFAULT_DEBUG_CHANNEL()

WINE_DEFAULT_DEBUG_CHANNEL ( ntlm  )

Variable Documentation

◆ infoA

const SecPkgInfoA infoA
static
Initial value:
= {
1,
}
static CHAR ntlm_comment_A[]
Definition: ntlm.c:1984
#define CAPS
Definition: ntlm.c:1993
static char ntlm_name_A[]
Definition: ntlm.c:1989
#define RPC_C_AUTHN_WINNT
Definition: rpcdce.h:158

Definition at line 2014 of file ntlm.c.

◆ infoW

const SecPkgInfoW infoW
static
Initial value:
= {
1,
}
static WCHAR ntlm_name_W[]
Definition: ntlm.c:1990
static WCHAR ntlm_comment_W[]
Definition: ntlm.c:1985

Definition at line 2005 of file ntlm.c.

◆ ntlm_auth

CHAR ntlm_auth[] = "ntlm_auth"
static

◆ ntlm_comment_A

CHAR ntlm_comment_A[] = NTLM_COMMENT
static

Definition at line 1984 of file ntlm.c.

◆ ntlm_comment_W

WCHAR ntlm_comment_W[] = NTLM_COMMENT
static

Definition at line 1985 of file ntlm.c.

◆ ntlm_name_A

char ntlm_name_A[] = NTLM_NAME
static

Definition at line 1989 of file ntlm.c.

◆ ntlm_name_W

WCHAR ntlm_name_W[] = NTLM_NAME
static

Definition at line 1990 of file ntlm.c.

◆ ntlm_package_infoA

SecPkgInfoA* ntlm_package_infoA = (SecPkgInfoA *)&infoA

Definition at line 2023 of file ntlm.c.

Referenced by nego_QueryContextAttributesA(), and SECUR32_initNTLMSP().

◆ ntlm_package_infoW

SecPkgInfoW* ntlm_package_infoW = (SecPkgInfoW *)&infoW

Definition at line 2024 of file ntlm.c.

Referenced by nego_QueryContextAttributesW(), and SECUR32_initNTLMSP().

◆ ntlmTableA

const SecurityFunctionTableA ntlmTableA
static
Initial value:
= {
1,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
NULL,
}
static SECURITY_STATUS SEC_ENTRY ntlm_RevertSecurityContext(PCtxtHandle phContext)
Definition: ntlm.c:1510
SECURITY_STATUS SEC_ENTRY ntlm_AcceptSecurityContext(PCredHandle phCredential, PCtxtHandle phContext, PSecBufferDesc pInput, ULONG fContextReq, ULONG TargetDataRep, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: ntlm.c:1029
static SECURITY_STATUS SEC_ENTRY ntlm_AcquireCredentialsHandleA(SEC_CHAR *pszPrincipal, SEC_CHAR *pszPackage, ULONG fCredentialUse, PLUID pLogonID, PVOID pAuthData, SEC_GET_KEY_FN pGetKeyFn, PVOID pGetKeyArgument, PCredHandle phCredential, PTimeStamp ptsExpiry)
Definition: ntlm.c:290
SECURITY_STATUS SEC_ENTRY ntlm_QueryContextAttributesA(PCtxtHandle phContext, ULONG ulAttribute, void *pBuffer)
Definition: ntlm.c:1482
static SECURITY_STATUS SEC_ENTRY ntlm_QueryCredentialsAttributesA(PCredHandle phCredential, ULONG ulAttribute, PVOID pBuffer)
Definition: ntlm.c:49
SECURITY_STATUS SEC_ENTRY ntlm_FreeCredentialsHandle(PCredHandle phCredential)
Definition: ntlm.c:1767
static SECURITY_STATUS SEC_ENTRY ntlm_ImpersonateSecurityContext(PCtxtHandle phContext)
Definition: ntlm.c:1491
static SECURITY_STATUS SEC_ENTRY ntlm_CompleteAuthToken(PCtxtHandle phContext, PSecBufferDesc pToken)
Definition: ntlm.c:1384
static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextA(PCredHandle phCredential, PCtxtHandle phContext, SEC_CHAR *pszTargetName, ULONG fContextReq, ULONG Reserved1, ULONG TargetDataRep, PSecBufferDesc pInput, ULONG Reserved2, PCtxtHandle phNewContext, PSecBufferDesc pOutput, ULONG *pfContextAttr, PTimeStamp ptsExpiry)
Definition: ntlm.c:995
SECURITY_STATUS SEC_ENTRY ntlm_MakeSignature(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: ntlm.c:1662
SECURITY_STATUS SEC_ENTRY ntlm_DecryptMessage(PCtxtHandle phContext, PSecBufferDesc pMessage, ULONG MessageSeqNo, PULONG pfQOP)
Definition: ntlm.c:1863
SECURITY_STATUS SEC_ENTRY ntlm_EncryptMessage(PCtxtHandle phContext, ULONG fQOP, PSecBufferDesc pMessage, ULONG MessageSeqNo)
Definition: ntlm.c:1792
SECURITY_STATUS SEC_ENTRY ntlm_DeleteSecurityContext(PCtxtHandle phContext)
Definition: ntlm.c:1398
SECURITY_STATUS WINAPI FreeContextBuffer(PVOID pv)
Definition: sspi.c:699

Definition at line 1917 of file ntlm.c.

Referenced by SECUR32_initNTLMSP().

◆ ntlmTableW