Java JNA CredUnPackAuthenticationBufferW - PullRequest
       38

Java JNA CredUnPackAuthenticationBufferW

0 голосов
/ 18 ноября 2018

Я пытаюсь открыть диалоговое окно аутентификации Windows и получить учетные данные, введенные пользователем, в Java.

Идея состоит в том, чтобы вызвать функции CredUIPromptForWindowsCredentialsW и CredUnPackAuthenticationBufferW.

В C ++ это прекрасно работает:

#include <string>
#include <Windows.h>
#include <wincred.h>

int main()
{
    CREDUI_INFOW credui = {};
    credui.pszMessageText = L"Hello1";
    credui.pszCaptionText = L"Hello2";
    credui.hwndParent = nullptr;
    credui.hbmBanner = nullptr;
    credui.cbSize = sizeof(credui);

    ULONG authPackage = 0;
    LPVOID outCredBuffer = nullptr;
    ULONG outCredSize = 0;
    BOOL save = false;

    int result = CredUIPromptForWindowsCredentialsW(
       &credui,
       0,
       &authPackage,
       NULL,
       0,
       &outCredBuffer,
       &outCredSize,
       &save,
       0x1);

    DWORD dwFlags = 0x1;
    std::wstring pszUserName = L" ";
    std::wstring pszDomain = L" ";
    std::wstring pszPassword = L" ";

    DWORD domainSize = 100;
    DWORD* pDomainSize = &domainSize;

    DWORD userNameSize = 100;
    DWORD* pUserNameSize = &userNameSize;

    DWORD passwordSize = 100;
    DWORD* pPasswordSize = &passwordSize;

    BOOL boolResult = CredUnPackAuthenticationBufferW(
       dwFlags,
       outCredBuffer,
       outCredSize,
       &pszUserName.at(0),
       pUserNameSize,
       &pszDomain.at(0),
       pDomainSize,
       &pszPassword.at(0),
       pPasswordSize);

    if (result == ERROR_SUCCESS) {
       printf("getlasterror(): %d\n", GetLastError());
    }

    return 0;
}

В Java с JNA я могу вызвать диалоговое окно аутентификации Windows, но не могу получить учетные данные пользователя:

package testcredui;

import com.sun.jna.Library;
import com.sun.jna.Native;
import com.sun.jna.Pointer;
import com.sun.jna.Structure;
import com.sun.jna.WString;
import com.sun.jna.platform.win32.WinDef.HBITMAP;
import com.sun.jna.platform.win32.WinDef.HWND;
import com.sun.jna.platform.win32.WinDef.ULONG;
import com.sun.jna.platform.win32.WinDef.ULONGByReference;
import com.sun.jna.platform.win32.WTypes.LPWSTR;
import com.sun.jna.platform.win32.WinDef;
import com.sun.jna.ptr.IntByReference;
import com.sun.jna.ptr.PointerByReference;
import com.sun.jna.platform.win32.WinDef.DWORD;
import com.sun.jna.platform.win32.WinDef.DWORDByReference;

import java.util.Arrays;
import java.util.List;

public class TestCredui {

   public interface CInterface extends Library 
   {
      CInterface INSTANCE = (CInterface) Native.load("Credui", CInterface.class);

     /*
      * CredUIPromptForWindowsCredentialsW
      * DWORD WINAPI CredUIPromptForWindowsCredentials(
      * PCREDUI_INFO pUiInfo,
      * DWORD        dwAuthError,
      * ULONG        *pulAuthPackage,
      * LPCVOID      pvInAuthBuffer,
      * ULONG        ulInAuthBufferSize,
      * LPVOID       *ppvOutAuthBuffer,
      * ULONG        *pulOutAuthBufferSize,
      * BOOL         *pfSave,
      * DWORD        dwFlags
      * )
      */
      int CredUIPromptForWindowsCredentialsW(
         CREDUI_INFO pUiInfo,
         int dwAuthError,
         ULONGByReference pulAuthPackage,
         Pointer pvInAuthBuffer,
         ULONG ulInAuthBufferSize,
         PointerByReference ppvOutAuthBuffer,
         ULONGByReference pulOutAuthBufferSize,
         IntByReference pfSave,
         int dwFlags
      );

     /*
      CREDUIAPI BOOL CredUnPackAuthenticationBufferW(
         DWORD  dwFlags,
         PVOID  pAuthBuffer,
         DWORD  cbAuthBuffer,
         LPWSTR pszUserName,
         DWORD  *pcchMaxUserName,
         LPWSTR pszDomainName,
         DWORD  *pcchMaxDomainName,
         LPWSTR pszPassword,
         DWORD  *pcchMaxPassword
      );
      */
      boolean CredUnPackAuthenticationBufferW(
         DWORD dwFlags,
         Pointer pAuthBuffer,
         DWORD cbAuthBuffer,
         LPWSTR pszUserName,
         DWORDByReference pcchlMaxUserName,
         LPWSTR pszDomainName,
         DWORDByReference pcchMaxDomainName,
         LPWSTR pszPassword,
         DWORDByReference pcchMaxPassword
      );

     /*
      * CREDUI_INFO
      * 
      * typedef struct _CREDUI_INFO {
      * DWORD   cbSize;
      * HWND    hwndParent;
      * PCTSTR  pszMessageText;
      * PCTSTR  pszCaptionText;
      * HBITMAP hbmBanner;
      * } CREDUI_INFO, *PCREDUI_INFO;
      */
      public static class CREDUI_INFO extends Structure {

         public int cbSize;
         public HWND hwndParent;
         public WString pszMessageText;
         public WString pszCaptionText;
         public HBITMAP hbmBanner;

        /**
         * getFieldOrder
         * @return 
         */
         @Override
         protected List getFieldOrder() {
            return Arrays.asList(new String[]{
               "cbSize", 
               "hwndParent",
               "pszMessageText",
               "pszCaptionText",
               "hbmBanner",
            });
         }
     }
  }

  public static void main(String[] args) 
  { 
     CInterface.CREDUI_INFO info = new CInterface.CREDUI_INFO();

     info.pszCaptionText = new WString("captionText");
     info.pszMessageText = new WString("MessageText");
     info.cbSize = info.size();

     WinDef.ULONGByReference authPackage = new WinDef.ULONGByReference();
     authPackage.setValue(new ULONG(0));      
     PointerByReference outCredBuffer = new PointerByReference();
     WinDef.ULONGByReference outCredSize = new WinDef.ULONGByReference();
     IntByReference save = new IntByReference(0);
     WinDef.ULONG ulInAuthBufferSize = new WinDef.ULONG(0);

     CInterface.INSTANCE.CredUIPromptForWindowsCredentialsW(
          info,
          0,
          authPackage, 
          null,
          ulInAuthBufferSize,
          outCredBuffer,
          outCredSize,
          save,
          0x1
     );

     WinDef.DWORD dwordValue = new DWORD(100);

     LPWSTR username = new LPWSTR("                ");
     WinDef.DWORDByReference usernameSize = new WinDef.DWORDByReference();
     usernameSize.setValue(dwordValue);

     LPWSTR domain = new LPWSTR("                ");
     WinDef.DWORDByReference domainSize = new WinDef.DWORDByReference();
     domainSize.setValue(dwordValue);

     LPWSTR password = new LPWSTR("                ");
     WinDef.DWORDByReference passwordSize = new WinDef.DWORDByReference();
     passwordSize.setValue(dwordValue);   

     WinDef.DWORD flags = new WinDef.DWORD(0x1);
     WinDef.DWORD bufferSize = new WinDef.DWORD(250);

     boolean r = CInterface.INSTANCE.CredUnPackAuthenticationBufferW(
          flags,
          outCredBuffer.getPointer(),
          bufferSize,
          username,
          usernameSize,
          domain,
          domainSize,
          password,
          passwordSize
     );

     System.out.println(username.getValue());

     if (r == false) {
        System.out.println(Native.getLastError());
     }   
  }  
}

Функция GetLastError возвращает 50 -> ERROR_NOT_SUPPORTED -> «Буфер аутентификации не поддерживается.»

Это общие учетные данные в виде обычного текста, которые поддерживаются всеми версиями Windows.

Не знаю почему.

Спасибо за вашу драгоценную помощь.

...