Refactor SigningTable and KeyTables based on more careful reading of the documentation
This commit is contained in:
+23
-35
@@ -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:
|
||||||
ds.append(line.strip())
|
if len(line.split(':')) == 1:
|
||||||
else:
|
ds.append(line.strip())
|
||||||
for element in line.split(':'):
|
else:
|
||||||
ds.append(element.strip().strip(':'))
|
for element in line.split(':'):
|
||||||
|
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()
|
||||||
return ds
|
if 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
@@ -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"""
|
||||||
|
|||||||
+11
-9
@@ -77,21 +77,23 @@ debugLevel 5
|
|||||||
EOF
|
EOF
|
||||||
|
|
||||||
cat > "$keytype.table.verify.conf" <<EOF
|
cat > "$keytype.table.verify.conf" <<EOF
|
||||||
Socket unix:$keytype.stable.verify.sock
|
Socket unix:$keytype.stable.verify.sock
|
||||||
PidFile $keytype.table.verify.pid
|
PidFile $keytype.table.verify.pid
|
||||||
Mode v
|
Mode v
|
||||||
DNSOverride $(cat testkey.$keytype.dns)
|
DNSOverride $(cat testkey.$keytype.dns)
|
||||||
UserID $(id --name --user):$(id --name --group)
|
UserID $(id --name --user):$(id --name --group)
|
||||||
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
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user