trusteddomainproject / opendkim Goto Github PK
View Code? Open in Web Editor NEWLicense: Other
License: Other
OPENDKIM README =============== This directory has the latest open source DKIM filter software from The OpenDKIM Project. There is a web site at http://www.opendkim.org that is home for the latest updates. +--------------+ | INTRODUCTION | +--------------+ The Trusted Domain Project is a community effort to develop and maintain an open source library for producing DKIM-aware applications, and a "milter"-based filter for providing DKIM service. The DKIM sender authentication system was originally created by the E-mail Signing Technology Group (ESTG) and is now a draft standard of the IETF (RFC6376). DKIM is an amalgamation of the DomainKeys (DK) proposal by Yahoo!, Inc. and the Internet Identified Mail (IIM) proposal by Cisco. "milter" is a portmanteau of "mail filter" and refers to a protocol and API for communicating mail traffic information between MTAs and mail filtering plug-in applications. It was originally invented at Sendmail, Inc. but has also been adapted to other MTAs. The OpenDKIM project started as a code fork of version 2.8.3 of the open source "dkim-milter" package developed and maintained by Sendmail, Inc. The license used by The OpenDKIM project is found in the LICENSE file. Portions of this project are also covered by the Sendmail Open Source License, available in this distribution in the file "LICENSE.Sendmail". See the copyright notice(s) in each source file to determine whether or not it is covered by both licenses. This package consists of a library that implements the DKIM service and a milter-based filter application that can plug in to any milter-aware MTA to provide that service to sufficiently recent sendmail, Postfix or other MTAs that support the milter protocol. An optional asynchronous resolver library is also provided to work around limitations of the basic BIND resolver which comes installed on most systems. +--------------+ | DEPENDENCIES | +--------------+ To compile and operate, this package requires the following: o OpenSSL (http://www.openssl.org, or ask your software vendor for a package). Any version will get you started, however v0.9.8 or later is required if you want to be able to sign or verify messages using the SHA256 message digest algorithm which is generally required for current DKIM applications. o sendmail v8.13.0 (or later), or Postfix 2.3, (or later) and libmilter. (These are only required if you are building the filter.) o Access to a working nameserver (required only for signature verification). o On Linux systems, either libbsd (BSD compatibility library) or some other library that provides strlcat() and strlcpy(). o If you wish to interface the filter with SQL databases, or store statistical information in a database, OpenDBX v1.3.7 or later is required. o If you wish to use the Lua interpreter hooks for filter policy control, or statistical extensions (--enable-statsext), Lua v5.1 or later is required. o If you wish to interface the filter with LDAP servers, OpenLDAP v2.1.3 or later is required. o For local hash or btree database support in either the filter or the library, Oracle's BerkeleyDB is required. All versions are supported. o If you are interested in tinkering with the build and packaging structure, you may need to upgrade to these versions of GNU's "autotools" components: autoconf (GNU Autoconf) 2.61 automake (GNU automake) 1.7 (or 1.9 to avoid warnings) ltmain.sh (GNU libtool) 2.2.6 (or 1.5.26 after make maintainer-clean) +-----------------------+ | RELATED DOCUMENTATION | +-----------------------+ The man page for opendkim (the actual filter program) is present in the opendkim directory of this source distribution. There is additional information in the INSTALL and FEATURES files, and in the README file in the opendkim directory. Changes are documented in the RELEASE_NOTES file. HTML-style documentation for libopendkim is available in libopendkim/docs in this source distribution. General information about DKIM can be found at http://www.dkim.org Mailing lists discussing and supporting the DKIM software found in this package are maintained via a list server at opendkim.org. Visit http://www.opendkim.org to subscribe or browse archives. The available lists are: opendkim-announce (moderated) Release announcements. opendkim-users General OpenDKIM user questions and answers. opendkim-dev Chatter among OpenDKIM developers. opendkim-cvs Automated source code change announcements. May be renamed soon to something more general since we're moving away from CVS. Bug tracking is done via the trackers on SourceForge at http://sourceforge.net/projects/opendkim. You can enter new bug reports there, but please check first for older bugs already open, or even already closed, before opening a new issue. +---------+ | WARNING | +---------+ Since OpenDKIM uses cryptography, the following information from OpenSSL applies to this package as well. PLEASE REMEMBER THAT EXPORT/IMPORT AND/OR USE OF STRONG CRYPTOGRAPHY SOFTWARE, PROVIDING CRYPTOGRAPHY HOOKS OR EVEN JUST COMMUNICATING TECHNICAL DETAILS ABOUT CRYPTOGRAPHY SOFTWARE IS ILLEGAL IN SOME PARTS OF THE WORLD. SO, WHEN YOU IMPORT THIS PACKAGE TO YOUR COUNTRY, RE-DISTRIBUTE IT FROM THERE OR EVEN JUST EMAIL TECHNICAL SUGGESTIONS OR EVEN SOURCE PATCHES TO THE AUTHOR OR OTHER PEOPLE YOU ARE STRONGLY ADVISED TO PAY CLOSE ATTENTION TO ANY EXPORT/IMPORT AND/OR USE LAWS WHICH APPLY TO YOU. THE AUTHORS ARE NOT LIABLE FOR ANY VIOLATIONS YOU MAKE HERE. SO BE CAREFUL, IT IS YOUR RESPONSIBILITY. If you use OpenSSL then make sure you read their README file which contains information about patents etc. +---------------------+ | DIRECTORY STRUCTURE | +---------------------+ contrib A collection of user contributed scripts that may be useful. docs A collection of RFCs and drafts related to opendkim. libar An optional thread-safe asynchronous resolver library. libopendkim A library that implements the proposed DKIM standard. libopendkim/docs HTML documentation describing the API provided by libopendkim. libvbr An optional library that implements Vouch By Reference (VBR, RFC5518). opendkim A milter-based filter application which uses libopenkim (and optionally libar) to provide DKIM service via an MTA using the milter protocol. +----------------+ | RUNTIME ISSUES | +----------------+ WARNING: symbol 'X' not available The filter attempted to get some information from the MTA that the MTA did not provide. At various points in the interaction between the MTA and the filter, certain macros containing information about the job in progress or the connection being handled are passed from the MTA to the filter. In the case of sendmail, the names of the macros the MTA should pass to the filter are defined by the "Milter.macros" settings in sendmail.cf, e.g. "Milter.macros.connect", "Milter.macros.envfrom", etc. This message indicates that the filter needed the contents of macro X, but that macro was not passed down from the MTA. Typically the values needed by this filter are passed from the MTA if the sendmail.cf was generated by the usual m4 method. If you do not have those options defined in your sendmail.cf, make sure your M4 configuration files are current and rebuild your sendmail.cf to get appropriate lines added to your sendmail.cf, and then restart sendmail. MTA timeouts By default, the MTA is configured to wait up to ten seconds for a response from a filter before giving up. When querying remote nameservers for key and policy data, the DKIM filter may not get a response from the resolver within that time frame, and thus this MTA timeout will occur. This can cause messages to be rejected, temp-failed or delivered without verification, depending on the failure mode selected for the filter. When using the standard resolver library provided with your system, the DNS timeout cannot be adjusted. If you encounter this problem, you must increase the time the MTA waits for replies. See the documentation in the sendmail open source distribution (libmilter/README in particular) for instructions on changing these timeouts. When using the provided asynchronous resolver library, you can use the "-T" command line option to change the timeout so that it is shorter than the MTA timeout. d2i_PUBKEY_bio() failed After retrieving and decoding a public key to perform a message verification, the OpenSSL library attempted to make use of that key but failed. The known possible causes are: (a) Memory exhaustion (b) Key corruption If you're set to temp-fail messages in these cases, the remote end will probably retry the message. If the same message fails again later, the key is probably corrupted or otherwise invalid. You can try compiling with _FFR_LOG_SSL_ERRORS to have the filter extract OpenSSL library errors and include them in the system log when such conditions occur for further diagnostics. In one observed case, a corrupt key also caused the following to be logged: error:0D0680A8:asn1 encoding routines:ASN1_CHECK_TLEN:wrong tag; error:0D07803A:asn1 encoding routines:ASN1_ITEM_EX_D2I:nested asn1 error Other OpenDKIM issues: Report any bugs to the email address [email protected] or to the sourceforge issue trackers accessible at: https://sourceforge.net/p/opendkim/_list/tickets +-----------------------------+ | Sendmail REWRITING FEATURES | +-----------------------------+ There are two features of the sendmail MTA which, if activated, can interfere with successful use of the DKIM service. The two features are MASQUERADE_AS and FEATURE(genericstable). See cf/README in the open source sendmail source code distribution for more information. Due to the way the milter protocol is incorporated into the MTA, opendkim sees the headers before they are modified as required by those two features. This means the DKIM signature is generated based on the headers originally injected by the mail client and not on the headers which are actually sent out by the MTA. As a result, the verifying agent at the receiver's side will be unable to verify the signature as the signed data and the received data don't match. The suggested solutions to this problem are: (1) Send mail with the headers already written as needed, obviating the need for these features (or just turn them off). (2) Have two MTAs set up, either on separate boxes or on the same box. The first MTA should do all of the rewriting (i.e. use these two features) and the second one should use opendkim to add the signature and do no rewriting at all. (3) Have multiple DaemonPortOptions lines in your configuration file. The first daemon port (port 25) does the header rewriting and then routes the message to the second port; the latter does no rewriting but does the signing and then sends the message on its way. There is also a feature of Sendmail that will cause it to alter addresses after signing but before they are transmitted. The feature, which is on by default, passes addresses in header fields to the resolver functions to ensure they are canonical. This can result in the replacement of those strings in the sent message with their canonical forms only after the message is signed, which will invalidate the signatures. To suppress this feature, add the following line to your sendmail.mc and submit.mc configuration files, re-generate your configuration and restart the filter: FEATURE(`nocanonify') -- Copyright (c) 2010-2012, 2014, The Trusted Domain Project. All rights reserved.
pw->pw_name
can be changed by a concurrent call of getpwuid()
, so reading pw->pw_name
it must be protected by the same lock, that protects getpwuid()
.
Copy of https://sourceforge.net/p/opendkim/patches/39/.
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -4724,10 +4724,9 @@ dkimf_securefile(const char *path, ino_t *ino, uid_t myuid, char *err,
if (myuid == (uid_t) -1)
myuid = pw->pw_uid;
- pthread_mutex_unlock(&pwdb_lock);
-
#ifdef HAVE_REALPATH
strlcpy(myname, pw->pw_name, sizeof myname);
+ pthread_mutex_unlock(&pwdb_lock);
p = realpath(path, real);
if (p == NULL)
@@ -4766,6 +4765,7 @@ dkimf_securefile(const char *path, ino_t *ino, uid_t myuid, char *err,
return 1;
#else /* HAVE_REALPATH */
+ pthread_mutex_unlock(&pwdb_lock);
struct stat s;
status = stat(path, &s);
Includes https://sourceforge.net/p/opendkim/patches/36/: gnutls_pubkey_verify_hash() was removed in v3.4 and gnutls_pubkey_verify_hash2() was added in version 3.0.20.
Compilation fixes after the introduction of ED25519.
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -6,7 +6,7 @@ release, and a summary of the changes in that release.
2.11.0 2018/05/31
README: Clarify for the send+verify mode how to tweak sendmail not
to break signatures.
- Add support for ED25519 keys.
+ Add support for ED25519 keys with OpenSSL.
Add "header.s" and "header.a" in generated Authentication-Results
header fields.
Add _FFR_CONDITIONAL, experimental support for conditional DKIM
diff --git a/libopendkim/dkim.c b/libopendkim/dkim.c
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -1172,7 +1172,7 @@ dkim_privkey_load(DKIM *dkim)
#endif /* USE_GNUTLS */
#ifdef USE_GNUTLS
- status = gnutls_x509_privkey_init(&crypto->rsa_key);
+ status = gnutls_x509_privkey_init(&crypto->crypto_key);
if (status != GNUTLS_E_SUCCESS)
{
dkim_load_ssl_errors(dkim, status);
@@ -1182,14 +1182,14 @@ dkim_privkey_load(DKIM *dkim)
if (strncmp((char *) dkim->dkim_key, "-----", 5) == 0)
{ /* PEM */
- status = gnutls_x509_privkey_import(crypto->rsa_key,
- &crypto->rsa_keydata,
+ status = gnutls_x509_privkey_import(crypto->crypto_key,
+ &crypto->crypto_keydata,
GNUTLS_X509_FMT_PEM);
}
else
{
- status = gnutls_x509_privkey_import(crypto->rsa_key,
- &crypto->rsa_keydata,
+ status = gnutls_x509_privkey_import(crypto->crypto_key,
+ &crypto->crypto_keydata,
GNUTLS_X509_FMT_DER);
}
@@ -1200,7 +1200,7 @@ dkim_privkey_load(DKIM *dkim)
return DKIM_STAT_NORESOURCE;
}
- status = gnutls_privkey_init(&crypto->rsa_privkey);
+ status = gnutls_privkey_init(&crypto->crypto_privkey);
if (status != GNUTLS_E_SUCCESS)
{
dkim_load_ssl_errors(dkim, status);
@@ -1208,18 +1208,18 @@ dkim_privkey_load(DKIM *dkim)
return DKIM_STAT_NORESOURCE;
}
- status = gnutls_privkey_import_x509(crypto->rsa_privkey,
- crypto->rsa_key, 0);
+ status = gnutls_privkey_import_x509(crypto->crypto_privkey,
+ crypto->crypto_key, 0);
if (status != GNUTLS_E_SUCCESS)
{
dkim_load_ssl_errors(dkim, status);
dkim_error(dkim, "gnutls_privkey_import_x509() failed");
- (void) gnutls_privkey_deinit(rsa->rsa_privkey);
+ (void) gnutls_privkey_deinit(crypto->crypto_privkey);
return DKIM_STAT_NORESOURCE;
}
- (void) gnutls_privkey_get_pk_algorithm(rsa->rsa_privkey,
- &rsa->rsa_keysize);
+ (void) gnutls_privkey_get_pk_algorithm(crypto->crypto_privkey,
+ &crypto->crypto_keysize);
#else /* USE_GNUTLS */
@@ -5533,6 +5533,11 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINFO *sig)
size_t diglen = 0;
#ifdef USE_GNUTLS
gnutls_datum_t key;
+#if GNUTLS_VERSION_MAJOR==3
+ gnutls_digest_algorithm_t hash;
+ gnutls_sign_algorithm_t sign_algo;
+#endif
+
#else /* USE_GNUTLS */
BIO *key;
#endif /* USE_GNUTLS */
@@ -5685,11 +5690,26 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINFO *sig)
return DKIM_STAT_OK;
}
+#if GNUTLS_VERSION_MAJOR==2
vstat = gnutls_pubkey_verify_hash(crypto->crypto_pubkey, 0,
+#else
+ hash = dkim_libfeature(dkim->dkim_libhandle, DKIM_FEATURE_SHA256) &&
+ sig->sig_hashtype == DKIM_HASHTYPE_SHA256 ? GNUTLS_DIG_SHA256 : GNUTLS_DIG_SHA1;
+
+ sign_algo = gnutls_pk_to_sign(GNUTLS_PK_RSA, hash);
+ if (sign_algo == GNUTLS_SIGN_UNKNOWN)
+ {
+ assert(0);
+ /* NOTREACHED */
+ }
+
+ vstat = gnutls_pubkey_verify_hash2(crypto->crypto_pubkey,
+ sign_algo, 0,
+#endif
&crypto->crypto_digest,
&crypto->crypto_sig);
if (vstat < 0)
- dkim_sig_load_ssl_errors(dkim, sig, rsastat);
+ dkim_sig_load_ssl_errors(dkim, sig, vstat);
(void) gnutls_pubkey_get_pk_algorithm(crypto->crypto_pubkey,
&crypto->crypto_keysize);
The tarballs published at https://github.com/trusteddomainproject/OpenDKIM/releases cannot be built and installed using the classic procedure ./configure
make
make install
. This used to work in the past, and it should work according to the INSTALL file.
$ curl -LO https://github.com/trusteddomainproject/OpenDKIM/archive/rel-opendkim-2-11-0-Beta2.tar.gz
$ tar xvf rel-opendkim-2-11-0-Beta2.tar.gz
$ cd OpenDKIM-rel-opendkim-2-11-0-Beta2
$ ./configure
configure: error: cannot find install-sh, install.sh, or shtool in build-aux "."/build-aux
On a system that has Autotools, autoreconf -i
can of course generate the missing files, but this additional step shouldn’t be necessary.
diff --git a/libopendkim/dkim.c b/libopendkim/dkim.c
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -5693,8 +5693,6 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINFO *sig)
vstat = gnutls_pubkey_verify_hash(crypto->crypto_pubkey, 0,
&crypto->crypto_digest,
&crypto->crypto_sig);
- if (vstat < 0)
- dkim_sig_load_ssl_errors(dkim, sig, vstat);
# else /* GNUTLS_VERSION_MAJOR == 2 */
hash = dkim_libfeature(dkim->dkim_libhandle,
DKIM_FEATURE_SHA256);
@@ -5709,9 +5707,12 @@ dkim_sig_process(DKIM *dkim, DKIM_SIGINFO *sig)
signalg, 0,
&crypto->crypto_digest,
&crypto->crypto_sig);
+# endif /* GNUTLS_VERSION_MAJOR == 2 */
if (vstat < 0)
dkim_sig_load_ssl_errors(dkim, sig, vstat);
-# endif /* GNUTLS_VERSION_MAJOR == 2 */
+ else
+ /* OpenSSL’s RSA_verify returns 1 on success, so we normalize vstat here */
+ vstat = 1;
(void) gnutls_pubkey_get_pk_algorithm(crypto->crypto_pubkey,
&crypto->crypto_keysize);
The most recent beta release file is named:
rel-opendkim-2-11-0-Beta0.tar.gz
This is novel. Is it on purpose?
I would have expected opendkim-2.11.0-Beta0.tar.gz.
It would be nice to have a more normal dot separated version number in the tarball name as some of the Debian tools are more difficult to use the way it is now.
Thanks for considering,
Scott K
diff --git a/opendkim/opendkim-db.c b/opendkim/opendkim-db.c
--- a/opendkim/opendkim-db.c
+++ b/opendkim/opendkim-db.c
@@ -20,7 +20,6 @@
#ifdef HAVE_STDBOOL_H
# include <stdbool.h>
#endif /* HAVE_STDBOOL_H */
-#include <syslog.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
diff --git a/opendkim/opendkim-lua.c b/opendkim/opendkim-lua.c
--- a/opendkim/opendkim-lua.c
+++ b/opendkim/opendkim-lua.c
@@ -600,7 +600,7 @@ dkimf_lua_setup_hook(void *ctx, const char *script, size_t scriptlen,
** -1 -- memory allocation failure
**
** Notes:
-** Called by mlfi_eom() so it can decide whether or not the message
+** Called by mlfi_eoh() so it can decide whether or not the message
** is acceptable.
*/
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -750,7 +750,6 @@ _Bool querycache; /* local query cache */
#endif /* QUERY_CACHE */
_Bool die; /* global "die" flag */
int diesig; /* signal to distribute */
-int thread_count; /* thread count */
#ifdef QUERY_CACHE
time_t cache_lastlog; /* last cache stats logged */
#endif /* QUERY_CACHE */
@@ -5233,7 +5232,7 @@ dkimf_msr_body(struct signreq *sr, DKIM **last, u_char *body, size_t bodylen)
/*
** DKIMF_MSR_MINBODY -- determine minimum body required to satisfy all
-** all open canonicalizations
+** open canonicalizations
**
** Parameters:
** srh -- head of the signature request list
@@ -11213,7 +11212,6 @@ mlfi_envrcpt(SMFICTX *ctx, char **envrcpt)
"message requeueing (internal error)");
}
- free(copy);
dkimf_cleanup(ctx);
return SMFIS_TEMPFAIL;
}
@@ -16595,11 +16593,11 @@ main(int argc, char **argv)
{
if (curconf->conf_dolog)
{
- syslog(LOG_ERR, "pthread_sigprocmask(): %s",
+ syslog(LOG_ERR, "pthread_sigmask(): %s",
strerror(status));
}
- fprintf(stderr, "%s: pthread_sigprocmask(): %s\n", progname,
+ fprintf(stderr, "%s: pthread_sigmask(): %s\n", progname,
strerror(status));
dkimf_zapkey(curconf);
diff --git a/opendkim/stats.c b/opendkim/stats.c
--- a/opendkim/stats.c
+++ b/opendkim/stats.c
@@ -56,11 +56,6 @@
#include "opendkim.h"
#include "opendkim-db.h"
-/* macros, defaults */
-#define DEFCT "text/plain"
-#define DEFCTE "7bit"
-#define DKIMF_STATS_MAXCOST 10
-
/* globals */
static pthread_mutex_t stats_lock;
RFC 8616 allows UTF-8 characters in domain and selector (and the i= tag). That doesn't seem to disturb signing. However, verification is hampered by a couple of ASCII checks in dkim.c. In addition, looking up the key requires IDNA encoding.
The configure issue should go in a separate bug, but I report it here to avoid having to manually edit the diff. It is res_ninit
, which is not detected it it is a macro (similar to bug #23).
The patch attached is a diff against the trunk at revision 5013. It makes verification work.
patch.txt
System:
Debian buster/sid via Raspbian
OpenDKIM:
opendkim: OpenDKIM Filter v2.11.0
Compiled with OpenSSL 1.1.1b 26 Feb 2019
SMFI_VERSION 0x1000001
libmilter version 1.0.1
Supported signing algorithms:
rsa-sha1
rsa-sha256
Supported canonicalization algorithms:
relaxed
simple
Active code options:
POLL
QUERY_CACHE
USE_DB
USE_LDAP
USE_LUA
USE_ODBX
USE_UNBOUND
_FFR_ATPS
_FFR_RBL
_FFR_REPLACE_RULES
_FFR_SENDER_MACRO
_FFR_STATS
_FFR_VBR
libopendkim 2.11.0: atps query_cache
Issue:
The following line is logged in syslog on startup:
[/usr/lib/tmpfiles.d/opendkim.conf:1] Line references path below legacy directory /var/run/, updating /var/run/opendkim → /run/opendkim; please update the tmpfiles.d/ drop-in file accordingly.
Looking at the tmpfiles.d config file, the content is:
rpi# cat /usr/lib/tmpfiles.d/opendkim.conf
d /var/run/opendkim 0750 opendkim opendkim - -
Path has been moved from /var/run to /run and systemd tmpfiles.d has been updated to warn when SW component still uses the old path.
OpenDKIM needs to be updated to use /run instead of /var/run for PID file.
Hello,
e-mails are being rejected as follows:
Jul 4 11:27:52 [servername] opendkim[37482]: F2BCE7E971: o4.hv30n.shared.sendgrid.net [167.89.100.125] not internal
Jul 4 11:27:52 [servername] opendkim[37482]: F2BCE7E971: not authenticated
Jul 4 11:27:53 [servername] opendkim[37482]: F2BCE7E971: signature=2pq1mzDc domain=example.com selector=s1 result="unprotected header field"
Jul 4 11:27:53 [servername] postfix/cleanup[87943]: F2BCE7E971: milter-reject: END-OF-MESSAGE from o4.hv30n.shared.sendgrid.net[167.89.100.125]: 4.7.0 DKIM signature processing failed; from=<bounces+16072861-25fe-[recipient]=[servername]@em285.example.com> to=<[recipient]@[servername]> proto=ESMTP helo=<o4.hv30n.shared.sendgrid.net>
To avoid the upfront rejection, I modified opendkim.conf from
On-BadSignature reject
On-SignatureError reject
to
On-BadSignature tempfail
On-SignatureError tempfail
and restarted the moving parts. As a result, the emails are still being rejected with the above message type.
Searching for "unprotected header field" here in github, I could only find one line of code, namely a definition of "DKIM_SIGERROR_MBSFAILED" in libopendkim/dkim-tables.c.
I then looked into the specification (rfc6541, rfc6376, rfc5672, rfc5518, rfc4871, rfc4870) and could not find any reference to "unprotected header field" and "DKIM_SIGERROR_MBSFAILED".
According to libopendkim/dkim.h, DKIM_SIGERROR_MBSFAILED means "must be signed" failure, that is "a header on the "must be signed" list was present but not covered by this signature".
# MustBeSigned (dataset)
# Specifies a set of header fields that, if present, must be cov-
# ered by the DKIM signature when verifying a message. If a
# header field in this set is present in the message and is not
# signed, the filter will treat even an otherwise valid signature
# as invalid. The default is an empty list.
ADDED TO CLARIFY
This scenario is about my opendkim server (example.com) verifying some one else's e-mail.
My understanding of the issue is that my opendkim server rejected an e-mail because its DKIM signature did not cover a header that had to be signed according to the sender's DKIM policy.
What I need from my opendkim server is to add a dkim=tempfail in the Authentication header and deliver the e-mail. I do not want it to reject the e-mail. I want to see the e-mail to inspect it myself.
Hello,
Today i have installed opendkim on ubuntu 16.04.4 and got error when i tryed to start it:
May 31 11:06:02 mail opendkim[59911]: opendkim: incompatible SSL versions (library = 0x0100020bf, filter = 01000204f)
OpenDKIM version - opendkim 2.10.3-3build1
Openssl version - 1.0.2.g-1ubuntu4.12
After that i tryed to download source of openssl from openssl.org and compile it and there is the same error with:
openssl version
OpenSSL 1.1.0.h 27 Mar 2018
opendkim 2.11.0-Beta2 reports in maillog:
failed to parse Authentication-Results: header field
I patched it to include the offending header content in the syslog to find it:
Authentication-Results: spf=pass (sender IP is 209.85.219.172)#12 smtp.mailfrom=example.org; alum.mit.edu; dkim=pass (signature was verified)#12 header.d=example.org;alum.mit.edu; dmarc=pass action=none#012 header.from=example.org;compauth=pass reason=100
This header is being added by MX alum-mit-edu.mail.protection.outlook.com which receives mail on behalf of the MIT alum.mit.edu email forwarding service, before forwarding on to the true destination address. At that true destination, opendkim reports its inability to parse this header.
When mail is sent directly from example.org to the true destination address (not going through the alum.mit.edu forwarder), the above header is not added, and opendkim works as expected.
Even if the configuration file delegates to a Lua script whether opendkim should verify or sign.
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
index 6938e21b..ab56ac22 100644
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -12299,7 +12299,7 @@ mlfi_eoh(SMFICTX *ctx)
*/
/* signing requests with signing mode disabled */
- if (dfc->mctx_srhead != NULL &&
+ if (!testmode && dfc->mctx_srhead != NULL &&
(conf->conf_mode & DKIMF_MODE_SIGNER) == 0)
return SMFIS_ACCEPT;
miltertest
crashes when a milter replaces the message body with a message body larger than 1 kilobyte or so. It looks like the cause is a buffer overflow in miltertest
. To reproduce:
overflow.c:
#include <assert.h>
#include <string.h>
#include "libmilter/mfapi.h"
// Crashes with size 1033, works when decreased:
#define BODYSIZE 1033
static sfsistat overflow_eom(SMFICTX *ctx) {
unsigned char body[BODYSIZE];
memset(body, '.', BODYSIZE);
int status = smfi_replacebody(ctx, body, BODYSIZE);
assert(status == MI_SUCCESS);
return SMFIS_CONTINUE;
}
int main(void) {
int status = smfi_setconn("inet:3000@localhost");
assert(status == MI_SUCCESS);
status = smfi_register((struct smfiDesc) {
.xxfi_version = SMFI_VERSION,
.xxfi_flags = SMFIF_CHGBODY,
.xxfi_eom = overflow_eom,
});
assert(status == MI_SUCCESS);
return smfi_main();
}
overflow.lua:
conn = mt.connect("inet:3000@localhost")
assert(conn)
local err = mt.eom(conn)
assert(err == nil, err)
assert(mt.getreply(conn) == SMFIR_CONTINUE)
Compile the milter with something like c99 -Wall overflow.c -lmilter -o overflow
, then start the milter with ./overflow
and run the test:
$ miltertest -s overflow.lua
*** stack smashing detected ***: <unknown> terminated
Aborted (core dumped)
We're currently making several changes to the Gentoo Linux ebuild of OpenDKIM to address security issues. While doing so, we came across a problem which is bugging us. We have a user opendkim
which is member of groups opendkim
and dkimsocket
. Group opendkim is meant to regulate read access to the private key file:
$ ls -l /var/lib/opendkim/
total 8.2M
-r--r----- 1 root opendkim 1.7K Feb 3 2019 mumble.key
-r--r--r-- 1 root opendkim 451 Feb 3 2019 mumble.pub
...
Group dkimsocket is meant to regulate write access to a local socket file via the following settings:
$ cat /etc/opendkim/opendkim.conf
Socket local:/run/opendkim/socket
UserID opendkim:dkimsocket
UMask 0117
...
$ ls -l /run/opendkim/
total 0
srw-rw---- 1 opendkim dkimsocket 0 Apr 1 19:38 socket=
Unfortunately the resulting process runs as only one group, namely dkimsocket, instead of running as both opendkim and dkimsocket:
$ cat /proc/26389/status
Name: opendkim
...
Uid: 108 108 108 108
Gid: 1007 1007 1007 1007
FDSize: 64
Groups: 1007
When using only UserID opendkim
(no group), and when dkimsocket is that user's primary group, the process picks up both groups, dkimsocket and opendkim:
$ cat /proc/26778/status
Name: opendkim
...
Uid: 108 108 108 108
Gid: 1007 1007 1007 1007
FDSize: 64
Groups: 108 1007
The combined result is that we cannot enforce access to the private key and the local socket using distinct groups. This matters because the MTA needs to write to the socket but should not have access to the key file, while OpenDKIM should not be able to access any of the MTA's files.
I can set the owner of mumble.key to opendkim:opendkim
instead of root:opendkim
, but from a security standpoint this means that if some adversary manages to run code as opendkim he can overwrite the key material.
libunbound:ub_ctx_config() uses internally a flex generated non-reentrant lexer and bison generated non-pure paprser. Calling simultaneously two non-reentrant lexers or parsers is a bad idea, and two threads can alter the state of the lexer/parser without synchronization.
The calls to ub_ctx_config in opendkim/opendkim-dns.c:dkimf_ub_config need to be protected by mutex.
The documentation of libunbound:ub_ctx_config() says the function is thread-safe, but this is only true when only one instance of libunbound:ub_ctx * is used in the application, which is not the case with opendkim. See also https://www.nlnetlabs.nl/bugs-script/show_bug.cgi?id=1913.
Copy of https://sourceforge.net/p/opendkim/bugs/265/.
diff --git a/opendkim/opendkim-dns.c b/opendkim/opendkim-dns.c
--- a/opendkim/opendkim-dns.c
+++ b/opendkim/opendkim-dns.c
@@ -75,6 +75,7 @@ struct dkimf_unbound
pthread_cond_t ub_ready;
};
+pthread_mutex_t ub_config_mutex;
/* struct dkimf_unbound_cb_data -- libunbound callback data */
struct dkimf_unbound_cb_data
{
@@ -440,7 +441,9 @@ dkimf_ub_config(void *srv, const char *file)
ub = srv;
+ pthread_mutex_lock(&ub_config_mutex);
status = ub_ctx_config(ub->ub_ub, (char *) file);
+ pthread_mutex_unlock(&ub_config_mutex);
return (status == 0 ? 0 : -1);
}
diff --git a/opendkim/opendkim-dns.h b/opendkim/opendkim-dns.h
--- a/opendkim/opendkim-dns.h
+++ b/opendkim/opendkim-dns.h
@@ -33,6 +33,7 @@ struct dkimf_filedns;
/* libunbound includes */
# include <unbound.h>
+extern pthread_mutex_t ub_config_mutex;
/* prototypes */
extern int dkimf_unbound_setup __P((DKIM_LIB *));
# ifdef _FFR_RBL
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -15555,6 +15555,9 @@ main(int argc, char **argv)
no_i_whine = TRUE;
conffile = NULL;
+#ifdef USE_UNBOUND
+ pthread_mutex_init(&ub_config_mutex, NULL);
+#endif
memset(myhostname, '\0', sizeof myhostname);
(void) gethostname(myhostname, sizeof myhostname);
This is an updated copy of https://sourceforge.net/p/opendkim/patches/40/.
diff --git a/RELEASE_NOTES b/RELEASE_NOTES
--- a/RELEASE_NOTES
+++ b/RELEASE_NOTES
@@ -4,6 +4,8 @@ This listing shows the versions of the OpenDKIM package, the date of
release, and a summary of the changes in that release.
2.11.0 2018/05/31
+ opendkim/README: Clarify for the send+verify mode how to tweak
+ sendmail not to break signatures.
Add support for ED25519 keys.
Add "header.s" and "header.a" in generated Authentication-Results
header fields.
diff --git a/opendkim/README b/opendkim/README
--- a/opendkim/README
+++ b/opendkim/README
@@ -160,7 +160,38 @@ start at step (5).
socket specification:
INPUT_MAIL_FILTER(`opendkim', `S=inet:8891@localhost')
- (c) Rebuild your sendmail.cf in the usual way
+ (c) 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, in particular when the
+ sending domain published p=reject; DMARC policy. By default, sendmail
+ adds quotes to address headers, when there are no quotes and the
+ display-part of the address contains fullstop or apostrophe,
+ invalidating any DKIM signatures contained in the message. To tell
+ sendmail not to modify the headers insert in sendmail.mc:
+ conf(`confMUST_QUOTE_CHARS', `')
+
+ (d) As stated in sendmail's KNOWNBUGS file, sendmail truncates
+ header-values longer than 256 characters, which could mean truncating
+ the domain of a long From:-header-value and invaldating the signature.
+ Consider increasing MAXNAME in sendmail/conf.h to mitigate changing
+ the messages and invalidating their signatures. This change requires
+ recompiling sendmail.
+
+ (e) Beware that when sendmail receives the header:
+
+To: Aaaaaaaaaaaaaaaaaa aaaaaaaaaaa aaaaaaaaaaaa <[email protected]>,Bbbbbbbbbbbbbbbbbb b <[email protected]>
+Message-ID: <[email protected]>
+
+ it will send it unmodified to the milter and later rewrite it to:
+
+To: Aaaaaaaaaaaaaaaaaa aaaaaaaaaaa aaaaaaaaaaaa <[email protected]>,
+ Bbbbbbbbbbbbbbbbbb b <[email protected]>
+
+ After the comma a new line and eight spaces were inserted. The
+ insertion of white space characters (during folding) breaks the DKIM
+ signature.
+
+ (f) Rebuild your sendmail.cf in the usual way
For Postfix:
@@ -272,6 +303,17 @@ your sendmail.mc file:
define(`confSEVEN_BIT_INPUT',true)dnl
+However, the aforementioned tweak changes the byte sequence C2 A0 (NO BREAK
+SPACE) into "B ", altering what is displayed to the final user. In practice,
+when the server running OpenDKIM is used just for relaying email in terms of
+aliases, having mailboxes hosted somewhere else, relayed messages are
+displayed correctly to the final user only when the tweak is not made.
+
+The further, when openDKIM is used both to sign and verify signatures, a set
+confSEVER_BIT_INPUT invalidates the signature added by the original sender.
+If the MTA connected to OpenDKIM is used to relay messages, e.g. as aliases,
+and the origianl sender set p=reject; DMARC policy, then the adjustment is
+counterproductive.
TESTING
=======
see #51
If I haven't missed any important update to the DKIM spec, the current spec says:
RFC6376, Section 3.6.1:
The "rsa" key type
indicates that an ASN.1 DER-encoded [ITU-X660-1997] RSAPublicKey
(see [RFC3447], Sections 3.1 and A.1.1) is being used in the "p="
tag. (Note: the "p=" tag further encodes the value using the
base64 algorithm.) Unrecognized key types MUST be ignored.
Errata exist (https://www.rfc-editor.org/errata/eid3017) that extend this to
The "rsa" key type
indicates that an ASN.1 DER-encoded [ITU-X660-1997] RSAPublicKey
(see [RFC3447], Sections 3.1 and A.1.1), which MAY be contained in
a SubjectPublicKeyInfo (see [RFC5280], Section A.1), is being used
in the "p=" tag.
The errata is set to "Held for Document Update":
The erratum is not a necessary update to the RFC. However, any future update of the document might consider this erratum, and determine whether it is correct and merits including in the update.
To my understanding, this may mean anything with regard to a future version of the spec.
I'm aware that appearantly the whole world uses SubjectPublicKeyInfo in published DNS records and I also noticed that, e.g. dkimpy is in its current state is also not able to parse a RSAPublicKey which is not contained in a SubjectPublicKeyInfo from the 'p=' tag in a TXT record. But still, the RFC defines the RSAPublicKey-represenation definitely as valid and therefore I think it would be somehow correct to support it.
Hi,
On linux opendkim is dependent on libbsd because of strlcpy and strlcat functions. I found a way how to remove this dependency with simple wrapper which uses strncpy and strncat functions which are included in glibc. Would you be open to a change which would add configuration argument to configure.ac, some conditionals to makefiles and conditionals to source files which are using strl* functions?
Hi everyone,
I noticed that with the default resolver active, libopendkim reports DKIM_SIGERROR_KEYFAIL if it receives a NXDOMAIN reply. This is not distinguishable from a SRVFAIL "reply", which would translate into a TEMPFAIL according to RFC 6376.
To my understanding, a DKIM_SIGERROR_NOKEY would be the more appropriate reaction, which then should be translated into a PERMFAIL in terms of DKIM results.
The default resolver in dkim-dns.c uses res_(n)query, which returns a failure and sets h_errno to HOST_NOT_FOUND in case of a NXDOMAIN reply. This is never checked however, so the evaluation of results in dkim-key.c justs sees a DKIM_DNS_ERROR and reports DKIM_STAT_KEYFAIL (which translates to DKIM_SIGERROR_KEYFAIL), which indicates a temporary failure (retry again later), which does not really make sense for NXDOMAIN.
Main problem is that the res_(n)query documentation does not cleary state what happens with the passed buffer in case of a NXDOMAIN response and that libopendkim does not define a explicit DKIM_DNS_ERROR_NOTFOUND.
The implementations I've seen all return -1 but still fill the buf with the actual DNS response packet. This could be used by copying the header data (maybe even setting hdr->rcode = NXDOMAIN for good measure) and returning DKIM_DNS_SUCCESS, as well as checking for NXDOMAIN earlier in dkim_get_key_dns (see workaround)
If someone with the capability to merge agrees to that solution or has ideas for improvement I'm happy to provide a PR.
When an email with DKIM-Signature: v=1; a=ed25519-sha256; c=relaxed/simple; …
arrives and opendkim is not compiled to support ed25519-sha256, in libopendkim/dkim.c:2106 sigalg is set to 2. dkim_libfeature(lib, DKIM_FEATURE_ED25519) on line 2134 returns false. On line 2141 continue
is executed. In turm on line 2150 dkim→dkim_siglist[c]→sig_signalg is not set. It stays 0, as set on line 1963 with memset. signalg 0 corresponds in dkim-tables.c:table algorithms to DKIM_SIGN_RSASHA1.
When adding the Authentication-Results’ header in opendkim.c:dkimf_ar_all_sigs(), first algorithm = dkim_sig_getalgorithm(sigs[c]);
is called, which returns rsa-sha1, and then header.a=rsa-sha1 is added to AR. But it should add ed25519-sha256.
Proposed fix, setting sig_signalg to 2 even when dkim_libfeature(lib, DKIM_FEATURE_ED25519) fails:
diff --git a/libopendkim/dkim.c b/libopendkim/dkim.c
--- a/libopendkim/dkim.c
+++ b/libopendkim/dkim.c
@@ -2103,7 +2103,7 @@ dkim_siglist_setup(DKIM *dkim)
}
else
{
- signalg = dkim_name_to_code(algorithms,
+ dkim->dkim_siglist[c]->sig_signalg = signalg = dkim_name_to_code(algorithms,
(char *) param);
if (signalg == -1)
@@ -2147,7 +2147,6 @@ dkim_siglist_setup(DKIM *dkim)
/* NOTREACHED */
}
- dkim->dkim_siglist[c]->sig_signalg = signalg;
dkim->dkim_siglist[c]->sig_hashtype = hashtype;
}
The attached patch allows the OpenDKIM-rel-opendkim-2-11-0-Beta2.tar.gz release to build against LibreSSL 2.8.2 (portable) on CentOS 7.
What I suspect is there is a better way, to check for OPENSSL_thread_stop()
support via autoconf - so that if future versions of LibreSSL add it, it will just be picked up. But this works for now if you are interested in it.
OpenDKIM-rel-opendkim-2-11-0-Beta2-thread_stop.patch.txt
Since this project is dead...
What are some alternative milters that support DKIM? Preferably something that works in RHEL 8/CentOS 8.
Thank you.
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
index 0c5132aa..db24b925 100644
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -12741,63 +12741,62 @@ mlfi_eoh(SMFICTX *ctx)
/* if requested, verify RFC5322-required headers (RFC5322 3.6) */
if (conf->conf_reqhdrs)
{
- _Bool ok = TRUE;
+ char *msg = NULL;
/* exactly one From: */
if (dkimf_findheader(dfc, "From", 0) == NULL ||
dkimf_findheader(dfc, "From", 1) != NULL)
- ok = FALSE;
+ msg = "Message does not have exactly one From header";
/* exactly one Date: */
if (dkimf_findheader(dfc, "Date", 0) == NULL ||
dkimf_findheader(dfc, "Date", 1) != NULL)
- ok = FALSE;
+ msg = "Message does not have exactly one Date header";
/* no more than one Reply-To: */
if (dkimf_findheader(dfc, "Reply-To", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one Reply-To headers";
/* no more than one To: */
if (dkimf_findheader(dfc, "To", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one To headers";
/* no more than one Cc: */
if (dkimf_findheader(dfc, "Cc", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one Cc headers";
/* no more than one Bcc: */
if (dkimf_findheader(dfc, "Bcc", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one Bcc headers";
/* no more than one Message-Id: */
if (dkimf_findheader(dfc, "Message-Id", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one Message-Id headers";
/* no more than one In-Reply-To: */
if (dkimf_findheader(dfc, "In-Reply-To", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one In-Reply-To headers";
/* no more than one References: */
if (dkimf_findheader(dfc, "References", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one References headers";
/* no more than one Subject: */
if (dkimf_findheader(dfc, "Subject", 1) != NULL)
- ok = FALSE;
+ msg = "Message has more than one Subject headers";
- if (!ok)
+ if (msg)
{
if (conf->conf_dolog)
{
syslog(LOG_INFO,
- "%s: RFC5322 header requirement error",
- dfc->mctx_jobid);
+ "%s: RFC5322 header requirement error %s",
+ dfc->mctx_jobid, msg);
}
-
- dfc->mctx_addheader = TRUE;
- dfc->mctx_headeronly = TRUE;
- dfc->mctx_status = DKIMF_STATUS_BADFORMAT;
- return SMFIS_CONTINUE;
+ if (dkimf_setreply(ctx, "550", "5.7.1", msg) != MI_SUCCESS &&
+ conf->conf_dolog)
+ syslog(LOG_NOTICE, "%s: smfi_setreply() failed", dfc->mctx_jobid);
+ return SMFIS_REJECT;
}
}
>pwd
/opt/src/OpenDKIM-rel-opendkim-2-11-0-Beta2
>autoconf
configure.ac:37: error: possibly undefined macro: AM_INIT_AUTOMAKE
If this token and others are legitimate, please use m4_pattern_allow.
See the Autoconf documentation.
configure.ac:65: error: possibly undefined macro: AM_PROG_CC_C_O
configure.ac:66: error: possibly undefined macro: AC_PROG_LIBTOOL
configure.ac:103: error: possibly undefined macro: AC_DEFINE
configure.ac:360: error: possibly undefined macro: AM_CONDITIONAL
configure.ac:629: error: possibly undefined macro: AC_MSG_WARN
>autoreconf
configure.ac:64: error: required file 'build-aux/compile' not found
configure.ac:64: 'automake --add-missing' can install 'compile'
configure.ac:67: error: required file 'build-aux/config.guess' not found
configure.ac:67: 'automake --add-missing' can install 'config.guess'
configure.ac:67: error: required file 'build-aux/config.sub' not found
configure.ac:67: 'automake --add-missing' can install 'config.sub'
configure.ac:44: error: required file 'build-aux/install-sh' not found
configure.ac:44: 'automake --add-missing' can install 'install-sh'
configure.ac:67: error: required file 'build-aux/ltmain.sh' not found
configure.ac:44: error: required file 'build-aux/missing' not found
configure.ac:44: 'automake --add-missing' can install 'missing'
autobuild/Makefile.am: error: required file 'build-aux/depcomp' not found
autobuild/Makefile.am: 'automake --add-missing' can install 'depcomp'
parallel-tests: error: required file 'build-aux/test-driver' not found
parallel-tests: 'automake --add-missing' can install 'test-driver'
./conf autoreconf: automake failed with exit status: 1
>./configure
configure: error: cannot find install-sh, install.sh, or shtool in build-aux "."/build-aux
>ls -l ./build-aux/
total 8
-rw-rw-r--@ 1 me staff 96 Nov 15 01:47 README
>cat ./build-aux/README
This directory is a placeholder for scripts generated during or required
by the build process.
OpenDKIM/opendkim/opendkim-genzone.c
Line 661 in ba29fa5
Hello Murray,
I've a negation in my code. Without that no dkimkeys for subdomains are found.
my code: if (!(domain_len == onlydomain_len &&
The OpenDKIM milter crashes when it does a DNS lookup during verification. I can reproduce this crash reliably (always); configuration and repro follow.
/etc/opendkim-debug.conf:
Background false
Syslog yes
UserID opendkim
UMask 007
PidFile /var/run/opendkim/opendkim.pid
Socket local:/var/spool/postfix/opendkim/opendkim.sock
Domain example.com
KeyFile /etc/dkimkeys/2018.private
Selector 2018
InternalHosts /dev/null
ResolverConfiguration /etc/unbound/unbound-debug.conf
/etc/unbound/unbound-debug.conf:
server:
auto-trust-anchor-file: "/var/lib/unbound/root.key"
GDB session:
~/tmp$ sudo gdb usr/local/sbin/opendkim
GNU gdb (Ubuntu 8.1-0ubuntu3.2) 8.1.0.20180409-git
...
Reading symbols from usr/local/sbin/opendkim...done.
(gdb) br opendkim-dns.c:554
Breakpoint 1 at 0x20168: file opendkim-dns.c, line 554.
(gdb) run -x /etc/opendkim-debug.conf
Starting program: /home/ubuntu/tmp/usr/local/sbin/opendkim -x /etc/opendkim-debug.conf
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib/x86_64-linux-gnu/libthread_db.so.1".
[New Thread 0x7ffff4d92700 (LWP 8979)]
[New Thread 0x7ffff4591700 (LWP 8980)]
[New Thread 0x7ffff3d90700 (LWP 8981)]
[New Thread 0x7ffff358f700 (LWP 8982)]
[New Thread 0x7ffff2d8e700 (LWP 8983)]
[New Thread 0x7ffff258d700 (LWP 9009)]
[Switching to Thread 0x7ffff2d8e700 (LWP 8983)]
Thread 6 "opendkim" hit Breakpoint 1, dkimf_ub_waitreply (srv=0x7fffe4000d90, qh=0x7fffe4048050, to=0x7ffff2d8a960, bytes=0x7ffff2d8a8f0, error=0x7ffff2d8a8c8,
dnssec=0x7ffff2d8a8cc) at opendkim-dns.c:554
554 status = dkimf_unbound_wait(ub, ubdata, to);
(gdb) bt
#0 dkimf_ub_waitreply (srv=0x7fffe4000d90, qh=0x7fffe4048050, to=0x7ffff2d8a960, bytes=0x7ffff2d8a8f0, error=0x7ffff2d8a8c8, dnssec=0x7ffff2d8a8cc)
at opendkim-dns.c:554
#1 0x00007ffff7bb7ea3 in dkim_get_key_dns (dkim=0x7fffe4044e70, sig=0x7fffe40457c0, buf=0x7ffff2d8cb30 "", buflen=1025) at dkim-keys.c:189
#2 0x00007ffff7bc1bf0 in dkim_get_key (dkim=0x7fffe4044e70, sig=0x7fffe40457c0, test=false) at dkim.c:2975
#3 0x00007ffff7bc6a38 in dkim_sig_process (dkim=0x7fffe4044e70, sig=0x7fffe40457c0) at dkim.c:5582
#4 0x00007ffff7bc304e in dkim_eoh_verify (dkim=0x7fffe4044e70) at dkim.c:3575
#5 0x00007ffff7bc838c in dkim_eoh (dkim=0x7fffe4044e70) at dkim.c:6631
#6 0x0000555555569027 in mlfi_eoh (ctx=0x5555557d9dd0) at opendkim.c:13219
#7 0x00007ffff79a36c2 in mi_engine () from /usr/lib/x86_64-linux-gnu/libmilter.so.1.0.1
#8 0x00007ffff79a610a in ?? () from /usr/lib/x86_64-linux-gnu/libmilter.so.1.0.1
#9 0x00007ffff69546db in start_thread (arg=0x7ffff2d8e700) at pthread_create.c:463
#10 0x00007ffff667d88f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
(gdb) c
Continuing.
[Thread 0x7ffff2d8e700 (LWP 8983) exited]
[Thread 0x7ffff358f700 (LWP 8982) exited]
[Thread 0x7ffff3d90700 (LWP 8981) exited]
[Thread 0x7ffff4591700 (LWP 8980) exited]
[Thread 0x7ffff4d92700 (LWP 8979) exited]
[Thread 0x7ffff7fe8500 (LWP 8975) exited]
[Inferior 1 (process 8975) exited with code 01]
(gdb) bt
No stack.
dkim_get_key_dns
never returns.
The crash is triggered on incoming mail containing a DKIM-Signature header. I use this command on the server to trigger the crash:
sed "s/@NOW@/$(date +'%s')/" <<'EOF' | sendmail -t [email protected]
DKIM-Signature: v=1; a=rsa-sha256; c=simple/simple; d=example.com; s=selector;
t=1573641096; bh=J7OfRAYFSdE62gucKQqRxN+C9lxwvN1kvGUkuM/t0O8=;
h=Date:From:To;
b=KneGz9SzBtGsAovEbzC4HC45/GyFABSwutje0JNre/iV0dnNt6pNVr91qOUJ0tOrA
wtdiif5agrf4j45sSSbQgCfYqMZrw/oGxi7Bz6iUuluq45Yx+ozxAuYZSt9n9Yy5zR
37DSMyH1nYUGiG7shF82VFhYo7mI0LHIBSm+6ygM=
Date: Wed, 13 Nov 2019 11:31:20 +0100
From: <[email protected]>
To: <[email protected]>
Message-Id: <@NOW@@localhost>
Subject: test
Test message.
EOF
In syslog the crash appears only as a Postfix error message:
Dec 25 16:59:33 kes postfix/cleanup[13981]: warning: milter unix:/opendkim/opendkim.sock: can't read SMFIC_EOH reply packet header: Success
When I use TrustAnchorFile /usr/share/dns/root.key
instead of the ResolverConfiguration
setting the crash does not happen. So it looks like it is related to DNS resolution with Unbound. This is on an Ubuntu 18.04 Server, /usr/share/dns/root.key is provided by the package dns-root-data, and /var/lib/unbound/root.key is managed by the unbound package.
I'm using the current tarball, version 2.11.0-beta2 to reproduce, but it is an old problem that occurs in earlier versions as well. I compiled opendkim using these options:
./configure --enable-debug --with-unbound
make
make install DESTDIR=$HOME/tmp
Need help debugging: first, can anyone confirm this reproduction? It should be reproducible on a stock opendkim install (2.11.0~alpha-11build1 from APT) on Ubuntu 18.04 Server. Just seeing the crash would be enough to rule out that it is something on my side. Replace example.com above with your domain. If you need further information, please let me know.
Could one of the board or someone responsible at the TrustedDomainProject please clearly comment on the website where users can see & find it about the real status of OpenDKIMs many open bugs, at https://sourceforge.net/p/opendkim/bugs/?
Most recent is the OpenSSL 111 non-support on FreeBSD? Looks like for other OSs too.
There's been no response from the author for a very long time.
If the project's been abandoned that's cool. Can you just finally say so devs can stop spinning their wheels and figure out a different solution?
if len(x) > 0:
is equivalent to if len(x):
and the latter is equivalent to if x:
for all internal types.
diff --git a/contrib/repute/repute.py b/contrib/repute/repute.py
--- a/contrib/repute/repute.py
+++ b/contrib/repute/repute.py
@@ -47,13 +47,13 @@ class DKIM(object):
"identity": "dkim",
}
- if res1[0] and len(res1[1]) > 0:
+ if res1[0] and res1[1]:
res1 = res1[1][0]
reputons["rating"] = res1[0]
reputons["sample-size"] = res1[2]
reputons["generated"] = res1[1]
- if res2[0] and len(res2[1]) > 0:
+ if res2[0] and res2[1]:
res2 = res2[1][0]
reputons['rate'] = res2[0]
@@ -79,7 +79,7 @@ class DKIM(object):
rows = yield self.cp.runQuery(query, {'domain': domain, 'reporter': reporter})
- if len(rows) > 0:
+ if rows:
ret = dict(itertools.izip(fields, rows[0]))
else:
ret = 0
@@ -103,7 +103,7 @@ class DKIM(object):
fields = ['domain'] + fields
rows = yield self.cp.runQuery(query, { 'reporter' : reporter } )
- if len(rows) > 0:
+ if rows:
ret = dict(itertools.izip(fields, rows[0]))
request.setHeader('Last-modified', rows[0][3].strftime("%A, %d, %B %Y %H:%M GMT"))
else:
If a header is wrapped immediately after the field name then it's (relaxed) canonicalized form will have a space between the field name and field value.
e.g.
List-Unsubscribe:
=?us-ascii?q?long_meaningless_value...
will canonicalize to
list-unsubscribe: =?us-ascii?q?long_meaningless_value...
instead of
list-unsubscribe:=?us-ascii?q?long_meaningless_value...
which causes validation to fail.
The RFC says that any whitespace after the colon should be deleted.
xxfi_close() is not necessary called, when SIGINT, SIGHUP or SIGTERM are sent to the signal handler thread established by smfi_main(), before smfi_main() returns. For this to happen the underlaying select/poll calls need to return. On some UNIX the poll/select calls exist, when libmilter closes the connection with the MTA, on Linux select/poll exit, when the timeout set by smfi_settimeout() expires.
In turn, when SIGTERM is sent to opendkim, the opened connections are not xxfi_closed() for each previously established xxfi_negotiate(), the reference counter is not decreased to zero and the assert fails.
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -5905,7 +5905,6 @@ static void
dkimf_config_free(struct dkimf_config *conf)
{
assert(conf != NULL);
- assert(conf->conf_refcnt == 0);
dkimf_zapkey(conf);
I can't seem to build the OpenDKIM library in Centos 7 version 1810.
I will post screenshots later as I currently can't upload files.
Currently nothing uses poll() within opendkim. libunbound and libmilter can use select() or poll(), but this is completely different stuff.
diff --git a/INSTALL b/INSTALL
--- a/INSTALL
+++ b/INSTALL
@@ -158,9 +158,6 @@ filter Compile the opendkim filter. Requires libmilter (see
live-testing Enables unit tests that require live access to the Internet
to succeed.
-poll Compile to use poll() instead of select() for asynchronous
- I/O.
-
popauth Enables support for POP-before-SMTP checks.
query_cache Compile the opendkim library to support local caching of
diff --git a/autobuild/autobuild.conf.sample b/autobuild/autobuild.conf.sample
--- a/autobuild/autobuild.conf.sample
+++ b/autobuild/autobuild.conf.sample
@@ -17,7 +17,6 @@
"--enable-diffheaders",
"--enable-vbr",
"--enable-atps",
- "--enable-poll",
"--with-unbound",
"--enable-replace_rules",
"--with-libmemcached",
diff --git a/configure.ac b/configure.ac
--- a/configure.ac
+++ b/configure.ac
@@ -353,8 +353,6 @@ AC_DEFUN([LIB_FFR_FEATURE],
#
FEATURE([popauth], [enable POP-before-SMTP support])
-FEATURE([poll], [use poll() instead of select()])
-
FFR_FEATURE([atps], [experimental Authorized Third Party Signers checks])
LIB_FFR_FEATURE([atps], [experimental Authorized Third Party Signers checks])
AM_CONDITIONAL([ATPS], [test x"$enable_atps" = x"yes"])
diff --git a/opendkim/util.c b/opendkim/util.c
--- a/opendkim/util.c
+++ b/opendkim/util.c
@@ -80,10 +80,6 @@ static char *optlist[] =
"DEBUG",
#endif /* DEBUG */
-#if POLL
- "POLL",
-#endif /* POLL */
-
#if POPAUTH
"POPAUTH",
#endif /* POPAUTH */
(END)
Fedora 33 (release due Fall 2020) is expected to deprecate libdb 5.3.x, and cannot move forward to libdb 6.x due to license change to AGPL. Upstream projects such as opendkim should be advised that in a future Fedora release (as early as F35 Fall 2021), libdb 5.3.x will not be available, and they should consider other methods of storage than libdb.
OpenDKIM uses libdb for it's cache.
OpenDKIM will only receive message body with length specified in DKIM signature (l=
), and reply SMFIS_SKIP to MTA. Thus, the body does not have to be ended with CRLF and should not trigger CRLF at end of body missing
if CRLF is not exist.
According to the section 3.7 of RFC6376,
the Signer/Verifier MUST hash the message body,
canonicalized using the body canonicalization algorithm specified in
the "c=" tag and then truncated to the length specified in the "l="
tag.
In addition to that, the "simple" and "relaxed" body canonicalization algorithm both suggest that if body is not empty and have no trailing CRLF, a CRLF is added. So, OpenDKIM should just append a CRLF to the body if body doesn't end with CRLF.
I suggest that this if-else block should be replaced by the if block.
In confgure.ac
we have among other things...
PKG_CHECK_MODULES([LIBLUA], [lua5.1],
[
lua_found="yes"
LIBLUA_INCDIRS="$LIBLUA_CFLAGS"
],
[AC_MSG_WARN([pkg-config for Lua not found, trying manual search...])])
The upstream pkg-config file is named lua.pc
, so lua5.1
is the wrong name unless some distros have renamed it. Either way we should check for lua
, but maybe we should also check for lua5.1
if someone knows why lua5.1
is there in the first place.
When the pkg-config check fails, the manual search looks first to /usr/lib
which can detect 32-bit libs on a 64-bit system (Gentoo bug 704556).
OpenDKIM generates a bad signature on this email message:
To: 'Jonathan Kamens' <[email protected]>
Subject: Testing one two three
From: Jonathan Kamens <[email protected]>
Testing one two three
The culprit is the single quotes in the To:
line. Take them away and the generated signature is valid.
P.S. Is anyone still maintaining this software?
The description says Boolean values default to "false". It is redundant to state that the defaults for DomainKeyCompat and ResignAll are false.
MinimumKeysBits states "The default is 1024, which accepts all signatures. A value of 0 causes the default to be used." There are 768bit signatures today, so that 0 means indeed all signatures are checked, but 1024 -the default - does not mean that all signatures are checked.
ReplaceRule states 'This can be used to accommodate expected changes such as are made to From: fields by MTA "masquerade" features.' -- needs rephrasing.
ScreenPolicyScript states "The script has access to all of the header fields and connection information and can that certain signatures be ignored based on that information." This needs rephrasing.
TemporaryDirectory speaks about libdkim but means libopendkim.
Copy of https://sourceforge.net/p/opendkim/bugs/263/.
diff --git a/opendkim/opendkim.conf.5.in b/opendkim/opendkim.conf.5.in
index 9046a1cd..127c5e69 100644
--- a/opendkim/opendkim.conf.5.in
+++ b/opendkim/opendkim.conf.5.in
@@ -233,7 +233,6 @@ is defined.
.I DomainKeysCompat (boolean)
If set, backward compatibility with DomainKeys (RFC4870) key records is
enabled. When not set, such keys are considered to be syntactically invalid.
-The default is "false".
.TP
.I DontSignMailTo (dataset)
@@ -507,7 +506,7 @@ for all addresses.
.TP
.I MilterDebug (integer)
Sets the debug level to be requested from the milter library. The
-default is 0.
+highest useful value is six.
.TP
.I Minimum (string)
@@ -533,8 +532,7 @@ valid.
.I MinimumKeyBits (integer)
Establishes a minimum key size for acceptable signatures. Signatures with
smaller key sizes, even if they otherwise pass DKIM validation, will me marked
-as invalid. The default is 1024, which accepts all signatures. A value of
-0 causes the default to be used.
+as invalid. The default is 1024. A value of 0 accepts all signatures.
.TP
.I Mode (string)
.I Mode (string)
@@ -789,7 +787,7 @@ setting. By default, all header fields are included.
Specifies a file containing a list of text replacement rules that are
applied to the message header fields to replace certain content expected to be
changed as the message passes through local MTAs. This can be used to
-accommodate expected changes such as are made to From: fields by MTA
+accommodate expected changes such as those made to From: fields by MTA
"masquerade" features. Each entry in the file consists of a POSIX regular
expression, followed by a tab (ASCII 9), followed by the text that should
be used to replace the text matching the expression. The '#' character
@@ -836,7 +834,6 @@ Where
.I ResignMailTo
triggers a re-signing action, this flag indicates whether or not all mail
should be signed (if set) versus only verified mail being signed (if not set).
-The default is "false".
@RESIGN_MANNOTICE@
.TP
@@ -871,7 +868,7 @@ Gives the name of a Lua script that should be run after all of the header
fields have been processed for a message; in particular, this is useful
after all DKIM signatures have been detected and initial evaluation has
been done. The script has access to all of the header fields and connection
-information and can that certain signatures be ignored based on that
+information and can determine that certain signatures be ignored based on that
information. See
.I opendkim-lua(3)
for details. @LUA_MANNOTICE@
@@ -1080,6 +1077,10 @@ data from a single repoter.
If set, instructs the DKIM library to refuse processing of a message if the
header field count does not conform to RFC5322 Section 3.6.
+.TP
+.I StatisticsPolicyScript (string)
+The statistics script is run after all of the DKIM verification and signing work has been completed but before any final message handling is done. The main purpose of this script is to give the user an opportunity to examine the message or its signatures and make arbitrary additional statistical observations that should be recorded by the statistics module.
+
.TP
.I StrictTestMode (Boolean)
Selects strict CRLF mode during testing (see the
@@ -1121,7 +1122,7 @@ messages.
.I TemporaryDirectory (string)
Specifies the directory in which temporary canonicalization files should
be written. The default is to use the
-.I libdkim
+.I libopendkim
default location, currently
.I /tmp.
Hi,
I'm running OpenDKIM 2.11.0-Beta2 in a Docker container based on Alpine. After migrating the setup from my physical machine into the Docker container, I got the following error:
mail._domainkey.domain1.net: key data is not secure: opendkim is in group 0 which has multiple users (e.g., "sync")
Checking the key permissions, everything seems fine for me:
/etc/opendkim # ls -l
total 36
-rw-r--r-- 1 opendkim opendkim 369 Jun 4 09:34 KeyTable
-rw-r--r-- 1 opendkim opendkim 177 Jun 4 09:34 SigningTable
-rw-r--r-- 1 opendkim opendkim 86 Jun 4 09:34 TrustedHosts
drwx------ 6 opendkim opendkim 86 Jun 4 09:34 keys
-rw-r--r-- 1 opendkim opendkim 21919 Jun 25 22:38 opendkim.conf
/etc/opendkim/keys # ls -l
total 0
drwx------ 2 opendkim opendkim 42 Jun 4 09:34 domain1.net
/etc/opendkim/keys/domain1.net # ls -la
total 8
drwx------ 2 opendkim opendkim 42 Jun 4 09:34 .
drwx------ 6 opendkim opendkim 86 Jun 4 09:34 ..
-rw------- 1 opendkim opendkim 887 Jun 4 09:34 mail.private
-rw------- 1 opendkim opendkim 309 Jun 4 09:34 mail.txt
OpenDKIM runs under the user opendkim
. Here the relevant parts of passwd and group:
/ # cat /etc/passwd
root:x:0:0:root:/root:/bin/ash
...
sync:x:5:0:sync:/sbin:/bin/sync
shutdown:x:6:0:shutdown:/sbin:/sbin/shutdown
halt:x:7:0:halt:/sbin:/sbin/halt
...
operator:x:11:0:operator:/root:/sbin/nologin
...
opendkim:x:101:102:opendkim:/run/opendkim:/sbin/nologin
/ # cat /etc/group
root:x:0:root
...
opendkim:x:102:opendkim
e6d59cba7235:~$ whoami
opendkim
e6d59cba7235:~$ groups
opendkim
Any ideas what could be wrong here? The strangest thing for me is that the safe key check says my user is in group 0, which it clearly isn't. I checked that all key files are owned by opendkim as well. Maybe the safe key check has a problem? I noticed that in Alpine Linux several users have group 0 assigned which seems to be not the case for other distros.
Any idea what I could miss?
For others having similar issues: I mitigated the problem by setting RequireSafeKeys No
in the config for now. However, this should not be used carelessly - key permissions should be correctly set.
Thanks for your support!
Cheers,
Chris
detected by the clang static analyzer
diff --git a/librbl/rbl.c b/librbl/rbl.c
--- a/librbl/rbl.c
+++ b/librbl/rbl.c
@@ -965,8 +965,13 @@ rbl_query_start(RBL *rbl, u_char *query, void **qh)
if (rbl->rbl_dns_service == NULL &&
rbl->rbl_dns_init != NULL &&
- rbl->rbl_dns_init(&rbl->rbl_dns_service) != 0)
+ rbl->rbl_dns_init(&rbl->rbl_dns_service) != 0) {
+ if (rbl->rbl_free)
+ rbl->rbl_free(rbl->rbl_closure, rq);
+ else
+ free(rq);
return RBL_STAT_DNSERROR;
+ }
status = rbl->rbl_dns_start(rbl->rbl_dns_service, T_A, rblquery,
rq->rq_buf, sizeof rq->rq_buf, &rq->rq_qh);
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -11404,6 +11404,8 @@ mlfi_header(SMFICTX *ctx, char *headerf, char *headerv)
if (conf->conf_dolog)
syslog(LOG_ERR, "dkimf_db_get() failed");
+ TRYFREE(newhdr->hdr_hdr);
+ free(newhdr);
return SMFIS_TEMPFAIL;
}
diff --git a/opendkim/util.c b/opendkim/util.c
--- a/opendkim/util.c
+++ b/opendkim/util.c
@@ -812,8 +812,10 @@ dkimf_load_replist(FILE *in, struct replace **list)
}
p = strrchr(rule, '\t');
- if (p == NULL)
+ if (p == NULL) {
+ free(newrep);
return FALSE;
+ }
*p = '\0';
@@ -821,6 +823,7 @@ dkimf_load_replist(FILE *in, struct replace **list)
if (status != 0)
{
fprintf(stderr, "%s: regcomp() failed\n", progname);
+ free(newrep);
return FALSE;
}
@@ -829,6 +832,7 @@ dkimf_load_replist(FILE *in, struct replace **list)
{
fprintf(stderr, "%s: strdup(): %s\n", progname,
strerror(errno));
+ free(newrep);
return FALSE;
}
sendmail sends bodies to libmilter in chunks of 64k.
When opendkim is supposed simulateneously to verify the signature of an email and to sign the message, the body is >64k, and the email has no signature yet, that can be verified, opendkim shall not send SMFIS_SKIP, hence ingoring the remaining chunks of the message, as opendkim needs the remaining chunks for correct signing of the message.
Copy of https://sourceforge.net/p/opendkim/patches/42/.
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -13394,13 +13394,10 @@ mlfi_body(SMFICTX *ctx, u_char *bodyp, size_t bodylen)
return dkimf_libstatus(ctx, last, "dkim_body()", status);
#ifdef SMFIS_SKIP
- if (dfc->mctx_srhead != NULL && cc->cctx_milterv2 &&
- dkimf_msr_minbody(dfc->mctx_srhead) == 0)
- return SMFIS_SKIP;
-
- if (dfc->mctx_dkimv != NULL && cc->cctx_milterv2 &&
- dkim_minbody(dfc->mctx_dkimv) == 0)
- return SMFIS_SKIP;
+ if (cc->cctx_milterv2 &&
+ (dfc->mctx_srhead == NULL || dkimf_msr_minbody(dfc->mctx_srhead) == 0) &&
+ (dfc->mctx_dkimv == NULL || dkim_minbody(dfc->mctx_dkimv) == 0))
+ return SMFIS_SKIP;
#endif /* SMFIS_SKIP */
return SMFIS_CONTINUE;
as these are trace headers:
diff --git a/opendkim/opendkim.c b/opendkim/opendkim.c
--- a/opendkim/opendkim.c
+++ b/opendkim/opendkim.c
@@ -4250,7 +4250,7 @@ dkimf_add_ar_fields(struct msgctx *dfc, struct dkimf_config *conf,
assert(conf != NULL);
assert(ctx != NULL);
- if (dkimf_insheader(ctx, 1, AUTHRESULTSHDR,
+ if (dkimf_insheader(ctx, 0, AUTHRESULTSHDR,
(char *) dfc->mctx_dkimar) == MI_FAILURE)
{
if (conf->conf_dolog)
@@ -13511,7 +13511,7 @@ mlfi_eom(SMFICTX *ctx)
dkimf_lookup_inttostr(dfc->mctx_status,
dkimf_statusstrings));
- if (dkimf_insheader(ctx, 1, AUTHRESULTSHDR,
+ if (dkimf_insheader(ctx, 0, AUTHRESULTSHDR,
(char *) header) == MI_FAILURE)
{
if (conf->conf_dolog)
@@ -14956,7 +14956,7 @@ mlfi_eom(SMFICTX *ctx)
sizeof header);
}
- if (dkimf_insheader(ctx, 1,
+ if (dkimf_insheader(ctx, 0,
AUTHRESULTSHDR,
(char *) header) == MI_FAILURE)
{
@@ -15159,7 +15159,7 @@ mlfi_eom(SMFICTX *ctx)
dkimf_stripcr((char *) start);
dkimf_dstring_cat(dfc->mctx_tmpstr, start);
- if (dkimf_insheader(ctx, 1, DKIM_SIGNHEADER,
+ if (dkimf_insheader(ctx, 0, DKIM_SIGNHEADER,
(char *) dkimf_dstring_get(dfc->mctx_tmpstr)) == MI_FAILURE)
{
if (conf->conf_dolog)
@@ -15195,7 +15195,7 @@ mlfi_eom(SMFICTX *ctx)
/* add VBR-Info header if generated */
if (dfc->mctx_vbrinfo != NULL)
{
- if (dkimf_insheader(ctx, 1, VBR_INFOHEADER,
+ if (dkimf_insheader(ctx, 0, VBR_INFOHEADER,
dfc->mctx_vbrinfo) == MI_FAILURE)
{
if (conf->conf_dolog)
The OpenDKIM site has download and issues menu entries still pointing to SOURCEFORGE. This may cause confusion.
It looks like the libopendkim.c changes in Beta0 only use a single parameter for the key file/selector. In order to produce a double rsa-sha256/ed25519-sha256 signed message (which is operationally what we'll need for quite some time), I believe that would mean passing a message through the library twice for signing. This seems inefficient.
Regardless of the library implementation, opendkim will need to know both rsa and ed25519 keys for dual signing. This will require some additional paraters for ed25519. I'd suggest something like:
.TP
.I KeyFileEd25519 (string)
Gives the location of a Ed25519 private key to be used for Ed25519 signing
all messages. File is the Base64 encoded output of RFC 8032 Ed25519 private Key
generation (as used in dkimpy). Ignored if a
.I KeyTableEd25519
is defined.
TP
.I SelectorEd25519 (string)
Defines the name of the selector to be used when signing messages using Ed25519.
See the
.B DKIM
specification for details. Used only when signing with a single key;
see the
.I SigningTable
parameter below for more information.
This parameter is ignored if a
.I KeyTableEd25519
is defined.
As per discussion at https://marc.info/?t=152682982800002&r=1&w=2.
diff --git a/opendkim/README b/opendkim/README
--- a/opendkim/README
+++ b/opendkim/README
@@ -273,8 +273,8 @@ You could put "file:" in front of the filename for the KeyTable just to be
precise, but "file:" is assumed if the value starts with a "/".
-HANDLING 8-BIT MESSAGES
-=======================
+HANDLING 8-BIT MESSAGES (Sendmail)
+==================================
SMTP was not designed for handling of other than 7-bit ASCII, and the
mechanisms to do so were added later. There is considerable flexibility in
@@ -301,6 +301,37 @@ If the MTA connected to OpenDKIM is used to relay messages, e.g. as aliases,
and the origianl sender set p=reject; DMARC policy, then the adjustment is
counterproductive.
+NOTES ON POSTFIX REWRITING OF MESSAGES
+=====================================
+Like other MIME-aware MTAs, Postfix downgrades 8bit body content to 7bit when
+a remote SMTP server does not announce 8BITMIME support. If DKIM signatures
+must survive transmission to servers that don't announce 8BITMIME, Wietse
+recommends to downgrade before signing (for example, specify "-o
+smtp_discard_ehlo_keywords=8bitmime,silent-discard" for an SMTP client that
+delivers to a null filter or to amavisd).
+
+You could specify "disable_mime_output_conversion = no" locally, but that won't
+prevent remote MTAs from doing the 8bit to 7bit downgrade and breaking DKIM
+signatures.
+
+You prevent Postfix from adding From/Date/Message-ID headers, and from rewriting
+addresses in headers, by setting the -G flag for the sendmail command, and by
+setting local_header_rewrite_clients to empty (by default these modifications
+are enabled only for submissions by local processes and from clients in local
+networks).
+
+Otherwise, Postfix should not modify a well-formed email message. For example,
+if the address in a from/to/etc. header is not modified, then the header is
+passed through unchanged regardless of the content of mailbox display names,
+comments, etc.
+
+However, there are no guarantees for out-of-spec email and for some obsolete
+forms. For example, Postfix will fold lines > 998 (not including the <CR><LF>) by
+inserting <CR><LF><SPACE> to minimize damage to MIME-formatted messages, will
+truncate (multiline) headers that contain >102400 bytes or >10240 tokens, and
+will replace the obsolete form "headername :" with the normal form "headername:"
+because many things in Postfix expect the normal form..
+
TESTING
=======
I'm using opendkim 2.10.3, seeing lots of these kinds of messages in the log:
opendkim[107]: 69C74D511E4: key retrieval failed (s=aweber_key_a, d=aweber.com): \
'aweber_key_a._domainkey.aweber.com' reply truncated
opendkim[107]: BBFC7D4F68B: key retrieval failed (s=20161025, d=gmail.com): \
'20161025._domainkey.gmail.com' reply truncated
According to https://stackoverflow.com/a/54893405/202311 it may be due to missing UDPSize
option in DNS lookup query.
On,
lsb_release -rd
Description: openSUSE Leap 15.0
Release: 15.0
uname -rm
4.18.12-lp150.3.ga880bd8-default x86_64
I've built & run,
/usr/local/opendkim/sbin/opendkim -V
opendkim: OpenDKIM Filter v2.11.0
Compiled with OpenSSL 1.1.1 11 Sep 2018
SMFI_VERSION 0x1000001
libmilter version 1.0.1
Supported signing algorithms:
rsa-sha1
rsa-sha256
ed25519-sha256
Supported canonicalization algorithms:
relaxed
simple
Active code options:
USE_MDB
USE_UNBOUND
_FFR_DIFFHEADERS
_FFR_STATS
_FFR_VBR
libopendkim 2.11.0: diffheaders debug
Once launched, it runs for a fair while, accepting/verifying submitted msgs, then intermittenly terminates with signal 6,
journalctl -f | grep -i opendkim
...
Oct 08 11:54:03 mail.loc systemd[1]: Starting OpenDKIM...
Oct 08 11:54:03 mail.loc systemd[1]: Started OpenDKIM.
Oct 08 11:54:03 mail.loc opendkim[44544]: OpenDKIM Filter: Opening listen socket on conn local:/var/run/opendkim/opendkim.sock
Oct 08 11:54:03 mail.loc opendkim[44544]: OpenDKIM Filter v2.11.0 starting (args: -l -x /usr/local/etc/opendkim/opendkim.conf -u opendkim)
...
Oct 08 13:39:16 mail.loc opendkim[44576]: 42TXK023bYz10hm: DKIM-Signature field added (s=dkim-7f99436557929e03, d=example.com)
Oct 08 13:39:16 mail.loc opendkim[44543]: terminated with signal 6, restarting
Oct 08 13:39:16 mail.loc opendkim[49996]: OpenDKIM Filter: Opening listen socket on conn local:/var/run/opendkim/opendkim.sock
Oct 08 13:39:16 mail.loc opendkim[49996]: OpenDKIM Filter v2.11.0 starting (args: -l -x /usr/local/etc/opendkim/opendkim.conf -u opendkim)
...
Core dumps
ls -al /var/lib/systemd/coredump/core*
-rw------- 1 opendkim postfix-milter 39M Oct 8 13:39 /var/lib/systemd/coredump/core.44576
and a backtrace reports,
gdb /usr/local/opendkim/sbin/opendkim /var/lib/systemd/coredump/core.44576
GNU gdb (GDB; openSUSE Leap 15.0) 8.1
Copyright (C) 2018 Free Software Foundation, Inc.
License GPLv3+: GNU GPL version 3 or later <http://gnu.org/licenses/gpl.html>
This is free software: you are free to change and redistribute it.
There is NO WARRANTY, to the extent permitted by law. Type "show copying"
and "show warranty" for details.
This GDB was configured as "x86_64-suse-linux".
Type "show configuration" for configuration details.
For bug reporting instructions, please see:
<http://bugs.opensuse.org/>.
Find the GDB manual and other documentation resources online at:
<http://www.gnu.org/software/gdb/documentation/>.
For help, type "help".
Type "apropos word" to search for commands related to "word"...
Reading symbols from /usr/local/opendkim/sbin/opendkim...done.
[New LWP 49990]
[New LWP 44576]
[New LWP 44577]
[New LWP 48292]
[New LWP 44578]
[Thread debugging using libthread_db enabled]
Using host libthread_db library "/lib64/libthread_db.so.1".
Core was generated by `/usr/local/opendkim/sbin/opendkim -l -x /usr/local/etc/opendkim/opendkim.conf -'.
Program terminated with signal SIGABRT, Aborted.
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
51 ../sysdeps/unix/sysv/linux/raise.c: No such file or directory.
[Current thread is 1 (Thread 0x7f6c460a3700 (LWP 49990))]
(gdb) print p
No symbol "p" in current context.
(gdb) bt
#0 __GI_raise (sig=sig@entry=6) at ../sysdeps/unix/sysv/linux/raise.c:51
#1 0x00007f6c492336c1 in __GI_abort () at abort.c:79
#2 0x00007f6c49275427 in __libc_message (action=action@entry=(do_abort | do_backtrace),
fmt=fmt@entry=0x7f6c4937e230 "*** Error in `%s': %s: 0x%s ***\n")
at ../sysdeps/posix/libc_fatal.c:181
#3 0x00007f6c4927bc43 in malloc_printerr (action=<optimized out>,
str=0x7f6c4937e5b8 "double free or corruption (out)", ptr=<optimized out>,
ar_ptr=<optimized out>) at malloc.c:5428
#4 0x00007f6c4927d549 in _int_free (av=0x7f6c495b0c20 <main_arena>, p=<optimized out>,
have_lock=<optimized out>) at malloc.c:4170
#5 0x00007f6c4936260b in tcache_thread_freeres () at malloc.c:2999
#6 0x00007f6c49362662 in __libc_thread_freeres () at thread-freeres.c:29
#7 0x00007f6c495bd57e in start_thread (arg=0x7f6c460a3700) at pthread_create.c:478
#8 0x00007f6c492f482f in clone () at ../sysdeps/unix/sysv/linux/x86_64/clone.S:95
Some emails show above error and when accompanied by a DMARC reject policy the email is subsequently rejected.
The email in this case was from american airlines customer relations - they use exchange servers. After changing the email to be used to gmail, and re-sending, the reply went through to gmail just fine.
I examined the email sent to google and the DKIM-signature looks fine to me and google is fine with it as well - showing dkim and dmarc both pass:
DKIM-Signature: v=1; a=rsa-sha256; c=relaxed/relaxed; d=aa.com; s=selector2;
h=From:Date:Subject:Message-ID:Content-Type:MIME-Version:X-MS-Exchange-SenderADCheck;
bh...
So seems to be a bug with OpenDKIM.
Is there any chance that a fix is in the works for opendkim?
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.