Windows NT 4.0 source code leak
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 
 
 
 
 

363 lines
12 KiB

/*#----------------------------------------------------------------------------
**
** File: sspcalls.c
**
** Synopsis: This module contains SSPI function calls for SSPI SPM DLL.
**
** Copyright (C) 1995 Microsoft Corporation. All Rights Reserved.
**
** Authors: LucyC Created 25 Sept. 1995
**
**---------------------------------------------------------------------------*/
#include "msnspmh.h"
/*****
#ifdef THIS_FILE
#undef THIS_FILE
#endif
static char __szTraceSourceFile[] = __FILE__;
#define THIS_FILE __szTraceSourceFile
*****/
BOOL g_fUUEncodeData = TRUE;
/*-----------------------------------------------------------------------------
**
** Function: GetSecAuthMsg
**
** Synopsis: This function generates a SSPI NEGOTIATE or RESPONSE
** authorization string for the specified SSPI package.
** The authorization string generated by this function
** follows the format:
** "<Package Name> <Package Specific Auth. Data>"
** If global uuencoding is turned on, this functions will
** uuencode the message before building it into an
** authorization string; by default, the uuencoding flag is
** always on.
** This functions calls InitializeSecurityContext() to
** generate the NEGOTIATE/RESPONSE message for the authori-
** zation string. If the SSPI function returns NO_CREDENTIAL,
** and if the PROMPT_CREDS flag is not turned on when blocking
** is permitted, this function will call the SSPI function
** again with the PROMPT_CREDS flag set; if SSPI returns
** NO_CREDENTIAL again, this SSPI will return ERROR to the
** caller.
**
**
** Arguments:
**
** pData - pointer to SspData containing the SSPI function table
** and the SSPI package list.
** pkgID - the package index of the SSPI package to use.
** pMyContext - pointer to a context handle. If NULL is specified,
** this function will use a temporary space for the context
** handle and delete the handle before returning to the
** caller. If non-NULL address is specified, the context
** handle created by the SSPI is returned to the caller.
** And the caller will have to delete the handle when it's
** done with it.
** fContextReq - the SSPI request flag to pass to InitializeSecurityContext
** pBuffIn - pointer to the uudecoded CHALLENGE message if any.
** For generating NEGOTIATE message, this pointer should be NULL.
** cbBuffIn - length of the CHALLENGE message. This should be zero when
** when pBuffIn is NULL.
** pFinalBuff - pointer to a buffer for the final authorization string.
** pszTarget - Server Host Name
** bNonBlock - a flag which is set if blocking is not permitted.
**
** Return Value:
**
** HTSPM_STATUS_OK - if an authorization string is generated successfully
** HTSPM_STATUS_WOULD_BLOCK - if generating an authorization string would
** cause blocking when blocking is not permitted.
** HTSPM_ERROR - if any problem/error is encountered in generating an
** authorization string, including user hitting cancel on
** the SSPI dialog prompt for name/password.
**
**---------------------------------------------------------------------------*/
HTSPMStatusCode
GetSecAuthMsg (
F_UserInterface fpUI,
void * pvOpaqueOS,
PSspData pData,
UCHAR pkgID, // the package index into package list
PCtxtHandle pMyContext,
ULONG fContextReq, // Request Flags
VOID *pBuffIn,
DWORD cbBuffIn,
char *pFinalBuff,
SEC_CHAR *pszTarget, // Server Host Name
UINT bNonBlock
)
{
BOOLEAN bOk;
SECURITY_STATUS SecStat;
CtxtHandle hContext;
CtxtHandle *phContext;
TimeStamp Lifetime;
SecBufferDesc OutBuffDesc;
SecBuffer OutSecBuff;
SecBufferDesc InBuffDesc;
SecBuffer InSecBuff;
ULONG ContextAttributes;
char OutBufPlain[MAX_AUTH_MSG_SIZE];
char *pOutMsg = NULL;
HTSPMStatusCode RetStatus;
UI_StatusCode uisc;
ULONG bGet;
UI_WindowHandle *pwh = NULL;
//TraceFunctEnter("GetSecAuthMsg");
//
// Initialize the final buffer to hold the package name followed by
// a space. And setup the pOutMsg pointer to points to the character
// following the space so that the final NEGOTIATE/RESPONSE can be
// copied into the pFinalBuff starting at the character pointed to
// by pOutMsg.
//
if (pFinalBuff)
{
strcpy (pFinalBuff, pData->PkgList[pkgID]->pName);
pOutMsg = pFinalBuff + strlen(pFinalBuff);
*pOutMsg++ = ' ';
}
//
// If caller does not want the context handle back
//
if (pMyContext == NULL)
phContext = &hContext; // use a temporary one
else
phContext = pMyContext;
//
// Prepare our output buffer. We use a temporary buffer because
// the real output buffer will most likely need to be uuencoded
//
OutBuffDesc.ulVersion = 0;
OutBuffDesc.cBuffers = 1;
OutBuffDesc.pBuffers = &OutSecBuff;
OutSecBuff.cbBuffer = MAX_AUTH_MSG_SIZE;
OutSecBuff.BufferType = SECBUFFER_TOKEN;
OutSecBuff.pvBuffer = OutBufPlain;
//
// Prepare our Input buffer if a CHALLENGE message is passed in.
//
if ( pBuffIn )
{
InBuffDesc.ulVersion = 0;
InBuffDesc.cBuffers = 1;
InBuffDesc.pBuffers = &InSecBuff;
InSecBuff.cbBuffer = cbBuffIn;
InSecBuff.BufferType = SECBUFFER_TOKEN;
InSecBuff.pvBuffer = pBuffIn;
}
//
// Call SSPI function generate the NEGOTIATE/RESPONSE message
//
SspiRetry:
SecStat = (*(pData->pFuncTbl->InitializeSecurityContext))(
&pData->PkgList[pkgID]->Credential,
(pBuffIn ? phContext : NULL),
pszTarget,
fContextReq,
0,
SECURITY_NATIVE_DREP,
(pBuffIn) ? &InBuffDesc : NULL,
0,
phContext,
&OutBuffDesc,
&ContextAttributes,
&Lifetime );
//
// If SSPI function fails
//
if ( !NT_SUCCESS( SecStat ) )
{
RetStatus = HTSPM_ERROR;
//ErrorTrace(SSPCALLSID,"InitializeSecurityContext failed [0x%x]\n",
// SecStat);
//
// If SSPI do not have user name/password for the secified package,
//
if (SecStat == SEC_E_NO_CREDENTIALS)
{
//
// If we have prompted the user and still get back "No Credential"
// error, it means the user does not have valid credential; the
// user hit <CANCEL> on the UI box. If we have supplied a valid
// credential, but get back a "No Credential" error, then something
// has gone wrong; we definitely should return to caller with ERROR
//
if ((fContextReq & ISC_REQ_PROMPT_FOR_CREDS) ||
(fContextReq & ISC_REQ_USE_SUPPLIED_CREDS))
{
RetStatus = HTSPM_ERROR; // return ERROR to caller
}
else if (bNonBlock)
{
//
// Blocking is not permitted, return WOULD_BLOCK to caller
//
RetStatus = HTSPM_STATUS_WOULD_BLOCK;
}
else
{
// Blocking is permitted and we have not asked the SSPI to
// prompt the user for proper credential, we should call
// the SSPI again with PROMPT_CREDS flag set.
//
fContextReq = fContextReq | ISC_REQ_PROMPT_FOR_CREDS;
goto SspiRetry;
}
}
SetLastError( SecStat );
//
// If we failed to generate a RESPONSE, and
// if the context handle is not to be returned to the caller, we
// should delete the context handle before we exit this function.
// However, if we failed to generate a NEGOTIATE,
// we don't need to worry about deleting the context handle because
// the context handle has not being created in this case.
//
if (pBuffIn != NULL && pMyContext == NULL)
(*(pData->pFuncTbl->DeleteSecurityContext))(phContext);
//TraceFunctLeave();
return (RetStatus);
}
RetStatus = HTSPM_STATUS_OK;
//
// Only uuencode message if a output buffer is specified
//
if (pOutMsg)
{
if ( g_fUUEncodeData && pOutMsg)
{
if ( !uuencode( (BYTE *) OutSecBuff.pvBuffer,
OutSecBuff.cbBuffer,
(CHAR *) pOutMsg,
MAX_AUTH_MSG_SIZE ))
{
//ErrorTrace(SSPCALLSID,
// "Failed to uuencode NEGOTIATE/RESPONSE\n");
RetStatus = HTSPM_ERROR;
}
}
else
{
memcpy( (CHAR *) pOutMsg,
OutSecBuff.pvBuffer,
OutSecBuff.cbBuffer );
}
}
//
// We have successfully generated a NEGOTIATE or RESPONSE, so a context
// handle has been created by the SSPI.
// If the context handle is not to be returned to the caller, we should
// delete the context handle before we exit this function.
//
if (pMyContext == NULL)
(*(pData->pFuncTbl->DeleteSecurityContext))(phContext);
//TraceFunctLeave();
return (RetStatus);
}
/*-----------------------------------------------------------------------------
**
** Function: GetSecCredential
**
** Synopsis:
**
** This function go through the list of SSPI pacakges supported and
** call AcquireCredentialsHandle for each package. If the call fails,
** the SSPI package is deleted from the package list.
**
** Arguments:
**
** fpUI - pointer from the Explorer for making UI_SERVICE call
** pvOpaqueOS - pointer from the Explorer for making UI_SERVICE call
** pData - pointer to the data structure containing the package list.
**
** Return Value:
**
** void.
**
**---------------------------------------------------------------------------*/
VOID
GetSecCredential (
F_UserInterface fpUI,
void *pvOpaqueOS,
PSspData pData
)
{
int ii;
SECURITY_STATUS ss;
TimeStamp Lifetime;
ii = 0;
//
// For every package in the out package list
//
while (ii < pData->PkgCnt)
{
//
// Call SSPI function acquire security credential for this package
//
ss = (*(pData->pFuncTbl->AcquireCredentialsHandle))(
NULL, // New principal
pData->PkgList[ii]->pName, // Package name
SECPKG_CRED_OUTBOUND,// Credential Use
NULL, // Logon ID
NULL, // Auth Data
NULL, // Get key func
NULL, // Get key arg
&pData->PkgList[ii]->Credential, // Credential Handle
&Lifetime );
//
// If SSPI can not create a credential handle for the package
//
if ( ss != STATUS_SUCCESS )
{
SetLastError( ss );
//
// Failed to acquire credential for this package,
// Deallocate memory for this package
//
spm_free (fpUI, pvOpaqueOS, pData->PkgList[ii]->pName);
spm_free (fpUI, pvOpaqueOS, pData->PkgList[ii]);
//
// remove this SSPI package from the package list.
//
if (ii < pData->PkgCnt - 1)
{
memcpy (&pData->PkgList[ii], &pData->PkgList[ii+1],
(pData->PkgCnt - ii -1) * sizeof(PSSPAuthPkg));
}
pData->PkgList[--pData->PkgCnt] = NULL;
}
else
ii++; // proceed to the next package
}
}