From a73a7c33b2ca233010ea388bad71c80b22337179 Mon Sep 17 00:00:00 2001 From: Dietmar Maurer Date: Thu, 16 Apr 2020 10:01:59 +0200 Subject: [PATCH] start impl. access permissions --- src/server/rest.rs | 36 +++++++++++++++++++++++++----------- 1 file changed, 25 insertions(+), 11 deletions(-) diff --git a/src/server/rest.rs b/src/server/rest.rs index 39bccfd7..45067b41 100644 --- a/src/server/rest.rs +++ b/src/server/rest.rs @@ -19,7 +19,7 @@ use url::form_urlencoded; use proxmox::http_err; use proxmox::api::{ApiHandler, ApiMethod, HttpError}; -use proxmox::api::{RpcEnvironment, RpcEnvironmentType}; +use proxmox::api::{RpcEnvironment, RpcEnvironmentType, check_api_permission}; use proxmox::api::schema::{ObjectSchema, parse_simple_value, verify_json_object, parse_parameter_strings}; use super::environment::RestEnvironment; @@ -28,6 +28,7 @@ use super::ApiConfig; use crate::auth_helpers::*; use crate::tools; +use crate::config::cached_user_info::CachedUserInfo; extern "C" { fn tzset(); } @@ -468,7 +469,12 @@ fn extract_auth_data(headers: &http::HeaderMap) -> (Option, Option, token: &Option) -> Result { +fn check_auth( + method: &hyper::Method, + ticket: &Option, + token: &Option, + user_info: &CachedUserInfo, +) -> Result { let ticket_lifetime = tools::ticket::TICKET_LIFETIME; @@ -481,6 +487,10 @@ fn check_auth(method: &hyper::Method, ticket: &Option, token: &Option bail!("missing ticket"), }; + if !user_info.is_active_user(&username) { + bail!("user account disabled or expired."); + } + if method != hyper::Method::GET { if let Some(token) = token { println!("CSRF prevention token: {:?}", token); @@ -508,6 +518,8 @@ pub async fn handle_request(api: Arc, req: Request) -> Result= 1 && components[0] == "api2" { @@ -531,16 +543,11 @@ pub async fn handle_request(api: Arc, req: Request) -> Result { - - // fixme: check permissions - - rpcenv.set_user(Some(username)); - } + match check_auth(&method, &ticket, &token, &user_info) { + Ok(username) => rpcenv.set_user(Some(username)), Err(err) => { // always delay unauthorized calls by 3 seconds (from start of request) - let err = http_err!(UNAUTHORIZED, format!("permission check failed - {}", err)); + let err = http_err!(UNAUTHORIZED, format!("authentication failed - {}", err)); tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await; return Ok((formatter.format_error)(err)); } @@ -553,6 +560,13 @@ pub async fn handle_request(api: Arc, req: Request) -> Result { + let user = rpcenv.get_user(); + if !check_api_permission(api_method.access.permission, user.as_deref(), &uri_param, &user_info) { + let err = http_err!(FORBIDDEN, format!("permission check failed")); + tokio::time::delay_until(Instant::from_std(delay_unauth_time)).await; + return Ok((formatter.format_error)(err)); + } + let result = if api_method.protected && env_type == RpcEnvironmentType::PUBLIC { proxy_protected_request(api_method, parts, body).await } else { @@ -577,7 +591,7 @@ pub async fn handle_request(api: Arc, req: Request) -> Result { let new_token = assemble_csrf_prevention_token(csrf_secret(), &username); return Ok(get_index(Some(username), Some(new_token)));