Add authenticated domain/mailbox/alias/password admin console
Port 1027 used to be an unauthenticated console (see ServerCore's ConsoleServer/ConsoleSession fix) that also exposed the raw SMTP command set (AUTH/DATA/EHLO/EXPN/HELO/...) to anyone who could reach it. It's now started only when barantmail.cfg has a real "admin" section configured (BARANTMailConfig::hasAdmin/getAdminPort/ getAdminUser/getAdminPassword), matching the same optional-listener pattern already used for smtpTLS/imap/pop3, and registers four real commands instead of the SMTP command table: domain add|remove|list mailbox add|remove|list alias add|remove|list password reset MailFileSystem gained the actual domain/mailbox/alias/password CRUD these commands call (createDomain/removeDomain/listDomains, createMailbox/removeMailbox/listMailboxes, createAlias/removeAlias/ listAliases, setPassword), matching its existing on-disk layout: a domain is a directory, a mailbox is a directory with Inbox/Spam/Trash and a .password file, an alias is a plain file listing target mailboxes one per line. getAliasMailboxes() was previously an unconditional stub that always returned empty (confirmed via grep to have zero callers anywhere), so an alias could be "created" but could never actually receive mail. It's now wired for real: SMTPServer::inCreate() checks ifAliasExists()/getAliasMailboxes() during local delivery and copies the same spam-scanned message to every target mailbox (extracted into a new deliverToMailbox() helper so the alias and single-mailbox delivery paths share it).
This commit is contained in:
1 parent
cd5e0a9905
commit
e8b2a79907
17 files changed
+667
-12
No files matched your search
@@ -12,12 +12,27 @@
|
||||
#include "SendMail.h"
|
||||
#include "BARANTMailConfig.h"
|
||||
#include "DKIMSigner.h"
|
||||
#include "__ADMIN_DOMAIN.h"
|
||||
#include "__ADMIN_MAILBOX.h"
|
||||
#include "__ADMIN_ALIAS.h"
|
||||
#include "__ADMIN_PASSWORD.h"
|
||||
#include <fcntl.h>
|
||||
#include <iomanip>
|
||||
#include <iostream>
|
||||
#include <signal.h>
|
||||
#include <sstream>
|
||||
|
||||
int main(int argc, char **argv) {
|
||||
// Every socket write in this process (outbound relay in
|
||||
// SendMail::deliverToHost(), and every client-facing SMTP/IMAP/
|
||||
// POP3 session) can hit a peer that already reset the connection.
|
||||
// The default SIGPIPE disposition kills the WHOLE process on the
|
||||
// very next write to it - not just that one connection - which is
|
||||
// exactly what repeated crash logs traced back to (a relay thread
|
||||
// writing DATA to an MX host that reset mid-write, taking down
|
||||
// every other in-flight connection with it). write()/send() still
|
||||
// report the failure normally via EPIPE once this is ignored.
|
||||
signal(SIGPIPE, SIG_IGN);
|
||||
// /var/log is root:syslog-owned and not writable by an unprivileged
|
||||
// user - this constructor throws immediately (before anything else
|
||||
// in main() runs) rather than silently falling back, when run as
|
||||
@@ -135,9 +150,44 @@ int main(int argc, char **argv) {
|
||||
core::IPAddress(ipAddress, config.getImapPort()),
|
||||
config.getTlsInfo());
|
||||
|
||||
core::ConsoleServer consoleServer(ePoll, core::IPAddress(ipAddress, 1027), nullptr);
|
||||
consoleServer.commands.add(consoleServer.commands, "help");
|
||||
consoleServer.commands.add(smtpServer.commands, "smtp");
|
||||
// Real, authenticated domain/mailbox/alias/password administration -
|
||||
// replaces what used to be an unauthenticated console that also
|
||||
// exposed the raw SMTP command set (AUTH/DATA/EHLO/EXPN/HELO/...)
|
||||
// to anyone who could reach the port; confirmed reachable
|
||||
// externally (bound 0.0.0.0) with a login flow that never actually
|
||||
// checked anything. Only started when barantmail.cfg has a real
|
||||
// "admin" section configured - matching the same optional-listener
|
||||
// pattern as smtpTLS/imap/pop3 above, rather than ever handing out
|
||||
// an admin port with nothing to authenticate against.
|
||||
core::ConsoleServer *consoleServer = nullptr;
|
||||
mail::__ADMIN_DOMAIN *adminDomain = nullptr;
|
||||
mail::__ADMIN_MAILBOX *adminMailbox = nullptr;
|
||||
mail::__ADMIN_ALIAS *adminAlias = nullptr;
|
||||
mail::__ADMIN_PASSWORD *adminPassword = nullptr;
|
||||
if (config.hasAdmin()) {
|
||||
std::string adminUser = config.getAdminUser();
|
||||
std::string adminPasswordValue = config.getAdminPassword();
|
||||
consoleServer = new core::ConsoleServer(ePoll, core::IPAddress(ipAddress, config.getAdminPort()), nullptr,
|
||||
[adminUser, adminPasswordValue](std::string user, std::string password) {
|
||||
return user == adminUser && password == adminPasswordValue;
|
||||
});
|
||||
adminDomain = new mail::__ADMIN_DOMAIN(mailFileSystem);
|
||||
adminMailbox = new mail::__ADMIN_MAILBOX(mailFileSystem);
|
||||
adminAlias = new mail::__ADMIN_ALIAS(mailFileSystem);
|
||||
adminPassword = new mail::__ADMIN_PASSWORD(mailFileSystem);
|
||||
// Command lookup upper-cases the typed keyword before matching
|
||||
// against these registered names (see CommandList::processRequest) -
|
||||
// every name here has to already be upper case or it can never
|
||||
// be found at all, which is exactly why "help" silently did
|
||||
// nothing even after CommandList::processCommand() itself was
|
||||
// fixed to list commands: it was registered as lower-case "help"
|
||||
// here and could never be looked up by the upper-cased key.
|
||||
consoleServer->commands.add(consoleServer->commands, "HELP");
|
||||
consoleServer->commands.add(*adminDomain, "DOMAIN");
|
||||
consoleServer->commands.add(*adminMailbox, "MAILBOX");
|
||||
consoleServer->commands.add(*adminAlias, "ALIAS");
|
||||
consoleServer->commands.add(*adminPassword, "PASSWORD");
|
||||
}
|
||||
|
||||
while(true)
|
||||
sleep(3600);
|
||||
|
||||
Reference in new issue
Block a user