replace Userid with Authid

in most generic places. this is accompanied by a change in
RpcEnvironment to purposefully break existing call sites.

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler
2020-10-23 13:33:21 +02:00
committed by Wolfgang Bumiller
parent e10c5c74f6
commit e6dc35acb8
43 changed files with 400 additions and 303 deletions

View File

@ -6,7 +6,7 @@ use proxmox::api::{RpcEnvironment, RpcEnvironmentType};
pub struct RestEnvironment {
env_type: RpcEnvironmentType,
result_attributes: Value,
user: Option<String>,
auth_id: Option<String>,
client_ip: Option<std::net::SocketAddr>,
}
@ -14,7 +14,7 @@ impl RestEnvironment {
pub fn new(env_type: RpcEnvironmentType) -> Self {
Self {
result_attributes: json!({}),
user: None,
auth_id: None,
client_ip: None,
env_type,
}
@ -35,12 +35,12 @@ impl RpcEnvironment for RestEnvironment {
self.env_type
}
fn set_user(&mut self, user: Option<String>) {
self.user = user;
fn set_auth_id(&mut self, auth_id: Option<String>) {
self.auth_id = auth_id;
}
fn get_user(&self) -> Option<String> {
self.user.clone()
fn get_auth_id(&self) -> Option<String> {
self.auth_id.clone()
}
fn set_client_ip(&mut self, client_ip: Option<std::net::SocketAddr>) {

View File

@ -42,7 +42,7 @@ use super::formatter::*;
use super::ApiConfig;
use crate::auth_helpers::*;
use crate::api2::types::Userid;
use crate::api2::types::{Authid, Userid};
use crate::tools;
use crate::tools::FileLogger;
use crate::tools::ticket::Ticket;
@ -138,9 +138,9 @@ fn log_response(
log::error!("{} {}: {} {}: [client {}] {}", method.as_str(), path, status.as_str(), reason, peer, message);
}
if let Some(logfile) = logfile {
let user = match resp.extensions().get::<Userid>() {
Some(userid) => userid.as_str(),
None => "-",
let auth_id = match resp.extensions().get::<Authid>() {
Some(auth_id) => auth_id.to_string(),
None => "-".to_string(),
};
let now = proxmox::tools::time::epoch_i64();
// time format which apache/nginx use (by default), copied from pve-http-server
@ -153,7 +153,7 @@ fn log_response(
.log(format!(
"{} - {} [{}] \"{} {}\" {} {} {}",
peer.ip(),
user,
auth_id,
datetime,
method.as_str(),
path,
@ -441,7 +441,7 @@ fn get_index(
.unwrap();
if let Some(userid) = userid {
resp.extensions_mut().insert(userid);
resp.extensions_mut().insert(Authid::from((userid, None)));
}
resp
@ -555,14 +555,15 @@ fn check_auth(
ticket: &Option<String>,
csrf_token: &Option<String>,
user_info: &CachedUserInfo,
) -> Result<Userid, Error> {
) -> Result<Authid, Error> {
let ticket_lifetime = tools::ticket::TICKET_LIFETIME;
let ticket = ticket.as_ref().map(String::as_str);
let userid: Userid = Ticket::parse(&ticket.ok_or_else(|| format_err!("missing ticket"))?)?
.verify_with_time_frame(public_auth_key(), "PBS", None, -300..ticket_lifetime)?;
if !user_info.is_active_user(&userid) {
let auth_id = Authid::from(userid.clone());
if !user_info.is_active_auth_id(&auth_id) {
bail!("user account disabled or expired.");
}
@ -574,7 +575,7 @@ fn check_auth(
}
}
Ok(userid)
Ok(Authid::from(userid))
}
async fn handle_request(
@ -632,7 +633,7 @@ async fn handle_request(
if auth_required {
let (ticket, csrf_token, _) = extract_auth_data(&parts.headers);
match check_auth(&method, &ticket, &csrf_token, &user_info) {
Ok(userid) => rpcenv.set_user(Some(userid.to_string())),
Ok(authid) => rpcenv.set_auth_id(Some(authid.to_string())),
Err(err) => {
// always delay unauthorized calls by 3 seconds (from start of request)
let err = http_err!(UNAUTHORIZED, "authentication failed - {}", err);
@ -648,8 +649,8 @@ async fn handle_request(
return Ok((formatter.format_error)(err));
}
Some(api_method) => {
let user = rpcenv.get_user();
if !check_api_permission(api_method.access.permission, user.as_deref(), &uri_param, user_info.as_ref()) {
let auth_id = rpcenv.get_auth_id();
if !check_api_permission(api_method.access.permission, auth_id.as_deref(), &uri_param, user_info.as_ref()) {
let err = http_err!(FORBIDDEN, "permission check failed");
tokio::time::delay_until(Instant::from_std(access_forbidden_time)).await;
return Ok((formatter.format_error)(err));
@ -666,9 +667,9 @@ async fn handle_request(
Err(err) => (formatter.format_error)(err),
};
if let Some(user) = user {
let userid: Userid = user.parse()?;
response.extensions_mut().insert(userid);
if let Some(auth_id) = auth_id {
let auth_id: Authid = auth_id.parse()?;
response.extensions_mut().insert(auth_id);
}
return Ok(response);
@ -687,9 +688,10 @@ async fn handle_request(
let (ticket, csrf_token, language) = extract_auth_data(&parts.headers);
if ticket != None {
match check_auth(&method, &ticket, &csrf_token, &user_info) {
Ok(userid) => {
let new_csrf_token = assemble_csrf_prevention_token(csrf_secret(), &userid);
return Ok(get_index(Some(userid), Some(new_csrf_token), language, &api, parts));
Ok(auth_id) => {
let userid = auth_id.user();
let new_csrf_token = assemble_csrf_prevention_token(csrf_secret(), userid);
return Ok(get_index(Some(userid.clone()), Some(new_csrf_token), language, &api, parts));
}
_ => {
tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await;

View File

@ -6,7 +6,7 @@ use proxmox::api::schema::{ApiStringFormat, Schema, StringSchema};
use proxmox::const_regex;
use proxmox::sys::linux::procfs;
use crate::api2::types::Userid;
use crate::api2::types::Authid;
/// Unique Process/Task Identifier
///
@ -34,8 +34,8 @@ pub struct UPID {
pub worker_type: String,
/// Worker ID (arbitrary ASCII string)
pub worker_id: Option<String>,
/// The user who started the task
pub userid: Userid,
/// The authenticated entity who started the task
pub auth_id: Authid,
/// The node name.
pub node: String,
}
@ -47,7 +47,7 @@ const_regex! {
pub PROXMOX_UPID_REGEX = concat!(
r"^UPID:(?P<node>[a-zA-Z0-9]([a-zA-Z0-9\-]*[a-zA-Z0-9])?):(?P<pid>[0-9A-Fa-f]{8}):",
r"(?P<pstart>[0-9A-Fa-f]{8,9}):(?P<task_id>[0-9A-Fa-f]{8,16}):(?P<starttime>[0-9A-Fa-f]{8}):",
r"(?P<wtype>[^:\s]+):(?P<wid>[^:\s]*):(?P<userid>[^:\s]+):$"
r"(?P<wtype>[^:\s]+):(?P<wid>[^:\s]*):(?P<authid>[^:\s]+):$"
);
}
@ -65,7 +65,7 @@ impl UPID {
pub fn new(
worker_type: &str,
worker_id: Option<String>,
userid: Userid,
auth_id: Authid,
) -> Result<Self, Error> {
let pid = unsafe { libc::getpid() };
@ -87,7 +87,7 @@ impl UPID {
task_id,
worker_type: worker_type.to_owned(),
worker_id,
userid,
auth_id,
node: proxmox::tools::nodename().to_owned(),
})
}
@ -122,7 +122,7 @@ impl std::str::FromStr for UPID {
task_id: usize::from_str_radix(&cap["task_id"], 16).unwrap(),
worker_type: cap["wtype"].to_string(),
worker_id,
userid: cap["userid"].parse()?,
auth_id: cap["authid"].parse()?,
node: cap["node"].to_string(),
})
} else {
@ -146,6 +146,6 @@ impl std::fmt::Display for UPID {
// more that 8 characters for pstart
write!(f, "UPID:{}:{:08X}:{:08X}:{:08X}:{:08X}:{}:{}:{}:",
self.node, self.pid, self.pstart, self.task_id, self.starttime, self.worker_type, wid, self.userid)
self.node, self.pid, self.pstart, self.task_id, self.starttime, self.worker_type, wid, self.auth_id)
}
}

View File

@ -17,7 +17,7 @@ use crate::{
pub fn do_verification_job(
mut job: Job,
verification_job: VerificationJobConfig,
userid: &Userid,
auth_id: &Authid,
schedule: Option<String>,
) -> Result<String, Error> {
@ -48,14 +48,14 @@ pub fn do_verification_job(
}
};
let email = crate::server::lookup_user_email(userid);
let email = crate::server::lookup_user_email(auth_id.user());
let job_id = job.jobname().to_string();
let worker_type = job.jobtype().to_string();
let upid_str = WorkerTask::new_thread(
&worker_type,
Some(job.jobname().to_string()),
userid.clone(),
auth_id.clone(),
false,
move |worker| {
job.start(&worker.upid().to_string())?;

View File

@ -21,7 +21,7 @@ use super::UPID;
use crate::tools::logrotate::{LogRotate, LogRotateFiles};
use crate::tools::{FileLogger, FileLogOptions};
use crate::api2::types::Userid;
use crate::api2::types::Authid;
macro_rules! PROXMOX_BACKUP_VAR_RUN_DIR_M { () => ("/run/proxmox-backup") }
macro_rules! PROXMOX_BACKUP_LOG_DIR_M { () => ("/var/log/proxmox-backup") }
@ -611,10 +611,10 @@ impl Drop for WorkerTask {
impl WorkerTask {
pub fn new(worker_type: &str, worker_id: Option<String>, userid: Userid, to_stdout: bool) -> Result<Arc<Self>, Error> {
pub fn new(worker_type: &str, worker_id: Option<String>, auth_id: Authid, to_stdout: bool) -> Result<Arc<Self>, Error> {
println!("register worker");
let upid = UPID::new(worker_type, worker_id, userid)?;
let upid = UPID::new(worker_type, worker_id, auth_id)?;
let task_id = upid.task_id;
let mut path = std::path::PathBuf::from(PROXMOX_BACKUP_TASK_DIR);
@ -664,14 +664,14 @@ impl WorkerTask {
pub fn spawn<F, T>(
worker_type: &str,
worker_id: Option<String>,
userid: Userid,
auth_id: Authid,
to_stdout: bool,
f: F,
) -> Result<String, Error>
where F: Send + 'static + FnOnce(Arc<WorkerTask>) -> T,
T: Send + 'static + Future<Output = Result<(), Error>>,
{
let worker = WorkerTask::new(worker_type, worker_id, userid, to_stdout)?;
let worker = WorkerTask::new(worker_type, worker_id, auth_id, to_stdout)?;
let upid_str = worker.upid.to_string();
let f = f(worker.clone());
tokio::spawn(async move {
@ -686,7 +686,7 @@ impl WorkerTask {
pub fn new_thread<F>(
worker_type: &str,
worker_id: Option<String>,
userid: Userid,
auth_id: Authid,
to_stdout: bool,
f: F,
) -> Result<String, Error>
@ -694,7 +694,7 @@ impl WorkerTask {
{
println!("register worker thread");
let worker = WorkerTask::new(worker_type, worker_id, userid, to_stdout)?;
let worker = WorkerTask::new(worker_type, worker_id, auth_id, to_stdout)?;
let upid_str = worker.upid.to_string();
let _child = std::thread::Builder::new().name(upid_str.clone()).spawn(move || {