someone said
[ghsmtp.git] / Session.hpp
blob11c8f2f2c092f8b271a6744dee7466f4b8fa5dbd
1 #ifndef SESSION_DOT_HPP
2 #define SESSION_DOT_HPP
4 #include <random>
5 #include <string>
6 #include <string_view>
7 #include <unordered_map>
8 #include <vector>
10 #include "CDB.hpp"
11 #include "DNS-fcrdns.hpp"
12 #include "Domain.hpp"
13 #include "Mailbox.hpp"
14 #include "MessageStore.hpp"
15 #include "SPF.hpp"
16 #include "Sock.hpp"
17 #include "TLD.hpp"
18 #include "message.hpp"
20 namespace Config {
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;
25 } // namespace Config
27 class Session {
28 public:
29 using parameters_t = std::unordered_map<std::string, std::string>;
31 Session(Session const&) = delete;
32 Session& operator=(Session const&) = delete;
34 explicit Session(
35 fs::path config_path,
36 std::function<void(void)> read_hook = []() {},
37 int fd_in = STDIN_FILENO,
38 int fd_out = STDOUT_FILENO);
40 void greeting();
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);
46 bool msg_new();
47 bool msg_write(char const* s, std::streamsize count);
49 bool data_start();
50 void data_done();
51 void data_size_error();
52 void data_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();
58 void bdat_io_error();
60 void rset();
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));
72 void starttls();
74 bool maxed_out() { return sock_.maxed_out(); }
75 bool timed_out() { return sock_.timed_out(); }
76 std::istream& in() { return sock_.in(); }
78 void flush();
79 void last_in_group_(std::string_view verb);
80 void check_for_pipeline_error_(std::string_view verb);
82 size_t max_msg_size() const { return max_msg_size_; }
83 void max_msg_size(size_t max);
85 void log_stats() { sock_.log_stats(); }
87 enum class SpamStatus : bool { ham, spam };
89 private:
90 friend struct Session_test;
92 std::tuple<SpamStatus, std::string> spam_status_();
94 std::string added_headers_(MessageStore const& msg);
96 std::ostream& out_() { return sock_.out(); }
97 void lo_(char const* verb, std::string_view client_identity);
99 void bad_host_(char const* msg) const __attribute__((noreturn));
101 std::string const& server_id_() const { return server_identity_.ascii(); }
103 // bool forward_to_(std::string const& forward, Mailbox const& rcpt_to);
104 // bool reply_to_(Reply::from_to const& reply_info, Mailbox const& rcpt_to);
105 // bool do_forward_(message::parsed& msg);
106 // bool do_reply_(message::parsed& msg);
107 bool do_deliver_();
109 // clear per transaction data, preserve per connection data
110 void reset_();
112 bool verify_ip_address_(std::string& error_msg);
113 bool verify_ip_address_dnsbl_(std::string& error_msg);
114 bool verify_client_(Domain const& client_identity, std::string& error_msg);
115 bool verify_recipient_(Mailbox const& recipient);
116 bool verify_sender_(Mailbox const& sender, std::string& error_msg);
117 bool verify_sender_domain_(Domain const& sender, std::string& error_msg);
118 bool verify_sender_domain_uribl_(std::string_view sender,
119 std::string& error_msg);
120 void do_spf_check_(Mailbox const& sender);
121 bool verify_from_params_(parameters_t const& parameters);
122 bool verify_rcpt_params_(parameters_t const& parameters);
124 // bool is_forwarding_() const
125 // {
126 // return forward_path_.empty() && !fwd_path_.empty();
127 // }
129 void exit_() __attribute__((noreturn));
131 private:
132 fs::path config_path_;
133 DNS::Resolver res_;
134 Sock sock_;
136 // forwarding and replies
137 // Send send_;
138 // Reply rep_;
139 // Mailbox fwd_path_;
140 // Mailbox fwd_from_;
141 // Reply::from_to rep_info_;
143 // per connection/session
144 Domain server_identity_; // who we identify as
145 std::vector<Domain> client_fcrdns_; // who they look-up as
146 std::vector<Domain> server_fcrdns_; // who we look-up as
147 std::string client_; // (fcrdns_ [sock_.them_c_str()])
149 // per transaction
150 Domain client_identity_; // from ehlo/helo
151 Mailbox reverse_path_; // "mail from"
152 std::vector<Mailbox> forward_path_; // for each "rcpt to"
153 std::string spf_received_;
154 std::unique_ptr<MessageStore> msg_;
156 TLD tld_db_;
158 std::random_device random_device_;
160 // Allow and block lists for domains.
161 CDB allow_;
162 CDB block_;
164 // Forwards
165 CDB forward_;
167 // Domains we receive mail for.
168 CDB accept_domains_;
170 size_t max_msg_size_;
172 int n_unrecognized_cmds_{0};
174 SPF::Result spf_result_;
175 Domain spf_sender_domain_;
177 // RFC 5321 section 3.3. Mail Transactions
178 enum class xact_step : int8_t {
179 helo,
180 mail,
181 rcpt,
182 data,
183 bdat, // RFC 3030
184 rset, // must now send RSET
187 // per transaction
188 xact_step state_ = xact_step::helo;
190 bool binarymime_{false};
191 bool extensions_{false};
192 bool smtputf8_{false};
193 // bool prdr_{false};
195 // per connection
196 bool fcrdns_allowed_{false};
197 bool ip_allowed_{false};
200 #endif // SESSION_DOT_HPP