secur32: Fix handling of ISC_REQ* flags in InitializeSecurityContext.

This commit is contained in:
Kai Blin 2006-11-13 15:55:39 +01:00 committed by Alexandre Julliard
parent 00e097b6e3
commit 1037e20bc7
2 changed files with 239 additions and 16 deletions

View File

@ -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;

View File

@ -551,6 +551,214 @@ 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)
@ -909,6 +1117,7 @@ START_TEST(ntlm)
pInitializeSecurityContextA && pCompleteAuthToken &&
pQuerySecurityPackageInfoA)
{
testInitializeSecurityContextFlags();
if(pAcceptSecurityContext)
{
testAuth(SECURITY_NATIVE_DREP, TRUE);