From 6e24660a80a9fc0e6771c04e009a94e4f747621d Mon Sep 17 00:00:00 2001 From: Jack Grigg Date: Thu, 21 Nov 2019 13:08:24 +0000 Subject: [PATCH] Clean up internal::setting_get_bool --- src/internal.rs | 117 +++++++++++++++--------------------------------- src/util.rs | 5 +-- 2 files changed, 38 insertions(+), 84 deletions(-) diff --git a/src/internal.rs b/src/internal.rs index ea65c5b..e6cee67 100644 --- a/src/internal.rs +++ b/src/internal.rs @@ -39,8 +39,9 @@ use des::{ block_cipher_trait::{generic_array::GenericArray, BlockCipher}, TdesEde3, }; -use libc::{c_char, c_int, fclose, feof, fgets, fopen, getenv, sscanf, strcasecmp, strcmp}; -use std::ffi::{CStr, CString}; +use std::env; +use std::fs::File; +use std::io::{BufRead, BufReader}; use zeroize::Zeroize; /// 3DES keys. The three subkeys are concatenated. @@ -160,12 +161,6 @@ pub enum Pkcs5ErrorKind { GeneralError = -1, } -/// Strip whitespace -// TODO(tarcieri): implement this -pub unsafe fn _strip_ws(sz: *mut c_char) -> *mut c_char { - sz -} - /// Source of how a setting was configured #[derive(Clone, Copy, Debug, Eq, PartialEq)] pub enum SettingSource { @@ -190,105 +185,65 @@ pub struct SettingBool { } /// Get a boolean config value -pub unsafe fn _get_bool_config(sz_setting: *const c_char) -> SettingBool { +pub fn _get_bool_config(key: &str) -> SettingBool { let mut setting: SettingBool = SettingBool { value: false, source: SettingSource::Default, }; - let mut sz_line = [0u8; 256]; - let mut psz_name: *mut c_char; - let mut psz_value: *mut c_char; - let mut sz_name = [0u8; 256]; - let mut sz_value = [0u8; 256]; - let pf = fopen( - b"/etc/yubico/yubikeypiv.conf\0".as_ptr() as *const c_char, - b"r\0".as_ptr() as *const c_char, - ); + if let Ok(f) = File::open("/etc/yubico/yubikeypiv.conf") { + for line in BufReader::new(f).lines() { + let line = match line { + Ok(line) => line, + _ => continue, + }; - if pf.is_null() { - return setting; + if line.starts_with('#') || line.starts_with('\r') || line.starts_with('\n') { + continue; + } + + let (name, value) = { + let mut parts = line.splitn(1, '='); + let name = parts.next(); + let value = parts.next(); + match (name, value, parts.next()) { + (Some(name), Some(value), None) => (name.trim(), value.trim()), + _ => continue, + } + }; + + if name == key { + setting.source = SettingSource::Admin; + setting.value = value == "1" || value == "true"; + break; + } + } } - while feof(pf) == 0 { - if fgets( - sz_line.as_mut_ptr() as *mut c_char, - sz_line.len() as c_int, - pf, - ) - .is_null() - { - continue; - } - - if sz_line[0] == b'#' { - continue; - } - - if sz_line[0] == b'\r' { - continue; - } - - if sz_line[0] == b'\n' { - continue; - } - - if sscanf( - sz_line.as_ptr() as *const c_char, - b"%255[^=]=%255s\0".as_ptr() as *const c_char, - sz_name.as_mut_ptr(), - sz_value.as_mut_ptr(), - ) != 2 - { - continue; - } - - psz_name = _strip_ws(sz_name.as_mut_ptr() as *mut c_char); - - if strcasecmp(psz_name, sz_setting) != 0 { - continue; - } - - psz_value = _strip_ws(sz_value.as_mut_ptr() as *mut c_char); - setting.source = SettingSource::Admin; - setting.value = strcmp(psz_value, b"1\0".as_ptr() as *const c_char) == 0 - || strcasecmp(psz_value, b"true\0".as_ptr() as *const c_char) == 0; - } - - fclose(pf); setting } /// Get a setting boolean from an environment variable -pub unsafe fn _get_bool_env(sz_setting: *const c_char) -> SettingBool { +pub fn _get_bool_env(key: &str) -> SettingBool { let mut setting: SettingBool = SettingBool { value: false, source: SettingSource::Default, }; - let sz_name = CString::new(format!( - "YUBIKEY_PIV_{}", - CStr::from_ptr(sz_setting).to_string_lossy() - )) - .unwrap(); - - let psz_value = getenv(sz_name.as_ptr()); - - if !psz_value.is_null() { + if let Ok(value) = env::var(format!("YUBIKEY_PIV_{}", key)) { setting.source = SettingSource::User; - setting.value = strcmp(psz_value, b"1\0".as_ptr() as *const c_char) == 0 - || strcasecmp(psz_value, b"true\0".as_ptr() as *const c_char) == 0; + setting.value = value == "1" || value == "true"; } setting } /// Get a setting boolean -pub unsafe fn setting_get_bool(sz_setting: *const c_char, def: bool) -> SettingBool { - let mut setting = _get_bool_config(sz_setting); +pub fn setting_get_bool(key: &str, def: bool) -> SettingBool { + let mut setting = _get_bool_config(key); if setting.source == SettingSource::Default { - setting = _get_bool_env(sz_setting); + setting = _get_bool_env(key); } if setting.source == SettingSource::Default { diff --git a/src/util.rs b/src/util.rs index 2d45ec7..18d4b0d 100644 --- a/src/util.rs +++ b/src/util.rs @@ -41,7 +41,7 @@ use log::{error, warn}; use pbkdf2::pbkdf2; use sha1::Sha1; use std::ops::DerefMut; -use std::{ffi::CString, mem, os::raw::c_void, ptr}; +use std::{mem, os::raw::c_void, ptr}; use zeroize::{Zeroize, Zeroizing}; /// Cardholder Unique Identifier (CHUID) Template @@ -1002,8 +1002,7 @@ pub unsafe fn ykpiv_util_generate_key( && state.ver.major == 4 && (state.ver.minor < 3 || state.ver.minor == 3 && (state.ver.patch < 5)) { - let setting_name = CString::new(SZ_SETTING_ROCA).unwrap(); - setting_roca = setting_get_bool(setting_name.as_ptr(), true); + setting_roca = setting_get_bool(SZ_SETTING_ROCA, true); let psz_msg = match setting_roca.source { SettingSource::User => {