Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Change watchdog to a single binary #10

Merged
merged 15 commits into from
Feb 6, 2020
Merged
Show file tree
Hide file tree
Changes from 9 commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1,716 changes: 0 additions & 1,716 deletions Cargo.lock

This file was deleted.

25 changes: 8 additions & 17 deletions Cargo.toml
Original file line number Diff line number Diff line change
Expand Up @@ -12,22 +12,13 @@ toml = "0.5.3"
reqwest = "0.9.20"
base64 = "0.10.1"
rust-crypto = "0.2.36"
simplelog = "^0.7.3"
log = "^0.4.8"
clap = "2.19"
error-chain="0.12.1"

[[bin]]
name = "pam_sudo"
path = "src/sudo/main.rs"

[[bin]]
name = "pam_su"
path = "src/su/main.rs"

[[bin]]
name = "pam_ssh"
path = "src/ssh/main.rs"

[[bin]]
name = "auth_keys_cmd"
path = "src/auth_keys_cmd/main.rs"
[[ bin ]]
name = "watchdog"
path = "src/main.rs"

[lib]
name = "common_lib"
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Use lib instead of common_lib

path = "src/lib.rs"
2 changes: 1 addition & 1 deletion install/edit-sshd-config.py
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@

UsePAM yes
PasswordAuthentication no
AuthorizedKeysCommand /opt/watchdog/bin/auth_keys_cmd %u %h %t %f %k
AuthorizedKeysCommand /opt/watchdog/bin/watchdog auth -u %u -t %t -p %k
AuthorizedKeysCommandUser root

# SDSLabs Watchdog configuration END
Expand Down
29 changes: 9 additions & 20 deletions install/install.sh
Original file line number Diff line number Diff line change
Expand Up @@ -2,26 +2,15 @@

# Install all the files at right place
mkdir -p /opt/watchdog/bin

cp ../target/debug/pam_ssh /opt/watchdog/bin/pam_ssh
chown root /opt/watchdog/bin/pam_ssh
chgrp root /opt/watchdog/bin/pam_ssh
chmod 700 /opt/watchdog/bin/pam_ssh

cp ../target/debug/pam_su /opt/watchdog/bin/pam_su
chown root /opt/watchdog/bin/pam_su
chgrp root /opt/watchdog/bin/pam_su
chmod 700 /opt/watchdog/bin/pam_su

cp ../target/debug/pam_sudo /opt/watchdog/bin/pam_sudo
chown root /opt/watchdog/bin/pam_sudo
chgrp root /opt/watchdog/bin/pam_sudo
chmod 700 /opt/watchdog/bin/pam_sudo

cp ../target/debug/auth_keys_cmd /opt/watchdog/bin/auth_keys_cmd
chown root /opt/watchdog/bin/auth_keys_cmd
chgrp root /opt/watchdog/bin/auth_keys_cmd
chmod 700 /opt/watchdog/bin/auth_keys_cmd
mkdir -p /opt/watchdog/logs
touch /opt/watchdog/logs/sudo.logs
touch /opt/watchdog/logs/su.logs
touch /opt/watchdog/logs/ssh.logs

cp ../target/debug/watchdog /opt/watchdog/bin/watchdog
chown root /opt/watchdog/bin/watchdog
chgrp root /opt/watchdog/bin/watchdog
chmod 700 /opt/watchdog/bin/watchdog

cp ../config.toml /opt/watchdog/config.toml

Expand Down
2 changes: 1 addition & 1 deletion install/pam-install-ssh.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
watchdog_config = """
# SDSLabs Watchdog configuration START

session optional pam_exec.so seteuid /opt/watchdog/bin/pam_ssh
session optional pam_exec.so seteuid log=/opt/watchdog/logs/ssh.logs /opt/watchdog/bin/watchdog ssh

# SDSLabs Watchdog configuration END
"""
Expand Down
2 changes: 1 addition & 1 deletion install/pam-install-su.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
watchdog_config = """
# SDSLabs Watchdog configuration START

session optional pam_exec.so seteuid /opt/watchdog/bin/pam_su
session optional pam_exec.so seteuid log=/opt/watchdog/logs/su.logs /opt/watchdog/bin/watchdog su

# SDSLabs Watchdog configuration END
"""
Expand Down
2 changes: 1 addition & 1 deletion install/pam-install-sudo.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,7 @@
watchdog_config = """
# SDSLabs Watchdog configuration START

session optional pam_exec.so seteuid /opt/watchdog/bin/pam_sudo
session optional pam_exec.so seteuid log=/opt/watchdog/logs/sudo.logs /opt/watchdog/bin/watchdog sudo

# SDSLabs Watchdog configuration END
"""
Expand Down
51 changes: 51 additions & 0 deletions src/auth.rs
Original file line number Diff line number Diff line change
@@ -0,0 +1,51 @@
use common_lib::config::read_config;
use common_lib::errors::*;
use common_lib::init::init;
use common_lib::keyhouse::{get_name, validate_user};
use common_lib::notifier::{Notifier, Slack};
use std::fs;
use std::process::Command;

pub fn handle_auth(ssh_host_username: &str, ssh_key: &str) -> Result<()> {
let config = read_config()?;
init(&config)?;

match validate_user(&config, ssh_host_username.to_string(), ssh_key) {
Ok(true) => {
let data = format!(
"ssh_host_username = '{}'\nssh_key = '{}'\n",
ssh_host_username, ssh_key
);

fs::write(&config.temp_env_file, data)
.chain_err(|| "Cannot write temporary environment file. Please check if the watchdog `auth_keys_cmd` is run by the root user")?;

println!("{}", ssh_key);
Ok(())
}

Ok(false) => {
let name = get_name(&config, ssh_key)?;

match Slack::new(&config) {
Some(notifier) => notifier.post_ssh_summary(
&config,
false,
name,
ssh_host_username.to_string(),
)?,
None => {}
};
Ok(())
}

Err(e) => Err(e).chain_err(|| "Error while validating user from keyhouse"),
}
}

pub fn handle_auth_logs() {
Command::new("less")
.arg("/opt/watchdog/logs/ssh.logs")
.status()
.expect("Something went wrong. Is `less` command present in your environment?");
}
44 changes: 0 additions & 44 deletions src/auth_keys_cmd/main.rs

This file was deleted.

10 changes: 5 additions & 5 deletions src/config.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::errors::*;
use serde_derive::Deserialize;
use std::fs;

Expand All @@ -12,9 +13,8 @@ pub struct Config {
pub error_log_file: String,
}

pub fn read_config() -> Config {
let toml_str = fs::read_to_string("/opt/watchdog/config.toml")
.expect("Error reading the config.toml file.");
let config: Config = toml::from_str(&toml_str).unwrap();
return config;
pub fn read_config() -> Result<Config> {
let toml_str = fs::read_to_string("/opt/watchdog/config.toml")?;
let config: Config = toml::from_str(&toml_str)?;
Ok(config)
}
9 changes: 5 additions & 4 deletions src/environment.rs
Original file line number Diff line number Diff line change
@@ -1,3 +1,4 @@
use crate::errors::*;
use serde_derive::Deserialize;
use std::fs;

Expand All @@ -7,8 +8,8 @@ pub struct TempEnvirontment {
pub ssh_key: String,
}

pub fn read_temp_env(path: &String) -> TempEnvirontment {
let toml_str = fs::read_to_string(path).expect("Error reading the environment toml file.");
let env: TempEnvirontment = toml::from_str(&toml_str).unwrap();
return env;
pub fn read_temp_env(path: &str) -> Result<TempEnvirontment> {
let toml_str = fs::read_to_string(path)?;
let env: TempEnvirontment = toml::from_str(&toml_str)?;
Ok(env)
}
36 changes: 4 additions & 32 deletions src/init.rs
Original file line number Diff line number Diff line change
@@ -1,34 +1,6 @@
extern crate simplelog;
use crate::config::Config;
use crate::errors::*;

use crate::config;
use log::error;
use simplelog::*;
use std::fs::OpenOptions;

pub fn init(config: &config::Config) {
init_logger(&config);
}

pub fn init_logger(config: &config::Config) {
let log_file = match OpenOptions::new()
.create_new(true)
.read(true)
.append(true)
.open(&config.error_log_file)
{
Ok(f) => f,
Err(_) => {
error!("Watchdog: Couldn't open log file");
panic!("Watchdog: Couldn't open log file");
}
};

let _res = match CombinedLogger::init(vec![WriteLogger::new(
LevelFilter::Info,
Config::default(),
log_file,
)]) {
Ok(_) => {}
Err(_) => error!("Watchdog: Couldnt start logger for some reason"),
};
pub fn init(_config: &Config) -> Result<()> {
Ok(())
}
64 changes: 39 additions & 25 deletions src/keyhouse.rs
Original file line number Diff line number Diff line change
@@ -1,40 +1,60 @@
extern crate base64;
extern crate crypto;
extern crate reqwest;
extern crate serde_json;

use crate::config::Config;
use crate::errors::*;

use crate::config;
use crypto::digest::Digest;
use crypto::sha2::Sha256;
use log::error;
use serde_json;

pub fn validate_user(config: &config::Config, user: String, ssh_key: &String) -> bool {
pub fn validate_user(config: &Config, user: String, ssh_key: &str) -> Result<bool> {
let mut hasher = Sha256::new();

hasher.input_str(&ssh_key);
let hex = hasher.result_str();

let res = reqwest::get(&format!(
"{}/access/{}/{}/{}?ref=build&access_token={}",
config.keyhouse_base_url, config.keyhouse_hostname, user, hex, config.keyhouse_token
));
let client = reqwest::Client::new();
let res = client
.get(&format!(
"{}/access/{}/{}/{}?ref=build",
config.keyhouse_base_url, config.keyhouse_hostname, user, hex
))
.header(
"Authorization",
&format!("Bearer {}", config.keyhouse_token),
)
.send();

match res {
Ok(r) => {
if r.status().is_success() {
return true;
return Ok(true);
} else {
return false;
return Ok(false);
}
}
Err(_) => {
error!("Error making request to keyhouse.");
return false;
}
Err(e) => Err(Error::from(format!("Unknown reqwest error \n-> {}", e))),
}
}

pub fn get_name(config: &config::Config, ssh_key: String) -> String {
fn get_content_from_github_json(json_text: &str) -> Result<String> {
let json: serde_json::Value = serde_json::from_str(json_text)
.chain_err(|| "Invalid JSON recieved from GitHub. Probably GitHub is facing some issues. Check https://githubstatus.com.")?;
let encoded_content = json["content"]
.as_str()
.ok_or(Error::from(""))
.chain_err(|| "No key 'content' found in JSON recieved from GitHub.")?;
let len = str::len(encoded_content);
let content = base64::decode(&encoded_content[..len-2])
.chain_err(|| "Bad Base64 Encoding. Probably GitHub is facing some issues. Check https://githubstatus.com.")?;
Ok(String::from_utf8(content).chain_err(|| {
"Bad UTF8 Encoding. Make sure the file you are trying to access is human readable."
})?)
}

pub fn get_name(config: &Config, ssh_key: &str) -> Result<String> {
let mut hasher = Sha256::new();

hasher.input_str(&ssh_key);
Expand All @@ -48,18 +68,12 @@ pub fn get_name(config: &config::Config, ssh_key: String) -> String {
match res {
Ok(mut r) => {
if r.status().is_success() {
let json_text = r.text().unwrap();
let json: serde_json::Value = serde_json::from_str(&json_text).unwrap();
let name = json["content"].as_str().unwrap();
let len = String::len(&String::from(name));
return String::from_utf8(base64::decode(&name[..len - 2]).unwrap()).unwrap();
let json_text = r.text()?;
return get_content_from_github_json(&json_text);
} else {
return String::new();
return Ok(String::from("UNKNOWN"));
}
}
Err(_) => {
error!("Error while making a request to keyhouse");
return String::new();
}
Err(e) => Err(Error::from(format!("Unknown reqwest error \n-> {}", e))),
}
}
17 changes: 17 additions & 0 deletions src/lib.rs
Original file line number Diff line number Diff line change
Expand Up @@ -4,3 +4,20 @@ pub mod init;
pub mod keyhouse;
pub mod notifier;
pub mod utils;

#[macro_use]
extern crate error_chain;

pub mod errors {
error_chain! {
foreign_links {
Io(::std::io::Error);
Json(::serde_json::Error);
B64DecodeError(::base64::DecodeError);
UTF8Error(::std::string::FromUtf8Error);
Reqwest(::reqwest::Error);
Toml(::toml::de::Error);
Time(::std::time::SystemTimeError);
}
}
}
Loading