]>
Commit | Line | Data |
---|---|---|
1360e6f0 DM |
1 | package PMG::Ticket; |
2 | ||
3 | use strict; | |
4 | use warnings; | |
5 | use Net::SSLeay; | |
6 | use Digest::SHA; | |
7 | ||
9d7f54a3 | 8 | use PVE::Tools; |
1360e6f0 DM |
9 | use PVE::Ticket; |
10 | ||
11 | use Crypt::OpenSSL::RSA; | |
12 | ||
13 | my $min_ticket_lifetime = -60*5; # allow 5 minutes time drift | |
14 | my $max_ticket_lifetime = 60*60*2; # 2 hours | |
15 | ||
9d7f54a3 DM |
16 | my $pmg_api_cert_fn = "/etc/proxmox/pmg-api.pem"; |
17 | ||
18 | ||
1360e6f0 DM |
19 | # fixme |
20 | my $rsa = Crypt::OpenSSL::RSA->generate_key(2048); | |
21 | ||
9d7f54a3 DM |
22 | sub generate_api_cert { |
23 | my ($nodename, $force) = @_; | |
24 | ||
25 | if (-f $pmg_api_cert_fn) { | |
26 | return $pmg_api_cert_fn if !$force; | |
27 | unlink $pmg_api_cert_fn; | |
28 | } | |
29 | ||
30 | my $cmd = ['openssl', 'req', '-batch', '-x509', '-newkey', 'rsa:4096', | |
31 | '-nodes', '-keyout', $pmg_api_cert_fn, '-out', $pmg_api_cert_fn, | |
32 | '-subj', "/CN=$nodename/", | |
33 | '-days', '3650']; | |
34 | ||
35 | PVE::Tools::run_command($cmd); | |
36 | ||
37 | return $pmg_api_cert_fn; | |
38 | } | |
39 | ||
1360e6f0 DM |
40 | ## fixme: |
41 | my $csrf_prevention_secret; | |
42 | my $get_csrfr_secret = sub { | |
43 | if (!$csrf_prevention_secret) { | |
44 | #my $input = PVE::Tools::file_get_contents($pve_www_key_fn); | |
45 | my $input = "ABCD"; # fixme | |
46 | $csrf_prevention_secret = Digest::SHA::sha1_base64($input); | |
47 | } | |
48 | return $csrf_prevention_secret; | |
49 | }; | |
50 | ||
51 | ||
52 | sub verify_csrf_prevention_token { | |
53 | my ($username, $token, $noerr) = @_; | |
54 | ||
55 | my $secret = &$get_csrfr_secret(); | |
56 | ||
57 | return PVE::Ticket::verify_csrf_prevention_token( | |
58 | $secret, $username, $token, $min_ticket_lifetime, | |
59 | $max_ticket_lifetime, $noerr); | |
60 | } | |
61 | ||
62 | sub assemble_csrf_prevention_token { | |
63 | my ($username) = @_; | |
64 | ||
65 | my $secret = &$get_csrfr_secret(); | |
66 | ||
67 | return PVE::Ticket::assemble_csrf_prevention_token ($secret, $username); | |
68 | } | |
69 | ||
70 | sub assemble_ticket { | |
71 | my ($username) = @_; | |
72 | ||
73 | return PVE::Ticket::assemble_rsa_ticket($rsa, 'PMG', $username); | |
74 | } | |
75 | ||
76 | sub verify_ticket { | |
77 | my ($ticket, $noerr) = @_; | |
78 | ||
79 | return PVE::Ticket::verify_rsa_ticket( | |
80 | $rsa, 'PMG', $ticket, undef, | |
81 | $min_ticket_lifetime, $max_ticket_lifetime, $noerr); | |
82 | } | |
83 | ||
84 | # VNC tickets | |
85 | # - they do not contain the username in plain text | |
86 | # - they are restricted to a specific resource path (example: '/vms/100') | |
87 | sub assemble_vnc_ticket { | |
88 | my ($username, $path) = @_; | |
89 | ||
90 | my $secret_data = "$username:$path"; | |
91 | ||
92 | return PVE::Ticket::assemble_rsa_ticket( | |
93 | $rsa, 'PMGVNC', undef, $secret_data); | |
94 | } | |
95 | ||
96 | sub verify_vnc_ticket { | |
97 | my ($ticket, $username, $path, $noerr) = @_; | |
98 | ||
99 | my $secret_data = "$username:$path"; | |
100 | ||
101 | return PVE::Ticket::verify_rsa_ticket( | |
102 | $rsa, 'PMGVNC', $ticket, $secret_data, -20, 40, $noerr); | |
103 | } | |
104 | ||
105 | 1; |