简体   繁体   中英

C# Call LogonUser fail with SecureString

everyone, I am facing an issue with LogonUser function.

I just want to know if I can import the LogonUser function into C# by this signature:

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

Because I want to secure my password not using a string, but a SecureString class. Then later the function is used like below:

var passwordPtr = Marshal.SecureStringToGlobalAllocUnicode(password);
var result = LogonUser(userName, domain, passwordPtr, LOGON32_LOGON_INTERACTIVE, LOGON32_PROVIDER_DEFAULT, ref token);

I always get result = 0 and the message shows that the user name and password is incorrect. But when I change the signature to use string password, then everything works well.

Please help me as to secure the password with SecureString is important to me.

As pointed out by Alex K, there's an example of using LogonUser in the SecureStringToGlobalAllocUnicode . Note that the P/Invoke declaration there is:

[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);

And that CharSet = CharSet.Unicode has been specified. Unfortunately, for historical reasons, the default CharSet value is Ansi and so that's what your P/Invoke attempt is going to use.

This will be fine for the username parameter since the P/Invoke infrastructure will ensure that it converts the string appropriately. But it's not appropriate for the password parameter since you've already performed the string conversion and you've done it as Unicode - and all that P/Invoke is seeing is an IntPtr now.

I'd suggest updating your P/Invoke signature to match that given in the sample.


Another alternative would be to switch to using SecureStringToGlobalAllocAnsi and leaving your P/Invoke signature alone. But this is a seriously second-rate solution. Writing non-Unicode aware code in 2015 is seriously not to be recommended.

Just get in the habit of always specifying CharSet.Unicode in any P/Invoke signatures you write.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM