mirror of
https://github.com/LordGrimmauld/yubi-oath-rs.git
synced 2025-03-04 05:44:40 +01:00
fmt
This commit is contained in:
parent
ec1d1bba0e
commit
5c01623394
2 changed files with 72 additions and 81 deletions
|
@ -1,13 +1,11 @@
|
||||||
/// Utilities for interacting with YubiKey OATH/TOTP functionality
|
|
||||||
|
|
||||||
extern crate pcsc;
|
|
||||||
extern crate byteorder;
|
extern crate byteorder;
|
||||||
|
/// Utilities for interacting with YubiKey OATH/TOTP functionality
|
||||||
|
extern crate pcsc;
|
||||||
|
|
||||||
use std::ffi::{CString};
|
|
||||||
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
use byteorder::{BigEndian, ReadBytesExt, WriteBytesExt};
|
||||||
|
use std::ffi::CString;
|
||||||
use std::io::{Cursor, Read, Write};
|
use std::io::{Cursor, Read, Write};
|
||||||
use std::time::{SystemTime};
|
use std::time::SystemTime;
|
||||||
|
|
||||||
|
|
||||||
pub type DetectResult<'a> = Result<Vec<YubiKey<'a>>, pcsc::Error>;
|
pub type DetectResult<'a> = Result<Vec<YubiKey<'a>>, pcsc::Error>;
|
||||||
|
|
||||||
|
@ -39,14 +37,14 @@ pub fn format_code(code: u32, digits: OathDigits) -> String {
|
||||||
} else {
|
} else {
|
||||||
code_string.split_off(code_string.len() - 6)
|
code_string.split_off(code_string.len() - 6)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
OathDigits::Eight => {
|
OathDigits::Eight => {
|
||||||
if code_string.len() <= 8 {
|
if code_string.len() <= 8 {
|
||||||
format!("{:0>8}", code_string)
|
format!("{:0>8}", code_string)
|
||||||
} else {
|
} else {
|
||||||
code_string.split_off(code_string.len() - 8)
|
code_string.split_off(code_string.len() - 8)
|
||||||
}
|
}
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -54,33 +52,21 @@ fn to_error_response(sw1: u8, sw2: u8) -> Option<String> {
|
||||||
let code: usize = (sw1 as usize | sw2 as usize) << 8;
|
let code: usize = (sw1 as usize | sw2 as usize) << 8;
|
||||||
|
|
||||||
match code {
|
match code {
|
||||||
code if code == ErrorResponse::GenericError as usize => {
|
code if code == ErrorResponse::GenericError as usize => Some(String::from("Generic error")),
|
||||||
Some(String::from("Generic error"))
|
code if code == ErrorResponse::NoSpace as usize => Some(String::from("No space on device")),
|
||||||
},
|
|
||||||
code if code == ErrorResponse::NoSpace as usize => {
|
|
||||||
Some(String::from("No space on device"))
|
|
||||||
},
|
|
||||||
code if code == ErrorResponse::CommandAborted as usize => {
|
code if code == ErrorResponse::CommandAborted as usize => {
|
||||||
Some(String::from("Command was aborted"))
|
Some(String::from("Command was aborted"))
|
||||||
},
|
}
|
||||||
code if code == ErrorResponse::AuthRequired as usize => {
|
code if code == ErrorResponse::AuthRequired as usize => {
|
||||||
Some(String::from("Authentication required"))
|
Some(String::from("Authentication required"))
|
||||||
},
|
}
|
||||||
code if code == ErrorResponse::WrongSyntax as usize => {
|
code if code == ErrorResponse::WrongSyntax as usize => Some(String::from("Wrong syntax")),
|
||||||
Some(String::from("Wrong syntax"))
|
|
||||||
},
|
|
||||||
code if code == ErrorResponse::InvalidInstruction as usize => {
|
code if code == ErrorResponse::InvalidInstruction as usize => {
|
||||||
Some(String::from("Invalid instruction"))
|
Some(String::from("Invalid instruction"))
|
||||||
},
|
}
|
||||||
code if code == SuccessResponse::Okay as usize => {
|
code if code == SuccessResponse::Okay as usize => None,
|
||||||
None
|
sw1 if sw1 == SuccessResponse::MoreData as usize => None,
|
||||||
},
|
_ => Some(String::from("Unknown error")),
|
||||||
sw1 if sw1 == SuccessResponse::MoreData as usize => {
|
|
||||||
None
|
|
||||||
},
|
|
||||||
_ => {
|
|
||||||
Some(String::from("Unknown error"))
|
|
||||||
},
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -176,12 +162,12 @@ pub enum OathType {
|
||||||
pub struct OathCredential {
|
pub struct OathCredential {
|
||||||
pub name: String,
|
pub name: String,
|
||||||
pub code: OathCode,
|
pub code: OathCode,
|
||||||
// TODO: Support this stuff
|
// TODO: Support this stuff
|
||||||
// pub oath_type: OathType,
|
// pub oath_type: OathType,
|
||||||
// pub touch: bool,
|
// pub touch: bool,
|
||||||
// pub algo: OathAlgo,
|
// pub algo: OathAlgo,
|
||||||
// pub hidden: bool,
|
// pub hidden: bool,
|
||||||
// pub steam: bool,
|
// pub steam: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
impl OathCredential {
|
impl OathCredential {
|
||||||
|
@ -189,11 +175,11 @@ impl OathCredential {
|
||||||
OathCredential {
|
OathCredential {
|
||||||
name: name.to_string(),
|
name: name.to_string(),
|
||||||
code: code,
|
code: code,
|
||||||
// oath_type: oath_type,
|
// oath_type: oath_type,
|
||||||
// touch: touch,
|
// touch: touch,
|
||||||
// algo: algo,
|
// algo: algo,
|
||||||
// hidden: name.starts_with("_hidden:"),
|
// hidden: name.starts_with("_hidden:"),
|
||||||
// steam: name.starts_with("Steam:"),
|
// steam: name.starts_with("Steam:"),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -208,8 +194,8 @@ pub enum OathDigits {
|
||||||
pub struct OathCode {
|
pub struct OathCode {
|
||||||
pub digits: OathDigits,
|
pub digits: OathDigits,
|
||||||
pub value: u32,
|
pub value: u32,
|
||||||
// pub expiration: u32,
|
// pub expiration: u32,
|
||||||
// pub steam: bool,
|
// pub steam: bool,
|
||||||
}
|
}
|
||||||
|
|
||||||
pub struct ApduResponse {
|
pub struct ApduResponse {
|
||||||
|
@ -224,7 +210,7 @@ pub struct YubiKey<'a> {
|
||||||
|
|
||||||
impl<'a> YubiKey<'a> {
|
impl<'a> YubiKey<'a> {
|
||||||
/// Read the OATH codes from the device
|
/// Read the OATH codes from the device
|
||||||
pub fn get_oath_codes(&self) -> Result<Vec<OathCredential>, String>{
|
pub fn get_oath_codes(&self) -> Result<Vec<OathCredential>, String> {
|
||||||
// Establish a PC/SC context
|
// Establish a PC/SC context
|
||||||
let ctx = match pcsc::Context::establish(pcsc::Scope::User) {
|
let ctx = match pcsc::Context::establish(pcsc::Scope::User) {
|
||||||
Ok(ctx) => ctx,
|
Ok(ctx) => ctx,
|
||||||
|
@ -235,7 +221,7 @@ impl<'a> YubiKey<'a> {
|
||||||
let mut card = match ctx.connect(
|
let mut card = match ctx.connect(
|
||||||
&CString::new(self.name).unwrap(),
|
&CString::new(self.name).unwrap(),
|
||||||
pcsc::ShareMode::Shared,
|
pcsc::ShareMode::Shared,
|
||||||
pcsc::Protocols::ANY
|
pcsc::Protocols::ANY,
|
||||||
) {
|
) {
|
||||||
Ok(card) => card,
|
Ok(card) => card,
|
||||||
Err(err) => return Err(format!("{}", err)),
|
Err(err) => return Err(format!("{}", err)),
|
||||||
|
@ -256,9 +242,17 @@ impl<'a> YubiKey<'a> {
|
||||||
let mut response_buf = Vec::new();
|
let mut response_buf = Vec::new();
|
||||||
|
|
||||||
// Request OATH codes from device
|
// Request OATH codes from device
|
||||||
let response = self.apdu(&tx, 0, Instruction::CalculateAll as u8, 0,
|
let response = self.apdu(
|
||||||
0x01, Some(&to_tlv(Tag::Challenge,
|
&tx,
|
||||||
&time_challenge(Some(SystemTime::now())))));
|
0,
|
||||||
|
Instruction::CalculateAll as u8,
|
||||||
|
0,
|
||||||
|
0x01,
|
||||||
|
Some(&to_tlv(
|
||||||
|
Tag::Challenge,
|
||||||
|
&time_challenge(Some(SystemTime::now())),
|
||||||
|
)),
|
||||||
|
);
|
||||||
|
|
||||||
// Handle errors from command
|
// Handle errors from command
|
||||||
match response {
|
match response {
|
||||||
|
@ -275,10 +269,10 @@ impl<'a> YubiKey<'a> {
|
||||||
sw1 = more_resp.sw1;
|
sw1 = more_resp.sw1;
|
||||||
sw2 = more_resp.sw2;
|
sw2 = more_resp.sw2;
|
||||||
response_buf.extend(more_resp.buf);
|
response_buf.extend(more_resp.buf);
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(format!("{}", e));
|
return Err(format!("{}", e));
|
||||||
},
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -287,7 +281,7 @@ impl<'a> YubiKey<'a> {
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ok(self.parse_list(&response_buf).unwrap());
|
return Ok(self.parse_list(&response_buf).unwrap());
|
||||||
},
|
}
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
return Err(format!("{}", e));
|
return Err(format!("{}", e));
|
||||||
}
|
}
|
||||||
|
@ -352,7 +346,7 @@ impl<'a> YubiKey<'a> {
|
||||||
|
|
||||||
results.push(OathCredential::new(
|
results.push(OathCredential::new(
|
||||||
&String::from_utf8(name).unwrap(),
|
&String::from_utf8(name).unwrap(),
|
||||||
OathCode { digits, value }
|
OathCode { digits, value },
|
||||||
));
|
));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -367,7 +361,7 @@ impl<'a> YubiKey<'a> {
|
||||||
instruction: u8,
|
instruction: u8,
|
||||||
parameter1: u8,
|
parameter1: u8,
|
||||||
parameter2: u8,
|
parameter2: u8,
|
||||||
data: Option<&[u8]>
|
data: Option<&[u8]>,
|
||||||
) -> Result<ApduResponse, pcsc::Error> {
|
) -> Result<ApduResponse, pcsc::Error> {
|
||||||
// Create a container for the transaction payload
|
// Create a container for the transaction payload
|
||||||
let mut tx_buf = Vec::new();
|
let mut tx_buf = Vec::new();
|
||||||
|
@ -443,4 +437,3 @@ impl<'a> YubiKey<'a> {
|
||||||
})
|
})
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,7 +21,7 @@ fn main() {
|
||||||
|
|
||||||
// Iterate over the connected USB devices
|
// Iterate over the connected USB devices
|
||||||
for reader in readers {
|
for reader in readers {
|
||||||
yubikeys.push(lib_ykoath::YubiKey{
|
yubikeys.push(lib_ykoath::YubiKey {
|
||||||
name: reader.to_str().unwrap(),
|
name: reader.to_str().unwrap(),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -41,7 +41,7 @@ fn main() {
|
||||||
Err(e) => {
|
Err(e) => {
|
||||||
println!("ERROR {}", e);
|
println!("ERROR {}", e);
|
||||||
continue;
|
continue;
|
||||||
},
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
// Show message is node codes found
|
// Show message is node codes found
|
||||||
|
@ -54,9 +54,7 @@ fn main() {
|
||||||
let code = lib_ykoath::format_code(oath.code.value, oath.code.digits);
|
let code = lib_ykoath::format_code(oath.code.value, oath.code.digits);
|
||||||
let name_clone = oath.name.clone();
|
let name_clone = oath.name.clone();
|
||||||
let mut label_vec: Vec<&str> = name_clone.split(":").collect();
|
let mut label_vec: Vec<&str> = name_clone.split(":").collect();
|
||||||
let mut code_entry_label: String = String::from(
|
let mut code_entry_label: String = String::from(label_vec.remove(0));
|
||||||
label_vec.remove(0)
|
|
||||||
);
|
|
||||||
|
|
||||||
if label_vec.len() > 0 {
|
if label_vec.len() > 0 {
|
||||||
code_entry_label.push_str(" (");
|
code_entry_label.push_str(" (");
|
||||||
|
|
Loading…
Add table
Reference in a new issue