1
|
#
|
2
|
# Module to generate authentication tickets for mod_auth_tkt apache module.
|
3
|
#
|
4
|
|
5
|
package Apache::AuthTkt;
|
6
|
|
7
|
use 5.005;
|
8
|
use Carp;
|
9
|
use MIME::Base64;
|
10
|
#use strict;
|
11
|
use vars qw($VERSION $AUTOLOAD);
|
12
|
|
13
|
$VERSION = 2.1;
|
14
|
|
15
|
my $me = 'Apache::AuthTkt';
|
16
|
my $PREFIX = 'TKTAuth';
|
17
|
my %DEFAULTS = (
|
18
|
digest_type => 'MD5',
|
19
|
cookie_name => 'auth_tkt',
|
20
|
back_arg_name => 'back',
|
21
|
timeout => 2 * 60 * 60,
|
22
|
timeout_min => 2 * 60,
|
23
|
timeout_refresh => 0.5,
|
24
|
guest_login => 0,
|
25
|
guest_user => 'guest',
|
26
|
ignore_ip => 0,
|
27
|
require_ssl => 0,
|
28
|
cookie_secure => 0,
|
29
|
);
|
30
|
my %BOOLEAN = map { $_ => 1 } qw(
|
31
|
TKTAuthGuestLogin TKTAuthIgnoreIP TKTAuthRequireSSL TKTAuthCookieSecure
|
32
|
);
|
33
|
# Default TKTAuthDomain to host part of HTTP_HOST, or SERVER_NAME
|
34
|
($DEFAULTS{TKTAuthDomain}) = split /:/, $ENV{HTTP_HOST} || '';
|
35
|
$DEFAULTS{TKTAuthDomain} ||= $ENV{SERVER_NAME};
|
36
|
my %ATTR = map { $_ => 1 } qw(
|
37
|
conf secret secret_old digest_type
|
38
|
cookie_name back_cookie_name back_arg_name domain cookie_expires
|
39
|
login_url timeout_url post_timeout_url unauth_url
|
40
|
timeout timeout_min timeout_refresh token debug
|
41
|
guest_login guest_user ignore_ip require_ssl cookie_secure
|
42
|
);
|
43
|
#my %TICKET_ARGS = map { $_ => 1 }
|
44
|
|
45
|
# digest_type => [ module, function ]
|
46
|
my %DIGEST_TYPE = (
|
47
|
MD5 => [ 'Digest::MD5', 'md5_hex' ],
|
48
|
SHA256 => [ 'Digest::SHA', 'sha256_hex' ],
|
49
|
SHA512 => [ 'Digest::SHA', 'sha512_hex' ],
|
50
|
);
|
51
|
|
52
|
# Helper routine to convert time units into seconds
|
53
|
my %units = (
|
54
|
s => 1,
|
55
|
m => 60,
|
56
|
h => 3600,
|
57
|
d => 86400,
|
58
|
w => 7 * 86400,
|
59
|
M => 30 * 86400,
|
60
|
y => 365 * 86400,
|
61
|
);
|
62
|
sub convert_time_seconds
|
63
|
{
|
64
|
my $self = shift;
|
65
|
local $_ = shift;
|
66
|
return $1 if m/^\s*(\d+)\s*$/;
|
67
|
my $sec = 0;
|
68
|
while (m/\G(\d+)([shdwmMy])\b\s*/gc) {
|
69
|
my $amt = $1;
|
70
|
my $unit = $2 || 's';
|
71
|
$sec += $amt * $units{$unit};
|
72
|
# print STDERR "$amt : $unit : $sec\n";
|
73
|
}
|
74
|
return $sec;
|
75
|
}
|
76
|
|
77
|
# Parse (simplistically) the given apache config file for TKTAuth directives
|
78
|
sub parse_conf
|
79
|
{
|
80
|
my $self = shift;
|
81
|
my ($conf) = @_;
|
82
|
|
83
|
my %seen = ();
|
84
|
open CF, "<$conf" or
|
85
|
die "[$me] open of config file '$conf' failed: $!";
|
86
|
|
87
|
# Take settings from first instance of each TKTAuth directive found
|
88
|
local $/ = "\n";
|
89
|
while (<CF>) {
|
90
|
if (m/^\s*(${PREFIX}\w+)\s+(.*)/) {
|
91
|
$seen{$1} = $2 unless exists $seen{$1};
|
92
|
}
|
93
|
}
|
94
|
|
95
|
close CF;
|
96
|
die "[$me] TKTAuthSecret directive not found in config file '$conf'"
|
97
|
unless $seen{TKTAuthSecret};
|
98
|
|
99
|
# Set directives as $self attributes
|
100
|
my %merge = ( %seen );
|
101
|
for my $directive (keys %merge) {
|
102
|
local $_ = $directive;
|
103
|
s/^TKTAuth(\w)/\L$1/;
|
104
|
s/([a-z])([A-Z]+)/\L$1_$2/g;
|
105
|
$merge{$directive} =~ s/^"([^"]+)"$/$1/ if $merge{$directive};
|
106
|
if ($BOOLEAN{$directive}) {
|
107
|
$merge{$directive} = 0
|
108
|
if $merge{$directive} =~ m/^(off|no|false)$/i;
|
109
|
$merge{$directive} = 1
|
110
|
if $merge{$directive} =~ m/^(on|yes|true)$/i;
|
111
|
}
|
112
|
elsif (defined $merge{$directive}) {
|
113
|
$merge{$directive} =~ s/^\s+//;
|
114
|
$merge{$directive} =~ s/\s+$//;
|
115
|
}
|
116
|
if ($directive eq 'TKTAuthCookieExpires' || $directive eq 'TKTAuthTimeout') {
|
117
|
$self->{$_} = $self->convert_time_seconds($merge{$directive});
|
118
|
}
|
119
|
# Don't allow TKTAuthDebug to turn on debugging here
|
120
|
elsif ($directive ne 'TKTAuthDebug') {
|
121
|
$self->{$_} = $merge{$directive};
|
122
|
}
|
123
|
}
|
124
|
}
|
125
|
|
126
|
# Process constructor args
|
127
|
sub init
|
128
|
{
|
129
|
my $self = shift;
|
130
|
my %arg = @_;
|
131
|
|
132
|
# Check for invalid args
|
133
|
for (keys %arg) {
|
134
|
croak "[$me] invalid argument to constructor: $_" unless exists $ATTR{$_};
|
135
|
}
|
136
|
|
137
|
# Parse config file if set
|
138
|
if ($arg{conf}) {
|
139
|
$self->parse_conf($arg{conf});
|
140
|
}
|
141
|
|
142
|
# Store/override from given args
|
143
|
$self->{$_} = $arg{$_} foreach keys %arg;
|
144
|
|
145
|
croak "[$me] bad constructor - 'secret' or 'conf' argument required"
|
146
|
unless $self->{conf} || $self->{secret};
|
147
|
croak "[$me] invalid digest_type '" . $self->{digest_type} . "'"
|
148
|
unless $DIGEST_TYPE{ $self->{digest_type } };
|
149
|
|
150
|
$self;
|
151
|
}
|
152
|
|
153
|
# Constructor
|
154
|
sub new
|
155
|
{
|
156
|
my $class = shift;
|
157
|
my $self = { %DEFAULTS };
|
158
|
bless $self, $class;
|
159
|
$self->init(@_);
|
160
|
}
|
161
|
|
162
|
# Setup autoload accessors/mutators
|
163
|
sub AUTOLOAD {
|
164
|
my $self = shift;
|
165
|
my $attr = $AUTOLOAD;
|
166
|
$attr =~ s/.*:://;
|
167
|
die qq(Can't locate object method "$attr" via package "$self")
|
168
|
unless $ATTR{$attr};
|
169
|
@_ and $self->{$attr} = $_[0];
|
170
|
return $self->{$attr};
|
171
|
}
|
172
|
|
173
|
sub DESTROY {}
|
174
|
|
175
|
sub errstr
|
176
|
{
|
177
|
my $self = shift;
|
178
|
$@[0] and $self->{errstr} = join ' ', @_;
|
179
|
$self->{errstr};
|
180
|
}
|
181
|
|
182
|
# Return a mod_auth_tkt ticket containing the given user details
|
183
|
sub ticket
|
184
|
{
|
185
|
my $self = shift;
|
186
|
my %DEFAULTS = (
|
187
|
base64 => 1,
|
188
|
data => '',
|
189
|
tokens => '',
|
190
|
);
|
191
|
my %arg = ( %DEFAULTS, %$self, @_ );
|
192
|
$arg{uid} = $self->guest_user unless exists $arg{uid};
|
193
|
$arg{ip_addr} = $arg{ignore_ip} ? '0.0.0.0' : $ENV{REMOTE_ADDR}
|
194
|
unless exists $arg{ip_addr};
|
195
|
# 0 or undef ip_addr treated as 0.0.0.0
|
196
|
$arg{ip_addr} ||= '0.0.0.0';
|
197
|
|
198
|
# Data cleanups
|
199
|
if ($arg{tokens}) {
|
200
|
$arg{tokens} =~ s/\s+,/,/g;
|
201
|
$arg{tokens} =~ s/,\s+/,/g;
|
202
|
}
|
203
|
|
204
|
# Data checks
|
205
|
if ($arg{ip_addr} !~ m/^([12]?[0-9]?[0-9]\.){3}[12]?[0-9]?[0-9]$/) {
|
206
|
$self->errstr("invalid ip_addr '$arg{ip_addr}'");
|
207
|
return undef;
|
208
|
}
|
209
|
if ($arg{tokens} =~ m/[!\s]/) {
|
210
|
$self->errstr("invalid chars in tokens '$arg{tokens}'");
|
211
|
return undef;
|
212
|
}
|
213
|
|
214
|
# Calculate the hash for the ticket
|
215
|
my $ts = $arg{ts} || time;
|
216
|
my $digest = $self->_get_digest($ts, $arg{ip_addr}, $arg{uid}, $arg{tokens},
|
217
|
$arg{data}, $arg{debug});
|
218
|
|
219
|
# Construct the ticket itself
|
220
|
my $ticket = sprintf "%s%08x%s!", $digest, $ts, $arg{uid};
|
221
|
$ticket .= $arg{tokens} . '!' if $arg{tokens};
|
222
|
$ticket .= $arg{data};
|
223
|
|
224
|
return $arg{base64} ? encode_base64($ticket, '') : $ticket;
|
225
|
}
|
226
|
|
227
|
sub _get_digest_function
|
228
|
{
|
229
|
my $self = shift;
|
230
|
|
231
|
die "Invalid digest_type '" . $self->digest_type . "'\n"
|
232
|
unless $DIGEST_TYPE{ $self->digest_type };
|
233
|
|
234
|
my ($module, $func) = @{ $DIGEST_TYPE{ $self->digest_type } };
|
235
|
eval "require $module";
|
236
|
return eval "\\&${module}::$func";
|
237
|
}
|
238
|
|
239
|
sub _get_digest
|
240
|
{
|
241
|
my ($self, $ts, $ip_addr, $uid, $tokens, $data, $debug) = @_;
|
242
|
my @ip = split /\./, $ip_addr;
|
243
|
my @ts = ( (($ts & 0xff000000) >> 24),
|
244
|
(($ts & 0xff0000) >> 16),
|
245
|
(($ts & 0xff00) >> 8),
|
246
|
(($ts & 0xff)) );
|
247
|
my $ipts = pack("C8", @ip, @ts);
|
248
|
my $raw = $ipts . $self->secret . $uid . "\0" . $tokens . "\0" . $data;
|
249
|
my $digest_function = $self->_get_digest_function;
|
250
|
my $digest0 = $digest_function->($raw);
|
251
|
my $digest = $digest_function->($digest0 . $self->secret);
|
252
|
|
253
|
if ($debug) {
|
254
|
print STDERR "ts: $ts\nip_addr: $ip_addr\nuid: $uid\ntokens: $tokens\ndata: $data\n";
|
255
|
print STDERR "secret: " . $self->secret . "\n";
|
256
|
print STDERR "raw: '$raw'\n";
|
257
|
my $len = length($raw);
|
258
|
print STDERR "digest0: $digest0 (input length $len)\n";
|
259
|
print STDERR "digest: $digest\n";
|
260
|
}
|
261
|
|
262
|
return $digest;
|
263
|
}
|
264
|
|
265
|
# Return a cookie containing a mod_auth_tkt ticket
|
266
|
sub cookie
|
267
|
{
|
268
|
my $self = shift;
|
269
|
my %DEFAULTS = (
|
270
|
cookie_name => 'auth_tkt',
|
271
|
cookie_path => '/',
|
272
|
);
|
273
|
my %arg = ( %DEFAULTS, %$self, @_ );
|
274
|
$arg{cookie_domain} ||= $self->domain;
|
275
|
|
276
|
# Get ticket, forcing base64 for cookies
|
277
|
my $ticket = $self->ticket(@_, base64 => 1) or return;
|
278
|
|
279
|
my $cookie_fmt = "%s=%s%s%s%s";
|
280
|
my $path_elt = "; path=$arg{cookie_path}";
|
281
|
my $domain_elt = $arg{cookie_domain} ? "; domain=$arg{cookie_domain}" : '';
|
282
|
my $secure_elt = $arg{cookie_secure} ? "; secure" : '';
|
283
|
return sprintf $cookie_fmt,
|
284
|
$arg{cookie_name}, $ticket, $domain_elt, $path_elt, $secure_elt;
|
285
|
}
|
286
|
|
287
|
# Returns a hashref representing the original ticket components
|
288
|
# Returns undef if there were any errors
|
289
|
sub validate_ticket
|
290
|
{
|
291
|
my $self = shift;
|
292
|
my $ticket = shift || croak "No ticket passed to validate_ticket";
|
293
|
my %arg = ( %$self, @_ );
|
294
|
|
295
|
$arg{ip_addr} = $arg{ignore_ip} ? '0.0.0.0' : $ENV{REMOTE_ADDR}
|
296
|
unless exists $arg{ip_addr};
|
297
|
# 0 or undef ip_addr treated as 0.0.0.0
|
298
|
$arg{ip_addr} ||= '0.0.0.0';
|
299
|
|
300
|
# Parse ticket
|
301
|
my $info = $self->parse_ticket($ticket);
|
302
|
|
303
|
# Validate digest
|
304
|
my $expected_digest = $self->_get_digest(
|
305
|
$info->{ts}, $arg{ip_addr}, $info->{uid},
|
306
|
$info->{tokens}, $info->{data});
|
307
|
|
308
|
return $info if $expected_digest eq $info->{digest};
|
309
|
return undef;
|
310
|
}
|
311
|
|
312
|
sub parse_ticket
|
313
|
{
|
314
|
my $self = shift;
|
315
|
my $ticket = shift or croak "No ticket passed to parse_ticket";
|
316
|
my $parts = {};
|
317
|
|
318
|
# Strip possible quotes
|
319
|
$ticket =~ s,^"|"$,,g;
|
320
|
|
321
|
return if length($ticket) < 40;
|
322
|
|
323
|
# Assume $ticket is not URL-escaped but may be base64-escaped
|
324
|
my $raw = $ticket =~ m/!/ ? $ticket : decode_base64($ticket);
|
325
|
|
326
|
# If $raw still doesn't have ! then it is bogus
|
327
|
return if $raw !~ m/!/;
|
328
|
|
329
|
# Deconstruct
|
330
|
my ($digest,$ts,$uid,$extra) = ($raw =~ m/^(.{32})(.{8})(.+?)!(.*)$/);
|
331
|
$parts->{digest} = $digest;
|
332
|
$parts->{ts} = hex($ts);
|
333
|
$parts->{uid} = $uid;
|
334
|
$parts->{tokens} = '';
|
335
|
$parts->{data} = '';
|
336
|
|
337
|
# Tokens and data if present
|
338
|
if (defined $extra) {
|
339
|
if ($extra =~ m/!/) {
|
340
|
($parts->{tokens},$parts->{data}) = split m/!/, $extra, 2;
|
341
|
}
|
342
|
else {
|
343
|
$parts->{data} = $extra;
|
344
|
}
|
345
|
}
|
346
|
return $parts;
|
347
|
}
|
348
|
|
349
|
# Alias for compatibility with Jose/Ton's original patch
|
350
|
*valid_ticket = \&validate_ticket;
|
351
|
|
352
|
1;
|
353
|
|
354
|
__END__
|
355
|
|
356
|
=head1 NAME
|
357
|
|
358
|
Apache::AuthTkt - module to generate authentication tickets for
|
359
|
mod_auth_tkt apache module.
|
360
|
|
361
|
|
362
|
=head1 SYNOPSIS
|
363
|
|
364
|
# Constructor - either (preferred):
|
365
|
$at = Apache::AuthTkt->new(
|
366
|
conf => '/etc/httpd/conf.d/auth_tkt.conf',
|
367
|
);
|
368
|
# OR:
|
369
|
$at = Apache::AuthTkt->new(
|
370
|
secret => '818f9c9d-91ed-4b74-9f48-ff99cfe00a0e',
|
371
|
digest_type => 'MD5',
|
372
|
);
|
373
|
|
374
|
# Generate ticket
|
375
|
$ticket = $at->ticket(uid => $username, ip_addr => $ip_addr);
|
376
|
|
377
|
# Or generate cookie containing ticket
|
378
|
$cookie = $at->cookie(
|
379
|
uid => $username,
|
380
|
cookie_name => 'auth_tkt',
|
381
|
cookie_domain => 'www.openfusion.com.au',
|
382
|
);
|
383
|
|
384
|
# Access the shared secret
|
385
|
$secret = $at->secret();
|
386
|
# If using the 'conf' constructor above, all other TKTAuth attributes
|
387
|
# are also available e.g.:
|
388
|
print $at->cookie_name(), $at->ignore_ip(), $at->request_ssl();
|
389
|
|
390
|
# Report error string
|
391
|
print $at->errstr;
|
392
|
|
393
|
|
394
|
=head1 INTRODUCTION
|
395
|
|
396
|
Apache::AuthTkt is a module for generating and validating
|
397
|
authentication tickets used with the 'mod_auth_tkt' apache module.
|
398
|
Tickets are typically generated by a login web page of some kind
|
399
|
when a user has been authenticated. The ticket contains a username/uid
|
400
|
for the authenticated user, and often also the IP address they
|
401
|
authenticated from, a set of authorisation tokens, and any other user
|
402
|
data required. The ticket also includes an MD5 hash of all the included
|
403
|
user data plus a shared secret, so that tickets can be validated by
|
404
|
mod_auth_tkt without requiring access to the user repository.
|
405
|
|
406
|
See http://www.openfusion.com.au/labs/mod_auth_tkt for mod_auth_tkt
|
407
|
itself.
|
408
|
|
409
|
|
410
|
=head1 DESCRIPTION
|
411
|
|
412
|
=head2 CONSTRUCTOR
|
413
|
|
414
|
An Apache::AuthTkt object is created via a standard constructor
|
415
|
with named arguments. The preferred form is to point the constructor
|
416
|
to the apache config file containing the mod_auth_tkt TKTAuthSecret
|
417
|
directive, from which Apache::AuthTkt will parse the shared secret
|
418
|
it needs, as well as any additional TKTAuth* directives it finds:
|
419
|
|
420
|
$at = Apache::Tkt->new(
|
421
|
conf => '/etc/httpd/conf/auth_tkt.conf',
|
422
|
);
|
423
|
|
424
|
Alternatively, you can pass the mod_auth_tkt shared secret (the
|
425
|
TKTAuthSecret value) and the digest_type to use (default is 'MD5')
|
426
|
explicitly to the constructor:
|
427
|
|
428
|
$at = Apache::AuthTkt->new(
|
429
|
secret => '818f9c9d-91ed-4b74-9f48-ff99cfe00a0e',
|
430
|
digest_type => 'SHA256',
|
431
|
);
|
432
|
|
433
|
=head2 ACCESSORS
|
434
|
|
435
|
If the 'conf' form of the constructor is used, Apache::AuthTkt parses
|
436
|
all additional TKTAuth* directives it finds there and stores them in
|
437
|
additional internal attributes. Those values are available via
|
438
|
accessors named after the relevant TKTAuth directive (with the 'TKTAuth'
|
439
|
prefix dropped and converted to lowercase underscore format) i.e.
|
440
|
|
441
|
$at->secret()
|
442
|
$at->secret_old()
|
443
|
$at->digest_type()
|
444
|
$at->cookie_name()
|
445
|
$at->back_cookie_name()
|
446
|
$at->back_arg_name()
|
447
|
$at->domain()
|
448
|
$at->cookie_expires()
|
449
|
$at->login_url()
|
450
|
$at->timeout_url()
|
451
|
$at->unauth_url()
|
452
|
$at->timeout()
|
453
|
$at->timeout_refresh()
|
454
|
$at->token ()
|
455
|
$at->guest_login()
|
456
|
$at->ignore_ip()
|
457
|
$at->require_ssl()
|
458
|
|
459
|
|
460
|
=head2 TICKET GENERATION
|
461
|
|
462
|
Tickets are generated using the ticket() method with named parameters:
|
463
|
|
464
|
# Generate ticket
|
465
|
$ticket = $at->ticket(uid => $username);
|
466
|
|
467
|
Ticket returns undef on error, with error information available via
|
468
|
the errstr() method:
|
469
|
|
470
|
$ticket = $at->ticket or die $at->errstr;
|
471
|
|
472
|
ticket() accepts the following arguments, all optional:
|
473
|
|
474
|
=over 4
|
475
|
|
476
|
=item uid
|
477
|
|
478
|
uid, username, or other user identifier for this ticket. There is no
|
479
|
requirement that this be unique per-user. Default: 'guest'.
|
480
|
|
481
|
=item ip_addr
|
482
|
|
483
|
IP address associated with this ticket. Default: if $at->ignore_ip
|
484
|
is true, then '0.0.0.0', otherwise $ENV{REMOTE_ADDR};
|
485
|
|
486
|
=item tokens
|
487
|
|
488
|
A comma-separated list of tokens associated with this user. Typically
|
489
|
only used if you are using the mod_auth_tkt TKTAuthToken directive.
|
490
|
Default: none.
|
491
|
|
492
|
=item data
|
493
|
|
494
|
Arbitrary user data to be stored for this ticket. This data is included
|
495
|
in the MD5 hash check. Default: none.
|
496
|
|
497
|
=item base64
|
498
|
|
499
|
Flag used to indicate whether to base64-encode the ticket. Default: 1.
|
500
|
|
501
|
=item ts
|
502
|
|
503
|
Explicitly set the timestamp to use for this ticket. Only for testing!
|
504
|
|
505
|
=back
|
506
|
|
507
|
|
508
|
As an alternative to ticket(), the cookie() method can be used to
|
509
|
return the generated ticket in cookie format. cookie() returns undef
|
510
|
on error, with error information available via the errstr() method:
|
511
|
|
512
|
$cookie = $at->cookie or die $at->errstr;
|
513
|
|
514
|
cookie() supports all the same arguments as ticket(), plus the
|
515
|
following:
|
516
|
|
517
|
=over 4
|
518
|
|
519
|
=item cookie_name
|
520
|
|
521
|
Cookie name. Should match the TKTAuthCookieName directive, if you're
|
522
|
using it. Default: $at->cookie_name, or 'auth_tkt'.
|
523
|
|
524
|
=item cookie_domain
|
525
|
|
526
|
Cookie domain. Should match the TKTAuthDomain directive, if you're
|
527
|
using it. Default: $at->domain.
|
528
|
|
529
|
=item cookie_path
|
530
|
|
531
|
Cookie path. Default: '/'.
|
532
|
|
533
|
=item cookie_secure
|
534
|
|
535
|
Flag whether to set the 'secure' cookie flag, so that the cookie is
|
536
|
returned only in HTTPS contexts. Default: $at->require_ssl, or 0.
|
537
|
|
538
|
=back
|
539
|
|
540
|
=head2 TICKET PARSING AND VALIDATION
|
541
|
|
542
|
You may parse and validate existing tickets with the validate_ticket()
|
543
|
method. It takes as its first parameter the ticket to be validated, and
|
544
|
then an optional list of named parameter overrides
|
545
|
(e.g. ip_addr => 'x.x.x.x'). If the ticket is valid, validate_ticket
|
546
|
returns a hashref with the following key/value pairs:
|
547
|
|
548
|
=over 4
|
549
|
|
550
|
=item digest
|
551
|
|
552
|
=item ts
|
553
|
|
554
|
=item uid
|
555
|
|
556
|
=item tokens
|
557
|
|
558
|
=item data
|
559
|
|
560
|
=back
|
561
|
|
562
|
validate_ticket() will return undef if any errors with the ticket value
|
563
|
are encountered.
|
564
|
|
565
|
The validate_ticket() method algorithm is analogous to the function with
|
566
|
the same name in the mod_auth_tkt C module.
|
567
|
|
568
|
There is also a parse_ticket() method available that parses the ticket
|
569
|
without running it through the validation phase, and returns the same
|
570
|
data as validate_ticket(). This is only safe to use where you are certain
|
571
|
that the ticket has been validated elsewhere. In general it's considerably
|
572
|
safer to just use validate_ticket.
|
573
|
|
574
|
|
575
|
=head2 DIGEST TYPES
|
576
|
|
577
|
As of version 2.1.0, mod_auth_tkt supports multiple digest types. The
|
578
|
following digest_types are currently supported:
|
579
|
|
580
|
=over 4
|
581
|
|
582
|
=item MD5
|
583
|
|
584
|
The current default, for backwards compatibility. Requires the Digest::MD5
|
585
|
perl module.
|
586
|
|
587
|
=item SHA256
|
588
|
|
589
|
Requires the Digest::SHA perl module.
|
590
|
|
591
|
=back
|
592
|
|
593
|
These can be set either via your config (the TKTAuthDigestType directive)
|
594
|
or by passing a 'digest_type' parameter to the AuthTkt constructor.
|
595
|
|
596
|
|
597
|
=head1 AUTHOR
|
598
|
|
599
|
Gavin Carr <gavin@openfusion.com.au>
|
600
|
|
601
|
Contributors:
|
602
|
|
603
|
Peter Karman <peter@peknet.com>
|
604
|
|
605
|
Ton Voon <ton.voon@altinity.com>
|
606
|
|
607
|
Jose Luis Martinez <jlmartinez@capside.com>
|
608
|
|
609
|
=head1 COPYRIGHT
|
610
|
|
611
|
Copyright 2001-2009 Gavin Carr and contributors.
|
612
|
|
613
|
This program is free software. You may copy or redistribute it under the
|
614
|
same terms as perl itself.
|
615
|
|
616
|
=cut
|
617
|
|
618
|
|
619
|
# vim:sw=4
|