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.
305 lines
8.1 KiB
305 lines
8.1 KiB
#ifndef MAC
|
|
#include <security.h>
|
|
#endif
|
|
|
|
#include <bootdefs.h>
|
|
#include <sspi.h>
|
|
#include <ntlmsspi.h>
|
|
#include <crypt.h>
|
|
#include <cred.h>
|
|
#include <winerror.h>
|
|
#include "cache.h"
|
|
|
|
#ifndef MAC
|
|
#include <rpc.h>
|
|
#endif
|
|
|
|
#define toupper(_c) ( ((_c) >= 'a' && (_c) <= 'z') ? ( (_c)-'a'+'A' ) : (_c) )
|
|
|
|
BOOL
|
|
SspGetWorkstation(
|
|
PSSP_CREDENTIAL Credential
|
|
);
|
|
|
|
static PSSP_CREDENTIAL Cache = NULL;
|
|
|
|
void
|
|
CacheInitializeCache(
|
|
)
|
|
{
|
|
}
|
|
|
|
BOOL
|
|
CacheGetPassword(
|
|
PSSP_CREDENTIAL Credential
|
|
)
|
|
{
|
|
if (Cache == NULL) {
|
|
return (FALSE);
|
|
}
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
Credential->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
|
|
if (Credential->LmPassword == NULL) {
|
|
return (FALSE);
|
|
}
|
|
#endif
|
|
Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
|
|
if (Credential->NtPassword == NULL) {
|
|
return (FALSE);
|
|
}
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
_fmemcpy((PCHAR)Credential->LmPassword, (PCHAR)Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
|
|
#endif
|
|
_fmemcpy((PCHAR)Credential->NtPassword, (PCHAR)Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
|
|
|
|
return (TRUE);
|
|
}
|
|
|
|
SECURITY_STATUS
|
|
CacheSetCredentials(
|
|
IN PVOID AuthData,
|
|
PSSP_CREDENTIAL Credential
|
|
)
|
|
{
|
|
SEC_WINNT_AUTH_IDENTITY *Identity = (SEC_WINNT_AUTH_IDENTITY*)AuthData;
|
|
char TmpText[CLEAR_BLOCK_LENGTH*2];
|
|
NT_PASSWORD TmpNtPassword;
|
|
WCHAR TmpUnicodeText[CLEAR_BLOCK_LENGTH*2];
|
|
int Length = 0;
|
|
int i = 0;
|
|
|
|
if (Identity->Domain == NULL)
|
|
return SEC_E_UNKNOWN_CREDENTIALS;
|
|
|
|
Credential->Username = NULL;
|
|
Credential->Domain = NULL;
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
Credential->LmPassword = NULL;
|
|
#endif
|
|
Credential->NtPassword = NULL;
|
|
Credential->Workstation = NULL;
|
|
|
|
// If no identity is passed and there is no cached identity, give up.
|
|
if (AuthData == NULL)
|
|
{
|
|
if (Cache == NULL)
|
|
return SEC_E_UNKNOWN_CREDENTIALS;
|
|
}
|
|
|
|
// Save the latest authentication information.
|
|
else
|
|
{
|
|
|
|
// If an old cache entry exists, release its strings.
|
|
if (Cache != NULL)
|
|
{
|
|
if (Cache->Username != NULL)
|
|
SspFree(Cache->Username);
|
|
if (Cache->Domain != NULL)
|
|
SspFree(Cache->Domain);
|
|
if (Cache->Workstation != NULL)
|
|
SspFree(Cache->Workstation);
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
if (Cache->LmPassword != NULL)
|
|
SspFree(Cache->LmPassword);
|
|
#endif
|
|
if (Cache->NtPassword != NULL)
|
|
SspFree(Cache->NtPassword);
|
|
}
|
|
|
|
// Otherwise, allocate a cache entry
|
|
else
|
|
{
|
|
Cache = (PSSP_CREDENTIAL) SspAlloc (sizeof(SSP_CREDENTIAL));
|
|
if (Cache == NULL) {
|
|
return (SEC_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
}
|
|
|
|
Cache->Username = NULL;
|
|
Cache->Domain = NULL;
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
Cache->LmPassword = NULL;
|
|
#endif
|
|
Cache->NtPassword = NULL;
|
|
Cache->Workstation = NULL;
|
|
|
|
Cache->Username = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->User) + 1);
|
|
if (Cache->Username == NULL) {
|
|
goto cache_failure;
|
|
}
|
|
_fstrcpy(Cache->Username, (const char*)Identity->User);
|
|
|
|
Cache->Domain = (PCHAR)SspAlloc(_fstrlen((const char*)Identity->Domain) + 1);
|
|
if (Cache->Domain == NULL) {
|
|
goto cache_failure;
|
|
}
|
|
_fstrcpy(Cache->Domain, (const char*)Identity->Domain);
|
|
|
|
// If netbios won't tell us the workstation name, make one up.
|
|
if (!SspGetWorkstation(Cache))
|
|
{
|
|
Cache->Workstation = (PCHAR)SspAlloc(_fstrlen("none") + 1);
|
|
if (Cache->Workstation == NULL) {
|
|
goto cache_failure;
|
|
}
|
|
_fstrcpy(Cache->Workstation, "none");
|
|
}
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
Cache->LmPassword = SspAlloc (sizeof(LM_OWF_PASSWORD));
|
|
if (Cache->LmPassword == NULL) {
|
|
goto cache_failure;
|
|
}
|
|
#endif
|
|
|
|
Cache->NtPassword = (LM_OWF_PASSWORD*)SspAlloc (sizeof(NT_OWF_PASSWORD));
|
|
if (Cache->NtPassword == NULL) {
|
|
goto cache_failure;
|
|
}
|
|
|
|
#ifdef ALLOW_NON_OWF_PASSWORD
|
|
if ( (Credential->CredentialUseFlags & SECPKG_CRED_OWF_PASSWORD) == 0 ) {
|
|
|
|
if (Identity->Password == NULL)
|
|
Length = 0;
|
|
else
|
|
Length = _fstrlen(Identity->Password);
|
|
if (Length > CLEAR_BLOCK_LENGTH * 2)
|
|
goto cache_failure;
|
|
|
|
// Allow NULL and "\0" passwords by prefilling TmpText with and
|
|
// empty string.
|
|
if (Length == 0)
|
|
TmpText[0] = 0;
|
|
else
|
|
for (i = 0; i <= Length; i++) {
|
|
TmpText[i] = toupper(Identity->Password[i]);
|
|
TmpUnicodeText[i] = (WCHAR)(Identity->Password[i]);
|
|
}
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
CalculateLmOwfPassword((PLM_PASSWORD)TmpText, Cache->LmPassword);
|
|
#endif
|
|
|
|
TmpNtPassword.Buffer = TmpUnicodeText;
|
|
TmpNtPassword.Length = Length * sizeof(WCHAR);
|
|
TmpNtPassword.MaximumLength = sizeof(TmpUnicodeText);
|
|
CalculateNtOwfPassword(&TmpNtPassword, Cache->NtPassword);
|
|
|
|
} else
|
|
#endif
|
|
{
|
|
|
|
//
|
|
// In this case the passed-in password is the LM and NT OWF
|
|
// passwords concatenated together.
|
|
//
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
_fmemcpy(Cache->LmPassword, Identity->Password, sizeof(LM_OWF_PASSWORD));
|
|
#endif
|
|
_fmemcpy(Cache->NtPassword, Identity->Password + sizeof(LM_OWF_PASSWORD), sizeof(NT_OWF_PASSWORD));
|
|
|
|
}
|
|
|
|
}
|
|
|
|
// Copy the credentials for the caller.
|
|
Credential->Username = (PCHAR)SspAlloc(_fstrlen(Cache->Username) + 1);
|
|
if (Credential->Username == NULL) {
|
|
goto out_failure;
|
|
}
|
|
_fstrcpy(Credential->Username, Cache->Username);
|
|
|
|
if (_fstrcmp(Cache->Domain, "WORKGROUP") != 0) {
|
|
Credential->Domain = (PCHAR)SspAlloc(_fstrlen(Cache->Domain) + 1);
|
|
if (Credential->Domain == NULL) {
|
|
goto out_failure;
|
|
}
|
|
_fstrcpy(Credential->Domain, Cache->Domain);
|
|
}
|
|
|
|
Credential->Workstation = (PCHAR)SspAlloc(_fstrlen(Cache->Workstation) + 1);
|
|
if (Credential->Workstation == NULL) {
|
|
goto out_failure;
|
|
}
|
|
_fstrcpy(Credential->Workstation, Cache->Workstation);
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
Credential->LmPassword = SspAlloc(sizeof(LM_OWF_PASSWORD));
|
|
if (Credential->LmPassword == NULL) {
|
|
goto out_failure;
|
|
}
|
|
_fmemcpy(Credential->LmPassword, Cache->LmPassword, sizeof(LM_OWF_PASSWORD));
|
|
#endif
|
|
|
|
Credential->NtPassword = (LM_OWF_PASSWORD*)SspAlloc(sizeof(NT_OWF_PASSWORD));
|
|
if (Credential->NtPassword == NULL) {
|
|
goto out_failure;
|
|
}
|
|
_fmemcpy(Credential->NtPassword, Cache->NtPassword, sizeof(NT_OWF_PASSWORD));
|
|
|
|
return (SEC_E_OK);
|
|
|
|
cache_failure:
|
|
|
|
if (Cache->Username != NULL) {
|
|
SspFree(Cache->Username);
|
|
}
|
|
|
|
if (Cache->Domain != NULL) {
|
|
SspFree(Cache->Domain);
|
|
}
|
|
|
|
if (Cache->Workstation != NULL) {
|
|
SspFree(Cache->Workstation);
|
|
}
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
if (Cache->LmPassword != NULL) {
|
|
SspFree(Cache->LmPassword);
|
|
}
|
|
#endif
|
|
|
|
if (Cache->NtPassword != NULL) {
|
|
SspFree(Cache->NtPassword);
|
|
}
|
|
|
|
SspFree(Cache);
|
|
Cache = NULL;
|
|
|
|
out_failure:
|
|
|
|
if (Credential->Username != NULL) {
|
|
SspFree(Credential->Username);
|
|
Credential->Username = NULL;
|
|
}
|
|
|
|
if (Credential->Domain != NULL) {
|
|
SspFree(Credential->Domain);
|
|
Credential->Domain = NULL;
|
|
}
|
|
|
|
if (Credential->Workstation != NULL) {
|
|
SspFree(Credential->Workstation);
|
|
Credential->Workstation = NULL;
|
|
}
|
|
|
|
#ifdef BL_USE_LM_PASSWORD
|
|
if (Credential->LmPassword != NULL) {
|
|
SspFree(Credential->LmPassword);
|
|
Credential->LmPassword = NULL;
|
|
}
|
|
#endif
|
|
|
|
if (Credential->NtPassword != NULL) {
|
|
SspFree(Credential->NtPassword);
|
|
Credential->NtPassword = NULL;
|
|
}
|
|
|
|
return (SEC_E_INSUFFICIENT_MEMORY);
|
|
}
|
|
|
|
|