mail_smtp.t 5.3 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236
  1. #!/usr/bin/perl
  2. # (C) Maxim Dounin
  3. # Tests for nginx mail smtp module.
  4. ###############################################################################
  5. use warnings;
  6. use strict;
  7. use Test::More;
  8. use MIME::Base64;
  9. use Socket qw/ CRLF /;
  10. BEGIN { use FindBin; chdir($FindBin::Bin); }
  11. use lib 'lib';
  12. use Test::Nginx;
  13. use Test::Nginx::SMTP;
  14. ###############################################################################
  15. select STDERR; $| = 1;
  16. select STDOUT; $| = 1;
  17. local $SIG{PIPE} = 'IGNORE';
  18. my $t = Test::Nginx->new()
  19. ->has(qw/mail smtp http rewrite/)->plan(25)
  20. ->run_daemon(\&Test::Nginx::SMTP::smtp_test_daemon)
  21. ->write_file_expand('nginx.conf', <<'EOF')->run();
  22. %%TEST_GLOBALS%%
  23. master_process off;
  24. daemon off;
  25. events {
  26. }
  27. mail {
  28. proxy_pass_error_message on;
  29. auth_http http://127.0.0.1:8080/mail/auth;
  30. xclient off;
  31. server {
  32. listen 127.0.0.1:8025;
  33. protocol smtp;
  34. smtp_auth login plain none;
  35. }
  36. }
  37. http {
  38. %%TEST_GLOBALS_HTTP%%
  39. server {
  40. listen 127.0.0.1:8080;
  41. server_name localhost;
  42. location = /mail/auth {
  43. set $reply ERROR;
  44. if ($http_auth_smtp_to ~ example.com) {
  45. set $reply OK;
  46. }
  47. set $userpass "$http_auth_user:$http_auth_pass";
  48. if ($userpass ~ '^test@example.com:secret$') {
  49. set $reply OK;
  50. }
  51. add_header Auth-Status $reply;
  52. add_header Auth-Server 127.0.0.1;
  53. add_header Auth-Port 8026;
  54. add_header Auth-Wait 1;
  55. return 204;
  56. }
  57. }
  58. }
  59. EOF
  60. ###############################################################################
  61. my $s = Test::Nginx::SMTP->new();
  62. $s->check(qr/^220 /, "greeting");
  63. $s->send('EHLO example.com');
  64. $s->check(qr/^250 /, "ehlo");
  65. $s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0bad", ''));
  66. $s->check(qr/^5.. /, 'auth plain with bad password');
  67. $s->send('AUTH PLAIN ' . encode_base64("\0test\@example.com\0secret", ''));
  68. $s->authok('auth plain');
  69. # We are talking to backend from this point
  70. $s->send('MAIL FROM:<test@example.com> SIZE=100');
  71. $s->ok('mail from after auth');
  72. $s->send('RSET');
  73. $s->ok('rset');
  74. $s->send('MAIL FROM:<test@xn--e1afmkfd.xn--80akhbyknj4f> SIZE=100');
  75. $s->ok("idn mail from (example.test in russian)");
  76. $s->send('QUIT');
  77. $s->ok("quit");
  78. # Try auth login in simple form
  79. $s = Test::Nginx::SMTP->new();
  80. $s->read();
  81. $s->send('EHLO example.com');
  82. $s->read();
  83. $s->send('AUTH LOGIN');
  84. $s->check(qr/^334 VXNlcm5hbWU6/, 'auth login simple username challenge');
  85. $s->send(encode_base64('test@example.com', ''));
  86. $s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login simple password challenge');
  87. $s->send(encode_base64('secret', ''));
  88. $s->authok('auth login simple');
  89. # Try auth plain with username. Details:
  90. #
  91. # [MS-XLOGIN]: SMTP Protocol AUTH LOGIN Extension Specification
  92. # http://download.microsoft.com/download/5/D/D/5DD33FDF-91F5-496D-9884-0A0B0EE698BB/%5BMS-XLOGIN%5D.pdf
  93. $s = Test::Nginx::SMTP->new();
  94. $s->read();
  95. $s->send('EHLO example.com');
  96. $s->read();
  97. $s->send('AUTH LOGIN ' . encode_base64('test@example.com', ''));
  98. $s->check(qr/^334 UGFzc3dvcmQ6/, 'auth login with username password challenge');
  99. $s->send(encode_base64('secret', ''));
  100. $s->authok('auth login with username');
  101. # Try auth plain with pipelining
  102. TODO: {
  103. local $TODO = 'pipelining not in official nginx';
  104. local $SIG{__WARN__} = sub {};
  105. $s = Test::Nginx::SMTP->new();
  106. $s->read();
  107. $s->send('EHLO example.com');
  108. $s->read();
  109. $s->send('INVALID COMMAND WITH ARGUMENTS' . CRLF
  110. . 'RSET');
  111. $s->read();
  112. $s->ok('pipelined rset after invalid command');
  113. $s->send('AUTH PLAIN '
  114. . encode_base64("\0test\@example.com\0bad", '') . CRLF
  115. . 'MAIL FROM:<test@example.com> SIZE=100');
  116. $s->read();
  117. $s->ok('mail from after failed pipelined auth');
  118. $s->send('AUTH PLAIN '
  119. . encode_base64("\0test\@example.com\0secret", '') . CRLF
  120. . 'MAIL FROM:<test@example.com> SIZE=100');
  121. $s->read();
  122. $s->ok('mail from after pipelined auth');
  123. }
  124. # Try auth none
  125. $s = Test::Nginx::SMTP->new();
  126. $s->read();
  127. $s->send('EHLO example.com');
  128. $s->read();
  129. $s->send('MAIL FROM:<test@example.com> SIZE=100');
  130. $s->ok('auth none - mail from');
  131. $s->send('RCPT TO:<test@example.com>');
  132. $s->ok('auth none - rcpt to');
  133. $s->send('RSET');
  134. $s->ok('auth none - rset, should go to backend');
  135. # Auth none with pipelining
  136. $s = Test::Nginx::SMTP->new();
  137. $s->read();
  138. $s->send('EHLO example.com');
  139. $s->read();
  140. $s->send('MAIL FROM:<test@example.com> SIZE=100' . CRLF
  141. . 'RCPT TO:<test@example.com>' . CRLF
  142. . 'RSET');
  143. $s->ok('pipelined mail from');
  144. TODO: {
  145. local $TODO = 'pipelining not in official nginx';
  146. local $SIG{__WARN__} = sub {};
  147. $s->ok('pipelined rcpt to');
  148. $s->ok('pipelined rset');
  149. }
  150. # Connection must stay even if error returned to rcpt to command
  151. $s = Test::Nginx::SMTP->new();
  152. $s->read();
  153. $s->send('EHLO example.com');
  154. $s->read();
  155. $s->send('MAIL FROM:<test@example.com> SIZE=100');
  156. $s->read(); # skip mail from reply
  157. $s->send('RCPT TO:<example.com>');
  158. $s->check(qr/^5.. /, "bad rcpt to");
  159. $s->send('RCPT TO:<test@example.com>');
  160. $s->ok('good rcpt to');
  161. # Make sure command splitted into many packets processed correctly
  162. $s = Test::Nginx::SMTP->new();
  163. $s->read();
  164. log_out('HEL');
  165. $s->print('HEL');
  166. $s->send('O example.com');
  167. $s->ok('splitted command');
  168. ###############################################################################