| 311 | |
| 312 | |
| 313 | class KeytabEntry(Packet): |
| 314 | fields_desc = [ |
| 315 | IntField("size", None), |
| 316 | FieldLenField("num_components", None, count_of="components"), |
| 317 | PacketField("realm", KTCountedOctetString(), KTCountedOctetString), |
| 318 | PacketListField( |
| 319 | "components", |
| 320 | [], |
| 321 | KTCountedOctetString, |
| 322 | count_from=lambda pkt: pkt.num_components, |
| 323 | ), |
| 324 | ConditionalField( |
| 325 | IntField("name_type", 0), |
| 326 | lambda pkt: pkt.parent.file_format_version != 0x501, |
| 327 | ), |
| 328 | UTCTimeField("timestamp", None), |
| 329 | ByteField("vno8", 0), |
| 330 | MayEnd(PacketField("key", KTKeyBlock(), KTKeyBlock)), |
| 331 | ConditionalField( |
| 332 | IntField("vno", None), |
| 333 | lambda pkt: "vno" in pkt.fields is not None or pkt.original, |
| 334 | ), |
| 335 | ] |
| 336 | |
| 337 | def getPrincipal(self): |
| 338 | comp = "/".join(x.data.decode() for x in self.components) |
| 339 | if self.realm.data: |
| 340 | return "%s@%s" % ( |
| 341 | comp, |
| 342 | self.realm.data.decode(), |
| 343 | ) |
| 344 | else: |
| 345 | return comp |
| 346 | |
| 347 | @property |
| 348 | def versionNumber(self): |
| 349 | if self.vno is not None: |
| 350 | return self.vno |
| 351 | return self.vno8 |
| 352 | |
| 353 | def post_build(self, p, pay): |
| 354 | # type: (bytes, bytes) -> bytes |
| 355 | if self.size is None: |
| 356 | p = struct.pack("!I", len(p)) + p[4:] |
| 357 | return p + pay |
| 358 | |
| 359 | def extract_padding(self, s): |
| 360 | # type: (bytes) -> Tuple[bytes, bytes] |
| 361 | rem = self.size - len(self.original) |
| 362 | return s[:rem], s[rem:] |
| 363 | |
| 364 | |
| 365 | class Keytab(Packet): |
no test coverage detected