server/rest.rs: verify auth cookie
This commit is contained in:
parent
f484eed3c2
commit
b9903d6331
|
@ -29,7 +29,7 @@ fn create_ticket(
|
||||||
match authenticate_user(username, password) {
|
match authenticate_user(username, password) {
|
||||||
Ok(_) => {
|
Ok(_) => {
|
||||||
|
|
||||||
let ticket = assemble_rsa_ticket( private_auth_key(), "PBS", None, None)?;
|
let ticket = assemble_rsa_ticket( private_auth_key(), "PBS", Some(username), None)?;
|
||||||
|
|
||||||
let token = assemble_csrf_prevention_token(csrf_secret(), username);
|
let token = assemble_csrf_prevention_token(csrf_secret(), username);
|
||||||
|
|
||||||
|
|
|
@ -2,6 +2,7 @@ use crate::tools;
|
||||||
use crate::api::schema::*;
|
use crate::api::schema::*;
|
||||||
use crate::api::router::*;
|
use crate::api::router::*;
|
||||||
use crate::api::config::*;
|
use crate::api::config::*;
|
||||||
|
use crate::auth_helpers::*;
|
||||||
use super::environment::RestEnvironment;
|
use super::environment::RestEnvironment;
|
||||||
use super::formatter::*;
|
use super::formatter::*;
|
||||||
|
|
||||||
|
@ -421,6 +422,20 @@ pub fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> BoxFut {
|
||||||
let env_type = api.env_type();
|
let env_type = api.env_type();
|
||||||
let mut rpcenv = RestEnvironment::new(env_type);
|
let mut rpcenv = RestEnvironment::new(env_type);
|
||||||
|
|
||||||
|
let delay_unauth_time = std::time::Instant::now() + std::time::Duration::from_millis(3000);
|
||||||
|
|
||||||
|
if let Some(raw_cookie) = parts.headers.get("COOKIE") {
|
||||||
|
if let Ok(cookie) = raw_cookie.to_str() {
|
||||||
|
if let Some(ticket) = tools::extract_auth_cookie(cookie, "PBSAuthCookie") {
|
||||||
|
if let Ok((_, Some(username))) = tools::ticket::verify_rsa_ticket(
|
||||||
|
public_auth_key(), "PBS", &ticket, None, -300, 3600*2) {
|
||||||
|
rpcenv.set_user(Some(username));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
if comp_len >= 1 && components[0] == "api2" {
|
if comp_len >= 1 && components[0] == "api2" {
|
||||||
println!("GOT API REQUEST");
|
println!("GOT API REQUEST");
|
||||||
if comp_len >= 2 {
|
if comp_len >= 2 {
|
||||||
|
@ -435,8 +450,21 @@ pub fn handle_request(api: Arc<ApiConfig>, req: Request<Body>) -> BoxFut {
|
||||||
|
|
||||||
let mut uri_param = HashMap::new();
|
let mut uri_param = HashMap::new();
|
||||||
|
|
||||||
// fixme: handle auth
|
if comp_len == 4 && components[2] == "access" && components[3] == "ticket" {
|
||||||
rpcenv.set_user(Some(String::from("root@pam")));
|
// explicitly allow those calls without auth
|
||||||
|
} else {
|
||||||
|
if let Some(_username) = rpcenv.get_user() {
|
||||||
|
// fixme: check permissions
|
||||||
|
} else {
|
||||||
|
// always delay unauthorized calls by 3 seconds (from start of request)
|
||||||
|
let resp = (formatter.format_error)(http_err!(UNAUTHORIZED, "permission check failed.".into()));
|
||||||
|
let delayed_response = tokio::timer::Delay::new(delay_unauth_time)
|
||||||
|
.map_err(|err| http_err!(INTERNAL_SERVER_ERROR, format!("tokio timer delay error: {}", err)))
|
||||||
|
.and_then(|_| Ok(resp));
|
||||||
|
|
||||||
|
return Box::new(delayed_response);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
match api.find_method(&components[2..], method, &mut uri_param) {
|
match api.find_method(&components[2..], method, &mut uri_param) {
|
||||||
MethodDefinition::None => {}
|
MethodDefinition::None => {}
|
||||||
|
|
24
src/tools.rs
24
src/tools.rs
|
@ -416,3 +416,27 @@ pub fn assert_if_modified(digest1: &str, digest2: &str) -> Result<(), Error> {
|
||||||
}
|
}
|
||||||
Ok(())
|
Ok(())
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// Extract authentication cookie from cookie header.
|
||||||
|
/// We assume cookie_name is already url encoded.
|
||||||
|
pub fn extract_auth_cookie(cookie: &str, cookie_name: &str) -> Option<String> {
|
||||||
|
|
||||||
|
for pair in cookie.split(';') {
|
||||||
|
|
||||||
|
let (name, value) = match pair.find('=') {
|
||||||
|
Some(i) => (pair[..i].trim(), pair[(i + 1)..].trim()),
|
||||||
|
None => return None, // Cookie format error
|
||||||
|
};
|
||||||
|
|
||||||
|
if name == cookie_name {
|
||||||
|
use url::percent_encoding::percent_decode;
|
||||||
|
if let Ok(value) = percent_decode(value.as_bytes()).decode_utf8() {
|
||||||
|
return Some(value.into());
|
||||||
|
} else {
|
||||||
|
return None; // Cookie format error
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
None
|
||||||
|
}
|
||||||
|
|
Loading…
Reference in New Issue