349 lines
8 KiB
C
349 lines
8 KiB
C
|
//
|
||
|
// keymigrt.c
|
||
|
//
|
||
|
// Copyright (c) Microsoft Corp, 2000
|
||
|
//
|
||
|
//
|
||
|
#include <nt.h>
|
||
|
#include <ntrtl.h>
|
||
|
#include <nturtl.h>
|
||
|
#include <windows.h>
|
||
|
#include <rpc.h>
|
||
|
|
||
|
#include <shlobj.h>
|
||
|
|
||
|
#include <wincrypt.h>
|
||
|
#define SECURITY_WIN32
|
||
|
#include <security.h>
|
||
|
#include <secext.h>
|
||
|
#include "passrec.h"
|
||
|
|
||
|
#include <stdio.h>
|
||
|
|
||
|
|
||
|
|
||
|
extern BOOL GetUserSid(HANDLE hClientToken,
|
||
|
PSID* ppSid,
|
||
|
DWORD* lpcbSid);
|
||
|
|
||
|
extern DWORD GetLocalSystemToken(HANDLE* phRet);
|
||
|
|
||
|
|
||
|
void Usage();
|
||
|
|
||
|
|
||
|
int __cdecl wmain(int cArg, wchar_t *rgszArg[])
|
||
|
{
|
||
|
|
||
|
DWORD dwBehavior = 0;
|
||
|
DWORD dwError = ERROR_SUCCESS;
|
||
|
HCRYPTPROV hProv = 0;
|
||
|
HANDLE hToken = NULL;
|
||
|
int i;
|
||
|
|
||
|
LPWSTR wszFilename = NULL;
|
||
|
|
||
|
LPWSTR wszPassword = NULL;
|
||
|
|
||
|
BOOL fGenerate = FALSE;
|
||
|
|
||
|
PSID pCurrentSid = NULL;
|
||
|
DWORD cbCurrentSid = 0;
|
||
|
|
||
|
UNICODE_STRING UserName;
|
||
|
UNICODE_STRING Password;
|
||
|
|
||
|
WCHAR UserNameBuffer[MAX_PATH];
|
||
|
|
||
|
PBYTE pbRecoveryPrivate = NULL;
|
||
|
|
||
|
DWORD cbRecoveryPrivate = 0;
|
||
|
HANDLE hPrivate = INVALID_HANDLE_VALUE;
|
||
|
|
||
|
|
||
|
|
||
|
if(cArg < 2)
|
||
|
{
|
||
|
Usage();
|
||
|
}
|
||
|
|
||
|
// Parse command line
|
||
|
|
||
|
for(i=1; i < cArg; i++)
|
||
|
{
|
||
|
LPWSTR szCurrentArg = rgszArg[i];
|
||
|
|
||
|
if((*szCurrentArg != L'-') &&
|
||
|
(*szCurrentArg != L'/'))
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
szCurrentArg++;
|
||
|
|
||
|
while(*szCurrentArg)
|
||
|
{
|
||
|
|
||
|
switch(*szCurrentArg++)
|
||
|
{
|
||
|
case L'n':
|
||
|
case L'N':
|
||
|
if(cArg < i+2)
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
if(*szCurrentArg)
|
||
|
{
|
||
|
if(cArg < i+1)
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
wszFilename = szCurrentArg;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(cArg < i+2)
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
i++;
|
||
|
wszFilename = rgszArg[i];
|
||
|
}
|
||
|
i++;
|
||
|
wszPassword = rgszArg[i];
|
||
|
fGenerate = TRUE;
|
||
|
break;
|
||
|
|
||
|
case L'r':
|
||
|
case L'R':
|
||
|
if(cArg < i+1)
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
if(*szCurrentArg)
|
||
|
{
|
||
|
wszFilename = szCurrentArg;
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
if(cArg < i+1)
|
||
|
{
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
i++;
|
||
|
wszFilename = rgszArg[i];
|
||
|
}
|
||
|
break;
|
||
|
|
||
|
default:
|
||
|
Usage();
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
}
|
||
|
|
||
|
|
||
|
if(fGenerate)
|
||
|
{
|
||
|
|
||
|
|
||
|
ULONG Length = MAX_PATH;
|
||
|
|
||
|
|
||
|
Password.Buffer = wszPassword;
|
||
|
Password.Length = wcslen(wszPassword)*sizeof(WCHAR);
|
||
|
Password.MaximumLength = Password.Length + sizeof(WCHAR);
|
||
|
|
||
|
UserName.Buffer = UserNameBuffer;
|
||
|
UserName.Length = MAX_PATH;
|
||
|
UserName.MaximumLength = MAX_PATH*sizeof(WCHAR);
|
||
|
|
||
|
if(!GetUserNameW(UserNameBuffer, &Length))
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not get user name:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
UserName.Length = (USHORT)Length*sizeof(WCHAR);
|
||
|
|
||
|
|
||
|
if(!GetUserSid(NULL,
|
||
|
&pCurrentSid,
|
||
|
&cbCurrentSid))
|
||
|
{
|
||
|
printf("Could not get user sid:%lx\n", dwError);
|
||
|
dwError = GetLastError();
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
dwError = GetLocalSystemToken(&hToken);
|
||
|
if(ERROR_SUCCESS != dwError)
|
||
|
{
|
||
|
printf("Could not retrieve local system token:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if(!ImpersonateLoggedOnUser(hToken))
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not impersonate local system:%lx\n", dwError);
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
dwError = PRGenerateRecoveryKey(
|
||
|
pCurrentSid,
|
||
|
&UserName,
|
||
|
&Password,
|
||
|
&pbRecoveryPrivate,
|
||
|
&cbRecoveryPrivate);
|
||
|
|
||
|
RevertToSelf();
|
||
|
|
||
|
if(ERROR_SUCCESS != dwError)
|
||
|
{
|
||
|
printf("Could not generate recovery key:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
hPrivate = CreateFileW(wszFilename,
|
||
|
GENERIC_WRITE,
|
||
|
0,
|
||
|
NULL,
|
||
|
CREATE_ALWAYS,
|
||
|
0,
|
||
|
NULL);
|
||
|
if(INVALID_HANDLE_VALUE == hPrivate)
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not open recovery key file:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if(!WriteFile(hPrivate, pbRecoveryPrivate, cbRecoveryPrivate, &cbRecoveryPrivate, NULL))
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not write recovery key file:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
}
|
||
|
else
|
||
|
{
|
||
|
|
||
|
if(!ImpersonateSelf(SecurityImpersonation))
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not impersonate self:%lx\n", dwError);
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
|
||
|
hPrivate = CreateFileW(wszFilename,
|
||
|
GENERIC_READ,
|
||
|
0,
|
||
|
NULL,
|
||
|
OPEN_EXISTING,
|
||
|
0,
|
||
|
NULL);
|
||
|
if(INVALID_HANDLE_VALUE == hPrivate)
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not open recovery key file:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
cbRecoveryPrivate = GetFileSize(hPrivate, NULL);
|
||
|
|
||
|
if(-1 == cbRecoveryPrivate)
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not retrieve recovery key file size:%lx\n", dwError);
|
||
|
goto error;
|
||
|
|
||
|
}
|
||
|
|
||
|
pbRecoveryPrivate = (PBYTE)LocalAlloc(LMEM_FIXED, cbRecoveryPrivate);
|
||
|
|
||
|
if(NULL == pbRecoveryPrivate)
|
||
|
{
|
||
|
dwError = ERROR_NOT_ENOUGH_MEMORY;
|
||
|
printf("Memory allocation failure:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
if(!ReadFile(hPrivate, pbRecoveryPrivate, cbRecoveryPrivate, &cbRecoveryPrivate, NULL))
|
||
|
{
|
||
|
dwError = GetLastError();
|
||
|
printf("Could not read recovery key file:%lx\n", dwError);
|
||
|
goto error;
|
||
|
}
|
||
|
|
||
|
|
||
|
dwError = PRRecoverPassword(
|
||
|
pbRecoveryPrivate,
|
||
|
cbRecoveryPrivate,
|
||
|
&Password);
|
||
|
|
||
|
if(ERROR_SUCCESS == dwError)
|
||
|
{
|
||
|
printf("Recovered Password: %S\n", Password.Buffer);
|
||
|
ZeroMemory(Password.Buffer, Password.MaximumLength);
|
||
|
LocalFree(Password.Buffer);
|
||
|
}
|
||
|
|
||
|
RevertToSelf();
|
||
|
}
|
||
|
|
||
|
|
||
|
error:
|
||
|
|
||
|
if(hToken)
|
||
|
{
|
||
|
CloseHandle(hToken);
|
||
|
}
|
||
|
|
||
|
if(hPrivate != INVALID_HANDLE_VALUE)
|
||
|
{
|
||
|
CloseHandle(hPrivate);
|
||
|
}
|
||
|
if(pbRecoveryPrivate)
|
||
|
{
|
||
|
ZeroMemory(pbRecoveryPrivate, cbRecoveryPrivate);
|
||
|
|
||
|
LocalFree(pbRecoveryPrivate);
|
||
|
}
|
||
|
|
||
|
if(pCurrentSid)
|
||
|
{
|
||
|
LocalFree(pCurrentSid);
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
return (ERROR_SUCCESS == dwError)?0:-1;
|
||
|
|
||
|
}
|
||
|
|
||
|
|
||
|
void Usage()
|
||
|
{
|
||
|
printf("Password Recovery Utility\n");
|
||
|
printf("Usage: passrec -n filename password\n");
|
||
|
printf(" passrec -r filename \n\n");
|
||
|
}
|
||
|
|
||
|
|
||
|
|