secur32: Fix handling of ISC_REQ* flags in InitializeSecurityContext.
This commit is contained in:
parent
00e097b6e3
commit
1037e20bc7
|
@ -443,29 +443,41 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
|
|||
}
|
||||
lstrcpyA(want_flags, "SF");
|
||||
if(fContextReq & ISC_REQ_CONFIDENTIALITY)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
|
||||
if(fContextReq & ISC_REQ_CONNECTION)
|
||||
{
|
||||
/* This is default, so we'll enable it */
|
||||
ctxt_attr |= ISC_RET_CONNECTION;
|
||||
/* Work around a bug in ntlm_auth that sets the
|
||||
* NTLMSSP_FEATURE_SIGN flag for this want flag, which
|
||||
* breaks RPC. */
|
||||
if(0)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SESSION_KEY");
|
||||
char *ptr;
|
||||
if((ptr = strstr(want_flags, "NTLMSSP_FEATURE_SEAL")) == NULL)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SEAL");
|
||||
}
|
||||
if(fContextReq & ISC_REQ_CONNECTION)
|
||||
ctxt_attr |= ISC_RET_CONNECTION;
|
||||
if(fContextReq & ISC_REQ_EXTENDED_ERROR)
|
||||
FIXME("ISC_REQ_EXTENDED_ERROR\n");
|
||||
ctxt_attr |= ISC_RET_EXTENDED_ERROR;
|
||||
if(fContextReq & ISC_REQ_INTEGRITY)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
|
||||
{
|
||||
char *ptr;
|
||||
if((ptr = strstr(want_flags, "NTLMSSP_FEATURE_SIGN")) == NULL)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
|
||||
}
|
||||
if(fContextReq & ISC_REQ_MUTUAL_AUTH)
|
||||
FIXME("ISC_REQ_MUTUAL_AUTH\n");
|
||||
ctxt_attr |= ISC_RET_MUTUAL_AUTH;
|
||||
if(fContextReq & ISC_REQ_REPLAY_DETECT)
|
||||
FIXME("ISC_REQ_REPLAY_DETECT\n");
|
||||
{
|
||||
char *ptr;
|
||||
if((ptr = strstr(want_flags, "NTLMSSP_FEATURE_SIGN")) == NULL)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
|
||||
}
|
||||
if(fContextReq & ISC_REQ_SEQUENCE_DETECT)
|
||||
FIXME("ISC_REQ_SEQUENCE_DETECT\n");
|
||||
{
|
||||
char *ptr;
|
||||
if((ptr = strstr(want_flags, "NTLMSSP_FEATURE_SIGN")) == NULL)
|
||||
lstrcatA(want_flags, " NTLMSSP_FEATURE_SIGN");
|
||||
}
|
||||
if(fContextReq & ISC_REQ_STREAM)
|
||||
FIXME("ISC_REQ_STREAM\n");
|
||||
if(fContextReq & ISC_REQ_USE_DCE_STYLE)
|
||||
ctxt_attr |= ISC_RET_USED_DCE_STYLE;
|
||||
if(fContextReq & ISC_REQ_DELEGATE)
|
||||
ctxt_attr |= ISC_RET_DELEGATE;
|
||||
|
||||
/* If no password is given, try to use cached credentials. Fall back to an empty
|
||||
* password if this failed. */
|
||||
|
@ -533,6 +545,8 @@ static SECURITY_STATUS SEC_ENTRY ntlm_InitializeSecurityContextW(
|
|||
max_len-1, &bin_len)) != SEC_E_OK)
|
||||
goto isc_end;
|
||||
|
||||
/* We need to set NTLMSSP_NEGOTIATE_ALWAYS_SIGN manually for now */
|
||||
bin[13] |= 0x80;
|
||||
/* put the decoded client blob into the out buffer */
|
||||
|
||||
ret = SEC_I_CONTINUE_NEEDED;
|
||||
|
|
|
@ -550,7 +550,215 @@ static void communicate(SspiData *from, SspiData *to)
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
/**********************************************************************/
|
||||
static void testInitializeSecurityContextFlags()
|
||||
{
|
||||
SECURITY_STATUS sec_status;
|
||||
PSecPkgInfo pkg_info = NULL;
|
||||
SspiData client;
|
||||
SEC_WINNT_AUTH_IDENTITY id;
|
||||
static char sec_pkg_name[] = "NTLM";
|
||||
ULONG req_attr, ctxt_attr;
|
||||
TimeStamp ttl;
|
||||
PBYTE packet;
|
||||
|
||||
if(pQuerySecurityPackageInfoA( sec_pkg_name, &pkg_info) != SEC_E_OK)
|
||||
{
|
||||
trace("Package not installed, skipping test!\n");
|
||||
return;
|
||||
}
|
||||
|
||||
pFreeContextBuffer(pkg_info);
|
||||
id.User = (unsigned char*) "testuser";
|
||||
id.UserLength = strlen((char *) id.User);
|
||||
id.Domain = (unsigned char *) "WORKGROUP";
|
||||
id.DomainLength = strlen((char *) id.Domain);
|
||||
id.Password = (unsigned char*) "testpass";
|
||||
id.PasswordLength = strlen((char *) id.Password);
|
||||
id.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;
|
||||
|
||||
client.id = &id;
|
||||
|
||||
if((sec_status = setupClient(&client, sec_pkg_name)) != SEC_E_OK)
|
||||
{
|
||||
trace("Setting up the client returned %s, skipping test!\n",
|
||||
getSecError(sec_status));
|
||||
return;
|
||||
}
|
||||
|
||||
packet = client.out_buf->pBuffers[0].pvBuffer;
|
||||
|
||||
/* Due to how the requesting of the flags is implemented in ntlm_auth,
|
||||
* the tests need to be in this order, as there is no way to specify
|
||||
* "I request no special features" in ntlm_auth */
|
||||
|
||||
/* Without any flags, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = 0;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"With req_attr == 0, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_CONNECTION, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = ISC_REQ_CONNECTION;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"For ISC_REQ_CONNECTION, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_EXTENDED_ERROR, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = ISC_REQ_EXTENDED_ERROR;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"For ISC_REQ_EXTENDED_ERROR, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_MUTUAL_AUTH, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = ISC_REQ_MUTUAL_AUTH;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"For ISC_REQ_MUTUAL_AUTH, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_USE_DCE_STYLE, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = ISC_REQ_USE_DCE_STYLE;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"For ISC_REQ_USE_DCE_STYLE, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_DELEGATE, the lowest byte should not have bits 0x20 or 0x10 set*/
|
||||
req_attr = ISC_REQ_DELEGATE;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok(((packet[12] & 0x10) == 0) && ((packet[12] & 0x20) == 0),
|
||||
"For ISC_REQ_DELEGATE, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_INTEGRITY, the lowest byte should have bit 0x10 set */
|
||||
req_attr = ISC_REQ_INTEGRITY;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok((packet[12] & 0x10) != 0,
|
||||
"For ISC_REQ_INTEGRITY, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_REPLAY_DETECT, the lowest byte should have bit 0x10 set */
|
||||
req_attr = ISC_REQ_REPLAY_DETECT;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok((packet[12] & 0x10) != 0,
|
||||
"For ISC_REQ_REPLAY_DETECT, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_SEQUENCE_DETECT, the lowest byte should have bit 0x10 set */
|
||||
req_attr = ISC_REQ_SEQUENCE_DETECT;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok((packet[12] & 0x10) != 0,
|
||||
"For ISC_REQ_SEQUENCE_DETECT, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
/* With ISC_REQ_CONFIDENTIALITY, the lowest byte should have bit 0x20 set */
|
||||
req_attr = ISC_REQ_CONFIDENTIALITY;
|
||||
|
||||
if((sec_status = pInitializeSecurityContextA(client.cred, NULL, NULL, req_attr,
|
||||
0, SECURITY_NETWORK_DREP, NULL, 0, client.ctxt, client.out_buf,
|
||||
&ctxt_attr, &ttl)) != SEC_I_CONTINUE_NEEDED)
|
||||
{
|
||||
trace("InitializeSecurityContext returned %s not SEC_I_CONTINUE_NEEDED, aborting.\n",
|
||||
getSecError(sec_status));
|
||||
goto tISCFend;
|
||||
}
|
||||
|
||||
ok((packet[12] & 0x20) != 0,
|
||||
"For ISC_REQ_CONFIDENTIALITY, flags are 0x%02x%02x%02x%02x.\n",
|
||||
packet[15], packet[14], packet[13], packet[12]);
|
||||
|
||||
tISCFend:
|
||||
cleanupBuffers(&client);
|
||||
pFreeCredentialsHandle(client.cred);
|
||||
|
||||
}
|
||||
|
||||
/**********************************************************************/
|
||||
|
||||
static void testAuth(ULONG data_rep, BOOL fake)
|
||||
|
@ -906,9 +1114,10 @@ START_TEST(ntlm)
|
|||
|
||||
if(pFreeCredentialsHandle && pDeleteSecurityContext &&
|
||||
pDeleteSecurityContext && pAcquireCredentialsHandleA &&
|
||||
pInitializeSecurityContextA && pCompleteAuthToken &&
|
||||
pInitializeSecurityContextA && pCompleteAuthToken &&
|
||||
pQuerySecurityPackageInfoA)
|
||||
{
|
||||
testInitializeSecurityContextFlags();
|
||||
if(pAcceptSecurityContext)
|
||||
{
|
||||
testAuth(SECURITY_NATIVE_DREP, TRUE);
|
||||
|
|
Loading…
Reference in New Issue