Skip to content

Commit

Permalink
Use HIBP padded passwords (brycx#20)
Browse files Browse the repository at this point in the history
  • Loading branch information
brycx committed Mar 24, 2020
1 parent 1e8b9c0 commit f17557c
Show file tree
Hide file tree
Showing 3 changed files with 21 additions and 10 deletions.
4 changes: 2 additions & 2 deletions src/api/errors.rs
Expand Up @@ -23,15 +23,15 @@
/// All the different errors for checkpwn;
/// Errors that are meant to be internal or or unreachable print this.
pub const USAGE_ERROR: &str = "Usage: checkpwn (acc/pass) (username/email/account_list.ls)";
pub const STATUSCODE_ERROR: &str = "Unrecognized status code recevied";
pub const STATUSCODE_ERROR: &str = "Unrecognized status code received";
pub const PASSWORD_ERROR: &str = "Error retrieving password from stdin";
pub const READ_FILE_ERROR: &str = "Error reading local file";
pub const NETWORK_ERROR: &str = "Failed to send request to HIBP";
pub const DECODING_ERROR: &str = "Failed to decode response from HIBP";
pub const API_ARG_ERROR: &str =
"SHOULD_BE_UNREACHABLE: Invalid argument in API route construction detected";
pub const BAD_RESPONSE_ERROR: &str =
"Recevied a bad response from HIBP - make sure the account is valid";
"Received a bad response from HIBP - make sure the account is valid";
pub const BUFREADER_ERROR: &str = "Failed to read file in to BufReader";
pub const READLINE_ERROR: &str = "Failed to read line from file";

Expand Down
19 changes: 13 additions & 6 deletions src/api/mod.rs
Expand Up @@ -78,7 +78,7 @@ fn format_req(api_route: &CheckableChoices, search_term: &str) -> String {
request
}

/// Take the user-supplied command-line arugments and make a URL for the HIBP API.
/// Take the user-supplied command-line arguments and make a URL for the HIBP API.
/// If the `pass` argument has been selected, `input_data` needs to be the hashed password.
pub fn arg_to_api_route(arg: &CheckableChoices, input_data: &str) -> String {
match arg {
Expand All @@ -91,22 +91,29 @@ pub fn arg_to_api_route(arg: &CheckableChoices, input_data: &str) -> String {
}
}

/// Find matching key in recevied set of keys.
/// Find matching key in received set of keys.
pub fn search_in_range(password_range_response: &str, hashed_key: &str) -> bool {
for line in password_range_response.lines() {
// Each response is truncated to only be the hash, no whitespaces, etc.
let pair: Vec<_> = line.split(':').collect();
// Padded entries always have an occurrence of 0 and should be
// discarded.
if *pair.get(1).unwrap() == "0" {
continue;
}

// Each response is truncated to only be the hash, no whitespace, etc.
// All hashes here have a length of 35, so the useless gets dropped by
// slicing. Don't include first five characters of own password, as
// this also is how the HIBP API returns passwords.
if line[..35] == hashed_key[5..] {
if *pair.get(0).unwrap() == &hashed_key[5..] {
return true;
}
}

false
}

/// Make a breach report based on StatusCode and print result to temrinal.
/// Make a breach report based on StatusCode and print result to terminal.
pub fn breach_report(status_code: StatusCode, searchterm: &str, is_password: bool) -> ((), bool) {
// Do not display password in terminal
let request_key = if is_password { "********" } else { searchterm };
Expand Down Expand Up @@ -221,7 +228,7 @@ fn test_breach_invalid_status() {
}

#[test]
fn test_search_succes_and_failure() {
fn test_search_success_and_failure() {
// https://api.pwnedpasswords.com/range/B1B37

let contains_pass = String::from(
Expand Down
8 changes: 6 additions & 2 deletions src/main.rs
Expand Up @@ -53,7 +53,7 @@ fn acc_check(data_search: &str) {
continue;
}
api::acc_breach_request(&line);
// Only one request every 1500 miliseconds from any given IP
// Only one request every 1500 milliseconds from any given IP
thread::sleep(time::Duration::from_millis(1600));
}
} else {
Expand All @@ -67,6 +67,10 @@ fn pass_check(data_search: &api::PassArg) {
header::USER_AGENT,
header::HeaderValue::from_static(api::CHECKPWN_USER_AGENT),
);
headers.insert(
"Add-Padding",
header::HeaderValue::from_str("true").unwrap(),
);

let client = Client::builder().default_headers(headers).build().unwrap();

Expand Down Expand Up @@ -117,7 +121,7 @@ fn main() {
for argument in argvs.iter_mut() {
argument.zeroize();
}
// Only one request every 1500 miliseconds from any given IP
// Only one request every 1500 milliseconds from any given IP
thread::sleep(time::Duration::from_millis(1600));
}

Expand Down

0 comments on commit f17557c

Please sign in to comment.