Coverage for /root/GitHubProjects/impacket/impacket/krb5/ccache.py : 15%

Hot-keys on this page
r m x p toggle line displays
j k next/prev highlighted chunk
0 (zero) top of page
1 (one) first highlighted chunk
1# SECUREAUTH LABS. Copyright 2018 SecureAuth Corporation. All rights reserved.
2#
3# This software is provided under under a slightly modified version
4# of the Apache Software License. See the accompanying LICENSE file
5# for more information.
6#
7# Author: Alberto Solino (@agsolino)
8#
9# Description:
10# Kerberos Credential Cache format implementation
11# based on file format described at:
12# https://repo.or.cz/w/krb5dissect.git/blob_plain/HEAD:/ccache.txt
13# Pretty lame and quick implementation, not a fun thing to do
14# Contribution is welcome to make it the right way
15#
16from __future__ import division
17from __future__ import print_function
18from datetime import datetime
19from struct import pack, unpack, calcsize
20from six import b
22from pyasn1.codec.der import decoder, encoder
23from pyasn1.type.univ import noValue
24from binascii import hexlify
26from impacket.structure import Structure
27from impacket.krb5 import crypto, constants, types
28from impacket.krb5.asn1 import AS_REP, seq_set, TGS_REP, EncTGSRepPart, EncASRepPart, Ticket, KRB_CRED, \
29 EncKrbCredPart, KrbCredInfo, seq_set_iter
30from impacket.krb5.types import KerberosTime
31from impacket import LOG
33DELTA_TIME = 1
35class Header(Structure):
36 structure = (
37 ('tag','!H=0'),
38 ('taglen','!H=0'),
39 ('_tagdata','_-tagdata','self["taglen"]'),
40 ('tagdata',':'),
41 )
43class DeltaTime(Structure):
44 structure = (
45 ('time_offset','!L=0'),
46 ('usec_offset','!L=0'),
47 )
49class CountedOctetString(Structure):
50 structure = (
51 ('length','!L=0'),
52 ('_data','_-data','self["length"]'),
53 ('data',':'),
54 )
56 def prettyPrint(self, indent=''):
57 return "%s%s" % (indent, hexlify(self['data']))
59class KeyBlock(Structure):
60 structure = (
61 ('keytype','!H=0'),
62 ('etype','!H=0'),
63 ('keylen','!H=0'),
64 ('_keyvalue','_-keyvalue','self["keylen"]'),
65 ('keyvalue',':'),
66 )
68 def prettyPrint(self):
69 return "Key: (0x%x)%s" % (self['keytype'], hexlify(self['keyvalue']))
71class Times(Structure):
72 structure = (
73 ('authtime','!L=0'),
74 ('starttime','!L=0'),
75 ('endtime','!L=0'),
76 ('renew_till','!L=0'),
77 )
78 def prettyPrint(self, indent = ''):
79 print(("%sAuth : %s" % (indent, datetime.fromtimestamp(self['authtime']).isoformat())))
80 print(("%sStart: %s" % (indent, datetime.fromtimestamp(self['starttime']).isoformat())))
81 print(("%sEnd : %s" % (indent, datetime.fromtimestamp(self['endtime']).isoformat())))
82 print(("%sRenew: %s" % (indent, datetime.fromtimestamp(self['renew_till']).isoformat())))
84class Address(Structure):
85 structure = (
86 ('addrtype','!H=0'),
87 ('addrdata',':', CountedOctetString),
88 )
90class AuthData(Structure):
91 structure = (
92 ('authtype','!H=0'),
93 ('authdata',':', CountedOctetString),
94 )
96class Principal:
97 class PrincipalHeader(Structure):
98 structure = (
99 ('name_type','!L=0'),
100 ('num_components','!L=0'),
101 )
102 def __init__(self, data=None):
103 self.components = []
104 self.realm = None
105 if data is not None:
106 self.header = self.PrincipalHeader(data)
107 data = data[len(self.header):]
108 self.realm = CountedOctetString(data)
109 data = data[len(self.realm):]
110 self.components = []
111 for component in range(self.header['num_components']):
112 comp = CountedOctetString(data)
113 data = data[len(comp):]
114 self.components.append(comp)
115 else:
116 self.header = self.PrincipalHeader()
118 def __len__(self):
119 totalLen = len(self.header) + len(self.realm)
120 for i in self.components:
121 totalLen += len(i)
122 return totalLen
124 def getData(self):
125 data = self.header.getData() + self.realm.getData()
126 for component in self.components:
127 data += component.getData()
128 return data
130 def __str__(self):
131 return self.getData()
133 def prettyPrint(self):
134 principal = b''
135 for component in self.components:
136 if isinstance(component['data'], bytes) is not True:
137 component = b(component['data'])
138 else:
139 component = component['data']
140 principal += component + b'/'
142 principal = principal[:-1]
143 if isinstance(self.realm['data'], bytes):
144 realm = self.realm['data']
145 else:
146 realm = b(self.realm['data'])
147 principal += b'@' + realm
148 return principal
150 def fromPrincipal(self, principal):
151 self.header['name_type'] = principal.type
152 self.header['num_components'] = len(principal.components)
153 octetString = CountedOctetString()
154 octetString['length'] = len(principal.realm)
155 octetString['data'] = principal.realm
156 self.realm = octetString
157 self.components = []
158 for c in principal.components:
159 octetString = CountedOctetString()
160 octetString['length'] = len(c)
161 octetString['data'] = c
162 self.components.append(octetString)
164 def toPrincipal(self):
165 return types.Principal(self.prettyPrint(), type=self.header['name_type'])
167class Credential:
168 class CredentialHeader(Structure):
169 structure = (
170 ('client',':', Principal),
171 ('server',':', Principal),
172 ('key',':', KeyBlock),
173 ('time',':', Times),
174 ('is_skey','B=0'),
175 ('tktflags','!L=0'),
176 ('num_address','!L=0'),
177 )
179 def __init__(self, data=None):
180 self.addresses = ()
181 self.authData = ()
182 self.header = None
183 self.ticket = None
184 self.secondTicket = None
186 if data is not None:
187 self.header = self.CredentialHeader(data)
188 data = data[len(self.header):]
189 self.addresses = []
190 for address in range(self.header['num_address']):
191 ad = Address(data)
192 data = data[len(ad):]
193 self.addresses.append(ad)
194 num_authdata = unpack('!L', data[:4])[0]
195 data = data[calcsize('!L'):]
196 for authdata in range(num_authdata):
197 ad = AuthData(data)
198 data = data[len(ad):]
199 self.authData.append(ad)
200 self.ticket = CountedOctetString(data)
201 data = data[len(self.ticket):]
202 self.secondTicket = CountedOctetString(data)
203 data = data[len( self.secondTicket):]
204 else:
205 self.header = self.CredentialHeader()
207 def __getitem__(self, key):
208 return self.header[key]
210 def __setitem__(self, item, value):
211 self.header[item] = value
213 def getServerPrincipal(self):
214 return self.header['server'].prettyPrint()
216 def __len__(self):
217 totalLen = len(self.header)
218 for i in self.addresses:
219 totalLen += len(i)
220 totalLen += calcsize('!L')
221 for i in self.authData:
222 totalLen += len(i)
223 totalLen += len(self.ticket)
224 totalLen += len(self.secondTicket)
225 return totalLen
227 def dump(self):
228 self.header.dump()
230 def getData(self):
231 data = self.header.getData()
232 for i in self.addresses:
233 data += i.getData()
234 data += pack('!L', len(self.authData))
235 for i in self.authData:
236 data += i.getData()
237 data += self.ticket.getData()
238 data += self.secondTicket.getData()
239 return data
241 def __str__(self):
242 return self.getData()
244 def prettyPrint(self, indent=''):
245 print(("%sClient: %s" % (indent, self.header['client'].prettyPrint())))
246 print(("%sServer: %s" % (indent, self.header['server'].prettyPrint())))
247 print(("%s%s" % (indent, self.header['key'].prettyPrint())))
248 print(("%sTimes: " % indent))
249 self.header['time'].prettyPrint('\t\t')
250 print(("%sSubKey: %s" % (indent, self.header['is_skey'])))
251 print(("%sFlags: 0x%x" % (indent, self.header['tktflags'])))
252 print(("%sAddresses: %d" % (indent, self.header['num_address'])))
253 for address in self.addresses:
254 address.prettyPrint('\t\t')
255 print(("%sAuth Data: %d" % (indent, len(self.authData))))
256 for ad in self.authData:
257 ad.prettyPrint('\t\t')
258 print(("%sTicket: %s" % (indent, self.ticket.prettyPrint())))
259 print(("%sSecond Ticket: %s" % (indent, self.secondTicket.prettyPrint())))
261 def toTGT(self):
262 tgt_rep = AS_REP()
263 tgt_rep['pvno'] = 5
264 tgt_rep['msg-type'] = int(constants.ApplicationTagNumbers.AS_REP.value)
265 tgt_rep['crealm'] = self['server'].realm['data']
267 # Fake EncryptedData
268 tgt_rep['enc-part'] = noValue
269 tgt_rep['enc-part']['etype'] = 1
270 tgt_rep['enc-part']['cipher'] = ''
271 seq_set(tgt_rep, 'cname', self['client'].toPrincipal().components_to_asn1)
272 ticket = types.Ticket()
273 ticket.from_asn1(self.ticket['data'])
274 seq_set(tgt_rep,'ticket', ticket.to_asn1)
276 cipher = crypto._enctype_table[self['key']['keytype']]()
278 tgt = dict()
279 tgt['KDC_REP'] = encoder.encode(tgt_rep)
280 tgt['cipher'] = cipher
281 tgt['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue'])
282 return tgt
284 def toTGS(self, newSPN=None):
285 tgs_rep = TGS_REP()
286 tgs_rep['pvno'] = 5
287 tgs_rep['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REP.value)
288 tgs_rep['crealm'] = self['server'].realm['data']
290 # Fake EncryptedData
291 tgs_rep['enc-part'] = noValue
292 tgs_rep['enc-part']['etype'] = 1
293 tgs_rep['enc-part']['cipher'] = ''
294 seq_set(tgs_rep, 'cname', self['client'].toPrincipal().components_to_asn1)
295 ticket = types.Ticket()
296 ticket.from_asn1(self.ticket['data'])
297 if newSPN is not None:
298 if newSPN.upper() != str(ticket.service_principal).upper():
299 LOG.debug('Changing sname from %s to %s and hoping for the best' % (ticket.service_principal, newSPN) )
300 ticket.service_principal = types.Principal(newSPN, type=int(ticket.service_principal.type))
301 seq_set(tgs_rep,'ticket', ticket.to_asn1)
303 cipher = crypto._enctype_table[self['key']['keytype']]()
305 tgs = dict()
306 tgs['KDC_REP'] = encoder.encode(tgs_rep)
307 tgs['cipher'] = cipher
308 tgs['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue'])
309 return tgs
311class CCache:
312 class MiniHeader(Structure):
313 structure = (
314 ('file_format_version','!H=0x0504'),
315 ('headerlen','!H=12'),
316 )
318 def __init__(self, data = None):
319 self.headers = None
320 self.principal = None
321 self.credentials = []
322 self.miniHeader = None
323 if data is not None:
324 miniHeader = self.MiniHeader(data)
325 data = data[len(miniHeader.getData()):]
327 headerLen = miniHeader['headerlen']
329 self.headers = []
330 while headerLen > 0:
331 header = Header(data)
332 self.headers.append(header)
333 headerLen -= len(header)
334 data = data[len(header):]
336 # Now the primary_principal
337 self.principal = Principal(data)
339 data = data[len(self.principal):]
341 # Now let's parse the credentials
342 self.credentials = []
343 while len(data) > 0:
344 cred = Credential(data)
345 if cred['server'].prettyPrint().find(b'krb5_ccache_conf_data') < 0:
346 self.credentials.append(cred)
347 data = data[len(cred.getData()):]
349 def getData(self):
350 data = self.MiniHeader().getData()
351 for header in self.headers:
352 data += header.getData()
353 data += self.principal.getData()
354 for credential in self.credentials:
355 data += credential.getData()
356 return data
358 def getCredential(self, server, anySPN=True):
359 for c in self.credentials:
360 if c['server'].prettyPrint().upper() == b(server.upper()) or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper())\
361 or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper().split('@')[0]):
362 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8'))
363 return c
364 LOG.debug('SPN %s not found in cache' % server.upper())
365 if anySPN is True:
366 LOG.debug('AnySPN is True, looking for another suitable SPN')
367 for c in self.credentials:
368 # Let's search for any TGT/TGS that matches the server w/o the SPN's service type/port, returns
369 # the first one
370 if c['server'].prettyPrint().find(b'/') >=0:
371 # Let's take the port out for comparison
372 cachedSPN = (c['server'].prettyPrint().upper().split(b'/')[1].split(b'@')[0].split(b':')[0] + b'@' + c['server'].prettyPrint().upper().split(b'/')[1].split(b'@')[1])
373 searchSPN = '%s@%s' % (server.upper().split('/')[1].split('@')[0].split(':')[0],
374 server.upper().split('/')[1].split('@')[1])
375 if cachedSPN == b(searchSPN):
376 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8'))
377 return c
379 return None
381 def toTimeStamp(self, dt, epoch=datetime(1970,1,1)):
382 td = dt - epoch
383 # return td.total_seconds()
384 return int((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) // 1e6)
386 def reverseFlags(self, flags):
387 result = 0
388 if isinstance(flags, str):
389 flags = flags[1:-2]
390 for i,j in enumerate(reversed(flags)):
391 if j != 0:
392 result += j << i
393 return result
395 def fromTGT(self, tgt, oldSessionKey, sessionKey):
396 self.headers = []
397 header = Header()
398 header['tag'] = 1
399 header['taglen'] = 8
400 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00'
401 self.headers.append(header)
403 decodedTGT = decoder.decode(tgt, asn1Spec = AS_REP())[0]
405 tmpPrincipal = types.Principal()
406 tmpPrincipal.from_asn1(decodedTGT, 'crealm', 'cname')
407 self.principal = Principal()
408 self.principal.fromPrincipal(tmpPrincipal)
410 # Now let's add the credential
411 cipherText = decodedTGT['enc-part']['cipher']
413 cipher = crypto._enctype_table[decodedTGT['enc-part']['etype']]
415 # Key Usage 3
416 # AS-REP encrypted part (includes TGS session key or
417 # application session key), encrypted with the client key
418 # (Section 5.4.2)
419 plainText = cipher.decrypt(oldSessionKey, 3, cipherText)
421 encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0]
422 credential = Credential()
423 server = types.Principal()
424 server.from_asn1(encASRepPart, 'srealm', 'sname')
425 tmpServer = Principal()
426 tmpServer.fromPrincipal(server)
428 credential['client'] = self.principal
429 credential['server'] = tmpServer
430 credential['is_skey'] = 0
432 credential['key'] = KeyBlock()
433 credential['key']['keytype'] = int(encASRepPart['key']['keytype'])
434 credential['key']['keyvalue'] = encASRepPart['key']['keyvalue'].asOctets()
435 credential['key']['keylen'] = len(credential['key']['keyvalue'])
437 credential['time'] = Times()
438 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['authtime']))
439 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['starttime']))
440 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['endtime']))
441 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['renew-till']))
443 flags = self.reverseFlags(encASRepPart['flags'])
444 credential['tktflags'] = flags
446 credential['num_address'] = 0
447 credential.ticket = CountedOctetString()
448 credential.ticket['data'] = encoder.encode(decodedTGT['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True))
449 credential.ticket['length'] = len(credential.ticket['data'])
450 credential.secondTicket = CountedOctetString()
451 credential.secondTicket['data'] = b''
452 credential.secondTicket['length'] = 0
453 self.credentials.append(credential)
455 def fromTGS(self, tgs, oldSessionKey, sessionKey):
456 self.headers = []
457 header = Header()
458 header['tag'] = 1
459 header['taglen'] = 8
460 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00'
461 self.headers.append(header)
463 decodedTGS = decoder.decode(tgs, asn1Spec = TGS_REP())[0]
465 tmpPrincipal = types.Principal()
466 tmpPrincipal.from_asn1(decodedTGS, 'crealm', 'cname')
467 self.principal = Principal()
468 self.principal.fromPrincipal(tmpPrincipal)
470 # Now let's add the credential
471 cipherText = decodedTGS['enc-part']['cipher']
473 cipher = crypto._enctype_table[decodedTGS['enc-part']['etype']]
475 # Key Usage 8
476 # TGS-REP encrypted part (includes application session
477 # key), encrypted with the TGS session key (Section 5.4.2)
478 plainText = cipher.decrypt(oldSessionKey, 8, cipherText)
480 encTGSRepPart = decoder.decode(plainText, asn1Spec = EncTGSRepPart())[0]
482 credential = Credential()
483 server = types.Principal()
484 server.from_asn1(encTGSRepPart, 'srealm', 'sname')
485 tmpServer = Principal()
486 tmpServer.fromPrincipal(server)
488 credential['client'] = self.principal
489 credential['server'] = tmpServer
490 credential['is_skey'] = 0
492 credential['key'] = KeyBlock()
493 credential['key']['keytype'] = int(encTGSRepPart['key']['keytype'])
494 credential['key']['keyvalue'] = encTGSRepPart['key']['keyvalue'].asOctets()
495 credential['key']['keylen'] = len(credential['key']['keyvalue'])
497 credential['time'] = Times()
498 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['authtime']))
499 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['starttime']))
500 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['endtime']))
501 # After KB4586793 for CVE-2020-17049 this timestamp may be omitted
502 if encTGSRepPart['renew-till'].hasValue():
503 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['renew-till']))
505 flags = self.reverseFlags(encTGSRepPart['flags'])
506 credential['tktflags'] = flags
508 credential['num_address'] = 0
510 credential.ticket = CountedOctetString()
511 credential.ticket['data'] = encoder.encode(decodedTGS['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True))
512 credential.ticket['length'] = len(credential.ticket['data'])
513 credential.secondTicket = CountedOctetString()
514 credential.secondTicket['data'] = b''
515 credential.secondTicket['length'] = 0
516 self.credentials.append(credential)
518 @classmethod
519 def loadFile(cls, fileName):
520 f = open(fileName,'rb')
521 data = f.read()
522 f.close()
523 return cls(data)
525 def saveFile(self, fileName):
526 f = open(fileName,'wb+')
527 f.write(self.getData())
528 f.close()
530 def prettyPrint(self):
531 print(("Primary Principal: %s" % self.principal.prettyPrint()))
532 print("Credentials: ")
533 for i, credential in enumerate(self.credentials):
534 print(("[%d]" % i))
535 credential.prettyPrint('\t')
537 @classmethod
538 def loadKirbiFile(cls, fileName):
539 f = open(fileName, 'rb')
540 data = f.read()
541 f.close()
542 ccache = cls()
543 ccache.fromKRBCRED(data)
544 return ccache
546 def saveKirbiFile(self, fileName):
547 f = open(fileName, 'wb+')
548 f.write(self.toKRBCRED())
549 f.close()
551 def fromKRBCRED(self, encodedKrbCred):
553 krbCred = decoder.decode(encodedKrbCred, asn1Spec=KRB_CRED())[0]
554 encKrbCredPart = decoder.decode(krbCred['enc-part']['cipher'], asn1Spec=EncKrbCredPart())[0]
555 krbCredInfo = encKrbCredPart['ticket-info'][0]
557 self.setDefaultHeader()
559 tmpPrincipal = types.Principal()
560 tmpPrincipal.from_asn1(krbCredInfo, 'prealm', 'pname')
561 self.principal = Principal()
562 self.principal.fromPrincipal(tmpPrincipal)
564 credential = Credential()
565 server = types.Principal()
566 server.from_asn1(krbCredInfo, 'srealm', 'sname')
567 tmpServer = Principal()
568 tmpServer.fromPrincipal(server)
570 credential['client'] = self.principal
571 credential['server'] = tmpServer
572 credential['is_skey'] = 0
574 credential['key'] = KeyBlock()
575 credential['key']['keytype'] = int(krbCredInfo['key']['keytype'])
576 credential['key']['keyvalue'] = str(krbCredInfo['key']['keyvalue'])
577 credential['key']['keylen'] = len(credential['key']['keyvalue'])
579 credential['time'] = Times()
581 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['starttime']))
582 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['endtime']))
583 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['renew-till']))
585 flags = self.reverseFlags(krbCredInfo['flags'])
586 credential['tktflags'] = flags
588 credential['num_address'] = 0
589 credential.ticket = CountedOctetString()
590 credential.ticket['data'] = encoder.encode(
591 krbCred['tickets'][0].clone(tagSet=Ticket.tagSet, cloneValueFlag=True)
592 )
593 credential.ticket['length'] = len(credential.ticket['data'])
594 credential.secondTicket = CountedOctetString()
595 credential.secondTicket['data'] = ''
596 credential.secondTicket['length'] = 0
598 self.credentials.append(credential)
600 def toKRBCRED(self):
601 principal = self.principal
602 credential = self.credentials[0]
604 krbCredInfo = KrbCredInfo()
606 krbCredInfo['key'] = noValue
607 krbCredInfo['key']['keytype'] = credential['key']['keytype']
608 krbCredInfo['key']['keyvalue'] = credential['key']['keyvalue']
610 krbCredInfo['prealm'] = principal.realm.fields['data']
612 krbCredInfo['pname'] = noValue
613 krbCredInfo['pname']['name-type'] = principal.header['name_type']
614 seq_set_iter(krbCredInfo['pname'], 'name-string', (principal.components[0].fields['data'],))
616 krbCredInfo['flags'] = credential['tktflags']
618 krbCredInfo['starttime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['starttime']))
619 krbCredInfo['endtime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['endtime']))
620 krbCredInfo['renew-till'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['renew_till']))
622 krbCredInfo['srealm'] = credential['server'].realm.fields['data']
624 krbCredInfo['sname'] = noValue
625 krbCredInfo['sname']['name-type'] = credential['server'].header['name_type']
626 seq_set_iter(krbCredInfo['sname'], 'name-string',
627 (credential['server'].components[0].fields['data'], credential['server'].realm.fields['data']))
629 encKrbCredPart = EncKrbCredPart()
630 seq_set_iter(encKrbCredPart, 'ticket-info', (krbCredInfo,))
632 krbCred = KRB_CRED()
633 krbCred['pvno'] = 5
634 krbCred['msg-type'] = 22
636 krbCred['enc-part'] = noValue
637 krbCred['enc-part']['etype'] = 0
638 krbCred['enc-part']['cipher'] = encoder.encode(encKrbCredPart)
640 ticket = decoder.decode(credential.ticket['data'], asn1Spec=Ticket())[0]
641 seq_set_iter(krbCred, 'tickets', (ticket,))
643 encodedKrbCred = encoder.encode(krbCred)
645 return encodedKrbCred
647 def setDefaultHeader(self):
648 self.headers = []
649 header = Header()
650 header['tag'] = 1
651 header['taglen'] = 8
652 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00'
653 self.headers.append(header)
657if __name__ == '__main__': 657 ↛ 658line 657 didn't jump to line 658, because the condition on line 657 was never true
658 import os
659 ccache = CCache.loadFile(os.getenv('KRB5CCNAME'))
660 ccache.prettyPrint()