From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: from firstgate.proxmox.com (firstgate.proxmox.com [IPv6:2a01:7e0:0:424::9]) by lore.proxmox.com (Postfix) with ESMTPS id 8B41C1FF170 for ; Thu, 10 Jul 2025 15:50:01 +0200 (CEST) Received: from firstgate.proxmox.com (localhost [127.0.0.1]) by firstgate.proxmox.com (Proxmox) with ESMTP id 8F0D835187; Thu, 10 Jul 2025 15:50:47 +0200 (CEST) From: Shannon Sterz To: pbs-devel@lists.proxmox.com Date: Thu, 10 Jul 2025 15:50:08 +0200 Message-Id: <20250710135010.305861-3-s.sterz@proxmox.com> X-Mailer: git-send-email 2.39.5 In-Reply-To: <20250710135010.305861-1-s.sterz@proxmox.com> References: <20250710135010.305861-1-s.sterz@proxmox.com> MIME-Version: 1.0 X-SPAM-LEVEL: Spam detection results: 0 AWL 0.020 Adjusted score from AWL reputation of From: address BAYES_00 -1.9 Bayes spam probability is 0 to 1% DMARC_MISSING 0.1 Missing DMARC policy KAM_DMARC_STATUS 0.01 Test Rule for DKIM or SPF Failure with Strict Alignment RCVD_IN_VALIDITY_CERTIFIED_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_RPBL_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. RCVD_IN_VALIDITY_SAFE_BLOCKED 0.001 ADMINISTRATOR NOTICE: The query to Validity was blocked. See https://knowledge.validity.com/hc/en-us/articles/20961730681243 for more information. SPF_HELO_NONE 0.001 SPF: HELO does not publish an SPF Record SPF_PASS -0.001 SPF: sender matches SPF record Subject: [pbs-devel] [PATCH proxmox-backup 1/3] api: access: add opt-in http only ticket authentication flow X-BeenThere: pbs-devel@lists.proxmox.com X-Mailman-Version: 2.1.29 Precedence: list List-Id: Proxmox Backup Server development discussion List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Reply-To: Proxmox Backup Server development discussion Content-Type: text/plain; charset="us-ascii" Content-Transfer-Encoding: 7bit Errors-To: pbs-devel-bounces@lists.proxmox.com Sender: "pbs-devel" this new flow returns https only cookies providing an additional layer of security for clients operating in a browser environment. opt-in only to not break existing clients. Signed-off-by: Shannon Sterz --- src/api2/access/mod.rs | 77 +++++++++++++++++++++++++++++++++++++++--- 1 file changed, 73 insertions(+), 4 deletions(-) diff --git a/src/api2/access/mod.rs b/src/api2/access/mod.rs index 832cdc66..b61b596e 100644 --- a/src/api2/access/mod.rs +++ b/src/api2/access/mod.rs @@ -2,14 +2,23 @@ use anyhow::{bail, format_err, Error}; -use serde_json::Value; +use hyper::header::CONTENT_TYPE; +use hyper::http::request::Parts; +use hyper::Response; +use serde_json::{json, Value}; + use std::collections::HashMap; use std::collections::HashSet; +use proxmox_auth_api::api::API_METHOD_CREATE_TICKET_HTTP_ONLY; +use proxmox_auth_api::types::{CreateTicket, CreateTicketResponse}; use proxmox_router::{ - http_bail, http_err, list_subdirs_api_method, Permission, Router, RpcEnvironment, SubdirMap, + http_bail, http_err, list_subdirs_api_method, ApiHandler, ApiMethod, ApiResponseFuture, + Permission, Router, RpcEnvironment, SubdirMap, +}; +use proxmox_schema::{ + api, AllOfSchema, ApiType, BooleanSchema, ObjectSchema, ParameterSchema, ReturnType, }; -use proxmox_schema::api; use proxmox_sortable_macro::sortable; use pbs_api_types::{ @@ -268,7 +277,9 @@ const SUBDIRS: SubdirMap = &sorted!([ ), ( "ticket", - &Router::new().post(&proxmox_auth_api::api::API_METHOD_CREATE_TICKET) + &Router::new() + .post(&API_METHOD_CREATE_TICKET_TOGGLE) + .delete(&proxmox_auth_api::api::API_METHOD_LOGOUT) ), ("openid", &openid::ROUTER), ("domains", &domain::ROUTER), @@ -277,6 +288,64 @@ const SUBDIRS: SubdirMap = &sorted!([ ("tfa", &tfa::ROUTER), ]); +const API_METHOD_CREATE_TICKET_TOGGLE: ApiMethod = ApiMethod::new_full( + &proxmox_router::ApiHandler::AsyncHttpBodyParameters(&handle_ticket_toggle), + ParameterSchema::AllOf(&AllOfSchema::new( + "Either create a new HttpOnly ticket or a regular ticket.", + &[ + &ObjectSchema::new( + "", + &[( + "http-only", + true, + &BooleanSchema::new( + "Whether the http only authentication flow should be used.", + ) + .default(false) + .schema(), + )], + ) + .schema(), + &CreateTicket::API_SCHEMA, + ], + )), +) +.returns(ReturnType::new(false, &CreateTicketResponse::API_SCHEMA)) +.protected(true) +.access(None, &Permission::World); + +fn handle_ticket_toggle( + parts: Parts, + mut param: Value, + info: &'static ApiMethod, + mut rpcenv: Box, +) -> ApiResponseFuture { + // If the client specifies that they want to use http only cookies, prefer those. + if Some(true) == param["http-only"].take().as_bool() { + if let ApiHandler::AsyncHttpBodyParameters(handler) = + API_METHOD_CREATE_TICKET_HTTP_ONLY.handler + { + return handler(parts, param, info, rpcenv); + } + } + + // Otherwise, default back to the previous ticket method. + Box::pin(async move { + let create_params: CreateTicket = serde_json::from_value(param)?; + + let ticket_response = + proxmox_auth_api::api::create_ticket(create_params, rpcenv.as_mut()).await?; + + let response = Response::builder().header(CONTENT_TYPE, "application/json"); + + Ok(response.body( + json!({"data": ticket_response, "status": 200, "success": true }) + .to_string() + .into(), + )?) + }) +} + pub const ROUTER: Router = Router::new() .get(&list_subdirs_api_method!(SUBDIRS)) .subdirs(SUBDIRS); -- 2.39.5 _______________________________________________ pbs-devel mailing list pbs-devel@lists.proxmox.com https://lists.proxmox.com/cgi-bin/mailman/listinfo/pbs-devel