line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
##@file |
2
|
|
|
|
|
|
|
# Zimbra preauthentication |
3
|
|
|
|
|
|
|
|
4
|
|
|
|
|
|
|
##@class |
5
|
|
|
|
|
|
|
# Zimbra preauthentication |
6
|
|
|
|
|
|
|
# |
7
|
|
|
|
|
|
|
# It will build Zimbra preauth URL |
8
|
|
|
|
|
|
|
|
9
|
|
|
|
|
|
|
# This specific handler is intended to be called directly by Apache |
10
|
|
|
|
|
|
|
|
11
|
|
|
|
|
|
|
package Lemonldap::NG::Handler::Specific::ZimbraPreAuth; |
12
|
|
|
|
|
|
|
|
13
|
1
|
|
|
1
|
|
17291
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
55
|
|
14
|
1
|
|
|
1
|
|
847
|
use Lemonldap::NG::Handler::SharedConf qw(:all); |
|
0
|
|
|
|
|
|
|
|
0
|
|
|
|
|
|
|
15
|
|
|
|
|
|
|
use base qw(Lemonldap::NG::Handler::SharedConf); |
16
|
|
|
|
|
|
|
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); |
17
|
|
|
|
|
|
|
use Lemonldap::NG::Handler::Main::Headers; |
18
|
|
|
|
|
|
|
use Lemonldap::NG::Handler::Main::Logger; |
19
|
|
|
|
|
|
|
|
20
|
|
|
|
|
|
|
our $VERSION = '1.0.0'; |
21
|
|
|
|
|
|
|
|
22
|
|
|
|
|
|
|
# Shared variables |
23
|
|
|
|
|
|
|
our ( $zimbraPreAuthKey, $zimbraAccountKey, $zimbraBy, $zimbraUrl, |
24
|
|
|
|
|
|
|
$zimbraSsoUrl, $timeout ); |
25
|
|
|
|
|
|
|
|
26
|
|
|
|
|
|
|
## @imethod protected void globalInit(hashRef args) |
27
|
|
|
|
|
|
|
# Overload globalInit to launch this class defaultValuesInit |
28
|
|
|
|
|
|
|
# @param $args reference to the configuration hash |
29
|
|
|
|
|
|
|
sub globalInit { |
30
|
|
|
|
|
|
|
my $class = shift; |
31
|
|
|
|
|
|
|
__PACKAGE__->defaultValuesInit(@_); |
32
|
|
|
|
|
|
|
$class->SUPER::globalInit(@_); |
33
|
|
|
|
|
|
|
} |
34
|
|
|
|
|
|
|
|
35
|
|
|
|
|
|
|
## @imethod protected void defaultValuesInit(hashRef args) |
36
|
|
|
|
|
|
|
# Overload defaultValuesInit |
37
|
|
|
|
|
|
|
# @param $args reference to the configuration hash |
38
|
|
|
|
|
|
|
sub defaultValuesInit { |
39
|
|
|
|
|
|
|
my ( $class, $args ) = splice @_; |
40
|
|
|
|
|
|
|
|
41
|
|
|
|
|
|
|
# Catch Zimbra parameters |
42
|
|
|
|
|
|
|
$zimbraPreAuthKey = $args->{'zimbraPreAuthKey'} || $zimbraPreAuthKey; |
43
|
|
|
|
|
|
|
$zimbraAccountKey = |
44
|
|
|
|
|
|
|
$args->{'zimbraAccountKey'} |
45
|
|
|
|
|
|
|
|| $zimbraAccountKey |
46
|
|
|
|
|
|
|
|| 'uid'; |
47
|
|
|
|
|
|
|
$zimbraBy = $args->{'zimbraBy'} || $zimbraBy || 'id'; |
48
|
|
|
|
|
|
|
$zimbraUrl = $args->{'zimbraUrl'} || $zimbraUrl || '/service/preauth'; |
49
|
|
|
|
|
|
|
$zimbraSsoUrl = $args->{'zimbraSsoUrl'} || $zimbraSsoUrl || '^/zimbrasso$'; |
50
|
|
|
|
|
|
|
$timeout = $args->{'timeout'} || $timeout || '0'; |
51
|
|
|
|
|
|
|
|
52
|
|
|
|
|
|
|
# Display found values in debug mode |
53
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( |
54
|
|
|
|
|
|
|
"zimbraPreAuthKey: $zimbraPreAuthKey", 'debug' ); |
55
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( |
56
|
|
|
|
|
|
|
"zimbraAccountKey: $zimbraAccountKey", 'debug' ); |
57
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraBy: $zimbraBy", |
58
|
|
|
|
|
|
|
'debug' ); |
59
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraUrl: $zimbraUrl", |
60
|
|
|
|
|
|
|
'debug' ); |
61
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( "zimbraSsoUrl: $zimbraSsoUrl", |
62
|
|
|
|
|
|
|
'debug' ); |
63
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( "timeout: $timeout", 'debug' ); |
64
|
|
|
|
|
|
|
|
65
|
|
|
|
|
|
|
# Delete Zimbra parameters |
66
|
|
|
|
|
|
|
delete $args->{'zimbraPreAuthKey'}; |
67
|
|
|
|
|
|
|
delete $args->{'zimbraAccountKey'}; |
68
|
|
|
|
|
|
|
delete $args->{'zimbraBy'}; |
69
|
|
|
|
|
|
|
delete $args->{'zimbraUrl'}; |
70
|
|
|
|
|
|
|
delete $args->{'zimbraSsoUrl'}; |
71
|
|
|
|
|
|
|
delete $args->{'timeout'}; |
72
|
|
|
|
|
|
|
|
73
|
|
|
|
|
|
|
# Call main subroutine |
74
|
|
|
|
|
|
|
return $class->SUPER::defaultValuesInit($args); |
75
|
|
|
|
|
|
|
} |
76
|
|
|
|
|
|
|
|
77
|
|
|
|
|
|
|
## @rmethod Apache2::Const run(Apache2::RequestRec r) |
78
|
|
|
|
|
|
|
# Overload main run method |
79
|
|
|
|
|
|
|
# @param r Current request |
80
|
|
|
|
|
|
|
# @return Apache2::Const value (OK, FORBIDDEN, REDIRECT or SERVER_ERROR) |
81
|
|
|
|
|
|
|
sub run { |
82
|
|
|
|
|
|
|
my $class = shift; |
83
|
|
|
|
|
|
|
my $r = $_[0]; |
84
|
|
|
|
|
|
|
my $ret = $class->SUPER::run(@_); |
85
|
|
|
|
|
|
|
|
86
|
|
|
|
|
|
|
# Continue only if user is authorized |
87
|
|
|
|
|
|
|
return $ret unless ( $ret == OK ); |
88
|
|
|
|
|
|
|
|
89
|
|
|
|
|
|
|
# Get current URI |
90
|
|
|
|
|
|
|
my $args = $r->args; |
91
|
|
|
|
|
|
|
my $uri = $r->uri . ( $args ? "?$args" : "" ); |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
# Return if we are not on a Zimbra SSO URI |
94
|
|
|
|
|
|
|
return OK unless ( $uri =~ $zimbraSsoUrl ); |
95
|
|
|
|
|
|
|
|
96
|
|
|
|
|
|
|
# Check mandatory parameters |
97
|
|
|
|
|
|
|
return $class->abort("No Zimbra preauth key configured") |
98
|
|
|
|
|
|
|
unless ($zimbraPreAuthKey); |
99
|
|
|
|
|
|
|
|
100
|
|
|
|
|
|
|
# Build URL |
101
|
|
|
|
|
|
|
my $zimbra_url = $class->_buildZimbraPreAuthUrl( |
102
|
|
|
|
|
|
|
$zimbraPreAuthKey, $zimbraUrl, |
103
|
|
|
|
|
|
|
$datas->{$zimbraAccountKey}, $zimbraBy |
104
|
|
|
|
|
|
|
); |
105
|
|
|
|
|
|
|
|
106
|
|
|
|
|
|
|
# Header location |
107
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Headers->lmSetHeaderOut( $r, |
108
|
|
|
|
|
|
|
'Location' => $zimbra_url ); |
109
|
|
|
|
|
|
|
|
110
|
|
|
|
|
|
|
# Return REDIRECT |
111
|
|
|
|
|
|
|
return REDIRECT; |
112
|
|
|
|
|
|
|
} |
113
|
|
|
|
|
|
|
|
114
|
|
|
|
|
|
|
## @method private string _buildZimbraPreAuthUrl(string key, string url, string account, string by) |
115
|
|
|
|
|
|
|
# Build Zimbra PreAuth URL |
116
|
|
|
|
|
|
|
# @param key PreAuthKey |
117
|
|
|
|
|
|
|
# @param url URL |
118
|
|
|
|
|
|
|
# @param account User account |
119
|
|
|
|
|
|
|
# @param by Account type |
120
|
|
|
|
|
|
|
# @return Zimbra PreAuth URL |
121
|
|
|
|
|
|
|
sub _buildZimbraPreAuthUrl { |
122
|
|
|
|
|
|
|
my ( $class, $key, $url, $account, $by ) = splice @_; |
123
|
|
|
|
|
|
|
|
124
|
|
|
|
|
|
|
# Expiration time is calculated with _utime and timeout |
125
|
|
|
|
|
|
|
my $expires = $timeout ? ( $datas->{_utime} + $timeout ) * 1000 : $timeout; |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
# Timestamp |
128
|
|
|
|
|
|
|
my $timestamp = time() * 1000; |
129
|
|
|
|
|
|
|
|
130
|
|
|
|
|
|
|
# Compute preauth value |
131
|
|
|
|
|
|
|
my $computed_value = |
132
|
|
|
|
|
|
|
hmac_sha1_hex( "$account|$by|$expires|$timestamp", $key ); |
133
|
|
|
|
|
|
|
|
134
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( |
135
|
|
|
|
|
|
|
"Compute value $account|$by|$expires|$timestamp into $computed_value", |
136
|
|
|
|
|
|
|
'debug' ); |
137
|
|
|
|
|
|
|
|
138
|
|
|
|
|
|
|
# Build PreAuth URL |
139
|
|
|
|
|
|
|
my $zimbra_url = |
140
|
|
|
|
|
|
|
"$url?account=$account&by=$by×tamp=$timestamp&expires=$expires&preauth=$computed_value"; |
141
|
|
|
|
|
|
|
|
142
|
|
|
|
|
|
|
Lemonldap::NG::Handler::Main::Logger->lmLog( |
143
|
|
|
|
|
|
|
"Build Zimbra URL: $zimbra_url", 'debug' ); |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
return $zimbra_url; |
146
|
|
|
|
|
|
|
} |
147
|
|
|
|
|
|
|
|
148
|
|
|
|
|
|
|
__PACKAGE__->init( {} ); |
149
|
|
|
|
|
|
|
|
150
|
|
|
|
|
|
|
1; |
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
__END__ |