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>
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
);
32 const Reply::from_to y1
{"x@y.z", "a=a"};
33 auto const x1
= Reply::dec_reply("rep=6NBM8PA4AR062FB101W40Y9EF8", secret
);
37 auto const z1
= Reply::dec_reply("rep=6nbm8pa4ar062fb101w40y9ef8", secret
);
42 // LOG(INFO) << Reply::enc_reply({"someone@example.com", "dab-dab"}, secret);
44 // LOG(INFO) << Reply::enc_reply({"anybody@mailhog.duck", "mydisabledalias"},
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
);