Zimbra preAuth is now an independent Handler (#12)
This commit is contained in:
parent
cdad662b0e
commit
bec0831f2d
|
@ -359,6 +359,7 @@ install_handler_site: install_conf_dir
|
|||
# Handler install
|
||||
@install -v -d ${RHANDLERDIR}
|
||||
@cp --remove-destination ${SRCHANDLERDIR}/example/MyHandler.pm ${RHANDLERDIR}
|
||||
@cp --remove-destination ${SRCHANDLERDIR}/example/MyHandlerZimbra.pm ${RHANDLERDIR}
|
||||
@rm -rf $$(find $(RHANDLERDIR) -type d -name .svn)
|
||||
|
||||
install_test_site:
|
||||
|
@ -605,6 +606,7 @@ default-diff:
|
|||
@# Handler
|
||||
@$(DIFF) lemonldap-ng-handler/lib/Lemonldap/NG/Handler /usr/local/share/perl/5.10.0/Lemonldap/NG/Handler ||true
|
||||
@$(DIFF) lemonldap-ng-handler/example/MyHandler.pm $(LMPREFIX)/handler/MyHandler.pm ||true
|
||||
@$(DIFF) lemonldap-ng-handler/example/MyHandlerZimbra.pm $(LMPREFIX)/handler/MyHandlerZimbra.pm ||true
|
||||
@# Common
|
||||
@$(DIFF) lemonldap-ng-common/lib/Lemonldap/NG/Common /usr/local/share/perl/5.10.0/Lemonldap/NG/Common ||true
|
||||
@$(DIFF) lemonldap-ng-common/lib/Lemonldap/NG/Common.pm /usr/local/share/perl/5.10.0/Lemonldap/NG/Common.pm ||true
|
||||
|
|
15
modules/lemonldap-ng-handler/example/MyHandlerZimbra.pm
Normal file
15
modules/lemonldap-ng-handler/example/MyHandlerZimbra.pm
Normal file
|
@ -0,0 +1,15 @@
|
|||
# Handler for Zimbra preauthentication
|
||||
|
||||
package My::Zimbra;
|
||||
|
||||
# Load Zimbra Handler
|
||||
use Lemonldap::NG::Handler::ZimbraPreAuth;
|
||||
@ISA = qw(Lemonldap::NG::Handler::ZimbraPreAuth);
|
||||
|
||||
__PACKAGE__->init(
|
||||
{
|
||||
# See Lemonldap::NG::Handler
|
||||
}
|
||||
);
|
||||
|
||||
1;
|
|
@ -22,7 +22,6 @@ use Lemonldap::NG::Common::Safelib; #link protected safe Safe object
|
|||
require Data::Dumper;
|
||||
require POSIX;
|
||||
use CGI::Util 'expires';
|
||||
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex); # Zimbra preauth
|
||||
|
||||
#inherits Cache::Cache
|
||||
#inherits Apache::Session
|
||||
|
@ -600,44 +599,12 @@ sub conditionSub {
|
|||
);
|
||||
}
|
||||
}
|
||||
|
||||
# Replace some strings in condition
|
||||
$cond =~ s/\$date/&POSIX::strftime("%Y%m%d%H%M%S",localtime())/e;
|
||||
$cond =~ s/\$(\w+)/\$datas->{$1}/g;
|
||||
$cond =~ s/\$datas->{vhost}/\$apacheRequest->hostname/g;
|
||||
|
||||
# Zimbra preauth trigger
|
||||
if ( $cond =~ /^zimbra_preauth(?:\s+(\S+)\s+(\S+)\s+(\S+)\s+(\S+))?$/i ) {
|
||||
|
||||
# Get preauth parameters
|
||||
my ( $ZimbraPreAuthKey, $ZimbraAccount, $ZimbraBy, $ZimbraUri ) =
|
||||
( $1, $2, $3, $4 );
|
||||
|
||||
my $ZimbraExpires = 0;
|
||||
my $ZimbraTimestamp = gmtime() * 1000;
|
||||
|
||||
# Compute preauth value
|
||||
my $ZimbraComputedValue = hmac_sha1_hex(
|
||||
"$ZimbraAccount|$ZimbraBy|$ZimbraExpires|$ZimbraTimestamp",
|
||||
$ZimbraPreAuthKey );
|
||||
|
||||
# Redirect user
|
||||
return (
|
||||
$class->safe->reval(
|
||||
"sub {
|
||||
\$datas->{_redirect} = 'http';
|
||||
\$datas->{_redirect} .= ( \$https ? 's' : '' ) . '://' ;
|
||||
\$datas->{_redirect} .= \$apacheRequest->get_server_name;
|
||||
\$datas->{_redirect} .= ':' . ( \$port ? \$port : \$apacheRequest->get_server_port );
|
||||
\$datas->{_redirect} .= '$ZimbraUri';
|
||||
\$datas->{_redirect} .= '?account='.$ZimbraAccount;
|
||||
\$datas->{_redirect} .= '&by=$ZimbraBy';
|
||||
\$datas->{_redirect} .= '&expires=$ZimbraExpires';
|
||||
\$datas->{_redirect} .= '&preauth=$ZimbraComputedValue';
|
||||
return 0; }"
|
||||
),
|
||||
1
|
||||
);
|
||||
}
|
||||
|
||||
# Eval sub
|
||||
my $sub = $class->safe->reval("sub {return ( $cond )}");
|
||||
|
||||
|
@ -870,15 +837,6 @@ sub forbidden {
|
|||
$class->localUnlog;
|
||||
return $class->goToPortal( $u, 'logout=1' );
|
||||
}
|
||||
elsif ( $datas->{_redirect} ) {
|
||||
$class->updateStatus( $datas->{$whatToTrace}, $_[0], 'REDIRECT' );
|
||||
my $u = $datas->{_redirect};
|
||||
$class->lmLog(
|
||||
"Redirect " . $apacheRequest->connection->remote_ip . " to $u",
|
||||
'debug' );
|
||||
lmSetHeaderOut( $apacheRequest, 'Location' => $u );
|
||||
return REDIRECT;
|
||||
}
|
||||
$class->updateStatus( $datas->{$whatToTrace}, $_[0], 'REJECT' );
|
||||
$apacheRequest->push_handlers(
|
||||
PerlLogHandler => sub { $class->logForbidden( $uri, $datas ); DECLINED }
|
||||
|
|
|
@ -0,0 +1,136 @@
|
|||
##@file
|
||||
# Zimbra preauthentication
|
||||
|
||||
##@class
|
||||
# Zimbra preauthentication
|
||||
#
|
||||
# It will build Zimbra preauth URL
|
||||
package Lemonldap::NG::Handler::ZimbraPreAuth;
|
||||
|
||||
use strict;
|
||||
use Lemonldap::NG::Handler::SharedConf qw(:all);
|
||||
our @ISA = qw(Lemonldap::NG::Handler::SharedConf);
|
||||
use Digest::HMAC_SHA1 qw(hmac_sha1 hmac_sha1_hex);
|
||||
|
||||
our $VERSION = '0.1';
|
||||
|
||||
# @method run()
|
||||
# Overload main run method
|
||||
# return Apache error code
|
||||
sub run {
|
||||
my $class = shift;
|
||||
my $r = $_[0];
|
||||
my $ret = $class->SUPER::run(@_);
|
||||
|
||||
# Continue only if user is authorized
|
||||
return $ret unless $ret eq OK;
|
||||
|
||||
# Get configuration parameters
|
||||
my $ZimbraPreAuthKey = $r->dir_config('ZimbraPreAuthKey');
|
||||
my $ZimbraAccountKey = $r->dir_config('ZimbraAccountKey') || "uid";
|
||||
my $ZimbraBy = $r->dir_config('ZimbraBy') || "id";
|
||||
my $ZimbraUrl = $r->dir_config('ZimbraUrl');
|
||||
|
||||
unless ( $ZimbraPreAuthKey and $ZimbraUrl ) {
|
||||
$class->lmLog( "No preauth key or URL configured", 'error' );
|
||||
return SERVER_ERROR;
|
||||
}
|
||||
|
||||
# Other values
|
||||
my $ZimbraAccount = $datas->{$ZimbraAccountKey};
|
||||
my $ZimbraExpires = 0;
|
||||
my $ZimbraTimestamp = gmtime() * 1000;
|
||||
|
||||
# Compute preauth value
|
||||
my $ZimbraComputedValue =
|
||||
hmac_sha1_hex( "$ZimbraAccount|$ZimbraBy|$ZimbraExpires|$ZimbraTimestamp",
|
||||
$ZimbraPreAuthKey );
|
||||
|
||||
# Build PreAuth URL
|
||||
my $zimbra_url;
|
||||
$zimbra_url .= $ZimbraUrl;
|
||||
$zimbra_url .= '?account=' . $ZimbraAccount;
|
||||
$zimbra_url .= '&by=' . $ZimbraBy;
|
||||
$zimbra_url .= '&expires=' . $ZimbraExpires;
|
||||
$zimbra_url .= '&preauth=' . $ZimbraComputedValue;
|
||||
|
||||
$class->lmLog( "Build Zimbra URL $zimbra_url", 'debug' );
|
||||
|
||||
# Header location
|
||||
lmSetHeaderOut( $r, 'Location' => $zimbra_url );
|
||||
|
||||
# Return REDIRECT
|
||||
return REDIRECT;
|
||||
}
|
||||
|
||||
1;
|
||||
|
||||
__END__
|
||||
|
||||
=head1 NAME
|
||||
|
||||
=encoding utf8
|
||||
|
||||
Lemonldap::NG::Handler::ZimbraPreAuth - Perl extension to generate Zimbra preauth URL
|
||||
for users authenticated by Lemonldap::NG
|
||||
|
||||
=head1 SYNOPSIS
|
||||
|
||||
package My::Zimbra;
|
||||
use Lemonldap::NG::Handler::ZimbraPreAuth;
|
||||
@ISA = qw(Lemonldap::NG::Handler::ZimbraPreAuth);
|
||||
|
||||
__PACKAGE__->init ( {
|
||||
# See Lemonldap::NG::Handler for more
|
||||
} );
|
||||
1;
|
||||
|
||||
=head1 DESCRIPTION
|
||||
|
||||
Edit you Zimbra vhost configuration like this to catch a specific SSO URL
|
||||
|
||||
<VirtualHost *>
|
||||
ServerName zimbra.example.com
|
||||
|
||||
# Default Handler
|
||||
PerlRequire __HANDLERDIR__/MyHandler.pm
|
||||
PerlHeaderParserHandler My::Zimbra
|
||||
|
||||
# Load Zimbra Handler
|
||||
PerlRequire __HANDLERDIR__/MyHandlerZimbra.pm
|
||||
|
||||
# Zimbra SSO URL
|
||||
<Location /zimbrasso>
|
||||
|
||||
PerlSetVar ZimbraPreAuthKey XXXX
|
||||
PerlSetVar ZimbraAccountKey uid
|
||||
PerlSetVar ZimbraBy id
|
||||
PerlSetVar ZimbraUrl /service/preauth
|
||||
|
||||
PerlHeaderParserHandler My::Zimbra
|
||||
|
||||
</Location>
|
||||
|
||||
</VirtualHost>
|
||||
|
||||
=head2 EXPORT
|
||||
|
||||
See L<Lemonldap::NG::Handler>
|
||||
|
||||
=head1 SEE ALSO
|
||||
|
||||
L<Lemonldap::NG::Handler>
|
||||
|
||||
=head1 AUTHOR
|
||||
|
||||
Clement Oudot, E<lt>clement@oodo.netE<gt>
|
||||
|
||||
=head1 COPYRIGHT AND LICENSE
|
||||
|
||||
Copyright (C) 201O by Clement Oudot
|
||||
|
||||
This library is free software; you can redistribute it and/or modify
|
||||
it under the same terms as Perl itself, either Perl version 5.10.0 or,
|
||||
at your option, any later version of Perl 5 you may have available.
|
||||
|
||||
=cut
|
|
@ -559,7 +559,7 @@ sub _compileRules {
|
|||
sub _conditionSub {
|
||||
my ( $self, $cond ) = splice @_;
|
||||
return sub { 1 }
|
||||
if ( $cond =~ /^(?:accept$|unprotect$|zimbra_preauth)/i );
|
||||
if ( $cond =~ /^(?:accept|unprotect)$/i );
|
||||
return sub { 0 }
|
||||
if ( $cond =~ /^(?:deny$|logout)/i );
|
||||
$cond =~ s/\$date/&POSIX::strftime("%Y%m%d%H%M%S",localtime())/e;
|
||||
|
|
|
@ -362,7 +362,7 @@ sub _conditionSub {
|
|||
my ( $self, $id, $cond ) = splice @_;
|
||||
my $h = $self->getApacheSession( $id, 1 );
|
||||
return sub { 1 }
|
||||
if ( $cond =~ /^(?:accept$|unprotect$|zimbra_preauth)/i );
|
||||
if ( $cond =~ /^(?:accept|unprotect)$/i );
|
||||
return sub { 0 }
|
||||
if ( !$h or $cond =~ /^(?:deny$|logout)/i );
|
||||
$cond =~ s/\$date/&POSIX::strftime("%Y%m%d%H%M%S",localtime())/e;
|
||||
|
|
Loading…
Reference in New Issue
Block a user