]>
Commit | Line | Data |
---|---|---|
46c01c09 MT |
1 | #!/usr/bin/perl |
2 | # | |
3 | # This code is distributed under the terms of the GPL | |
4 | # | |
0a638396 | 5 | # (c) 2006-2008 marco.s - http://update-accelerator.advproxy.net |
46c01c09 | 6 | # |
0a638396 | 7 | # $Id: updxlrator,v 2.0 2008/04/06 00:00:00 marco.s Exp $ |
46c01c09 MT |
8 | # |
9 | ||
10 | use strict; | |
0a638396 | 11 | use HTTP::Date; |
46c01c09 MT |
12 | |
13 | $|=1; | |
14 | ||
15 | my $swroot="/var/ipfire"; | |
381f2e71 | 16 | my $updcachedir="/var/updatecache"; |
0a638396 CS |
17 | my $apphome="/var/ipfire/updatexlrator"; |
18 | my $logfile="/var/log/updatexlrator/cache.log"; | |
19 | my $wget="$apphome/bin/wget"; | |
20 | my $debug=(-e "$apphome/debug"); | |
21 | my $http_port='81'; | |
46c01c09 | 22 | my %netsettings=(); |
0a638396 | 23 | my %proxysettings=(); |
46c01c09 | 24 | my %xlratorsettings=(); |
46c01c09 MT |
25 | my $logging=0; |
26 | my $passive_mode=0; | |
27 | my $maxusage=0; | |
28 | my $nice=''; | |
29 | my @tmp=(); | |
46c01c09 | 30 | my $request=''; |
0a638396 CS |
31 | my $xlrator_url=0; |
32 | my $source_url=''; | |
46c01c09 MT |
33 | my $hostaddr=''; |
34 | my $username=''; | |
35 | my $method=''; | |
0a638396 CS |
36 | my $unique = 0; |
37 | my $mirror = 1; | |
46c01c09 MT |
38 | |
39 | readhash("${swroot}/ethernet/settings", \%netsettings); | |
40 | ||
41 | if (-e "$swroot/updatexlrator/settings") | |
42 | { | |
43 | &readhash("$swroot/updatexlrator/settings", \%xlratorsettings); | |
44 | if ($xlratorsettings{'ENABLE_LOG'} eq 'on') { $logging=1; }; | |
45 | if ($xlratorsettings{'PASSIVE_MODE'} eq 'on') { $passive_mode=1; }; | |
46 | $maxusage=$xlratorsettings{'MAX_DISK_USAGE'}; | |
0a638396 | 47 | if ($xlratorsettings{'LOW_DOWNLOAD_PRIORITY'} eq 'on') { $nice='/usr/bin/nice --adjustment=15 '; }; |
46c01c09 MT |
48 | } |
49 | if (!$maxusage) { $maxusage=75; }; | |
50 | ||
51 | ||
52 | while (<>) { | |
53 | ||
54 | $request=$_; | |
46c01c09 MT |
55 | |
56 | @tmp=split(/ /,$request); | |
57 | chomp(@tmp); | |
58 | ||
0a638396 CS |
59 | $source_url = $tmp[0]; |
60 | $hostaddr = $tmp[1]; while ($hostaddr =~ /.*\/$/) { chop $hostaddr; } | |
61 | $username = $tmp[2]; if ($username eq '') { $username='-'; }; | |
62 | $method = $tmp[3]; | |
63 | ||
64 | $xlrator_url = $source_url; | |
46c01c09 MT |
65 | |
66 | if (($method eq 'GET') || ($method eq 'HEAD')) | |
67 | { | |
68 | ||
69 | # ----------------------------------------------------------- | |
70 | # Section: Windows Update / Windows Downloads | |
71 | # ----------------------------------------------------------- | |
72 | ||
73 | if ( | |
0a638396 CS |
74 | (($source_url =~ m@^http://[^/]*\.microsoft\.com/.*\.(exe|psf|msi|msp|cab)$@i) || |
75 | ($source_url =~ m@^http://[^/]*\.windowsupdate\.com/.*\.(exe|psf|msi|msp|cab)$@i)) | |
76 | && ($source_url !~ m@^http://[^/]*\.microsoft\.com/.*(/autoupd|selfupdate/).*\.cab@i) | |
77 | && ($source_url !~ m@\&@) | |
46c01c09 MT |
78 | ) |
79 | { | |
0a638396 | 80 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Microsoft",$unique); |
46c01c09 MT |
81 | } |
82 | ||
83 | # ----------------------------------------------------------- | |
84 | # Section: Adobe Downloads | |
85 | # ----------------------------------------------------------- | |
86 | ||
0a638396 CS |
87 | if ( |
88 | ($source_url =~ m@^http://(ar)?download\.adobe\.com/.*\.(exe|msi|bin|dmg|idx|gz)$@i) || | |
89 | ($source_url =~ m@^http://swupdl\.adobe\.com/updates/.*\.(exe|msi|bin|dmg|idx|gz|[a-z][a-z]_[A-Z][A-Z])$@i) || | |
90 | ($source_url =~ m@^http://swupmf\.adobe\.com/manifest/.*\.upd$@i) | |
91 | ) | |
92 | { | |
93 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Adobe",$unique); | |
94 | } | |
95 | ||
96 | # ----------------------------------------------------------- | |
97 | # Section: Linux Downloads | |
98 | # ----------------------------------------------------------- | |
99 | ||
100 | if ($source_url =~ m@^[h|f]t?tp://[^?]+\.(deb|rpm)$@i) | |
46c01c09 | 101 | { |
0a638396 CS |
102 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Linux",$mirror); |
103 | } | |
104 | ||
105 | # ----------------------------------------------------------- | |
106 | # Section: Trend Micro Downloads | |
107 | # ----------------------------------------------------------- | |
108 | ||
109 | if ( | |
110 | ($source_url =~ m@^http://[^/]*\.trendmicro\.com/activeupdate/.*@i) && | |
111 | ($source_url !~ m@.*/tmnotify\.dat$@i) && | |
112 | ($source_url !~ m@.*/ini_xml\.zip$@i) && | |
113 | ($source_url !~ m@.*/server\.ini$@i) | |
114 | ) | |
115 | { | |
116 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"TrendMicro",$mirror); | |
46c01c09 MT |
117 | } |
118 | ||
119 | # ----------------------------------------------------------- | |
120 | # Section: Symantec Downloads | |
121 | # ----------------------------------------------------------- | |
122 | ||
0a638396 | 123 | if ($source_url =~ m@^[h|f]tt?p://[^/]*\.symantec(liveupdate)?\.com/.*\.(exe|zip|vdb|xdb)$@i) |
46c01c09 | 124 | { |
0a638396 | 125 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Symantec",$unique); |
46c01c09 | 126 | } |
0a638396 | 127 | |
5b2a12ff | 128 | # ----------------------------------------------------------- |
0a638396 | 129 | # Section: Apple Downloads |
46c01c09 | 130 | # ----------------------------------------------------------- |
0a638396 CS |
131 | |
132 | if ( | |
133 | (($source_url =~ m@^http://swcdn\.apple\.com/content/downloads/.*\.(tar)$@i) || | |
134 | ($source_url =~ m@^http://appldnld\.apple\.com\.edgesuite\.net/.*\.(exe|dmg)$@i) || | |
135 | ($source_url =~ m@^http://.*\.g.akamai.net/.*/3093/1/.*\.(tar|pkg|dmg|exe)$@i)) | |
136 | ) | |
5b2a12ff | 137 | { |
0a638396 | 138 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Apple",$unique); |
5b2a12ff | 139 | } |
0a638396 CS |
140 | |
141 | # ----------------------------------------------------------- | |
142 | # Section: Avast Downloads | |
143 | # ----------------------------------------------------------- | |
144 | ||
145 | if ($source_url =~ m@^http://download[\d]+\.avast\.com/.*\.(exe|vpu)$@i) | |
146 | { | |
147 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Avast",$mirror); | |
186e3d2c | 148 | } |
0a638396 CS |
149 | |
150 | # ----------------------------------------------------------- | |
186e3d2c | 151 | |
0a638396 CS |
152 | # ----------------------------------------------------------- |
153 | # Section: Avira Downloads | |
154 | # ----------------------------------------------------------- | |
155 | ||
156 | if ($source_url =~ m@^http://dl[0-9]\.avgate\.net/.*\.(htm|html|gz)$@i) | |
157 | { | |
158 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"Avira",$mirror); | |
2dfb38e6 | 159 | } |
4ae86474 AF |
160 | |
161 | # ----------------------------------------------------------- | |
0a638396 | 162 | # Section: IPFire Downloads |
4ae86474 AF |
163 | # ----------------------------------------------------------- |
164 | ||
0a638396 | 165 | if ($source_url =~ m@^[f|h]t?tp://.*\.(ipfire)$@i) |
4ae86474 | 166 | { |
0a638396 | 167 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"IPFire",$mirror); |
4ae86474 AF |
168 | } |
169 | ||
0a638396 | 170 | } |
2dfb38e6 | 171 | |
0a638396 CS |
172 | # ----------------------------------------------------------- |
173 | # Section: AVG Downloads | |
174 | # ----------------------------------------------------------- | |
46c01c09 | 175 | |
0a638396 CS |
176 | if ($source_url =~ m@^http://[^/]*\.(grisoft|avg)\.com/.*\.(bin)$@i) |
177 | { | |
178 | $xlrator_url = &check_cache($source_url,$hostaddr,$username,"AVG",$mirror); | |
46c01c09 MT |
179 | } |
180 | ||
0a638396 | 181 | $request="$xlrator_url $hostaddr $username $method\n"; |
46c01c09 MT |
182 | |
183 | print $request; | |
184 | } | |
185 | ||
186 | # ------------------------------------------------------------------- | |
187 | ||
188 | sub readhash | |
189 | { | |
190 | my $filename = $_[0]; | |
191 | my $hash = $_[1]; | |
192 | my ($var, $val); | |
193 | ||
194 | if (-e $filename) | |
195 | { | |
196 | open(FILE, $filename) or die "Unable to read file $filename"; | |
197 | while (<FILE>) | |
198 | { | |
199 | chop; | |
200 | ($var, $val) = split /=/, $_, 2; | |
201 | if ($var) | |
202 | { | |
203 | $val =~ s/^\'//g; | |
204 | $val =~ s/\'$//g; | |
205 | ||
206 | # Untaint variables read from hash | |
207 | $var =~ /([A-Za-z0-9_-]*)/; $var = $1; | |
208 | $val =~ /([\w\W]*)/; $val = $1; | |
209 | $hash->{$var} = $val; | |
210 | } | |
211 | } | |
212 | close FILE; | |
213 | } | |
214 | } | |
215 | ||
216 | # ------------------------------------------------------------------- | |
217 | ||
218 | sub writelog | |
219 | { | |
0a638396 CS |
220 | if ($logging) |
221 | { | |
222 | open(LOGFILE,">>$logfile"); | |
223 | print LOGFILE time." $_[0] $_[1] $_[2] $_[3] $_[4]\n"; | |
224 | close(LOGFILE); | |
225 | } | |
46c01c09 MT |
226 | } |
227 | ||
228 | # ------------------------------------------------------------------- | |
229 | ||
0a638396 | 230 | sub debuglog |
46c01c09 | 231 | { |
0a638396 | 232 | if ($debug) |
46c01c09 | 233 | { |
0a638396 CS |
234 | open(LOGFILE,">>/var/log/updatexlrator/debug.log"); |
235 | my @now = localtime(time); | |
236 | printf LOGFILE "%04d-%02d-%02d %02d:%02d:%02d [%d] [%s] %s\n",$now[5]+1900,$now[4]+1,$now[3],$now[2],$now[1],$now[0],$$,"updxlrator",$_[0]; | |
237 | close(LOGFILE); | |
46c01c09 | 238 | } |
0a638396 CS |
239 | } |
240 | ||
241 | # ------------------------------------------------------------------- | |
242 | ||
243 | sub setcachestatus | |
244 | { | |
245 | open (FILE,">>$_[0]"); | |
246 | print FILE "$_[1]\n"; | |
247 | close FILE; | |
248 | } | |
249 | ||
250 | # ------------------------------------------------------------------- | |
251 | ||
252 | sub diskfree | |
253 | { | |
254 | open(DF,"/bin/df --block-size=1 $_[0]|"); | |
255 | my @dfdata = <DF>; | |
46c01c09 | 256 | close DF; |
0a638396 CS |
257 | shift(@dfdata); |
258 | chomp(@dfdata); | |
259 | my $dfstr = join(' ',@dfdata); | |
260 | my ($device,$size,$used,$free,$percent,$mount) = split(' ',$dfstr); | |
261 | if ($free =~ m/^(\d+)$/) | |
262 | { | |
263 | return $free; | |
264 | } | |
46c01c09 MT |
265 | } |
266 | ||
267 | # ------------------------------------------------------------------- | |
268 | ||
269 | sub diskusage | |
270 | { | |
271 | open(DF,"/bin/df $_[0]|"); | |
0a638396 CS |
272 | my @dfdata = <DF>; |
273 | close DF; | |
274 | shift(@dfdata); | |
275 | chomp(@dfdata); | |
276 | my $dfstr = join(' ',@dfdata); | |
277 | my ($device,$size,$used,$free,$percent,$mount) = split(' ',$dfstr); | |
278 | if ($percent =~ m/^(\d+)%$/) | |
46c01c09 | 279 | { |
0a638396 CS |
280 | $percent =~ s/%$//; |
281 | return $percent; | |
46c01c09 | 282 | } |
46c01c09 MT |
283 | } |
284 | ||
285 | # ------------------------------------------------------------------- | |
286 | ||
0a638396 | 287 | sub getmtime |
46c01c09 | 288 | { |
0a638396 | 289 | my ($dev,$ino,$mode,$nlink,$uid,$gid,$rdev,$size,$atime,$mtime,$ctime,$blksize,$blocks) = stat($_[0]); |
46c01c09 | 290 | |
0a638396 CS |
291 | return $mtime; |
292 | } | |
46c01c09 | 293 | |
0a638396 | 294 | # ------------------------------------------------------------------- |
46c01c09 | 295 | |
0a638396 CS |
296 | sub check_cache |
297 | { | |
298 | my $updsource="UPDCACHE"; | |
299 | my $updfile=''; | |
300 | my $cacheurl=''; | |
301 | my $vendorid=''; | |
302 | my $uuid=''; | |
303 | my @http_header=(); | |
304 | my $remote_size=0; | |
305 | my $remote_mtime=0; | |
306 | my $login=''; | |
307 | my $useragent="Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.1)"; | |
308 | ||
309 | my $sourceurl=$_[0]; | |
310 | my $cfmirror=$_[4]; | |
311 | ||
312 | $sourceurl =~ s@\%2f@/@ig; | |
313 | $updfile = substr($sourceurl,rindex($sourceurl,"/")+1); | |
314 | $updfile =~ s@\%20@ @ig; | |
315 | ||
316 | if ($cfmirror) | |
46c01c09 | 317 | { |
0a638396 CS |
318 | $uuid = `echo $updfile | md5sum`; |
319 | } else { | |
320 | $uuid = `echo $sourceurl | md5sum`; | |
46c01c09 MT |
321 | } |
322 | ||
0a638396 CS |
323 | $uuid =~ s/[^0-9a-f]//g; |
324 | $uuid =~ s/([a-f\d]{8})([a-f\d]{4})([a-f\d]{4})([a-f\d]{4})([a-f\d]{12})/$1-$2-$3-$4-$5/; | |
325 | ||
326 | $vendorid = $_[3]; | |
327 | $vendorid =~ tr/A-Z/a-z/; | |
328 | ||
329 | &debuglog("Processing URL $sourceurl"); | |
330 | &debuglog("Vendor ID is $vendorid"); | |
331 | &debuglog("UUID is $uuid"); | |
332 | ||
333 | if (($proxysettings{'UPSTREAM_PROXY'}) && ($proxysettings{'UPSTREAM_USER'})) | |
46c01c09 | 334 | { |
0a638396 CS |
335 | $login = "--proxy-user=\"$proxysettings{'UPSTREAM_USER'}\""; |
336 | if ($proxysettings{'UPSTREAM_PASSWORD'}) | |
46c01c09 | 337 | { |
0a638396 | 338 | $login .= " --proxy-password=\"$proxysettings{'UPSTREAM_PASSWORD'}\""; |
46c01c09 MT |
339 | } |
340 | } | |
46c01c09 | 341 | |
0a638396 | 342 | if ($proxysettings{'UPSTREAM_PROXY'}) { &debuglog("Using upstream proxy $proxysettings{'UPSTREAM_PROXY'}"); } |
46c01c09 | 343 | |
0a638396 CS |
344 | $ENV{'http_proxy'} = $proxysettings{'UPSTREAM_PROXY'}; |
345 | @http_header = `$wget $login --user-agent="$useragent" --spider -S $sourceurl 2>&1`; | |
346 | $ENV{'http_proxy'} = ''; | |
46c01c09 | 347 | |
0a638396 | 348 | foreach (@http_header) |
46c01c09 | 349 | { |
0a638396 CS |
350 | chomp; |
351 | if (/^\s*Content-Length:\s/) { $remote_size = $_; $remote_size =~ s/[^0-9]//g; } | |
352 | if (/^\s*Last-Modified:\s/) { $remote_mtime = $_; $remote_mtime =~ s/^\s*Last-Modified:\s//; $remote_mtime = HTTP::Date::str2time($remote_mtime) } | |
46c01c09 MT |
353 | } |
354 | ||
0a638396 CS |
355 | if ( |
356 | (-e "$updcachedir/$vendorid/$uuid/$updfile") && | |
357 | ($remote_size == (-s "$updcachedir/$vendorid/$uuid/$updfile")) && | |
358 | ($remote_mtime == &getmtime("$updcachedir/$vendorid/$uuid/$updfile")) | |
359 | ) | |
46c01c09 | 360 | { |
0a638396 CS |
361 | &debuglog("File exists in cache and is up to date"); |
362 | &debuglog("Retrieving file from cache ($updsource)"); | |
363 | &setcachestatus("$updcachedir/$vendorid/$uuid/access.log",time); | |
364 | system("$apphome/bin/setperms $vendorid/$uuid/access.log"); | |
365 | $cacheurl="http://$netsettings{'GREEN_ADDRESS'}:$http_port/updatecache/$vendorid/$uuid/$updfile"; | |
46c01c09 MT |
366 | } |
367 | else | |
368 | { | |
0a638396 CS |
369 | if (-e "$updcachedir/$vendorid/$uuid/$updfile") |
370 | { | |
371 | &debuglog("Local filesize: " . (-s "$updcachedir/$vendorid/$uuid/$updfile")); | |
372 | &debuglog("Local timestamp: " . &getmtime("$updcachedir/$vendorid/$uuid/$updfile")); | |
373 | } else { &debuglog("File not found in cache"); } | |
46c01c09 | 374 | $updsource="DLSOURCE"; |
0a638396 CS |
375 | &debuglog("Remote filesize: $remote_size"); |
376 | &debuglog("Remote timestamp: $remote_mtime"); | |
377 | &debuglog("Free disk space: " . &diskfree($updcachedir)); | |
378 | &debuglog("Disk usage: " . &diskusage($updcachedir) . "% (max. $maxusage%)"); | |
379 | if (-e "$updcachedir/download/$vendorid/$updfile") { &debuglog("File download/$vendorid/$updfile exists"); } | |
380 | &debuglog("Retrieving file from source ($updsource)"); | |
381 | if ((!$passive_mode) && (&diskusage($updcachedir) <= $maxusage) && ($remote_size <= &diskfree($updcachedir)) && (!-e "$updcachedir/download/$vendorid/$updfile")) | |
46c01c09 | 382 | { |
0a638396 CS |
383 | &debuglog("Running command $nice$apphome/bin/download $vendorid $sourceurl $cfmirror &"); |
384 | system("$nice$apphome/bin/download $vendorid $sourceurl $cfmirror &"); | |
46c01c09 | 385 | } |
0a638396 | 386 | $cacheurl=$sourceurl; |
46c01c09 MT |
387 | } |
388 | ||
0a638396 | 389 | &writelog($_[1],$_[2],$_[3],$updsource,$sourceurl); |
46c01c09 | 390 | |
0a638396 | 391 | return $cacheurl; |
46c01c09 MT |
392 | } |
393 | ||
394 | # ------------------------------------------------------------------- |