diff --git a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj index c61e2963..c588715a 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj +++ b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj @@ -1,4 +1,4 @@ - + @@ -403,6 +403,7 @@ + diff --git a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters index 9b6364c0..85a09b0c 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters +++ b/MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters @@ -1,4 +1,4 @@ - + @@ -45,6 +45,9 @@ Resource Files + + Header Files + diff --git a/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj b/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj index 2ce0f510..fdc341c1 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj +++ b/MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj @@ -355,6 +355,9 @@ xcopy /Y ..\..\..\..\Sources\Plasma\Apps\plClient\external\resource.dat ..\..\.. + + diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/loginfix.h b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/loginfix.h new file mode 100644 index 00000000..47bb7130 --- /dev/null +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/loginfix.h @@ -0,0 +1,91 @@ +/*==LICENSE==* + +CyanWorlds.com Engine - MMOG client, server and tools +Copyright (C) 2011 Cyan Worlds, Inc. + +This program is free software: you can redistribute it and/or modify +it under the terms of the GNU General Public License as published by +the Free Software Foundation, either version 3 of the License, or +(at your option) any later version. + +This program is distributed in the hope that it will be useful, +but WITHOUT ANY WARRANTY; without even the implied warranty of +MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the +GNU General Public License for more details. + +You should have received a copy of the GNU General Public License +along with this program. If not, see . + +Additional permissions under GNU GPL version 3 section 7 + +If you modify this Program, or any covered work, by linking or +combining it with any of RAD Game Tools Bink SDK, Autodesk 3ds Max SDK, +NVIDIA PhysX SDK, Microsoft DirectX SDK, OpenSSL library, Independent +JPEG Group JPEG library, Microsoft Windows Media SDK, or Apple QuickTime SDK +(or a modified version of those libraries), +containing parts covered by the terms of the Bink SDK EULA, 3ds Max EULA, +PhysX SDK EULA, DirectX SDK EULA, OpenSSL and SSLeay licenses, IJG +JPEG Library README, Windows Media SDK EULA, or QuickTime SDK EULA, the +licensors of this Program grant you additional +permission to convey the resulting work. Corresponding Source for a +non-source form of such a combination shall include the source code for +the parts of OpenSSL and IJG JPEG Library used as well as that of the covered +work. + +You can contact Cyan Worlds, Inc. by email legal@cyan.com + or by snail mail at: + Cyan Worlds, Inc. + 14617 N Newport Hwy + Mead, WA 99021 + +*==LICENSE==*/ + +//////////////////////////////////////////////////////////////////////////////// +// The stuff below seems to be missing fron WinIoCtl.h in MSVC2003 but is +// probably present in later versions. This was robbed from MSDN to fill +// the gap. + +#if (_MSC_VER < 1500) // For VS2005 and earlier only (might need to make it VS2003 only (1310)) + +#define IOCTL_STORAGE_QUERY_PROPERTY CTL_CODE(IOCTL_STORAGE_BASE, 0x0500, METHOD_BUFFERED, FILE_ANY_ACCESS) + + // retrieve the storage device descriptor data for a device. + typedef struct _STORAGE_DEVICE_DESCRIPTOR { + ULONG Version; + ULONG Size; + UCHAR DeviceType; + UCHAR DeviceTypeModifier; + BOOLEAN RemovableMedia; + BOOLEAN CommandQueueing; + ULONG VendorIdOffset; + ULONG ProductIdOffset; + ULONG ProductRevisionOffset; + ULONG SerialNumberOffset; + STORAGE_BUS_TYPE BusType; + ULONG RawPropertiesLength; + UCHAR RawDeviceProperties[1]; + } STORAGE_DEVICE_DESCRIPTOR, *PSTORAGE_DEVICE_DESCRIPTOR; + + // retrieve the properties of a storage device or adapter. + typedef enum _STORAGE_QUERY_TYPE { + PropertyStandardQuery = 0, + PropertyExistsQuery, + PropertyMaskQuery, + PropertyQueryMaxDefined + } STORAGE_QUERY_TYPE, *PSTORAGE_QUERY_TYPE; + + // retrieve the properties of a storage device or adapter. + typedef enum _STORAGE_PROPERTY_ID { + StorageDeviceProperty = 0, + StorageAdapterProperty, + StorageDeviceIdProperty + } STORAGE_PROPERTY_ID, *PSTORAGE_PROPERTY_ID; + + // retrieve the properties of a storage device or adapter. + typedef struct _STORAGE_PROPERTY_QUERY { + STORAGE_PROPERTY_ID PropertyId; + STORAGE_QUERY_TYPE QueryType; + UCHAR AdditionalParameters[1]; + } STORAGE_PROPERTY_QUERY, *PSTORAGE_PROPERTY_QUERY; +#endif +// End of stuff taken from MSDN diff --git a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp index fe7fb7c1..deff9485 100644 --- a/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp +++ b/MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp @@ -76,6 +76,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #include #include "WinHttp.h" +#include "loginfix.h" // // Defines // @@ -93,6 +94,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com #define STATUS_PATH L"support.cyanworlds.com" #endif + // // Globals // @@ -200,6 +202,8 @@ struct LoginDialogParam { bool AuthenticateNetClientComm(ENetError* result, HWND parentWnd); bool IsExpired(); +bool GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc); +void GetOldCryptKey(UInt32* cryptKey, unsigned size); void GetCryptKey(UInt32* cryptKey, unsigned size); static void SaveUserPass (char *username, char *password, ShaDigest *pNamePassHash, bool remember_password, bool fromGT); @@ -1155,10 +1159,15 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p UInt32 cryptKey[4]; ZeroMemory(cryptKey, sizeof(cryptKey)); GetCryptKey(cryptKey, arrsize(cryptKey)); + UInt32 cryptKeyOld[4]; // The old cryptKey stuff + ZeroMemory(cryptKeyOld, sizeof(cryptKeyOld)); + GetOldCryptKey(cryptKeyOld, arrsize(cryptKeyOld)); char* temp; *pRemember = false; username[0] = '\0'; + bool cryptKeyOk = false; + bool cryptKeyOldOk = false; if (!fromGT) { @@ -1186,6 +1195,42 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p { StrCopy(username, temp, kMaxAccountNameLength); delete temp; + cryptKeyOk = true; + } + else + username[0] = '\0'; + + *pRemember = stream->Readbool(); + + if (*pRemember) + { + stream->Read(sizeof(pNamePassHash->data), pNamePassHash->data); + *pFocus = IDOK; + } + else + *pFocus = IDC_URULOGIN_PASSWORD; + } + + stream->Close(); + delete stream; + } + if (!cryptKeyOk) // Try the old cryptKey + { + hsStream* stream = plEncryptedStream::OpenEncryptedFile(fileAndPath, true, cryptKeyOld); + if (stream && !stream->AtEnd()) + { + UInt32 savedKey[4]; + stream->Read(sizeof(savedKey), savedKey); + + if (memcmp(cryptKeyOld, savedKey, sizeof(savedKey)) == 0) + { + temp = stream->ReadSafeString(); + + if (temp) + { + StrCopy(username, temp, kMaxAccountNameLength); + delete temp; + cryptKeyOldOk = true; } else username[0] = '\0'; @@ -1203,6 +1248,21 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p stream->Close(); delete stream; + } // Done trying the old cryptKey + } + if (cryptKeyOldOk) // We need to re-write the login.dat file + { + hsStream* stream = plEncryptedStream::OpenEncryptedFileWrite(fileAndPath, cryptKey); + if (stream) + { + stream->Write(sizeof(cryptKey), cryptKey); + stream->WriteSafeString(username); + stream->Writebool(*pRemember); + if (*pRemember) + stream->Write(sizeof(pNamePassHash->data), pNamePassHash->data); + stream->Close(); + delete stream; + } } } else @@ -2017,7 +2077,7 @@ bool IsExpired() return expired; } -void GetCryptKey(UInt32* cryptKey, unsigned numElements) +void GetOldCryptKey(UInt32* cryptKey, unsigned numElements) { char volName[] = "C:\\"; int index = 0; @@ -2048,3 +2108,99 @@ void GetCryptKey(UInt32* cryptKey, unsigned numElements) } } +void GetCryptKey(UInt32* cryptKey, unsigned numElements) +{ + char volName[] = "C:\\"; + char volID[] = "\\\\.\\C:"; // Need the drive ID in \\.\C: format for CreateFile() + int index = 0; + DWORD logicalDrives = GetLogicalDrives(); + PSTORAGE_DEVICE_DESCRIPTOR pDevDesc; + + for (int i = 2; i < 26; ++i) // Drives A: B: prove nothing + { + if (logicalDrives & (1 << i)) + { + volName[0] = ('A' + i); // Previous base drive letter of C: was incorrect + + UINT driveType = GetDriveType( + volName //LPCTSTR lpRootPathName + ); + + if (driveType != DRIVE_FIXED) + { + continue; // next i + } + + // We've got "Fixed" drive but still need to check + // that it's not a USB (i.e. removable) drive. + HANDLE hDevice; + volID[4] = 'A' + i; + hDevice = CreateFile( + volID, + GENERIC_READ, + FILE_SHARE_READ | FILE_SHARE_WRITE, + NULL, + OPEN_EXISTING, + NULL, + NULL + ); + + if (hDevice != INVALID_HANDLE_VALUE) + { + pDevDesc = (PSTORAGE_DEVICE_DESCRIPTOR)new BYTE[sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1]; + if(pDevDesc != NULL) + { + pDevDesc->Size = sizeof(STORAGE_DEVICE_DESCRIPTOR) + 512 - 1; + + if (GetDisksProperty(hDevice, pDevDesc)) + { + if (pDevDesc->BusType == BusTypeUsb) // This is the ‘Check Point’!!! ;-) + continue; // next i + } + delete pDevDesc; + CloseHandle(hDevice); + } + } + + DWORD volSerialNum = 0; + BOOL result = GetVolumeInformation( + volName, //LPCTSTR lpRootPathName, + NULL, //LPTSTR lpVolumeNameBuffer, + 0, //DWORD nVolumeNameSize, + &volSerialNum, //LPDWORD lpVolumeSerialNumber, + NULL, //LPDWORD lpMaximumComponentLength, + NULL, //LPDWORD lpFileSystemFlags, + NULL, //LPTSTR lpFileSystemNameBuffer, + 0 //DWORD nFileSystemNameSize + ); + + if (!result) + continue; // next i + + cryptKey[index] = (cryptKey[index] ^ volSerialNum); + index = (++index) % numElements; + } + } +} + +bool GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc) +{ + STORAGE_PROPERTY_QUERY Query; // input param for query + DWORD dwOutBytes; // IOCTL output length + BOOL bResult; // IOCTL return val + + // specify the query type + Query.PropertyId = StorageDeviceProperty; + Query.QueryType = PropertyStandardQuery; + + // Query using IOCTL_STORAGE_QUERY_PROPERTY + bResult = ::DeviceIoControl(hDevice, // device handle + IOCTL_STORAGE_QUERY_PROPERTY, // info of device property + &Query, sizeof(STORAGE_PROPERTY_QUERY), // input data buffer + pDevDesc, pDevDesc->Size, // output data buffer + &dwOutBytes, // out's length + (LPOVERLAPPED)NULL); + + return bResult; +} +