File: ServiceToken.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 (108 lines) | stat: -rw-r--r-- 3,309 bytes parent folder | download | duplicates (2)
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
107
108
package Lemonldap::NG::Handler::Lib::ServiceToken;

use strict;

our $VERSION = '2.19.0';

sub fetchId {
    my ( $class, $req ) = @_;
    my $token = $req->{env}->{HTTP_X_LLNG_TOKEN};
    return $class->Lemonldap::NG::Handler::Main::fetchId($req)
      unless ( $token =~ /\w+/ );
    $class->logger->debug("Found token: $token");

    # Decrypt token
    my $s = $class->tsv->{cipher}->decrypt($token);

# Token format:
# time:_session_id:vhost1:vhost2:serviceHeader1=value1:serviceHeader2=value2,...
    my ( $t, $_session_id, @vhosts ) = split /:/, $s;
    $class->logger->debug("Found epoch: $t");
    $class->logger->debug("Found _session_id: $_session_id");

    # Looking for service headers
    my $vhost = $class->resolveAlias($req);
    my ( %serviceHeaders, @vhostRegexp );
    @vhosts = grep {
        if (/^([\w\-]+)=(.+)$/) {
            $serviceHeaders{$1} = $2;
            $class->logger->debug("Found service header: $1 => $2");
            0;
        }
        elsif (m#^/(.+)?/$#) {
            push @vhostRegexp, qr/$1/;
            $class->logger->debug("Found VHost regexp: $1");
            0;
        }
        elsif (/^[\w.*%-]+$/) {
            $class->logger->debug("Found VHost: $_");
            1;
        }
        else {
            $class->logger->warn("Found a non valid VHost: $_");
            0;
        }
    } @vhosts;

    # $_session_id and at least one vhost or RegExp
    unless ( $_session_id and ( @vhosts or @vhostRegexp ) ) {
        $class->auditLog(
            $req,
            message => 'Bad service token',
            code    => "INVALID_SERVICE_TOKEN",
        );
        $class->logger->debug(
            $_session_id ? 'No VH or RegExp found' : 'No _session_id found' );
        return 0;
    }

    # Is vhost listed in token ?
    if ( grep { $_ eq $vhost } @vhosts ) {
        $class->logger->debug( "$vhost found in VHosts list: " . join ', ',
            @vhosts );
    }
    elsif ( grep { $vhost =~ $_ } @vhostRegexp ) {
        $class->logger->debug( "$vhost matches a VHost regexp: " . join ', ',
            @vhostRegexp );
    }
    else {
        $class->auditLog(
            $req,
            message => (
                "$vhost not allowed in token scope ("
                  . join( ', ', ( @vhostRegexp, @vhosts ) ) . ')'
            ),
            code        => "INVALID_SERVICE_TOKEN_SCOPE",
            vhostRegexp => \@vhostRegexp,
            vhosts      => \@vhosts,
        );
        return 0;
    }

    # Is token in good interval ?
    my $ttl =
      ( $class->tsv->{serviceTokenTTL}->{$vhost} > 0 )
      ? $class->tsv->{serviceTokenTTL}->{$vhost}
      : $class->tsv->{handlerServiceTokenTTL};
    my $now = time;
    unless ( $t <= $now and $t > $now - $ttl ) {
        $class->auditLog(
            $req,
            message => 'Expired service token',
            code    => "EXPIRED_SERVICE_TOKEN",
        );
        $class->logger->debug("VH: $vhost with ServiceTokenTTL: $ttl");
        $class->logger->debug("TokenTime: $t / Time: $now");
        return 0;
    }

    # Send service headers to protected application if exist
    if (%serviceHeaders) {
        $class->logger->info("Append service header(s)...");
        $class->set_header_in( $req, %serviceHeaders );
    }

    return $_session_id;
}

1;