#ifndef __SMTPSession_h__ # define __SMTPSession_h__ # include "TCPSession.h" # include "TCPServer.h" # include "MString.h" # include "SPFChecker.h" # define CRLF "\r\n" namespace mail { enum State {CONNECT, READY, READYX, MAIL, RCPT, DATA, SENT}; enum AuthState {USER_UNKNOWN, USER_QUERY, USER_SECRET_QUERY, USER_KNOWN}; enum Mode {WAIT_FOR_DATA, RECEIVE_DATA}; class SMTPSession : public core::TCPSession { public: SMTPSession(core::EPoll &ePoll, core::TCPServer &server); void onConnected() override; coreutils::MString clientDomainName; coreutils::MString userName; coreutils::MString password; coreutils::MString mailData; State state = CONNECT; AuthState authState = USER_UNKNOWN; Mode mode = WAIT_FOR_DATA; // Defaults to false: relaying to a non-local recipient is only // permitted after a real, successful AUTH (see __SMTP_AUTH.cpp, // which sets this true on success) - defaulting to true made every // brand-new, unauthenticated connection an open relay for anyone // (__SMTP_RCPT.cpp checks exactly this flag before accepting a // recipient whose mailbox does not exist locally). bool relay = false; coreutils::MString from; std::vector recipientList; // Computed once at MAIL FROM time (see __SMTP_MAIL.cpp) and // reused at DATA time (__SMTP_DATA.cpp), rather than re-running // the SPF DNS lookups a second time for the same transaction. The // header is ready to prepend to the message as-is; domain/result // are also kept separately since DMARC's own alignment check // (also run at DATA time) needs the raw identity/result, not the // pre-formatted header text. std::string spfHeader; std::string spfDomain; SPFChecker::Result spfResult = SPFChecker::Result::None; }; } #endif