CRLF
[ghsmtp.git] / Session.hpp
blobfc812f2747f1e62c349a5530eee4b068d4bd772e
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_();
108 void xfer_response_(std::string_view success_msg);
110 // clear per transaction data, preserve per connection data
111 void reset_();
113 bool verify_ip_address_(std::string& error_msg);
114 bool verify_ip_address_dnsbl_(std::string& error_msg);
115 bool verify_client_(Domain const& client_identity, std::string& error_msg);
116 bool verify_recipient_(Mailbox const& recipient);
117 bool verify_sender_(Mailbox const& sender, std::string& error_msg);
118 bool verify_sender_domain_(Domain const& sender, std::string& error_msg);
119 bool verify_sender_domain_uribl_(std::string_view sender,
120 std::string& error_msg);
121 void do_spf_check_(Mailbox const& sender);
122 bool verify_from_params_(parameters_t const& parameters);
123 bool verify_rcpt_params_(parameters_t const& parameters);
125 // bool is_forwarding_() const
126 // {
127 // return forward_path_.empty() && !fwd_path_.empty();
128 // }
130 void exit_() __attribute__((noreturn));
132 private:
133 fs::path config_path_;
134 DNS::Resolver res_;
135 Sock sock_;
137 // forwarding and replies
138 // Send send_;
139 // Reply rep_;
140 // Mailbox fwd_path_;
141 // Mailbox fwd_from_;
142 // Reply::from_to rep_info_;
144 // per connection/session
145 Domain server_identity_; // who we identify as
146 std::vector<Domain> client_fcrdns_; // who they look-up as
147 std::vector<Domain> server_fcrdns_; // who we look-up as
148 std::string client_; // (fcrdns_ [sock_.them_c_str()])
150 // per transaction
151 Domain client_identity_; // from ehlo/helo
152 Mailbox reverse_path_; // "mail from"
153 std::vector<Mailbox> forward_path_; // for each "rcpt to"
154 std::string spf_received_;
155 std::unique_ptr<MessageStore> msg_;
157 TLD tld_db_;
159 std::random_device random_device_;
161 // Domains we receive mail for.
162 CDB accept_domains_;
164 // Allow and block lists for domains.
165 CDB allow_;
166 CDB block_;
168 // Forwards
169 CDB forward_;
171 size_t max_msg_size_;
173 int n_unrecognized_cmds_{0};
175 SPF::Result spf_result_;
176 Domain spf_sender_domain_;
178 // RFC 5321 section 3.3. Mail Transactions
179 enum class xact_step : int8_t {
180 helo,
181 mail,
182 rcpt,
183 data,
184 bdat, // RFC 3030
185 rset, // must now send RSET
188 // per transaction
189 xact_step state_ = xact_step::helo;
191 bool binarymime_{false};
192 bool extensions_{false};
193 bool smtputf8_{false};
194 bool prdr_{false};
196 // per connection
197 bool fcrdns_allowed_{false};
198 bool ip_allowed_{false};
201 #endif // SESSION_DOT_HPP