Hide keyboard shortcuts

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# Impacket - Collection of Python classes for working with network protocols. 

2# 

3# SECUREAUTH LABS. Copyright (C) 2020 SecureAuth Corporation. All rights reserved. 

4# 

5# This software is provided under a slightly modified version 

6# of the Apache Software License. See the accompanying LICENSE file 

7# for more information. 

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# 

16# Author: 

17# Alberto Solino (@agsolino) 

18# 

19from __future__ import division 

20from __future__ import print_function 

21from datetime import datetime 

22from struct import pack, unpack, calcsize 

23from six import b 

24 

25from pyasn1.codec.der import decoder, encoder 

26from pyasn1.type.univ import noValue 

27from binascii import hexlify 

28 

29from impacket.structure import Structure 

30from impacket.krb5 import crypto, constants, types 

31from impacket.krb5.asn1 import AS_REP, seq_set, TGS_REP, EncTGSRepPart, EncASRepPart, Ticket, KRB_CRED, \ 

32 EncKrbCredPart, KrbCredInfo, seq_set_iter 

33from impacket.krb5.types import KerberosTime 

34from impacket import LOG 

35 

36DELTA_TIME = 1 

37 

38class Header(Structure): 

39 structure = ( 

40 ('tag','!H=0'), 

41 ('taglen','!H=0'), 

42 ('_tagdata','_-tagdata','self["taglen"]'), 

43 ('tagdata',':'), 

44 ) 

45 

46class DeltaTime(Structure): 

47 structure = ( 

48 ('time_offset','!L=0'), 

49 ('usec_offset','!L=0'), 

50 ) 

51 

52class CountedOctetString(Structure): 

53 structure = ( 

54 ('length','!L=0'), 

55 ('_data','_-data','self["length"]'), 

56 ('data',':'), 

57 ) 

58 

59 def prettyPrint(self, indent=''): 

60 return "%s%s" % (indent, hexlify(self['data'])) 

61 

62class KeyBlock(Structure): 

63 structure = ( 

64 ('keytype','!H=0'), 

65 ('etype','!H=0'), 

66 ('keylen','!H=0'), 

67 ('_keyvalue','_-keyvalue','self["keylen"]'), 

68 ('keyvalue',':'), 

69 ) 

70 

71 def prettyPrint(self): 

72 return "Key: (0x%x)%s" % (self['keytype'], hexlify(self['keyvalue'])) 

73 

74class Times(Structure): 

75 structure = ( 

76 ('authtime','!L=0'), 

77 ('starttime','!L=0'), 

78 ('endtime','!L=0'), 

79 ('renew_till','!L=0'), 

80 ) 

81 def prettyPrint(self, indent = ''): 

82 print(("%sAuth : %s" % (indent, datetime.fromtimestamp(self['authtime']).isoformat()))) 

83 print(("%sStart: %s" % (indent, datetime.fromtimestamp(self['starttime']).isoformat()))) 

84 print(("%sEnd : %s" % (indent, datetime.fromtimestamp(self['endtime']).isoformat()))) 

85 print(("%sRenew: %s" % (indent, datetime.fromtimestamp(self['renew_till']).isoformat()))) 

86 

87class Address(Structure): 

88 structure = ( 

89 ('addrtype','!H=0'), 

90 ('addrdata',':', CountedOctetString), 

91 ) 

92 

93class AuthData(Structure): 

94 structure = ( 

95 ('authtype','!H=0'), 

96 ('authdata',':', CountedOctetString), 

97 ) 

98 

99class Principal: 

100 class PrincipalHeader(Structure): 

101 structure = ( 

102 ('name_type','!L=0'), 

103 ('num_components','!L=0'), 

104 ) 

105 def __init__(self, data=None): 

106 self.components = [] 

107 self.realm = None 

108 if data is not None: 

109 self.header = self.PrincipalHeader(data) 

110 data = data[len(self.header):] 

111 self.realm = CountedOctetString(data) 

112 data = data[len(self.realm):] 

113 self.components = [] 

114 for component in range(self.header['num_components']): 

115 comp = CountedOctetString(data) 

116 data = data[len(comp):] 

117 self.components.append(comp) 

118 else: 

119 self.header = self.PrincipalHeader() 

120 

121 def __len__(self): 

122 totalLen = len(self.header) + len(self.realm) 

123 for i in self.components: 

124 totalLen += len(i) 

125 return totalLen 

126 

127 def getData(self): 

128 data = self.header.getData() + self.realm.getData() 

129 for component in self.components: 

130 data += component.getData() 

131 return data 

132 

133 def __str__(self): 

134 return self.getData() 

135 

136 def prettyPrint(self): 

137 principal = b'' 

138 for component in self.components: 

139 if isinstance(component['data'], bytes) is not True: 

140 component = b(component['data']) 

141 else: 

142 component = component['data'] 

143 principal += component + b'/' 

144 

145 principal = principal[:-1] 

146 if isinstance(self.realm['data'], bytes): 

147 realm = self.realm['data'] 

148 else: 

149 realm = b(self.realm['data']) 

150 principal += b'@' + realm 

151 return principal 

152 

153 def fromPrincipal(self, principal): 

154 self.header['name_type'] = principal.type 

155 self.header['num_components'] = len(principal.components) 

156 octetString = CountedOctetString() 

157 octetString['length'] = len(principal.realm) 

158 octetString['data'] = principal.realm 

159 self.realm = octetString 

160 self.components = [] 

161 for c in principal.components: 

162 octetString = CountedOctetString() 

163 octetString['length'] = len(c) 

164 octetString['data'] = c 

165 self.components.append(octetString) 

166 

167 def toPrincipal(self): 

168 return types.Principal(self.prettyPrint(), type=self.header['name_type']) 

169 

170class Credential: 

171 class CredentialHeader(Structure): 

172 structure = ( 

173 ('client',':', Principal), 

174 ('server',':', Principal), 

175 ('key',':', KeyBlock), 

176 ('time',':', Times), 

177 ('is_skey','B=0'), 

178 ('tktflags','!L=0'), 

179 ('num_address','!L=0'), 

180 ) 

181 

182 def __init__(self, data=None): 

183 self.addresses = () 

184 self.authData = () 

185 self.header = None 

186 self.ticket = None 

187 self.secondTicket = None 

188 

189 if data is not None: 

190 self.header = self.CredentialHeader(data) 

191 data = data[len(self.header):] 

192 self.addresses = [] 

193 for address in range(self.header['num_address']): 

194 ad = Address(data) 

195 data = data[len(ad):] 

196 self.addresses.append(ad) 

197 num_authdata = unpack('!L', data[:4])[0] 

198 data = data[calcsize('!L'):] 

199 for authdata in range(num_authdata): 

200 ad = AuthData(data) 

201 data = data[len(ad):] 

202 self.authData.append(ad) 

203 self.ticket = CountedOctetString(data) 

204 data = data[len(self.ticket):] 

205 self.secondTicket = CountedOctetString(data) 

206 data = data[len( self.secondTicket):] 

207 else: 

208 self.header = self.CredentialHeader() 

209 

210 def __getitem__(self, key): 

211 return self.header[key] 

212 

213 def __setitem__(self, item, value): 

214 self.header[item] = value 

215 

216 def getServerPrincipal(self): 

217 return self.header['server'].prettyPrint() 

218 

219 def __len__(self): 

220 totalLen = len(self.header) 

221 for i in self.addresses: 

222 totalLen += len(i) 

223 totalLen += calcsize('!L') 

224 for i in self.authData: 

225 totalLen += len(i) 

226 totalLen += len(self.ticket) 

227 totalLen += len(self.secondTicket) 

228 return totalLen 

229 

230 def dump(self): 

231 self.header.dump() 

232 

233 def getData(self): 

234 data = self.header.getData() 

235 for i in self.addresses: 

236 data += i.getData() 

237 data += pack('!L', len(self.authData)) 

238 for i in self.authData: 

239 data += i.getData() 

240 data += self.ticket.getData() 

241 data += self.secondTicket.getData() 

242 return data 

243 

244 def __str__(self): 

245 return self.getData() 

246 

247 def prettyPrint(self, indent=''): 

248 print(("%sClient: %s" % (indent, self.header['client'].prettyPrint()))) 

249 print(("%sServer: %s" % (indent, self.header['server'].prettyPrint()))) 

250 print(("%s%s" % (indent, self.header['key'].prettyPrint()))) 

251 print(("%sTimes: " % indent)) 

252 self.header['time'].prettyPrint('\t\t') 

253 print(("%sSubKey: %s" % (indent, self.header['is_skey']))) 

254 print(("%sFlags: 0x%x" % (indent, self.header['tktflags']))) 

255 print(("%sAddresses: %d" % (indent, self.header['num_address']))) 

256 for address in self.addresses: 

257 address.prettyPrint('\t\t') 

258 print(("%sAuth Data: %d" % (indent, len(self.authData)))) 

259 for ad in self.authData: 

260 ad.prettyPrint('\t\t') 

261 print(("%sTicket: %s" % (indent, self.ticket.prettyPrint()))) 

262 print(("%sSecond Ticket: %s" % (indent, self.secondTicket.prettyPrint()))) 

263 

264 def toTGT(self): 

265 tgt_rep = AS_REP() 

266 tgt_rep['pvno'] = 5 

267 tgt_rep['msg-type'] = int(constants.ApplicationTagNumbers.AS_REP.value) 

268 tgt_rep['crealm'] = self['server'].realm['data'] 

269 

270 # Fake EncryptedData 

271 tgt_rep['enc-part'] = noValue 

272 tgt_rep['enc-part']['etype'] = 1 

273 tgt_rep['enc-part']['cipher'] = '' 

274 seq_set(tgt_rep, 'cname', self['client'].toPrincipal().components_to_asn1) 

275 ticket = types.Ticket() 

276 ticket.from_asn1(self.ticket['data']) 

277 seq_set(tgt_rep,'ticket', ticket.to_asn1) 

278 

279 cipher = crypto._enctype_table[self['key']['keytype']]() 

280 

281 tgt = dict() 

282 tgt['KDC_REP'] = encoder.encode(tgt_rep) 

283 tgt['cipher'] = cipher 

284 tgt['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue']) 

285 return tgt 

286 

287 def toTGS(self, newSPN=None): 

288 tgs_rep = TGS_REP() 

289 tgs_rep['pvno'] = 5 

290 tgs_rep['msg-type'] = int(constants.ApplicationTagNumbers.TGS_REP.value) 

291 tgs_rep['crealm'] = self['server'].realm['data'] 

292 

293 # Fake EncryptedData 

294 tgs_rep['enc-part'] = noValue 

295 tgs_rep['enc-part']['etype'] = 1 

296 tgs_rep['enc-part']['cipher'] = '' 

297 seq_set(tgs_rep, 'cname', self['client'].toPrincipal().components_to_asn1) 

298 ticket = types.Ticket() 

299 ticket.from_asn1(self.ticket['data']) 

300 if newSPN is not None: 

301 if newSPN.upper() != str(ticket.service_principal).upper(): 

302 LOG.debug('Changing sname from %s to %s and hoping for the best' % (ticket.service_principal, newSPN) ) 

303 ticket.service_principal = types.Principal(newSPN, type=int(ticket.service_principal.type)) 

304 seq_set(tgs_rep,'ticket', ticket.to_asn1) 

305 

306 cipher = crypto._enctype_table[self['key']['keytype']]() 

307 

308 tgs = dict() 

309 tgs['KDC_REP'] = encoder.encode(tgs_rep) 

310 tgs['cipher'] = cipher 

311 tgs['sessionKey'] = crypto.Key(cipher.enctype, self['key']['keyvalue']) 

312 return tgs 

313 

314class CCache: 

315 class MiniHeader(Structure): 

316 structure = ( 

317 ('file_format_version','!H=0x0504'), 

318 ('headerlen','!H=12'), 

319 ) 

320 

321 def __init__(self, data = None): 

322 self.headers = None 

323 self.principal = None 

324 self.credentials = [] 

325 self.miniHeader = None 

326 if data is not None: 

327 miniHeader = self.MiniHeader(data) 

328 data = data[len(miniHeader.getData()):] 

329 

330 headerLen = miniHeader['headerlen'] 

331 

332 self.headers = [] 

333 while headerLen > 0: 

334 header = Header(data) 

335 self.headers.append(header) 

336 headerLen -= len(header) 

337 data = data[len(header):] 

338 

339 # Now the primary_principal 

340 self.principal = Principal(data) 

341 

342 data = data[len(self.principal):] 

343 

344 # Now let's parse the credentials 

345 self.credentials = [] 

346 while len(data) > 0: 

347 cred = Credential(data) 

348 if cred['server'].prettyPrint().find(b'krb5_ccache_conf_data') < 0: 

349 self.credentials.append(cred) 

350 data = data[len(cred.getData()):] 

351 

352 def getData(self): 

353 data = self.MiniHeader().getData() 

354 for header in self.headers: 

355 data += header.getData() 

356 data += self.principal.getData() 

357 for credential in self.credentials: 

358 data += credential.getData() 

359 return data 

360 

361 def getCredential(self, server, anySPN=True): 

362 for c in self.credentials: 

363 if c['server'].prettyPrint().upper() == b(server.upper()) or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper())\ 

364 or c['server'].prettyPrint().upper().split(b'@')[0] == b(server.upper().split('@')[0]): 

365 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8')) 

366 return c 

367 LOG.debug('SPN %s not found in cache' % server.upper()) 

368 if anySPN is True: 

369 LOG.debug('AnySPN is True, looking for another suitable SPN') 

370 for c in self.credentials: 

371 # Let's search for any TGT/TGS that matches the server w/o the SPN's service type/port, returns 

372 # the first one 

373 if c['server'].prettyPrint().find(b'/') >=0: 

374 # Let's take the port out for comparison 

375 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]) 

376 searchSPN = '%s@%s' % (server.upper().split('/')[1].split('@')[0].split(':')[0], 

377 server.upper().split('/')[1].split('@')[1]) 

378 if cachedSPN == b(searchSPN): 

379 LOG.debug('Returning cached credential for %s' % c['server'].prettyPrint().upper().decode('utf-8')) 

380 return c 

381 

382 return None 

383 

384 def toTimeStamp(self, dt, epoch=datetime(1970,1,1)): 

385 td = dt - epoch 

386 # return td.total_seconds() 

387 return int((td.microseconds + (td.seconds + td.days * 24 * 3600) * 10**6) // 1e6) 

388 

389 def reverseFlags(self, flags): 

390 result = 0 

391 if isinstance(flags, str): 

392 flags = flags[1:-2] 

393 for i,j in enumerate(reversed(flags)): 

394 if j != 0: 

395 result += j << i 

396 return result 

397 

398 def fromTGT(self, tgt, oldSessionKey, sessionKey): 

399 self.headers = [] 

400 header = Header() 

401 header['tag'] = 1 

402 header['taglen'] = 8 

403 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

404 self.headers.append(header) 

405 

406 decodedTGT = decoder.decode(tgt, asn1Spec = AS_REP())[0] 

407 

408 tmpPrincipal = types.Principal() 

409 tmpPrincipal.from_asn1(decodedTGT, 'crealm', 'cname') 

410 self.principal = Principal() 

411 self.principal.fromPrincipal(tmpPrincipal) 

412 

413 # Now let's add the credential 

414 cipherText = decodedTGT['enc-part']['cipher'] 

415 

416 cipher = crypto._enctype_table[decodedTGT['enc-part']['etype']] 

417 

418 # Key Usage 3 

419 # AS-REP encrypted part (includes TGS session key or 

420 # application session key), encrypted with the client key 

421 # (Section 5.4.2) 

422 plainText = cipher.decrypt(oldSessionKey, 3, cipherText) 

423 

424 encASRepPart = decoder.decode(plainText, asn1Spec = EncASRepPart())[0] 

425 credential = Credential() 

426 server = types.Principal() 

427 server.from_asn1(encASRepPart, 'srealm', 'sname') 

428 tmpServer = Principal() 

429 tmpServer.fromPrincipal(server) 

430 

431 credential['client'] = self.principal 

432 credential['server'] = tmpServer 

433 credential['is_skey'] = 0 

434 

435 credential['key'] = KeyBlock() 

436 credential['key']['keytype'] = int(encASRepPart['key']['keytype']) 

437 credential['key']['keyvalue'] = encASRepPart['key']['keyvalue'].asOctets() 

438 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

439 

440 credential['time'] = Times() 

441 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['authtime'])) 

442 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['starttime'])) 

443 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['endtime'])) 

444 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encASRepPart['renew-till'])) 

445 

446 flags = self.reverseFlags(encASRepPart['flags']) 

447 credential['tktflags'] = flags 

448 

449 credential['num_address'] = 0 

450 credential.ticket = CountedOctetString() 

451 credential.ticket['data'] = encoder.encode(decodedTGT['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True)) 

452 credential.ticket['length'] = len(credential.ticket['data']) 

453 credential.secondTicket = CountedOctetString() 

454 credential.secondTicket['data'] = b'' 

455 credential.secondTicket['length'] = 0 

456 self.credentials.append(credential) 

457 

458 def fromTGS(self, tgs, oldSessionKey, sessionKey): 

459 self.headers = [] 

460 header = Header() 

461 header['tag'] = 1 

462 header['taglen'] = 8 

463 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

464 self.headers.append(header) 

465 

466 decodedTGS = decoder.decode(tgs, asn1Spec = TGS_REP())[0] 

467 

468 tmpPrincipal = types.Principal() 

469 tmpPrincipal.from_asn1(decodedTGS, 'crealm', 'cname') 

470 self.principal = Principal() 

471 self.principal.fromPrincipal(tmpPrincipal) 

472 

473 # Now let's add the credential 

474 cipherText = decodedTGS['enc-part']['cipher'] 

475 

476 cipher = crypto._enctype_table[decodedTGS['enc-part']['etype']] 

477 

478 # Key Usage 8 

479 # TGS-REP encrypted part (includes application session 

480 # key), encrypted with the TGS session key (Section 5.4.2) 

481 plainText = cipher.decrypt(oldSessionKey, 8, cipherText) 

482 

483 encTGSRepPart = decoder.decode(plainText, asn1Spec = EncTGSRepPart())[0] 

484 

485 credential = Credential() 

486 server = types.Principal() 

487 server.from_asn1(encTGSRepPart, 'srealm', 'sname') 

488 tmpServer = Principal() 

489 tmpServer.fromPrincipal(server) 

490 

491 credential['client'] = self.principal 

492 credential['server'] = tmpServer 

493 credential['is_skey'] = 0 

494 

495 credential['key'] = KeyBlock() 

496 credential['key']['keytype'] = int(encTGSRepPart['key']['keytype']) 

497 credential['key']['keyvalue'] = encTGSRepPart['key']['keyvalue'].asOctets() 

498 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

499 

500 credential['time'] = Times() 

501 credential['time']['authtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['authtime'])) 

502 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['starttime'])) 

503 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['endtime'])) 

504 # After KB4586793 for CVE-2020-17049 this timestamp may be omitted 

505 if encTGSRepPart['renew-till'].hasValue(): 

506 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(encTGSRepPart['renew-till'])) 

507 

508 flags = self.reverseFlags(encTGSRepPart['flags']) 

509 credential['tktflags'] = flags 

510 

511 credential['num_address'] = 0 

512 

513 credential.ticket = CountedOctetString() 

514 credential.ticket['data'] = encoder.encode(decodedTGS['ticket'].clone(tagSet=Ticket.tagSet, cloneValueFlag=True)) 

515 credential.ticket['length'] = len(credential.ticket['data']) 

516 credential.secondTicket = CountedOctetString() 

517 credential.secondTicket['data'] = b'' 

518 credential.secondTicket['length'] = 0 

519 self.credentials.append(credential) 

520 

521 @classmethod 

522 def loadFile(cls, fileName): 

523 f = open(fileName,'rb') 

524 data = f.read() 

525 f.close() 

526 return cls(data) 

527 

528 def saveFile(self, fileName): 

529 f = open(fileName,'wb+') 

530 f.write(self.getData()) 

531 f.close() 

532 

533 def prettyPrint(self): 

534 print(("Primary Principal: %s" % self.principal.prettyPrint())) 

535 print("Credentials: ") 

536 for i, credential in enumerate(self.credentials): 

537 print(("[%d]" % i)) 

538 credential.prettyPrint('\t') 

539 

540 @classmethod 

541 def loadKirbiFile(cls, fileName): 

542 f = open(fileName, 'rb') 

543 data = f.read() 

544 f.close() 

545 ccache = cls() 

546 ccache.fromKRBCRED(data) 

547 return ccache 

548 

549 def saveKirbiFile(self, fileName): 

550 f = open(fileName, 'wb+') 

551 f.write(self.toKRBCRED()) 

552 f.close() 

553 

554 def fromKRBCRED(self, encodedKrbCred): 

555 

556 krbCred = decoder.decode(encodedKrbCred, asn1Spec=KRB_CRED())[0] 

557 encKrbCredPart = decoder.decode(krbCred['enc-part']['cipher'], asn1Spec=EncKrbCredPart())[0] 

558 krbCredInfo = encKrbCredPart['ticket-info'][0] 

559 

560 self.setDefaultHeader() 

561 

562 tmpPrincipal = types.Principal() 

563 tmpPrincipal.from_asn1(krbCredInfo, 'prealm', 'pname') 

564 self.principal = Principal() 

565 self.principal.fromPrincipal(tmpPrincipal) 

566 

567 credential = Credential() 

568 server = types.Principal() 

569 server.from_asn1(krbCredInfo, 'srealm', 'sname') 

570 tmpServer = Principal() 

571 tmpServer.fromPrincipal(server) 

572 

573 credential['client'] = self.principal 

574 credential['server'] = tmpServer 

575 credential['is_skey'] = 0 

576 

577 credential['key'] = KeyBlock() 

578 credential['key']['keytype'] = int(krbCredInfo['key']['keytype']) 

579 credential['key']['keyvalue'] = str(krbCredInfo['key']['keyvalue']) 

580 credential['key']['keylen'] = len(credential['key']['keyvalue']) 

581 

582 credential['time'] = Times() 

583 

584 credential['time']['starttime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['starttime'])) 

585 credential['time']['endtime'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['endtime'])) 

586 credential['time']['renew_till'] = self.toTimeStamp(types.KerberosTime.from_asn1(krbCredInfo['renew-till'])) 

587 

588 flags = self.reverseFlags(krbCredInfo['flags']) 

589 credential['tktflags'] = flags 

590 

591 credential['num_address'] = 0 

592 credential.ticket = CountedOctetString() 

593 credential.ticket['data'] = encoder.encode( 

594 krbCred['tickets'][0].clone(tagSet=Ticket.tagSet, cloneValueFlag=True) 

595 ) 

596 credential.ticket['length'] = len(credential.ticket['data']) 

597 credential.secondTicket = CountedOctetString() 

598 credential.secondTicket['data'] = '' 

599 credential.secondTicket['length'] = 0 

600 

601 self.credentials.append(credential) 

602 

603 def toKRBCRED(self): 

604 principal = self.principal 

605 credential = self.credentials[0] 

606 

607 krbCredInfo = KrbCredInfo() 

608 

609 krbCredInfo['key'] = noValue 

610 krbCredInfo['key']['keytype'] = credential['key']['keytype'] 

611 krbCredInfo['key']['keyvalue'] = credential['key']['keyvalue'] 

612 

613 krbCredInfo['prealm'] = principal.realm.fields['data'] 

614 

615 krbCredInfo['pname'] = noValue 

616 krbCredInfo['pname']['name-type'] = principal.header['name_type'] 

617 seq_set_iter(krbCredInfo['pname'], 'name-string', (principal.components[0].fields['data'],)) 

618 

619 krbCredInfo['flags'] = credential['tktflags'] 

620 

621 krbCredInfo['starttime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['starttime'])) 

622 krbCredInfo['endtime'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['endtime'])) 

623 krbCredInfo['renew-till'] = KerberosTime.to_asn1(datetime.utcfromtimestamp(credential['time']['renew_till'])) 

624 

625 krbCredInfo['srealm'] = credential['server'].realm.fields['data'] 

626 

627 krbCredInfo['sname'] = noValue 

628 krbCredInfo['sname']['name-type'] = credential['server'].header['name_type'] 

629 seq_set_iter(krbCredInfo['sname'], 'name-string', 

630 (credential['server'].components[0].fields['data'], credential['server'].realm.fields['data'])) 

631 

632 encKrbCredPart = EncKrbCredPart() 

633 seq_set_iter(encKrbCredPart, 'ticket-info', (krbCredInfo,)) 

634 

635 krbCred = KRB_CRED() 

636 krbCred['pvno'] = 5 

637 krbCred['msg-type'] = 22 

638 

639 krbCred['enc-part'] = noValue 

640 krbCred['enc-part']['etype'] = 0 

641 krbCred['enc-part']['cipher'] = encoder.encode(encKrbCredPart) 

642 

643 ticket = decoder.decode(credential.ticket['data'], asn1Spec=Ticket())[0] 

644 seq_set_iter(krbCred, 'tickets', (ticket,)) 

645 

646 encodedKrbCred = encoder.encode(krbCred) 

647 

648 return encodedKrbCred 

649 

650 def setDefaultHeader(self): 

651 self.headers = [] 

652 header = Header() 

653 header['tag'] = 1 

654 header['taglen'] = 8 

655 header['tagdata'] = b'\xff\xff\xff\xff\x00\x00\x00\x00' 

656 self.headers.append(header) 

657 

658 

659 

660if __name__ == '__main__': 660 ↛ 661line 660 didn't jump to line 661, because the condition on line 660 was never true

661 import os 

662 ccache = CCache.loadFile(os.getenv('KRB5CCNAME')) 

663 ccache.prettyPrint()