From 1b5f534487e25b7a34b69247261a69ed6dc6d413 Mon Sep 17 00:00:00 2001 From: usa Date: Fri, 30 Jun 2017 12:10:59 +0000 Subject: [PATCH] merge revision(s) 55324,55325: [Backport #13651] * 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. RFC5321. Thanks, Jeremy Daer. git-svn-id: svn+ssh://ci.ruby-lang.org/ruby/branches/ruby_2_3@59230 b2dd03c8-39d4-4d8f-98ff-823fe69b080e --- ChangeLog | 6 +++++ lib/net/smtp.rb | 9 ++++++++ test/net/smtp/test_smtp.rb | 47 ++++++++++++++++++++++++++++++++++++++ version.h | 2 +- 4 files changed, 63 insertions(+), 1 deletion(-) diff --git a/ChangeLog b/ChangeLog index 1b54315d93..b3f80f2bad 100644 --- a/ChangeLog +++ b/ChangeLog @@ -1,3 +1,9 @@ +Fri Jun 30 21:10:48 2017 Shugo Maeda + + * 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. Thanks, Jeremy Daer. + Fri Jun 30 21:07:56 2017 NAKAMURA Usaku * eval.c (exc_setup_cause): need to unfreeze(=dup) the exception before diff --git a/lib/net/smtp.rb b/lib/net/smtp.rb index d634274c3e..78f2181d2a 100644 --- a/lib/net/smtp.rb +++ b/lib/net/smtp.rb @@ -926,7 +926,15 @@ module Net private + def validate_line(line) + # A bare CR or LF is not allowed in RFC5321. + if /[\r\n]/ =~ line + raise ArgumentError, "A line must not contain CR or LF" + end + end + def getok(reqline) + validate_line reqline res = critical { @socket.writeline reqline recv_response() @@ -936,6 +944,7 @@ module Net end def get_response(reqline) + validate_line reqline @socket.writeline reqline recv_response() end diff --git a/test/net/smtp/test_smtp.rb b/test/net/smtp/test_smtp.rb index 0edb3419d5..3bcceb6fc5 100644 --- a/test/net/smtp/test_smtp.rb +++ b/test/net/smtp/test_smtp.rb @@ -6,6 +6,8 @@ require 'test/unit' module Net class TestSMTP < Test::Unit::TestCase class FakeSocket + attr_reader :write_io + def initialize out = "250 OK\n" @write_io = StringIO.new @read_io = StringIO.new out @@ -51,5 +53,50 @@ module Net assert smtp.rset end + + def test_mailfrom + sock = FakeSocket.new + smtp = Net::SMTP.new 'localhost', 25 + smtp.instance_variable_set :@socket, sock + assert smtp.mailfrom("foo@example.com").success? + assert_equal "MAIL FROM:\r\n", sock.write_io.string + end + + def test_rcptto + sock = FakeSocket.new + smtp = Net::SMTP.new 'localhost', 25 + smtp.instance_variable_set :@socket, sock + assert smtp.rcptto("foo@example.com").success? + assert_equal "RCPT TO:\r\n", sock.write_io.string + end + + def test_auth_plain + sock = FakeSocket.new + smtp = Net::SMTP.new 'localhost', 25 + smtp.instance_variable_set :@socket, sock + assert smtp.auth_plain("foo", "bar").success? + assert_equal "AUTH PLAIN AGZvbwBiYXI=\r\n", sock.write_io.string + end + + def test_crlf_injection + smtp = Net::SMTP.new 'localhost', 25 + smtp.instance_variable_set :@socket, FakeSocket.new + + assert_raise(ArgumentError) do + smtp.mailfrom("foo\r\nbar") + end + + assert_raise(ArgumentError) do + smtp.mailfrom("foo\rbar") + end + + assert_raise(ArgumentError) do + smtp.mailfrom("foo\nbar") + end + + assert_raise(ArgumentError) do + smtp.rcptto("foo\r\nbar") + end + end end end diff --git a/version.h b/version.h index 86b0f18019..f8f143c42f 100644 --- a/version.h +++ b/version.h @@ -1,6 +1,6 @@ #define RUBY_VERSION "2.3.5" #define RUBY_RELEASE_DATE "2017-06-30" -#define RUBY_PATCHLEVEL 326 +#define RUBY_PATCHLEVEL 327 #define RUBY_RELEASE_YEAR 2017 #define RUBY_RELEASE_MONTH 6