Skip to content

Commit

Permalink
Merge pull request #11 from danielpclark/error_system
Browse files Browse the repository at this point in the history
Error system
  • Loading branch information
danielpclark committed Oct 10, 2017
2 parents 1bfa54d + 01f8089 commit 2b82d08
Show file tree
Hide file tree
Showing 8 changed files with 179 additions and 36 deletions.
2 changes: 1 addition & 1 deletion Cargo.toml
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
[package]
name = "abrute"
version = "0.0.6"
version = "0.1.0"
authors = ["Daniel P. Clark <[email protected]>"]
description = "AESCrypt Brute force attempter."
documentation = "http:https://danielpclark.github.io/abrute/index.html"
Expand Down
Empty file modified install.sh
100644 → 100755
Empty file.
10 changes: 5 additions & 5 deletions src/core.rs
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ use digits::Digits;
use std::io::{self, Write};
use std::process::Command;
use rayon::prelude::*;
use super::result::Error;
extern crate num_cpus;

fn chunk_sequence(d: &mut Digits, qty: usize, adj: Option<&str>) -> Vec<String> {
Expand All @@ -25,11 +26,10 @@ fn chunk_sequence(d: &mut Digits, qty: usize, adj: Option<&str>) -> Vec<String>
result
}

pub fn core_loop<'a>(max: usize, mut sequencer: Digits<'a>, target: &str, adj: Option<&str>) -> Result<(),String> {
pub fn core_loop<'a>(max: usize, mut sequencer: Digits<'a>, target: &str, adj: Option<&str>) -> Result<(), Error> {
loop {
if sequencer.length() > max {
writeln!(io::stderr(), "Password not found for given length and character set.").err();
return Err("EOL".to_string());
return Err(Error::PasswordNotFound);
}

print!("{}..", sequencer.to_s()); // Verbose
Expand All @@ -46,7 +46,7 @@ pub fn core_loop<'a>(max: usize, mut sequencer: Digits<'a>, target: &str, adj: O
arg(&value).
arg(&target).
output().
expect("Failed to execute decryption command!");
unwrap();

if output.status.success() {
let mut code_mutex = code.lock().unwrap();
Expand All @@ -69,7 +69,7 @@ pub fn core_loop<'a>(max: usize, mut sequencer: Digits<'a>, target: &str, adj: O
arg(code.first().unwrap()).
arg(&target).
output().
expect("Failed to execute decryption command!");
unwrap();
break;
}
}
Expand Down
75 changes: 51 additions & 24 deletions src/main.rs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,10 @@ extern crate rayon;
use digits::Digits;
use std::path::Path;
use std::io::{self, Write};
use std::process::{Command,Stdio};
mod result;
use result::Error;
use std::error::Error as StdError;
mod process_input;
use process_input::*;
mod validators;
Expand All @@ -20,11 +24,12 @@ use core::*;
extern crate clap;
use clap::{Arg, App};

fn run_app() -> Result<(), String> {
fn run_app() -> Result<(), Error> {
let matches = App::new("abrute - AES Brute Force File Decryptor").
version(&format!("v{}", crate_version!())[..]).
version_short("v").
author(crate_authors!("\n")).
usage("abrute <RANGE> <CHARACTERS> [OPTIONS] -- <TARGET>").
arg(Arg::with_name("RANGE").
required(true).
index(1)
Expand All @@ -36,8 +41,7 @@ fn run_app() -> Result<(), String> {
arg(Arg::with_name("adjacent").
short("a").
long("adjacent").
takes_value(true).
validator(validate_is_digit)
takes_value(true)
).
arg(Arg::with_name("start").
short("s").
Expand All @@ -54,49 +58,67 @@ fn run_app() -> Result<(), String> {
-------------------------------------------------------------
By: {author}
USAGE:\tabrute <RANGE> <CHARACTERS> [OPTIONS] -- <TARGET>
<RANGE> Single digit or a range 4:6 for password length.
<CHARACTERS> Characters to use in password attempt. Don't use quotes unless
they may be in password. Backslash may escape characters such
as space.
-a, --adjacent Set a limit for allowed adjacent characters. Zero will not
allow any characters of the same kind to neghibor in the
attempts.
-s, --start Starting character sequence to begin at.
<TARGET> Target file to decrypt. The target must be preceeded by a
double dash: -- target.aes
-h, --help Prints help information.
-v, --version Prints version information.
USAGE:\tabrute <RANGE> <CHARACTERS> [OPTIONS] -- <TARGET>
<RANGE> Single digit or a range 4:6 for password length.
<CHARACTERS> Characters to use in password attempt. Don't use quotes
unless they may be in the password. Backslash may escape
characters such as space.
-a, --adjacent Set a limit for allowed adjacent characters. Zero will
not allow any characters of the same kind to neighbor
in the attempts.
-s, --start Starting character sequence to begin with.
<TARGET> Target file to decrypt. The target must be preceeded
by a double dash: -- target.aes
-h, --help Prints help information.
-v, --version Prints version information.
-------------------------------------------------------------
USE OF THIS BINARY FALLS UNDER THE MIT LICENSE (c) 2017").
get_matches();

if Command::new("aescrypt").
stdout(Stdio::null()).
stderr(Stdio::null()).
spawn().
is_err() {
return Err(Error::AescryptMissing);
}

let (min, max) = derive_min_max(matches.value_of("RANGE").unwrap());
let (min, max) = derive_min_max(matches.value_of("RANGE").unwrap())?;
let mapping = derive_character_base(matches.value_of("CHARACTERS").unwrap());

if let Some(s) = matches.value_of("start") {
let result = validate_string_length(s, max);
if result.is_err() { return result; }
let _ = validate_string_length(s, max)?;

let chrctrs: Vec<char> = matches.value_of("CHARACTERS").unwrap().chars().collect();
let mut itr = s.chars();
loop {
match itr.next() {
Some(ref c) => {
if !chrctrs.contains(c) { return Err(Error::InvalidCharacterSet); }
},
_ => break,
}
}
}

let mut sequencer = Digits::new(&mapping, matches.value_of("start").unwrap_or("").to_string());
sequencer.zero_fill(min as usize);
let target = matches.value_of("TARGET").unwrap();
let target = matches.value_of("TARGET").unwrap_or("");
let adjacent = matches.value_of("adjacent");

let seq_base = sequencer.base();
if let &Some(num) = &adjacent {
validate_adjacent_input(num.to_string())?;
if seq_base > 3 {
validate_is_digit(num.to_string()).ok();
sequencer.prep_non_adjacent(num.parse::<usize>().unwrap());
}
}

if !Path::new(&target).exists() {
writeln!(io::stderr(), "Error: File {:?} does not exist.", target).err();
return Err("Please verify last argument is the proper filename.".to_string())
return Err(Error::FileMissing)
}

core_loop(max, sequencer, target, adjacent)
Expand All @@ -107,7 +129,12 @@ fn main() {
match run_app() {
Ok(_) => 0,
Err(err) => {
writeln!(io::stderr(), "error: {:?}", err).unwrap();
writeln!(
io::stderr(),
"Error: {}\n{}\n\nUse `abrute -h` for a help menu.",
err,
err.description()
).unwrap();
1
}
}
Expand Down
6 changes: 4 additions & 2 deletions src/process_input.rs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
use digits::BaseCustom;
use super::result::Error;

pub fn derive_min_max(range: &str) -> (usize, usize) {
pub fn derive_min_max(range: &str) -> Result<(usize, usize), Error> {
let rvals = range.split(':').collect::<Vec<&str>>();
for item in &rvals { if item.parse::<u8>().is_err() { return Err(Error::InvalidRange); } }
let mut rivals = rvals.iter();
let min = rivals.next().unwrap();
let max = rivals.next();
Expand All @@ -12,7 +14,7 @@ pub fn derive_min_max(range: &str) -> (usize, usize) {
_ => { min }
}
};
(min, get_max())
Ok((min, get_max()))
}

pub fn derive_character_base(characters: &str) -> BaseCustom<char> {
Expand Down
76 changes: 76 additions & 0 deletions src/result.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,76 @@
use std::fmt;
use std::error::Error as StdError;

#[derive(Debug)]
pub enum Error {
AescryptMissing,
FileMissing,
InvalidAdjacentNumber,
InvalidCharacterSet,
InvalidRange,
InvalidStringLength,
PasswordNotFound,
}

impl fmt::Display for Error {
fn fmt(&self, f: &mut fmt::Formatter) -> fmt::Result {
match *self {
Error::AescryptMissing => f.write_str("AescryptMissing" ),
Error::FileMissing => f.write_str("FileMissing" ),
Error::InvalidAdjacentNumber => f.write_str("InvalidAdjacentNumber"),
Error::InvalidCharacterSet => f.write_str("InvalidCharacterSet" ),
Error::InvalidRange => f.write_str("InvalidRange" ),
Error::InvalidStringLength => f.write_str("InvalidStringLength" ),
Error::PasswordNotFound => f.write_str("PasswordNotFound" ),
}
}
}

#[inline]
fn aescrypt_missing() -> &'static str {
"aescrypt does not appear to be installed."
}

#[inline]
fn file_missing() -> &'static str {
"The target file seems to be missing."
}

#[inline]
fn invalid_adjacent_number() -> &'static str {
"Invalid number for adjacent input."
}

#[inline]
fn invalid_character_set() -> &'static str {
"Invalid character set provided for start."
}

#[inline]
fn invalid_range() -> &'static str {
"Invalid range input given."
}

#[inline]
fn invalid_string_length() -> &'static str {
"Invalid string length for start given."
}

#[inline]
fn password_not_found() -> &'static str {
"Password not found for given length and character set."
}

impl StdError for Error {
fn description(&self) -> &str {
match *self {
Error::AescryptMissing => aescrypt_missing(),
Error::FileMissing => file_missing(),
Error::InvalidAdjacentNumber => invalid_adjacent_number(),
Error::InvalidCharacterSet => invalid_character_set(),
Error::InvalidRange => invalid_range(),
Error::InvalidStringLength => invalid_string_length(),
Error::PasswordNotFound => password_not_found(),
}
}
}
10 changes: 6 additions & 4 deletions src/validators.rs
Original file line number Diff line number Diff line change
@@ -1,9 +1,11 @@
pub fn validate_is_digit(v: String) -> Result<(), String> {
use super::result::Error;

pub fn validate_adjacent_input(v: String) -> Result<(), Error> {
if v.parse::<u8>().is_ok() { return Ok(()); }
Err(String::from("The value did not contain valid digit from 0 to 255"))
Err(Error::InvalidAdjacentNumber)
}

pub fn validate_string_length(v: &str, max: usize) -> Result<(), String> {
pub fn validate_string_length(v: &str, max: usize) -> Result<(), Error> {
if v.len() <= max { return Ok(()); }
Err(String::from("The value did not contain valid digit from 0 to 255"))
Err(Error::InvalidStringLength)
}
36 changes: 36 additions & 0 deletions test/invalid.test
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,40 @@ describe "* abrute with invalid input"
target/debug/abrute 4:4 asdf -- test/data/example-thingy.file.aes 2>/dev/null
assert unequal $? 0
end

it "does not panic with invalid range"
message=`target/debug/abrute asdf asdf -- asdf 2>& 1`
echo "$message" | grep -q "thread*"
assert unequal $? 0
end

it "does not panic with file missing"
message=`target/debug/abrute 4 asdf -- asdf 2>& 1`
echo "$message" | grep -q "thread*"
assert unequal $? 0
end

it "does not panic with invalid adjacent number"
message=`target/debug/abrute 4 asdf -a g -- asdf 2>& 1`
echo "$message" | grep -q "thread*"
assert unequal $? 0
end

it "does not panic with invalid character starters"
message=`target/debug/abrute 4 asdf -s 1234 -- asdf 2>& 1`
echo "$message" | grep -q "thread*"
assert unequal $? 0
end

it "does not panic with invalid characters length"
message=`target/debug/abrute 4 asdf -s 12 -- asdf 2>& 1`
echo "$message" | grep -q "thread*"
assert unequal $? 0
end

it "does not show invalid double dash on invalid dash usage"
message=`target/debug/abrute 4 asdf asdf 2>& 1`
echo "$message" | grep -q " -- "
assert equal $? 0
end
end

0 comments on commit 2b82d08

Please sign in to comment.