-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathAuthenticate.pm
More file actions
97 lines (72 loc) · 2.05 KB
/
Authenticate.pm
File metadata and controls
97 lines (72 loc) · 2.05 KB
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
96
97
#!/usr/bin/perl -W
package CookieMonster::Authenticate;
use strict;
use CookieMonster::AuthCert;
use CookieMonster::AuthForm;
use CookieMonster::Secret;
use CGI;
use Digest::SHA qw(sha256_base64);
use Apache2::Const qw(OK DECLINED FORBIDDEN);
use File::Basename;
# Fixme: Determine these paths automatically, or provide a better way to
# configure them
my $docRoot = '/srv/www/';
my $tmplPrompt = 'include/login-prompt.html';
my $tmplSuccess = 'include/login-success.html';
my $tmplFailure = 'include/login-failure.html';
sub handler {
my $r = shift;
my $query = CGI->new($r);
if (my $user = CookieMonster::AuthCert::authenticate($r)) {
return success($r, $user);
} elsif ($r->method eq 'POST') {
if (my $user = CookieMonster::AuthForm::authenticate($r)) {
return success($r, $user);
} else {
return failure($r);
}
} else {
return prompt($r);
}
}
sub success {
my ($r, $user) = @_;
my $resp = CGI->new($r);
my $ip = $r->connection->remote_ip;
my $hash = sha256_base64($user . $ip . CookieMonster::Secret::secret());
my $token = {'user' => $user, 'ip' => $ip, 'hash' => $hash};
my $cookie = CGI->cookie(-name=>'auth', -value=>$token);
$r->print($resp->header("text/html", -cookie=>$cookie));
my $redirect;
if (my $dest = $resp->param('dest')) {
my $target = ($resp->param('sec') eq '1' ? 'https://' : 'http://') .
$resp->server_name() . $dest;
$redirect = "<meta http-equiv=\"Refresh\" content=\"1;url=$target\">";
}
printTemplate($r, $docRoot . $tmplSuccess, {'redirect' => $redirect});
return OK;
}
sub failure {
my $r = shift;
printTemplate($r, $docRoot . $tmplFailure, {});
return OK;
}
sub prompt {
my $r = shift;
my $resp = CGI->new($r);
printTemplate($r, $docRoot . $tmplPrompt, {'dest' => $resp->param('dest'),
'sec' => $resp->param('sec')});
return OK;
}
sub printTemplate {
my $r = shift;
my $file = shift;
my %env = %{(shift)};
open TMPL, $file or die "Can't open $file";
$r->content_type('text/html');
while (<TMPL>) {
$_ =~ s/\$(\w*)/$env{$1}/g;
$r->print($_);
}
}
1;