// // keymigrt.c // // Copyright (c) Microsoft Corp, 2000 // // #include #include #include #include #include #include #include #define SECURITY_WIN32 #include #include #include "passrec.h" #include 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"); }