Skip to content

Instantly share code, notes, and snippets.

@rusty-snake
Last active August 1, 2019 14:22
Show Gist options
  • Save rusty-snake/9035b6d9330968322356918a7834eb86 to your computer and use it in GitHub Desktop.
Save rusty-snake/9035b6d9330968322356918a7834eb86 to your computer and use it in GitHub Desktop.
Check for every noblacklist in firejail profiles a corresponding blacklist exists
/*
* Copyright © 2019 rusty-snake <print_hello_world+License@protonmail.com>
*
* Permission to use, copy, modify, and distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
// # Install rust
//
// curl https://sh.rustup.rs -sSf | sh
//
// If you don't trust `curl | sh':
// - https://www.rust-lang.org/tools/install
// - ArchLinux: 'pacman -S rust'
// - Fedora: 'dnf install rust'
//
// # Compile
//
// rustc --edition=2018 -O -o fjcb firejail-check-blacklist.rs
//
// # Run
//
// ./fjcb /etc/firejail/*.profile
//
// # Usage
//
// FJCB_DISINC_BASE_PATH=<PATH> ./fjcb <PROFILES>
//
// FJCB_DISINC_BASE_PATH is where to look for disable-*.inc,
// if not set /etc/firejail is assumed.
use std::{env, fs, io};
fn main() -> Result<(), io::Error> {
let noblacklist = noblacklisted_paths()?;
let blacklist = blacklisted_paths()?;
check(blacklist, noblacklist);
Ok(())
}
/// Check for every entry in noblacklist if there is a corresponding entry in blacklist
fn check(blacklist: Vec<String>, noblacklist: Vec<String>) {
for path in noblacklist {
if !blacklist.contains(&path) {
println!("Could not find blacklist for: noblacklist {}", path);
}
}
}
/// Get all noblacklist-paths from profiles specified on the command line
///
/// Some noblacklist-paths are whitelisted because
/// - they are very common and it is quick to sort them out here
/// - `${DOCUMENTS}`
/// - `${MUSIC}`
/// - `${PICTURES}`
/// - `${VIDEOS}`
/// - the blacklisting is built in firejail
/// - `/sys/module`
/// - this program can not check paths if they are using globing
/// - `${HOME}/.tor-browser-*`
/// - `${HOME}/.tor-browser_*`
/// - `${HOME}/.dropbox*`
/// - `${HOME}/.PyCharm*`
/// - `${HOME}/.electrum*`
/// - `/etc/cron*`
/// - `${HOME}/.*_history`
/// - the blacklisting occurrs in a redirected profile
/// - `/tmp/.X11-unix` in xlinks.profile
fn noblacklisted_paths() -> Result<Vec<String>, io::Error> {
let mut noblacklists: Vec<String> = Vec::new();
for arg in env::args().skip(1) {
for line in fs::read_to_string(&arg)?.lines() {
if line.starts_with("noblacklist ") {
// whitelisted noblacklist lines
if line == "noblacklist ${DOCUMENTS}"
|| line == "noblacklist ${MUSIC}"
|| line == "noblacklist ${PICTURES}"
|| line == "noblacklist ${VIDEOS}"
|| line == "noblacklist /sys/module"
|| line.starts_with("noblacklist ${HOME}/.tor-browser-")
|| line.starts_with("noblacklist ${HOME}/.tor-browser_")
|| line.starts_with("noblacklist ${HOME}/.dropbox")
|| line.starts_with("noblacklist ${HOME}/.PyCharm")
|| line.starts_with("noblacklist ${HOME}/.electrum")
|| line.starts_with("noblacklist /etc/cron")
|| (line.starts_with("noblacklist ${HOME}/.") && line.ends_with("_history"))
|| (line == "noblacklist /tmp/.X11-unix" && arg.ends_with("xlinks.profile"))
{
continue;
}
noblacklists.push(line[12..].to_string());
}
}
}
Ok(noblacklists)
}
/// Get all blacklist-paths specified in disable-*.inc (except disable-xdg.inc)
fn blacklisted_paths() -> Result<Vec<String>, io::Error> {
let mut blacklists: Vec<String> = Vec::new();
let disinc_base_path = match env::var("FJCB_DISINC_BASE_PATH") {
Ok(path) => path,
Err(env::VarError::NotPresent) => "/etc/firejail".to_string(),
Err(env::VarError::NotUnicode(_)) => {
panic!("FJCB_DISINC_BASE_PATH doesn't contain valid unicode")
}
};
for disable_inc_file in &[
disinc_base_path.clone() + "/disable-common.inc",
disinc_base_path.clone() + "/disable-devel.inc",
disinc_base_path.clone() + "/disable-interpreters.inc",
disinc_base_path.clone() + "/disable-passwdmgr.inc",
disinc_base_path.clone() + "/disable-programs.inc",
//disinc_base_path.clone() + "/disable-xdg.inc",
] {
for line in fs::read_to_string(disable_inc_file)?.lines() {
if line.starts_with("blacklist ") {
blacklists.push(line[10..].to_string());
} else if line.starts_with("blacklist-nolog ") {
blacklists.push(line[16..].to_string());
}
}
}
Ok(blacklists)
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment