DWORD dwTickBegin = GetTickCount(); while (GetTickCount() < dwTickBegin + 5000) Sleep(100);
#define __STDSTRING #include <string> #include <stdio.h> #include <windows.h> using namespace std; int main(int argc, char* argv[]) { DWORD tick_begin, tick_end; tick_begin = GetTickCount(); #ifdef __STDSTRING string dest; string src("test1"); for (int x = 0; x < 100000; x++) dest = src + "test2"; #else char* dest = (char*)malloc(1024); memset(dest, 0, 1024); char* src = "test1"; for (int x = 0; x < 100000; x++) { memset(dest, 0, 1024); strcat(dest, (char*)&src); strcat(dest, "test2"); } free(dest); #endif tick_end = GetTickCount(); printf("100000 additions in %u msec (%u, %u) -- %.5f per add\n", tick_end - tick_begin, tick_begin, tick_end, (tick_end - tick_begin) / 100000.0); return (0); }
' WinAPI structures Private Type ACL AclRevision As Byte Sbz1 As Byte AclSize As Integer AceCount As Integer Sbz2 As Integer End Type Private Type SECURITY_DESCRIPTOR Revision As Byte Sbz1 As Byte Control As Long Owner As Long Group As Long Sacl As ACL Dacl As ACL End Type Private Type SECURITY_ATTRIBUTES nLength As Long lpSecurityDescriptor As Long bInheritHandle As Long End Type ' WinAPI constants Private Const MUTEX_ALL_ACCESS = 2031617 Private Const SECURITY_DESCRIPTOR_REVISION = (1) ' Mutex related WinAPI imports Private Declare Function CreateMutex Lib "kernel32" Alias "CreateMutexA" (lpMutexAttributes As SECURITY_ATTRIBUTES, ByVal bInitialOwner As Long, ByVal lpName As String) As Long Private Declare Function OpenMutex Lib "kernel32" Alias "OpenMutexA" (ByVal dwDesiredAccess As Long, ByVal bInheritHandle As Long, ByVal lpName As String) As Long Private Declare Function InitializeSecurityDescriptor Lib "advapi32.dll" (pSecurityDescriptor As SECURITY_DESCRIPTOR, ByVal dwRevision As Long) As Long Private Declare Function SetSecurityDescriptorDacl Lib "advapi32.dll" (pSecurityDescriptor As SECURITY_DESCRIPTOR, ByVal bDaclPresent As Long, pDacl As Long, ByVal bDaclDefaulted As Long) As Long ... Dim MutexHandle As Long ... ' Opening mutex with NULL DACL MutexHandle = OpenMutex(MUTEX_ALL_ACCESS, 0, "VBMUTEX05") If MutexHandle = 0 Then Select Case Err.LastDllError Case 2& ' Preparation of NULL SECURITY_DESCRIPTOR Dim MutexAtts As SECURITY_ATTRIBUTES MutexAtts.bInheritHandle = False MutexAtts.nLength = Len(MutexAtts) Dim SecDesc As SECURITY_DESCRIPTOR Dim SecInitRes As Boolean SecInitRes = InitializeSecurityDescriptor(SecDesc, _ SECURITY_DESCRIPTOR_REVISION) If Not SecInitRes Then ' ERROR initializing SD Exit Sub End If Dim SetSDRes As Boolean SetSDRes = SetSecurityDescriptorDacl(SecDesc, _ True, ByVal 0&, False) If Not SetSDRes Then ' ERROR creating DACL-SD Exit Sub End If MutexAtts.lpSecurityDescriptor = VarPtr(SecDesc) ' Creating the mutex with NULL DACL MutexHandle = CreateMutex(ByVal MutexAtts, 0, "VBMUTEX05") Case Else ' ERROR: Unknown Exit Sub End Select End If ' SUCCESS ...
BEGIN TRAN [SQL_QUERY ktoru chceme zanalyzovat] EXEC sp_lock SELECT object_name([ID z vysledku ObjID volania sp_lock]) UNION [dalsie objectnames]...; COMMIT
BEGIN TRAN UPDATE J ... UPDATE V ... UPDATE V ... ... UPDATE V ... COMMIT
SELECT COUNT(*) from J ...
SELECT count(*) from J (NOLOCK) where ...
SELECT count(*) from J (READPAST) where ...
Základný problém prihlasovania sa cez http protokol (pri absencii https), prípadne pri prihlasovaní sa na služby tretích strán, je možnosť odchytenia plaintext hesla, či už na strane poskytovateľa internetového pripojenia (prípadne na trase od klienta na server), alebo priamo na serveri zo strany implementátora služby.
Riešením by bolo, neprenášať heslo v plaintext tvare a tým zamedziť uloženiu a následnému zneužitiu hesla.
CramMD5 autentifikácia je založená na predspracovaní hesla na strane klientskej stanice. Základom je skriptovací jazyk (najčastejšie použitý JavaScript), ktorý vytvorí na základe vstupných dát poskytnutých serverom MD5 hash, ktorý sa použije na porovnanie hesla na strane serveru. Tento hash sa potom prenesie v plaintext forme nezašifrovanou linkou a tým zamedzí odchyteniu plaintext hesla. Takýto hash je potom v závislosti na implementácii platný pre dané spojenie, prípadne obmedzený aj špecificky na IP adresu.
Riešenie CramMD5 autentifikácie sa skladá z klientskej a serverovej časti.
V prípade, že nie je používateľ autentifikovaný, zobrazuje sa – ako v každej klasickej webovej aplikácii – prihlasovací formulár. V prípade CramMD5 autentifikácie je rozšírený o niekoľko skriptov a skryté polia, obsahujúce kontrolné informácie. (Ako konkrétne príklady implementácie použijem zdrojový kód demonštrácie sociálnych sietí.)
<form action="" method="POST" onSubmit="return (SecOnSubmit())"> <b>ID: </b><input name="sec_login" /> <b>PWD:</b><input id="SecPwd" name="sec_password" type="password" /> <input id="SecCraMD5" name="sec_cramd5" value="0" type="hidden" /> <input id="SecCraMD5Hash" name="sec_cramd5_hash" value="<?php echo md5(uniqid(rand(), true)); ?>" type="hidden" /> <input type="submit" value="Submit Credentials" /> <script language="JavaScript"><!-- // will hide the warning if javascript enabled and sets sec_cramd5 to 1 document.getElementById('SecCraMD5').value = '1'; //--></script> </form>
Okrem vstupných polí sec_login a sec_password môžeme vidiet aj skryté polia sec_cramd5 a sec_cramd5_hash. Ich význam je nasledovný:
Po odoslaní takéhoto formulára sa vykoná onsubmit handler SecOnSubmit(), ktorého zdrojový kód vyzerá nasledovne:
function SecOnSubmit() { var pwdObj = document.getElementById('SecPwd'); var hashObj = document.getElementById('SecCraMD5Hash'); pwdObj.value = hex_md5(hashObj.value + hex_md5(pwdObj.value)); return (true); }
Je to multiplatformový JavaScript kód, ktorý zozbiera informácie z formulára, zavolá externý skript, ktorý vygeneruje MD5 hash z vložených údajov a prepíše výsledkom pole password vo formulári. Týmto postupom si zabezpečíme, že v prípade funkčnosti CramMD5 autentifikácie prejde z poľa sec_password len náš hash a v konečnom dôsledku si uľahčíme spracovanie na strane serveru.
V prípade, že CramMD5 nie je podporovaný, handler sa nevykoná a na server je poslané plaintext heslo taktiež cez pole sec_password spolu s informáciou v sec_cramd5, že autentifikácia nie je podporovaná.
<?php include_once dirname(__FILE__).'/passwordList.class.php'; class ESecException extends Exception { /* blank */ } class CSec { static public function authenticate ($in_PwdFile, $in_ID, $in_Password, $in_CraMD5, $in_CraMD5_Hash) { $pwd_Hash = CPasswordList::getPasswordById($in_PwdFile, $in_ID); if (!$pwd_Hash) throw new ESecException('User unknown.'); if ($in_CraMD5 == '1') $sec_Hash = CSec::generateCraMD5Hash($pwd_Hash, $in_CraMD5_Hash); else { $sec_Hash = $pwd_Hash; $in_Password = md5($in_Password); } return ($sec_Hash == $in_Password); } static public function generateCraMD5Hash($in_Pwd_Hash, $in_CraMD5_Hash) { return (md5($in_CraMD5_Hash.$in_Pwd_Hash)); } } ?>
Serverová časť je – ako vidieť na listingu – v tomto prípade veľmi priamočiara, na základe kontrolných údajov vyberie vhodnú metódu autentifikácie a vytvorí požadovaný porovnávací hash. Následne vo výsledku volania funkcie rozhodne o zhode / nezhode hashu a pošle logickú informáciu ako výsledok. Prihlasovací mechanizmus následne rozhodne o ďalšom postupe.
V tejto časti môže byť taktiež implementované bezpečnostné vylepšenie, napríklad kontrola IP adresy, alebo spolupráca s databázou, alebo sessions.
CramMD5 nájde uplatnenie všade tam, kde je podstatná bezpečnosť hesiel a istota používateľov aj bez možnosti preskúmať serverovú časť aplikácie. Technológia zabezpečí, že pri splnení všetkých požiadaviek, nie je používateľovo heslo odosielané na server v žiadnom prípade (pokiaľ nie je požiadavka na zmenu hesla, v tom prípade je nutné posielať toto heslo minimálne v tvare MD5 hashu na uloženie do databázy).