Refactor SigningTable and KeyTables based on more careful reading of the documentation

This commit is contained in:
Scott Kitterman
2019-10-29 01:50:28 -04:00
parent 403f8c8d1d
commit 5b956b9c7d
3 changed files with 43 additions and 59 deletions
+17 -29
View File
@@ -261,26 +261,10 @@ def _make_authserv_id(as_id):
as_id = socket.gethostname() as_id = socket.gethostname()
return as_id return as_id
def _dataset_multiline(dst, dataset):
"""Convert one list element per line on multi-line datasets to a list of
lists"""
result = []
for row in dataset:
rowl = row.split(',')
for element in rowl:
rowl[rowl.index(element)] = element.strip().strip(',')
if dst == 'KeyTable' and len(rowl) != 3:
raise dkim.ParameterError('Invalid {0} element (need three paramters per row): {1}'
.format(str(dst), str(rowl)))
if dst == 'SigningTable' and len(rowl) > 2:
raise dkim.ParameterError('Invalid {0} element (need one or two paramters per row): {1}'
.format(str(dst), str(rowl)))
result.append(rowl)
return result
def _dataset_to_list(dataset): def _dataset_to_list(dataset):
"""Convert a dataset (as defined in dkimpymilter.8) and return a python """Convert a dataset (as defined in dkimpymilter.8) and return a python
list of values.""" list of values. For multiline datasets like KeyTable and SigningTable a
key : values dictionary is returned"""
if not isinstance(dataset, str): if not isinstance(dataset, str):
# If it was a csl with more than one value, it's already a list, we # If it was a csl with more than one value, it's already a list, we
# only need to remove the name from the first value. # only need to remove the name from the first value.
@@ -290,23 +274,34 @@ def _dataset_to_list(dataset):
dataset[dataset.index(item)] = item.strip().strip(',') dataset[dataset.index(item)] = item.strip().strip(',')
return dataset return dataset
elif isinstance(dataset, str): elif isinstance(dataset, str):
if dataset[0] == '/' or dataset[:5] == 'file:': if dataset[0] == '/' or dataset[:5] == 'file:' or dataset[:7] == 'refile:':
# This is a flat file dataset # This is a flat file dataset, which are key value:value stores
ds = [] ds = []
dsd = {}
if dataset[0] == '/': if dataset[0] == '/':
dsname = dataset dsname = dataset
if dataset[:5] == 'file:': elif dataset[:5] == 'file:':
dsname = dataset[5:] dsname = dataset[5:]
elif dataset[:7] == 'refile:':
dsname = dataset[7:]
dsf = open(dsname, 'r') dsf = open(dsname, 'r')
for line in dsf.readlines(): for line in dsf.readlines():
if line[0] != '#': if line[0] != '#':
if len(line.split()) == 1:
if len(line.split(':')) == 1: if len(line.split(':')) == 1:
ds.append(line.strip()) ds.append(line.strip())
else: else:
for element in line.split(':'): for element in line.split(':'):
ds.append(element.strip().strip(':')) ds.append(element.strip().strip(':'))
elif len(line.split()) == 2: # key value:value:value
key, values = line.split()
values = values.split(':')
dsd.update({key:values})
dsf.close() dsf.close()
if ds:
return ds return ds
elif dsd:
return dsd
# If it's a str and csl, it has one value and we return a list # If it's a str and csl, it has one value and we return a list
if dataset[:4] == 'csl:': if dataset[:4] == 'csl:':
return [dataset[4:].strip().strip(',')] return [dataset[4:].strip().strip(',')]
@@ -428,14 +423,7 @@ def _readConfigFile(path, configData=None, configGlobal={}):
elif conversion == 'int': elif conversion == 'int':
configData[name] = int(value) configData[name] = int(value)
elif conversion == 'dataset': elif conversion == 'dataset':
interim_value = _dataset_to_list(value) configData[name] = _dataset_to_list(value)
# These are the only multi-line dataset types
if name == 'KeyTable' or name == 'KeyTableEd25519':
configData[name] = _dataset_multiline('KeyTable', interim_value)
elif name == 'SigningTable':
configData[name] = _dataset_multiline('SigningTable', interim_value)
else:
configData[name] = interim_value
else: else:
syslog.syslog(str('name: ' + name + ' value: ' + value + syslog.syslog(str('name: ' + name + ' value: ' + value +
' conversion: ' + conversion)) ' conversion: ' + conversion))
+9 -15
View File
@@ -187,25 +187,19 @@ def read_keyfile(keyfile, milterconfig):
key += line key += line
return key return key
def read_keytable(tablelist, milterconfig): def read_keytable(tabledict, milterconfig):
"""Read keytables into in memory configuration data so all keys are read """Read keytables into in memory configuration data so all keys are read
before priviledges are dropped. before priviledges are dropped.
tablelist contains a list of KeyTable rows (three elements, comma separated): When loaded, tabeldict is a dict:
domain, selector, key file location {searchkey: [donamin, selector, key]}
When loaded, KeyTableData is a dict: If key is a file (startswith('/'), then the key is returned in its place."""
{domain: [selector, key]}"""
import dkim import dkim
import syslog import syslog
keytabledata = {} for dictkey, values in tabledict.items():
for row in tablelist: if values[-1][:1] == '/':
for element in row: key = read_keyfile(values[-1], milterconfig)
row[row.index(element)] = element.strip().strip(',') tabledict[dictkey] = [values[0], values[1], key]
if len(row) != 3: return tabledict
raise dkim.ParameterError('Invalid KeyTable element (need three paramters per row): {0}'
.format(str(row)))
key = read_keyfile(row[2], milterconfig)
keytabledata.update({row[0]:[row[1], key]})
return keytabledata
def get_keys(milterconfig): def get_keys(milterconfig):
"""Read keys (table or file) into memory before dropping priviledges""" """Read keys (table or file) into memory before dropping priviledges"""
+6 -4
View File
@@ -85,13 +85,15 @@ cat > "$keytype.table.verify.conf" <<EOF
EOF EOF
cat > "$keytype-table" <<EOF cat > "$keytype-table" <<EOF
example.org, testnokey, testkey.$keytype.key preskey example.org:testkey:$WORKDIR/testkey.$keytype.key
example.net, testkey, testkey.$keytype.key orgkey example.org:testkey:$WORKDIR/testkey.$keytype.key
netkey example.net:testkey:$WORKDIR/testkey.$keytype.key
EOF EOF
cat > "signing-table" <<EOF cat > "signing-table" <<EOF
example.org president@example.org @special.example.org:preskey
%, @test.test.example.net *@example.org orgkey
*@example.net netkey
EOF EOF
done done