This repository has been archived by the owner on Feb 24, 2024. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 65
/
kerberos.py
392 lines (254 loc) · 11.2 KB
/
kerberos.py
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
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
##
# Copyright (c) 2006-2016 Apple Inc. All rights reserved.
#
# Licensed under the Apache License, Version 2.0 (the "License");
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an "AS IS" BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
##
"""
PyKerberos Function Description.
"""
class KrbError(Exception):
pass
class BasicAuthError(KrbError):
pass
class GSSError(KrbError):
pass
def checkPassword(user, pswd, service, default_realm):
"""
This function provides a simple way to verify that a user name and password
match those normally used for Kerberos authentication.
It does this by checking that the supplied user name and password can be
used to get a ticket for the supplied service.
If the user name does not contain a realm, then the default realm supplied
is used.
For this to work properly the Kerberos must be configured properly on this
machine.
That will likely mean ensuring that the edu.mit.Kerberos preference file
has the correct realms and KDCs listed.
IMPORTANT: This method is vulnerable to KDC spoofing attacks and it should
only used for testing. Do not use this in any production system - your
security could be compromised if you do.
@param user: A string containing the Kerberos user name.
A realm may be included by appending an C{"@"} followed by the realm
string to the actual user id.
If no realm is supplied, then the realm set in the default_realm
argument will be used.
@param pswd: A string containing the password for the user.
@param service: A string containing the Kerberos service to check access
for.
This will be of the form C{"sss/xx.yy.zz"}, where C{"sss"} is the
service identifier (e.g., C{"http"}, C{"krbtgt"}), and C{"xx.yy.zz"} is
the hostname of the server.
@param default_realm: A string containing the default realm to use if one
is not supplied in the user argument.
Note that Kerberos realms are normally all uppercase (e.g.,
C{"EXAMPLE.COM"}).
@return: True if authentication succeeds, false otherwise.
"""
def changePassword(user, oldpswd, newpswd):
"""
This function allows to change the user password on the KDC.
@param user: A string containing the Kerberos user name.
A realm may be included by appending a C{"@"} followed by the realm
string to the actual user id.
If no realm is supplied, then the realm set in the default_realm
argument will be used.
@param oldpswd: A string containing the old (current) password for the
user.
@param newpswd: A string containing the new password for the user.
@return: True if password changing succeeds, false otherwise.
"""
def getServerPrincipalDetails(service, hostname):
"""
This function returns the service principal for the server given a service
type and hostname.
Details are looked up via the C{/etc/keytab} file.
@param service: A string containing the Kerberos service type for the
server.
@param hostname: A string containing the hostname of the server.
@return: A string containing the service principal.
"""
"""
GSSAPI Function Result Codes:
-1 : Error
0 : GSSAPI step continuation (only returned by 'Step' function)
1 : GSSAPI step complete, or function return OK
"""
# Some useful result codes
AUTH_GSS_CONTINUE = 0
AUTH_GSS_COMPLETE = 1
# Some useful gss flags
GSS_C_DELEG_FLAG = 1
GSS_C_MUTUAL_FLAG = 2
GSS_C_REPLAY_FLAG = 4
GSS_C_SEQUENCE_FLAG = 8
GSS_C_CONF_FLAG = 16
GSS_C_INTEG_FLAG = 32
GSS_C_ANON_FLAG = 64
GSS_C_PROT_READY_FLAG = 128
GSS_C_TRANS_FLAG = 256
def authGSSClientInit(service, **kwargs):
"""
Initializes a context for GSSAPI client-side authentication with the given
service principal.
L{authGSSClientClean} must be called after this function returns an OK
result to dispose of the context once all GSSAPI operations are complete.
@param service: A string containing the service principal in the form
C{"type@fqdn"}.
@param principal: Optional string containing the client principal in the
form C{"user@realm"}.
@param gssflags: Optional integer used to set GSS flags.
(e.g. C{GSS_C_DELEG_FLAG|GSS_C_MUTUAL_FLAG|GSS_C_SEQUENCE_FLAG} will
allow for forwarding credentials to the remote host)
@param delegated: Optional server context containing delegated credentials
@param mech_oid: Optional GGS mech OID
@return: A tuple of (result, context) where result is the result code (see
above) and context is an opaque value that will need to be passed to
subsequent functions.
"""
def authGSSClientClean(context):
"""
Destroys the context for GSSAPI client-side authentication. After this call
the context object is invalid and should not be used again.
@param context: The context object returned from L{authGSSClientInit}.
@return: A result code (see above).
"""
def authGSSClientInquireCred(context):
"""
Get the current user name, if any, without a client-side GSSAPI step.
If the principal has already been authenticated via completed client-side
GSSAPI steps then the user name of the authenticated principal is kept. The
user name will be available via authGSSClientUserName.
@param context: The context object returned from L{authGSSClientInit}.
@return: A result code (see above).
"""
def authGSSClientStep(context, challenge):
"""
Processes a single GSSAPI client-side step using the supplied server data.
@param context: The context object returned from L{authGSSClientInit}.
@param challenge: A string containing the base64-encoded server data (which
may be empty for the first step).
@return: A result code (see above).
"""
def authGSSClientResponse(context):
"""
Get the client response from the last successful GSSAPI client-side step.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the base64-encoded client data to be sent to
the server.
"""
def authGSSClientResponseConf(context):
"""
Determine whether confidentiality was enabled in the previously unwrapped
buffer.
@param context: The context object returned from L{authGSSClientInit}.
@return: C{1} if confidentiality was enabled in the previously unwrapped
buffer, C{0} otherwise.
"""
def authGSSClientUserName(context):
"""
Get the user name of the principal authenticated via the now complete
GSSAPI client-side operations, or the current user name obtained via
authGSSClientInquireCred. This method must only be called after
authGSSClientStep or authGSSClientInquireCred return a complete response
code.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the user name.
"""
def authGSSClientUnwrap(context, challenge):
"""
Perform the client side GSSAPI unwrap step.
@param challenge: A string containing the base64-encoded server data.
@return: A result code (see above)
"""
def authGSSClientWrap(context, data, user=None, protect=0):
"""
Perform the client side GSSAPI wrap step.
@param data: The result of the L{authGSSClientResponse} after the
L{authGSSClientUnwrap}.
@param user: The user to authorize.
@param protect: If C{0}, then just provide integrity protection.
If C{1}, then provide confidentiality as well.
@return: A result code (see above)
"""
def authGSSServerInit(service):
"""
Initializes a context for GSSAPI server-side authentication with the given
service principal.
authGSSServerClean must be called after this function returns an OK result
to dispose of the context once all GSSAPI operations are complete.
@param service: A string containing the service principal in the form
C{"type@fqdn"}. To initialize the context for the purpose of accepting
delegated credentials, pass the literal string C{"DELEGATE"}.
@return: A tuple of (result, context) where result is the result code (see
above) and context is an opaque value that will need to be passed to
subsequent functions.
"""
def authGSSServerClean(context):
"""
Destroys the context for GSSAPI server-side authentication.
After this call the context object is invalid and should not be used again.
@param context: The context object returned from L{authGSSClientInit}.
@return: A result code (see above).
"""
def authGSSServerStep(context, challenge):
"""
Processes a single GSSAPI server-side step using the supplied client data.
@param context: The context object returned from L{authGSSClientInit}.
@param challenge: A string containing the base64-encoded client data.
@return: A result code (see above).
"""
def authGSSServerResponse(context):
"""
Get the server response from the last successful GSSAPI server-side step.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the base64-encoded server data to be sent to
the client.
"""
def authGSSServerHasDelegated(context):
"""
Checks whether a server context has delegated credentials.
@param context: The context object returned from L{authGSSClientInit}.
@return: A bool saying whether delegated credentials are available.
"""
def authGSSServerUserName(context):
"""
Get the user name of the principal trying to authenticate to the server.
This method must only be called after L{authGSSServerStep} returns a
complete or continue response code.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the user name.
"""
def authGSSServerTargetName(context):
"""
Get the target name if the server did not supply its own credentials.
This method must only be called after L{authGSSServerStep} returns a
complete or continue response code.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the target name.
"""
def authGSSServerStoreDelegate(context):
"""
Save the ticket sent to the server in the file C{/tmp/krb5_pyserv_XXXXXX}.
This method must only be called after L{authGSSServerStep} returns a
complete or continue response code.
@param context: The context object returned from L{authGSSClientInit}.
@return: A result code (see above).
"""
def authGSSServerCacheName(context):
"""
Get the name of the credential cache created with
L{authGSSServerStoreDelegate}.
This method must only be called after L{authGSSServerStoreDelegate}.
@param context: The context object returned from L{authGSSClientInit}.
@return: A string containing the cache name.
"""