line |
stmt |
bran |
cond |
sub |
pod |
time |
code |
1
|
|
|
|
|
|
|
#!/usr/bin/perl |
2
|
1
|
|
|
1
|
|
23456
|
use strict; |
|
1
|
|
|
|
|
3
|
|
|
1
|
|
|
|
|
38
|
|
3
|
1
|
|
|
1
|
|
5
|
use warnings; |
|
1
|
|
|
|
|
2
|
|
|
1
|
|
|
|
|
55
|
|
4
|
|
|
|
|
|
|
|
5
|
|
|
|
|
|
|
package Authen::Krb5::Effortless; |
6
|
|
|
|
|
|
|
our $VERSION = "0.02"; |
7
|
1
|
|
|
1
|
|
7
|
use Carp; |
|
1
|
|
|
|
|
6
|
|
|
1
|
|
|
|
|
82
|
|
8
|
1
|
|
|
1
|
|
773
|
use parent qw(Authen::Krb5); |
|
1
|
|
|
|
|
319
|
|
|
1
|
|
|
|
|
6
|
|
9
|
|
|
|
|
|
|
|
10
|
|
|
|
|
|
|
sub new { |
11
|
|
|
|
|
|
|
my $class = shift(); |
12
|
|
|
|
|
|
|
my $self = {}; |
13
|
|
|
|
|
|
|
my $a = Authen::Krb5::init_context(); # initialize module |
14
|
|
|
|
|
|
|
if ( !$a ) { confess( "Unable to initialize Authen::Krb5 module" ); } |
15
|
|
|
|
|
|
|
bless( $self, $class ); |
16
|
|
|
|
|
|
|
return $self; |
17
|
|
|
|
|
|
|
} |
18
|
|
|
|
|
|
|
|
19
|
|
|
|
|
|
|
sub read_cache { |
20
|
|
|
|
|
|
|
my $self = shift(); |
21
|
|
|
|
|
|
|
my ( $cc, $cache_pointer, $cache_object ); |
22
|
|
|
|
|
|
|
$cc = Authen::Krb5::cc_default(); # load krb5 cache into mem |
23
|
|
|
|
|
|
|
$cache_pointer = $cc->start_seq_get(); # create a cache pointer |
24
|
|
|
|
|
|
|
if ( $cache_pointer ) { |
25
|
|
|
|
|
|
|
$cache_object = $cc->next_cred( $cache_pointer ); # fetch copy of object from cache |
26
|
|
|
|
|
|
|
$self->{'cache_present'} = 1; # flag to show cache is found |
27
|
|
|
|
|
|
|
$self->{'starttime'} = $cache_object->starttime(); # start time of credential |
28
|
|
|
|
|
|
|
$self->{'authtime'} = $cache_object->authtime(); |
29
|
|
|
|
|
|
|
$self->{'endtime'} = $cache_object->endtime(); |
30
|
|
|
|
|
|
|
$self->{'principal'} = $cache_object->client(); # prints principal name |
31
|
|
|
|
|
|
|
$cc->end_seq_get( $cache_pointer ); # destroy pointer |
32
|
|
|
|
|
|
|
} else { |
33
|
|
|
|
|
|
|
$self->{'cache_present'} = 0; # cache not found |
34
|
|
|
|
|
|
|
} |
35
|
|
|
|
|
|
|
return $self; |
36
|
|
|
|
|
|
|
} |
37
|
|
|
|
|
|
|
|
38
|
|
|
|
|
|
|
sub clear_cache { |
39
|
|
|
|
|
|
|
my $self = shift(); # clear cache if it exists |
40
|
|
|
|
|
|
|
my ( $cc ); |
41
|
|
|
|
|
|
|
$cc = Authen::Krb5::cc_default() or confess( "KRB5 Cache error:", Authen::Krb5::error() ); |
42
|
|
|
|
|
|
|
if ( $cc ) { |
43
|
|
|
|
|
|
|
$cc->destroy() or carp( "KRB5 Cache warn: ", Authen::Krb5::error() ); |
44
|
|
|
|
|
|
|
} |
45
|
|
|
|
|
|
|
|
46
|
|
|
|
|
|
|
return "True"; |
47
|
|
|
|
|
|
|
|
48
|
|
|
|
|
|
|
} |
49
|
|
|
|
|
|
|
|
50
|
|
|
|
|
|
|
sub fetch_TGT_KEYTAB { |
51
|
|
|
|
|
|
|
my $self = shift(); |
52
|
|
|
|
|
|
|
my $keytab = shift(); |
53
|
|
|
|
|
|
|
my $username = shift(); |
54
|
|
|
|
|
|
|
my ( $TGT, $cc, $principal ); |
55
|
|
|
|
|
|
|
$keytab = Authen::Krb5::kt_resolve( $keytab ); # load keytab into mem |
56
|
|
|
|
|
|
|
if ( !$keytab ) { croak( "KRB5 Keytab error: ", Authen::Krb5::error() ); } |
57
|
|
|
|
|
|
|
|
58
|
|
|
|
|
|
|
$cc = Authen::Krb5::cc_default(); # initialize default cache |
59
|
|
|
|
|
|
|
if ( !$cc ) { croak( "KRB5 Cache error: ", Authen::Krb5::error() ); } |
60
|
|
|
|
|
|
|
|
61
|
|
|
|
|
|
|
$principal = Authen::Krb5::parse_name( $username ); # initialize principal name |
62
|
|
|
|
|
|
|
if ( !$principal ) { croak( "KRB5 Principal error: ", Authen::Krb5::error() ); } |
63
|
|
|
|
|
|
|
|
64
|
|
|
|
|
|
|
$TGT = Authen::Krb5::get_init_creds_keytab( $principal, $keytab ); # Fetch TGT |
65
|
|
|
|
|
|
|
if ( !$TGT ) { croak( "KRB5 TGT error: ", Authen::Krb5::error() ); } |
66
|
|
|
|
|
|
|
|
67
|
|
|
|
|
|
|
$cc->initialize( $principal ); # store TGT |
68
|
|
|
|
|
|
|
Authen::Krb5::Ccache::store_cred( $cc, $TGT ); |
69
|
|
|
|
|
|
|
return "True"; |
70
|
|
|
|
|
|
|
} |
71
|
|
|
|
|
|
|
|
72
|
|
|
|
|
|
|
sub fetch_TGT_PW { |
73
|
|
|
|
|
|
|
my $self = shift(); |
74
|
|
|
|
|
|
|
my $pw = shift(); |
75
|
|
|
|
|
|
|
my $username = shift(); |
76
|
|
|
|
|
|
|
my ( $TGT, $cc, $principal ); |
77
|
|
|
|
|
|
|
|
78
|
|
|
|
|
|
|
$cc = Authen::Krb5::cc_default(); # initialize default cache |
79
|
|
|
|
|
|
|
if ( !$cc ) { croak( "KRB5 Cache error: ", Authen::Krb5::error() ); } |
80
|
|
|
|
|
|
|
|
81
|
|
|
|
|
|
|
$principal = Authen::Krb5::parse_name( $username ); # initialize principal name |
82
|
|
|
|
|
|
|
if ( !$principal ) { croak( "KRB5 Principal error: ", Authen::Krb5::error() ); } |
83
|
|
|
|
|
|
|
|
84
|
|
|
|
|
|
|
$TGT = Authen::Krb5::get_init_creds_password( $principal, $pw ); # Fetch TGT |
85
|
|
|
|
|
|
|
if ( !$TGT ) { croak( "KRB5 TGT error: ", Authen::Krb5::error() ); } |
86
|
|
|
|
|
|
|
|
87
|
|
|
|
|
|
|
# store TGT |
88
|
|
|
|
|
|
|
$cc->initialize( $principal ); |
89
|
|
|
|
|
|
|
Authen::Krb5::Ccache::store_cred( $cc, $TGT ); |
90
|
|
|
|
|
|
|
return "True"; |
91
|
|
|
|
|
|
|
} |
92
|
|
|
|
|
|
|
|
93
|
|
|
|
|
|
|
return 1; |
94
|
|
|
|
|
|
|
|
95
|
|
|
|
|
|
|
=pod |
96
|
|
|
|
|
|
|
|
97
|
|
|
|
|
|
|
=head1 NAME |
98
|
|
|
|
|
|
|
|
99
|
|
|
|
|
|
|
Authen::Krb5::Effortless - This module is a subclass to Authen::Krb5, adding 'Effortless' ways to authenticate against a Kerberos Domain Controller. |
100
|
|
|
|
|
|
|
|
101
|
|
|
|
|
|
|
=head1 VERSION |
102
|
|
|
|
|
|
|
|
103
|
|
|
|
|
|
|
Version 0.02 |
104
|
|
|
|
|
|
|
|
105
|
|
|
|
|
|
|
=cut |
106
|
|
|
|
|
|
|
|
107
|
|
|
|
|
|
|
=head1 Description |
108
|
|
|
|
|
|
|
|
109
|
|
|
|
|
|
|
Authen::Krb5::Effortless is more then a 'Simple' module, as it supports both pass-phrase and key-tab based authorization. |
110
|
|
|
|
|
|
|
|
111
|
|
|
|
|
|
|
=head1 Methods |
112
|
|
|
|
|
|
|
|
113
|
|
|
|
|
|
|
=over 3 |
114
|
|
|
|
|
|
|
|
115
|
|
|
|
|
|
|
=item new() - Initializes Authen::Krb5 and returns a Authen::Krb5::Effortless object. |
116
|
|
|
|
|
|
|
|
117
|
|
|
|
|
|
|
=item fetch_TGT_KEYTAB() - Uses a keytab file to get a Kerberos credential. |
118
|
|
|
|
|
|
|
|
119
|
|
|
|
|
|
|
=item fetch_TGT_PW() - Will use a password to get and cache a Kerberos credential. |
120
|
|
|
|
|
|
|
|
121
|
|
|
|
|
|
|
=item clear_cache() - Will clear your local cache of all stored principals. |
122
|
|
|
|
|
|
|
|
123
|
|
|
|
|
|
|
=item read_cache() - Will read your Kerberos cache and return the following values from the cache: |
124
|
|
|
|
|
|
|
|
125
|
|
|
|
|
|
|
=over 6 |
126
|
|
|
|
|
|
|
|
127
|
|
|
|
|
|
|
=item cache_present: returns 0 or 1 if the cache is present |
128
|
|
|
|
|
|
|
|
129
|
|
|
|
|
|
|
=item starttime: epoch time when ticket is good from |
130
|
|
|
|
|
|
|
|
131
|
|
|
|
|
|
|
=item authtime: epoch time when authentication occured |
132
|
|
|
|
|
|
|
|
133
|
|
|
|
|
|
|
=item endtime: epoch time when the ticket expires |
134
|
|
|
|
|
|
|
|
135
|
|
|
|
|
|
|
=item principal: name of the principal contained in the cache |
136
|
|
|
|
|
|
|
|
137
|
|
|
|
|
|
|
=back |
138
|
|
|
|
|
|
|
|
139
|
|
|
|
|
|
|
=back |
140
|
|
|
|
|
|
|
|
141
|
|
|
|
|
|
|
=head1 EXAMPLES |
142
|
|
|
|
|
|
|
|
143
|
|
|
|
|
|
|
A keytab example: |
144
|
|
|
|
|
|
|
|
145
|
|
|
|
|
|
|
use Authen::Krb5::Effortless; |
146
|
|
|
|
|
|
|
my $username = getlogin(); |
147
|
|
|
|
|
|
|
my $keytab = "/path/to/my/keytab"; |
148
|
|
|
|
|
|
|
my $krb5 = Authen::Krb5::Effortless->new(); |
149
|
|
|
|
|
|
|
$krb5->fetch_TGT_KEYTAB($keytab, $username); |
150
|
|
|
|
|
|
|
|
151
|
|
|
|
|
|
|
|
152
|
|
|
|
|
|
|
A password example: |
153
|
|
|
|
|
|
|
|
154
|
|
|
|
|
|
|
use Authen::Krb5::Effortless; |
155
|
|
|
|
|
|
|
my $username = getlogin(); |
156
|
|
|
|
|
|
|
my $krb5 = Authen::Krb5::Effortless->new(); |
157
|
|
|
|
|
|
|
$krb5->fetch_TGT_PW('sekret_phss_wurd', $username); |
158
|
|
|
|
|
|
|
|
159
|
|
|
|
|
|
|
|
160
|
|
|
|
|
|
|
A example for reading cache: |
161
|
|
|
|
|
|
|
|
162
|
|
|
|
|
|
|
use Authen::Krb5::Effortless; |
163
|
|
|
|
|
|
|
my $krb5 = Authen::Krb5::Effortless->new(); |
164
|
|
|
|
|
|
|
$krb5->read_cache(); |
165
|
|
|
|
|
|
|
if ($krb5->{'cache_present'}) { |
166
|
|
|
|
|
|
|
print $krb5->{'principal'}, "\n"; |
167
|
|
|
|
|
|
|
} |
168
|
|
|
|
|
|
|
|
169
|
|
|
|
|
|
|
|
170
|
|
|
|
|
|
|
A example for deleting the cache: |
171
|
|
|
|
|
|
|
|
172
|
|
|
|
|
|
|
use Authen::Krb5::Effortless; |
173
|
|
|
|
|
|
|
my $krb5 = Authen::Krb5::Effortless->new(); |
174
|
|
|
|
|
|
|
$krb5->clear_cache(); |
175
|
|
|
|
|
|
|
|
176
|
|
|
|
|
|
|
=head1 REQUIREMENETS |
177
|
|
|
|
|
|
|
|
178
|
|
|
|
|
|
|
Authen::Krb5 needs to be installed for this module to work. In addition, because I'm using a pragma introduced with perl 5.10.1, I am requireing the use of perl 5.10.1 or newer. |
179
|
|
|
|
|
|
|
|
180
|
|
|
|
|
|
|
=head1 AUTHOR |
181
|
|
|
|
|
|
|
|
182
|
|
|
|
|
|
|
Adam Faris, C<< >> |
183
|
|
|
|
|
|
|
|
184
|
|
|
|
|
|
|
=head1 BUGS |
185
|
|
|
|
|
|
|
|
186
|
|
|
|
|
|
|
Bugs are tracked at github. Please report any bugs to L |
187
|
|
|
|
|
|
|
|
188
|
|
|
|
|
|
|
=head1 SUPPORT |
189
|
|
|
|
|
|
|
|
190
|
|
|
|
|
|
|
You can find documentation for this module with the perldoc command. |
191
|
|
|
|
|
|
|
|
192
|
|
|
|
|
|
|
perldoc Authen::Krb5::Effortless |
193
|
|
|
|
|
|
|
|
194
|
|
|
|
|
|
|
|
195
|
|
|
|
|
|
|
You can also look for information at: |
196
|
|
|
|
|
|
|
|
197
|
|
|
|
|
|
|
=over 4 |
198
|
|
|
|
|
|
|
|
199
|
|
|
|
|
|
|
=item * AnnoCPAN: Annotated CPAN documentation |
200
|
|
|
|
|
|
|
|
201
|
|
|
|
|
|
|
L |
202
|
|
|
|
|
|
|
|
203
|
|
|
|
|
|
|
=item * CPAN Ratings |
204
|
|
|
|
|
|
|
|
205
|
|
|
|
|
|
|
L |
206
|
|
|
|
|
|
|
|
207
|
|
|
|
|
|
|
=item * Search CPAN |
208
|
|
|
|
|
|
|
|
209
|
|
|
|
|
|
|
L |
210
|
|
|
|
|
|
|
|
211
|
|
|
|
|
|
|
=back |
212
|
|
|
|
|
|
|
|
213
|
|
|
|
|
|
|
|
214
|
|
|
|
|
|
|
=head1 ACKNOWLEDGEMENTS |
215
|
|
|
|
|
|
|
|
216
|
|
|
|
|
|
|
I would like to acknowledge Jeff Horwitz, Doug MacEachern, Malcolm Beattie, and Scott Hutton |
217
|
|
|
|
|
|
|
for their work on Authen::Krb5. |
218
|
|
|
|
|
|
|
|
219
|
|
|
|
|
|
|
=head1 LICENSE AND COPYRIGHT |
220
|
|
|
|
|
|
|
|
221
|
|
|
|
|
|
|
Copyright 2013 Adam Faris. |
222
|
|
|
|
|
|
|
|
223
|
|
|
|
|
|
|
Licensed under the Apache License, Version 2.0 (the "License"); |
224
|
|
|
|
|
|
|
you may not use this file except in compliance with the License. |
225
|
|
|
|
|
|
|
You may obtain a copy of the License at |
226
|
|
|
|
|
|
|
|
227
|
|
|
|
|
|
|
L |
228
|
|
|
|
|
|
|
|
229
|
|
|
|
|
|
|
Unless required by applicable law or agreed to in writing, software |
230
|
|
|
|
|
|
|
distributed under the License is distributed on an "AS IS" BASIS, |
231
|
|
|
|
|
|
|
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. |
232
|
|
|
|
|
|
|
See the License for the specific language governing permissions and |
233
|
|
|
|
|
|
|
limitations under the License. |
234
|
|
|
|
|
|
|
|
235
|
|
|
|
|
|
|
=cut |
236
|
|
|
|
|
|
|
|