Обертывание API диспетчера учетных данных в .NETCF - PullRequest
0 голосов
/ 30 января 2009

думаю, что я успешно создал управляемый класс-оболочку для упомянутых функций Credential API здесь с небольшой помощью от там По крайней мере коды ошибок Win32, возвращаемые из этих функций, равны нулю или другим ожидается (т. е. 1168 от CredDelete, если он вызывается дважды), и соответствующие значения хранятся в правильном месте в реестре (HKLM / Comm / Security / Credman / 1 ..).

Теперь я использую Webbrowser-Control, встроенный в WindowsForm на PPC, для аутентификации на веб-сайте, который использует NTLM-аутентификацию. Я не хочу, чтобы появился всплывающий диалог, в котором пользователь должен ввести свои учетные данные. Вместо этого я даю пользователю возможность сохранить свои учетные данные на устройстве, которое он в первую очередь ввел в форме Optiondialog-Form (практикующий вызывает CredWrite / CredUpdate).

Но PIE наплевать на то, что я делаю с API, на самом деле не работает ни CredWrite, ни -Update, ни -Delete. Так чего мне здесь не хватает?

Пример кода для CredWrite:

[DllImport("coredll.dll", CharSet = CharSet.Unicode, SetLastError = true)]
static extern int CredWrite([In]IntPtr pCred, [In]CREDWRITE_FLAGS dwflags);

public enum CREDWRITE_FLAGS : int
{
    CRED_FLAG_FAIL_IF_EXISTING = 0x00000400
}

    public struct CRED
    {
        public int dwVersion;
        public CRED_TYPE dwType;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string wszUser;
        public int dwUserLen;
        [MarshalAs(UnmanagedType.LPWStr)]
        public string wszTarget;
        public int dwTargetLen;
        public IntPtr pBlob;
        public int dwBlobSize;
        public CRED_FLAGS dwFlags;
    }
    public enum CRED_TYPE
    {
        CRED_TYPE_NTLM = 0x00010002,
        CRED_TYPE_KERBEROS = 0x00010004,
        CRED_TYPE_PLAINTEXT_PASSWORD = 0x00010006,
        CRED_TYPE_CERTIFICATE = 0x00010008,
        CRED_TYPE_GENERIC = 0x0001000a,
        CRED_TYPE_DOMAIN_PASSWORD = 0x00010001,
    }
    public enum CRED_FLAGS : int
    {
        CRED_FLAG_PERSIST = 0x00000001,
        CRED_FLAG_DEFAULT = 0x00000002,
        CRED_FLAG_SENSITIVE = 0x00000008,
        CRED_FLAG_TRUSTED = 0x00000010
    }

public static void WriteCredentials(string target, string userName, string password)
{
    CRED cred = new CRED();
    cred.dwVersion = 1;
    cred.dwType = CRED_TYPE.CRED_TYPE_NTLM;
    cred.wszTarget = target;
    cred.dwTargetLen = target.Length + 1;
    cred.wszUser = userName;
    cred.dwUserLen = userName.Length + 1; 

    cred.dwBlobSize = (Encoding.Unicode.GetBytes(password).Length + 1) * 2;
    //cred.pBlob = Marshal.StringToCoTaskMemUni(password); //<--not in CF
    //cred.pBlob = Marshal2.StringToHGlobalUni(password); //<--from OpenNETCF, the same?
    cred.pBlob = Marshal.StringToBSTR(password); //<--not sure of that, but tried the other one also
    cred.dwFlags = CRED_FLAGS.CRED_FLAG_PERSIST | CRED_FLAGS.CRED_FLAG_SENSITIVE | CRED_FLAGS.CRED_FLAG_TRUSTED; //<-- results in 25 which is also used in creds read which are stored by the IE-UI-CredMan-dialog

    IntPtr credPtr = Marshal.AllocHGlobal(Marshal.SizeOf(cred));
    Marshal.StructureToPtr(cred, credPtr, true);

    int ret = -1;
    ret = CredWrite(credPtr, CREDWRITE_FLAGS.CRED_FLAG_FAIL_IF_EXISTING); //returns zero, unless called twice with the same target/username-tuple.

    Marshal.FreeHGlobal(credPtr);
}

Кстати, так называемые «MS-Experts» упоминают, что PIE имеет свой собственный механизм кэширования для кредитов, и поэтому PIE игнорирует изменения в CredUpdate. Но я сомневаюсь, что это на 100% правильно, потому что когда я вызываю CredWrite на устройстве без учетных данных, PIE тоже игнорирует их (всплывающее окно cred-inputdialog).

Может ли кто-нибудь помочь мне в этом?

1 Ответ

0 голосов
/ 30 января 2009

Вещи, которые я бы проверил:

  1. Если вы входите в систему с помощью диалогового окна вручную, хранится ли в нем что-либо с ожидаемым ключом реестра (HKLM / Comm / Security / Credman / 1 ..)? Если нет, то я бы сказал, что это довольно убедительное доказательство того, что он не использует Cred Manager.
  2. Если вы выполняете проверку подлинности NTLM вручную (например, с помощью Explorer), появляется ли в браузере диалоговое окно учетных данных?

Ранее я выполнял проверку подлинности NTLM на устройстве, но не с помощью управления браузером, и я использовал API служб аутентификации . Вот пример на родном . Я хотел перенести его на управляемый, просто не нашел время.

Редактировать 1 : В дальнейшем, глядя на ваш код, мне не нравится блоб. Что заставляет вас думать, что это должно войти как BSTR? Это тип COM, и я очень сомневаюсь, что это то, что вы хотите. Я был бы склонен просто отправить байтовый массив с паролем. Сначала я бы попробовал Unicode, поскольку CE сильно смещен в сторону Unicode, а затем ASCII, если это не помогло.

Я также думаю, что ваш маршалинг структуры CRED является подозрительным, но это просто потому, что я использую CF с версии до 1.0 и научился «доверять, но проверять» все, что делает маршалер. По крайней мере, я бы посмотрел на экземпляр CRED в представлении памяти и убедился, что эти строки действительно являются просто 4-байтовыми указателями и что адреса, на которые они указывают, на самом деле содержат ваши строковые данные (ничего более и ноль завершается). *

...