]> git.proxmox.com Git - proxmox-backup.git/blame - src/api2/access.rs
tree-wide: use 'dyn' for all trait objects
[proxmox-backup.git] / src / api2 / access.rs
CommitLineData
34f956bc
DM
1use failure::*;
2
3use crate::tools;
ef2f2efb 4use crate::api_schema::*;
dc9a007b 5use crate::api_schema::router::*;
34f956bc
DM
6use crate::tools::ticket::*;
7use crate::auth_helpers::*;
8
a154a8e8
DM
9use hyper::StatusCode;
10
34f956bc
DM
11use serde_json::{json, Value};
12
13fn authenticate_user(username: &str, password: &str) -> Result<(), Error> {
14
f8f94534
DM
15 let ticket_lifetime = tools::ticket::TICKET_LIFETIME;
16
17 if password.starts_with("PBS:") {
18 if let Ok((_age, Some(ticket_username))) = tools::ticket::verify_rsa_ticket(public_auth_key(), "PBS", password, None, -300, ticket_lifetime) {
19 if ticket_username == username {
20 return Ok(());
21 } else {
22 bail!("ticket login failed - wrong username");
23 }
24 }
25 }
26
c82bc1a1 27 if username == "root@pam" {
1d77b6cf
WB
28 let mut auth = pam::Authenticator::with_password("proxmox-backup-auth").unwrap();
29 auth.get_handler().set_credentials("root", password);
c82bc1a1 30 auth.authenticate()?;
34f956bc
DM
31 return Ok(());
32 }
33
34 bail!("inavlid credentials");
35}
36
37fn create_ticket(
38 param: Value,
39 _info: &ApiMethod,
dd5495d6 40 _rpcenv: &mut dyn RpcEnvironment,
34f956bc
DM
41) -> Result<Value, Error> {
42
43 let username = tools::required_string_param(&param, "username")?;
44 let password = tools::required_string_param(&param, "password")?;
45
46 match authenticate_user(username, password) {
47 Ok(_) => {
48
b9903d63 49 let ticket = assemble_rsa_ticket( private_auth_key(), "PBS", Some(username), None)?;
34f956bc
DM
50
51 let token = assemble_csrf_prevention_token(csrf_secret(), username);
52
53 log::info!("successful auth for user '{}'", username);
54
55 return Ok(json!({
56 "username": username,
57 "ticket": ticket,
58 "CSRFPreventionToken": token,
59 }));
60 }
61 Err(err) => {
62 let client_ip = "unknown"; // $rpcenv->get_client_ip() || '';
63 log::error!("authentication failure; rhost={} user={} msg={}", client_ip, username, err.to_string());
a154a8e8 64 return Err(http_err!(UNAUTHORIZED, "permission check failed.".into()));
34f956bc
DM
65 }
66 }
67}
68
69pub fn router() -> Router {
70
71 let route = Router::new()
34f956bc
DM
72 .subdir(
73 "ticket",
74 Router::new()
75 .post(
76 ApiMethod::new(
77 create_ticket,
78 ObjectSchema::new("Create or verify authentication ticket.")
79 .required(
80 "username",
81 StringSchema::new("User name.")
82 .max_length(64)
83 )
84 .required(
85 "password",
86 StringSchema::new("The secret password. This can also be a valid ticket.")
87 )
88 ).returns(
89 ObjectSchema::new("Returns authentication ticket with additional infos.")
90 .required("username", StringSchema::new("User name."))
91 .required("ticket", StringSchema::new("Auth ticket."))
92 .required("CSRFPreventionToken", StringSchema::new("Cross Site Request Forgery Prevention Token."))
93 ).protected(true)
94 )
13f1cc17
DM
95 )
96 .list_subdirs();
34f956bc
DM
97
98 route
99}