Skip to content

Commit d5be1f1

Browse files
committed
Add a higher-level AuthenticatorService that can query multiple backends
- This moves the callback mechanism into its own file, as it gets more complex - Reworks the C API to use the AuthenticatorService
1 parent 51c576a commit d5be1f1

File tree

16 files changed

+921
-138
lines changed

16 files changed

+921
-138
lines changed

Cargo.toml

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -49,3 +49,4 @@ bitflags = "1.0"
4949
sha2 = "^0.8.2"
5050
base64 = "^0.10"
5151
env_logger = "^0.6"
52+
getopts = "^0.2"

examples/main.rs

Lines changed: 63 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -2,29 +2,14 @@
22
* License, v. 2.0. If a copy of the MPL was not distributed with this
33
* file, You can obtain one at http://mozilla.org/MPL/2.0/. */
44

5-
extern crate authenticator;
6-
extern crate base64;
7-
extern crate sha2;
85
use authenticator::{
9-
AuthenticatorTransports, KeyHandle, RegisterFlags, SignFlags, StatusUpdate, U2FManager,
6+
authenticatorservice::AuthenticatorService, statecallback::StateCallback,
7+
AuthenticatorTransports, KeyHandle, RegisterFlags, SignFlags, StatusUpdate,
108
};
9+
use getopts::Options;
1110
use sha2::{Digest, Sha256};
1211
use std::sync::mpsc::{channel, RecvError};
13-
use std::{io, thread};
14-
15-
extern crate env_logger;
16-
extern crate log;
17-
18-
macro_rules! try_or {
19-
($val:expr, $or:expr) => {
20-
match $val {
21-
Ok(v) => v,
22-
Err(e) => {
23-
return $or(e);
24-
}
25-
}
26-
};
27-
}
12+
use std::{env, io, thread};
2813

2914
fn u2f_get_key_handle_from_register_response(register_response: &[u8]) -> io::Result<Vec<u8>> {
3015
if register_response[0] != 0x05 {
@@ -42,9 +27,37 @@ fn u2f_get_key_handle_from_register_response(register_response: &[u8]) -> io::Re
4227
Ok(key_handle)
4328
}
4429

30+
fn print_usage(program: &str, opts: Options) {
31+
let brief = format!("Usage: {} [options]", program);
32+
print!("{}", opts.usage(&brief));
33+
}
34+
4535
fn main() {
4636
env_logger::init();
4737

38+
let args: Vec<String> = env::args().collect();
39+
let program = args[0].clone();
40+
41+
let mut opts = Options::new();
42+
opts.optflag("x", "no-u2f-usb-hid", "do not enable u2f-usb-hid platforms");
43+
44+
opts.optflag("h", "help", "print this help menu");
45+
let matches = match opts.parse(&args[1..]) {
46+
Ok(m) => m,
47+
Err(f) => panic!(f.to_string()),
48+
};
49+
if matches.opt_present("help") {
50+
print_usage(&program, opts);
51+
return;
52+
}
53+
54+
let mut manager =
55+
AuthenticatorService::new().expect("The auth service should initialize safely");
56+
57+
if !matches.opt_present("no-u2f-usb-hid") {
58+
manager.add_u2f_usb_hid_platform_transports();
59+
}
60+
4861
println!("Asking a security key to register now...");
4962
let challenge_str = format!(
5063
"{}{}",
@@ -59,7 +72,6 @@ fn main() {
5972
application.input(b"http://demo.yubico.com");
6073
let app_bytes = application.result().to_vec();
6174

62-
let manager = U2FManager::new().unwrap();
6375
let flags = RegisterFlags::empty();
6476

6577
let (status_tx, status_rx) = channel::<StatusUpdate>();
@@ -82,25 +94,26 @@ fn main() {
8294
});
8395

8496
let (register_tx, register_rx) = channel();
97+
let callback = StateCallback::new(Box::new(move |rv| {
98+
register_tx.send(rv).unwrap();
99+
}));
100+
85101
manager
86102
.register(
87103
flags,
88-
15_000,
104+
60_000 * 5,
89105
chall_bytes.clone(),
90106
app_bytes.clone(),
91107
vec![],
92108
status_tx.clone(),
93-
move |rv| {
94-
register_tx.send(rv).unwrap();
95-
},
109+
callback,
96110
)
97-
.unwrap();
111+
.expect("Couldn't register");
98112

99-
let register_result = try_or!(register_rx.recv(), |_| {
100-
panic!("Problem receiving, unable to continue");
101-
});
102-
let (register_data, device_info) =
103-
register_result.unwrap_or_else(|e| panic!("Registration failed: {:?}", e));
113+
let register_result = register_rx
114+
.recv()
115+
.expect("Problem receiving, unable to continue");
116+
let (register_data, device_info) = register_result.expect("Registration failed");
104117

105118
println!("Register result: {}", base64::encode(&register_data));
106119
println!("Device info: {}", &device_info);
@@ -113,25 +126,27 @@ fn main() {
113126

114127
let flags = SignFlags::empty();
115128
let (sign_tx, sign_rx) = channel();
116-
manager
117-
.sign(
118-
flags,
119-
15_000,
120-
chall_bytes,
121-
vec![app_bytes],
122-
vec![key_handle],
123-
status_tx,
124-
move |rv| {
125-
sign_tx.send(rv).unwrap();
126-
},
127-
)
128-
.unwrap();
129129

130-
let sign_result = try_or!(sign_rx.recv(), |_| {
131-
panic!("Problem receiving, unable to continue");
132-
});
133-
let (_, handle_used, sign_data, device_info) =
134-
sign_result.unwrap_or_else(|e| panic!("Sign failed: {:?}", e));
130+
let callback = StateCallback::new(Box::new(move |rv| {
131+
sign_tx.send(rv).unwrap();
132+
}));
133+
134+
if let Err(e) = manager.sign(
135+
flags,
136+
15_000,
137+
chall_bytes,
138+
vec![app_bytes],
139+
vec![key_handle],
140+
status_tx,
141+
callback,
142+
) {
143+
panic!("Couldn't register: {:?}", e);
144+
}
145+
146+
let sign_result = sign_rx
147+
.recv()
148+
.expect("Problem receiving, unable to continue");
149+
let (_, handle_used, sign_data, device_info) = sign_result.expect("Sign failed");
135150

136151
println!("Sign result: {}", base64::encode(&sign_data));
137152
println!("Key handle used: {}", base64::encode(&handle_used));

0 commit comments

Comments
 (0)