Allow any old and crufty protocol version
[ghsmtp.git] / Reply-test.cpp
blob8f42c9c22e7175cdaab0a8419d99ff5abb83c5bf
1 #include "Reply.hpp"
3 #include "Mailbox.hpp"
4 #include "osutil.hpp"
6 #include <iostream>
8 #include <fmt/format.h>
9 #include <fmt/ostream.h>
11 #include <gflags/gflags.h>
13 #include <glog/logging.h>
15 #include <cppcodec/base32_crockford.hpp>
16 #include <openssl/sha.h>
18 using std::begin;
19 using std::end;
21 constexpr char secret[] = "Not a real secret, of course.";
23 int main(int argc, char* argv[])
25 google::ParseCommandLineFlags(&argc, &argv, true);
27 const Reply::from_to y0{"x@y.z", "a"};
28 auto const x0 = Reply::dec_reply("rep=RHGA7M=a=x=y.z", secret);
29 if (*x0 != y0) {
30 CHECK(y0 == *x0);
32 const Reply::from_to y1{"x@y.z", "a=a"};
33 auto const x1 = Reply::dec_reply("rep=6NBM8PA4AR062FB101W40Y9EF8", secret);
34 if (*x1 != y1) {
35 CHECK(y1 == *x1);
37 auto const z1 = Reply::dec_reply("rep=6nbm8pa4ar062fb101w40y9ef8", secret);
38 if (*x1 != z1) {
39 CHECK(z1 == *x1);
42 // LOG(INFO) << Reply::enc_reply({"someone@example.com", "dab-dab"}, secret);
44 // LOG(INFO) << Reply::enc_reply({"anybody@mailhog.duck", "mydisabledalias"},
45 // secret);
46 // LOG(INFO) << Reply::enc_reply({"x@y.z", "a"}, secret);
48 CHECK_EQ(Reply::enc_reply({"x@y.z", "a"}, secret), "x_at_y.z_rhga7m_a");
49 CHECK_EQ(Reply::enc_reply({"x_x@y.z", "a"}, secret), "x_x_at_y.z_4797dj_a");
50 CHECK_EQ(Reply::enc_reply({"x=x@y.z", "a"}, secret), "x=x_at_y.z_a0dt6k_a");
51 CHECK_EQ(Reply::enc_reply({"x=x@y.z", "a_a"}, secret),
52 "x=x=at=y.z=2a2qpd=a_a");
53 CHECK_EQ(Reply::enc_reply({"x.x@y.z", "a"}, secret), "x.x_at_y.z_9avgdj_a");
54 CHECK_EQ(Reply::enc_reply({"x@y.z", "a=a"}, secret), "x_at_y.z_5wdydv_a=a");
55 CHECK_EQ(Reply::enc_reply({"x@y.z", "a_a"}, secret), "x=at=y.z=3d8qs3=a_a");
56 CHECK_EQ(Reply::enc_reply({"\"x\"@y.z", "a"}, secret),
57 "ewtk8dkqew062012f0h40y9ef8");
58 CHECK_EQ(Reply::enc_reply({"x@[IPv6:::1]", "a"}, secret),
59 "cgwkgrbdcc06203r81dmjm3p6rx3mehhbm");
61 Reply::from_to test_cases[] = {
62 {"reply@example.com", "local"},
63 {"reply@example.com", "local_address"},
64 {"reply@example.com", "local-address"},
65 {"reply@example.com", "local=address"},
66 {"one.reply@example.com", "local"},
67 {"one-reply@example.com", "local"},
68 {"one=reply@example.com", "local"},
69 {"one_reply@example.com", "local"},
70 {"reply=something@example.com", "local"},
72 // Should work with UTF-8 in all the places.
73 {"♥@♥.example.com", "♥"},
75 // These should force blob mode:
76 {"reply@example.com", "\"local part\""},
77 {"reply@example.com", "has=both_separators"},
78 {"\"quoted string\"@example.com", "local"},
79 {"reply@[127.0.0.1]", "local"},
80 {"reply@[IPv6:::1]", "local"},
83 for (auto const& test_case : test_cases) {
84 auto const enc_rep = Reply::enc_reply(test_case, secret);
85 // std::cout << enc_rep << '\n';
86 CHECK(Mailbox::validate(fmt::format("{}@x.y", enc_rep))) << enc_rep;
87 auto const dec_rep = Reply::dec_reply(enc_rep, secret);
88 if (!dec_rep || *dec_rep != test_case) {
89 LOG(INFO) << "in mail_from == " << test_case.mail_from;
90 LOG(INFO) << "in local_part == " << test_case.rcpt_to_local_part;
91 LOG(INFO) << " enc_rep == " << enc_rep;
92 LOG(INFO) << "out mail_from == " << dec_rep->mail_from;
93 LOG(INFO) << "out local_part == " << dec_rep->rcpt_to_local_part;
94 CHECK(test_case == *dec_rep);