diff options
Diffstat (limited to 'security/tor-browser/patches/patch-third__party_rust_authenticator_src_netbsd_device.rs')
-rw-r--r-- | security/tor-browser/patches/patch-third__party_rust_authenticator_src_netbsd_device.rs | 145 |
1 files changed, 145 insertions, 0 deletions
diff --git a/security/tor-browser/patches/patch-third__party_rust_authenticator_src_netbsd_device.rs b/security/tor-browser/patches/patch-third__party_rust_authenticator_src_netbsd_device.rs new file mode 100644 index 00000000000..381d724688a --- /dev/null +++ b/security/tor-browser/patches/patch-third__party_rust_authenticator_src_netbsd_device.rs @@ -0,0 +1,145 @@ +$NetBSD: patch-third__party_rust_authenticator_src_netbsd_device.rs,v 1.1.2.2 2020/10/23 17:27:13 bsiegert Exp $ + +Add NetBSD support for U2F. + +Submitted upstream: + +https://github.com/mozilla/authenticator-rs/pull/116 + +--- third_party/rust/authenticator/src/netbsd/device.rs.orig 2020-07-15 16:29:34.208835297 +0000 ++++ third_party/rust/authenticator/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; ++ } ++} |