]> git.proxmox.com Git - pve-manager.git/blame - lib/PVE/APLInfo.pm
imported from svn 'pve-manager/pve2'
[pve-manager.git] / lib / PVE / APLInfo.pm
CommitLineData
aff192e6
DM
1package PVE::APLInfo;
2
3use strict;
4use IO::File;
5use PVE::SafeSyslog;
6use PVE::I18N;
7use LWP::UserAgent;
8use PVE::Config;
9use POSIX qw(strftime);
10
11my $logfile = "/var/log/pveam.log";
12
13# Default list of GPG keys allowed to sign aplinfo
14#
15#pub 1024D/5CAC72FE 2004-06-24
16# Key fingerprint = 9ABD 7E02 AD24 3AD3 C2FB BCCC B0C1 CC22 5CAC 72FE
17#uid Proxmox Support Team <support@proxmox.com>
18
19my $valid_keys = {
20 '9ABD7E02AD243AD3C2FBBCCCB0C1CC225CAC72FE' => 1, # fingerprint support@proxmox.com
21 '25CAC72FE' => 1, # keyid support@proxmox.com
22};
23
24sub import_gpg_keys {
25
26 my $keyfile = '/usr/share/doc/pve-manager/support@proxmox.com.pubkey';
27
28 return system ("/usr/bin/gpg --batch --no-tty --status-fd=1 -q " .
29 "--logger-fd=1 --import $keyfile >>$logfile");
30}
31
32sub logmsg {
33 my ($logfd, $msg) = @_;
34
35 chomp $msg;
36
37 my $tstr = strftime ("%b %d %H:%M:%S", localtime);
38
39 foreach my $line (split (/\n/, $msg)) {
40 print $logfd "$tstr $line\n";
41 }
42}
43
44sub url_get {
45 my ($ua, $url, $file, $logfh) = @_;
46
47 my $req = HTTP::Request->new(GET => $url);
48
49 logmsg ($logfh, "start download $url");
50 my $res = $ua->request($req, $file);
51
52 if ($res->is_success) {
53 logmsg ($logfh, "download finished: " . $res->status_line);
54 return 0;
55 }
56
57 logmsg ($logfh, "download failed: " . $res->status_line);
58
59 return 1;
60}
61
62sub update {
63 my ($proxy) = @_;
64
65 my $aplurl = "http://download.proxmox.com/appliances";
66 my $aplsrcurl = "$aplurl/aplinfo.dat.gz";
67 my $aplsigurl = "$aplurl/aplinfo.dat.asc";
68
69 my $size;
70 if (($size = (-s $logfile) || 0) > (1024*50)) {
71 system ("mv $logfile $logfile.0");
72 }
73 my $logfd = IO::File->new (">>$logfile");
74 logmsg ($logfd, "starting update");
75
76 import_gpg_keys();
77
78 my $tmp = "/tmp/pveam.tmp.$$";
79 my $tmpgz = "$tmp.gz";
80 my $sigfn = "$tmp.asc";
81
82 # this code works for ftp and http
83 # always use passive ftp
84 local $ENV{FTP_PASSIVE} = 1;
85 my $ua = LWP::UserAgent->new;
86 $ua->agent("PVE/1.0");
87
88 if ($proxy) {
89 $ua->proxy(['http'], $proxy);
90 } else {
91 $ua->env_proxy;
92 }
93
94 eval {
95 if (url_get ($ua, $aplsigurl, $sigfn, $logfd) != 0) {
96 die "update failed - no signature\n";
97 }
98
99 if (url_get ($ua, $aplsrcurl, $tmpgz, $logfd) != 0) {
100 die "update failed - no data\n";
101 }
102
103 if (system ("zcat -f $tmpgz >$tmp 2>/dev/null") != 0) {
104 die "update failed: unable to unpack '$tmpgz'\n";
105 }
106
107 # verify signature
108
109 my $cmd = "/usr/bin/gpg --verify --batch --no-tty --status-fd=1 -q " .
110 "--logger-fd=1 $sigfn $tmp";
111
112 open (CMD, "$cmd|") ||
113 die "unable to execute '$cmd': $!\n";
114
115 my $line;
116 my $signer = '';
117 while (defined ($line = <CMD>)) {
118 chomp $line;
119 logmsg ($logfd, $line);
120
121 # code borrowed from SA
122 next if $line !~ /^\Q[GNUPG:]\E (?:VALID|GOOD)SIG (\S{8,40})/;
123 my $key = $1;
124
125 # we want either a keyid (8) or a fingerprint (40)
126 if (length $key > 8 && length $key < 40) {
127 substr($key, 8) = '';
128 }
129 # use the longest match we can find
130 $signer = $key if (length $key > length $signer) && $valid_keys->{$key};
131 }
132
133 close (CMD);
134
135 die "unable to verify signature\n" if !$signer;
136
137 logmsg ($logfd, "signature valid: $signer");
138
139 # test syntax
140 eval {
141 my $fh = IO::File->new ("<$tmp") ||
142 die "unable to open file '$tmp' - $!\n";
143 PVE::Config::read_aplinfo ($tmp, $fh, 1);
144 close ($fh);
145 };
146 die "update failed: $@" if $@;
147
148 if (system ("mv $tmp /var/lib/pve-manager/apl-available 2>/dev/null") != 0) {
149 die "update failed: unable to store data\n";
150 }
151
152 logmsg ($logfd, "update sucessful");
153 };
154
155 my $err = $@;
156
157 unlink $tmp;
158 unlink $tmpgz;
159 unlink $sigfn;
160
161 if ($err) {
162 logmsg ($logfd, $err);
163 close ($logfd);
164
165 return 0;
166 }
167
168 close ($logfd);
169
170 return 1;
171}
172
173sub load_data {
174
175 my $filename = "/var/lib/pve-manager/apl-available";
176
177 if (! -f $filename) {
178 system ("cp /usr/share/doc/pve-manager/aplinfo.dat /var/lib/pve-manager/apl-available");
179 }
180
181 return PVE::Config::read_file ('aplinfo');
182}
183
184sub display_name {
185 my ($template) = @_;
186
187 my $templates = load_data ();
188
189 return $template if !$templates;
190
191 my $d = $templates->{'all'}->{$template};
192
193 $template =~ s/\.tar\.gz$//;
194 $template =~ s/_i386$//;
195
196 return $template if !$d;
197
198 return "$d->{package}_$d->{version}";
199}
200
201sub pkginfo {
202 my ($template) = @_;
203
204 my $templates = load_data ();
205
206 return undef if !$templates;
207
208 my $d = $templates->{'all'}->{$template};
209
210 return $d;
211}
212
213sub webnews {
214 my ($lang) = @_;
215
216 my $templates = load_data ();
217
218 my $html = '';
219
220 $html .= __("<b>Welcome</b> to the Proxmox Virtual Environment!");
221 $html .= "<br><br>";
222 $html .= __("For more information please visit our homepage at");
223 $html .= " <a href='http://www.proxmox.com' target='_blank'>www.proxmox.com</a>.";
224
225 return $html if !$templates;
226
227 # my $d = $templates->{'all'}->{"pve-web-news-$lang"} ||
228 my $d = $templates->{all}->{'pve-web-news'};
229
230 return $html if !$d;
231
232 return $d->{description};
233}
234
2351;
236