Hi
TL;DR: this is an experimental port update to add U2F/FIDO support and
I'd appreciate testing and feedback. See the issues below why this
needs further work and discussion.
I've attached an updated port for Firefox 71 that adds support for
U2F/FIDO USB security keys under OpenBSD. Since everyone got such
security keys for OpenSSH now ;-), I'd also like to use them for web
authentication (WebAuthn) as a better alternative to (T)OTP or SMS.
I've implemented the missing bits in the Rust crate that is
responsible for accessing the USB HID devices, see
https://github.com/reyk/authenticator-rs/tree/reyk/openbsd
It does come with issues:
- Firefox uses "vendored" versions of the Rust crates; it includes the
source code of all dependencies in its tarball (which is a good
thing). Updating the 'third_pary/rust/authenticator' makes the ports'
patches rather large and the goal should be to get it into upstream.
- In case you wonder about the Linux bits in the patches, it updates
it to a new version of authenticator-rs that includes some internal
changes. Maintaining patches for the old one version would make it
much more difficult.
- It doesn't work with pledge(2). As described in the package README
snippet below, the only way to use it is to disable 'pledge.main'.
I think there are three ways to deal with it:
1. Keep it as it is and let users disable 'pledge.main' manually if
they need U2F/FIDO (which isn't happening all the time).
2. Add access to the required USB HID ioctls to a new pledge class.
3. Split authenticator into a fork+exec model where USB HID access is
done by an external handler or daemon that runs without pledge. This
wouldn't be impossible but a lot more complicated and potentially
difficult to get into upstream. OpenSSH uses a similar model with
/usr/libexec/ssh-sk-helper.
>From pkg/README:
> Web Authentication
> ==================
> Support for web authentication (WebAuthn) with U2F/FIDO-compatible
> security keys is supported but requires direct access to the uhid(4)
> USB device layer. This is currently not possible with the default
> sandbox under OpenBSD: the installed unveil(2) policy permits access
> to the first 10 '/dev/uhid*' devices but pledge(2) prevents the
> required USB/UHID ioctls.
>
> To enable U2F/FIDO support, a) make sure that the user has read/write
> to '/dev/uhid*' (this is the case if the user is a member of group
> wheel) and b) set 'pledge.main' to 'disable'. For example:
>
> # mkdir /etc/firefox && echo disable > /etc/firefox/pledge.main
>
> WARNING: While 'pledge.main' is already the weakest policy, compared
> to 'pledge.content' or 'pledge.gpu', disabling it weakens the
> sandboxed security of Firefox itself. It does not alter the
> protection that is offered by unveil(2).
Even if we have to solve the issues first, I'd appreciate testing and
feedback. It takes a bit long to build the www/mozilla-firefox port
(and don't forget to bump the ulimits first) but it is worth the
effort if you need U2F/FIDO.
You can use any U2F/FIDO key, such as modern YubiKeys, and test it on
pages like https://webauthn.io/ or
https://demo.yubico.com/webauthn-technical/.
Reyk
Index: www/mozilla-firefox/Makefile
===================================================================
RCS file: /cvs/ports/www/mozilla-firefox/Makefile,v
retrieving revision 1.405
diff -u -p -u -p -r1.405 Makefile
--- www/mozilla-firefox/Makefile 3 Dec 2019 17:00:46 -0000 1.405
+++ www/mozilla-firefox/Makefile 10 Dec 2019 13:55:19 -0000
@@ -9,6 +9,7 @@ MOZILLA_VERSION = 71.0
MOZILLA_BRANCH = release
MOZILLA_PROJECT = firefox
MOZILLA_CODENAME = browser
+REVISION = 0
WRKDIST = ${WRKDIR}/${MOZILLA_DIST}-${MOZILLA_DIST_VERSION:C/b[0-9]*//}
HOMEPAGE = https://www.mozilla.org/firefox/
Index: www/mozilla-firefox/files/unveil.main
===================================================================
RCS file: /cvs/ports/www/mozilla-firefox/files/unveil.main,v
retrieving revision 1.1
diff -u -p -u -p -r1.1 unveil.main
--- www/mozilla-firefox/files/unveil.main 3 Dec 2019 17:00:46 -0000
1.1
+++ www/mozilla-firefox/files/unveil.main 10 Dec 2019 13:55:19 -0000
@@ -3,6 +3,18 @@
/dev/video rw
/dev/video0 rw
+# U2F/FIDO keys
+/dev/uhid0 rw
+/dev/uhid1 rw
+/dev/uhid2 rw
+/dev/uhid3 rw
+/dev/uhid4 rw
+/dev/uhid5 rw
+/dev/uhid6 rw
+/dev/uhid7 rw
+/dev/uhid8 rw
+/dev/uhid9 rw
+
/etc/fonts r
/etc/machine-id r
Index: www/mozilla-firefox/patches/patch-Cargo_lock
===================================================================
RCS file: www/mozilla-firefox/patches/patch-Cargo_lock
diff -N www/mozilla-firefox/patches/patch-Cargo_lock
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ www/mozilla-firefox/patches/patch-Cargo_lock 10 Dec 2019 13:55:19
-0000
@@ -0,0 +1,35 @@
+$OpenBSD$
+
+Add U2F/FIDO authenticator support for OpenBSD.
+This currently only works with pledge.main = disable.
+
+Index: Cargo.lock
+--- Cargo.lock.orig
++++ Cargo.lock
+@@ -144,7 +144,7 @@ dependencies = [
+ [[package]]
+ name = "authenticator"
+ version = "0.2.6"
+-source = "registry+https://github.com/rust-lang/crates.io-index"
++source =
"git+https://github.com/reyk/authenticator-rs?rev=63541d7786ffc21b526271b2666164f3dd49b9a4#63541d7786ffc21b526271b2666164f3dd49b9a4"
+ dependencies = [
+ "bitflags 1.2.0 (registry+https://github.com/rust-lang/crates.io-index)",
+ "boxfnonce 0.0.3 (registry+https://github.com/rust-lang/crates.io-index)",
+@@ -1222,7 +1222,7 @@ dependencies = [
+ "audio_thread_priority 0.20.2
(registry+https://github.com/rust-lang/crates.io-index)",
+ "audioipc-client 0.4.0",
+ "audioipc-server 0.2.3",
+- "authenticator 0.2.6
(registry+https://github.com/rust-lang/crates.io-index)",
++ "authenticator 0.2.6
(git+https://github.com/reyk/authenticator-rs?rev=63541d7786ffc21b526271b2666164f3dd49b9a4)",
+ "bitsdownload 0.1.0",
+ "bookmark_sync 0.1.0",
+ "cert_storage 0.0.1",
+@@ -3812,7 +3812,7 @@ dependencies = [
+ "checksum atomic_refcell 0.1.0
(registry+https://github.com/rust-lang/crates.io-index)" =
"fb2dcb6e6d35f20276943cc04bb98e538b348d525a04ac79c10021561d202f21"
+ "checksum atty 0.2.11
(registry+https://github.com/rust-lang/crates.io-index)" =
"9a7d5b8723950951411ee34d271d99dddcc2035a16ab25310ea2c8cfd4369652"
+ "checksum audio_thread_priority 0.20.2
(registry+https://github.com/rust-lang/crates.io-index)" =
"197b2d259505d11c92d266e1784f01cc935eb764d2f54e16aedf4e5085197871"
+-"checksum authenticator 0.2.6
(registry+https://github.com/rust-lang/crates.io-index)" =
"ec149e5d5d4caa2c9ead53a8ce1ea9c4204c388c65bf3b96c2d1dc0fcf4aeb66"
++"checksum authenticator 0.2.6
(git+https://github.com/reyk/authenticator-rs?rev=63541d7786ffc21b526271b2666164f3dd49b9a4)"
= "<none>"
+ "checksum autocfg 0.1.6
(registry+https://github.com/rust-lang/crates.io-index)" =
"b671c8fb71b457dd4ae18c4ba1e59aa81793daacc361d82fcd410cef0d491875"
+ "checksum backtrace 0.3.9
(registry+https://github.com/rust-lang/crates.io-index)" =
"89a47830402e9981c5c41223151efcced65a0510c13097c769cede7efb34782a"
+ "checksum backtrace-sys 0.1.24
(registry+https://github.com/rust-lang/crates.io-index)" =
"c66d56ac8dabd07f6aacdaf633f4b8262f5b3601a810a0dcddffd5c22c69daa0"
Index: www/mozilla-firefox/patches/patch-Cargo_toml
===================================================================
RCS file: www/mozilla-firefox/patches/patch-Cargo_toml
diff -N www/mozilla-firefox/patches/patch-Cargo_toml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ www/mozilla-firefox/patches/patch-Cargo_toml 10 Dec 2019 13:55:19
-0000
@@ -0,0 +1,15 @@
+$OpenBSD$
+
+Index: Cargo.toml
+--- Cargo.toml.orig
++++ Cargo.toml
+@@ -70,5 +70,9 @@ rev = "182414f15c18538dfebbe040469ec8001e93ecc5"
+ git = "https://github.com/CraneStation/Cranelift"
+ rev = "182414f15c18538dfebbe040469ec8001e93ecc5"
+
++[patch.crates-io.authenticator]
++git = "https://github.com/reyk/authenticator-rs"
++rev = "63541d7786ffc21b526271b2666164f3dd49b9a4"
++
+ [patch.crates-io.coreaudio-sys]
+ path = "third_party/rust/coreaudio-sys"
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_Cargo_toml
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_Cargo_toml
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_Cargo_toml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ www/mozilla-firefox/patches/patch-third_party_rust_authenticator_Cargo_toml
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,92 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/Cargo.toml
+--- third_party/rust/authenticator/Cargo.toml.orig
++++ third_party/rust/authenticator/Cargo.toml
+@@ -1,53 +1,45 @@
+-# THIS FILE IS AUTOMATICALLY GENERATED BY CARGO
+-#
+-# When uploading crates to the registry Cargo will automatically
+-# "normalize" Cargo.toml files for maximal compatibility
+-# with all versions of Cargo and also rewrite `path` dependencies
+-# to registry (e.g., crates.io) dependencies
+-#
+-# If you believe there's an error in this file please file an
+-# issue against the rust-lang/cargo repository. If you're
+-# editing this file be aware that the upstream Cargo.toml
+-# will likely look very different (and much more reasonable)
+-
+ [package]
+ name = "authenticator"
+ version = "0.2.6"
+ authors = ["J.C. Jones <[email protected]>", "Tim Taubert
<[email protected]>", "Kyle Machulis <[email protected]>"]
+-description = "Library for interacting with CTAP1/2 security keys for Web
Authentication. Used by Firefox."
+-license = "MPL-2.0"
+ repository = "https://github.com/mozilla/authenticator-rs/"
+-[dependencies.bitflags]
+-version = "1.0"
++license = "MPL-2.0"
++description = "Library for interacting with CTAP1/2 security keys for Web
Authentication. Used by Firefox."
+
+-[dependencies.boxfnonce]
+-version = "0.0.3"
++[features]
++binding-recompile = ["bindgen"]
+
+-[dependencies.libc]
+-version = "0.2"
++[target.'cfg(target_os = "linux")'.dependencies]
++libudev = "^0.2"
+
+-[dependencies.log]
+-version = "0.4"
++[target.'cfg(target_os = "freebsd")'.dependencies]
++devd-rs = "0.3"
+
+-[dependencies.rand]
+-version = "0.6"
++[target.'cfg(target_os = "macos")'.dependencies]
++core-foundation = "0.6.2"
+
+-[dependencies.runloop]
+-version = "0.1.0"
+-[dev-dependencies.base64]
+-version = "^0.10"
++[target.'cfg(target_os = "windows")'.dependencies.winapi]
++version = "0.3"
++features = [
++ "handleapi",
++ "hidclass",
++ "hidpi",
++ "hidusage",
++ "setupapi",
++]
+
+-[dev-dependencies.env_logger]
+-version = "0.6"
++[build-dependencies]
++bindgen = { version = "0.51", optional = true }
+
+-[dev-dependencies.sha2]
+-version = "^0.8"
+-[target."cfg(target_os = \"freebsd\")".dependencies.devd-rs]
+-version = "0.3"
+-[target."cfg(target_os = \"linux\")".dependencies.libudev]
+-version = "^0.2"
+-[target."cfg(target_os = \"macos\")".dependencies.core-foundation]
+-version = "0.6.2"
+-[target."cfg(target_os = \"windows\")".dependencies.winapi]
+-version = "0.3"
+-features = ["handleapi", "hidclass", "hidpi", "hidusage", "setupapi"]
++[dependencies]
++rand = "0.6"
++log = "0.4"
++libc = "0.2"
++boxfnonce = "0.0.3"
++runloop = "0.1.0"
++bitflags = "1.0"
++
++[dev-dependencies]
++sha2 = "^0.8"
++base64 = "^0.10"
++env_logger = "0.6"
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__cargo-checksum_json
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__cargo-checksum_json
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__cargo-checksum_json
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__cargo-checksum_json
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,10 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/.cargo-checksum.json
+--- third_party/rust/authenticator/.cargo-checksum.json.orig
++++ third_party/rust/authenticator/.cargo-checksum.json
+@@ -1 +1 @@
+-{"files":{"Cargo.toml":"5af2217a89aa4af5db14fd48c05144e264b53e067a8cf0433638e5196ad85f25","LICENSE":"e147f11fd8c5b7d151db93eabbb02ddb8b481082047008062025afd1ff7e2a27","README.md":"1c291ddb3f131b55e706f13a98eec871055ceb17ef502ce75f608b67136cc7c3","examples/main.rs":"7af9e288b1836fb9362589b6bf54c1f1d277bdf64df60c1caccef98c1bfe792c","rustfmt.toml":"de4e1daab481c1572805aed3e51e72c5dc1b3e5af757bc675e1717b251c6e922","src/capi.rs":"33b91e8e43003fb11b0fbb4ea72e4a5dba8f4dcc11e2503a8186eaea020c13c3","src/consts.rs":"4c34980f94d1017e5e75e29b26750c1678e0609c9227296951ffbb9e180a5adf","src/freebsd/device.rs":"914ac446ff24cc3fc050732372e286e1fedf8341a8d4754e392bc9f38393b142","src/freebsd/mod.rs":"42dcb57fbeb00140003a8ad39acac9b547062b8f281a3fa5deb5f92a6169dde6","src/freebsd/monitor.rs":"3683370931b15f05403d240a788a87b1bea801284ee74b849e1f330a4a231dd0","src/freebsd/transaction.rs":"e3615cfdd7f23e9a80a53c32e0fa2a5ae290a432b009bed2b2e74e0df77f8266","src/freebsd/uhid.rs":"d19ade6e808e63981ba5f93d482d676ffa9dff29cb2b7011486591f69ddbbdcd","src/hidproto.rs":"966ee74341e2ecff262e5490f99dcc9b9f9427451f3ded1b9cb9698a6984a3cc","src/lib.rs":"1dc04a7d7af14e9f1172a3839522386492a47218df14dfb0f24f98fe314c3d06","src/linux/device.rs":"2271fbb8d176ec01f83a899c0c8194a954465fdd8670a9b136ab88baaba2ee48","src/linux/hidraw.rs":"179cf38a1bd86c191c625a814d16e7ac00a774df9b3828ac4f735313a030f1e5","src/linux/mod.rs":"1056db0c258ccd9975066ffa8407ded689ecf5ece67fc17e732c487b69557b2c","src/linux/monitor.rs":"876d4e095d77858412c61d35560a3b85855a9c00beea6950b5f50796d8fd3eab","src/linux/transaction.rs":"e3615cfdd7f23e9a80a53c32e0fa2a5ae290a432b009bed2b2e74e0df77f8266","src/macos/device.rs":"57186092fd937124f96afacef57d0493efce86553ac50d527e6365b93eaabddf","src/macos/iokit.rs":"a0fd818224718e96ad5d106dfc235f4bc9218a59f5114b9f9825abe3ee62bce7","src/macos/mod.rs":"333e561554fc901d4f6092f6e4c85823e2b0c4ff31c9188d0e6d542b71a0a07c","src/macos/monitor.rs":"1f132a8566858b22309b33f8ae96d5596c42f515785be841bb51db80e20471d1","src/macos/transaction.rs":"b8e362575b2bcc54232022131bfa073d605969119326dcb549f4d87037a31541","src/manager.rs":"7428fc23038b004841936d8f27f8dc33234d5c06361efa75b73c7a5c035dae75","src/statemachine.rs":"28477fba601f5086b85e911da1e4f04af3f0060329e6e0e1172b960f9c52fd41","src/stub/device.rs":"32e134fc8826667d16b02fe32831fc29f4d52d0a7a065d7d649c4a1c5faa0dcc","src/stub/mod.rs":"6a7fec504a52d403b0241b18cd8b95088a31807571f4c0a67e4055afc74f4453","src/stub/transaction.rs":"8655bc37b69c318ff0bc69a62fcb31820eb6ad7921a53e0cecffa15e80d97630","src/u2fhid-capi.h":"fc2575f720ab8f6bc0c523c57310f35c464576bd5150c3c2b1873d3abde5909b","src/u2fprotocol.rs":"77b6d5005d8b3d98cd96e480013c1e97155da5df3cf5e19819ee82ac8e3b6c7d","src/u2ftypes.rs":"a28c07956a339d97d37f91b7257d1a5d1ea3b34f5c37bb9da0e17490115e5d8d","src/util.rs":"70c8b9b8d90e6d581a7d2568aeff3bbde6c2d9f3864cee9fbc2486c1f3002a13","src/windows/device.rs":"86a6ecc239608977a963f375336780746e90e95c3eb9ff303347beb983c40ab6","src/windows/mod.rs":"218e7f2fe91ecb390c12bba5a5ffdad2c1f0b22861c937f4d386262e5b3dd617","src/windows/monitor.rs":"d8e8316e5bd9fc6ebed737bd8d6e0713c99287aca04f392f6319cdfd8576f754","src/windows/transaction.rs":"1b9a5af866048911ccaec8c94b698b28ae1b80e3d4842f9d6ed38462f459c796","src/windows/winapi.rs":"a4286fd5e8dcb178e37df512ba7752b2a3c38fe30e1176022767d2c05c242bf8"},"package":"ec149e5d5d4caa2c9ead53a8ce1ea9c4204c388c65bf3b96c2d1dc0fcf4aeb66"}
+\ No newline at end of file
++{"files":{".clippy.toml":"e4825bd4c3e9b0d59a10f4427b9d979a3bc09ed99002cf4d37da79a9e09d7af2",".travis.yml":"0fea6ccda66d81d7d5282bac3234e0840c60923fe6370d46b30a1d1dab47d23d","Cargo.toml":"46b700225274e99b1f2a5f289b1f7e56d46bbe3d39655b4750667bbbb0f83749","LICENSE":"e147f11fd8c5b7d151db93eabbb02ddb8b481082047008062025afd1ff7e2a27","README.md":"1c291ddb3f131b55e706f13a98eec871055ceb17ef502ce75f608b67136cc7c3","build.rs":"7273d026bcc1ef3e4ebf73b60779e8a921193e154c955ec119f00b8144ef846f","examples/main.rs":"7af9e288b1836fb9362589b6bf54c1f1d277bdf64df60c1caccef98c1bfe792c","rustfmt.toml":"de4e1daab481c1572805aed3e51e72c5dc1b3e5af757bc675e1717b251c6e922","src/capi.rs":"33b91e8e43003fb11b0fbb4ea72e4a5dba8f4dcc11e2503a8186eaea020c13c3","src/consts.rs":"4c34980f94d1017e5e75e29b26750c1678e0609c9227296951ffbb9e180a5adf","src/freebsd/device.rs":"914ac446ff24cc3fc050732372e286e1fedf8341a8d4754e392bc9f38393b142","src/freebsd/mod.rs":"42dcb57fbeb00140003a8ad39acac9b547062b8f281a3fa5deb5f92a6169dde6","src/freebsd/monitor.rs":"3683370931b15f05403d240a788a87b1bea801284ee74b849e1f330a4a231dd0","src/freebsd/transaction.rs":"e3615cfdd7f23e9a80a53c32e0fa2a5ae290a432b009bed2b2e74e0df77f8266","src/freebsd/uhid.rs":"d19ade6e808e63981ba5f93d482d676ffa9dff29cb2b7011486591f69ddbbdcd","src/hidproto.rs":"966ee74341e2ecff262e5490f99dcc9b9f9427451f3ded1b9cb9698a6984a3cc","src/lib.rs":"4b43ad18b4eae9356ba6d7954542a38f3015ab8a72ab1fde28169aaf343721d8","src/linux/device.rs":"2271fbb8d176ec01f83a899c0c8194a954465fdd8670a9b136ab88baaba2ee48","src/linux/hidraw.rs":"0d5804d1cd99e7c30c8bde3089f8ed98d7d683d3cd487821e29b133b1ee90228","src/linux/hidwrapper.h":"72785db3a9b27ea72b6cf13a958fee032af54304522d002f56322473978a20f9","src/linux/hidwrapper.rs":"b6dfb20e16f97eb534dfa9742b97443368f08fde962d789f044ec8cc2536502f","src/linux/ioctl_powerpc64le.rs":"8c698780df59ba0215a02b88569f48a0b384bfc1c0eaca34a2f2578c0104e439","src/linux/ioctl_x86_64.rs":"dc072df769e4a99c1cadc019041123966792b97db3a2b0f660099d8decce9a14","src/linux/mod.rs":"9dacd694fdb52911a5b22f97ea22ff9505f05a246700dd10e72d4186ce369631","src/linux/monitor.rs":"876d4e095d77858412c61d35560a3b85855a9c00beea6950b5f50796d8fd3eab","src/linux/transaction.rs":"e3615cfdd7f23e9a80a53c32e0fa2a5ae290a432b009bed2b2e74e0df77f8266","src/macos/device.rs":"57186092fd937124f96afacef57d0493efce86553ac50d527e6365b93eaabddf","src/macos/iokit.rs":"a0fd818224718e96ad5d106dfc235f4bc9218a59f5114b9f9825abe3ee62bce7","src/macos/mod.rs":"333e561554fc901d4f6092f6e4c85823e2b0c4ff31c9188d0e6d542b71a0a07c","src/macos/monitor.rs":"1f132a8566858b22309b33f8ae96d5596c42f515785be841bb51db80e20471d1","src/macos/transaction.rs":"b8e362575b2bcc54232022131bfa073d605969119326dcb549f4d87037a31541","src/manager.rs":"7428fc23038b004841936d8f27f8dc33234d5c06361efa75b73c7a5c035dae75","src/openbsd/bindings.rs":"6a9eb45330db2658608aebc686c0a4dd13891dc658b3c53e1f2be9e9d129e7df","src/openbsd/device.rs":"698fcd06b63a1541c2f3c7016e3cc1ced76f95f43abd88f7d6f70d1610fa64e4","src/openbsd/mod.rs":"1ef7b81131c1dadb89675202e0bcf95e82b475e6fd72f64f44b92ba3ab4dbaa4","src/openbsd/monitor.rs":"db95a42af94c618f062312eb80ef889e293a33605e5841a859eff0dbf2cfe7a7","src/openbsd/transaction.rs":"92b47d064c1fa5fe2674f65d06c519601480fc1c2b03667ade19a186a6ec9d13","src/openbsd/usbhid.rs":"0b10580c8381215c564d4e226941093a59dd6fe9ceea8a565be51af44a274284","src/openbsd/wrapper.h":"679b0817b9d38a55583caff4a9d25a30f4ed05bd689badd974b1585c9fecd3e4","src/openbsd/wrapper.rs":"de1d032fe96a9b07391fa5f878cb697024f7c6171d26c75092fad087c62cf256","src/statemachine.rs":"28477fba601f5086b85e911da1e4f04af3f0060329e6e0e1172b960f9c52fd41","src/stub/device.rs":"32e134fc8826667d16b02fe32831fc29f4d52d0a7a065d7d649c4a1c5faa0dcc","src/stub/mod.rs":"6a7fec504a52d403b0241b18cd8b95088a31807571f4c0a67e4055afc74f4453","src/stub/transaction.rs":"8655bc37b69c318ff0bc69a62fcb31820eb6ad7921a53e0cecffa15e80d97630","src/u2fhid-capi.h":"fc2575f720ab8f6bc0c523c57310f35c464576bd5150c3c2b1873d3abde5909b","src/u2fprotocol.rs":"77b6d5005d8b3d98cd96e480013c1e97155da5df3cf5e19819ee82ac8e3b6c7d","src/u2ftypes.rs":"a28c07956a339d97d37f91b7257d1a5d1ea3b34f5c37bb9da0e17490115e5d8d","src/util.rs":"53338654dda59bcd4afd0f50650c0ba8d7f172d6f5a0d67109b0f9f9f9b2f7d1","src/windows/device.rs":"86a6ecc239608977a963f375336780746e90e95c3eb9ff303347beb983c40ab6","src/windows/mod.rs":"218e7f2fe91ecb390c12bba5a5ffdad2c1f0b22861c937f4d386262e5b3dd617","src/windows/monitor.rs":"d8e8316e5bd9fc6ebed737bd8d6e0713c99287aca04f392f6319cdfd8576f754","src/windows/transaction.rs":"1b9a5af866048911ccaec8c94b698b28ae1b80e3d4842f9d6ed38462f459c796","src/windows/winapi.rs":"a4286fd5e8dcb178e37df512ba7752b2a3c38fe30e1176022767d2c05c242bf8"},"package":null}
+\ No newline at end of file
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__clippy_toml
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__clippy_toml
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__clippy_toml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__clippy_toml
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,8 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/.clippy.toml
+--- third_party/rust/authenticator/.clippy.toml.orig
++++ third_party/rust/authenticator/.clippy.toml
+@@ -0,0 +1 @@
++type-complexity-threshold = 384
+\ No newline at end of file
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__travis_yml
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__travis_yml
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__travis_yml
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator__travis_yml
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,48 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/.travis.yml
+--- third_party/rust/authenticator/.travis.yml.orig
++++ third_party/rust/authenticator/.travis.yml
+@@ -0,0 +1,42 @@
++sudo: false
++language: rust
++cache: cargo
++rust:
++ - stable
++ - beta
++ - nightly
++
++matrix:
++ allow_failures:
++ - rust: nightly
++
++addons:
++ apt:
++ packages:
++ - build-essential
++ - libudev-dev
++
++before_install:
++ - pkg-config --list-all
++ - pkg-config --libs libudev
++ - pkg-config --modversion libudev
++
++install:
++ - rustup install nightly
++ - rustup component add rustfmt-preview
++ - rustup component add clippy-preview
++
++script:
++- |
++ if [ "$TRAVIS_RUST_VERSION" == "nightly" ] ; then
++ export
ASAN_OPTIONS="detect_odr_violation=1:leak_check_at_exit=0:detect_leaks=0"
++ export RUSTFLAGS="-Z sanitizer=address"
++ fi
++- |
++ if [ "$TRAVIS_RUST_VERSION" == "stable" ] ; then
++ echo "Running rustfmt"
++ cargo fmt --all -- --check
++ echo "Running clippy"
++ cargo clippy --all-targets -- -A renamed_and_removed_lints -A
clippy::new-ret-no-self -D warnings
++ fi
++- cargo test
Index: www/mozilla-firefox/patches/patch-third_party_rust_authenticator_build_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_build_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_build_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ www/mozilla-firefox/patches/patch-third_party_rust_authenticator_build_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,92 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/build.rs
+--- third_party/rust/authenticator/build.rs.orig
++++ third_party/rust/authenticator/build.rs
+@@ -0,0 +1,86 @@
++#[cfg(all(target_os = "linux", feature = "binding-recompile"))]
++extern crate bindgen;
++
++#[cfg(all(target_os = "linux", feature = "binding-recompile"))]
++use std::path::PathBuf;
++
++#[cfg(all(target_os = "openbsd", feature = "binding-recompile"))]
++use std::path::PathBuf;
++
++#[cfg(any(
++ all(not(target_os = "linux"), not(target_os = "openbsd")),
++ all(not(feature = "binding-recompile"), not(target_os = "openbsd")),
++))]
++fn main() {}
++
++#[cfg(all(target_os = "linux", feature = "binding-recompile"))]
++fn main() {
++ let bindings = bindgen::Builder::default()
++ .header("src/linux/hidwrapper.h")
++ .whitelist_var("_HIDIOCGRDESCSIZE")
++ .whitelist_var("_HIDIOCGRDESC")
++ .generate()
++ .expect("Unable to get hidraw bindings");
++
++ let out_path = PathBuf::new();
++ let name = if cfg!(target_arch = "x86") {
++ "ioctl_x86.rs"
++ } else if cfg!(target_arch = "x86_64") {
++ "ioctl_x86_64.rs"
++ } else if cfg!(all(target_arch = "mips", target_endian = "big")) {
++ "ioctl_mipsbe.rs"
++ } else if cfg!(all(target_arch = "mips", target_endian = "little")) {
++ "ioctl_mipsle.rs"
++ } else if cfg!(all(target_arch = "powerpc", target_endian = "little")) {
++ "ioctl_powerpcle.rs"
++ } else if cfg!(all(target_arch = "powerpc", target_endian = "big")) {
++ "ioctl_powerpcbe.rs"
++ } else if cfg!(all(target_arch = "powerpc64", target_endian = "little")) {
++ "ioctl_powerpc64le.rs"
++ } else if cfg!(all(target_arch = "powerpc64", target_endian = "big")) {
++ "ioctl_powerpc64be.rs"
++ } else if cfg!(all(target_arch = "arm", target_endian = "little")) {
++ "ioctl_armle.rs"
++ } else if cfg!(all(target_arch = "arm", target_endian = "big")) {
++ "ioctl_armbe.rs"
++ } else if cfg!(all(target_arch = "aarch64", target_endian = "little")) {
++ "ioctl_aarch64le.rs"
++ } else if cfg!(all(target_arch = "aarch64", target_endian = "big")) {
++ "ioctl_aarch64be.rs"
++ } else {
++ panic!("architecture not supported");
++ };
++ bindings
++ .write_to_file(out_path.join("src").join("linux").join(name))
++ .expect("Couldn't write hidraw bindings");
++}
++
++#[cfg(target_os = "openbsd")]
++fn link_lib() {
++ println!("cargo:rustc-link-search=native=/usr/lib");
++ println!("cargo:rustc-link-lib=static=usbhid");
++}
++
++#[cfg(all(target_os = "openbsd", feature = "binding-recompile"))]
++fn main() {
++ link_lib();
++
++ let bindings = bindgen::Builder::default()
++ .header("src/openbsd/wrapper.h")
++ .whitelist_var("^IOC.*")
++ .whitelist_type("^usb_device_info")
++ .whitelist_type("^hid_.*")
++ .whitelist_function("^hid_.*")
++ .generate()
++ .expect("Unable to get usbhid bindings");
++
++ let out_path = PathBuf::from("src/openbsd/bindings.rs");
++ bindings
++ .write_to_file(out_path)
++ .expect("Couldn't write usbhid bindings");
++}
++
++#[cfg(all(target_os = "openbsd", not(feature = "binding-recompile")))]
++fn main() {
++ link_lib();
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_lib_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_lib_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_lib_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++ www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_lib_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,24 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/lib.rs
+--- third_party/rust/authenticator/src/lib.rs.orig
++++ third_party/rust/authenticator/src/lib.rs
+@@ -22,6 +22,10 @@ extern crate devd_rs;
+ #[path = "freebsd/mod.rs"]
+ pub mod platform;
+
++#[cfg(any(target_os = "openbsd"))]
++#[path = "openbsd/mod.rs"]
++pub mod platform;
++
+ #[cfg(any(target_os = "macos"))]
+ extern crate core_foundation;
+
+@@ -36,6 +40,7 @@ pub mod platform;
+ #[cfg(not(any(
+ target_os = "linux",
+ target_os = "freebsd",
++ target_os = "openbsd",
+ target_os = "macos",
+ target_os = "windows"
+ )))]
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidraw_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidraw_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidraw_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidraw_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,74 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/hidraw.rs
+--- third_party/rust/authenticator/src/linux/hidraw.rs.orig
++++ third_party/rust/authenticator/src/linux/hidraw.rs
+@@ -6,9 +6,9 @@
+ extern crate libc;
+
+ use std::io;
+-use std::mem;
+ use std::os::unix::io::RawFd;
+
++use super::hidwrapper::{_HIDIOCGRDESC, _HIDIOCGRDESCSIZE};
+ use hidproto::*;
+ use util::{from_unix_result, io_err};
+
+@@ -19,42 +19,26 @@ pub struct LinuxReportDescriptor {
+ value: [u8; 4096],
+ }
+
+-const NRBITS: u32 = 8;
+-const TYPEBITS: u32 = 8;
+-
+-const READ: u8 = 2;
+-const SIZEBITS: u8 = 14;
+-
+-const NRSHIFT: u32 = 0;
+-const TYPESHIFT: u32 = NRSHIFT + NRBITS as u32;
+-const SIZESHIFT: u32 = TYPESHIFT + TYPEBITS as u32;
+-const DIRSHIFT: u32 = SIZESHIFT + SIZEBITS as u32;
+-
+-// https://github.com/torvalds/linux/blob/master/include/uapi/linux/hid.h
+ const HID_MAX_DESCRIPTOR_SIZE: usize = 4096;
+
+-macro_rules! ioctl {
+- ($dir:expr, $name:ident, $ioty:expr, $nr:expr; $ty:ty) => {
+- pub unsafe fn $name(fd: libc::c_int, val: *mut $ty) ->
io::Result<libc::c_int> {
+- let size = mem::size_of::<$ty>();
+- let ioc = (($dir as u32) << DIRSHIFT)
+- | (($ioty as u32) << TYPESHIFT)
+- | (($nr as u32) << NRSHIFT)
+- | ((size as u32) << SIZESHIFT);
++#[cfg(not(target_env = "musl"))]
++type IocType = libc::c_ulong;
++#[cfg(target_env = "musl")]
++type IocType = libc::c_int;
+
+- #[cfg(not(target_env = "musl"))]
+- type IocType = libc::c_ulong;
+- #[cfg(target_env = "musl")]
+- type IocType = libc::c_int;
+-
+- from_unix_result(libc::ioctl(fd, ioc as IocType, val))
+- }
+- };
++pub unsafe fn hidiocgrdescsize(
++ fd: libc::c_int,
++ val: *mut ::libc::c_int,
++) -> io::Result<libc::c_int> {
++ from_unix_result(libc::ioctl(fd, _HIDIOCGRDESCSIZE as IocType, val))
+ }
+
+-// https://github.com/torvalds/linux/blob/master/include/uapi/linux/hidraw.h
+-ioctl!(READ, hidiocgrdescsize, b'H', 0x01; ::libc::c_int);
+-ioctl!(READ, hidiocgrdesc, b'H', 0x02; /*struct*/ LinuxReportDescriptor);
++pub unsafe fn hidiocgrdesc(
++ fd: libc::c_int,
++ val: *mut LinuxReportDescriptor,
++) -> io::Result<libc::c_int> {
++ from_unix_result(libc::ioctl(fd, _HIDIOCGRDESC as IocType, val))
++}
+
+ pub fn is_u2f_device(fd: RawFd) -> bool {
+ match read_report_descriptor(fd) {
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_h
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_h
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_h
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,18 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/hidwrapper.h
+--- third_party/rust/authenticator/src/linux/hidwrapper.h.orig
++++ third_party/rust/authenticator/src/linux/hidwrapper.h
+@@ -0,0 +1,12 @@
++#include<sys/ioctl.h>
++#include<linux/hidraw.h>
++
++/* we define these constants to work around the fact that bindgen
++ can't deal with the _IOR macro function. We let cpp deal with it
++ for us. */
++
++const __u32 _HIDIOCGRDESCSIZE = HIDIOCGRDESCSIZE;
++#undef HIDIOCGRDESCSIZE
++
++const __u32 _HIDIOCGRDESC = HIDIOCGRDESC;
++#undef HIDIOCGRDESC
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_hidwrapper_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,48 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/hidwrapper.rs
+--- third_party/rust/authenticator/src/linux/hidwrapper.rs.orig
++++ third_party/rust/authenticator/src/linux/hidwrapper.rs
+@@ -0,0 +1,42 @@
++#![allow(non_upper_case_globals)]
++#![allow(non_camel_case_types)]
++#![allow(non_snake_case)]
++// sadly we need this file so we can avoid the suprious warnings that
++// would come with bindgen, as well as to avoid cluttering the mod.rs
++// with spurious architecture specific modules.
++
++#[cfg(target_arch = "x86")]
++include!("ioctl_x86.rs");
++
++#[cfg(target_arch = "x86_64")]
++include!("ioctl_x86_64.rs");
++
++#[cfg(all(target_arch = "mips", target_endian = "little"))]
++include!("ioctl_mipsle.rs");
++
++#[cfg(all(target_arch = "mips", target_endian = "big"))]
++include!("ioctl_mipsbe.rs");
++
++#[cfg(all(target_arch = "powerpc", target_endian = "little"))]
++include!("ioctl_powerpcle.rs");
++
++#[cfg(all(target_arch = "powerpc", target_endian = "big"))]
++include!("ioctl_powerpcbe.rs");
++
++#[cfg(all(target_arch = "powerpc64", target_endian = "little"))]
++include!("ioctl_powerpc64le.rs");
++
++#[cfg(all(target_arch = "powerpc64", target_endian = "big"))]
++include!("ioctl_powerpc64be.rs");
++
++#[cfg(all(target_arch = "arm", target_endian = "little"))]
++include!("ioctl_armle.rs");
++
++#[cfg(all(target_arch = "arm", target_endian = "big"))]
++include!("ioctl_armbe.rs");
++
++#[cfg(all(target_arch = "aarch64", target_endian = "little"))]
++include!("ioctl_aarch64le.rs");
++
++#[cfg(all(target_arch = "aarch64", target_endian = "big"))]
++include!("ioctl_aarch64be.rs");
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_powerpc64le_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_powerpc64le_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_powerpc64le_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_powerpc64le_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,10 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/ioctl_powerpc64le.rs
+--- third_party/rust/authenticator/src/linux/ioctl_powerpc64le.rs.orig
++++ third_party/rust/authenticator/src/linux/ioctl_powerpc64le.rs
+@@ -0,0 +1,3 @@
++/* automatically generated by rust-bindgen */
++
++pub type __u32 = :: std :: os :: raw :: c_uint ; pub const _HIDIOCGRDESCSIZE
: __u32 = 1074022401 ; pub const _HIDIOCGRDESC : __u32 = 1342457858 ;
+\ No newline at end of file
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_x86_64_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_x86_64_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_x86_64_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_ioctl_x86_64_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,10 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/ioctl_x86_64.rs
+--- third_party/rust/authenticator/src/linux/ioctl_x86_64.rs.orig
++++ third_party/rust/authenticator/src/linux/ioctl_x86_64.rs
+@@ -0,0 +1,3 @@
++/* automatically generated by rust-bindgen */
++
++pub type __u32 = :: std :: os :: raw :: c_uint ; pub const _HIDIOCGRDESCSIZE
: __u32 = 2147764225 ; pub const _HIDIOCGRDESC : __u32 = 2416199682 ;
+\ No newline at end of file
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_mod_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_mod_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_mod_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_linux_mod_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,12 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/linux/mod.rs
+--- third_party/rust/authenticator/src/linux/mod.rs.orig
++++ third_party/rust/authenticator/src/linux/mod.rs
+@@ -5,5 +5,6 @@
+ pub mod device;
+ pub mod transaction;
+
++mod hidwrapper;
+ mod hidraw;
+ mod monitor;
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_bindings_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_bindings_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_bindings_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_bindings_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,630 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/bindings.rs
+--- third_party/rust/authenticator/src/openbsd/bindings.rs.orig
++++ third_party/rust/authenticator/src/openbsd/bindings.rs
+@@ -0,0 +1,624 @@
++/* automatically generated by rust-bindgen */
++
++pub const IOCPARM_MASK: u32 = 8191;
++pub type __uint8_t = ::std::os::raw::c_uchar;
++pub type __uint16_t = ::std::os::raw::c_ushort;
++pub type __int32_t = ::std::os::raw::c_int;
++pub type __uint32_t = ::std::os::raw::c_uint;
++pub type u_int8_t = __uint8_t;
++pub type u_int16_t = __uint16_t;
++pub type u_int32_t = __uint32_t;
++#[repr(C)]
++#[derive(Copy, Clone)]
++pub struct usb_device_info {
++ pub udi_bus: u_int8_t,
++ pub udi_addr: u_int8_t,
++ pub udi_product: [::std::os::raw::c_char; 127usize],
++ pub udi_vendor: [::std::os::raw::c_char; 127usize],
++ pub udi_release: [::std::os::raw::c_char; 8usize],
++ pub udi_productNo: u_int16_t,
++ pub udi_vendorNo: u_int16_t,
++ pub udi_releaseNo: u_int16_t,
++ pub udi_class: u_int8_t,
++ pub udi_subclass: u_int8_t,
++ pub udi_protocol: u_int8_t,
++ pub udi_config: u_int8_t,
++ pub udi_speed: u_int8_t,
++ pub udi_port: u_int8_t,
++ pub udi_power: ::std::os::raw::c_int,
++ pub udi_nports: ::std::os::raw::c_int,
++ pub udi_devnames: [[::std::os::raw::c_char; 16usize]; 4usize],
++ pub udi_ports: [u_int32_t; 16usize],
++ pub udi_serial: [::std::os::raw::c_char; 127usize],
++}
++#[test]
++fn bindgen_test_layout_usb_device_info() {
++ assert_eq!(
++ ::std::mem::size_of::<usb_device_info>(),
++ 540usize,
++ concat!("Size of: ", stringify!(usb_device_info))
++ );
++ assert_eq!(
++ ::std::mem::align_of::<usb_device_info>(),
++ 4usize,
++ concat!("Alignment of ", stringify!(usb_device_info))
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_bus as
*const _ as usize },
++ 0usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_bus)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_addr as
*const _ as usize },
++ 1usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_addr)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_product as
*const _ as usize },
++ 2usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_product)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_vendor as
*const _ as usize },
++ 129usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_vendor)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_release as
*const _ as usize },
++ 256usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_release)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_productNo as
*const _ as usize },
++ 264usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_productNo)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_vendorNo as
*const _ as usize },
++ 266usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_vendorNo)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_releaseNo as
*const _ as usize },
++ 268usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_releaseNo)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_class as
*const _ as usize },
++ 270usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_class)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_subclass as
*const _ as usize },
++ 271usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_subclass)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_protocol as
*const _ as usize },
++ 272usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_protocol)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_config as
*const _ as usize },
++ 273usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_config)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_speed as
*const _ as usize },
++ 274usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_speed)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_port as
*const _ as usize },
++ 275usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_port)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_power as
*const _ as usize },
++ 276usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_power)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_nports as
*const _ as usize },
++ 280usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_nports)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_devnames as
*const _ as usize },
++ 284usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_devnames)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_ports as
*const _ as usize },
++ 348usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_ports)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<usb_device_info>())).udi_serial as
*const _ as usize },
++ 412usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(usb_device_info),
++ "::",
++ stringify!(udi_serial)
++ )
++ );
++}
++#[repr(C)]
++#[derive(Debug, Copy, Clone)]
++pub struct report_desc {
++ _unused: [u8; 0],
++}
++pub type report_desc_t = *mut report_desc;
++#[repr(C)]
++#[derive(Debug, Copy, Clone)]
++pub struct hid_data {
++ _unused: [u8; 0],
++}
++pub type hid_data_t = *mut hid_data;
++pub const hid_kind_hid_input: hid_kind = 0;
++pub const hid_kind_hid_output: hid_kind = 1;
++pub const hid_kind_hid_feature: hid_kind = 2;
++pub const hid_kind_hid_collection: hid_kind = 3;
++pub const hid_kind_hid_endcollection: hid_kind = 4;
++pub type hid_kind = u32;
++pub use self::hid_kind as hid_kind_t;
++#[repr(C)]
++#[derive(Debug, Copy, Clone)]
++pub struct hid_item {
++ pub _usage_page: u32,
++ pub logical_minimum: i32,
++ pub logical_maximum: i32,
++ pub physical_minimum: i32,
++ pub physical_maximum: i32,
++ pub unit_exponent: i32,
++ pub unit: i32,
++ pub report_size: i32,
++ pub report_ID: i32,
++ pub report_count: i32,
++ pub usage: u32,
++ pub usage_minimum: i32,
++ pub usage_maximum: i32,
++ pub designator_index: i32,
++ pub designator_minimum: i32,
++ pub designator_maximum: i32,
++ pub string_index: i32,
++ pub string_minimum: i32,
++ pub string_maximum: i32,
++ pub set_delimiter: i32,
++ pub collection: i32,
++ pub collevel: ::std::os::raw::c_int,
++ pub kind: hid_kind,
++ pub flags: u32,
++ pub pos: u32,
++ pub next: *mut hid_item,
++}
++#[test]
++fn bindgen_test_layout_hid_item() {
++ assert_eq!(
++ ::std::mem::size_of::<hid_item>(),
++ 112usize,
++ concat!("Size of: ", stringify!(hid_item))
++ );
++ assert_eq!(
++ ::std::mem::align_of::<hid_item>(),
++ 8usize,
++ concat!("Alignment of ", stringify!(hid_item))
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>()))._usage_page as *const _
as usize },
++ 0usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(_usage_page)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).logical_minimum as
*const _ as usize },
++ 4usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(logical_minimum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).logical_maximum as
*const _ as usize },
++ 8usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(logical_maximum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).physical_minimum as
*const _ as usize },
++ 12usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(physical_minimum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).physical_maximum as
*const _ as usize },
++ 16usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(physical_maximum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).unit_exponent as *const
_ as usize },
++ 20usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(unit_exponent)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).unit as *const _ as
usize },
++ 24usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(unit)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).report_size as *const _
as usize },
++ 28usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(report_size)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).report_ID as *const _
as usize },
++ 32usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(report_ID)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).report_count as *const
_ as usize },
++ 36usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(report_count)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).usage as *const _ as
usize },
++ 40usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(usage)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).usage_minimum as *const
_ as usize },
++ 44usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(usage_minimum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).usage_maximum as *const
_ as usize },
++ 48usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(usage_maximum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).designator_index as
*const _ as usize },
++ 52usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(designator_index)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).designator_minimum as
*const _ as usize },
++ 56usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(designator_minimum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).designator_maximum as
*const _ as usize },
++ 60usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(designator_maximum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).string_index as *const
_ as usize },
++ 64usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(string_index)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).string_minimum as
*const _ as usize },
++ 68usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(string_minimum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).string_maximum as
*const _ as usize },
++ 72usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(string_maximum)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).set_delimiter as *const
_ as usize },
++ 76usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(set_delimiter)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).collection as *const _
as usize },
++ 80usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(collection)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).collevel as *const _ as
usize },
++ 84usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(collevel)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).kind as *const _ as
usize },
++ 88usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(kind)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).flags as *const _ as
usize },
++ 92usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(flags)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).pos as *const _ as
usize },
++ 96usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(pos)
++ )
++ );
++ assert_eq!(
++ unsafe { &(*(::std::ptr::null::<hid_item>())).next as *const _ as
usize },
++ 104usize,
++ concat!(
++ "Offset of field: ",
++ stringify!(hid_item),
++ "::",
++ stringify!(next)
++ )
++ );
++}
++pub type hid_item_t = hid_item;
++extern "C" {
++ pub fn hid_get_report_desc(file: ::std::os::raw::c_int) -> report_desc_t;
++}
++extern "C" {
++ pub fn hid_use_report_desc(
++ data: *mut ::std::os::raw::c_uchar,
++ size: ::std::os::raw::c_uint,
++ ) -> report_desc_t;
++}
++extern "C" {
++ pub fn hid_dispose_report_desc(arg1: report_desc_t);
++}
++extern "C" {
++ pub fn hid_start_parse(
++ d: report_desc_t,
++ kindset: ::std::os::raw::c_int,
++ id: ::std::os::raw::c_int,
++ ) -> hid_data_t;
++}
++extern "C" {
++ pub fn hid_end_parse(s: hid_data_t);
++}
++extern "C" {
++ pub fn hid_get_item(s: hid_data_t, h: *mut hid_item_t) ->
::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_report_size(
++ d: report_desc_t,
++ k: hid_kind,
++ id: ::std::os::raw::c_int,
++ ) -> ::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_locate(
++ d: report_desc_t,
++ usage: ::std::os::raw::c_uint,
++ k: hid_kind,
++ h: *mut hid_item_t,
++ id: ::std::os::raw::c_int,
++ ) -> ::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_usage_page(i: ::std::os::raw::c_int) -> *const
::std::os::raw::c_char;
++}
++extern "C" {
++ pub fn hid_usage_in_page(u: ::std::os::raw::c_uint) -> *const
::std::os::raw::c_char;
++}
++extern "C" {
++ pub fn hid_init(file: *const ::std::os::raw::c_char);
++}
++extern "C" {
++ pub fn hid_start(file: *const ::std::os::raw::c_char) ->
::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_parse_usage_in_page(name: *const ::std::os::raw::c_char) ->
::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_parse_usage_page(name: *const ::std::os::raw::c_char) ->
::std::os::raw::c_int;
++}
++extern "C" {
++ pub fn hid_get_data(p: *const ::std::os::raw::c_void, h: *const
hid_item_t) -> i32;
++}
++extern "C" {
++ pub fn hid_set_data(p: *mut ::std::os::raw::c_void, h: *const hid_item_t,
data: i32);
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_device_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_device_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_device_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_device_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,162 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/device.rs
+--- third_party/rust/authenticator/src/openbsd/device.rs.orig
++++ third_party/rust/authenticator/src/openbsd/device.rs
+@@ -0,0 +1,156 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++extern crate libc;
++
++use std::ffi::{CString, OsString};
++use std::io::{Read, Result, Write};
++use std::mem;
++use std::os::unix::prelude::*;
++
++use consts::CID_BROADCAST;
++use platform::usbhid;
++use u2ftypes::U2FDevice;
++use util::{from_unix_result, io_err};
++
++#[derive(Debug)]
++pub struct Device {
++ path: OsString,
++ fd: libc::c_int,
++ cid: [u8; 4],
++ usbhid: usbhid::UsbHid,
++}
++
++impl Device {
++ pub fn new(path: OsString) -> Result<Self> {
++ let cstr = CString::new(path.as_bytes())?;
++ let fd = unsafe { libc::open(cstr.as_ptr(), libc::O_RDWR) };
++ let fd = from_unix_result(fd)?;
++ debug!("device found: {:?} fd {}", path, fd);
++ Ok(Self {
++ path,
++ fd,
++ cid: CID_BROADCAST,
++ usbhid: Default::default(),
++ })
++ }
++
++ pub fn is_u2f(&mut self) -> bool {
++ if !usbhid::is_u2f_device(self.fd) {
++ return false;
++ }
++ debug!("device {:?} is U2F/FIDO", self.path);
++ match usbhid::open_u2f_device(self.fd) {
++ Ok(usbhid) => {
++ self.usbhid = usbhid;
++ }
++ Err(err) => {
++ debug!("device {:?} error: {}", self.path, err);
++ return false;
++ }
++ }
++
++ // From OpenBSD's libfido2 in 6.6-current:
++ // "OpenBSD (as of 201910) has a bug that causes it to lose
++ // track of the DATA0/DATA1 sequence toggle across uhid device
++ // open and close. This is a terrible hack to work around it."
++ match self.ping() {
++ Ok(_) => true,
++ Err(err) => {
++ debug!("device {:?} is not responding: {}", self.path, err);
++ false
++ }
++ }
++ }
++
++ fn ping(&mut self) -> Result<()> {
++ let capacity = 256;
++
++ if capacity < self.usbhid.out_len + 1 {
++ return Err(io_err("reported out len too small"));
++ }
++
++ for _ in 0..10 {
++ let mut data = vec![0u8; capacity];
++
++ // Send 1 byte ping
++ data[..8].copy_from_slice(&[0, 0xff, 0xff, 0xff, 0xff, 0x81, 0,
1]);
++ self.write_all(&data[0..=self.usbhid.out_len])?;
++
++ // Wait for response
++ let mut pfd: libc::pollfd = unsafe { mem::zeroed() };
++ pfd.fd = self.fd;
++ pfd.events = libc::POLLIN;
++ if from_unix_result(unsafe { libc::poll(&mut pfd, 1, 100) })? ==
0 {
++ debug!("device {:?} timeout", self.path);
++ continue;
++ }
++
++ // Read response
++ self.read_exact(&mut data[0..self.usbhid.out_len])?;
++
++ return Ok(());
++ }
++
++ Err(io_err("no response from device"))
++ }
++}
++
++impl Drop for Device {
++ fn drop(&mut self) {
++ // Close the fd, ignore any errors.
++ let _ = unsafe { libc::close(self.fd) };
++ debug!("device {:?} closed", self.path);
++ }
++}
++
++impl PartialEq for Device {
++ fn eq(&self, other: &Device) -> bool {
++ self.path == other.path
++ }
++}
++
++impl Read for Device {
++ fn read(&mut self, buf: &mut [u8]) -> Result<usize> {
++ if buf.len() != self.usbhid.in_len {
++ return Err(io_err("invalid read length"));
++ }
++ let buf_ptr = buf.as_mut_ptr() as *mut libc::c_void;
++ let rv = unsafe { libc::read(self.fd, buf_ptr, buf.len()) };
++ if from_unix_result(rv as usize)? != buf.len() {
++ return Err(io_err("invalid read result"));
++ }
++ Ok(buf.len())
++ }
++}
++
++impl Write for Device {
++ fn write(&mut self, buf: &[u8]) -> Result<usize> {
++ if buf.len() != self.usbhid.out_len + 1 {
++ return Err(io_err("invalid write length"));
++ }
++ // Always skip the first byte (report number)
++ let data = &buf[1..];
++ let data_ptr = data.as_ptr() as *const libc::c_void;
++ let rv = unsafe { libc::write(self.fd, data_ptr, data.len()) };
++ if from_unix_result(rv as usize)? != data.len() {
++ return Err(io_err("invalid write result"));
++ }
++ Ok(buf.len())
++ }
++
++ fn flush(&mut self) -> Result<()> {
++ Ok(())
++ }
++}
++
++impl U2FDevice for Device {
++ fn get_cid(&self) -> &[u8; 4] {
++ &self.cid
++ }
++
++ fn set_cid(&mut self, cid: [u8; 4]) {
++ self.cid = cid;
++ }
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_mod_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_mod_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_mod_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_mod_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/mod.rs
+--- third_party/rust/authenticator/src/openbsd/mod.rs.orig
++++ third_party/rust/authenticator/src/openbsd/mod.rs
+@@ -0,0 +1,10 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++pub mod device;
++pub mod transaction;
++
++mod monitor;
++mod usbhid;
++mod wrapper;
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_monitor_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_monitor_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_monitor_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_monitor_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,117 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/monitor.rs
+--- third_party/rust/authenticator/src/openbsd/monitor.rs.orig
++++ third_party/rust/authenticator/src/openbsd/monitor.rs
+@@ -0,0 +1,111 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++use std::collections::HashMap;
++use std::ffi::{CString, OsString};
++use std::io;
++use std::os::unix::ffi::OsStrExt;
++use std::path::PathBuf;
++use std::sync::Arc;
++use std::thread;
++use std::time::Duration;
++
++use runloop::RunLoop;
++use util::from_unix_result;
++
++const POLL_TIMEOUT: u64 = 500;
++
++pub struct Monitor<F>
++where
++ F: Fn(OsString, &dyn Fn() -> bool) + Sync,
++{
++ runloops: HashMap<OsString, RunLoop>,
++ new_device_cb: Arc<F>,
++}
++
++impl<F> Monitor<F>
++where
++ F: Fn(OsString, &dyn Fn() -> bool) + Send + Sync + 'static,
++{
++ pub fn new(new_device_cb: F) -> Self {
++ Self {
++ runloops: HashMap::new(),
++ new_device_cb: Arc::new(new_device_cb),
++ }
++ }
++
++ pub fn run(&mut self, alive: &dyn Fn() -> bool) -> io::Result<()> {
++ // Loop until we're stopped by the controlling thread, or fail.
++ while alive() {
++ // Iterate the first 100 uhid(4) devices.
++ //
++ // We could scan the /dev directory for all existing uhid
++ // devices but this wouldn't work under the strict
++ // unveil(2) policy of Firefox under OpenBSD that only
++ // allows direct access to certain files under /dev.
++ for path in (0..100)
++ .map(|unit| PathBuf::from(&format!("/dev/uhid{}", unit)))
++ .filter(|path| path.exists())
++ {
++ let os_path = path.as_os_str().to_os_string();
++ let cstr = CString::new(os_path.as_bytes())?;
++
++ // Try to open the device.
++ let fd = unsafe { libc::open(cstr.as_ptr(), libc::O_RDWR) };
++ match from_unix_result(fd) {
++ Ok(fd) => {
++ // The device is available if it can be opened.
++ unsafe { libc::close(fd) };
++ self.add_device(os_path);
++ }
++ Err(ref err) if err.raw_os_error() == Some(libc::EBUSY)
=> {
++ // The device is available but currently in use.
++ self.add_device(os_path);
++ }
++ _ => {
++ // libc::ENODEV or any other error.
++ self.remove_device(os_path);
++ }
++ }
++ }
++
++ thread::sleep(Duration::from_millis(POLL_TIMEOUT));
++ }
++
++ // Remove all tracked devices.
++ self.remove_all_devices();
++
++ Ok(())
++ }
++
++ fn add_device(&mut self, path: OsString) {
++ if !self.runloops.contains_key(&path) {
++ let f = self.new_device_cb.clone();
++ let key = path.clone();
++
++ let runloop = RunLoop::new(move |alive| {
++ if alive() {
++ f(path, alive);
++ }
++ });
++
++ if let Ok(runloop) = runloop {
++ self.runloops.insert(key, runloop);
++ }
++ }
++ }
++
++ fn remove_device(&mut self, path: OsString) {
++ if let Some(runloop) = self.runloops.remove(&path) {
++ runloop.cancel();
++ }
++ }
++
++ fn remove_all_devices(&mut self) {
++ while !self.runloops.is_empty() {
++ let path = self.runloops.keys().next().unwrap().clone();
++ self.remove_device(path);
++ }
++ }
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_transaction_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_transaction_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_transaction_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_transaction_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,55 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/transaction.rs
+--- third_party/rust/authenticator/src/openbsd/transaction.rs.orig
++++ third_party/rust/authenticator/src/openbsd/transaction.rs
+@@ -0,0 +1,49 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++use platform::monitor::Monitor;
++use runloop::RunLoop;
++use std::ffi::OsString;
++use util::OnceCallback;
++
++pub struct Transaction {
++ // Handle to the thread loop.
++ thread: Option<RunLoop>,
++}
++
++impl Transaction {
++ pub fn new<F, T>(
++ timeout: u64,
++ callback: OnceCallback<T>,
++ new_device_cb: F,
++ ) -> Result<Self, ::Error>
++ where
++ F: Fn(OsString, &dyn Fn() -> bool) + Sync + Send + 'static,
++ T: 'static,
++ {
++ let thread = RunLoop::new_with_timeout(
++ move |alive| {
++ // Create a new device monitor.
++ let mut monitor = Monitor::new(new_device_cb);
++
++ // Start polling for new devices.
++ try_or!(monitor.run(alive), |_|
callback.call(Err(::Error::Unknown)));
++
++ // Send an error, if the callback wasn't called already.
++ callback.call(Err(::Error::NotAllowed));
++ },
++ timeout,
++ )
++ .map_err(|_| ::Error::Unknown)?;
++
++ Ok(Self {
++ thread: Some(thread),
++ })
++ }
++
++ pub fn cancel(&mut self) {
++ // This must never be None.
++ self.thread.take().unwrap().cancel();
++ }
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_usbhid_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_usbhid_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_usbhid_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_usbhid_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,137 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/usbhid.rs
+--- third_party/rust/authenticator/src/openbsd/usbhid.rs.orig
++++ third_party/rust/authenticator/src/openbsd/usbhid.rs
+@@ -0,0 +1,131 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++extern crate libc;
++
++use std::ffi::CStr;
++use std::io::Result;
++use std::mem;
++use std::os::unix::io::RawFd;
++
++use platform::wrapper::*;
++use util::{from_unix_ptr, from_unix_result, io_err};
++
++#[derive(Default, Debug)]
++pub struct UsbHid {
++ pub in_len: usize,
++ pub out_len: usize,
++}
++
++const IOR: u32 = 0x4000_0000;
++const IOC_TYPESHIFT: u32 = 8;
++const IOC_SIZESHIFT: u32 = 16;
++
++macro_rules! ioctl {
++ ($dir:expr, $name:ident, $ioty:expr, $nr:expr; $ty:ty) => {
++ pub unsafe fn $name(fd: libc::c_int, val: *mut $ty) ->
Result<libc::c_int> {
++ let ioc = ($dir as u32)
++ | ((mem::size_of::<$ty>() as u32 & IOCPARM_MASK) <<
IOC_SIZESHIFT)
++ | (($ioty as u32) << IOC_TYPESHIFT)
++ | ($nr as u32);
++ from_unix_result(libc::ioctl(fd, ioc as libc::c_ulong, val))
++ }
++ };
++}
++
++// https://github.com/openbsd/src/blob/master/sys/dev/usb/usb.h
++ioctl!(IOR, usb_get_deviceinfo_ioctl, b'U', 112; usb_device_info);
++ioctl!(IOR, usb_get_report_id_ioctl, b'U', 25; i32);
++
++unsafe fn usbhid_is_u2f(fd: RawFd) -> Result<bool> {
++ // Get USB device info to make sure that it's a valid USB device.
++ let mut udi: usb_device_info = mem::zeroed();
++ let _ = usb_get_deviceinfo_ioctl(fd, &mut udi)?;
++
++ let vendor = CStr::from_ptr(udi.udi_vendor.as_ptr()).to_string_lossy();
++ let product = CStr::from_ptr(udi.udi_product.as_ptr()).to_string_lossy();
++ debug!(
++ "device vendor {} product {} ({:04x}:{:04x})",
++ vendor, product, udi.udi_vendorNo, udi.udi_productNo
++ );
++
++ // Get report descriptor.
++ let desc = from_unix_ptr(hid_get_report_desc(fd))?;
++
++ // Start parsing of the HID collection.
++ let kindset = 1 << hid_kind_hid_collection;
++ let hdata = match from_unix_ptr(hid_start_parse(desc, kindset, -1)) {
++ Ok(hdata) => hdata,
++ Err(err) => {
++ hid_dispose_report_desc(desc);
++ return Err(err);
++ }
++ };
++
++ // Find U2F/FIDO key.
++ let mut is_fido = false;
++ loop {
++ let mut hitem: hid_item = mem::zeroed();
++ if hid_get_item(hdata, &mut hitem) <= 0 {
++ break;
++ }
++ if (hitem._usage_page & 0xFFFF_0000) == 0xF1D0_0000 {
++ is_fido = true;
++ }
++ }
++
++ // Cleanup.
++ hid_end_parse(hdata);
++ hid_dispose_report_desc(desc);
++
++ Ok(is_fido)
++}
++
++unsafe fn usbhid_open_u2f(fd: RawFd) -> Result<UsbHid> {
++ let max_report_len = 1024; // this should be size of ucr_data
++
++ // Get USB device report ID.
++ let mut usb_report_id = 0;
++ let _ = usb_get_report_id_ioctl(fd, &mut usb_report_id)?;
++
++ // Get report descriptor.
++ let desc = from_unix_ptr(hid_get_report_desc(fd))?;
++
++ // Get the input report size.
++ let in_len = match hid_report_size(desc, hid_kind_hid_input,
usb_report_id) {
++ len if len > 0 && len <= max_report_len => len as usize,
++ _ => {
++ hid_dispose_report_desc(desc);
++ return Err(io_err("bad output report size"));
++ }
++ };
++
++ // Get the output report size.
++ let out_len = match hid_report_size(desc, hid_kind_hid_output,
usb_report_id) {
++ len if len > 0 && len <= max_report_len => len as usize,
++ _ => {
++ hid_dispose_report_desc(desc);
++ return Err(io_err("bad output report size"));
++ }
++ };
++
++ // Cleanup.
++ hid_dispose_report_desc(desc);
++
++ Ok(UsbHid { in_len, out_len })
++}
++
++pub fn is_u2f_device(fd: RawFd) -> bool {
++ match unsafe { usbhid_is_u2f(fd) } {
++ Ok(val) => val,
++ Err(err) => {
++ debug!("usbhid error {}", err);
++ false
++ }
++ }
++}
++
++pub fn open_u2f_device(fd: RawFd) -> Result<UsbHid> {
++ unsafe { usbhid_open_u2f(fd) }
++}
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_h
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_h
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_h
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_h
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,10 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/wrapper.h
+--- third_party/rust/authenticator/src/openbsd/wrapper.h.orig
++++ third_party/rust/authenticator/src/openbsd/wrapper.h
+@@ -0,0 +1,4 @@
++#include <sys/types.h>
++#include <sys/ioctl.h>
++#include <dev/usb/usb.h>
++#include <usbhid.h>
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_openbsd_wrapper_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,16 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/openbsd/wrapper.rs
+--- third_party/rust/authenticator/src/openbsd/wrapper.rs.orig
++++ third_party/rust/authenticator/src/openbsd/wrapper.rs
+@@ -0,0 +1,10 @@
++/* This Source Code Form is subject to the terms of the Mozilla Public
++ * License, v. 2.0. If a copy of the MPL was not distributed with this
++ * file, You can obtain one at http://mozilla.org/MPL/2.0/. */
++
++#![allow(non_upper_case_globals)]
++#![allow(non_camel_case_types)]
++#![allow(non_snake_case)]
++#![allow(unused)]
++
++include!("bindings.rs");
Index:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_util_rs
===================================================================
RCS file:
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_util_rs
diff -N
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_util_rs
--- /dev/null 1 Jan 1970 00:00:00 -0000
+++
www/mozilla-firefox/patches/patch-third_party_rust_authenticator_src_util_rs
10 Dec 2019 13:55:19 -0000
@@ -0,0 +1,30 @@
+$OpenBSD$
+
+Index: third_party/rust/authenticator/src/util.rs
+--- third_party/rust/authenticator/src/util.rs.orig
++++ third_party/rust/authenticator/src/util.rs
+@@ -56,6 +56,24 @@ pub fn from_unix_result<T: Signed>(rv: T) -> io::Resul
+ }
+ }
+
++#[cfg(any(target_os = "openbsd"))]
++pub fn from_unix_result<T: Signed>(rv: T) -> io::Result<T> {
++ if rv.is_negative() {
++ Err(io::Error::last_os_error())
++ } else {
++ Ok(rv)
++ }
++}
++
++#[cfg(any(target_os = "openbsd"))]
++pub fn from_unix_ptr<T>(ptr: *mut T) -> io::Result<*mut T> {
++ if ptr.is_null() {
++ Err(io_err("returned null pointer"))
++ } else {
++ Ok(ptr)
++ }
++}
++
+ pub fn io_err(msg: &str) -> io::Error {
+ io::Error::new(io::ErrorKind::Other, msg)
+ }
Index: www/mozilla-firefox/pkg/README
===================================================================
RCS file: /cvs/ports/www/mozilla-firefox/pkg/README,v
retrieving revision 1.25
diff -u -p -u -p -r1.25 README
--- www/mozilla-firefox/pkg/README 3 Dec 2019 17:00:46 -0000 1.25
+++ www/mozilla-firefox/pkg/README 10 Dec 2019 13:55:19 -0000
@@ -145,3 +145,23 @@ hardware must support at least OpenGL 4.
Check
https://wiki.mozilla.org/Platform/GFX/Quantum_Render for more details.
+
+Web Authentication
+==================
+Support for web authentication (WebAuthn) with U2F/FIDO-compatible
+security keys is supported but requires direct access to the uhid(4)
+USB device layer. This is currently not possible with the default
+sandbox under OpenBSD: the installed unveil(2) policy permits access
+to the first 10 '/dev/uhid*' devices but pledge(2) prevents the
+required USB/UHID ioctls.
+
+To enable U2F/FIDO support, a) make sure that the user has read/write
+to '/dev/uhid*' (this is the case if the user is a member of group
+wheel) and b) set 'pledge.main' to 'disable'. For example:
+
+# mkdir /etc/firefox && echo disable > /etc/firefox/pledge.main
+
+WARNING: While 'pledge.main' is already the weakest policy, compared
+to 'pledge.content' or 'pledge.gpu', disabling it weakens the
+sandboxed security of Firefox itself. It does not alter the
+protection that is offered by unveil(2).