Skip to content
dfimd.rs 5.73 KiB
Newer Older
Luker's avatar
Luker committed
/*
 * Copyright (c) 2021, Luca Fulchir <luker@fenrirproject.org>
 *
 * This file is part of dfim.
 *
 * dfim is free software: you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation, either version 3 of the License, or
 * (at your option) any later version.
 *
 * dfim is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU General Public License for more details.
 *
 * You should have received a copy of the GNU General Public License
 * along with dfim.  If not, see <https://www.gnu.org/licenses/>.
 */

extern crate clap;
Luker's avatar
Luker committed
extern crate libdfim;
Luker's avatar
Luker committed

mod worker;

/// # dfim: Device&Filesystem Initialization&Monitoring
fn main() -> Result<(), ::std::io::Error> {
    let clap_app = ::clap::App::new("dfim")
        .author(::clap::crate_version!())
        .version(::clap::crate_version!())
        .about(::clap::crate_description!())
        .arg(
            ::clap::Arg::new("config")
                .help("Sets a custom config file")
                .long("config")
                .short('c')
                .value_name("CONFIG")
                .takes_value(true),
        );

    let cmdline = clap_app.get_matches();
    let cfg_path = ::std::path::Path::new(
        cmdline.value_of("config").unwrap_or("/etc/d4fim.ron"),
    );
    let logger: ::std::sync::Arc<::slog::Logger> =
Luker's avatar
Luker committed
        ::std::sync::Arc::new(::libdfim::log::create_default_logger());
Luker's avatar
Luker committed

    let is_metadata = ::std::fs::metadata(cfg_path);

    match is_metadata {
        Ok(meta) => {
            let mode = ::std::os::linux::fs::MetadataExt::st_mode(&meta);
            const OTHERS: u32 = 0x0007;
            let is_world_accessible = mode & OTHERS;
            if is_world_accessible != 0 {
                ::slog::error!(
                    logger,
                    "Configuration file is world accessible"
                );
Luker's avatar
Luker committed
                ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                ::std::process::exit(1);
            }
        }
        Err(meta_err) => {
            ::slog::error!(logger, "Error on configuration file: {}", meta_err);
Luker's avatar
Luker committed
            ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
            ::std::process::exit(1);
        }
    }

Luker's avatar
Luker committed
    let raw_cfg = match ::libdfim::config::FullConfig::parse(&logger, cfg_path)
    {
        Ok(cfg) => cfg,
        Err(_e) => {
            ::slog::error!(logger, "Error parsing conf file");
Luker's avatar
Luker committed
            ::libdfim::log::drop_logger(logger);
            ::std::process::exit(1);
        }
    };
Luker's avatar
Luker committed
    let cfg = match ::libdfim::state::cfg::Cfg::new(&logger, raw_cfg) {
Luker's avatar
Luker committed
        Ok(cfg) => cfg,
Luker's avatar
Luker committed
        Err(_e) => {
Luker's avatar
Luker committed
            ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
            ::std::process::exit(1);
        }
    };

    let logger: ::std::sync::Arc<::slog::Logger> = ::std::sync::Arc::new(
Luker's avatar
Luker committed
        match ::libdfim::log::create_logger(&cfg.main.logging) {
Luker's avatar
Luker committed
            Err(e) => {
                ::slog::error!(logger, "Error: can't setup logger: {}", e);
Luker's avatar
Luker committed
                ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                ::std::process::exit(1);
            }
            Ok(new_logger) => {
Luker's avatar
Luker committed
                ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                new_logger
            }
        },
    );
    ::slog::info!(logger, "Configuration correctly loaded");

    /*
     * This only for the notification deamon
    let current_user = match ::users::get_current_username() {
        Some(user) => match user.into_string() {
            Ok(user_str) => user_str,
            Err(_e) => {
                ::slog::error!(logger, "current user is not utf-8?");
Luker's avatar
Luker committed
                ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                ::std::process::exit(1);
            }
        },
        None => {
            ::slog::error!(logger, "Error getting current user");
Luker's avatar
Luker committed
            ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
            ::std::process::exit(1);
        }
    };
    let mut drop_privs = true;
    if cfg.user == current_user {
        let group_list = match ::users::group_access_list() {
            Ok(group_list) => group_list,
            Err(_e) => {
                ::slog::error!(logger, "Can't get list of current groups");
Luker's avatar
Luker committed
                ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                ::std::process::exit(6);
            }
        };
        let group_found: bool = group_list.iter().any(|g| {
            match g.name().to_os_string().into_string() {
                Ok(g_str) => {
                    ::slog::info!(logger, "found group: {} ", g_str);
                    g_str == cfg.group
                }
                Err(_e) => {
                    ::slog::error!(logger, "non utf-8 group found");
                    false
                }
            }
        });
        match group_found {
            true => {
                drop_privs = false;
            }
            false => {}
        };
    }

    match drop_privs {
        false => {
            ::slog::info!(logger, "Not dropping privileges");
        }
        true => {
            // drop privileges
            match ::privdrop::PrivDrop::default()
                .user(&cfg.user)
                .group(&cfg.group)
                .apply()
            {
                Ok(_) => {
                    ::slog::info!(logger, "privileges dropped");
                }
                Err(e) => {
                    ::slog::error!(logger, "Can't drop privileges: {}", e);
Luker's avatar
Luker committed
                    ::libdfim::log::drop_logger(logger);
Luker's avatar
Luker committed
                    ::std::process::exit(7);
                }
            };
        }
    };
    */
    ::tokio::runtime::Builder::new_multi_thread()
        .enable_all()
        .build()
        .unwrap()
        .block_on(worker::entry(logger, cfg))
}