diff --git a/include/mail.hpp b/include/mail.hpp index 2503184..cc063d6 100644 --- a/include/mail.hpp +++ b/include/mail.hpp @@ -16,6 +16,7 @@ namespace mail { struct session_t { bool has_header = 0; + protocol::token::string_t token; message_t message; }; diff --git a/include/protocol/protocol.hpp b/include/protocol/protocol.hpp index 0736cb2..bf5f6f6 100644 --- a/include/protocol/protocol.hpp +++ b/include/protocol/protocol.hpp @@ -18,16 +18,14 @@ namespace protocol { using handler_t = std::function; using handler_map_t = std::map; - struct session_key_t { - std::string session; - std::string token; - }; - - bool operator==(const session_key_t& l, const session_key_t& r); + using session_key_t = token::string_t; session_key_t session_key_from(const token::list_t& tokens); session_key_t session_key_from(const message_t& message); + token::string_t session_token_from(const token::list_t& tokens); + token::string_t session_token_from(const message_t& message); + class protocol_t { public: void set_handlers(const handler_map_t handlers); @@ -36,11 +34,11 @@ namespace protocol { void send(const token::list_t& tokens); // TODO: Move these methods to a separate session_t class! - void send_result(const session_key_t& session_key, token::list_t tokens); - void proceed(const session_key_t& session_key); - void junk(const session_key_t& session_key); - void fail(const session_key_t& session_key); - void submit_message(const session_key_t& session_key, const std::vector& header, const std::vector& body); + void send_result(const session_key_t& session_key, const token::string_t& session_token, token::list_t tokens); + void proceed(const session_key_t& session_key, const token::string_t& session_token); + void junk(const session_key_t& session_key, const token::string_t& session_token); + void fail(const session_key_t& session_key, const token::string_t& session_token); + void submit_message(const session_key_t& session_key, const token::string_t& session_token, const std::vector& header, const std::vector& body); protected: virtual void emit(const std::string& output) { }; @@ -50,7 +48,7 @@ namespace protocol { size_t max_pattern_length; std::string version; - void send_data_line(const session_key_t& session_key, const std::string& data_line); + void send_data_line(const session_key_t& session_key, const token::string_t& session_token, const std::string& data_line); }; class ios_protocol_t : public protocol_t { @@ -65,17 +63,6 @@ namespace protocol { std::istream& in; std::ostream& out; }; - -} - -namespace std { - template<> struct hash { - std::size_t operator()(protocol::session_key_t const& session) const noexcept { - auto session_hash = std::hash{}(session.session); - auto token_hash = std::hash{}(session.token); - return session_hash ^ (token_hash << 1); - } - }; } #endif \ No newline at end of file diff --git a/src/bogofilter-smtpd.cpp b/src/bogofilter-smtpd.cpp index 7eafd09..e0cebbc 100644 --- a/src/bogofilter-smtpd.cpp +++ b/src/bogofilter-smtpd.cpp @@ -25,8 +25,9 @@ void on_ready(protocol::protocol_t& protocol, protocol::message_t message) { void on_data(protocol::protocol_t& protocol, protocol::message_t message) { debug && cerr << "New message" << endl; auto session_key = protocol::session_key_from(message); + auto session_token = protocol::session_token_from(message); sessions.emplace(session_key, mail::session_t{}); - protocol.proceed(session_key); + protocol.proceed(session_key, session_token); } void on_data_line(protocol::protocol_t& protocol, protocol::message_t message) { @@ -34,6 +35,7 @@ void on_data_line(protocol::protocol_t& protocol, protocol::message_t message) { auto tokens = protocol::token::decompose(message.input); auto session_key = protocol::session_key_from(tokens); + auto session_token = protocol::session_token_from(tokens); try { auto& session = sessions.at(session_key); auto& data_line = tokens.at(7); @@ -60,21 +62,22 @@ void on_data_line(protocol::protocol_t& protocol, protocol::message_t message) { session.message.body.push_back(data_line); } catch(out_of_range& e) { debug && cerr << "Unknown session key" << endl; - protocol.fail(session_key); + protocol.fail(session_key, session_token); } } void on_commit(protocol::protocol_t& protocol, protocol::message_t message) { debug && cerr << "Message committed" << endl; auto session_key = protocol::session_key_from(message); + auto session_token = protocol::session_token_from(message); try { auto& session = sessions.at(session_key); - protocol.submit_message(session_key, session.message.header, session.message.body); + protocol.submit_message(session_key, session_token, session.message.header, session.message.body); sessions.erase(session_key); - protocol.proceed(session_key); + protocol.proceed(session_key, session_token); } catch(out_of_range& e) { debug && cerr << "Unknown session key" << endl; - protocol.fail(session_key); + protocol.fail(session_key, session_token); } } diff --git a/src/protocol/protocol.cpp b/src/protocol/protocol.cpp index ba3bb8c..1bfa58b 100644 --- a/src/protocol/protocol.cpp +++ b/src/protocol/protocol.cpp @@ -51,12 +51,12 @@ namespace protocol { } } - void protocol_t::send_result(const session_key_t& session_key, token::list_t tokens) { + void protocol_t::send_result(const session_key_t& session_key, const token::string_t& session_token, token::list_t tokens) { token::list_t result{"filter-result"}; if(version < "0.5") { - result.insert(result.end(), {session_key.token, session_key.session}); + result.insert(result.end(), {session_token, session_key}); } else { - result.insert(result.end(), {session_key.session, session_key.token}); + result.insert(result.end(), {session_key, session_token}); } for(auto& token : tokens) { result.push_back(token); @@ -64,39 +64,39 @@ namespace protocol { send(result); } - void protocol_t::proceed(const session_key_t& session_key) { - send_result(session_key, {"proceed"}); + void protocol_t::proceed(const session_key_t& session_key, const token::string_t& session_token) { + send_result(session_key, session_token, {"proceed"}); } - void protocol_t::junk(const session_key_t& session_key) { - send_result(session_key, {"junk"}); + void protocol_t::junk(const session_key_t& session_key, const token::string_t& session_token) { + send_result(session_key, session_token, {"junk"}); } - void protocol_t::fail(const session_key_t& session_key) { - send_result(session_key, {"disconnect", "451 Aborted"}); + void protocol_t::fail(const session_key_t& session_key, const token::string_t& session_token) { + send_result(session_key, session_token, {"disconnect", "451 Aborted"}); } - void protocol_t::send_data_line(const session_key_t& session_key, const string& data_line) { - send({"filter-dataline", session_key.session, session_key.token, data_line}); + void protocol_t::send_data_line(const session_key_t& session_key, const token::string_t& session_token, const string& data_line) { + send({"filter-dataline", session_key, session_token, data_line}); } - void protocol_t::submit_message(const session_key_t& session_key, const vector& header, const vector& body) { + void protocol_t::submit_message(const session_key_t& session_key, const token::string_t& session_token, const vector& header, const vector& body) { for(auto& data_line : header) { - send_data_line(session_key, data_line); + send_data_line(session_key, session_token, data_line); } - send_data_line(session_key, ""); + send_data_line(session_key, session_token, ""); for(auto& data_line : body) { if(data_line == ".") { - send_data_line(session_key, ".."); + send_data_line(session_key, session_token, ".."); continue; } - send_data_line(session_key, data_line); + send_data_line(session_key, session_token, data_line); } - send_data_line(session_key, "."); + send_data_line(session_key, session_token, "."); } ios_protocol_t::ios_protocol_t(std::istream& in, std::ostream& out) : @@ -114,18 +114,21 @@ namespace protocol { } } - bool operator==(const session_key_t& l, const session_key_t& r) { - return l.session == r.session && l.token == r.token; - } - session_key_t session_key_from(const token::list_t& tokens) { - auto session_id = tokens.at(5); - auto session_token = tokens.at(6); - return {session_id, session_token}; + return tokens.at(5); } session_key_t session_key_from(const message_t& message) { - auto tokens = token::decompose(message.input); + auto tokens = token::decompose(message.input, 6); return session_key_from(tokens); } + + token::string_t session_token_from(const token::list_t& tokens) { + return tokens.at(6); + } + + token::string_t session_token_from(const message_t& message) { + auto tokens = token::decompose(message.input, 7); + return session_token_from(tokens); + } }