Skip to content

Commit 0827a7e

Browse files
committed
* lib/net/smtp.rb (getok, get_response): raise an ArgumentError when
CR or LF is included in a line, because they are not allowed in RFC5321. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/trunk@55324 b2dd03c8-39d4-4d8f-98ff-823fe69b080e
1 parent e5230fb commit 0827a7e

File tree

3 files changed

+62
-0
lines changed

3 files changed

+62
-0
lines changed

Diff for: ChangeLog

+6
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,9 @@
1+
Wed Jun 8 16:03:09 2016 Shugo Maeda <shugo@ruby-lang.org>
2+
3+
* lib/net/smtp.rb (getok, get_response): raise an ArgumentError when
4+
CR or LF is included in a line, because they are not allowed in
5+
RFC5321.
6+
17
Tue Jun 7 21:27:25 2016 Kazuki Yamaguchi <k@rhe.jp>
28

39
* test/rubygems/*_{cert,cert_32}.pem: Regenerate test certificates for

Diff for: lib/net/smtp.rb

+9
Original file line numberDiff line numberDiff line change
@@ -926,7 +926,15 @@ def quit
926926

927927
private
928928

929+
def validate_line(line)
930+
# A bare CR or LF is not allowed in RFC5321.
931+
if /[\r\n]/ =~ line
932+
raise ArgumentError, "A line must not contain CR or LF"
933+
end
934+
end
935+
929936
def getok(reqline)
937+
validate_line reqline
930938
res = critical {
931939
@socket.writeline reqline
932940
recv_response()
@@ -936,6 +944,7 @@ def getok(reqline)
936944
end
937945

938946
def get_response(reqline)
947+
validate_line reqline
939948
@socket.writeline reqline
940949
recv_response()
941950
end

Diff for: test/net/smtp/test_smtp.rb

+47
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,8 @@
66
module Net
77
class TestSMTP < Test::Unit::TestCase
88
class FakeSocket
9+
attr_reader :write_io
10+
911
def initialize out = "250 OK\n"
1012
@write_io = StringIO.new
1113
@read_io = StringIO.new out
@@ -51,5 +53,50 @@ def test_rset
5153

5254
assert smtp.rset
5355
end
56+
57+
def test_mailfrom
58+
sock = FakeSocket.new
59+
smtp = Net::SMTP.new 'localhost', 25
60+
smtp.instance_variable_set :@socket, sock
61+
assert smtp.mailfrom("foo@example.com").success?
62+
assert_equal "MAIL FROM:<foo@example.com>\r\n", sock.write_io.string
63+
end
64+
65+
def test_rcptto
66+
sock = FakeSocket.new
67+
smtp = Net::SMTP.new 'localhost', 25
68+
smtp.instance_variable_set :@socket, sock
69+
assert smtp.rcptto("foo@example.com").success?
70+
assert_equal "RCPT TO:<foo@example.com>\r\n", sock.write_io.string
71+
end
72+
73+
def test_auth_plain
74+
sock = FakeSocket.new
75+
smtp = Net::SMTP.new 'localhost', 25
76+
smtp.instance_variable_set :@socket, sock
77+
assert smtp.auth_plain("foo", "bar").success?
78+
assert_equal "AUTH PLAIN AGZvbwBiYXI=\r\n", sock.write_io.string
79+
end
80+
81+
def test_crlf_injection
82+
smtp = Net::SMTP.new 'localhost', 25
83+
smtp.instance_variable_set :@socket, FakeSocket.new
84+
85+
assert_raise(ArgumentError) do
86+
smtp.mailfrom("foo\r\nbar")
87+
end
88+
89+
assert_raise(ArgumentError) do
90+
smtp.mailfrom("foo\rbar")
91+
end
92+
93+
assert_raise(ArgumentError) do
94+
smtp.mailfrom("foo\nbar")
95+
end
96+
97+
assert_raise(ArgumentError) do
98+
smtp.rcptto("foo\r\nbar")
99+
end
100+
end
54101
end
55102
end

0 commit comments

Comments
 (0)