1 #ifndef SESSION_DOT_HPP
2 #define SESSION_DOT_HPP
7 #include <unordered_map>
11 #include "DNS-fcrdns.hpp"
13 #include "Mailbox.hpp"
14 #include "Message.hpp"
21 constexpr size_t kibibyte
= 1024;
22 constexpr size_t mebibyte
= kibibyte
* kibibyte
;
23 constexpr size_t max_msg_size_initial
= 15 * mebibyte
;
24 constexpr size_t max_msg_size_bro
= 150 * mebibyte
;
29 using parameters_t
= std::unordered_map
<std::string
, std::string
>;
31 Session(Session
const&) = delete;
32 Session
& operator=(Session
const&) = delete;
36 std::function
<void(void)> read_hook
= []() {},
37 int fd_in
= STDIN_FILENO
,
38 int fd_out
= STDOUT_FILENO
);
41 void ehlo(std::string_view client_identity
) { lo_("EHLO", client_identity
); }
42 void helo(std::string_view client_identity
) { lo_("HELO", client_identity
); }
43 void mail_from(Mailbox
&& reverse_path
, parameters_t
const& parameters
);
44 void rcpt_to(Mailbox
&& forward_path
, parameters_t
const& parameters
);
47 bool msg_write(char const* s
, std::streamsize count
);
51 void data_size_error();
54 bool bdat_start(size_t n
);
55 void bdat_done(size_t n
, bool last
);
56 void bdat_size_error();
57 void bdat_seq_error();
61 void noop(std::string_view str
);
62 void vrfy(std::string_view str
);
63 void help(std::string_view str
);
64 void quit() __attribute__((noreturn
));
65 void auth() __attribute__((noreturn
));
66 void error(std::string_view log_msg
);
67 void cmd_unrecognized(std::string_view log_msg
);
68 void bare_lf() __attribute__((noreturn
));
70 void max_out() __attribute__((noreturn
));
71 void time_out() __attribute__((noreturn
));
74 bool maxed_out() { return sock_
.maxed_out(); }
75 bool timed_out() { return sock_
.timed_out(); }
76 std::istream
& in() { return sock_
.in(); }
79 void last_in_group_(std::string_view verb
);
81 size_t max_msg_size() const { return max_msg_size_
; }
82 void max_msg_size(size_t max
);
84 void log_stats() { sock_
.log_stats(); }
86 enum class SpamStatus
: bool { ham
, spam
};
89 friend struct Session_test
;
91 std::tuple
<SpamStatus
, std::string
> spam_status_();
93 std::string
added_headers_(Message
const& msg
);
95 std::ostream
& out_() { return sock_
.out(); }
96 void lo_(char const* verb
, std::string_view client_identity
);
98 void bad_host_(char const* msg
) const __attribute__((noreturn
));
100 std::string
const& server_id_() const { return server_identity_
.ascii(); }
104 // clear per transaction data, preserve per connection data
107 bool verify_ip_address_(std::string
& error_msg
);
108 bool verify_ip_address_dnsbl_(std::string
& error_msg
);
109 bool verify_client_(Domain
const& client_identity
, std::string
& error_msg
);
110 bool verify_recipient_(Mailbox
const& recipient
);
111 bool verify_sender_(Mailbox
const& sender
, std::string
& error_msg
);
112 bool verify_sender_domain_(Domain
const& sender
, std::string
& error_msg
);
113 bool verify_sender_domain_uribl_(std::string_view sender
,
114 std::string
& error_msg
);
115 bool verify_sender_spf_(Mailbox
const& sender
);
116 bool verify_from_params_(parameters_t
const& parameters
);
117 bool verify_rcpt_params_(parameters_t
const& parameters
);
119 bool is_forwarding_() const
121 return forward_path_
.empty() && !fwd_path_
.empty();
124 void exit_() __attribute__((noreturn
));
127 fs::path config_path_
;
133 std::vector
<Mailbox
> fwd_path_
; // for each "rcpt to"
135 // per connection/session
136 Domain server_identity_
; // who we identify as
137 std::vector
<Domain
> client_fcrdns_
; // who they look-up as
138 std::vector
<Domain
> server_fcrdns_
; // who we look-up as
139 std::string client_
; // (fcrdns_ [sock_.them_c_str()])
142 Domain client_identity_
; // from ehlo/helo
143 Mailbox reverse_path_
; // "mail from"
144 std::vector
<Mailbox
> forward_path_
; // for each "rcpt to"
145 std::string spf_received_
;
146 std::unique_ptr
<Message
> msg_
;
150 std::random_device random_device_
;
152 // White and black lists for domains.
157 // Domains we receive mail for.
160 size_t max_msg_size_
;
162 int n_unrecognized_cmds_
{0};
164 SPF::Result spf_result_
;
165 Domain spf_sender_domain_
;
167 // RFC 5321 section 3.3. Mail Transactions
168 enum class xact_step
: int8_t {
174 rset
, // must now send RSET
178 xact_step state_
= xact_step::helo
;
180 bool binarymime_
{false};
181 bool extensions_
{false};
182 bool smtputf8_
{false};
186 bool fcrdns_whitelisted_
{false};
187 bool ip_whitelisted_
{false};
190 #endif // SESSION_DOT_HPP