Browse Source

Merged branch to PR #42 including login hash from mdeforest

rarified/gameserverportfix
rarified 6 years ago
parent
commit
0d518e3465
  1. 130
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp

130
MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp

@ -200,13 +200,25 @@ struct LoginDialogParam {
wchar accountName[kMaxAccountNameLength]; wchar accountName[kMaxAccountNameLength];
}; };
// List of hash styles we are going to test against the server
// ... this method of trying multiple hashes against the server has risks of being more compromised than just testing one hash.
// ... So, if you know your unique client is only going to connect to your server then it would be wise to limit the testing to one hash.
// ... Which can be done simply by setting FIRST_PASSWORD_HASH and LAST_PASSWORD_HASH to the hash that you use.
enum
{
kPasswordHashSHA0,
kPasswordHashSHA1
};
static const int FIRST_PASSWORD_HASH = kPasswordHashSHA1;
static const int LAST_PASSWORD_HASH = kPasswordHashSHA0;
bool AuthenticateNetClientComm(ENetError* result, HWND parentWnd); bool AuthenticateNetClientComm(ENetError* result, HWND parentWnd);
bool IsExpired(); bool IsExpired();
bool GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc); bool GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc);
void GetOldCryptKey(UInt32* cryptKey, unsigned size); void GetOldCryptKey(UInt32* cryptKey, unsigned size);
void GetCryptKey(UInt32* cryptKey, unsigned size); void GetCryptKey(UInt32* cryptKey, unsigned size);
static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHash, bool remember_password, static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHash, bool remember_password,
bool fromGT); int whichHash);
static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *pNamePassHash, bool *pRemember, static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *pNamePassHash, bool *pRemember,
bool fromGT, int *pFocus); bool fromGT, int *pFocus);
static void AuthFailedStrings (ENetError authError, bool fromGT, static void AuthFailedStrings (ENetError authError, bool fromGT,
@ -322,11 +334,22 @@ static bool TGRunLoginDialog (const wchar *accountName, bool fromGT)
if (Remember[0] == 'y') if (Remember[0] == 'y')
bRemember = true; bRemember = true;
SaveUserPass (Username, Password, &NamePassHash, bRemember, fromGT); // cycle through the hash types until we find one that matches or errors out
// Do login & see if it failed
ENetError auth; ENetError auth;
bool cancelled = AuthenticateNetClientComm(&auth, NULL); bool cancelled;
for (int whichHash=FIRST_PASSWORD_HASH; whichHash >= LAST_PASSWORD_HASH; whichHash-- )
{
SaveUserPass (Username, Password, &NamePassHash, bRemember, whichHash);
// Do login & see if it failed
cancelled = AuthenticateNetClientComm(&auth, NULL);
// if the password was successful then go to the end processing
if (IS_NET_SUCCESS(auth) && !cancelled)
break;
// if it was cancelled or any error other than wrong password then go to end processing
if (cancelled || auth != kNetErrAuthenticationFailed)
break;
}
if (IS_NET_SUCCESS (auth) && !cancelled) if (IS_NET_SUCCESS (auth) && !cancelled)
break; break;
@ -933,18 +956,6 @@ void DebugMsgF(const char* format, ...)
#endif #endif
} }
static bool IsMachineLittleEndian() {
int i = 1;
char *p = (char *) &i;
if (p[0] == 1) // Lowest address contains the least significant byte
return true;
else
return false;
}
inline static dword ToBigEndian (dword value) {
return ((value) << 24) | ((value & 0x0000ff00) << 8) | ((value & 0x00ff0000) >> 8) | ((value) >> 24);
}
static void AuthFailedStrings (ENetError authError, bool fromGT, static void AuthFailedStrings (ENetError authError, bool fromGT,
const char **ppStr1, const char **ppStr2, const char **ppStr1, const char **ppStr2,
@ -1081,7 +1092,7 @@ BOOL CALLBACK UruTOSDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM l
} }
static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHash, bool remember_password, static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHash, bool remember_password,
bool fromGT) int whichHash)
{ {
UInt32 cryptKey[4]; UInt32 cryptKey[4];
ZeroMemory(cryptKey, sizeof(cryptKey)); ZeroMemory(cryptKey, sizeof(cryptKey));
@ -1097,7 +1108,31 @@ static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHa
if (StrCmp(password, FAKE_PASS_STRING) != 0) if (StrCmp(password, FAKE_PASS_STRING) != 0)
{ {
StrToUnicode(wpassword, password, arrsize(wpassword)); StrToUnicode(wpassword, password, arrsize(wpassword));
CryptHashPassword(wusername, wpassword, pNamePassHash);
switch( whichHash )
{
case kPasswordHashSHA1:
CryptDigest(
kCryptSha1,
pNamePassHash,
StrLen(password) * sizeof(password[0]),
password
);
// switch the endianness of the hash to big endian
// NOTE: this is legacy from GameTap days to match GameTap's endianness
pNamePassHash->data[0] = hsUNSWAP32(pNamePassHash->data[0]);
pNamePassHash->data[1] = hsUNSWAP32(pNamePassHash->data[1]);
pNamePassHash->data[2] = hsUNSWAP32(pNamePassHash->data[2]);
pNamePassHash->data[3] = hsUNSWAP32(pNamePassHash->data[3]);
pNamePassHash->data[4] = hsUNSWAP32(pNamePassHash->data[4]);
break;
case kPasswordHashSHA0:
default:
CryptHashPassword(wusername, wpassword, pNamePassHash);
break;
}
} }
NetCommSetAccountUsernamePassword(wusername, *pNamePassHash); NetCommSetAccountUsernamePassword(wusername, *pNamePassHash);
@ -1106,28 +1141,26 @@ static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHa
else else
NetCommSetAuthTokenAndOS(nil, L"win"); NetCommSetAuthTokenAndOS(nil, L"win");
if (!fromGT) { wchar fileAndPath[MAX_PATH];
wchar fileAndPath[MAX_PATH]; PathGetInitDirectory(fileAndPath, arrsize(fileAndPath));
PathGetInitDirectory(fileAndPath, arrsize(fileAndPath)); PathAddFilename(fileAndPath, fileAndPath, L"login.dat", arrsize(fileAndPath));
PathAddFilename(fileAndPath, fileAndPath, L"login.dat", arrsize(fileAndPath));
#ifndef PLASMA_EXTERNAL_RELEASE #ifndef PLASMA_EXTERNAL_RELEASE
// internal builds can use the local init directory // internal builds can use the local init directory
wchar localFileAndPath[MAX_PATH]; wchar localFileAndPath[MAX_PATH];
StrCopy(localFileAndPath, L"init\\login.dat", arrsize(localFileAndPath)); StrCopy(localFileAndPath, L"init\\login.dat", arrsize(localFileAndPath));
if (PathDoesFileExist(localFileAndPath)) if (PathDoesFileExist(localFileAndPath))
StrCopy(fileAndPath, localFileAndPath, arrsize(localFileAndPath)); StrCopy(fileAndPath, localFileAndPath, arrsize(localFileAndPath));
#endif #endif
hsStream* stream = plEncryptedStream::OpenEncryptedFileWrite(fileAndPath, cryptKey); hsStream* stream = plEncryptedStream::OpenEncryptedFileWrite(fileAndPath, cryptKey);
if (stream) if (stream)
{ {
stream->Write(sizeof(cryptKey), cryptKey); stream->Write(sizeof(cryptKey), cryptKey);
stream->WriteSafeString(username); stream->WriteSafeString(username);
stream->Writebool(remember_password); stream->Writebool(remember_password);
if (remember_password) if (remember_password)
stream->Write(sizeof(pNamePassHash->data), pNamePassHash->data); stream->Write(sizeof(pNamePassHash->data), pNamePassHash->data);
stream->Close(); stream->Close();
delete stream; delete stream;
}
} }
} }
@ -1418,11 +1451,22 @@ BOOL CALLBACK UruLoginDialogProc( HWND hwndDlg, UINT uMsg, WPARAM wParam, LPARAM
GetDlgItemText(hwndDlg, IDC_URULOGIN_PASSWORD, password, kMaxPasswordLength); GetDlgItemText(hwndDlg, IDC_URULOGIN_PASSWORD, password, kMaxPasswordLength);
remember_password = (IsDlgButtonChecked(hwndDlg, IDC_URULOGIN_REMEMBERPASS) == BST_CHECKED); remember_password = (IsDlgButtonChecked(hwndDlg, IDC_URULOGIN_REMEMBERPASS) == BST_CHECKED);
SaveUserPass (username, password, &namePassHash, remember_password, loginParam->fromGT); // cycle through the hash types until we find one that matches or errors out
LoginDialogParam loginParam; LoginDialogParam loginParam;
MemSet(&loginParam, 0, sizeof(loginParam)); bool cancelled;
bool cancelled = AuthenticateNetClientComm(&loginParam.authError, hwndDlg); for (int whichHash=FIRST_PASSWORD_HASH; whichHash >= LAST_PASSWORD_HASH; whichHash-- )
{
SaveUserPass (username, password, &namePassHash, remember_password, whichHash);
MemSet(&loginParam, 0, sizeof(loginParam));
cancelled = AuthenticateNetClientComm(&loginParam.authError, hwndDlg);
// if the password was successful then go to the end processing
if (IS_NET_SUCCESS(loginParam.authError) && !cancelled)
break;
// if it was cancelled or any error other than wrong password then go to end processing
if (cancelled || loginParam.authError != kNetErrAuthenticationFailed)
break;
}
if (IS_NET_SUCCESS(loginParam.authError) && !cancelled) if (IS_NET_SUCCESS(loginParam.authError) && !cancelled)
EndDialog(hwndDlg, ok); EndDialog(hwndDlg, ok);

Loading…
Cancel
Save