- 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>
137 lines
4.5 KiB
C++
137 lines
4.5 KiB
C++
#include "BARANTMailConfig.h"
|
|
#include "Exception.h"
|
|
#include "JFile.h"
|
|
|
|
namespace mail {
|
|
|
|
BARANTMailConfig::BARANTMailConfig(const std::string &path) {
|
|
file = new coreutils::JFile(coreutils::ZString(path.c_str(), path.length()));
|
|
|
|
if (!file->exists("hostName"))
|
|
throw coreutils::Exception("BARANTMailConfig: \"hostName\" is missing from " + path);
|
|
if (!file->exists("mailPath"))
|
|
throw coreutils::Exception("BARANTMailConfig: \"mailPath\" is missing from " + path);
|
|
if (!file->exists("smtp.port"))
|
|
throw coreutils::Exception("BARANTMailConfig: \"smtp.port\" is missing from " + path);
|
|
|
|
if ((file->exists("admin.user") || file->exists("admin.password") || file->exists("admin.port")) &&
|
|
(!file->exists("admin.user") || !file->exists("admin.password")))
|
|
throw coreutils::Exception(
|
|
"BARANTMailConfig: \"admin\" is configured but \"admin.user\"/\"admin.password\" "
|
|
"is missing from " + path);
|
|
|
|
bool needsTls = file->exists("smtpTLS.port") || file->exists("imap.port") || file->exists("pop3.port");
|
|
if (needsTls) {
|
|
if (!file->exists("tls.certificate") || !file->exists("tls.key"))
|
|
throw coreutils::Exception(
|
|
"BARANTMailConfig: smtpTLS/imap/pop3 is configured but \"tls.certificate\"/\"tls.key\" "
|
|
"is missing from " + path);
|
|
certPath = file->getString("tls.certificate");
|
|
keyPath = file->getString("tls.key");
|
|
tlsInfo.certificate = certPath.c_str();
|
|
tlsInfo.key = keyPath.c_str();
|
|
if (file->exists("tls.caCertificate")) {
|
|
caPath = file->getString("tls.caCertificate");
|
|
tlsInfo.cACertificate = caPath.c_str();
|
|
}
|
|
hasTls = true;
|
|
}
|
|
}
|
|
|
|
BARANTMailConfig::~BARANTMailConfig() {
|
|
delete file;
|
|
}
|
|
|
|
std::string BARANTMailConfig::getHostName() {
|
|
return file->getString("hostName");
|
|
}
|
|
|
|
std::string BARANTMailConfig::getMailPath() {
|
|
return file->getString("mailPath");
|
|
}
|
|
|
|
int BARANTMailConfig::getSmtpPort() {
|
|
return (int)file->getInt("smtp.port");
|
|
}
|
|
|
|
bool BARANTMailConfig::hasSmtpTLS() {
|
|
return file->exists("smtpTLS.port");
|
|
}
|
|
|
|
int BARANTMailConfig::getSmtpTLSPort() {
|
|
return (int)file->getInt("smtpTLS.port");
|
|
}
|
|
|
|
bool BARANTMailConfig::hasImap() {
|
|
return file->exists("imap.port");
|
|
}
|
|
|
|
int BARANTMailConfig::getImapPort() {
|
|
return (int)file->getInt("imap.port");
|
|
}
|
|
|
|
bool BARANTMailConfig::hasPop3() {
|
|
return file->exists("pop3.port");
|
|
}
|
|
|
|
int BARANTMailConfig::getPop3Port() {
|
|
return (int)file->getInt("pop3.port");
|
|
}
|
|
|
|
core::TLSInfo *BARANTMailConfig::getTlsInfo() {
|
|
return hasTls ? &tlsInfo : NULL;
|
|
}
|
|
|
|
std::vector<BARANTMailConfig::DkimEntry> BARANTMailConfig::getDkimEntries() {
|
|
std::vector<DkimEntry> entries;
|
|
// No length-prefixed array accessor on JFile/JString - probe
|
|
// ascending indices via exists() (the same technique the JSON
|
|
// path syntax's own "a[2]" bracket form is meant for) until one
|
|
// is missing, matching a plain JSON array's natural "no trailing
|
|
// comma/count field" shape.
|
|
for (int i = 0; ; i++) {
|
|
std::string indexPrefix = "dkim[" + std::to_string(i) + "]";
|
|
std::string domainPath = indexPrefix + ".domain";
|
|
if (!file->exists(domainPath))
|
|
break;
|
|
std::string selectorPath = indexPrefix + ".selector";
|
|
std::string keyPath = indexPrefix + ".privateKey";
|
|
DkimEntry entry;
|
|
entry.domain = file->getString(domainPath);
|
|
entry.selector = file->getString(selectorPath);
|
|
entry.privateKeyPath = file->getString(keyPath);
|
|
entries.push_back(entry);
|
|
}
|
|
return entries;
|
|
}
|
|
|
|
bool BARANTMailConfig::hasLog() {
|
|
return file->exists("log");
|
|
}
|
|
|
|
size_t BARANTMailConfig::getLogMaxSizeBytes() {
|
|
return file->exists("log.maxSizeBytes") ? (size_t)file->getInt("log.maxSizeBytes") : 104857600;
|
|
}
|
|
|
|
int BARANTMailConfig::getLogMaxBackups() {
|
|
return file->exists("log.maxBackups") ? (int)file->getInt("log.maxBackups") : 5;
|
|
}
|
|
|
|
bool BARANTMailConfig::hasAdmin() {
|
|
return file->exists("admin.user");
|
|
}
|
|
|
|
int BARANTMailConfig::getAdminPort() {
|
|
return file->exists("admin.port") ? (int)file->getInt("admin.port") : 1027;
|
|
}
|
|
|
|
std::string BARANTMailConfig::getAdminUser() {
|
|
return file->getString("admin.user");
|
|
}
|
|
|
|
std::string BARANTMailConfig::getAdminPassword() {
|
|
return file->getString("admin.password");
|
|
}
|
|
|
|
}
|