Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking โ€œSign up for GitHubโ€, you agree to our terms of service and privacy statement. Weโ€™ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

[PM-17619] Add Intial Windows WebAuthn Plugin Authenticator Bindings Crate #13112

Merged
merged 23 commits into from
Feb 3, 2025
Merged
Changes from all commits
Commits
Show all changes
23 commits
Select commit Hold shift + click to select a range
b101094
PM-17619: Add intial Windows WebAuthn Plugin Authenticator bindings cโ€ฆ
coltonhurst Jan 28, 2025
0265a55
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 28, 2025
0b6004c
PM-17619: Move crate to desktop_native
coltonhurst Jan 29, 2025
be7e576
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 29, 2025
fb39f20
PM-17619: Update codeowners file
coltonhurst Jan 29, 2025
a0e5d72
PM-17619: Fix failing Mac build
coltonhurst Jan 29, 2025
946a9b6
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 29, 2025
a1358ff
PM-17619: Switch to OUT_DIR
coltonhurst Jan 29, 2025
4edd5bc
PM-17619: cargo fmt
coltonhurst Jan 29, 2025
6c1ae75
PM-17619: Update bindings output dir
coltonhurst Jan 29, 2025
18acf4b
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 29, 2025
f21704e
PM-17619: Use std::env::var for OUT_DIR
coltonhurst Jan 30, 2025
7d2887e
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 30, 2025
22940c3
PM-17619: Prevent clippy failures on the generated Rust code
coltonhurst Jan 30, 2025
344b643
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 30, 2025
f6e8e39
PM-17619: Test moving the clippy:all
coltonhurst Jan 31, 2025
cdedc27
PM-17619: Small updates
coltonhurst Jan 31, 2025
a3436d4
Merge main into branch
coltonhurst Jan 31, 2025
937afca
PM-17619: Remove todo
coltonhurst Jan 31, 2025
f849e6b
PM-17619: Ignore rustc warnings on the generated code
coltonhurst Jan 31, 2025
158ade1
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Jan 31, 2025
65481bc
PM-17619: Address PR comments
coltonhurst Feb 3, 2025
7531297
Merge branch 'main' into autofill/pm-17619/initial-win-pa-bindings
coltonhurst Feb 3, 2025
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions .github/CODEOWNERS
Original file line number Diff line number Diff line change
@@ -105,6 +105,7 @@ apps/browser/src/autofill @bitwarden/team-autofill-dev
apps/desktop/src/autofill @bitwarden/team-autofill-dev
libs/common/src/autofill @bitwarden/team-autofill-dev
apps/desktop/macos/autofill-extension @bitwarden/team-autofill-dev
apps/desktop/desktop_native/windows-plugin-authenticator @bitwarden/team-autofill-dev
# DuckDuckGo integration
apps/desktop/native-messaging-test-runner @bitwarden/team-autofill-dev
apps/desktop/src/services/duckduckgo-message-handler.service.ts @bitwarden/team-autofill-dev
1 change: 1 addition & 0 deletions apps/desktop/desktop_native/.gitignore
Original file line number Diff line number Diff line change
@@ -5,3 +5,4 @@ index.node
npm-debug.log*
*.node
dist
windows_pluginauthenticator_bindings.rs
72 changes: 72 additions & 0 deletions apps/desktop/desktop_native/Cargo.lock

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion apps/desktop/desktop_native/Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[workspace]
resolver = "2"
members = ["napi", "core", "proxy", "macos_provider"]
members = ["napi", "core", "proxy", "macos_provider", "windows-plugin-authenticator"]

[workspace.dependencies]
anyhow = "=1.0.94"
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
[package]
name = "windows-plugin-authenticator"
version = "0.0.0"
edition = "2021"
license = "GPL-3.0"
publish = false

[target.'cfg(target_os = "windows")'.build-dependencies]
bindgen = "0.71.1"
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# windows-plugin-authenticator

This is an internal crate that's meant to be a safe abstraction layer over the generated Rust bindings for the Windows WebAuthn Plugin Authenticator API's.

You can find more information about the Windows WebAuthn API's [here](https://github.com/microsoft/webauthn).

## Building

To build this crate, set the following environment variables:

- `LIBCLANG_PATH` -> the path to the `bin` directory of your LLVM install ([more info](https://rust-lang.github.io/rust-bindgen/requirements.html?highlight=libclang_path#installing-clang))

### Bash Example

```
export LIBCLANG_PATH='C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin'
```

### PowerShell Example

```
$env:LIBCLANG_PATH = 'C:\Program Files\Microsoft Visual Studio\2022\Community\VC\Tools\Llvm\x64\bin'
```
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
fn main() {
#[cfg(target_os = "windows")]
windows();
}

#[cfg(target_os = "windows")]
fn windows() {
let out_dir = std::env::var("OUT_DIR").expect("OUT_DIR not set");

let bindings = bindgen::Builder::default()
.header("pluginauthenticator.hpp")
.parse_callbacks(Box::new(bindgen::CargoCallbacks::new()))
.generate()
.expect("Unable to generate bindings.");

bindings
.write_to_file(format!(
"{}\\windows_pluginauthenticator_bindings.rs",
out_dir
))
.expect("Couldn't write bindings.");
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,231 @@
/*
Bitwarden's pluginauthenticator.hpp
Source: https://github.com/microsoft/webauthn/blob/master/experimental/pluginauthenticator.h
This is a C++ header file, so the extension has been manually
changed from `.h` to `.hpp`, so bindgen will automatically
generate the correct C++ bindings.
More Info: https://rust-lang.github.io/rust-bindgen/cpp.html
*/

/* this ALWAYS GENERATED file contains the definitions for the interfaces */

/* File created by MIDL compiler version 8.01.0628 */
/* @@MIDL_FILE_HEADING( ) */

/* verify that the <rpcndr.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCNDR_H_VERSION__
#define __REQUIRED_RPCNDR_H_VERSION__ 501
#endif

/* verify that the <rpcsal.h> version is high enough to compile this file*/
#ifndef __REQUIRED_RPCSAL_H_VERSION__
#define __REQUIRED_RPCSAL_H_VERSION__ 100
#endif

#include "rpc.h"
#include "rpcndr.h"

#ifndef __RPCNDR_H_VERSION__
#error this stub requires an updated version of <rpcndr.h>
#endif /* __RPCNDR_H_VERSION__ */

#ifndef COM_NO_WINDOWS_H
#include "windows.h"
#include "ole2.h"
#endif /*COM_NO_WINDOWS_H*/

#ifndef __pluginauthenticator_h__
#define __pluginauthenticator_h__

#if defined(_MSC_VER) && (_MSC_VER >= 1020)
#pragma once
#endif

#ifndef DECLSPEC_XFGVIRT
#if defined(_CONTROL_FLOW_GUARD_XFG)
#define DECLSPEC_XFGVIRT(base, func) __declspec(xfg_virtual(base, func))
#else
#define DECLSPEC_XFGVIRT(base, func)
#endif
#endif

/* Forward Declarations */

#ifndef __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__
#define __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__
typedef interface EXPERIMENTAL_IPluginAuthenticator EXPERIMENTAL_IPluginAuthenticator;

#endif /* __EXPERIMENTAL_IPluginAuthenticator_FWD_DEFINED__ */

/* header files for imported files */
#include "oaidl.h"
#include "webauthn.h"

#ifdef __cplusplus
extern "C"{
#endif

/* interface __MIDL_itf_pluginauthenticator_0000_0000 */
/* [local] */

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST
{
HWND hWnd;
GUID transactionId;
DWORD cbRequestSignature;
/* [size_is] */ byte *pbRequestSignature;
DWORD cbEncodedRequest;
/* [size_is] */ byte *pbEncodedRequest;
} EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST;

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST *EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_REQUEST;

typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST;

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE
{
DWORD cbEncodedResponse;
/* [size_is] */ byte *pbEncodedResponse;
} EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE;

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE *EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE;

typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_OPERATION_RESPONSE *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_RESPONSE;

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST
{
GUID transactionId;
DWORD cbRequestSignature;
/* [size_is] */ byte *pbRequestSignature;
} EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST;

typedef struct _EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST *EXPERIMENTAL_PWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST;

typedef const EXPERIMENTAL_WEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST *EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST;

extern RPC_IF_HANDLE __MIDL_itf_pluginauthenticator_0000_0000_v0_0_c_ifspec;
extern RPC_IF_HANDLE __MIDL_itf_pluginauthenticator_0000_0000_v0_0_s_ifspec;

#ifndef __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__
#define __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__

/* interface EXPERIMENTAL_IPluginAuthenticator */
/* [unique][version][uuid][object] */

EXTERN_C const IID IID_EXPERIMENTAL_IPluginAuthenticator;

#if defined(__cplusplus) && !defined(CINTERFACE)

MIDL_INTERFACE("e6466e9a-b2f3-47c5-b88d-89bc14a8d998")
EXPERIMENTAL_IPluginAuthenticator : public IUnknown
{
public:
virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginMakeCredential(
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request,
/* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response) = 0;

virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginGetAssertion(
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request,
/* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response) = 0;

virtual HRESULT STDMETHODCALLTYPE EXPERIMENTAL_PluginCancelOperation(
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST request) = 0;

};

#else /* C style interface */

typedef struct EXPERIMENTAL_IPluginAuthenticatorVtbl
{
BEGIN_INTERFACE

DECLSPEC_XFGVIRT(IUnknown, QueryInterface)
HRESULT ( STDMETHODCALLTYPE *QueryInterface )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This,
/* [in] */ __RPC__in REFIID riid,
/* [annotation][iid_is][out] */
_COM_Outptr_ void **ppvObject);

DECLSPEC_XFGVIRT(IUnknown, AddRef)
ULONG ( STDMETHODCALLTYPE *AddRef )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This);

DECLSPEC_XFGVIRT(IUnknown, Release)
ULONG ( STDMETHODCALLTYPE *Release )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This);

DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginMakeCredential)
HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginMakeCredential )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This,
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request,
/* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response);

DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginGetAssertion)
HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginGetAssertion )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This,
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_OPERATION_REQUEST request,
/* [out] */ __RPC__deref_out_opt EXPERIMENTAL_PWEBAUTHN_PLUGIN_OPERATION_RESPONSE *response);

DECLSPEC_XFGVIRT(EXPERIMENTAL_IPluginAuthenticator, EXPERIMENTAL_PluginCancelOperation)
HRESULT ( STDMETHODCALLTYPE *EXPERIMENTAL_PluginCancelOperation )(
__RPC__in EXPERIMENTAL_IPluginAuthenticator * This,
/* [in] */ __RPC__in EXPERIMENTAL_PCWEBAUTHN_PLUGIN_CANCEL_OPERATION_REQUEST request);

END_INTERFACE
} EXPERIMENTAL_IPluginAuthenticatorVtbl;

interface EXPERIMENTAL_IPluginAuthenticator
{
CONST_VTBL struct EXPERIMENTAL_IPluginAuthenticatorVtbl *lpVtbl;
};

#ifdef COBJMACROS


#define EXPERIMENTAL_IPluginAuthenticator_QueryInterface(This,riid,ppvObject) \
( (This)->lpVtbl -> QueryInterface(This,riid,ppvObject) )

#define EXPERIMENTAL_IPluginAuthenticator_AddRef(This) \
( (This)->lpVtbl -> AddRef(This) )

#define EXPERIMENTAL_IPluginAuthenticator_Release(This) \
( (This)->lpVtbl -> Release(This) )


#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginMakeCredential(This,request,response) \
( (This)->lpVtbl -> EXPERIMENTAL_PluginMakeCredential(This,request,response) )

#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginGetAssertion(This,request,response) \
( (This)->lpVtbl -> EXPERIMENTAL_PluginGetAssertion(This,request,response) )

#define EXPERIMENTAL_IPluginAuthenticator_EXPERIMENTAL_PluginCancelOperation(This,request) \
( (This)->lpVtbl -> EXPERIMENTAL_PluginCancelOperation(This,request) )

#endif /* COBJMACROS */

#endif /* C style interface */

#endif /* __EXPERIMENTAL_IPluginAuthenticator_INTERFACE_DEFINED__ */

/* Additional Prototypes for ALL interfaces */

unsigned long __RPC_USER HWND_UserSize( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * );
unsigned char * __RPC_USER HWND_UserMarshal( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * );
unsigned char * __RPC_USER HWND_UserUnmarshal(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * );
void __RPC_USER HWND_UserFree( __RPC__in unsigned long *, __RPC__in HWND * );

unsigned long __RPC_USER HWND_UserSize64( __RPC__in unsigned long *, unsigned long , __RPC__in HWND * );
unsigned char * __RPC_USER HWND_UserMarshal64( __RPC__in unsigned long *, __RPC__inout_xcount(0) unsigned char *, __RPC__in HWND * );
unsigned char * __RPC_USER HWND_UserUnmarshal64(__RPC__in unsigned long *, __RPC__in_xcount(0) unsigned char *, __RPC__out HWND * );
void __RPC_USER HWND_UserFree64( __RPC__in unsigned long *, __RPC__in HWND * );

/* end of Additional Prototypes */

#ifdef __cplusplus
}
#endif

#endif
Original file line number Diff line number Diff line change
@@ -0,0 +1,11 @@
#![cfg(target_os = "windows")]

mod pa;

pub fn get_version_number() -> u64 {
unsafe { pa::WebAuthNGetApiVersionNumber() }.into()
}

pub fn add_authenticator() {
unimplemented!();
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
/*
The 'pa' (plugin authenticator) module will contain the generated
bindgen code.
The attributes below will suppress warnings from the generated code.
*/

#![cfg(target_os = "windows")]
#![allow(clippy::all)]
#![allow(warnings)]

include!(concat!(
env!("OUT_DIR"),
"/windows_pluginauthenticator_bindings.rs"
));