RE: InitializeSecurityContext() and Digest in C++



Jeffrey,

Thanks for the reply. I have tried to use the SSPI Workbench but cannot get
Digest to work correctly.

Steps I do in the Workbench and error I receive when running WinXP Prof. SP2:
1. Select Clieint from initial dialog.
2. "Shoose a particular SSP" radio and select "Digest"
3. Click OK and section 2 is enabled.
4. "Provide explicit credentials" radio and enter in:
Authority = domain
Principle = User Name
Password = User password
5. Click on AquireCredentialsHandle and get an error
"AcquireCredentialsHandle Failed: The function requested is not supported".

Here is a funcion that shows what I am working with.. Keep in mind that it
is not pretty and all I am wanting to do at this point is get the code to run
and generate a Digest value - not actually intract with a web server at this
time. But I will end up using the Digest in a web request.

Sample function call and code.
------------------------------------------------------------
Function call
ret = TestDigest(
m_auth,
"realm=\"Web Server Name here\", algorithm = \"MD5-sess\", qop=\"auth\",
nonce=\"0123456789abcdef\"",
m_buff,
"Digest",
"Domain Naim here",
"User Name here",
"User Password here");
------------------------------------------------------------
Sample code
BOOL TestDigest(AUTH_SEQ *pAS,
VOID *pBuffIn,
BUFFER *pbuffOut,
const CHAR *pszPackage,
const CHAR *pszDomain,
const CHAR *pszUser,
const CHAR *pszPassword)
{
SECURITY_STATUS ss;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff[3];
ULONG ContextAttributes = 0;
ULONG fContextReq;
BUFFER buffData;
BUFFER buff;
BOOL fSt;
BOOL fReply;

DWORD cbBuffIn;
SecPkgInfo * pspkg = NULL;
SEC_WINNT_AUTH_IDENTITY AuthIdentity;
SEC_WINNT_AUTH_IDENTITY * pAuthIdentity;

printf("TestDigest()\r\n");

BufferInit( &buffData );
BufferInit( &buff );

pAuthIdentity = &AuthIdentity;

memset( &AuthIdentity, 0, sizeof( AuthIdentity ) );

AuthIdentity.User = (unsigned char *) pszUser;
AuthIdentity.UserLength = pszUser != NULL ? strlen( pszUser ) : 0;

AuthIdentity.Password = (unsigned char *) pszPassword;
AuthIdentity.PasswordLength = pszPassword != NULL ? strlen( pszPassword ) :
0;

AuthIdentity.Domain = (unsigned char *) pszDomain;
AuthIdentity.DomainLength = pszDomain != NULL ? strlen( pszDomain ) : 0;

AuthIdentity.Flags = SEC_WINNT_AUTH_IDENTITY_ANSI;

printf("Call AcquireCredentialsHandle()\r\n");
ss = pAcquireCredentialsHandleA( NULL, // New principal
(char*)pszPackage, // Package name
SECPKG_CRED_OUTBOUND,
NULL, // Logon ID
&AuthIdentity, // Auth Data
NULL, // Get key func
NULL, // Get key arg
&pAS->_hcred,
&Lifetime );

DisplayReturnValue(ss);

//
// Need to determine the max token size for this package
//

if ( ss == STATUS_SUCCESS )
{
pAS->_fHaveCredHandle = TRUE;
ss = pQuerySecurityPackageInfoA(
(char *) pszPackage,
&pspkg );
}

if ( ss != STATUS_SUCCESS )
{
SetLastError( ss );
return FALSE;
}

pAS->_cbMaxToken = pspkg->cbMaxToken;

pFreeContextBuffer( pspkg );

//
// Prepare our output buffer. We use a temporary buffer because
// the real output buffer will most likely need to be uuencoded
//

if ( !BufferResize( &buff, pAS->_cbMaxToken ))
{
fSt = FALSE;
goto ex;
}

OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;

OutSecBuff.cbBuffer = pAS->_cbMaxToken;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = BufferQueryPtr( &buff );

//
// Prepare our Input buffer.
//

if ( pBuffIn )
{
InBuffDesc.ulVersion = 0;
InBuffDesc.cBuffers = 3;
InBuffDesc.pBuffers = &InSecBuff;

//Complete Digest string returned from server.
InSecBuff[0].cbBuffer = strlen(pBuffIn);
InSecBuff[0].BufferType = SECBUFFER_TOKEN;
InSecBuff[0].pvBuffer = pBuffIn;

//The request method used in the web request.
InSecBuff[1].cbBuffer = 3;
InSecBuff[1].BufferType = SECBUFFER_PKG_PARAMS;
InSecBuff[1].pvBuffer = "GET";

//If I set this to what I believe is the cnonce (client generated hex
string) then it fails
//with Invalid Token.
//If set to NULL and zero then I get No Credentials error.
InSecBuff[2].cbBuffer = 0;
InSecBuff[2].BufferType = SECBUFFER_PKG_PARAMS;
InSecBuff[2].pvBuffer = NULL;
}
//
// will return success when its done but we still
// need to send the out buffer if there are bytes to send
//

printf("First call InitializeSecurityContext()\r\n");
ss = pInitializeSecurityContextA(
&pAS->_hcred,
NULL,
"/WindowsIntSite/WebForm1.aspx",
0,
0,
0,
NULL,
0,
&pAS->_hctxt,
&OutBuffDesc,
&ContextAttributes,
&Lifetime );

DisplayReturnValue(ss);

if(ss == SEC_E_OK || ss == SEC_I_CONTINUE_NEEDED)
{
printf("Second call InitializeSecurityContext()\r\n");
ss = pInitializeSecurityContextA(
&pAS->_hcred,
&pAS->_hctxt,
"/WindowsIntSite/WebForm1.aspx",
0,
0,
0,
&InBuffDesc,
0,
&pAS->_hctxt,
&OutBuffDesc,
&ContextAttributes,
&Lifetime );
}

DisplayReturnValue(ss);

if ( !SEC_SUCCESS( ss ) )
{
if ( ss == SEC_E_LOGON_DENIED )
ss = ERROR_LOGON_FAILURE;

SetLastError( ss );
fSt = FALSE;
goto ex;
}

//Encode the digest value that was generated.
if ( !uuencode( (BYTE *) OutSecBuff.pvBuffer,
OutSecBuff.cbBuffer,
pbuffOut ))
{
fSt = FALSE;
goto ex;
}

fSt = TRUE;

ex:
BufferTerminate( &buffData );
BufferTerminate( &buff );

return fSt;
}
------------------------------------------------------------






--
Chuck C


""Jeffrey Tan[MSFT]"" wrote:

Hi Chuck,

Thanks for your post!

1. Is it possible for you to provide a little sample project and detailed
steps to help us reproduce this behavior? With the current information
available it is hard for me to give it a useful suggestion or guess for
root cause.

My current suggestion is downloading "SSPI Workbench Utility" in keith
brown's article below:
"Explore the Security Support Provider Interface Using the SSPI Workbench
Utility "
http://msdn.microsoft.com/msdnmag/issues/0800/security/

This tool can be used to do testing on various SSPI protocols including
Digest. You may give it a test and if it works, you may refer to the source
code of the tool for a sample.

2. Yes, it seems ISC_REQ_HTTP is missed in windows header files, I will try
to give it a research and get back to you ASAP. Thanks.

Best regards,
Jeffrey Tan
Microsoft Online Community Support
==================================================
Get notification to my posts through email? Please refer to
http://msdn.microsoft.com/subscriptions/managednewsgroups/default.aspx#notif
ications.

Note: The MSDN Managed Newsgroup support offering is for non-urgent issues
where an initial response from the community or a Microsoft Support
Engineer within 1 business day is acceptable. Please note that each follow
up response may take approximately 2 business days as the support
professional working with you may need further investigation to reach the
most efficient resolution. The offering is not appropriate for situations
that require urgent, real-time or phone-based interactions or complex
project analysis and dump analysis issues. Issues of this nature are best
handled working with a dedicated Microsoft Support Engineer by contacting
Microsoft Customer Support Services (CSS) at
http://msdn.microsoft.com/subscriptions/support/default.aspx.
==================================================
This posting is provided "AS IS" with no warranties, and confers no rights.


.



Relevant Pages