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
+42
-14
@@ -95,20 +95,48 @@ namespace mail {
|
||||
while (std::getline(in, line)) {
|
||||
if (line.empty())
|
||||
continue;
|
||||
std::istringstream stream(line);
|
||||
Message message;
|
||||
std::string uidStr, dateStr, flagsBlob;
|
||||
stream >> message.fileName >> uidStr >> dateStr;
|
||||
std::getline(stream, flagsBlob);
|
||||
// The flags blob (if any) is whatever's left after the third
|
||||
// field, minus the single separating space istream>> already
|
||||
// consumed up to.
|
||||
if (!flagsBlob.empty() && flagsBlob[0] == ' ')
|
||||
flagsBlob.erase(0, 1);
|
||||
message.uid = (uint32_t)std::stoul(uidStr);
|
||||
message.internalDate = (time_t)std::stoll(dateStr);
|
||||
message.flags = splitFlags(flagsBlob);
|
||||
mMessages.push_back(message);
|
||||
try {
|
||||
std::istringstream stream(line);
|
||||
Message message;
|
||||
std::string uidStr, dateStr, flagsBlob;
|
||||
stream >> message.fileName >> uidStr >> dateStr;
|
||||
std::getline(stream, flagsBlob);
|
||||
// The flags blob (if any) is whatever's left after the third
|
||||
// field, minus the single separating space istream>> already
|
||||
// consumed up to.
|
||||
if (!flagsBlob.empty() && flagsBlob[0] == ' ')
|
||||
flagsBlob.erase(0, 1);
|
||||
// A short/truncated line (a write cut off mid-flush by a
|
||||
// crash or restart racing save() - which already logs that
|
||||
// this exact failure mode is possible, see save() below)
|
||||
// leaves uidStr/dateStr empty, and stoul/stoll throw
|
||||
// std::invalid_argument on that - uncaught, that previously
|
||||
// propagated all the way up through load() and every IMAP
|
||||
// handler that calls it (SELECT, EXAMINE) into
|
||||
// CommandList::processRequest()'s own generic catch-all,
|
||||
// which silently swallowed it and sent NO response at all -
|
||||
// indistinguishable from the server hanging, since the
|
||||
// client just waits forever for a reply that was never
|
||||
// coming. Confirmed live: a single truncated trailing line
|
||||
// ("Seen", missing its filename/uid/date - the tail end of
|
||||
// what should have been a real message line) in a real
|
||||
// user's Inbox .imapindex made every single SELECT/EXAMINE
|
||||
// of that folder hang the connection, indefinitely,
|
||||
// deterministically, until this line was found and
|
||||
// skipped. Catching here instead means one corrupt line is
|
||||
// dropped (logged) rather than taking the whole folder
|
||||
// load - and therefore the whole command - down; the
|
||||
// in-memory message list this produces is what save() (also
|
||||
// called at the end of load(), unconditionally) rewrites
|
||||
// the index file from, so the corrupt line is
|
||||
// self-healed away on the very next successful load().
|
||||
message.uid = (uint32_t)std::stoul(uidStr);
|
||||
message.internalDate = (time_t)std::stoll(dateStr);
|
||||
message.flags = splitFlags(flagsBlob);
|
||||
mMessages.push_back(message);
|
||||
} catch (...) {
|
||||
coreutils::Log(coreutils::LOG_EXCEPT) << "MailFolder: skipping malformed .imapindex line in " << path << ": [" << line << "]";
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in new issue
Block a user