match authenticate_user(username, password) {
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);
use crate::api::schema::*;
use crate::api::router::*;
use crate::api::config::*;
+use crate::auth_helpers::*;
use super::environment::RestEnvironment;
use super::formatter::*;
let env_type = api.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" {
println!("GOT API REQUEST");
if comp_len >= 2 {
let mut uri_param = HashMap::new();
- // fixme: handle auth
- rpcenv.set_user(Some(String::from("root@pam")));
+ if comp_len == 4 && components[2] == "access" && components[3] == "ticket" {
+ // 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) {
MethodDefinition::None => {}
}
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
+}