3
3
import argparse
4
4
import contextlib
5
5
import json
6
+ from pathlib import Path
6
7
import re
8
+ import pprp
7
9
8
10
CHECKSUM_MIN_VERSION = ('V1.0' , 'beta' , '1' )
9
11
10
12
11
- def BYTE4 (n ):
12
- return (n & 0xFF000000 ) >> 24
13
-
14
- def BYTE3 (n ):
15
- return (n & 0x00FF0000 ) >> 16
16
-
17
-
18
- def BYTE2 (n ):
19
- return (n & 0x0000FF00 ) >> 8
20
-
21
-
22
- def BYTE1 (n ):
23
- return (n & 0x000000FF ) >> 0
24
-
13
+ def eac_checksum (text ):
14
+ # Ignore newlines
15
+ text = text .replace ('\r ' , '' ).replace ('\n ' , '' )
25
16
26
- def rotate_right ( n ):
27
- return (( n & 0x000000FF ) << 24 ) | ( n >> 8 )
17
+ # Fuzzing reveals BOMs are also ignored
18
+ text = text . replace ( ' \ufeff ' , '' ). replace ( ' \ufffe ' , '' )
28
19
20
+ # Setup Rijndael-256 with a 256-bit blocksize
21
+ cipher = pprp .crypto_3 .rijndael (
22
+ # Probably SHA256('super secret password') but it doesn't actually matter
23
+ key = bytes .fromhex ('9378716cf13e4265ae55338e940b376184da389e50647726b35f6f341ee3efd9' ),
24
+ block_size = 256 // 8
25
+ )
29
26
30
- UNKNOWNS = [0x6C717893 , 0x65423EF1 , 0x8E3355AE , 0x61370B94 , 0x9E38DA84 , 0x26776450 , 0x346F5FB3 , 0xD9EFE31E , 0x1E44A783 , 0x7B069972 , 0xF535CCDC , 0x9402C748 , 0xBC4F1CD6 , 0x9A387886 , 0xAE572735 , 0x77B8C42B , 0xEFB1CB9D , 0x94B752EF , 0x61829E33 , 0xF580597B , 0x5A82D7F7 , 0xC0BAAF71 , 0x6EED8844 , 0x19554C6F , 0x476537B0 , 0xD3D2655F , 0xB250FB6C , 0x47D0A217 , 0xFAF2ED07 , 0x3A484276 , 0x54A5CA32 , 0x4DF0865D , 0x0B86BBFC , 0xD854DEA3 , 0x6A0425CF , 0x2DD487D8 , 0x22BAFA66 , 0x18F2B810 , 0x4C577222 , 0x01A7F47F , 0xD9FAE753 , 0x01AE39F0 , 0x6BAA1C3F , 0x467E9BE7 , 0x7849EEF2 , 0x60BB56E2 , 0x2CEC24C0 , 0x2D4BD0BF , 0xD1225403 , 0xD08C6DF3 , 0xBB2671CC , 0xFD58EA2B , 0x2C236903 , 0x4C983FE1 , 0x60741B21 , 0x4D3FCB9E , 0xDAC1215C , 0x0A4D4CAF , 0xB16B3D63 , 0x4C33D748 , 0x05E06751 , 0x497858B0 , 0x290C4391 , 0x6433880F , 0xAC82E218 , 0xA6CFAEB7 , 0x17A493D4 , 0x5B97449C , 0x3C687C8F , 0x7510243F , 0x5C1C67AE , 0x382FEFA1 , 0x9E85F7DC , 0x384A596B , 0x2FEECABF , 0x74798E23 , 0xAEDE65A9 , 0xDBCE4196 , 0x87D22638 , 0xBFFDC999 , 0x708DA337 , 0x48C7FA5C , 0x672930E3 , 0x1350BEC0 , 0xD38DCB13 , 0x08438A85 , 0x8F91ACBD , 0x306C6524 , 0x4689F316 , 0x0E4E094A , 0x696739A9 , 0x7A378769 , 0x0917DCEA , 0x0154566F , 0x8EC5FAD2 , 0xBEA99FF6 , 0x04272015 , 0x0A69295F , 0x630E10F6 , 0x1939979F , 0xDD055431 , 0xDC51025E , 0x5294F88C , 0xEC3D677A , 0xDEE9073B , 0xD4802E64 , 0xB78E3E92 , 0xAEB7A90D , 0x39AC87E6 , 0xE5FD85B8 , 0xB7697D34 , 0x5B541A4E , 0xF1D027D4 , 0x255009B0 , 0x92DE3722 , 0x3C699E2F , 0xD2558CF3 , 0x37A8094B , 0x80C1747F , 0xDB956E31 ]
31
- S_BOX = [0x63 , 0x7C , 0x77 , 0x7B , 0xF2 , 0x6B , 0x6F , 0xC5 , 0x30 , 0x01 , 0x67 , 0x2B , 0xFE , 0xD7 , 0xAB , 0x76 , 0xCA , 0x82 , 0xC9 , 0x7D , 0xFA , 0x59 , 0x47 , 0xF0 , 0xAD , 0xD4 , 0xA2 , 0xAF , 0x9C , 0xA4 , 0x72 , 0xC0 , 0xB7 , 0xFD , 0x93 , 0x26 , 0x36 , 0x3F , 0xF7 , 0xCC , 0x34 , 0xA5 , 0xE5 , 0xF1 , 0x71 , 0xD8 , 0x31 , 0x15 , 0x04 , 0xC7 , 0x23 , 0xC3 , 0x18 , 0x96 , 0x05 , 0x9A , 0x07 , 0x12 , 0x80 , 0xE2 , 0xEB , 0x27 , 0xB2 , 0x75 , 0x09 , 0x83 , 0x2C , 0x1A , 0x1B , 0x6E , 0x5A , 0xA0 , 0x52 , 0x3B , 0xD6 , 0xB3 , 0x29 , 0xE3 , 0x2F , 0x84 , 0x53 , 0xD1 , 0x00 , 0xED , 0x20 , 0xFC , 0xB1 , 0x5B , 0x6A , 0xCB , 0xBE , 0x39 , 0x4A , 0x4C , 0x58 , 0xCF , 0xD0 , 0xEF , 0xAA , 0xFB , 0x43 , 0x4D , 0x33 , 0x85 , 0x45 , 0xF9 , 0x02 , 0x7F , 0x50 , 0x3C , 0x9F , 0xA8 , 0x51 , 0xA3 , 0x40 , 0x8F , 0x92 , 0x9D , 0x38 , 0xF5 , 0xBC , 0xB6 , 0xDA , 0x21 , 0x10 , 0xFF , 0xF3 , 0xD2 , 0xCD , 0x0C , 0x13 , 0xEC , 0x5F , 0x97 , 0x44 , 0x17 , 0xC4 , 0xA7 , 0x7E , 0x3D , 0x64 , 0x5D , 0x19 , 0x73 , 0x60 , 0x81 , 0x4F , 0xDC , 0x22 , 0x2A , 0x90 , 0x88 , 0x46 , 0xEE , 0xB8 , 0x14 , 0xDE , 0x5E , 0x0B , 0xDB , 0xE0 , 0x32 , 0x3A , 0x0A , 0x49 , 0x06 , 0x24 , 0x5C , 0xC2 , 0xD3 , 0xAC , 0x62 , 0x91 , 0x95 , 0xE4 , 0x79 , 0xE7 , 0xC8 , 0x37 , 0x6D , 0x8D , 0xD5 , 0x4E , 0xA9 , 0x6C , 0x56 , 0xF4 , 0xEA , 0x65 , 0x7A , 0xAE , 0x08 , 0xBA , 0x78 , 0x25 , 0x2E , 0x1C , 0xA6 , 0xB4 , 0xC6 , 0xE8 , 0xDD , 0x74 , 0x1F , 0x4B , 0xBD , 0x8B , 0x8A , 0x70 , 0x3E , 0xB5 , 0x66 , 0x48 , 0x03 , 0xF6 , 0x0E , 0x61 , 0x35 , 0x57 , 0xB9 , 0x86 , 0xC1 , 0x1D , 0x9E , 0xE1 , 0xF8 , 0x98 , 0x11 , 0x69 , 0xD9 , 0x8E , 0x94 , 0x9B , 0x1E , 0x87 , 0xE9 , 0xCE , 0x55 , 0x28 , 0xDF , 0x8C , 0xA1 , 0x89 , 0x0D , 0xBF , 0xE6 , 0x42 , 0x68 , 0x41 , 0x99 , 0x2D , 0x0F , 0xB0 , 0x54 , 0xBB , 0x16 ]
27
+ # Encode the text as UTF-16-LE
28
+ plaintext = text .encode ('utf-16-le' )
32
29
33
- T1 = [0xC6A56363 , 0xF8847C7C , 0xEE997777 , 0xF68D7B7B , 0xFF0DF2F2 , 0xD6BD6B6B , 0xDEB16F6F , 0x9154C5C5 , 0x60503030 , 0x02030101 , 0xCEA96767 , 0x567D2B2B , 0xE719FEFE , 0xB562D7D7 , 0x4DE6ABAB , 0xEC9A7676 , 0x8F45CACA , 0x1F9D8282 , 0x8940C9C9 , 0xFA877D7D , 0xEF15FAFA , 0xB2EB5959 , 0x8EC94747 , 0xFB0BF0F0 , 0x41ECADAD , 0xB367D4D4 , 0x5FFDA2A2 , 0x45EAAFAF , 0x23BF9C9C , 0x53F7A4A4 , 0xE4967272 , 0x9B5BC0C0 , 0x75C2B7B7 , 0xE11CFDFD , 0x3DAE9393 , 0x4C6A2626 , 0x6C5A3636 , 0x7E413F3F , 0xF502F7F7 , 0x834FCCCC , 0x685C3434 , 0x51F4A5A5 , 0xD134E5E5 , 0xF908F1F1 , 0xE2937171 , 0xAB73D8D8 , 0x62533131 , 0x2A3F1515 , 0x080C0404 , 0x9552C7C7 , 0x46652323 , 0x9D5EC3C3 , 0x30281818 , 0x37A19696 , 0x0A0F0505 , 0x2FB59A9A , 0x0E090707 , 0x24361212 , 0x1B9B8080 , 0xDF3DE2E2 , 0xCD26EBEB , 0x4E692727 , 0x7FCDB2B2 , 0xEA9F7575 , 0x121B0909 , 0x1D9E8383 , 0x58742C2C , 0x342E1A1A , 0x362D1B1B , 0xDCB26E6E , 0xB4EE5A5A , 0x5BFBA0A0 , 0xA4F65252 , 0x764D3B3B , 0xB761D6D6 , 0x7DCEB3B3 , 0x527B2929 , 0xDD3EE3E3 , 0x5E712F2F , 0x13978484 , 0xA6F55353 , 0xB968D1D1 , 0x0 , 0xC12CEDED , 0x40602020 , 0xE31FFCFC , 0x79C8B1B1 , 0xB6ED5B5B , 0xD4BE6A6A , 0x8D46CBCB , 0x67D9BEBE , 0x724B3939 , 0x94DE4A4A , 0x98D44C4C , 0xB0E85858 , 0x854ACFCF , 0xBB6BD0D0 , 0xC52AEFEF , 0x4FE5AAAA , 0xED16FBFB , 0x86C54343 , 0x9AD74D4D , 0x66553333 , 0x11948585 , 0x8ACF4545 , 0xE910F9F9 , 0x04060202 , 0xFE817F7F , 0xA0F05050 , 0x78443C3C , 0x25BA9F9F , 0x4BE3A8A8 , 0xA2F35151 , 0x5DFEA3A3 , 0x80C04040 , 0x058A8F8F , 0x3FAD9292 , 0x21BC9D9D , 0x70483838 , 0xF104F5F5 , 0x63DFBCBC , 0x77C1B6B6 , 0xAF75DADA , 0x42632121 , 0x20301010 , 0xE51AFFFF , 0xFD0EF3F3 , 0xBF6DD2D2 , 0x814CCDCD , 0x18140C0C , 0x26351313 , 0xC32FECEC , 0xBEE15F5F , 0x35A29797 , 0x88CC4444 , 0x2E391717 , 0x9357C4C4 , 0x55F2A7A7 , 0xFC827E7E , 0x7A473D3D , 0xC8AC6464 , 0xBAE75D5D , 0x322B1919 , 0xE6957373 , 0xC0A06060 , 0x19988181 , 0x9ED14F4F , 0xA37FDCDC , 0x44662222 , 0x547E2A2A , 0x3BAB9090 , 0x0B838888 , 0x8CCA4646 , 0xC729EEEE , 0x6BD3B8B8 , 0x283C1414 , 0xA779DEDE , 0xBCE25E5E , 0x161D0B0B , 0xAD76DBDB , 0xDB3BE0E0 , 0x64563232 , 0x744E3A3A , 0x141E0A0A , 0x92DB4949 , 0x0C0A0606 , 0x486C2424 , 0xB8E45C5C , 0x9F5DC2C2 , 0xBD6ED3D3 , 0x43EFACAC , 0xC4A66262 , 0x39A89191 , 0x31A49595 , 0xD337E4E4 , 0xF28B7979 , 0xD532E7E7 , 0x8B43C8C8 , 0x6E593737 , 0xDAB76D6D , 0x018C8D8D , 0xB164D5D5 , 0x9CD24E4E , 0x49E0A9A9 , 0xD8B46C6C , 0xACFA5656 , 0xF307F4F4 , 0xCF25EAEA , 0xCAAF6565 , 0xF48E7A7A , 0x47E9AEAE , 0x10180808 , 0x6FD5BABA , 0xF0887878 , 0x4A6F2525 , 0x5C722E2E , 0x38241C1C , 0x57F1A6A6 , 0x73C7B4B4 , 0x9751C6C6 , 0xCB23E8E8 , 0xA17CDDDD , 0xE89C7474 , 0x3E211F1F , 0x96DD4B4B , 0x61DCBDBD , 0x0D868B8B , 0x0F858A8A , 0xE0907070 , 0x7C423E3E , 0x71C4B5B5 , 0xCCAA6666 , 0x90D84848 , 0x06050303 , 0xF701F6F6 , 0x1C120E0E , 0xC2A36161 , 0x6A5F3535 , 0xAEF95757 , 0x69D0B9B9 , 0x17918686 , 0x9958C1C1 , 0x3A271D1D , 0x27B99E9E , 0xD938E1E1 , 0xEB13F8F8 , 0x2BB39898 , 0x22331111 , 0xD2BB6969 , 0xA970D9D9 , 0x07898E8E , 0x33A79494 , 0x2DB69B9B , 0x3C221E1E , 0x15928787 , 0xC920E9E9 , 0x8749CECE , 0xAAFF5555 , 0x50782828 , 0xA57ADFDF , 0x038F8C8C , 0x59F8A1A1 , 0x09808989 , 0x1A170D0D , 0x65DABFBF , 0xD731E6E6 , 0x84C64242 , 0xD0B86868 , 0x82C34141 , 0x29B09999 , 0x5A772D2D , 0x1E110F0F , 0x7BCBB0B0 , 0xA8FC5454 , 0x6DD6BBBB , 0x2C3A1616 ]
34
- T2 = list (map (rotate_right , T1 ))
35
- T3 = list (map (rotate_right , T2 ))
36
- T4 = list (map (rotate_right , T3 ))
30
+ # The IV is all zeroes so we don't have to handle it
31
+ signature = b'\x00 ' * 32
37
32
33
+ # Process it block-by-block
34
+ for i in range (0 , len (plaintext ), 32 ):
35
+ # Zero-pad the last block, if necessary
36
+ plaintext_block = plaintext [i :i + 32 ].ljust (32 , b'\x00 ' )
38
37
39
- def eac_checksum (text ):
40
- # Ignore newlines
41
- text = text .replace ('\r ' , '' ).replace ('\n ' , '' )
38
+ # CBC mode (XOR the previous ciphertext block into the plaintext)
39
+ cbc_plaintext = bytes (a ^ b for a , b in zip (signature , plaintext_block ))
42
40
43
- # Fuzzing reveals BOMs are ignored
44
- text = text . replace ( ' \ufeff ' , '' ). replace ( ' \ufffe ' , '' )
41
+ # New signature is the ciphertext.
42
+ signature = cipher . encrypt ( cbc_plaintext )
45
43
46
- # Initialize the "AES" state
47
- aes_state = [0 , 0 , 0 , 0 , 0 , 0 , 0 , 0 ]
48
-
49
- # Read the text in chunks of 16
50
- for i in range (0 , len (text ), 16 ):
51
- # Pad the final chunk with zero bytes
52
- chunk = text [i :i + 16 ].ljust (16 , '\x00 ' )
53
-
54
- # Mix pairs of characters into the AES state
55
- for i , offset in enumerate (range (0 , 16 , 2 )):
56
- aes_state [i ] ^= int .from_bytes (chunk [offset :offset + 2 ].encode ('utf-16le' ), 'little' )
57
-
58
- # Perform one "AES" round
59
- a1 = UNKNOWNS [0 ] ^ aes_state [0 ]
60
- a2 = UNKNOWNS [1 ] ^ aes_state [1 ]
61
- a3 = UNKNOWNS [2 ] ^ aes_state [2 ]
62
- a4 = UNKNOWNS [3 ] ^ aes_state [3 ]
63
- a5 = UNKNOWNS [4 ] ^ aes_state [4 ]
64
- a6 = UNKNOWNS [5 ] ^ aes_state [5 ]
65
- a7 = UNKNOWNS [6 ] ^ aes_state [6 ]
66
- a8 = UNKNOWNS [7 ] ^ aes_state [7 ]
67
-
68
- for i in range (0 , 13 ):
69
- b1 = UNKNOWNS [ 8 + 8 * i ] ^ (T1 [BYTE4 (a5 )] ^ T2 [BYTE3 (a4 )] ^ T3 [BYTE2 (a2 )] ^ T4 [BYTE1 (a1 )])
70
- b2 = UNKNOWNS [ 9 + 8 * i ] ^ (T1 [BYTE4 (a6 )] ^ T2 [BYTE3 (a5 )] ^ T3 [BYTE2 (a3 )] ^ T4 [BYTE1 (a2 )])
71
- b3 = UNKNOWNS [10 + 8 * i ] ^ (T1 [BYTE4 (a7 )] ^ T2 [BYTE3 (a6 )] ^ T3 [BYTE2 (a4 )] ^ T4 [BYTE1 (a3 )])
72
- b4 = UNKNOWNS [11 + 8 * i ] ^ (T1 [BYTE4 (a8 )] ^ T2 [BYTE3 (a7 )] ^ T3 [BYTE2 (a5 )] ^ T4 [BYTE1 (a4 )])
73
- b5 = UNKNOWNS [12 + 8 * i ] ^ (T1 [BYTE4 (a1 )] ^ T2 [BYTE3 (a8 )] ^ T3 [BYTE2 (a6 )] ^ T4 [BYTE1 (a5 )])
74
- b6 = UNKNOWNS [13 + 8 * i ] ^ (T1 [BYTE4 (a2 )] ^ T2 [BYTE3 (a1 )] ^ T3 [BYTE2 (a7 )] ^ T4 [BYTE1 (a6 )])
75
- b7 = UNKNOWNS [14 + 8 * i ] ^ (T1 [BYTE4 (a3 )] ^ T2 [BYTE3 (a2 )] ^ T3 [BYTE2 (a8 )] ^ T4 [BYTE1 (a7 )])
76
- b8 = UNKNOWNS [15 + 8 * i ] ^ (T1 [BYTE4 (a4 )] ^ T2 [BYTE3 (a3 )] ^ T3 [BYTE2 (a1 )] ^ T4 [BYTE1 (a8 )])
77
-
78
- a1 = b1
79
- a2 = b2
80
- a3 = b3
81
- a4 = b4
82
- a5 = b5
83
- a6 = b6
84
- a7 = b7
85
- a8 = b8
86
-
87
- aes_state [0 ] = UNKNOWNS [112 ] ^ ((S_BOX [BYTE4 (a5 )] << 24 ) | (S_BOX [BYTE3 (a4 )] << 16 ) | (S_BOX [BYTE2 (a2 )] << 8 ) | S_BOX [BYTE1 (a1 )])
88
- aes_state [1 ] = UNKNOWNS [113 ] ^ ((S_BOX [BYTE4 (a6 )] << 24 ) | (S_BOX [BYTE3 (a5 )] << 16 ) | (S_BOX [BYTE2 (a3 )] << 8 ) | S_BOX [BYTE1 (a2 )])
89
- aes_state [2 ] = UNKNOWNS [114 ] ^ ((S_BOX [BYTE4 (a7 )] << 24 ) | (S_BOX [BYTE3 (a6 )] << 16 ) | (S_BOX [BYTE2 (a4 )] << 8 ) | S_BOX [BYTE1 (a3 )])
90
- aes_state [3 ] = UNKNOWNS [115 ] ^ ((S_BOX [BYTE4 (a8 )] << 24 ) | (S_BOX [BYTE3 (a7 )] << 16 ) | (S_BOX [BYTE2 (a5 )] << 8 ) | S_BOX [BYTE1 (a4 )])
91
- aes_state [4 ] = UNKNOWNS [116 ] ^ ((S_BOX [BYTE4 (a1 )] << 24 ) | (S_BOX [BYTE3 (a8 )] << 16 ) | (S_BOX [BYTE2 (a6 )] << 8 ) | S_BOX [BYTE1 (a5 )])
92
- aes_state [5 ] = UNKNOWNS [117 ] ^ ((S_BOX [BYTE4 (a2 )] << 24 ) | (S_BOX [BYTE3 (a1 )] << 16 ) | (S_BOX [BYTE2 (a7 )] << 8 ) | S_BOX [BYTE1 (a6 )])
93
- aes_state [6 ] = UNKNOWNS [118 ] ^ ((S_BOX [BYTE4 (a3 )] << 24 ) | (S_BOX [BYTE3 (a2 )] << 16 ) | (S_BOX [BYTE2 (a8 )] << 8 ) | S_BOX [BYTE1 (a7 )])
94
- aes_state [7 ] = UNKNOWNS [119 ] ^ ((S_BOX [BYTE4 (a4 )] << 24 ) | (S_BOX [BYTE3 (a3 )] << 16 ) | (S_BOX [BYTE2 (a1 )] << 8 ) | S_BOX [BYTE1 (a8 )])
95
-
96
- # Dump out the "AES" state as hex
97
- return b'' .join (n .to_bytes (4 , 'little' ) for n in aes_state ).hex ().upper ()
44
+ # Textual signature is just the hex representation
45
+ return signature .hex ().upper ()
98
46
99
47
100
48
def extract_info (text ):
@@ -108,9 +56,9 @@ def extract_info(text):
108
56
else :
109
57
version = tuple (version .split ()[3 :6 ])
110
58
111
- match = re .search ('\r ? \n \r ? \n ==== (.*) ([A-Z0-9]+) ====' , text )
59
+ match = re .search ('\n \n ==== (.*) ([A-Z0-9]+) ====' , text )
112
60
if match :
113
- text , signature_parts = re .split ('\r ? \n \r ? \n ==== {}' .format (match .group (1 )), text )
61
+ text , signature_parts = re .split ('\n \n ==== {}' .format (match .group (1 )), text )
114
62
signature = signature_parts .split ()[0 ].strip ()
115
63
else :
116
64
signature = None
@@ -130,6 +78,10 @@ def get_logs(data):
130
78
if text .startswith ('\ufeff ' ):
131
79
text = text [1 :]
132
80
81
+ # The checksum strips off the newlines anyway, so we can simplify them here
82
+ # for our own regexes
83
+ text = text .replace ('\r \n ' , '\n ' )
84
+
133
85
# Null bytes screw it up
134
86
if '\x00 ' in text :
135
87
text = text [:text .index ('\x00 ' )]
@@ -138,23 +90,21 @@ def get_logs(data):
138
90
if any (len (l ) + 1 > 2 ** 13 for l in text .split ('\n ' )):
139
91
raise RuntimeError ('EAC cannot handle lines longer than 2^13 chars' )
140
92
141
- return [x .strip () for x in re .split ('^' + ( '-' * 60 ) , text )]
93
+ return [x .strip () for x in re .split (r'[^-]-{60}[^-]' , text )]
142
94
143
95
144
- def main ():
145
- parser = argparse .ArgumentParser (description = 'Verifies and resigns EAC logs' )
146
- parser .add_argument ('--json' , action = 'store_true' , help = 'Output as JSON' )
147
- parser .add_argument ('file' , type = argparse .FileType (mode = 'rb' ), help = 'input log file' )
148
-
149
- args = parser .parse_args ()
96
+ def check_checksum (arg_file , arg_json ):
97
+ if not isinstance (arg_file , Path ):
98
+ arg_file = Path (arg_file )
99
+
100
+ output = []
150
101
151
- cnt = 1
152
- output = {}
153
- print ('Log Integrity Checker (C) 2010 by Andre Wiethoff' )
154
- print ('' )
102
+ if not arg_file .exists ():
103
+ if not arg_json :
104
+ print ('Could not find logfile to examine.' )
155
105
156
106
try :
157
- with contextlib . closing ( args . file ) as open_file :
107
+ with arg_file . open ( 'rb' ) as open_file :
158
108
logs = get_logs (open_file .read ())
159
109
160
110
for log in logs :
@@ -170,27 +120,37 @@ def main():
170
120
message = 'Log entry is fine!'
171
121
status = "OK"
172
122
173
- output [cnt ] = {
174
- "name" : args .file .name ,
175
- "message" : message
176
- }
177
-
178
- if not args .json :
179
- print ('{:d}. {:s}' .format (cnt , message ))
180
- cnt += 1
181
-
123
+ output .append ({
124
+ "message" : message ,
125
+ "status" : status
126
+ })
182
127
except (UnicodeDecodeError , RuntimeError ):
183
128
message = 'Log entry has no checksum!'
184
- json_output [cnt ] = {
185
- "name" : args .file .name ,
129
+ output .append ({
186
130
"message" : message ,
187
131
"status" : "NO"
188
- }
189
- if not args .json :
190
- print ('{:d}. {:s}' .format (cnt , message ))
132
+ })
133
+
134
+ return output
135
+
191
136
137
+ def main ():
138
+ parser = argparse .ArgumentParser (description = 'Verifies and resigns EAC logs' )
139
+ parser .add_argument ('--json' , action = 'store_true' , help = 'Output as JSON' )
140
+ parser .add_argument ('file' , type = Path , help = 'input log file' )
141
+
142
+ args = parser .parse_args ()
143
+
144
+ output = {}
145
+ if not args .json :
146
+ print ('Log Integrity Checker (C) 2010 by Andre Wiethoff' )
147
+ print ('' )
148
+ output = check_checksum (args .file , args .json )
192
149
if args .json :
193
150
print (json .dumps (output ))
151
+ else :
152
+ for i in range (len (output )):
153
+ print ('{:d}. {:s}' .format (i + 1 , output [i ]['message' ]))
194
154
195
155
if __name__ == '__main__' :
196
156
main ()
0 commit comments