Leaked source code of windows server 2003
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.
 
 
 
 
 
 

438 lines
12 KiB

/*++
Copyright (c) 1994-2000 Microsoft Corporation
Module Name:
Creds.cxx
Abstract:
Contains the Creds APIs
Contents:
WinHttpSetCredentialsA
WinHttpSetCredentials
WinHttpQueryAuthSchemes
Author:
Biao Wang (biaow) 27-June-2000
Environment:
Win32 user-mode DLL
Revision History:
27-June-2000 biaow
Created
--*/
#include <wininetp.h>
/*
BOOLAPI WinHttpQueryAuthParams(
IN HINTERNET hRequest, // HINTERNET handle returned by WinHttpOpenRequest
IN DWORD AuthScheme,
OUT LPVOID* pAuthParams // Scheme-specific Advanced auth parameters
)
{
//BUG-BUG Verify parameters
// biaow: to implement this fully
*pAuthParams = 0;
return TRUE;
}
*/
BOOLAPI WinHttpQueryAuthSchemes(
IN HINTERNET hRequest, // HINTERNET handle returned by HttpOpenRequest.
OUT LPDWORD lpdwSupportedSchemes,// a bitmap of available Authentication Schemes
OUT LPDWORD lpdwPreferredScheme, // WinHttp's preferred Authentication Method
OUT LPDWORD pdwAuthTarget
)
{
DEBUG_ENTER_API((DBG_API,
Bool,
"WinHttpQueryAuthSchemes",
"%#x, %#x, %#x",
hRequest,
lpdwSupportedSchemes,
lpdwPreferredScheme
));
DWORD dwErr = ERROR_SUCCESS;
HINTERNET hRequestMapped = NULL;
BOOL fResult = FALSE;
HINTERNET_HANDLE_TYPE HandleType;
dwErr = ::MapHandleToAddress(hRequest, (LPVOID *)&hRequestMapped, FALSE);
if ((dwErr != ERROR_SUCCESS) || (hRequestMapped == NULL))
{
dwErr = ERROR_INVALID_HANDLE;
goto cleanup;
}
HTTP_REQUEST_HANDLE_OBJECT * pRequest;
if ((::RGetHandleType(hRequestMapped, &HandleType) != ERROR_SUCCESS)
|| (HandleType != TypeHttpRequestHandle))
{
dwErr = ERROR_INVALID_HANDLE;
goto cleanup;
}
pRequest = (HTTP_REQUEST_HANDLE_OBJECT *)hRequestMapped;
if (::IsBadWritePtr(lpdwSupportedSchemes, sizeof(DWORD))
|| ::IsBadWritePtr(lpdwPreferredScheme, sizeof(DWORD))
|| ::IsBadWritePtr(pdwAuthTarget, sizeof(DWORD)))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
if ((!pRequest->_SupportedSchemes) || (!pRequest->_PreferredScheme))
{
dwErr = ERROR_INVALID_OPERATION;
goto cleanup;
}
*lpdwSupportedSchemes = pRequest->_SupportedSchemes;
*lpdwPreferredScheme = pRequest->_PreferredScheme;
*pdwAuthTarget = pRequest->_AuthTarget;
fResult = TRUE;
cleanup:
if (hRequestMapped)
{
DereferenceObject(hRequestMapped);
}
if (dwErr!= ERROR_SUCCESS)
{
::SetLastError(dwErr);
DEBUG_ERROR(HTTP, dwErr);
}
DEBUG_LEAVE_API(fResult);
return fResult;
}
BOOL WinHttpSetCredentialsA (
IN HINTERNET hRequest, // HINTERNET handle returned by HttpOpenRequest.
IN DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and
// WINHTTP_AUTH_TARGET_PROXY are supported
// in this version and they are mutually
// exclusive
IN DWORD AuthScheme, // must be one of the supported Auth Schemes
// returned from HttpQueryAuthSchemes(), Apps
// should use the Preferred Scheme returned
IN LPCSTR pszUserName, // 1) NULL if default creds is to be used, in
// which case pszPassword will be ignored
IN LPCSTR pszPassword, // 1) "" == Blank Passowrd; 2)Parameter ignored
// if pszUserName is NULL; 3) Invalid to pass in
// NULL if pszUserName is not NULL
IN LPVOID pAuthParams
)
{
DEBUG_ENTER_API((DBG_API,
Bool,
"WinHttpSetCredentialsA",
"%#x, %#x, %#x, %q, %q, %q",
hRequest,
AuthTargets,
AuthScheme,
pAuthParams,
pszUserName,
pszPassword
));
// Note: we assume WinHttp will explose an Unicode only API, so this function
// will not be called directly by Apps. If this assumption is no longer true
// in future revisions, we need to add more elaborate parameter validation here.
DWORD dwErr = ERROR_SUCCESS;
BOOL fResult = FALSE;
HINTERNET hRequestMapped = NULL;
HTTP_REQUEST_HANDLE_OBJECT* pRequest;
HINTERNET_HANDLE_TYPE HandleType;
PSTR pszRealm = NULL;
// validate API symantics
if (pszUserName != NULL)
{
// in any case, it doesn't make sense (and therefore invalid) to pass
// in a blank("") User Name
if (::strlen(pszUserName) == 0)
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
else if (pszPassword == NULL)
{
// in any case, if an app passes in a UserName, it is invalid to
// then pass in a NULL password (should use "" for blank passowrd)
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
}
// biaow: is blank scheme OK?
// if an app picks BASIC auth, it must also supply an UserName and password
if ((AuthScheme == WINHTTP_AUTH_SCHEME_BASIC) && (pszUserName == NULL))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
// default credentials (UserName/Password == NULL/NULL) are allowed only for
// NTLM/NEGOTIATE/PASSPORT auth
if (pszUserName == NULL)
{
if ((AuthScheme != WINHTTP_AUTH_SCHEME_NTLM)
&& (AuthScheme != WINHTTP_AUTH_SCHEME_NEGOTIATE)
&& (AuthScheme != WINHTTP_AUTH_SCHEME_PASSPORT))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
}
dwErr = ::MapHandleToAddress(hRequest, (LPVOID *)&hRequestMapped, FALSE);
if ((dwErr != ERROR_SUCCESS) || (hRequestMapped == NULL)) {
dwErr = ERROR_INVALID_HANDLE;
goto cleanup;
}
if ((::RGetHandleType(hRequestMapped, &HandleType) != ERROR_SUCCESS)
|| (HandleType != TypeHttpRequestHandle))
{
dwErr = ERROR_INVALID_HANDLE;
goto cleanup;
}
pRequest =
reinterpret_cast<HTTP_REQUEST_HANDLE_OBJECT*>(hRequestMapped);
if (AuthScheme == WINHTTP_AUTH_SCHEME_DIGEST)
{
if (pAuthParams)
{
pszRealm = NewString((PCSTR)pAuthParams);
}
else
{
pszRealm = pRequest->_pszRealm;
}
if (pszRealm == NULL)
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
}
if (AuthTargets == WINHTTP_AUTH_TARGET_PROXY)
{
delete pRequest->_pProxyCreds;
pRequest->_pProxyCreds = New WINHTTP_REQUEST_CREDENTIALS(AuthScheme,
pszRealm, pszUserName, pszPassword);
if (pRequest->_pProxyCreds == NULL)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
}
else
{
delete pRequest->_pServerCreds;
pRequest->_pServerCreds = New WINHTTP_REQUEST_CREDENTIALS(AuthScheme,
pszRealm, pszUserName, pszPassword);
if (pRequest->_pServerCreds == NULL)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
}
pRequest->_PreferredScheme = 0x00000000;
pRequest->_SupportedSchemes = 0x00000000;
pRequest->_AuthTarget = 0x00000000;
if (pRequest->_pszRealm)
{
FREE_MEMORY(pRequest->_pszRealm);
pRequest->_pszRealm = NULL;
}
fResult = TRUE;
cleanup:
if (hRequestMapped)
{
DereferenceObject(hRequestMapped);
}
if (dwErr!=ERROR_SUCCESS)
{
::SetLastError(dwErr);
DEBUG_ERROR(HTTP, dwErr);
}
DEBUG_LEAVE_API(fResult);
return fResult;
}
BOOLAPI
WinHttpSetCredentials(
IN HINTERNET hRequest, // HINTERNET handle returned by HttpOpenRequest.
IN DWORD AuthTargets, // Only WINHTTP_AUTH_TARGET_SERVER and
// WINHTTP_AUTH_TARGET_PROXY are supported
// in this version and they are mutually
// exclusive
IN DWORD AuthScheme, // must be one of the supported Auth Schemes
// returned from HttpQueryAuthSchemes(), Apps
// should use the Preferred Scheme returned
IN LPCWSTR pwszUserName, // 1) NULL if default creds is to be used, in
// which case pszPassword will be ignored
IN LPCWSTR pwszPassword, // 1) "" == Blank Passowrd; 2)Parameter ignored
// if pszUserName is NULL; 3) Invalid to pass in
// NULL if pszUserName is not NULL
IN LPVOID pAuthParams
)
{
DEBUG_ENTER_API((DBG_API,
Bool,
"WinHttpSetCredentials",
"%#x, %#x, %#x, %wq, %wq, %wq",
hRequest,
AuthTargets,
AuthScheme,
pAuthParams,
pwszUserName,
pwszPassword
));
DWORD dwErr = ERROR_SUCCESS;
BOOL fResult = FALSE;
LPCWSTR pwszRealm = NULL;
MEMORYPACKET mpRealm, mpUserName, mpPassword;
if (!hRequest)
{
dwErr = ERROR_INVALID_HANDLE;
goto cleanup;
}
// make sure only one bit in AuthScheme is set
if ((AuthScheme & (AuthScheme - 1)) != 0x00000000)
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
// make sure the input strings are valid
if (pwszUserName
&& ::IsBadStringPtrW(pwszUserName, INTERNET_MAX_USER_NAME_LENGTH))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
if (pwszPassword
&& ::IsBadStringPtrW(pwszPassword, INTERNET_MAX_PASSWORD_LENGTH))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
if ((AuthScheme == WINHTTP_AUTH_SCHEME_DIGEST) && pAuthParams)
{
pwszRealm = (LPCWSTR)pAuthParams;
}
if (pwszRealm
&& ::IsBadStringPtrW(pwszRealm, INTERNET_MAX_REALM_LENGTH))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
// make sure AuthTargets are either Server or Proxy (not both)
if ((AuthTargets != WINHTTP_AUTH_TARGET_SERVER)
&& (AuthTargets != WINHTTP_AUTH_TARGET_PROXY))
{
dwErr = ERROR_INVALID_PARAMETER;
goto cleanup;
}
// convert Unicode strings to Ansi
if (pwszUserName)
{
ALLOC_MB(pwszUserName, 0, mpUserName);
if (!mpUserName.psStr)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
UNICODE_TO_ANSI(pwszUserName, mpUserName);
}
if (pwszPassword)
{
ALLOC_MB(pwszPassword, 0, mpPassword);
if (!mpPassword.psStr)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
UNICODE_TO_ANSI(pwszPassword, mpPassword);
}
if (pwszRealm)
{
ALLOC_MB(pwszRealm, 0, mpRealm);
if (!mpRealm.psStr)
{
dwErr = ERROR_NOT_ENOUGH_MEMORY;
goto cleanup;
}
UNICODE_TO_ANSI(pwszRealm, mpRealm);
}
fResult = ::WinHttpSetCredentialsA(hRequest, AuthTargets,
AuthScheme, mpUserName.psStr, mpPassword.psStr, mpRealm.psStr);
cleanup:
if (dwErr!=ERROR_SUCCESS)
{
::SetLastError(dwErr);
DEBUG_ERROR(HTTP, dwErr);
}
DEBUG_LEAVE_API(fResult);
return fResult;
}