forked from osmocom/wireshark
Tools: Check the last modified date in make-tls-ct-logids.py
In "update" mode, exclude the last modified time when comparing against the current code block.
This commit is contained in:
parent
cbbddcfa3a
commit
47fa90e41e
|
@ -9,7 +9,9 @@
|
|||
|
||||
import argparse
|
||||
from base64 import b64decode, b64encode
|
||||
from enum import Enum
|
||||
import itertools
|
||||
import os
|
||||
import requests
|
||||
from hashlib import sha256
|
||||
|
||||
|
@ -19,12 +21,18 @@ HEADER = "/* Generated by tools/make-tls-ct-logids.py\n"
|
|||
# See also https://www.certificate-transparency.org/known-logs
|
||||
CT_JSON_URL = 'https://www.gstatic.com/ct/log_list/v3/all_logs_list.json'
|
||||
# File to be patched
|
||||
SOURCE_FILE = "epan/dissectors/packet-tls-utils.c"
|
||||
SOURCE_FILE = os.path.join('epan', 'dissectors', 'packet-tls-utils.c')
|
||||
|
||||
# Maximum elements per line in the value array. 11 is chosen because it results
|
||||
# in output consistent with clang-format.
|
||||
BYTES_PER_LINE = 11
|
||||
|
||||
class SourceStage(Enum):
|
||||
BEGIN = 1
|
||||
IN_METAINFO = 2
|
||||
IN_BLOCK = 3
|
||||
END = 4
|
||||
|
||||
|
||||
def escape_c(s):
|
||||
return s.replace('\\', '\\\\').replace('"', '\\"')
|
||||
|
@ -36,47 +44,55 @@ def byteshex(b):
|
|||
|
||||
def process_json(obj, lastmod):
|
||||
logs = list(itertools.chain(*[op['logs'] for op in obj['operators']]))
|
||||
lines = HEADER
|
||||
lines += " * Last-Modified %s, %s entries. */\n" % (lastmod, len(logs))
|
||||
lines += "static const bytes_string ct_logids[] = {\n"
|
||||
metainfo, block = HEADER, ''
|
||||
metainfo += " * Last-Modified %s, %s entries. */\n" % (lastmod, len(logs))
|
||||
block += "static const bytes_string ct_logids[] = {\n"
|
||||
for entry in logs:
|
||||
desc = entry["description"]
|
||||
pubkey_der = b64decode(entry["key"])
|
||||
key_id = sha256(pubkey_der).digest()
|
||||
lines += ' { (const guint8[]){\n'
|
||||
block += ' { (const guint8[]){\n'
|
||||
for offset in range(0, len(key_id), BYTES_PER_LINE):
|
||||
lines += ' %s\n' % \
|
||||
block += ' %s\n' % \
|
||||
byteshex(key_id[offset:offset+BYTES_PER_LINE])
|
||||
lines += ' },\n'
|
||||
lines += ' %d, "%s" },\n' % (len(key_id), escape_c(desc))
|
||||
lines += " { NULL, 0, NULL }\n"
|
||||
lines += "};\n"
|
||||
return lines
|
||||
block += ' },\n'
|
||||
block += ' %d, "%s" },\n' % (len(key_id), escape_c(desc))
|
||||
block += " { NULL, 0, NULL }\n"
|
||||
block += "};\n"
|
||||
return metainfo, block
|
||||
|
||||
|
||||
def parse_source():
|
||||
def parse_source(source_path):
|
||||
"""
|
||||
Reads the source file and tries to split it in the parts before, inside and
|
||||
after the block.
|
||||
"""
|
||||
begin, block, end = '', '', ''
|
||||
# Stages: 1 (before block), 2 (in block, skip), 3 (after block)
|
||||
stage = 1
|
||||
with open(SOURCE_FILE) as f:
|
||||
begin, metainfo, block, end = '', '', '', ''
|
||||
# Stages: BEGIN (before block), IN_METAINFO, IN_BLOCK (skip), END
|
||||
stage = SourceStage.BEGIN
|
||||
with open(source_path) as f:
|
||||
for line in f:
|
||||
if line == HEADER:
|
||||
stage = 2 # Begin of block
|
||||
if stage == 1:
|
||||
if line.startswith('/* Generated by '):
|
||||
stage = SourceStage.IN_METAINFO
|
||||
|
||||
|
||||
if stage == SourceStage.BEGIN:
|
||||
begin += line
|
||||
elif stage == 2:
|
||||
elif stage == SourceStage.IN_METAINFO:
|
||||
metainfo += line
|
||||
elif stage == SourceStage.IN_BLOCK:
|
||||
block += line
|
||||
if line.startswith('}'):
|
||||
stage = 3 # End of block reached
|
||||
elif stage == 3:
|
||||
stage = SourceStage.END
|
||||
elif stage == SourceStage.END:
|
||||
end += line
|
||||
if stage != 3:
|
||||
raise RuntimeError("Could not parse file (in stage %d)" % stage)
|
||||
return begin, block, end
|
||||
|
||||
if line.startswith(' * Last-Modified '):
|
||||
stage = SourceStage.IN_BLOCK
|
||||
|
||||
if stage != SourceStage.END:
|
||||
raise RuntimeError("Could not parse file (in stage %s)" % stage.name)
|
||||
return begin, metainfo, block, end
|
||||
|
||||
|
||||
parser = argparse.ArgumentParser()
|
||||
|
@ -86,21 +102,24 @@ parser.add_argument("--update", action="store_true",
|
|||
|
||||
def main():
|
||||
args = parser.parse_args()
|
||||
this_dir = os.path.dirname(__file__)
|
||||
r = requests.get(CT_JSON_URL)
|
||||
code = process_json(r.json(), lastmod=r.headers['Last-Modified'])
|
||||
j_metainfo, j_block = process_json(r.json(), lastmod=r.headers['Last-Modified'])
|
||||
source_path = os.path.join(this_dir, '..', SOURCE_FILE)
|
||||
|
||||
if args.update:
|
||||
begin, block, end = parse_source()
|
||||
if block == code:
|
||||
s_begin, _, s_block, s_end = parse_source(source_path)
|
||||
if s_block == j_block:
|
||||
print("File is up-to-date")
|
||||
else:
|
||||
with open(SOURCE_FILE, "w") as f:
|
||||
f.write(begin)
|
||||
f.write(code)
|
||||
f.write(end)
|
||||
print("Updated %s" % SOURCE_FILE)
|
||||
with open(source_path, "w") as f:
|
||||
f.write(s_begin)
|
||||
f.write(j_metainfo)
|
||||
f.write(j_block)
|
||||
f.write(s_end)
|
||||
print("Updated %s" % source_path)
|
||||
else:
|
||||
print(code)
|
||||
print(j_metainfo, j_block)
|
||||
|
||||
|
||||
if __name__ == '__main__':
|
||||
|
|
Loading…
Reference in New Issue