Browse code

Improve simple-to-full layout conversion.

yamltab now computes record lengths.

Xavier G authored on 26/04/2020 20:38:01
Showing 1 changed files

  • yamltab index 5ee11ed..c199220 100755
... ...
@@ -320,6 +320,12 @@ def output_data(data, args, exit=None):
320 320
 	if exit is not None:
321 321
 		sys.exit(exit)
322 322
 
323
+def len_data(data):
324
+	return 2 + len(data)
325
+
326
+def len_str(string, encoding=DEFAULT_ENCODING):
327
+	return len_data(string.encode(encoding))
328
+
323 329
 def pack_data(data):
324 330
 	return struct.pack('>H', len(data)) + data
325 331
 
... ...
@@ -420,6 +426,16 @@ def spn_to_principal(spn, name_type='KRB5_NT_PRINCIPAL'):
420 426
 			principal['components'].append(component)
421 427
 	return principal
422 428
 
429
+def principal_length(principal):
430
+	# component count:
431
+	length = 2
432
+	length += len_str(principal.get('realm', ''))
433
+	for component in principal.get('components', []):
434
+		length += len_str(component)
435
+	if principal.get('name_type_raw', principal.get('name_type')):
436
+		length += 4
437
+	return length
438
+
423 439
 def simple_principal_to_full(inentry, index, entry):
424 440
 	if 'principal' in inentry:
425 441
 		principal = entry['principal'] = inentry['principal']
... ...
@@ -434,6 +450,7 @@ def simple_principal_to_full(inentry, index, entry):
434 450
 	elif 'spn' in inentry:
435 451
 		entry['spn'] = inentry['spn']
436 452
 		entry['principal'] = spn_to_principal(inentry['spn'])
453
+	return principal_length(entry['principal'])
437 454
 
438 455
 def simple_kvno_to_full(inentry, index, entry, record):
439 456
 	if 'kvno' in inentry:
... ...
@@ -447,6 +464,7 @@ def simple_kvno_to_full(inentry, index, entry, record):
447 464
 			message = 'Cannot store kvno > 255 without kvno_in_tail in entry #%d'
448 465
 			raise KeytabComposingError(message % index)
449 466
 		record['tail'] += to_bytes(inentry.get('extra_tail', b''))
467
+	return 1
450 468
 
451 469
 def simple_timestamp_to_full(inentry, index, entry):
452 470
 	if 'timestamp' in inentry:
... ...
@@ -461,6 +479,7 @@ def simple_timestamp_to_full(inentry, index, entry):
461 479
 				entry['timestamp'] = int(parsed_date.timestamp())
462 480
 			except:
463 481
 				raise KeytabParsingError('Invalid date specified in entry #%d' % index)
482
+	return 4
464 483
 
465 484
 def simple_enctype_to_full(inentry, index,  entry):
466 485
 	if 'enctype_raw' in inentry:
... ...
@@ -473,6 +492,7 @@ def simple_enctype_to_full(inentry, index,  entry):
473 492
 			message = 'Invalid or unknown enctype specified in entry #%d'
474 493
 			message += '; use enctype_raw to enforce an arbitrary value'
475 494
 			raise KeytabParsingError(message % index)
495
+	return 2
476 496
 
477 497
 def simple_keytab_to_full(indata):
478 498
 	now = int(datetime.now().timestamp())
... ...
@@ -483,13 +503,17 @@ def simple_keytab_to_full(indata):
483 503
 	for index, inentry in enumerate(indata.get('entries', [])):
484 504
 		entry = {}
485 505
 		record = {'type': 'record', 'entry': entry, 'tail': b''}
486
-		simple_principal_to_full(inentry, index, entry)
487
-		simple_kvno_to_full(inentry, index, entry, record)
488
-		simple_timestamp_to_full(inentry, index, entry)
489
-		simple_enctype_to_full(inentry, index, entry)
506
+		length = 0
507
+		length += simple_principal_to_full(inentry, index, entry)
508
+		length += simple_kvno_to_full(inentry, index, entry, record)
509
+		length += simple_timestamp_to_full(inentry, index, entry)
510
+		length += simple_enctype_to_full(inentry, index, entry)
490 511
 		if 'key' in inentry:
491 512
 			entry['key'] = inentry['key']
492 513
 			entry['key_length'] = len(to_bytes(inentry['key']))
514
+			length += 2 + entry['key_length']
515
+		length += len(to_bytes(record['tail']))
516
+		record['length'] = length
493 517
 		data['records'].append(record)
494 518
 	return data
495 519