pkgsrc-Changes archive

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index][Old Index]

CVS commit: pkgsrc/security/tor-browser



Module Name:    pkgsrc
Committed By:   riastradh
Date:           Mon Aug 17 06:58:32 UTC 2020

Modified Files:
        pkgsrc/security/tor-browser: distinfo
Added Files:
        pkgsrc/security/tor-browser/patches:
            patch-dom_webauthn_u2f-hid-rs_src_lib.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs
            patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs

Log Message:
security/tor-browser: Add U2F support to NetBSD.

The webauthn API is disabled by default in the Tor Browser:

https://gitlab.torproject.org/tpo/applications/tor-browser/-/issues/26614

In order to use it, risking the consequences since the Tor Project
has not audited its anonymity properties, you have to explicitly
enable security.webauthn.webauthn=true in about:config.

So if you definitely want to log into a web site using U2F in spite
of that, with location privacy but not anonymity, then these patches
now enable it to work on NetBSD (with the caveat that enabling
security.webauthn.webauthn=true applies also to any web site that
tries to use the webauthn API, not just the ones you want to log
into).


To generate a diff of this commit:
cvs rdiff -u -r1.25 -r1.26 pkgsrc/security/tor-browser/distinfo
cvs rdiff -u -r0 -r1.1 \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_lib.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs \
    pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs

Please note that diffs are not public domain; they are subject to the
copyright notices on the relevant files.

Modified files:

Index: pkgsrc/security/tor-browser/distinfo
diff -u pkgsrc/security/tor-browser/distinfo:1.25 pkgsrc/security/tor-browser/distinfo:1.26
--- pkgsrc/security/tor-browser/distinfo:1.25   Wed Jul 29 07:46:37 2020
+++ pkgsrc/security/tor-browser/distinfo        Mon Aug 17 06:58:32 2020
@@ -1,4 +1,4 @@
-$NetBSD: distinfo,v 1.25 2020/07/29 07:46:37 wiz Exp $
+$NetBSD: distinfo,v 1.26 2020/08/17 06:58:32 riastradh Exp $
 
 SHA1 (src-firefox-tor-browser-68.11.0esr-9.5-1-build1.tar.xz) = be69e804180d7cc1fb500b1a497f79ab41c4f0db
 RMD160 (src-firefox-tor-browser-68.11.0esr-9.5-1-build1.tar.xz) = 625ab420108a64c3f50f2c482190ece3afcbd974
@@ -16,6 +16,13 @@ SHA1 (patch-build_moz.configure_rust.con
 SHA1 (patch-config_gcc-stl-wrapper.template.h) = 11b45e0c7a9399c5b74b170648280a388dd67d89
 SHA1 (patch-dom_base_nsAttrName.h) = ac7ba441a3b27df2855cf2673eea36b1cb44ad49
 SHA1 (patch-dom_media_CubebUtils.cpp) = 3cd2c65ab281d802c56216565970450767a3fb24
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_lib.rs) = c0dfe8b1e7ebbc7c1d6066c204030f13b063b8d7
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs) = 091ffab5bd6a15425acb2ab023cc26f6b23324c6
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs) = 57f5c3c879b07375234e5cb0cbe0469b15105a6a
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs) = 7160fc9fe6d197b42104856b997337f823d2a791
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs) = 527722bd4fbf0aca07d710e0a8b73f95b2adad40
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs) = aeafe7c1df614bb5e46cb7fb1cb351001f292caf
+SHA1 (patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs) = c1d2157350803fb3eaef6f7a00e7c81dd9cf708b
 SHA1 (patch-gfx_angle_checkout_src_common_third__party_smhasher_src_PMurHash.cpp) = e458c9c8dc66edc69c1874734af28a77fc5e3993
 SHA1 (patch-gfx_angle_checkout_src_compiler_translator_InfoSink.h) = 2f73c76c48852613e0c55c1680fcc2a9eb3cf4ef
 SHA1 (patch-gfx_gl_GLContextProviderGLX.cpp) = 2c909a10a341e600392417240ad0c556f495d6ba

Added files:

Index: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_lib.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_lib.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_lib.rs        Mon Aug 17 06:58:32 2020
@@ -0,0 +1,34 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_lib.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/lib.rs.orig    2020-06-22 22:55:03.000000000 +0000
++++ dom/webauthn/u2f-hid-rs/src/lib.rs
+@@ -5,7 +5,7 @@
+ #[macro_use]
+ mod util;
+ 
+-#[cfg(any(target_os = "linux", target_os = "freebsd"))]
++#[cfg(any(target_os = "linux", target_os = "freebsd", target_os = "netbsd"))]
+ pub mod hidproto;
+ 
+ #[cfg(any(target_os = "linux"))]
+@@ -22,6 +22,10 @@ extern crate devd_rs;
+ #[path = "freebsd/mod.rs"]
+ pub mod platform;
+ 
++#[cfg(any(target_os = "netbsd"))]
++#[path = "netbsd/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 = "netbsd",
+     target_os = "macos",
+     target_os = "windows"
+ )))]
Index: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs      Mon Aug 17 06:58:32 2020
@@ -0,0 +1,141 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_device.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/device.rs.orig  2020-07-15 16:19:08.142403669 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/device.rs
+@@ -0,0 +1,134 @@
++/* 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::mem;
++use std::io::Read;
++use std::io::Write;
++use std::io;
++
++use consts::CID_BROADCAST;
++use consts::HID_RPT_SIZE;
++use platform::fd::Fd;
++use platform::uhid;
++use u2ftypes::U2FDevice;
++use util::io_err;
++
++#[derive(Debug)]
++pub struct Device {
++    fd: Fd,
++    cid: [u8; 4],
++}
++
++impl Device {
++    pub fn new(fd: Fd) -> io::Result<Self> {
++        Ok(Self { fd, cid: CID_BROADCAST })
++    }
++
++    pub fn is_u2f(&mut self) -> bool {
++        if !uhid::is_u2f_device(&self.fd) {
++            return false;
++        }
++        // This step is not strictly necessary -- NetBSD puts fido
++        // devices into raw mode automatically by default, but in
++        // principle that might change, and this serves as a test to
++        // verify that we're running on a kernel with support for raw
++        // mode at all so we don't get confused issuing writes that try
++        // to set the report descriptor rather than transfer data on
++        // the output interrupt pipe as we need.
++        match uhid::hid_set_raw(&self.fd, true) {
++            Ok(_) => (),
++            Err(_) => return false,
++        }
++        if let Err(_) = self.ping() {
++            return false;
++        }
++        true
++    }
++
++    fn ping(&mut self) -> io::Result<()> {
++        for i in 0..10 {
++            let mut buf = vec![0u8; 1 + HID_RPT_SIZE];
++
++            buf[0] = 0;         // report number
++            buf[1] = 0xff;      // CID_BROADCAST
++            buf[2] = 0xff;
++            buf[3] = 0xff;
++            buf[4] = 0xff;
++            buf[5] = 0x81;      // ping
++            buf[6] = 0;
++            buf[7] = 1;         // one byte
++
++            self.write(&buf[..])?;
++
++            // Wait for response
++            let mut pfd: libc::pollfd = unsafe { mem::zeroed() };
++            pfd.fd = self.fd.fileno;
++            pfd.events = libc::POLLIN;
++            let nfds = unsafe { libc::poll(&mut pfd, 1, 100) };
++            if nfds == -1 {
++                return Err(io::Error::last_os_error());
++            }
++            if nfds == 0 {
++                debug!("device timeout {}", i);
++                continue;
++            }
++
++            // Read response
++            self.read(&mut buf[..])?;
++
++            return Ok(());
++        }
++
++        Err(io_err("no response from device"))
++    }
++}
++
++impl PartialEq for Device {
++    fn eq(&self, other: &Device) -> bool {
++        self.fd == other.fd
++    }
++}
++
++impl Read for Device {
++    fn read(&mut self, buf: &mut [u8]) -> io::Result<usize> {
++        let bufp = buf.as_mut_ptr() as *mut libc::c_void;
++        let nread = unsafe { libc::read(self.fd.fileno, bufp, buf.len()) };
++        if nread == -1 {
++            return Err(io::Error::last_os_error());
++        }
++        Ok(nread as usize)
++    }
++}
++
++impl Write for Device {
++    fn write(&mut self, buf: &[u8]) -> io::Result<usize> {
++        // Always skip the first byte (report number)
++        let data = &buf[1..];
++        let data_ptr = data.as_ptr() as *const libc::c_void;
++        let nwrit = unsafe {
++            libc::write(self.fd.fileno, data_ptr, data.len())
++        };
++        if nwrit == -1 {
++            return Err(io::Error::last_os_error());
++        }
++        // Pretend we wrote the report number byte
++        Ok(nwrit as usize + 1)
++    }
++
++    fn flush(&mut self) -> io::Result<()> {
++        Ok(())
++    }
++}
++
++impl U2FDevice for Device {
++    fn get_cid<'a>(&'a self) -> &'a [u8; 4] {
++        &self.cid
++    }
++
++    fn set_cid(&mut self, cid: [u8; 4]) {
++        self.cid = cid;
++    }
++}
Index: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs  Mon Aug 17 06:58:32 2020
@@ -0,0 +1,54 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_fd.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/fd.rs.orig      2020-07-15 16:19:08.142740434 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/fd.rs
+@@ -0,0 +1,47 @@
++/* 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;
++use std::io;
++use std::mem;
++use std::os::raw::c_int;
++use std::os::unix::io::RawFd;
++
++#[derive(Debug)]
++pub struct Fd {
++    pub fileno: RawFd,
++}
++
++impl Fd {
++    pub fn open(path: &str, flags: c_int) -> io::Result<Fd> {
++        let cpath = CString::new(path.as_bytes())?;
++        let rv = unsafe { libc::open(cpath.as_ptr(), flags) };
++        if rv == -1 {
++            return Err(io::Error::last_os_error());
++        }
++        Ok(Fd { fileno: rv })
++    }
++}
++
++impl Drop for Fd {
++    fn drop(&mut self) {
++        unsafe { libc::close(self.fileno) };
++    }
++}
++
++impl PartialEq for Fd {
++    fn eq(&self, other: &Fd) -> bool {
++        let mut st: libc::stat = unsafe { mem::zeroed() };
++        let mut sto: libc::stat = unsafe { mem::zeroed() };
++        if unsafe { libc::fstat(self.fileno, &mut st) } == -1 {
++            return false;
++        }
++        if unsafe { libc::fstat(other.fileno, &mut sto) } == -1 {
++            return false;
++        }
++        (st.st_dev == sto.st_dev) & (st.st_ino == sto.st_ino)
++    }
++}
Index: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs Mon Aug 17 06:58:32 2020
@@ -0,0 +1,17 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_mod.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/mod.rs.orig     2020-07-15 16:19:08.143016295 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/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 fd;
++mod monitor;
++mod uhid;
Index: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs     Mon Aug 17 06:58:32 2020
@@ -0,0 +1,96 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_monitor.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/monitor.rs.orig 2020-07-15 16:19:08.143281894 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/monitor.rs
+@@ -0,0 +1,89 @@
++/* 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::OsString;
++use std::io;
++use std::sync::Arc;
++use std::thread;
++use std::time::Duration;
++
++use runloop::RunLoop;
++
++use platform::fd::Fd;
++
++// XXX Should use drvctl, but it doesn't do pubsub properly yet so
++// DRVGETEVENT requires write access to /dev/drvctl.  Instead, for now,
++// just poll every 500ms.
++const POLL_TIMEOUT: u64 = 500;
++
++pub struct Monitor<F>
++where
++    F: Fn(Fd, &dyn Fn() -> bool) + Send + Sync + 'static,
++{
++    runloops: HashMap<OsString, RunLoop>,
++    new_device_cb: Arc<F>,
++}
++
++impl<F> Monitor<F>
++where
++    F: Fn(Fd, &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<()> {
++        while alive() {
++            for n in 0..100 {
++                let uhidpath = format!("/dev/uhid{}", n);
++                match Fd::open(&uhidpath, libc::O_RDWR | libc::O_CLOEXEC) {
++                    Ok(uhid) => {
++                        self.add_device(uhid, OsString::from(&uhidpath));
++                    },
++                    Err(ref err) => {
++                        match err.raw_os_error() {
++                            Some(libc::EBUSY) => continue,
++                            Some(libc::ENOENT) => break,
++                            _ => self.remove_device(OsString::from(&uhidpath)),
++                        }
++                    },
++                }
++            }
++            thread::sleep(Duration::from_millis(POLL_TIMEOUT));
++        }
++        self.remove_all_devices();
++        Ok(())
++    }
++
++    fn add_device(&mut self, fd: Fd, path: OsString) {
++        let f = self.new_device_cb.clone();
++
++        let runloop = RunLoop::new(move |alive| {
++            if alive() {
++                f(fd, alive);
++            }
++        });
++
++        if let Ok(runloop) = runloop {
++            self.runloops.insert(path.clone(), 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: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs Mon Aug 17 06:58:32 2020
@@ -0,0 +1,57 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_transaction.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/transaction.rs.orig     2020-07-15 16:19:08.143583561 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/transaction.rs
+@@ -0,0 +1,50 @@
++/* 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 runloop::RunLoop;
++use util::OnceCallback;
++
++use platform::fd::Fd;
++use platform::monitor::Monitor;
++
++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(Fd, &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: pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs
diff -u /dev/null pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs:1.1
--- /dev/null   Mon Aug 17 06:58:32 2020
+++ pkgsrc/security/tor-browser/patches/patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs        Mon Aug 17 06:58:32 2020
@@ -0,0 +1,86 @@
+$NetBSD: patch-dom_webauthn_u2f-hid-rs_src_netbsd_uhid.rs,v 1.1 2020/08/17 06:58:32 riastradh Exp $
+
+Add NetBSD support for U2F.
+
+--- dom/webauthn/u2f-hid-rs/src/netbsd/uhid.rs.orig    2020-07-15 16:19:08.143860020 +0000
++++ dom/webauthn/u2f-hid-rs/src/netbsd/uhid.rs
+@@ -0,0 +1,79 @@
++/* 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::io;
++use std::mem;
++use std::os::raw::c_int;
++use std::os::raw::c_uchar;
++
++use hidproto::ReportDescriptor;
++use hidproto::has_fido_usage;
++use platform::fd::Fd;
++use util::io_err;
++
++/* sys/ioccom.h */
++
++const IOCPARM_MASK: u32 = 0x1fff;
++const IOCPARM_SHIFT: u32 = 16;
++const IOCGROUP_SHIFT: u32 = 8;
++
++//const IOC_VOID: u32 = 0x20000000;
++const IOC_OUT: u32 = 0x40000000;
++const IOC_IN: u32 = 0x80000000;
++//const IOC_INOUT: u32 = IOC_IN|IOC_OUT;
++
++macro_rules! ioctl {
++    ($dir:expr, $name:ident, $group:expr, $nr:expr, $ty:ty) => {
++        unsafe fn $name(fd: libc::c_int, val: *mut $ty)
++                -> io::Result<libc::c_int> {
++            let ioc = ($dir as u32)
++                | ((mem::size_of::<$ty>() as u32 & IOCPARM_MASK)
++                   << IOCPARM_SHIFT)
++                | (($group as u32) << IOCGROUP_SHIFT)
++                | ($nr as u32);
++            let rv = libc::ioctl(fd, ioc as libc::c_ulong, val);
++            if rv == -1 {
++                return Err(io::Error::last_os_error());
++            }
++            Ok(rv)
++        }
++    };
++}
++
++#[allow(non_camel_case_types)]
++#[repr(C)]
++struct usb_ctl_report_desc {
++    ucrd_size: c_int,
++    ucrd_data: [c_uchar; 1024],
++}
++
++ioctl!(IOC_OUT, usb_get_report_desc, b'U', 21, usb_ctl_report_desc);
++
++fn read_report_descriptor(fd: &Fd) -> io::Result<ReportDescriptor> {
++    let mut desc = unsafe { mem::zeroed() };
++    unsafe { usb_get_report_desc(fd.fileno, &mut desc) }?;
++    if desc.ucrd_size < 0 {
++        return Err(io_err("negative report descriptor size"));
++    }
++    let size = desc.ucrd_size as usize;
++    let value = Vec::from(&desc.ucrd_data[..size]);
++    Ok(ReportDescriptor { value })
++}
++
++pub fn is_u2f_device(fd: &Fd) -> bool {
++    match read_report_descriptor(fd) {
++        Ok(desc) => has_fido_usage(desc),
++        Err(_) => false,
++    }
++}
++
++ioctl!(IOC_IN, usb_hid_set_raw_ioctl, b'h', 2, c_int);
++
++pub fn hid_set_raw(fd: &Fd, raw: bool) -> io::Result<()> {
++    let mut raw_int: c_int = if raw { 1 } else { 0 };
++    unsafe { usb_hid_set_raw_ioctl(fd.fileno, &mut raw_int) }?;
++    Ok(())
++}



Home | Main Index | Thread Index | Old Index