2015-01-08 11 views
6

Per motivi di apprendimento, sto scrivendo il mio client Active Directory. Per eseguire comandi come sbloccare gli account e reimpostare le password, devo inserire il mio account amministratore e la password e utilizzare e WindowsIdentity.Impersonate eseguire il codice come account amministratore. Mi sto interrogando sulle mie opzioni per proteggere la mia password, poiché deve essere utilizzata più volte nel mio programma.Utilizzo di SecureString con LogonUser

Da quello che ho capito, posso usare SecureString per memorizzare la password. Ma per eseguire il codice come account amministratore, ho utilizzato WindowsIdentity.Impersonate e per utilizzarlo devo ottenere un token da LogonUser che richiede un normale string e non SecureString.

Così avrei dovuto:

  1. Accesso all'avvio

  2. Convertire ingresso a un SecureString

  3. Cancella l'ingresso

Poi più tardi, quando ho vuoi preformare una funzione che richiede l'elevazione:

  1. Converti precedentemente creato SecureString a string

  2. Passare la stringa convertita al LogonUser

  3. Cancella la stringa convertito al null

  4. Esegue il comando

  5. C lear l'oggetto LogonUser

È questo il modo corretto di avvicinarsi a questo? Sembra strano dover convertire lo SecureString in string per usarlo ... sembra come se potesse vanificare lo scopo e lasciare la password più vulnerabile mentre la sto convertendo.

EDIT: Risolto il nome per LogonUser

+1

Hai ragione, la conversione in stringhe lo scopo. Che cos'è UserImpersonation? Fa PInvoke su un'API Win32? Potrebbe essere necessario modificare la funzione che utilizza per passare in IntPtr anziché in stringa. –

+0

Oh whoops mi dispiace ... risolverò la mia domanda. Sì, 'UserImpersonation' è una classe che ho scritto un po 'di tempo fa ... è fondamentalmente un wrapper per [LogonUser] (http://msdn.microsoft.com/en-us/library/windows/desktop/aa378184%28v= vs.85% 29.aspx), che richiede anche una stringa per una password. Può essere cambiato in un 'IntPtr'? In tal caso, posso passare un parametro 'SecureString' al parametro password?(Vorrei provare ora ma non sono più al lavoro ...) – duckwizzle

+1

No, non è possibile utilizzare 'SecureString' direttamente ma non dovrebbe essere difficile passare la password in sicurezza. Risponderò di seguito ... –

risposta

5

Nella classe UserImpersonation, cambiare il modo di dichiarare LogonUser utilizzare IntPtr invece di string per la password.

L'esempio di codice per Marshal.SecureStringToGlobalAllocUnicode ha esattamente quello che ti serve. Ecco lo snippet pertinente:

[DllImport("advapi32.dll", SetLastError = true, CharSet = CharSet.Unicode)] 
internal static extern bool LogonUser(String username, String domain, 
             IntPtr password, int logonType, 
             int logonProvider, ref IntPtr token); 

... 

IntPtr tokenHandle = IntPtr.Zero; 

IntPtr passwordPtr = IntPtr.Zero; 

try 
{ 
    // Marshal the SecureString to unmanaged memory. 
    passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password); 

    returnValue = LogonUser(userName, domainName, passwordPtr, 
          LOGON32_LOGON_INTERACTIVE, 
          LOGON32_PROVIDER_DEFAULT, ref tokenHandle); 

} 
finally 
{ 
    // Zero-out and free the unmanaged string reference. 
    Marshal.ZeroFreeGlobalAllocUnicode(passwordPtr); 

    // Close the token handle. 
    CloseHandle(tokenHandle); 
} 
+0

Perfetto! Grazie! :) – duckwizzle

+0

@duckwizzle Nessun problema –