move token_shadow to pbs_config workspace
Also moved out crypt.rs (libcrypt bindings) to pbs_tools workspace.
This commit is contained in:
		@ -7,6 +7,7 @@ pub mod remote;
 | 
				
			|||||||
pub mod sync;
 | 
					pub mod sync;
 | 
				
			||||||
pub mod tape_encryption_keys;
 | 
					pub mod tape_encryption_keys;
 | 
				
			||||||
pub mod tape_job;
 | 
					pub mod tape_job;
 | 
				
			||||||
 | 
					pub mod token_shadow;
 | 
				
			||||||
pub mod verify;
 | 
					pub mod verify;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use anyhow::{format_err, Error};
 | 
					use anyhow::{format_err, Error};
 | 
				
			||||||
 | 
				
			|||||||
@ -6,9 +6,9 @@ use serde_json::{from_value, Value};
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use proxmox::tools::fs::CreateOptions;
 | 
					use proxmox::tools::fs::CreateOptions;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api2::types::Authid;
 | 
					use pbs_api_types::Authid;
 | 
				
			||||||
use crate::auth;
 | 
					//use crate::auth;
 | 
				
			||||||
use pbs_config::open_backup_lockfile;
 | 
					use crate::{open_backup_lockfile, BackupLockGuard};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
const LOCK_FILE: &str = pbs_buildcfg::configdir!("/token.shadow.lock");
 | 
					const LOCK_FILE: &str = pbs_buildcfg::configdir!("/token.shadow.lock");
 | 
				
			||||||
const CONF_FILE: &str = pbs_buildcfg::configdir!("/token.shadow");
 | 
					const CONF_FILE: &str = pbs_buildcfg::configdir!("/token.shadow");
 | 
				
			||||||
@ -21,6 +21,11 @@ pub struct ApiTokenSecret {
 | 
				
			|||||||
    pub secret: String,
 | 
					    pub secret: String,
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// Get exclusive lock
 | 
				
			||||||
 | 
					fn lock_config() -> Result<BackupLockGuard, Error> {
 | 
				
			||||||
 | 
					    open_backup_lockfile(LOCK_FILE, None, true)
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn read_file() -> Result<HashMap<Authid, String>, Error> {
 | 
					fn read_file() -> Result<HashMap<Authid, String>, Error> {
 | 
				
			||||||
    let json = proxmox::tools::fs::file_get_json(CONF_FILE, Some(Value::Null))?;
 | 
					    let json = proxmox::tools::fs::file_get_json(CONF_FILE, Some(Value::Null))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -33,7 +38,7 @@ fn read_file() -> Result<HashMap<Authid, String>, Error> {
 | 
				
			|||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
fn write_file(data: HashMap<Authid, String>) -> Result<(), Error> {
 | 
					fn write_file(data: HashMap<Authid, String>) -> Result<(), Error> {
 | 
				
			||||||
    let backup_user = pbs_config::backup_user()?;
 | 
					    let backup_user = crate::backup_user()?;
 | 
				
			||||||
    let options = CreateOptions::new()
 | 
					    let options = CreateOptions::new()
 | 
				
			||||||
        .perm(nix::sys::stat::Mode::from_bits_truncate(0o0640))
 | 
					        .perm(nix::sys::stat::Mode::from_bits_truncate(0o0640))
 | 
				
			||||||
        .owner(backup_user.uid)
 | 
					        .owner(backup_user.uid)
 | 
				
			||||||
@ -43,6 +48,7 @@ fn write_file(data: HashMap<Authid, String>) -> Result<(), Error> {
 | 
				
			|||||||
    proxmox::tools::fs::replace_file(CONF_FILE, &json, options)
 | 
					    proxmox::tools::fs::replace_file(CONF_FILE, &json, options)
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Verifies that an entry for given tokenid / API token secret exists
 | 
					/// Verifies that an entry for given tokenid / API token secret exists
 | 
				
			||||||
pub fn verify_secret(tokenid: &Authid, secret: &str) -> Result<(), Error> {
 | 
					pub fn verify_secret(tokenid: &Authid, secret: &str) -> Result<(), Error> {
 | 
				
			||||||
    if !tokenid.is_token() {
 | 
					    if !tokenid.is_token() {
 | 
				
			||||||
@ -52,7 +58,7 @@ pub fn verify_secret(tokenid: &Authid, secret: &str) -> Result<(), Error> {
 | 
				
			|||||||
    let data = read_file()?;
 | 
					    let data = read_file()?;
 | 
				
			||||||
    match data.get(tokenid) {
 | 
					    match data.get(tokenid) {
 | 
				
			||||||
        Some(hashed_secret) => {
 | 
					        Some(hashed_secret) => {
 | 
				
			||||||
            auth::verify_crypt_pw(secret, &hashed_secret)
 | 
					            pbs_tools::crypt::verify_crypt_pw(secret, &hashed_secret)
 | 
				
			||||||
        },
 | 
					        },
 | 
				
			||||||
        None => bail!("invalid API token"),
 | 
					        None => bail!("invalid API token"),
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
@ -64,10 +70,10 @@ pub fn set_secret(tokenid: &Authid, secret: &str) -> Result<(), Error> {
 | 
				
			|||||||
        bail!("not an API token ID");
 | 
					        bail!("not an API token ID");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let _guard = open_backup_lockfile(LOCK_FILE, None, true)?;
 | 
					    let _guard = lock_config()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut data = read_file()?;
 | 
					    let mut data = read_file()?;
 | 
				
			||||||
    let hashed_secret = auth::encrypt_pw(secret)?;
 | 
					    let hashed_secret = pbs_tools::crypt::encrypt_pw(secret)?;
 | 
				
			||||||
    data.insert(tokenid.clone(), hashed_secret);
 | 
					    data.insert(tokenid.clone(), hashed_secret);
 | 
				
			||||||
    write_file(data)?;
 | 
					    write_file(data)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -80,7 +86,7 @@ pub fn delete_secret(tokenid: &Authid) -> Result<(), Error> {
 | 
				
			|||||||
        bail!("not an API token ID");
 | 
					        bail!("not an API token ID");
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let _guard = open_backup_lockfile(LOCK_FILE, None, true)?;
 | 
					    let _guard = lock_config()?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    let mut data = read_file()?;
 | 
					    let mut data = read_file()?;
 | 
				
			||||||
    data.remove(tokenid);
 | 
					    data.remove(tokenid);
 | 
				
			||||||
							
								
								
									
										68
									
								
								pbs-tools/src/crypt.rs
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										68
									
								
								pbs-tools/src/crypt.rs
									
									
									
									
									
										Normal file
									
								
							@ -0,0 +1,68 @@
 | 
				
			|||||||
 | 
					use std::ffi::CStr;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					use anyhow::{bail, Error};
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					// from libcrypt1, 'lib/crypt.h.in'
 | 
				
			||||||
 | 
					const CRYPT_OUTPUT_SIZE: usize = 384;
 | 
				
			||||||
 | 
					const CRYPT_MAX_PASSPHRASE_SIZE: usize = 512;
 | 
				
			||||||
 | 
					const CRYPT_DATA_RESERVED_SIZE: usize = 767;
 | 
				
			||||||
 | 
					const CRYPT_DATA_INTERNAL_SIZE: usize = 30720;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					#[repr(C)]
 | 
				
			||||||
 | 
					struct crypt_data {
 | 
				
			||||||
 | 
					    output: [libc::c_char; CRYPT_OUTPUT_SIZE],
 | 
				
			||||||
 | 
					    setting: [libc::c_char; CRYPT_OUTPUT_SIZE],
 | 
				
			||||||
 | 
					    input: [libc::c_char; CRYPT_MAX_PASSPHRASE_SIZE],
 | 
				
			||||||
 | 
					    reserved: [libc::c_char; CRYPT_DATA_RESERVED_SIZE],
 | 
				
			||||||
 | 
					    initialized: libc::c_char,
 | 
				
			||||||
 | 
					    internal: [libc::c_char; CRYPT_DATA_INTERNAL_SIZE],
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn crypt(password: &[u8], salt: &[u8]) -> Result<String, Error> {
 | 
				
			||||||
 | 
					    #[link(name = "crypt")]
 | 
				
			||||||
 | 
					    extern "C" {
 | 
				
			||||||
 | 
					        #[link_name = "crypt_r"]
 | 
				
			||||||
 | 
					        fn __crypt_r(
 | 
				
			||||||
 | 
					            key: *const libc::c_char,
 | 
				
			||||||
 | 
					            salt: *const libc::c_char,
 | 
				
			||||||
 | 
					            data: *mut crypt_data,
 | 
				
			||||||
 | 
					        ) -> *mut libc::c_char;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let mut data: crypt_data = unsafe { std::mem::zeroed() };
 | 
				
			||||||
 | 
					    for (i, c) in salt.iter().take(data.setting.len() - 1).enumerate() {
 | 
				
			||||||
 | 
					        data.setting[i] = *c as libc::c_char;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    for (i, c) in password.iter().take(data.input.len() - 1).enumerate() {
 | 
				
			||||||
 | 
					        data.input[i] = *c as libc::c_char;
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let res = unsafe {
 | 
				
			||||||
 | 
					        let status = __crypt_r(
 | 
				
			||||||
 | 
					            &data.input as *const _,
 | 
				
			||||||
 | 
					            &data.setting as *const _,
 | 
				
			||||||
 | 
					            &mut data as *mut _,
 | 
				
			||||||
 | 
					        );
 | 
				
			||||||
 | 
					        if status.is_null() {
 | 
				
			||||||
 | 
					            bail!("internal error: crypt_r returned null pointer");
 | 
				
			||||||
 | 
					        }
 | 
				
			||||||
 | 
					        CStr::from_ptr(&data.output as *const _)
 | 
				
			||||||
 | 
					    };
 | 
				
			||||||
 | 
					    Ok(String::from(res.to_str()?))
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn encrypt_pw(password: &str) -> Result<String, Error> {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    let salt = proxmox::sys::linux::random_data(8)?;
 | 
				
			||||||
 | 
					    let salt = format!("$5${}$", base64::encode_config(&salt, base64::CRYPT));
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    crypt(password.as_bytes(), salt.as_bytes())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					pub fn verify_crypt_pw(password: &str, enc_password: &str) -> Result<(), Error> {
 | 
				
			||||||
 | 
					    let verify = crypt(password.as_bytes(), enc_password.as_bytes())?;
 | 
				
			||||||
 | 
					    if verify != enc_password {
 | 
				
			||||||
 | 
					        bail!("invalid credentials");
 | 
				
			||||||
 | 
					    }
 | 
				
			||||||
 | 
					    Ok(())
 | 
				
			||||||
 | 
					}
 | 
				
			||||||
@ -6,6 +6,7 @@ pub mod broadcast_future;
 | 
				
			|||||||
pub mod cert;
 | 
					pub mod cert;
 | 
				
			||||||
pub mod cli;
 | 
					pub mod cli;
 | 
				
			||||||
pub mod compression;
 | 
					pub mod compression;
 | 
				
			||||||
 | 
					pub mod crypt;
 | 
				
			||||||
pub mod crypt_config;
 | 
					pub mod crypt_config;
 | 
				
			||||||
pub mod format;
 | 
					pub mod format;
 | 
				
			||||||
pub mod fd;
 | 
					pub mod fd;
 | 
				
			||||||
 | 
				
			|||||||
@ -13,9 +13,9 @@ use pbs_api_types::{
 | 
				
			|||||||
    PASSWORD_FORMAT, PROXMOX_CONFIG_DIGEST_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA, Authid,
 | 
					    PASSWORD_FORMAT, PROXMOX_CONFIG_DIGEST_SCHEMA, SINGLE_LINE_COMMENT_SCHEMA, Authid,
 | 
				
			||||||
    Tokenname, UserWithTokens, Userid,
 | 
					    Tokenname, UserWithTokens, Userid,
 | 
				
			||||||
};
 | 
					};
 | 
				
			||||||
 | 
					use pbs_config::token_shadow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::config::user;
 | 
					use crate::config::user;
 | 
				
			||||||
use crate::config::token_shadow;
 | 
					 | 
				
			||||||
use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_PERMISSIONS_MODIFY};
 | 
					use crate::config::acl::{PRIV_SYS_AUDIT, PRIV_PERMISSIONS_MODIFY};
 | 
				
			||||||
use crate::config::cached_user_info::CachedUserInfo;
 | 
					use crate::config::cached_user_info::CachedUserInfo;
 | 
				
			||||||
use pbs_config::open_backup_lockfile;
 | 
					use pbs_config::open_backup_lockfile;
 | 
				
			||||||
 | 
				
			|||||||
							
								
								
									
										75
									
								
								src/auth.rs
									
									
									
									
									
								
							
							
						
						
									
										75
									
								
								src/auth.rs
									
									
									
									
									
								
							@ -4,7 +4,6 @@
 | 
				
			|||||||
 | 
					
 | 
				
			||||||
use std::process::{Command, Stdio};
 | 
					use std::process::{Command, Stdio};
 | 
				
			||||||
use std::io::Write;
 | 
					use std::io::Write;
 | 
				
			||||||
use std::ffi::CStr;
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
use anyhow::{bail, format_err, Error};
 | 
					use anyhow::{bail, format_err, Error};
 | 
				
			||||||
use serde_json::json;
 | 
					use serde_json::json;
 | 
				
			||||||
@ -19,7 +18,7 @@ pub trait ProxmoxAuthenticator {
 | 
				
			|||||||
    fn remove_password(&self, username: &UsernameRef) -> Result<(), Error>;
 | 
					    fn remove_password(&self, username: &UsernameRef) -> Result<(), Error>;
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct PAM();
 | 
					struct PAM();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
impl ProxmoxAuthenticator for PAM {
 | 
					impl ProxmoxAuthenticator for PAM {
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -70,73 +69,7 @@ impl ProxmoxAuthenticator for PAM {
 | 
				
			|||||||
    }
 | 
					    }
 | 
				
			||||||
}
 | 
					}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
pub struct PBS();
 | 
					struct PBS();
 | 
				
			||||||
 | 
					 | 
				
			||||||
// from libcrypt1, 'lib/crypt.h.in'
 | 
					 | 
				
			||||||
const CRYPT_OUTPUT_SIZE: usize = 384;
 | 
					 | 
				
			||||||
const CRYPT_MAX_PASSPHRASE_SIZE: usize = 512;
 | 
					 | 
				
			||||||
const CRYPT_DATA_RESERVED_SIZE: usize = 767;
 | 
					 | 
				
			||||||
const CRYPT_DATA_INTERNAL_SIZE: usize = 30720;
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
#[repr(C)]
 | 
					 | 
				
			||||||
struct crypt_data {
 | 
					 | 
				
			||||||
    output: [libc::c_char; CRYPT_OUTPUT_SIZE],
 | 
					 | 
				
			||||||
    setting: [libc::c_char; CRYPT_OUTPUT_SIZE],
 | 
					 | 
				
			||||||
    input: [libc::c_char; CRYPT_MAX_PASSPHRASE_SIZE],
 | 
					 | 
				
			||||||
    reserved: [libc::c_char; CRYPT_DATA_RESERVED_SIZE],
 | 
					 | 
				
			||||||
    initialized: libc::c_char,
 | 
					 | 
				
			||||||
    internal: [libc::c_char; CRYPT_DATA_INTERNAL_SIZE],
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn crypt(password: &[u8], salt: &[u8]) -> Result<String, Error> {
 | 
					 | 
				
			||||||
    #[link(name = "crypt")]
 | 
					 | 
				
			||||||
    extern "C" {
 | 
					 | 
				
			||||||
        #[link_name = "crypt_r"]
 | 
					 | 
				
			||||||
        fn __crypt_r(
 | 
					 | 
				
			||||||
            key: *const libc::c_char,
 | 
					 | 
				
			||||||
            salt: *const libc::c_char,
 | 
					 | 
				
			||||||
            data: *mut crypt_data,
 | 
					 | 
				
			||||||
        ) -> *mut libc::c_char;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let mut data: crypt_data = unsafe { std::mem::zeroed() };
 | 
					 | 
				
			||||||
    for (i, c) in salt.iter().take(data.setting.len() - 1).enumerate() {
 | 
					 | 
				
			||||||
        data.setting[i] = *c as libc::c_char;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    for (i, c) in password.iter().take(data.input.len() - 1).enumerate() {
 | 
					 | 
				
			||||||
        data.input[i] = *c as libc::c_char;
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let res = unsafe {
 | 
					 | 
				
			||||||
        let status = __crypt_r(
 | 
					 | 
				
			||||||
            &data.input as *const _,
 | 
					 | 
				
			||||||
            &data.setting as *const _,
 | 
					 | 
				
			||||||
            &mut data as *mut _,
 | 
					 | 
				
			||||||
        );
 | 
					 | 
				
			||||||
        if status.is_null() {
 | 
					 | 
				
			||||||
            bail!("internal error: crypt_r returned null pointer");
 | 
					 | 
				
			||||||
        }
 | 
					 | 
				
			||||||
        CStr::from_ptr(&data.output as *const _)
 | 
					 | 
				
			||||||
    };
 | 
					 | 
				
			||||||
    Ok(String::from(res.to_str()?))
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn encrypt_pw(password: &str) -> Result<String, Error> {
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    let salt = proxmox::sys::linux::random_data(8)?;
 | 
					 | 
				
			||||||
    let salt = format!("$5${}$", base64::encode_config(&salt, base64::CRYPT));
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
    crypt(password.as_bytes(), salt.as_bytes())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					 | 
				
			||||||
pub fn verify_crypt_pw(password: &str, enc_password: &str) -> Result<(), Error> {
 | 
					 | 
				
			||||||
    let verify = crypt(password.as_bytes(), enc_password.as_bytes())?;
 | 
					 | 
				
			||||||
    if verify != enc_password {
 | 
					 | 
				
			||||||
        bail!("invalid credentials");
 | 
					 | 
				
			||||||
    }
 | 
					 | 
				
			||||||
    Ok(())
 | 
					 | 
				
			||||||
}
 | 
					 | 
				
			||||||
 | 
					
 | 
				
			||||||
const SHADOW_CONFIG_FILENAME: &str = configdir!("/shadow.json");
 | 
					const SHADOW_CONFIG_FILENAME: &str = configdir!("/shadow.json");
 | 
				
			||||||
 | 
					
 | 
				
			||||||
@ -146,13 +79,13 @@ impl ProxmoxAuthenticator for PBS {
 | 
				
			|||||||
        let data = proxmox::tools::fs::file_get_json(SHADOW_CONFIG_FILENAME, Some(json!({})))?;
 | 
					        let data = proxmox::tools::fs::file_get_json(SHADOW_CONFIG_FILENAME, Some(json!({})))?;
 | 
				
			||||||
        match data[username.as_str()].as_str() {
 | 
					        match data[username.as_str()].as_str() {
 | 
				
			||||||
            None => bail!("no password set"),
 | 
					            None => bail!("no password set"),
 | 
				
			||||||
            Some(enc_password) => verify_crypt_pw(password, enc_password)?,
 | 
					            Some(enc_password) => pbs_tools::crypt::verify_crypt_pw(password, enc_password)?,
 | 
				
			||||||
        }
 | 
					        }
 | 
				
			||||||
        Ok(())
 | 
					        Ok(())
 | 
				
			||||||
    }
 | 
					    }
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    fn store_password(&self, username: &UsernameRef, password: &str) -> Result<(), Error> {
 | 
					    fn store_password(&self, username: &UsernameRef, password: &str) -> Result<(), Error> {
 | 
				
			||||||
        let enc_password = encrypt_pw(password)?;
 | 
					        let enc_password = pbs_tools::crypt::encrypt_pw(password)?;
 | 
				
			||||||
        let mut data = proxmox::tools::fs::file_get_json(SHADOW_CONFIG_FILENAME, Some(json!({})))?;
 | 
					        let mut data = proxmox::tools::fs::file_get_json(SHADOW_CONFIG_FILENAME, Some(json!({})))?;
 | 
				
			||||||
        data[username.as_str()] = enc_password.into();
 | 
					        data[username.as_str()] = enc_password.into();
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
				
			|||||||
@ -20,7 +20,6 @@ pub mod cached_user_info;
 | 
				
			|||||||
pub mod datastore;
 | 
					pub mod datastore;
 | 
				
			||||||
pub mod node;
 | 
					pub mod node;
 | 
				
			||||||
pub mod tfa;
 | 
					pub mod tfa;
 | 
				
			||||||
pub mod token_shadow;
 | 
					 | 
				
			||||||
pub mod user;
 | 
					pub mod user;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
/// Check configuration directory permissions
 | 
					/// Check configuration directory permissions
 | 
				
			||||||
 | 
				
			|||||||
@ -4,6 +4,7 @@ use anyhow::{format_err, Error};
 | 
				
			|||||||
use std::sync::Arc;
 | 
					use std::sync::Arc;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use pbs_tools::ticket::{self, Ticket};
 | 
					use pbs_tools::ticket::{self, Ticket};
 | 
				
			||||||
 | 
					use pbs_config::token_shadow;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
use crate::api2::types::{Authid, Userid};
 | 
					use crate::api2::types::{Authid, Userid};
 | 
				
			||||||
use crate::auth_helpers::*;
 | 
					use crate::auth_helpers::*;
 | 
				
			||||||
@ -131,7 +132,7 @@ impl ApiAuth for UserApiAuth {
 | 
				
			|||||||
                    .decode_utf8()
 | 
					                    .decode_utf8()
 | 
				
			||||||
                    .map_err(|_| format_err!("failed to decode API token header"))?;
 | 
					                    .map_err(|_| format_err!("failed to decode API token header"))?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                crate::config::token_shadow::verify_secret(&tokenid, &tokensecret)?;
 | 
					                token_shadow::verify_secret(&tokenid, &tokensecret)?;
 | 
				
			||||||
 | 
					
 | 
				
			||||||
                Ok(tokenid)
 | 
					                Ok(tokenid)
 | 
				
			||||||
            }
 | 
					            }
 | 
				
			||||||
 | 
				
			|||||||
		Reference in New Issue
	
	Block a user