Registriert seit: 10. Okt 2006
Ort: 's-Hertogenbosch, Die Niederlande
222 Beiträge
RAD-Studio 2010 Arc
|
Re: Password hash in RDP files
29. Mär 2007, 10:59
Yes I should have noticed you used CamelCase. I will test with my Delphi version ( BDS 2006) and confirm, I'm assuming you're right and the documentation is wrong. As for the SHR thing I copy/pasted this from http://www.delphibasics.co.uk/RTL.asp?Name=Shr.
Personally I do think using shr is clever and probably faster than div.
http://www.merlyn.demon.co.uk/del-bits.htm:
Zitat:
The basic Delphi operations are shl and shr, apparently on the unsigned bit patterns. One can also use *2 and div 2 which should treat the sign of the value arithmetically.
Be careful about possible unexpected (or needed) behaviour of the leftmost bit on a shift right, or vice versa; it appears ill-defined, and may (or perhaps should) depend on whether the type is signed.
Consider that a variable of a small type, such as a shortint, may be extended before the operation is carried out. Check, in particular, what happens with shr and div on a negative value.
I conclude that shr is allright with positive values, therefore fine in this solution.
Not really sure what you mean by this sentence: First class function result types are all those types which are intended to be used in an expression.
Something in else (in case anyone finds it usefull):
Below a sample to create an rdp file in UniCode and start a session with it. It uses Rijndael encryption to hide the real password.
To make it secure you should hide the secret and delete the rdp file after connecting.
Delphi-Quellcode:
uses uRDPHash, Windows, JwaWinNt, SysUtils, Classes, shFolder, LbCipher, LbClass;
{$R *.res}
const
BOM_UTF16 = $FEFF; // BOM = Byte Order Mark
var
fs : TFileStream;
BOM : WideString;
sFolder: string;
sRDPFileName: string;
LocalAppData: PAnsiChar;
lpRect: TRect;
Helper: TLbRijndael;
sServer: string;
si: _STARTUPINFOW;
pi: PROCESS_INFORMATION;
pwCmdLine: PWideChar;
pwMsg: PWideChar;
const
SHGFP_TYPE_CURRENT = 0; // current value for user, verify it exists
procedure WriteLnFs( var fs: TFileStream; sLine: String);
var ws: WideString;
begin
ws := WideString(sLine) + WideChar($0D) + WideChar($0A);;
try
fs.WriteBuffer(ws[1], Length(ws) * SizeOf(WideChar));
except
// Handle Exception
end;
end;
begin
// Set folder path
sFolder := ' C:\Temp\gprmc.rdp';
// Try to find LocalAppData folder
GetMem(LocalAppData, MAX_PATH);
if ShGetFolderPath(THandle( nil),
CSIDL_LOCAL_APPDATA,
THandle( nil),
SHGFP_TYPE_CURRENT,
LocalAppData) = S_OK then
begin
// and create GPRMC subfolder
sFolder := String(LocalAppData + ' \GPRMC');
if not DirectoryExists(sFolder) then
begin
MkDir(sFolder);
end;
sRDPFilename := sFolder + ' \GPRMC.rdp';
// Cleanup
FreeMem(LocalAppData);
end
else
begin
MessageBox(0, PAnsiChar(SysErrorMessage(GetLastError)), ' ShGetFolderPath', MB_OK);
end;
sServer := ' SERVER';
// Obfuscate the password key
Helper := TLbRijndael.Create( nil);
Helper.CipherMode := cmECB;
Helper.KeySize := ks128;
Helper.GenerateKey(' The Secret Key Which you should hide somewhere');
// Get Screen Width and Height
GetWindowRect(GetDesktopWindow, lpRect);
// RDP Unicode Byte Order Mark (BOM)
BOM := Widechar(BOM_UTF16);
// Create RDP File
fs := TFileStream.Create(sRDPFileName, fmCreate);
// Write BOM
fs.WriteBuffer(BOM[1], Length(BOM)*sizeof(Widechar));
// Write RDP file
WriteLnFs(fs, ' screen mode id:i:1');
WriteLnFs(fs, Format(' desktopwidth:i:%d', [lpRect.Right]));
WriteLnFs(fs, Format(' desktopheight:i:%d', [lpRect.Bottom - 50]));
WriteLnFs(fs, ' session bpp:i:16');
WriteLnFs(fs, ' winposstr:s:2,3,247,0,1055,627');
WriteLnFs(fs, Format(' full address:s:%s', [sServer]));
WriteLnFs(fs, ' compression:i:1');
WriteLnFs(fs, ' keyboardhook:i:2');
WriteLnFs(fs, ' audiomode:i:2');
WriteLnFs(fs, ' redirectdrives:i:0');
WriteLnFs(fs, ' redirectprinters:i:0');
WriteLnFs(fs, ' redirectcomports:i:0');
WriteLnFs(fs, ' redirectsmartcards:i:0');
WriteLnFs(fs, ' displayconnectionbar:i:1');
WriteLnFs(fs, ' autoreconnection enabled:i:1');
WriteLnFs(fs, Format(' username:s:%s', [' USERNAME']));
WriteLnFs(fs, Format(' domain:s:%s', [' DOMAIN']));
WriteLnFs(fs, ' password 51:b:' + CryptRdpPassWord(Helper.DecryptString(' GSMZHifunaBaegL6ehnkmw==')));
WriteLnFs(fs, ' disable wallpaper:i:1');
WriteLnFs(fs, ' disable full window drag:i:1');
WriteLnFs(fs, ' disable menu anims:i:1');
WriteLnFs(fs, ' disable themes:i:1');
WriteLnFs(fs, ' disable cursor setting:i:0');
WriteLnFs(fs, ' bitmapcachepersistenable:i:1');
// Cleanup
Helper.Free;
fs.Free;
ZeroMemory(@si, SizeOf(si));
si.cb := SizeOf(si);
si.lpDesktop := nil;
pwCmdLine := PWideChar(WideString(' mstsc.exe ' + ' "' + sRDPFileName + ' "'));
if not CreateProcessW( nil,
pwCmdLine,
nil,
nil,
False,
0,
nil,
nil,
si,
pi) then
begin
pwMsg := PWideChar(WideString(' Failed to start MSTSC.EXE' +#10#13+
SysErrorMessage(GetLastError)));
MessageBoxExW(0,
pwMsg,
' Sample Program',
MB_ICONERROR or MB_OK,
MAKELANGID(LANG_NEUTRAL, SUBLANG_NEUTRAL));
end;
end.
|