Compare commits
38 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 2528632ba6 | |||
| 3ea22f1529 | |||
| 097e053309 | |||
| 419d2b54ea | |||
| 3ff685205c | |||
| 7986de6629 | |||
| 5322c81027 | |||
| 94538ffa6b | |||
| 721da801fe | |||
| 51c8fdcb6c | |||
| aa4dadc22f | |||
| b1abbf9d61 | |||
| ea2b612e8d | |||
| 5945e818ca | |||
| f38fed3bee | |||
| 06948b3dbc | |||
| e951ab6c5e | |||
| 03c86a2b08 | |||
| 2cda1758c1 | |||
| a188bd3960 | |||
| c91a12f0d1 | |||
| 286ffbb6c9 | |||
| ec3252c367 | |||
| a2ff03727d | |||
| af4b05e242 | |||
| 6509eaad35 | |||
| f9483fea8c | |||
| 7a3a7bfb43 | |||
| 8a0e1bdd97 | |||
| e3005aa723 | |||
| 45d3ba13ca | |||
| f05309437f | |||
| d4499f6990 | |||
| 7d87309f4b | |||
| 1d8c309da9 | |||
| 4d5961e4d5 | |||
| 59448e8e57 | |||
| 695de0db14 |
@@ -1,3 +1,46 @@
|
|||||||
|
1.0.2 2019-10-07
|
||||||
|
- Fix startup logging so it provides information at a useful time
|
||||||
|
- Fix message extraction so that signing in the same pass through the milter
|
||||||
|
as verifying works correctly
|
||||||
|
- Fix variable initialization so mailformed mails missing body From do not
|
||||||
|
cause a traceback (LP: #1844161)
|
||||||
|
- Catch more ascii encoding errors to improve resilience against bad data
|
||||||
|
(LP: #1844189)
|
||||||
|
- Fix sysv init so it works (LP: #1839487)
|
||||||
|
|
||||||
|
1.0.1 2019-02-11
|
||||||
|
* Reorder milter start and dropping privileges so permissions on Unix socket
|
||||||
|
are correct (LP: 1797720)
|
||||||
|
- Make domain checks case insensitive for determining if signing should be
|
||||||
|
done (LP: #1815311)
|
||||||
|
- Add additional Sendmail configuration information to README from OpenDKIM
|
||||||
|
update based on input from Дилян Палаузов (LP: #1801619)
|
||||||
|
- Add information on Ed25519 key creation to README (LP: #1815313)
|
||||||
|
|
||||||
|
1.0.0 2018-05-11
|
||||||
|
- Minor documentation updates
|
||||||
|
- Deleted reference to obsolete syslog target in unit file
|
||||||
|
|
||||||
|
0.9.7 2018-03-19
|
||||||
|
- Made sysv init executable
|
||||||
|
- Add missing documentation key to system/dkimpy-milter.service
|
||||||
|
- Put version directly in setup.py and do not import dkimpy_milter to ease
|
||||||
|
install via pip
|
||||||
|
- Minor sysv init improvments
|
||||||
|
|
||||||
|
0.9.6 2018-03-13
|
||||||
|
- Fixed typo in package installation section of README
|
||||||
|
- Added more to README about first run with systemd
|
||||||
|
- Fixed typo in path for fallback location of the config file if one is not
|
||||||
|
provided
|
||||||
|
- Added protection for malformed From addresses. If the From does not at
|
||||||
|
least have an '@' in the address, then the signing domain is not extracted
|
||||||
|
and the message will not be signed
|
||||||
|
|
||||||
|
0.9.5.1 2018-03-10
|
||||||
|
- Add conf file location to systemd unit file
|
||||||
|
- Fix setup.py install locations so they are installed correctly
|
||||||
|
|
||||||
0.9.5 2018-03-10
|
0.9.5 2018-03-10
|
||||||
- Beta 1 (updated Alpha -> Beta warning in README and trove classifiers)
|
- Beta 1 (updated Alpha -> Beta warning in README and trove classifiers)
|
||||||
- Added support for MacroList option
|
- Added support for MacroList option
|
||||||
|
|||||||
@@ -1,11 +1,17 @@
|
|||||||
This is a DKIM signing and verification milter. In theory it works with both
|
OVERVIEW
|
||||||
Postfix and Sendmail, but the author has zero experience with Sendmail, so
|
========
|
||||||
reports of success/failure with Sendmail and patches are welcom.
|
|
||||||
|
This is a DKIM signing and verification milter. It has been tested with both
|
||||||
|
Postfix and Sendmail.
|
||||||
|
|
||||||
The configuration file is designed to be compatible with OpenDKIM, but only
|
The configuration file is designed to be compatible with OpenDKIM, but only
|
||||||
a subset of OpenDKIM options are supported. If an unsupported option is
|
a subset of OpenDKIM options are supported. If an unsupported option is
|
||||||
specified, an error will be raised.
|
specified, an error will be raised.
|
||||||
|
|
||||||
|
|
||||||
|
INSTALLATION
|
||||||
|
===========
|
||||||
|
|
||||||
This package includes a default configuration file and man pages. For those
|
This package includes a default configuration file and man pages. For those
|
||||||
to be installed when installing using setup.py, the following incantation is
|
to be installed when installing using setup.py, the following incantation is
|
||||||
required because setuptools developers decided not being able to do this by
|
required because setuptools developers decided not being able to do this by
|
||||||
@@ -13,11 +19,11 @@ default is a feature:
|
|||||||
|
|
||||||
python setup.py install --single-version-externally-managed --record=/dev/null
|
python setup.py install --single-version-externally-managed --record=/dev/null
|
||||||
|
|
||||||
For users of Debian Stable (Debian 9, Codename Squueze), all dependencies are
|
For users of Debian Stable (Debian 9, Codename Squeeze), all dependencies are
|
||||||
available in either the main or backports repositories:
|
available in either the main or backports repositories:
|
||||||
|
|
||||||
[sudo] apt install python-milter python-nacl pthon-ipaddress python-dnspython
|
[sudo] apt install python-milter python-nacl python-ipaddress python-dnspython
|
||||||
[sudo] apt install -t squeeze-backports python-authres python-dkim
|
[sudo] apt install -t stretch-backports python-authres python-dkim
|
||||||
|
|
||||||
The preferred method of installation is from PyPi using pip (if distribution
|
The preferred method of installation is from PyPi using pip (if distribution
|
||||||
packages are not available):
|
packages are not available):
|
||||||
@@ -25,17 +31,61 @@ packages are not available):
|
|||||||
[sudo] pip install dkimpy_milter
|
[sudo] pip install dkimpy_milter
|
||||||
|
|
||||||
Using pip will cause required packages to be installed via easy_install if they
|
Using pip will cause required packages to be installed via easy_install if they
|
||||||
have not been previously installed.
|
have not been previously installed. Because pymilter and PyNaCl are compiled
|
||||||
|
Python extensions, the system will need appropriate development packages and
|
||||||
|
an C compiler. Alternately, install these dependencies from dsitribution/OS
|
||||||
|
packages and then pip install dkimpy_milter.
|
||||||
|
|
||||||
The milter will work with either pydns (DNS) or dnspython (dns), preferring
|
The milter will work with either pydns (DNS) or dnspython (dns), preferring
|
||||||
dnspython is both are available. The dkimpy DKIM module also works with
|
dnspython if both are available. The dkimpy DKIM module also works with
|
||||||
either.
|
either.
|
||||||
|
|
||||||
|
|
||||||
|
SETUP
|
||||||
|
====
|
||||||
|
|
||||||
|
SIGNING KEYS
|
||||||
|
============
|
||||||
|
|
||||||
|
In order to create DKIM signatures, a private key must be available. Signing
|
||||||
|
keys should be protected (owned by root:root with permissions 600 in a
|
||||||
|
directory that is not world readable). Different keys are required for RSA
|
||||||
|
and (if used) Ed25519.
|
||||||
|
|
||||||
|
RSA
|
||||||
|
===
|
||||||
|
|
||||||
|
Both public and private keys for RSA have standard formats and there are many
|
||||||
|
tools available to create them. Keys must (RFC 8302) have a minimum size of
|
||||||
|
1024 bits and should have a size of at least 2048 bits. The dknewkey script
|
||||||
|
that is provided with dkimpy is one such tool:
|
||||||
|
|
||||||
|
dknewkey exampleprivkey
|
||||||
|
|
||||||
|
will produce both the private key file (.key suffix) and a file with the DKIM
|
||||||
|
public key record to be published DNS (.dns suffix). RSA is the default key
|
||||||
|
type. 2048 bits is the default key size.
|
||||||
|
|
||||||
|
ED25519
|
||||||
|
=======
|
||||||
|
|
||||||
|
There is no standardized non-binary representation for Ed25519 private keys,
|
||||||
|
so in order to generate Ed25519 keys for dkimpy-milter, dkimpy specific tools
|
||||||
|
must be used to be compatible. The same dknewkey script support Ed25519:
|
||||||
|
|
||||||
|
dknewkey --ktype ed25519 anothernewkey
|
||||||
|
|
||||||
|
will provide both the private key file (.key suffix) and a file with the DKIM
|
||||||
|
public key record to be published DNS (.dns suffix). Ed25519 keys do not have
|
||||||
|
variable bit lengths.
|
||||||
|
|
||||||
|
MTA INTEGRATION
|
||||||
|
==============
|
||||||
|
|
||||||
Both a systemd unit file and a sysv init file are provided. Both make
|
Both a systemd unit file and a sysv init file are provided. Both make
|
||||||
assumptions about defaults being used, e.g. if a non-standard pidfile name is
|
assumptions about defaults being used, e.g. if a non-standard pidfile name is
|
||||||
used, they will need to be updated. The sysv init file is Debian specific and
|
used, they will need to be updated. The sysv init file uses start-stop-deamon
|
||||||
untested, since the developers are not using sysv init. Feedback/patches
|
from Debian. It is not portable to systems without that available.
|
||||||
welcome.
|
|
||||||
|
|
||||||
The dkimpy-milter drops priviledges after setup to the user/group specified in
|
The dkimpy-milter drops priviledges after setup to the user/group specified in
|
||||||
UserID. During initial setup, this system user needs to be manually created.
|
UserID. During initial setup, this system user needs to be manually created.
|
||||||
@@ -48,10 +98,19 @@ As an example, using the default dkimpy-user on Debian, the command would be:
|
|||||||
Since /var/run or /run is sometimes on a tempfs, if the PID file directory is
|
Since /var/run or /run is sometimes on a tempfs, if the PID file directory is
|
||||||
missing, the milter will create it on startup.
|
missing, the milter will create it on startup.
|
||||||
|
|
||||||
|
To start dkimpy-milter with systemd for the first time, you will need to take
|
||||||
|
the following steps:
|
||||||
|
|
||||||
|
[sudo] systemctl daemon-reload
|
||||||
|
[sudo] systemctl enable dkimpy-milter
|
||||||
|
[sudo] systemctl start dkimpy-milter
|
||||||
|
[sudo] systemctl status dkimpy-milter (to verify it started correctly)
|
||||||
|
|
||||||
As with all milters, dkimpy-milter needs to be integrated with your MTA of
|
As with all milters, dkimpy-milter needs to be integrated with your MTA of
|
||||||
choice (Sendmail or Postfix).
|
choice (Sendmail or Postfix).
|
||||||
|
|
||||||
For Sendmail:
|
SENDMAIL
|
||||||
|
========
|
||||||
|
|
||||||
Configuration is very similar to opendkim, but needs some adjustment for
|
Configuration is very similar to opendkim, but needs some adjustment for
|
||||||
dkimpy-milter. Here's an example configuration line to include in your
|
dkimpy-milter. Here's an example configuration line to include in your
|
||||||
@@ -67,12 +126,64 @@ Milter support should be present by default in most versions of sendmail
|
|||||||
these days, but if not included in your Sendmail build, see:
|
these days, but if not included in your Sendmail build, see:
|
||||||
http://www.elandsys.com/resources/sendmail/milter.html
|
http://www.elandsys.com/resources/sendmail/milter.html
|
||||||
|
|
||||||
For Postfix:
|
ISSUES USING SENDMAIL TO SIGN AND VERIFY
|
||||||
|
========================================
|
||||||
|
|
||||||
|
When using the sendmail MTA in both signing and verifying mode, there are
|
||||||
|
a few issues of which to be aware that might cause operational problems
|
||||||
|
and deserve consideration.
|
||||||
|
|
||||||
|
(a) When the MTA will be used for relaying emails, e.g. delivering to other
|
||||||
|
hosts using the aliases mechanism, it is important not to break
|
||||||
|
signatures inserted by the original sender. This is particularly sensitive
|
||||||
|
particular when the sending domain has published a "reject" DMARC policy.
|
||||||
|
|
||||||
|
By default, sendmail quotes to address header fields when there are no
|
||||||
|
quotes and the display part of the address contains a period or an
|
||||||
|
apostrophe. However, opendkim only sees the raw, unmodified form of
|
||||||
|
the header field, and so the content that gets verified and what gets
|
||||||
|
signed will not be the same, guaranteeing the attached signature is not
|
||||||
|
valid.
|
||||||
|
|
||||||
|
To direct sendmail not to modify the headers, add this to your sendmail.mc:
|
||||||
|
|
||||||
|
conf(`confMUST_QUOTE_CHARS', `')
|
||||||
|
|
||||||
|
(b) As stated in sendmail's KNOWNBUGS file, sendmail truncates header field
|
||||||
|
values longer than 256 characters, which could mean truncating the domain
|
||||||
|
of a long From: header field value and invalidating the signature.
|
||||||
|
You may wish to consider increasing MAXNAME in sendmail/conf.h to mitigate
|
||||||
|
changing the messages and invalidating their signatures. This change
|
||||||
|
requires recompiling sendmail.
|
||||||
|
|
||||||
|
(c) Similar to (a) above, sendmail may wrap very long single-line recipient
|
||||||
|
fields for presentation purposes; for example:
|
||||||
|
|
||||||
|
To: very long name <a@example.org>,anotherloo...ong name b <b@example.org>
|
||||||
|
|
||||||
|
...might be rewritten as:
|
||||||
|
|
||||||
|
To: very long name <a@example.org>,
|
||||||
|
anotherloo...ong name b <b@example.org>
|
||||||
|
|
||||||
|
This rewrite is also done after opendkim has seen the message, meaning
|
||||||
|
the signature opendkim attaches to the message does not match the
|
||||||
|
content it signed. There is not a known configuration change to
|
||||||
|
mitigate this mutation.
|
||||||
|
|
||||||
|
The only known mechanism for dealing with this is to have distinct
|
||||||
|
instances of opendkim do the verifying (inbound) and signing (outbound)
|
||||||
|
so that the version that arrives at the signing instance is already
|
||||||
|
in the rewritten form, guaranteeing the input and output are the same
|
||||||
|
and thus the signature matches the payload.
|
||||||
|
|
||||||
|
POSTFIX
|
||||||
|
=======
|
||||||
|
|
||||||
Integration of dkimpy-milter into Postfix is like any milter (See Postfix's
|
Integration of dkimpy-milter into Postfix is like any milter (See Postfix's
|
||||||
README_FILES/MILTER_README). Here's an example master.cf excerpt the talks to
|
README_FILES/MILTER_README). Here's an example master.cf excerpt that talks
|
||||||
two dkimpy-milter instances, one configured for signing and one configured for
|
to two dkimpy-milter instances, one configured for signing and one configured
|
||||||
verification:
|
for verification:
|
||||||
|
|
||||||
smtp inet n - - - - smtpd
|
smtp inet n - - - - smtpd
|
||||||
...
|
...
|
||||||
@@ -117,11 +228,15 @@ MacroListVerify daemon_name|VERIFYING
|
|||||||
...
|
...
|
||||||
|
|
||||||
|
|
||||||
The python DKIM library, dkimpy, requires the entire message being signed or
|
NOTES
|
||||||
verified to be in memory, so dkimpy-milter does not write messages out to a temp
|
=====
|
||||||
file. This may impact performance on low-memory systems.
|
|
||||||
|
|
||||||
This is an beta grade release to support interoperability testing with Ed25519
|
The python DKIM library, dkimpy, requires the entire message being signed or
|
||||||
signatures sufficient functionality for basic use. The documented
|
verified to be in memory, so dkimpy-milter does not write messages out to a
|
||||||
functionality has been implemented and at least partially tested. It is free
|
temp file. This may impact performance on low-memory systems.
|
||||||
of known major defects, but is not fully tested in a variety of environments.
|
|
||||||
|
DKIM with Ed25519 signatures are described in RFC 8463. Version 1.0.0 and
|
||||||
|
later support Ed25519 signing and verification. RFC 8301 removed rsa-sha1
|
||||||
|
from DKIM. dkimpy-milter does not sign with rsa-sha1, but still considers
|
||||||
|
rsa-sha1 signatures as valid for verification because they are still in
|
||||||
|
common use and are not known to be cryptographically broken.
|
||||||
|
|||||||
@@ -39,10 +39,16 @@ MacroListVerify implemented verified
|
|||||||
SyslogSuccess implemented verified
|
SyslogSuccess implemented verified
|
||||||
|
|
||||||
1.0.0
|
1.0.0
|
||||||
No additional features planned
|
No additional features
|
||||||
|
|
||||||
Plannedataset type support (if needed):
|
1.0.1
|
||||||
db:/.db
|
Bug fix only, improved documentation
|
||||||
|
|
||||||
|
1.1.0 (planned)
|
||||||
|
Port to Python 3
|
||||||
|
Subdomain support
|
||||||
|
|
||||||
|
Planned dataset type support (if needed):
|
||||||
mdb:
|
mdb:
|
||||||
|
|
||||||
Considered for near-term feature release
|
Considered for near-term feature release
|
||||||
@@ -50,9 +56,10 @@ Considered for near-term feature release
|
|||||||
AlwaysAddARHeader
|
AlwaysAddARHeader
|
||||||
ChangeRootDirectory
|
ChangeRootDirectory
|
||||||
ClockDrift (requires dkimpy change)
|
ClockDrift (requires dkimpy change)
|
||||||
DNSTimeout (requires dkmpy change)
|
DNSTimeout (requires dkimpy change)
|
||||||
MilterDebug
|
MilterDebug
|
||||||
MinimumKeyBits
|
MinimumKeyBits
|
||||||
|
OversignHeaders (may require dkimpy changes)
|
||||||
PeerList
|
PeerList
|
||||||
SignatureAlgorithm
|
SignatureAlgorithm
|
||||||
|
|
||||||
@@ -83,7 +90,6 @@ On-InternalError
|
|||||||
On-KeyNotFound
|
On-KeyNotFound
|
||||||
On-NoSignature
|
On-NoSignature
|
||||||
On-SignatureError
|
On-SignatureError
|
||||||
OversignHeaders
|
|
||||||
RemoveARAll
|
RemoveARAll
|
||||||
RemoveARFrom
|
RemoveARFrom
|
||||||
RemoveOldSignatures
|
RemoveOldSignatures
|
||||||
|
|||||||
+42
-16
@@ -39,7 +39,7 @@ from dkimpy_milter.util import read_keyfile
|
|||||||
from dkimpy_milter.util import own_socketfile
|
from dkimpy_milter.util import own_socketfile
|
||||||
from dkimpy_milter.util import fold
|
from dkimpy_milter.util import fold
|
||||||
|
|
||||||
__version__ = "0.9.5"
|
__version__ = "1.0.1"
|
||||||
FWS = re.compile(r'\r?\n[ \t]+')
|
FWS = re.compile(r'\r?\n[ \t]+')
|
||||||
|
|
||||||
|
|
||||||
@@ -54,6 +54,7 @@ class dkimMilter(Milter.Base):
|
|||||||
self.privatersa = privateRSA
|
self.privatersa = privateRSA
|
||||||
self.privateed25519 = privateEd25519
|
self.privateed25519 = privateEd25519
|
||||||
self.fp = None
|
self.fp = None
|
||||||
|
self.fdomain = ''
|
||||||
|
|
||||||
@Milter.noreply
|
@Milter.noreply
|
||||||
def connect(self, hostname, unused, hostaddr):
|
def connect(self, hostname, unused, hostaddr):
|
||||||
@@ -130,14 +131,21 @@ class dkimMilter(Milter.Base):
|
|||||||
self.has_dkim += 1
|
self.has_dkim += 1
|
||||||
if lname == 'from':
|
if lname == 'from':
|
||||||
fname, self.author = parseaddr(val)
|
fname, self.author = parseaddr(val)
|
||||||
self.fdomain = self.author.split('@')[1]
|
try:
|
||||||
|
self.fdomain = self.author.split('@')[1].lower()
|
||||||
|
except IndexError as er:
|
||||||
|
pass # self.author was not a proper email address
|
||||||
if (milterconfig.get('Syslog') and
|
if (milterconfig.get('Syslog') and
|
||||||
milterconfig.get('debugLevel') >= 1):
|
milterconfig.get('debugLevel') >= 1):
|
||||||
syslog.syslog("{0}: {1}".format(name, val))
|
syslog.syslog("{0}: {1}".format(name, val))
|
||||||
elif lname == 'authentication-results':
|
elif lname == 'authentication-results':
|
||||||
self.arheaders.append(val)
|
self.arheaders.append(val)
|
||||||
if self.fp:
|
if self.fp:
|
||||||
|
try:
|
||||||
self.fp.write("%s: %s\n" % (name, val))
|
self.fp.write("%s: %s\n" % (name, val))
|
||||||
|
except:
|
||||||
|
# Don't choke on header fields with garbage in them.
|
||||||
|
pass
|
||||||
return Milter.CONTINUE
|
return Milter.CONTINUE
|
||||||
|
|
||||||
@Milter.noreply
|
@Milter.noreply
|
||||||
@@ -171,20 +179,19 @@ class dkimMilter(Milter.Base):
|
|||||||
except:
|
except:
|
||||||
# Don't error out on unparseable AR header fiels
|
# Don't error out on unparseable AR header fiels
|
||||||
pass
|
pass
|
||||||
# Check or sign DKIM
|
# Check and/or sign DKIM
|
||||||
self.fp.seek(0)
|
self.fp.seek(0)
|
||||||
|
txt = self.fp.read()
|
||||||
if milterconfig.get('Domain'):
|
if milterconfig.get('Domain'):
|
||||||
domain = milterconfig.get('Domain')
|
domain = milterconfig.get('Domain')
|
||||||
else:
|
else:
|
||||||
domain = ''
|
domain = ''
|
||||||
if ((self.fdomain in domain) and not milterconfig.get('Mode') == 'v'
|
if ((self.fdomain in domain) and not milterconfig.get('Mode') == 'v'
|
||||||
and not self.external_connection):
|
and not self.external_connection):
|
||||||
txt = self.fp.read()
|
|
||||||
self.sign_dkim(txt)
|
self.sign_dkim(txt)
|
||||||
if ((self.has_dkim) and (not self.internal_connection) and
|
if ((self.has_dkim) and (not self.internal_connection) and
|
||||||
(milterconfig.get('Mode') == 'v' or
|
(milterconfig.get('Mode') == 'v' or
|
||||||
milterconfig.get('Mode') == 'sv')):
|
milterconfig.get('Mode') == 'sv')):
|
||||||
txt = self.fp.read()
|
|
||||||
self.check_dkim(txt)
|
self.check_dkim(txt)
|
||||||
if self.arresults:
|
if self.arresults:
|
||||||
h = authres.AuthenticationResultsHeader(authserv_id=
|
h = authres.AuthenticationResultsHeader(authserv_id=
|
||||||
@@ -225,7 +232,7 @@ class dkimMilter(Milter.Base):
|
|||||||
'd={3})'.format(self.getsymval('i'),
|
'd={3})'.format(self.getsymval('i'),
|
||||||
d.signature_fields.get(b'a'),
|
d.signature_fields.get(b'a'),
|
||||||
d.signature_fields.get(b's'),
|
d.signature_fields.get(b's'),
|
||||||
d.domain))
|
d.domain.lower()))
|
||||||
if privateEd25519:
|
if privateEd25519:
|
||||||
d = dkim.DKIM(txt)
|
d = dkim.DKIM(txt)
|
||||||
h = d.sign(milterconfig.get('SelectorEd25519'), self.fdomain,
|
h = d.sign(milterconfig.get('SelectorEd25519'), self.fdomain,
|
||||||
@@ -241,7 +248,7 @@ class dkimMilter(Milter.Base):
|
|||||||
'd={3})'.format(self.getsymval('i'),
|
'd={3})'.format(self.getsymval('i'),
|
||||||
d.signature_fields.get(b'a'),
|
d.signature_fields.get(b'a'),
|
||||||
d.signature_fields.get(b's'),
|
d.signature_fields.get(b's'),
|
||||||
d.domain))
|
d.domain.lower()))
|
||||||
except dkim.DKIMException as x:
|
except dkim.DKIMException as x:
|
||||||
if milterconfig.get('Syslog'):
|
if milterconfig.get('Syslog'):
|
||||||
syslog.syslog('DKIM: {0}'.format(x))
|
syslog.syslog('DKIM: {0}'.format(x))
|
||||||
@@ -252,6 +259,7 @@ class dkimMilter(Milter.Base):
|
|||||||
|
|
||||||
def check_dkim(self, txt):
|
def check_dkim(self, txt):
|
||||||
res = False
|
res = False
|
||||||
|
self.header_a = None
|
||||||
for y in range(self.has_dkim): # Verify _ALL_ the signatures
|
for y in range(self.has_dkim): # Verify _ALL_ the signatures
|
||||||
d = dkim.DKIM(txt)
|
d = dkim.DKIM(txt)
|
||||||
try:
|
try:
|
||||||
@@ -278,9 +286,20 @@ class dkimMilter(Milter.Base):
|
|||||||
self.dkim_comment = str(x)
|
self.dkim_comment = str(x)
|
||||||
if milterconfig.get('Syslog'):
|
if milterconfig.get('Syslog'):
|
||||||
syslog.syslog("check_dkim: {0}".format(x))
|
syslog.syslog("check_dkim: {0}".format(x))
|
||||||
|
try:
|
||||||
self.header_i = d.signature_fields.get(b'i')
|
self.header_i = d.signature_fields.get(b'i')
|
||||||
|
except TypeError as x:
|
||||||
|
self.header_i = None
|
||||||
|
try:
|
||||||
self.header_d = d.signature_fields.get(b'd')
|
self.header_d = d.signature_fields.get(b'd')
|
||||||
self.header_a = d.signature_fields.get(b'a')
|
self.header_a = d.signature_fields.get(b'a')
|
||||||
|
except Exception as x:
|
||||||
|
self.dkim_comment = str(x)
|
||||||
|
if milterconfig.get('Syslog'):
|
||||||
|
syslog.syslog("check_dkim: {0}".format(x))
|
||||||
|
self.header_d = None
|
||||||
|
if not self.header_a:
|
||||||
|
self.header_a = 'rsa-sha256'
|
||||||
if res:
|
if res:
|
||||||
if (milterconfig.get('Syslog') and
|
if (milterconfig.get('Syslog') and
|
||||||
(milterconfig.get('SyslogSuccess') or
|
(milterconfig.get('SyslogSuccess') or
|
||||||
@@ -289,8 +308,8 @@ class dkimMilter(Milter.Base):
|
|||||||
'd={3})'.format(self.getsymval('i'),
|
'd={3})'.format(self.getsymval('i'),
|
||||||
d.signature_fields.get(b'a'),
|
d.signature_fields.get(b'a'),
|
||||||
d.signature_fields.get(b's'),
|
d.signature_fields.get(b's'),
|
||||||
d.domain))
|
d.domain.lower()))
|
||||||
self.dkim_domain = d.domain
|
self.dkim_domain = d.domain.lower()
|
||||||
else:
|
else:
|
||||||
if milterconfig.get('DiagnosticDirectory'):
|
if milterconfig.get('DiagnosticDirectory'):
|
||||||
fd, fname = tempfile.mkstemp(".dkim")
|
fd, fname = tempfile.mkstemp(".dkim")
|
||||||
@@ -300,12 +319,18 @@ class dkimMilter(Milter.Base):
|
|||||||
syslog.syslog('DKIM: Fail (saved as {0})'
|
syslog.syslog('DKIM: Fail (saved as {0})'
|
||||||
.format(fname))
|
.format(fname))
|
||||||
else:
|
else:
|
||||||
syslog.syslog('DKIM: Fail ({0})'.format(d.domain))
|
if milterconfig.get('Syslog'):
|
||||||
|
if d.domain:
|
||||||
|
syslog.syslog('DKIM: Fail ({0})'
|
||||||
|
.format(d.domain.lower()))
|
||||||
|
else:
|
||||||
|
syslog.syslog('DKIM: Fail, unextractable domain')
|
||||||
if res:
|
if res:
|
||||||
result = 'pass'
|
result = 'pass'
|
||||||
else:
|
else:
|
||||||
result = 'fail'
|
result = 'fail'
|
||||||
res = False
|
res = False
|
||||||
|
if self.header_d:
|
||||||
self.arresults.append(
|
self.arresults.append(
|
||||||
authres.DKIMAuthenticationResult(result=result,
|
authres.DKIMAuthenticationResult(result=result,
|
||||||
header_i=self.header_i,
|
header_i=self.header_i,
|
||||||
@@ -314,6 +339,7 @@ class dkimMilter(Milter.Base):
|
|||||||
result_comment=
|
result_comment=
|
||||||
self.dkim_comment)
|
self.dkim_comment)
|
||||||
)
|
)
|
||||||
|
self.header_a = None
|
||||||
return
|
return
|
||||||
|
|
||||||
|
|
||||||
@@ -324,7 +350,7 @@ def main():
|
|||||||
global privateEd25519
|
global privateEd25519
|
||||||
privateRSA = False
|
privateRSA = False
|
||||||
privateEd25519 = False
|
privateEd25519 = False
|
||||||
configFile = '/etc/dkimpy-milter.conf'
|
configFile = '/usr/local/etc/dkimpy-milter.conf'
|
||||||
if len(sys.argv) > 1:
|
if len(sys.argv) > 1:
|
||||||
if sys.argv[1] in ('-?', '--help', '-h'):
|
if sys.argv[1] in ('-?', '--help', '-h'):
|
||||||
print('usage: dkimpy-milter [<configfilename>]')
|
print('usage: dkimpy-milter [<configfilename>]')
|
||||||
@@ -345,13 +371,13 @@ def main():
|
|||||||
Milter.set_flags(Milter.CHGHDRS + Milter.ADDHDRS)
|
Milter.set_flags(Milter.CHGHDRS + Milter.ADDHDRS)
|
||||||
miltername = 'dkimpy-filter'
|
miltername = 'dkimpy-filter'
|
||||||
socketname = milterconfig.get('Socket')
|
socketname = milterconfig.get('Socket')
|
||||||
if milterconfig.get('Syslog'):
|
|
||||||
syslog.syslog('dkimpy-milter started:{0} user:{1}'
|
|
||||||
.format(pid, milterconfig.get('UserID')))
|
|
||||||
sys.stdout.flush()
|
|
||||||
Milter.runmilter(miltername, socketname, 240)
|
|
||||||
own_socketfile(milterconfig)
|
own_socketfile(milterconfig)
|
||||||
drop_privileges(milterconfig)
|
drop_privileges(milterconfig)
|
||||||
|
sys.stdout.flush()
|
||||||
|
if milterconfig.get('Syslog'):
|
||||||
|
syslog.syslog('dkimpy-milter starting:{0} user:{1}'
|
||||||
|
.format(pid, milterconfig.get('UserID')))
|
||||||
|
Milter.runmilter(miltername, socketname, 240)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
main()
|
main()
|
||||||
|
|||||||
+1
-13
@@ -294,19 +294,7 @@ def _dataset_to_list(dataset):
|
|||||||
else:
|
else:
|
||||||
return [dataset.strip().strip(',')]
|
return [dataset.strip().strip(',')]
|
||||||
if dataset[-3:] == '.db' or dataset[:3] == 'db:':
|
if dataset[-3:] == '.db' or dataset[:3] == 'db:':
|
||||||
# This is a Sleepycat (Oracle) DB dataset
|
# This is a Sleepycat (Oracle) DB dataset, which we dont support
|
||||||
import whichdb # Will need rewriting someday for python3
|
|
||||||
if dataset[-3:] == '.db':
|
|
||||||
dbname = dataset
|
|
||||||
elif dataset[:3] == 'db:':
|
|
||||||
dbname = dataset[3:]
|
|
||||||
else:
|
|
||||||
raise dkim.ParameterError('Unimplmented dataset type: {0}'
|
|
||||||
.format(type(dataset)))
|
|
||||||
if whichdb.whichdb(dbname) != 'dbhash':
|
|
||||||
raise dkim.ParameterError('Unimplmented dataset type: {0}'
|
|
||||||
.format(type(dataset)))
|
|
||||||
#TODO replace this with code to use db maps
|
|
||||||
raise dkim.ParameterError('Unsupported dataset db datase: {0}'
|
raise dkim.ParameterError('Unsupported dataset db datase: {0}'
|
||||||
.format(type(dataset)))
|
.format(type(dataset)))
|
||||||
|
|
||||||
|
|||||||
+5
-4
@@ -127,7 +127,6 @@
|
|||||||
.rm #[ #] #H #V #F C
|
.rm #[ #] #H #V #F C
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "dkimpy-milter 8"
|
|
||||||
.TH dkimpyy-milter 8
|
.TH dkimpyy-milter 8
|
||||||
.SH NAME
|
.SH NAME
|
||||||
.B dkimpy
|
.B dkimpy
|
||||||
@@ -269,7 +268,7 @@ proposal, and Cisco's
|
|||||||
.B Internet Identified Mail
|
.B Internet Identified Mail
|
||||||
(IIM) proposal.
|
(IIM) proposal.
|
||||||
.SH VERSION
|
.SH VERSION
|
||||||
This man page covers version 0.9.4 of
|
This man page covers version 1.1.0 of
|
||||||
.I dkimpy-milter.
|
.I dkimpy-milter.
|
||||||
.SH COPYRIGHT
|
.SH COPYRIGHT
|
||||||
Copyright (c) 2005-2008, Sendmail, Inc. and its suppliers. All rights
|
Copyright (c) 2005-2008, Sendmail, Inc. and its suppliers. All rights
|
||||||
@@ -278,7 +277,7 @@ reserved.
|
|||||||
Copyright (c) 2009-2013, 2015, The Trusted Domain Project.
|
Copyright (c) 2009-2013, 2015, The Trusted Domain Project.
|
||||||
All rights reserved.
|
All rights reserved.
|
||||||
|
|
||||||
Copyright (c) 2018 Scott Kitterman <scott@kitterman.com>
|
Copyright (c) 2018, 2019 Scott Kitterman <scott@kitterman.com>
|
||||||
.SH SEE ALSO
|
.SH SEE ALSO
|
||||||
.I dkimpy-milter.conf(5), sendmail(8)
|
.I dkimpy-milter.conf(5), sendmail(8)
|
||||||
.P
|
.P
|
||||||
@@ -292,4 +291,6 @@ RFC6376 - DomainKeys Identified Mail
|
|||||||
.P
|
.P
|
||||||
RFC7601 - Message Header Field for Indicating Message Authentication Status
|
RFC7601 - Message Header Field for Indicating Message Authentication Status
|
||||||
.P
|
.P
|
||||||
draft-ietf-dcrup-dkim-crypto - A new cryptographic signature method for DKIM
|
RFC8301 - Cryptographic Algorithm and Key Usage Update to DomainKeys Identified Mail (DKIM)
|
||||||
|
.P
|
||||||
|
RFC8463 - A New Cryptographic Signature Method for DomainKeys Identified Mail (DKIM)
|
||||||
|
|||||||
@@ -127,16 +127,13 @@
|
|||||||
.rm #[ #] #H #V #F C
|
.rm #[ #] #H #V #F C
|
||||||
.\" ========================================================================
|
.\" ========================================================================
|
||||||
.\"
|
.\"
|
||||||
.IX Title "dkimpy-milter.conf 5"
|
|
||||||
.TH dkimpy-milter.conf 5 "2018-02-12"
|
.TH dkimpy-milter.conf 5 "2018-02-12"
|
||||||
.SH "NAME"
|
.SH "NAME"
|
||||||
dkimpy-milter \- Python milter for DKIM signing and validation
|
dkimpy-milter \- Python milter for DKIM signing and validation
|
||||||
.SH "VERSION"
|
.SH "VERSION"
|
||||||
.IX Header "VERSION"
|
|
||||||
0\.9\.2
|
0\.9\.2
|
||||||
|
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.IX Header "DESCRIPTION"
|
|
||||||
.I dkimpy-milter(8)
|
.I dkimpy-milter(8)
|
||||||
implements the
|
implements the
|
||||||
.B DKIM
|
.B DKIM
|
||||||
@@ -160,18 +157,15 @@ The provided setup.py installs this configuration file in /etc or
|
|||||||
Command line invocation of parameters as is done by OpenDKIM is not supported.
|
Command line invocation of parameters as is done by OpenDKIM is not supported.
|
||||||
|
|
||||||
.SH "USAGE"
|
.SH "USAGE"
|
||||||
.IX Header "USAGE"
|
|
||||||
Usage:
|
Usage:
|
||||||
dkimpy-milter [/etc/dkimpy-milter.conf]
|
dkimpy-milter [/etc/dkimpy-milter.conf]
|
||||||
|
|
||||||
.SH "OTHER DOCUMENTATION"
|
.SH "OTHER DOCUMENTATION"
|
||||||
.IX Header "OTHER DOCUMENTATION"
|
|
||||||
This documentation assumes you have read Postfix's README_FILES/MILTER_README
|
This documentation assumes you have read Postfix's README_FILES/MILTER_README
|
||||||
(or Sendmail equivalent) and are generally familiar with Domain Keys Identified
|
(or Sendmail equivalent) and are generally familiar with Domain Keys Identified
|
||||||
Mail (DKIM). See RFC 6376 for details.
|
Mail (DKIM). See RFC 6376 for details.
|
||||||
|
|
||||||
.SH "SYNOPSIS"
|
.SH "SYNOPSIS"
|
||||||
.IX Header "SYNOPSIS"
|
|
||||||
|
|
||||||
dkimpy-milter operates with a default installed configuration file and
|
dkimpy-milter operates with a default installed configuration file and
|
||||||
set of default configuration options that are used if the configuration file
|
set of default configuration options that are used if the configuration file
|
||||||
@@ -181,14 +175,12 @@ files can be used directly. Not all OpenDKIM options are supported. If an
|
|||||||
unsupported option from OpenDKIM is specified, an error will be raised.
|
unsupported option from OpenDKIM is specified, an error will be raised.
|
||||||
|
|
||||||
.SH "DESCRIPTION"
|
.SH "DESCRIPTION"
|
||||||
.IX Header "DESCRIPTION"
|
|
||||||
|
|
||||||
Configuration options are described here and in the configuration file
|
Configuration options are described here and in the configuration file
|
||||||
provided with the package. The provided setup.py installs this configuration
|
provided with the package. The provided setup.py installs this configuration
|
||||||
file in /etc or /usr/local/etc.
|
file in /etc or /usr/local/etc.
|
||||||
|
|
||||||
.SH "OPTIONS"
|
.SH "OPTIONS"
|
||||||
.IX Header "OPTIONS"
|
|
||||||
|
|
||||||
.TP
|
.TP
|
||||||
.I AuthservID (string)
|
.I AuthservID (string)
|
||||||
@@ -441,7 +433,6 @@ unless an alternate
|
|||||||
is specified.
|
is specified.
|
||||||
|
|
||||||
.SH "AUTHORS"
|
.SH "AUTHORS"
|
||||||
.IX Header "AUTHORS"
|
|
||||||
\ddkimpy-milter\fR was written by Scott Kitterman <scott@kitterman.com>.
|
\ddkimpy-milter\fR was written by Scott Kitterman <scott@kitterman.com>.
|
||||||
It is based on dkimpy-milter.py Copyright (c) 2001-2013 Business Management Systems, Inc.
|
It is based on dkimpy-milter.py Copyright (c) 2001-2013 Business Management Systems, Inc.
|
||||||
Copyright (c) 2013-2015 Stuart D. Gathman
|
Copyright (c) 2013-2015 Stuart D. Gathman
|
||||||
|
|||||||
@@ -18,7 +18,6 @@
|
|||||||
|
|
||||||
from setuptools import setup
|
from setuptools import setup
|
||||||
import os
|
import os
|
||||||
import dkimpy_milter
|
|
||||||
|
|
||||||
description = "Domain Keys Identified Mail (DKIM) signing/verifying milter for Postfix/Sendmail."
|
description = "Domain Keys Identified Mail (DKIM) signing/verifying milter for Postfix/Sendmail."
|
||||||
|
|
||||||
@@ -31,14 +30,14 @@ except ImportError: # If PyDNS is not installed, prefer dnspython
|
|||||||
|
|
||||||
setup(
|
setup(
|
||||||
name='dkimpy-milter',
|
name='dkimpy-milter',
|
||||||
version=dkimpy_milter.__version__,
|
version='1.0.2',
|
||||||
author='Scott Kitterman',
|
author='Scott Kitterman',
|
||||||
author_email='scott@kitterman.com',
|
author_email='scott@kitterman.com',
|
||||||
url='https://launchpad.net/dkimpy-milter',
|
url='https://launchpad.net/dkimpy-milter',
|
||||||
description=description,
|
description=description,
|
||||||
download_url = "https://pypi.python.org/pypi/dkimpy-milter",
|
download_url = "https://pypi.python.org/pypi/dkimpy-milter",
|
||||||
classifiers= [
|
classifiers= [
|
||||||
'Development Status :: 4 - Beta',
|
'Development Status :: 5 - Production/Stable',
|
||||||
'Environment :: No Input/Output (Daemon)',
|
'Environment :: No Input/Output (Daemon)',
|
||||||
'Intended Audience :: System Administrators',
|
'Intended Audience :: System Administrators',
|
||||||
'License :: OSI Approved :: GNU General Public License (GPL)',
|
'License :: OSI Approved :: GNU General Public License (GPL)',
|
||||||
@@ -59,8 +58,8 @@ setup(
|
|||||||
data_files=[(os.path.join('share', 'man', 'man5'),
|
data_files=[(os.path.join('share', 'man', 'man5'),
|
||||||
['man/dkimpy-milter.conf.5']), (os.path.join('share', 'man', 'man8'),
|
['man/dkimpy-milter.conf.5']), (os.path.join('share', 'man', 'man8'),
|
||||||
['man/dkimpy-milter.8']), ('etc', ['etc/dkimpy-milter.conf']),
|
['man/dkimpy-milter.8']), ('etc', ['etc/dkimpy-milter.conf']),
|
||||||
(os.path.join('/lib', 'systemd', 'system'),
|
(os.path.join('lib', 'systemd', 'system'),
|
||||||
['system/dkimpy-milter.service']),(os.path.join('/etc', 'init.d'),
|
['system/dkimpy-milter.service']),(os.path.join('etc', 'init.d'),
|
||||||
['system/dkimpy-milter'])],
|
['system/dkimpy-milter'])],
|
||||||
zip_safe = False,
|
zip_safe = False,
|
||||||
**kw
|
**kw
|
||||||
|
|||||||
Regular → Executable
+9
-9
@@ -13,8 +13,6 @@
|
|||||||
# Provides: dkim-milter dkim-milter-python dkimpy-milter
|
# Provides: dkim-milter dkim-milter-python dkimpy-milter
|
||||||
# Required-Start: $remote_fs $syslog $network $time
|
# Required-Start: $remote_fs $syslog $network $time
|
||||||
# Required-Stop: $remote_fs $syslog $network
|
# Required-Stop: $remote_fs $syslog $network
|
||||||
# Should-Start:
|
|
||||||
# Should-Stop:
|
|
||||||
# Default-Start: 2 3 4 5
|
# Default-Start: 2 3 4 5
|
||||||
# Default-Stop: 0 1 6
|
# Default-Stop: 0 1 6
|
||||||
# Short-Description: dkimpy-milter
|
# Short-Description: dkimpy-milter
|
||||||
@@ -22,16 +20,16 @@
|
|||||||
### END INIT INFO
|
### END INIT INFO
|
||||||
prefix="/usr/local"
|
prefix="/usr/local"
|
||||||
exec_prefix=${prefix}
|
exec_prefix=${prefix}
|
||||||
sysconfdir="/etc/dkimpy-milter"
|
sysconfdir="/usr/local/etc"
|
||||||
bindir="${exec_prefix}/bin/"
|
bindir="${exec_prefix}/bin/"
|
||||||
RUNDIR="/var/run/dkimpy-milter"
|
RUNDIR="/run/dkimpy-milter"
|
||||||
DAEMON=${bindir}/dkimpy-milter
|
DAEMON=${bindir}/dkimpy-milter
|
||||||
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
|
PATH=/sbin:/bin:/usr/sbin:/usr/bin:/usr/local/bin:
|
||||||
NAME=dkimpy-milter
|
NAME=dkimpy-milter
|
||||||
DESC="Python DKIM Milter"
|
DESC="Python DKIM Milter"
|
||||||
USER=dkimpy-milter
|
USER=dkimpy-milter
|
||||||
GROUP=dkimpy-milter
|
GROUP=dkimpy-milter
|
||||||
SOCKET=$RUNDIR/dkimpy-milter.pid
|
SOCKET=$RUNDIR/dkimpy-milter.sock
|
||||||
|
|
||||||
test -x $DAEMON || exit 0
|
test -x $DAEMON || exit 0
|
||||||
|
|
||||||
@@ -69,14 +67,14 @@ case "$1" in
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
|
start-stop-daemon --start --background --quiet --pidfile \
|
||||||
start-stop-daemon --start --chuid $USER --background --quiet --pidfile \
|
|
||||||
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
||||||
echo "$NAME."
|
echo "$NAME."
|
||||||
;;
|
;;
|
||||||
stop)
|
stop)
|
||||||
echo -n "Stopping $DESC: "
|
echo -n "Stopping $DESC: "
|
||||||
if [ -f $RUNDIR/$NAME.pid ]; then
|
if [ -f $RUNDIR/$NAME.pid ]; then
|
||||||
|
chown root:root $RUNDIR/$NAME.pid
|
||||||
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
||||||
rm $RUNDIR/$NAME.pid
|
rm $RUNDIR/$NAME.pid
|
||||||
#echo $SOCKET
|
#echo $SOCKET
|
||||||
@@ -89,6 +87,7 @@ case "$1" in
|
|||||||
force-reload)
|
force-reload)
|
||||||
echo -n "Force reloading $DESC: "
|
echo -n "Force reloading $DESC: "
|
||||||
if [ -f $RUNDIR/$NAME.pid ]; then
|
if [ -f $RUNDIR/$NAME.pid ]; then
|
||||||
|
chown root:root $RUNDIR/$NAME.pid
|
||||||
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
||||||
rm $RUNDIR/$NAME.pid
|
rm $RUNDIR/$NAME.pid
|
||||||
#echo $SOCKET
|
#echo $SOCKET
|
||||||
@@ -97,7 +96,7 @@ case "$1" in
|
|||||||
fi
|
fi
|
||||||
fi
|
fi
|
||||||
sleep 1
|
sleep 1
|
||||||
start-stop-daemon --start --chuid $USER --background --quiet --pidfile \
|
start-stop-daemon --start --background --quiet --pidfile \
|
||||||
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
||||||
echo "$NAME."
|
echo "$NAME."
|
||||||
;;
|
;;
|
||||||
@@ -105,6 +104,7 @@ case "$1" in
|
|||||||
echo "Restarting $DESC: "
|
echo "Restarting $DESC: "
|
||||||
echo -n "Stopping $DESC: "
|
echo -n "Stopping $DESC: "
|
||||||
if [ -f $RUNDIR/$NAME.pid ]; then
|
if [ -f $RUNDIR/$NAME.pid ]; then
|
||||||
|
chown root:root $RUNDIR/$NAME.pid
|
||||||
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
start-stop-daemon --stop --pidfile $RUNDIR/$NAME.pid
|
||||||
rm $RUNDIR/$NAME.pid
|
rm $RUNDIR/$NAME.pid
|
||||||
#echo $SOCKET
|
#echo $SOCKET
|
||||||
@@ -115,7 +115,7 @@ case "$1" in
|
|||||||
echo "$NAME."
|
echo "$NAME."
|
||||||
sleep 1
|
sleep 1
|
||||||
echo -n "Starting $DESC: "
|
echo -n "Starting $DESC: "
|
||||||
start-stop-daemon --start --chuid $USER --background --quiet --pidfile \
|
start-stop-daemon --start --background --quiet --pidfile \
|
||||||
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
$RUNDIR/$NAME.pid --exec $DAEMON $sysconfdir/$NAME.conf
|
||||||
echo "$NAME."
|
echo "$NAME."
|
||||||
;;
|
;;
|
||||||
|
|||||||
@@ -1,11 +1,12 @@
|
|||||||
[Unit]
|
[Unit]
|
||||||
Description=DKIMpy Milter
|
Description=DKIMpy Milter
|
||||||
After=syslog.target network.target
|
Documentation=man:dkimpy-milter(8) man:dkimpy-milter.conf(5)
|
||||||
|
After=network.target
|
||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
PIDFile=/var/run/dkimpy-milter/dkimpy-milter.pid
|
PIDFile=/var/run/dkimpy-milter/dkimpy-milter.pid
|
||||||
ExecStart=/usr/local/bin/dkimpy-milter
|
ExecStart=/usr/local/bin/dkimpy-milter /usr/local/etc/dkimpy-milter.conf
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
|
|||||||
Reference in New Issue
Block a user