api tokens: add authorization method

and properly decode secret (which is a no-op with the current scheme).

Signed-off-by: Fabian Grünbichler <f.gruenbichler@proxmox.com>
This commit is contained in:
Fabian Grünbichler 2020-10-30 13:10:38 +01:00 committed by Thomas Lamprecht
parent 2762481cc8
commit 362739054e
2 changed files with 10 additions and 3 deletions

View File

@ -493,7 +493,7 @@ impl HttpClient {
let auth = self.login().await?; let auth = self.login().await?;
if auth.auth_id.is_token() { if auth.auth_id.is_token() {
let enc_api_token = format!("{}:{}", auth.auth_id, percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET)); let enc_api_token = format!("PBSAPIToken {}:{}", auth.auth_id, percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET));
req.headers_mut().insert("Authorization", HeaderValue::from_str(&enc_api_token).unwrap()); req.headers_mut().insert("Authorization", HeaderValue::from_str(&enc_api_token).unwrap());
} else { } else {
let enc_ticket = format!("PBSAuthCookie={}", percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET)); let enc_ticket = format!("PBSAuthCookie={}", percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET));
@ -602,7 +602,7 @@ impl HttpClient {
let auth = self.login().await?; let auth = self.login().await?;
if auth.auth_id.is_token() { if auth.auth_id.is_token() {
let enc_api_token = format!("{}:{}", auth.auth_id, percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET)); let enc_api_token = format!("PBSAPIToken {}:{}", auth.auth_id, percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET));
req.headers_mut().insert("Authorization", HeaderValue::from_str(&enc_api_token).unwrap()); req.headers_mut().insert("Authorization", HeaderValue::from_str(&enc_api_token).unwrap());
} else { } else {
let enc_ticket = format!("PBSAuthCookie={}", percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET)); let enc_ticket = format!("PBSAuthCookie={}", percent_encode(auth.ticket.as_bytes(), DEFAULT_ENCODE_SET));

View File

@ -17,6 +17,7 @@ use lazy_static::lazy_static;
use serde_json::{json, Value}; use serde_json::{json, Value};
use tokio::fs::File; use tokio::fs::File;
use tokio::time::Instant; use tokio::time::Instant;
use percent_encoding::percent_decode_str;
use url::form_urlencoded; use url::form_urlencoded;
use regex::Regex; use regex::Regex;
@ -568,7 +569,9 @@ fn extract_auth_data(headers: &http::HeaderMap) -> Option<AuthData> {
} }
match headers.get("AUTHORIZATION").map(|v| v.to_str()) { match headers.get("AUTHORIZATION").map(|v| v.to_str()) {
Some(Ok(v)) => Some(AuthData::ApiToken(v.to_owned())), Some(Ok(v)) if v.starts_with("PBSAPIToken ") => {
Some(AuthData::ApiToken(v["PBSAPIToken ".len()..].to_owned()))
},
_ => None, _ => None,
} }
} }
@ -609,6 +612,10 @@ fn check_auth(
let tokensecret = parts.next() let tokensecret = parts.next()
.ok_or_else(|| format_err!("failed to split API token header"))?; .ok_or_else(|| format_err!("failed to split API token header"))?;
let tokensecret = percent_decode_str(tokensecret)
.decode_utf8()
.map_err(|_| format_err!("failed to decode API token header"))?;
crate::config::token_shadow::verify_secret(&tokenid, &tokensecret)?; crate::config::token_shadow::verify_secret(&tokenid, &tokensecret)?;
Ok(tokenid) Ok(tokenid)