Browse Source

Merged in ian_mcintosh/cwe-ou/lostlogins (pull request #33)

Fix for forgotten logins when removable media attached.

Incorporated suggestions from PR #32 which this replaces. Moved CloseHandle as suggested.

Addresses JIRA CWE-37 Corrects incorrect assignment of drive letter to the drive actually being interrogated and ignores removable drive types such as CD/DVD and USB Flash and HDs.

Alternative solution that moves login credentials to the registry is being prepared by Deledrius - H-uru/Plasma PR#448 may be a better long term fix - I'm simply offering what I have.
mdeforest/changed-password-hashing-to-try-sha1-fir-1492090943988
Christian Walther 10 years ago
parent
commit
2abd744ba6
  1. 3
      MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj
  2. 5
      MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters
  3. 3
      MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj
  4. 91
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/loginfix.h
  5. 158
      MOULOpenSourceClientPlugin/Plasma20/Sources/Plasma/Apps/plClient/winmain.cpp

3
MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project DefaultTargets="Build" ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup Label="ProjectConfigurations"> <ItemGroup Label="ProjectConfigurations">
<ProjectConfiguration Include="Debug_Internal|Win32"> <ProjectConfiguration Include="Debug_Internal|Win32">
@ -403,6 +403,7 @@
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\PlClient\plClient.h" /> <ClInclude Include="..\..\..\..\Sources\Plasma\Apps\PlClient\plClient.h" />
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\plClientCreatable.h" /> <ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\plClientCreatable.h" />
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\resource.h" /> <ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\resource.h" />
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\loginfix.h" />
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\banner.bmp" /> <None Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\banner.bmp" />

5
MOULOpenSourceClientPlugin/Plasma20/MSVC10Projects/Plasma/Apps/plClient/plClient.vcxproj.filters

@ -1,4 +1,4 @@
<?xml version="1.0" encoding="utf-8"?> <?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003"> <Project ToolsVersion="4.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<ItemGroup> <ItemGroup>
<Filter Include="Source Files"> <Filter Include="Source Files">
@ -45,6 +45,9 @@
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\resource.h"> <ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\resource.h">
<Filter>Resource Files</Filter> <Filter>Resource Files</Filter>
</ClInclude> </ClInclude>
<ClInclude Include="..\..\..\..\Sources\Plasma\Apps\plClient\loginfix.h">
<Filter>Header Files</Filter>
</ClInclude>
</ItemGroup> </ItemGroup>
<ItemGroup> <ItemGroup>
<None Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\banner.bmp"> <None Include="..\..\..\..\Sources\Plasma\Apps\plClient\res\banner.bmp">

3
MOULOpenSourceClientPlugin/Plasma20/MsDevProjects/Plasma/Apps/plClient/plClient.vcproj

@ -353,6 +353,9 @@ xcopy /Y ..\..\..\..\Sources\Plasma\Apps\plClient\external\resource.dat ..\..\..
<File <File
RelativePath="..\..\..\..\Sources\Plasma\Apps\plClient\plClientUpdateFormat.h"> RelativePath="..\..\..\..\Sources\Plasma\Apps\plClient\plClientUpdateFormat.h">
</File> </File>
<File
RelativePath="..\..\..\..\Sources\Plasma\Apps\PlClient\loginfix.h">
</File>
<File <File
RelativePath="..\..\..\..\Sources\Tools\MaxSceneViewer\plPluginClient.h"> RelativePath="..\..\..\..\Sources\Tools\MaxSceneViewer\plPluginClient.h">
</File> </File>

91
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 <http://www.gnu.org/licenses/>.
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

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

@ -76,6 +76,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#include <shellapi.h> #include <shellapi.h>
#include "WinHttp.h" #include "WinHttp.h"
#include "loginfix.h"
// //
// Defines // Defines
// //
@ -93,6 +94,7 @@ You can contact Cyan Worlds, Inc. by email legal@cyan.com
#define STATUS_PATH L"support.cyanworlds.com" #define STATUS_PATH L"support.cyanworlds.com"
#endif #endif
// //
// Globals // Globals
// //
@ -200,6 +202,8 @@ struct LoginDialogParam {
bool AuthenticateNetClientComm(ENetError* result, HWND parentWnd); bool AuthenticateNetClientComm(ENetError* result, HWND parentWnd);
bool IsExpired(); bool IsExpired();
bool GetDisksProperty(HANDLE hDevice, PSTORAGE_DEVICE_DESCRIPTOR pDevDesc);
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); bool fromGT);
@ -1155,10 +1159,15 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p
UInt32 cryptKey[4]; UInt32 cryptKey[4];
ZeroMemory(cryptKey, sizeof(cryptKey)); ZeroMemory(cryptKey, sizeof(cryptKey));
GetCryptKey(cryptKey, arrsize(cryptKey)); GetCryptKey(cryptKey, arrsize(cryptKey));
UInt32 cryptKeyOld[4]; // The old cryptKey stuff
ZeroMemory(cryptKeyOld, sizeof(cryptKeyOld));
GetOldCryptKey(cryptKeyOld, arrsize(cryptKeyOld));
char* temp; char* temp;
*pRemember = false; *pRemember = false;
username[0] = '\0'; username[0] = '\0';
bool cryptKeyOk = false;
bool cryptKeyOldOk = false;
if (!fromGT) if (!fromGT)
{ {
@ -1186,6 +1195,7 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p
{ {
StrCopy(username, temp, kMaxAccountNameLength); StrCopy(username, temp, kMaxAccountNameLength);
delete temp; delete temp;
cryptKeyOk = true;
} }
else else
username[0] = '\0'; username[0] = '\0';
@ -1204,6 +1214,56 @@ static void LoadUserPass (const wchar *accountName, char *username, ShaDigest *p
stream->Close(); stream->Close();
delete stream; 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';
*pRemember = stream->Readbool();
if (*pRemember)
{
stream->Read(sizeof(pNamePassHash->data), pNamePassHash->data);
*pFocus = IDOK;
}
else
*pFocus = IDC_URULOGIN_PASSWORD;
}
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 else
{ {
@ -2021,7 +2081,7 @@ bool IsExpired()
return expired; return expired;
} }
void GetCryptKey(UInt32* cryptKey, unsigned numElements) void GetOldCryptKey(UInt32* cryptKey, unsigned numElements)
{ {
char volName[] = "C:\\"; char volName[] = "C:\\";
int index = 0; int index = 0;
@ -2052,3 +2112,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;
}

Loading…
Cancel
Save