Add per-domain DKIM signing, admin console TLS, log rotation, and resolver timeout scoping
- DKIM signing was hardcoded to one domain; now keyed per-domain off the sending address, fixing mail for every domain but the original. - Admin console (port 1027) is now TLS-wrapped instead of plaintext. - barantmail.log now rotates by size (config-driven) instead of growing unbounded (previously hit 23GB). - ResolverThreadScope.h: a <setenv> scoping fix for name resolution inside a <try> block that previously did not survive its own container. - IMAPArgs.cpp: fixed "UID STORE 1:*" wrongly requiring UID 1 to exist, which silently made empty-folder operations delete nothing. Co-Authored-By: Claude Sonnet 5 <noreply@anthropic.com>
This commit is contained in:
1 parent
5f3e6ed2e6
commit
407cc2e915
11 files changed
+284
-81
No files matched your search
+21
-8
@@ -1,6 +1,7 @@
|
||||
#include "SendMail.h"
|
||||
#include "Log.h"
|
||||
#include <algorithm>
|
||||
#include <map>
|
||||
#include <arpa/inet.h>
|
||||
#include <arpa/nameser.h>
|
||||
#include <cstdlib>
|
||||
@@ -16,9 +17,9 @@ namespace mail {
|
||||
|
||||
SendMail::SendMail(std::string hostName, std::string sendLogPath, std::string messageId,
|
||||
coreutils::MString from, coreutils::MString recipient, coreutils::MString mailData,
|
||||
DKIMSigner *dkimSigner)
|
||||
std::map<std::string, DKIMSigner*> *dkimSigners)
|
||||
: hostName(hostName), sendLogPath(sendLogPath), messageId(messageId),
|
||||
from(from), recipient(recipient), mailData(mailData), dkimSigner(dkimSigner) {}
|
||||
from(from), recipient(recipient), mailData(mailData), dkimSigners(dkimSigners) {}
|
||||
|
||||
std::string SendMail::domainOf(coreutils::MString &address) {
|
||||
std::string addr = address.str();
|
||||
@@ -216,17 +217,29 @@ namespace mail {
|
||||
coreutils::File log(logFileName, O_CREAT | O_WRONLY | O_APPEND, 0660);
|
||||
log.write("=== delivery attempt: message " + messageId + " -> " + recipient.str() + " ===\n");
|
||||
|
||||
if (dkimSigner) {
|
||||
if (dkimSigners) {
|
||||
// Signed once here, not inside deliverToHost() - deliverToHost()
|
||||
// can run again against a second MX host if the first fails, and
|
||||
// the signature (over this exact message content) is the same
|
||||
// either way, so signing once upfront avoids redundant RSA ops
|
||||
// and keeps every delivery attempt for this message consistent.
|
||||
std::string signature = dkimSigner->sign(mailData.str());
|
||||
coreutils::MString signedData;
|
||||
signedData << signature.c_str() << mailData;
|
||||
mailData = signedData;
|
||||
log.write("DKIM-signed.\n");
|
||||
// Which signer (if any) is used depends on the sender's own
|
||||
// domain, not a single server-wide identity - a real multi-
|
||||
// domain deployment must never sign one domain's mail with a
|
||||
// different domain's key (DMARC alignment would fail it
|
||||
// anyway, and it would leak which private key production
|
||||
// uses for an unrelated domain).
|
||||
std::string fromDomain = domainOf(from);
|
||||
auto it = dkimSigners->find(fromDomain);
|
||||
if (it != dkimSigners->end()) {
|
||||
std::string signature = it->second->sign(mailData.str());
|
||||
coreutils::MString signedData;
|
||||
signedData << signature.c_str() << mailData;
|
||||
mailData = signedData;
|
||||
log.write("DKIM-signed (domain: " + fromDomain + ").\n");
|
||||
} else {
|
||||
log.write("No DKIM key configured for domain: " + fromDomain + " - sending unsigned.\n");
|
||||
}
|
||||
}
|
||||
|
||||
std::string domain = domainOf(recipient);
|
||||
|
||||
Reference in new issue
Block a user