forked from refracta/dcss-server
-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathauth-save-downloader.pl
executable file
·95 lines (79 loc) · 2.06 KB
/
auth-save-downloader.pl
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
#! /usr/bin/perl
#
# Allows DGL admin users to download saves.
#
use CGI qw/:standard/;
use MIME::Base64;
use DBI;
my $DB = "%%LOGIN_DB%%";
my $CONTENT_DIR = '%%SAVE_DUMPDIR%%/';
my $AUTH_REALM = 'Developer account';
sub request_auth() {
print(header(-type => 'text/html',
-status => '401 Authorization Required',
-WWW_Authenticate => "Basic realm=\"$AUTH_REALM\""),
start_html('Save dumps'),
p('Must authenticate to access saves'),
end_html);
return undef;
}
sub match_password($$) {
my ($plain, $crypt) = @_;
my $cc = crypt($plain, $crypt);
return crypt($plain, $crypt) eq $crypt;
}
sub valid_user($$) {
my ($user, $password) = @_;
my $db = DBI->connect("dbi:SQLite:dbname=$DB", '', '')
or die "Can't open auth db: $DB\n";
my $st = $db->prepare(<<QUERY);
SELECT username, password FROM dglusers
WHERE username=? AND (flags & 1) = 1;
QUERY
$st->execute($user);
my $row = $st->fetchrow_arrayref;
# Should have at least one row.
return defined($row) && match_password($password, $row->[1]);
}
sub valid_auth($) {
my $header = shift;
return unless $header =~ s/^Basic //;
my $decoded = decode_base64($header);
my ($user, $password) = $decoded =~ /(.*?):(.*)/;
valid_user($user, $password)
}
sub authenticate() {
my $auth_header = http('Authorization');
return request_auth() unless $auth_header && valid_auth($auth_header);
1
}
sub file_bytes($) {
my $file = shift;
open my $inf, '<', $file;
binmode $inf;
my $content = do { local $/; <$inf> };
close $inf;
$content
}
sub serve_file() {
my ($file) = param('file');
my $absfile = "$CONTENT_DIR/$file";
if ($file =~ /[.]{2}/ ||
$file !~ /^[a-zA-Z0-9._-]+$/ ||
$file !~ /\.(?:tar\.bz2|cs|core)$/ ||
!-r $absfile)
{
print(header(-status => '404 Not Found'),
start_html,
p("Could not find $absfile"),
end_html);
return;
}
print(header(-type => 'application/octet-stream'),
file_bytes($absfile));
}
sub main() {
return unless authenticate();
serve_file();
}
main();