|
|
/*++
Copyright (c) 1990 Microsoft Corporation
Module Name:
creden.cxx
Abstract:
This module abstracts user credentials for the multiple credential support.
Author:
Krishna Ganugapati (KrishnaG) 03-Aug-1996
Revision History:
--*/
extern "C" { #include <nt.h>
#include <ntrtl.h>
#include <nturtl.h>
#include <windows.h>
#include <imagehlp.h>
#include <stdio.h>
#include <stdlib.h>
#include "memory.h"
}
#include <basetyps.h>
#include <des.h>
#include <crypt.h>
typedef long HRESULT;
#include "misc.hxx"
#include "creden.hxx"
#include "macro.h"
//
// This routine allocates and stores the password in the
// passed in pointer. The assumption here is that pszString
// is valid, it can be an empty string but not NULL.
// Note that this code cannot be used as is on Win2k and below
// as they do not support the newer functions.
//
HRESULT EncryptString( LPWSTR pszString, LPWSTR *ppszSafeString, PDWORD pdwLen ) { HRESULT hr = S_OK; DWORD dwLenStr = 0; DWORD dwPwdLen = 0; LPWSTR pszTempStr = NULL; NTSTATUS errStatus = STATUS_SUCCESS;
*ppszSafeString = NULL; *pdwLen = 0;
//
// If the string is valid, then we need to get the length
// and initialize the unicode string.
//
if (pszString) { UNICODE_STRING Password;
//
// Determine the length of buffer taking padding into account.
//
dwLenStr = wcslen(pszString);
dwPwdLen = (dwLenStr + 1) * sizeof(WCHAR) + (DES_BLOCKLEN -1);
pszTempStr = (LPWSTR) AllocADsMem(dwPwdLen); if (!pszTempStr) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
wcscpy(pszTempStr, pszString);
RtlInitUnicodeString(&Password, pszTempStr);
USHORT usExtra = 0;
if (usExtra = (Password.MaximumLength % DES_BLOCKLEN)) { Password.MaximumLength += (DES_BLOCKLEN - usExtra); }
errStatus = RtlEncryptMemory( Password.Buffer, Password.MaximumLength, 0 );
if (errStatus != STATUS_SUCCESS) {
BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus)); }
*pdwLen = Password.MaximumLength; *ppszSafeString = pszTempStr; }
error:
if (FAILED(hr) && pszTempStr) { FreeADsMem(pszTempStr); }
RRETURN(hr); }
HRESULT DecryptString( LPWSTR pszEncodedString, LPWSTR *ppszString, DWORD dwLen ) { HRESULT hr = S_OK; LPWSTR pszTempStr = NULL; UNICODE_STRING Password; NTSTATUS errStatus; if (!dwLen || !ppszString) { RRETURN(E_FAIL); }
*ppszString = NULL;
if (dwLen) { pszTempStr = (LPWSTR) AllocADsMem(dwLen); if (!pszTempStr) { BAIL_ON_FAILURE(hr = E_OUTOFMEMORY); }
memcpy(pszTempStr, pszEncodedString, dwLen);
errStatus = RtlDecryptMemory(pszTempStr, dwLen, 0); if (errStatus != STATUS_SUCCESS) { BAIL_ON_FAILURE(hr = HRESULT_FROM_NT(errStatus)); } *ppszString = pszTempStr; }
error:
if (FAILED(hr)) { FreeADsStr(pszTempStr); }
RRETURN(hr); }
//
// Static member of the class
//
CCredentials::CCredentials(): _lpszUserName(NULL), _lpszPassword(NULL), _dwAuthFlags(0), _dwPasswordLen(0) { }
CCredentials::CCredentials( LPWSTR lpszUserName, LPWSTR lpszPassword, DWORD dwAuthFlags ): _lpszUserName(NULL), _lpszPassword(NULL), _dwAuthFlags(0), _dwPasswordLen(0) {
//
// AjayR 10-04-99 we need a way to bail if the
// alloc's fail. Since it is in the constructor this is
// not very easy to do.
//
if (lpszUserName) { _lpszUserName = AllocADsStr(lpszUserName); } else { _lpszUserName = NULL; }
if (lpszPassword) { //
// The call can fail but we cannot recover from this.
//
EncryptString( lpszPassword, &_lpszPassword, &_dwPasswordLen ); }else {
_lpszPassword = NULL;
}
_dwAuthFlags = dwAuthFlags;
}
CCredentials::~CCredentials() { if (_lpszUserName) { FreeADsStr(_lpszUserName); }
if (_lpszPassword) { FreeADsStr(_lpszPassword); }
}
HRESULT CCredentials::GetUserName( LPWSTR *lppszUserName ) { if (!lppszUserName) { RRETURN(E_FAIL); }
if (!_lpszUserName) { *lppszUserName = NULL; }else {
*lppszUserName = AllocADsStr(_lpszUserName);
if (!*lppszUserName) {
RRETURN(E_OUTOFMEMORY); } }
RRETURN(S_OK); }
HRESULT CCredentials::GetPassword( LPWSTR * lppszPassword ) { UNICODE_STRING Password; LPWSTR lpTempPassword = NULL;
Password.Length = 0;
if (!lppszPassword) { RRETURN(E_FAIL); }
if (!_lpszPassword) { *lppszPassword = NULL; }else {
RRETURN( DecryptString( _lpszPassword, lppszPassword, _dwPasswordLen ) );
}
RRETURN(S_OK); }
HRESULT CCredentials::SetUserName( LPWSTR lpszUserName ) { if (_lpszUserName) { FreeADsStr(_lpszUserName); }
if (!lpszUserName) {
_lpszUserName = NULL; RRETURN(S_OK); }
_lpszUserName = AllocADsStr( lpszUserName ); if(!_lpszUserName) { RRETURN(E_FAIL); }
RRETURN(S_OK); }
HRESULT CCredentials::SetPassword( LPWSTR lpszPassword ) {
if (_lpszPassword) { FreeADsStr(_lpszPassword); }
if (!lpszPassword) {
_lpszPassword = NULL; RRETURN(S_OK); }
RRETURN( EncryptString( lpszPassword, &_lpszPassword, &_dwPasswordLen ) ); }
CCredentials::CCredentials( const CCredentials& Credentials ) { HRESULT hr = S_OK; LPWSTR pszTmpPwd = NULL;
_lpszUserName = NULL; _lpszPassword = NULL;
_lpszUserName = AllocADsStr( Credentials._lpszUserName );
if (Credentials._lpszPassword) { hr = DecryptString( Credentials._lpszPassword, &pszTmpPwd, Credentials._dwPasswordLen ); }
if (SUCCEEDED(hr) && pszTmpPwd) { hr = EncryptString( pszTmpPwd, &_lpszPassword, &_dwPasswordLen ); }
if (pszTmpPwd) { FreeADsStr(pszTmpPwd); } _dwAuthFlags = Credentials._dwAuthFlags;
}
void CCredentials::operator=( const CCredentials& other ) { HRESULT hr = S_OK; LPWSTR pszTmpPwd = NULL;
if ( &other == this) { return; }
if (_lpszUserName) { FreeADsStr(_lpszUserName); }
if (_lpszPassword) { FreeADsStr(_lpszPassword); }
_lpszUserName = AllocADsStr( other._lpszUserName );
if (other._lpszPassword) { hr = DecryptString( other._lpszPassword, &pszTmpPwd, other._dwPasswordLen ); }
if (SUCCEEDED(hr) && pszTmpPwd) { hr = EncryptString( pszTmpPwd, &_lpszPassword, &_dwPasswordLen ); }
if (pszTmpPwd) { FreeADsStr(pszTmpPwd); } _dwAuthFlags = other._dwAuthFlags;
return; }
BOOL operator==( CCredentials& x, CCredentials& y ) { BOOL bEqualUser = FALSE; BOOL bEqualPassword = FALSE; BOOL bEqualFlags = FALSE;
LPWSTR lpszXPassword = NULL; LPWSTR lpszYPassword = NULL; BOOL bReturnCode = FALSE; HRESULT hr = S_OK;
if (x._lpszUserName && y._lpszUserName) { bEqualUser = !(wcscmp(x._lpszUserName, y._lpszUserName)); }else if (!x._lpszUserName && !y._lpszUserName){ bEqualUser = TRUE; }
hr = x.GetPassword(&lpszXPassword); if (FAILED(hr)) { goto error; }
hr = y.GetPassword(&lpszYPassword); if (FAILED(hr)) { goto error; }
if ((lpszXPassword && lpszYPassword)) { bEqualPassword = !(wcscmp(lpszXPassword, lpszYPassword)); }else if (!lpszXPassword && !lpszYPassword) { bEqualPassword = TRUE; }
if (x._dwAuthFlags == y._dwAuthFlags) { bEqualFlags = TRUE; }
if (bEqualUser && bEqualPassword && bEqualFlags) {
bReturnCode = TRUE; }
error:
if (lpszXPassword) { FreeADsStr(lpszXPassword); }
if (lpszYPassword) { FreeADsStr(lpszYPassword); }
return(bReturnCode);
}
BOOL CCredentials::IsNullCredentials( ) { // The function will return true even if the flags are set
// this is because we want to try and get the default credentials
// even if the flags were set
if (!_lpszUserName && !_lpszPassword) { return(TRUE); }else { return(FALSE); }
}
DWORD CCredentials::GetAuthFlags() { return(_dwAuthFlags); }
void CCredentials::SetAuthFlags( DWORD dwAuthFlags ) { _dwAuthFlags = dwAuthFlags; }
|