summaryrefslogtreecommitdiff
path: root/src/main.rs
blob: 56df61142d3490a88fc82e928aac6ac90c6cee8a (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
use std::env;
use std::process::ExitCode;


mod auth;
mod flags;
mod persist;
mod secure;


const ERROR_ARGS:               u8 = 1;
const ERROR_CONFIG:             u8 = 2;
const ERROR_NOT_AUTHORIZED:     u8 = 3;
const ERROR_AUTH_FAILED:        u8 = 4;
const ERROR_ELEVATE_PRIVILEGES: u8 = 5;


fn main() -> ExitCode {

    // gets the arguments from the env
    let args: Vec<String> = env::args().collect();

    // pase the arguments into valid flags that are usuable by crab
    let flags = match flags::parse(&args[1..]) {
        Some(data) => data,
        // if there is an invalid flag, print the help message and exit
        None => {
            help();
            return ExitCode::from(ERROR_ARGS);
        }
    };

    // If the version arg flag is set, print the crab version
    if flags.version {
        println!("crab version 0.0.6");
        return ExitCode::SUCCESS;
    }

    // If the help arg flag is set, print the crab help message
    if flags.help {
        help();
        return ExitCode::SUCCESS;
    }

    // If the amount of acutal command arguments is less than two, a.k.a just `crab`, print the command usage
    if args.len() - flags.arg_count < 2 {
        println!("usage: crab [-d] command [args]");
        return ExitCode::SUCCESS;
    }

    // Load the command config from /etc
    let configs = match auth::load_config_file("/etc/crab.conf") {
        Some(data) => data,
        None => return ExitCode::from(ERROR_CONFIG)
    };


    // check if the user is authorized
    let auth = match auth::authorize(&configs, nix::unistd::getuid()) {
        Some(data) => data,
        None => {
            eprintln!("Operation Not Permitted.");
            return ExitCode::from(ERROR_NOT_AUTHORIZED);
        }
    };

    // authenticate the user
    if !auth::authenticate(&configs[auth], flags.dont_persist, nix::unistd::getuid()) {
        eprintln!("Authentication failed.");
        return ExitCode::from(ERROR_AUTH_FAILED);
    }

    // elevate privileges
    if nix::unistd::setuid(configs[auth].privlaged_uid).is_err() {
        eprintln!("Failed to elevate privileges.");
        return ExitCode::from(ERROR_ELEVATE_PRIVILEGES);
    };

    // execute the passed command
    let start = 1 + flags.arg_count;
    let err = exec::execvp(&args[start], &args[start..]);
    
    // print an error if an error was returned
    eprintln!("{}", err);
    
    ExitCode::SUCCESS
}


/// Prints the help message to the standard output
fn help() {
    let help = 
"Usage:
    crab [-d] command [args]
Options:
    -v --version    Get the current version of the package
    -h --help       Generates the crab help message
    -d              If your user is set to persist, dont save persistance";
    println!("{}", help);
}