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