File: ZimbraPreAuth.pm

package info (click to toggle)
lemonldap-ng 2.21.2%2Bds-1
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 28,024 kB
  • sloc: perl: 77,414; javascript: 25,284; xml: 6,473; makefile: 1,303; sh: 453; sql: 159; python: 53; php: 26
file content (106 lines) | stat: -rw-r--r-- 3,253 bytes parent folder | download | duplicates (3)
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
98
99
100
101
102
103
104
105
106
##@file
# Zimbra preauthentication

##@class
# Zimbra preauthentication
#
# It will build Zimbra preauth URL

package Lemonldap::NG::Handler::Lib::ZimbraPreAuth;

use strict;
use URI::Escape;
use Digest::HMAC_SHA1 qw(hmac_sha1_hex);

our $VERSION = '2.0.7';

# Overload main run method
sub run {
    my ( $class, $req )     = @_;
    my ( $ret,   $session ) = $class->Lemonldap::NG::Handler::Main::run($req);

    # Continue only if user is authorized
    return $ret unless ( $ret == $class->OK );

    # Get current URI
    my $uri = $req->{env}->{REQUEST_URI};

    # Get Zimbra parameters
    my $localConfig      = $class->localConfig;
    my $zimbraPreAuthKey = $localConfig->{zimbraPreAuthKey};
    my $zimbraAccountKey = $localConfig->{zimbraAccountKey} || 'uid';
    my $zimbraBy         = $localConfig->{zimbraBy}         || 'id';
    my $zimbraUrl        = $localConfig->{zimbraUrl}    || '/service/preauth';
    my $zimbraSsoUrl     = $localConfig->{zimbraSsoUrl} || '^/zimbrasso$';
    my $timeout          = $localConfig->{'timeout'}    || '0';

    # Remove trailing white-spaces
    $zimbraAccountKey =~ s/\s+$//;
    $zimbraBy         =~ s/\s+$//;
    $zimbraUrl        =~ s/\s+$//;
    $zimbraSsoUrl     =~ s/\s+$//;

    # Display found values in debug mode
    $class->logger->debug("zimbraPreAuthKey: $zimbraPreAuthKey");
    $class->logger->debug("zimbraAccountKey: $zimbraAccountKey");
    $class->logger->debug("zimbraBy: $zimbraBy");
    $class->logger->debug("zimbraUrl: $zimbraUrl");
    $class->logger->debug("zimbraSsoUrl: $zimbraSsoUrl");
    $class->logger->debug("timeout: $timeout");

    # Return if we are not on a Zimbra SSO URI
    return $class->OK unless ( $uri =~ $zimbraSsoUrl );

    # Check mandatory parameters
    unless ($zimbraPreAuthKey) {
        $class->logger->error("No Zimbra preauth key configured");
        return $class->SERVER_ERROR;
    }

    # Build URL
    my $zimbra_url =
      $class->_buildZimbraPreAuthUrl( $req, $zimbraPreAuthKey, $zimbraUrl,
        $class->data->{$zimbraAccountKey},
        $zimbraBy, $timeout );

    # Header location
    $class->set_header_out( $req, 'Location' => $zimbra_url );

    return $class->REDIRECT;
}

## @method private string _buildZimbraPreAuthUrl(string key, string url, string account, string by, int timeout)
# Build Zimbra PreAuth URL
# @param key PreAuthKey
# @param url URL
# @param account User account
# @param by Account type
# @param timeout Timout
# @return Zimbra PreAuth URL
sub _buildZimbraPreAuthUrl {
    my ( $class, $req, $key, $url, $account, $by, $timeout ) = @_;

    # Expiration time is calculated with _utime and timeout
    my $expires =
      $timeout ? ( $class->data->{_utime} + $timeout ) * 1000 : $timeout;

    # Timestamp
    my $timestamp = time() * 1000;

    # Compute preauth value
    my $computed_value =
      hmac_sha1_hex( "$account|$by|$expires|$timestamp", $key );

    $class->logger->debug(
        "Compute value $account|$by|$expires|$timestamp into $computed_value");

    # Build PreAuth URL
    my $zimbra_url =
"$url?account=$account&by=$by&timestamp=$timestamp&expires=$expires&preauth=$computed_value";

    $class->logger->debug("Build Zimbra URL: $zimbra_url");

    return $zimbra_url;
}

1;