net-smtp 0.3.2 → 0.4.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 642b3ab1e326ac890c33653e8293421558c50a8d6cdc3483b5c41edb26bdaebe
4
- data.tar.gz: 8c31ba69f42e11a41eda04a31cffe375bcca4cee447b9bc1b1cda218a8f905f3
3
+ metadata.gz: 0af9f3ec513aec9b2c9e9b59c086858e3ab6dfe4b66dced534439f3229661327
4
+ data.tar.gz: 307cd96a3a772e525294153b4e36d20fc7722cac80855a40cd9a2d0e11a21694
5
5
  SHA512:
6
- metadata.gz: a2b5433005fe906635edee7e0bb1c9d0d81a6fff1da5af97ad39b16bf7e8a3330dafa9d9a513a3e83b17fe5a53c1489e07f52445c8cdefd81192f83a8cc4f6e7
7
- data.tar.gz: be1a223db50575fbb0f14ebac46af142b0f109d422049d5ae49c57a0548c4560904931d8b8c75cc35e95c1978ad9c620ed059bee541d7b443f7a3668e1df2a43
6
+ metadata.gz: 9cd5a79d90ebb1d94872e25c416a539afebba68f322bec9953826e984f8e13ddd7403216fde5f09c2ef03a2b6a41cc2b5514b1697b7fd10fa7c663f202ed1fb8
7
+ data.tar.gz: a4d0b4d3749e98173aef3df7bcb2f0a0dd56a8404e801d4af68a38db31f02969f7f94ff659fe50d28b0dcc9f1083f03d0802c3954d9fe87141cf17abdf7777d9
data/NEWS.md ADDED
@@ -0,0 +1,114 @@
1
+ # NEWS
2
+
3
+ ## Version 0.4.0 (2023-09-20)
4
+
5
+ ### Improvements
6
+
7
+ * add Net::SMTP::Authenticator class and auth_* methods are separated from the Net::SMTP class. <https://github.com/ruby/net-smtp/pull/53>
8
+ This allows you to add a new authentication method to Net::SMTP.
9
+ Create a class with an `auth` method that inherits Net::SMTP::Authenticator.
10
+ The `auth` method has two arguments, `user` and `secret`.
11
+ Send an instruction to the SMTP server by using the `continue` or `finish` method.
12
+ For more information, see lib/net/smtp/auto _*.rb.
13
+ * Add SMTPUTF8 support <https://github.com/ruby/net-smtp/pull/49>
14
+
15
+ ### Fixes
16
+
17
+ * Revert "Replace Timeout.timeout with socket timeout" <https://github.com/ruby/net-smtp/pull/51>
18
+ * Fixed issue sending emails to unaffected recipients on 53x error <https://github.com/ruby/net-smtp/pull/56>
19
+
20
+ ### Others
21
+
22
+ * Removed unnecessary Subversion keywords <https://github.com/ruby/net-smtp/pull/57>
23
+
24
+ ## Version 0.3.3 (2022-10-29)
25
+
26
+ * No timeout library required <https://github.com/ruby/net-smtp/pull/44>
27
+ * Make the digest library optional <https://github.com/ruby/net-smtp/pull/45>
28
+
29
+ ## Version 0.3.2 (2022-09-28)
30
+
31
+ * Make exception API compatible with what Ruby expects <https://github.com/ruby/net-smtp/pull/42>
32
+
33
+ ## Version 0.3.1 (2021-12-12)
34
+
35
+ ### Improvements
36
+
37
+ * add Net::SMTP::Address.
38
+ * add Net::SMTP#capable? and Net::SMTP#capabilities.
39
+ * add Net::SMTP#tls_verify, Net::SMTP#tls_hostname, Net::SMTP#ssl_context_params
40
+
41
+ ## Version 0.3.0 (2021-10-14)
42
+
43
+ ### Improvements
44
+
45
+ * Add `tls`, `starttls` keyword arguments.
46
+ ```ruby
47
+ # always use TLS connection for port 465.
48
+ Net::SMTP.start(hostname, 465, tls: true)
49
+
50
+ # do not use starttls for localhost
51
+ Net::SMTP.start('localhost', starttls: false)
52
+ ```
53
+
54
+ ### Incompatible changes
55
+
56
+ * The tls_* paramter has been moved from start() to initialize().
57
+
58
+ ## Version 0.2.2 (2021-10-09)
59
+
60
+ * Add `response` to SMTPError exceptions.
61
+ * `Net::SMTP.start()` and `#start()` accepts `ssl_context_params` keyword argument.
62
+ * Replace `Timeout.timeout` with socket timeout.
63
+ * Remove needless files from gem.
64
+ * Add dependency on digest, timeout.
65
+
66
+ ## Version 0.2.1 (2020-11-18)
67
+
68
+ ### Fixes
69
+
70
+ * Update the license for the default gems to dual licenses.
71
+ * Add dependency for net-protocol.
72
+
73
+ ## Version 0.2.0 (2020-11-15)
74
+
75
+ ### Incompatible changes
76
+
77
+ * Verify the server's certificate by default.
78
+ If you don't want verification, specify `start(tls_verify: false)`.
79
+ <https://github.com/ruby/net-smtp/pull/12>
80
+
81
+ * Use STARTTLS by default if possible.
82
+ If you don't want starttls, specify:
83
+ ```
84
+ smtp = Net::SMTP.new(hostname, port)
85
+ smtp.disable_starttls
86
+ smtp.start do |s|
87
+ s.send_message ....
88
+ end
89
+ ```
90
+ <https://github.com/ruby/net-smtp/pull/9>
91
+
92
+ ### Improvements
93
+
94
+ * Net::SMTP.start and Net::SMTP#start arguments are keyword arguments.
95
+ ```
96
+ start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil) { |smtp| ... }
97
+ ```
98
+ `password` is an alias of `secret`.
99
+ <https://github.com/ruby/net-smtp/pull/7>
100
+
101
+ * Add `tls_hostname` parameter to `start()`.
102
+ If you want to use a different hostname than the certificate for the connection, you can specify the certificate hostname with `tls_hostname`.
103
+ <https://github.com/ruby/net-smtp/pull/14>
104
+
105
+ * Add SNI support to net/smtp <https://github.com/ruby/net-smtp/pull/4>
106
+
107
+ ### Fixes
108
+
109
+ * enable_starttls before disable_tls causes an error. <https://github.com/ruby/net-smtp/pull/10>
110
+ * TLS should not check the hostname when verify_mode is disabled. <https://github.com/ruby/net-smtp/pull/6>
111
+
112
+ ## Version 0.1.0 (2019-12-03)
113
+
114
+ This is the first release of net-smtp gem.
data/README.md ADDED
@@ -0,0 +1,97 @@
1
+ # Net::SMTP
2
+
3
+ This library provides functionality to send internet mail via SMTP, the Simple Mail Transfer Protocol.
4
+
5
+ For details of SMTP itself, see [RFC2821](http://www.ietf.org/rfc/rfc2821.txt).
6
+
7
+ ## Installation
8
+
9
+ Add this line to your application's Gemfile:
10
+
11
+ ```ruby
12
+ gem 'net-smtp'
13
+ ```
14
+
15
+ And then execute:
16
+
17
+ $ bundle
18
+
19
+ Or install it yourself as:
20
+
21
+ $ gem install net-smtp
22
+
23
+ ## Usage
24
+
25
+ ### Sending Messages
26
+
27
+ You must open a connection to an SMTP server before sending messages.
28
+ The first argument is the address of your SMTP server, and the second
29
+ argument is the port number. Using SMTP.start with a block is the simplest
30
+ way to do this. This way, the SMTP connection is closed automatically
31
+ after the block is executed.
32
+
33
+ ```ruby
34
+ require 'net/smtp'
35
+ Net::SMTP.start('your.smtp.server', 25) do |smtp|
36
+ # Use the SMTP object smtp only in this block.
37
+ end
38
+ ```
39
+
40
+ Replace 'your.smtp.server' with your SMTP server. Normally
41
+ your system manager or internet provider supplies a server
42
+ for you.
43
+
44
+ Then you can send messages.
45
+
46
+ ```ruby
47
+ msgstr = <<END_OF_MESSAGE
48
+ From: Your Name <your@mail.address>
49
+ To: Destination Address <someone@example.com>
50
+ Subject: test message
51
+ Date: Sat, 23 Jun 2001 16:26:43 +0900
52
+ Message-Id: <unique.message.id.string@example.com>
53
+
54
+ This is a test message.
55
+ END_OF_MESSAGE
56
+
57
+ require 'net/smtp'
58
+ Net::SMTP.start('your.smtp.server', 25) do |smtp|
59
+ smtp.send_message msgstr,
60
+ 'your@mail.address',
61
+ 'his_address@example.com'
62
+ end
63
+ ```
64
+
65
+ ### Closing the Session
66
+
67
+ You MUST close the SMTP session after sending messages, by calling
68
+ the #finish method:
69
+
70
+ ```ruby
71
+ # using SMTP#finish
72
+ smtp = Net::SMTP.start('your.smtp.server', 25)
73
+ smtp.send_message msgstr, 'from@address', 'to@address'
74
+ smtp.finish
75
+ ```
76
+
77
+ You can also use the block form of SMTP.start/SMTP#start. This closes
78
+ the SMTP session automatically:
79
+
80
+ ```ruby
81
+ # using block form of SMTP.start
82
+ Net::SMTP.start('your.smtp.server', 25) do |smtp|
83
+ smtp.send_message msgstr, 'from@address', 'to@address'
84
+ end
85
+ ```
86
+
87
+ I strongly recommend this scheme. This form is simpler and more robust.
88
+
89
+ ## Development
90
+
91
+ After checking out the repo, run `bin/setup` to install dependencies. Then, run `rake test` to run the tests. You can also run `bin/console` for an interactive prompt that will allow you to experiment.
92
+
93
+ To install this gem onto your local machine, run `bundle exec rake install`. To release a new version, update the version number in `version.rb`, and then run `bundle exec rake release`, which will create a git tag for the version, push git commits and tags, and push the `.gem` file to [rubygems.org](https://rubygems.org).
94
+
95
+ ## Contributing
96
+
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/net-smtp.
@@ -0,0 +1,48 @@
1
+ unless defined? OpenSSL
2
+ begin
3
+ require 'digest/md5'
4
+ rescue LoadError
5
+ end
6
+ end
7
+
8
+ class Net::SMTP
9
+ class AuthCramMD5 < Net::SMTP::Authenticator
10
+ auth_type :cram_md5
11
+
12
+ def auth(user, secret)
13
+ challenge = continue('AUTH CRAM-MD5')
14
+ crammed = cram_md5_response(secret, challenge.unpack1('m'))
15
+ finish(base64_encode("#{user} #{crammed}"))
16
+ end
17
+
18
+ IMASK = 0x36
19
+ OMASK = 0x5c
20
+
21
+ # CRAM-MD5: [RFC2195]
22
+ def cram_md5_response(secret, challenge)
23
+ tmp = digest_class::MD5.digest(cram_secret(secret, IMASK) + challenge)
24
+ digest_class::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
25
+ end
26
+
27
+ CRAM_BUFSIZE = 64
28
+
29
+ def cram_secret(secret, mask)
30
+ secret = digest_class::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
31
+ buf = secret.ljust(CRAM_BUFSIZE, "\0")
32
+ 0.upto(buf.size - 1) do |i|
33
+ buf[i] = (buf[i].ord ^ mask).chr
34
+ end
35
+ buf
36
+ end
37
+
38
+ def digest_class
39
+ @digest_class ||= if defined?(OpenSSL::Digest)
40
+ OpenSSL::Digest
41
+ elsif defined?(::Digest)
42
+ ::Digest
43
+ else
44
+ raise '"openssl" or "digest" library is required'
45
+ end
46
+ end
47
+ end
48
+ end
@@ -0,0 +1,11 @@
1
+ class Net::SMTP
2
+ class AuthLogin < Net::SMTP::Authenticator
3
+ auth_type :login
4
+
5
+ def auth(user, secret)
6
+ continue('AUTH LOGIN')
7
+ continue(base64_encode(user))
8
+ finish(base64_encode(secret))
9
+ end
10
+ end
11
+ end
@@ -0,0 +1,9 @@
1
+ class Net::SMTP
2
+ class AuthPlain < Net::SMTP::Authenticator
3
+ auth_type :plain
4
+
5
+ def auth(user, secret)
6
+ finish('AUTH PLAIN ' + base64_encode("\0#{user}\0#{secret}"))
7
+ end
8
+ end
9
+ end
@@ -0,0 +1,46 @@
1
+ module Net
2
+ class SMTP
3
+ class Authenticator
4
+ def self.auth_classes
5
+ @classes ||= {}
6
+ end
7
+
8
+ def self.auth_type(type)
9
+ Authenticator.auth_classes[type] = self
10
+ end
11
+
12
+ def self.auth_class(type)
13
+ Authenticator.auth_classes[type.intern]
14
+ end
15
+
16
+ attr_reader :smtp
17
+
18
+ def initialize(smtp)
19
+ @smtp = smtp
20
+ end
21
+
22
+ # @param arg [String] message to server
23
+ # @return [String] message from server
24
+ def continue(arg)
25
+ res = smtp.get_response arg
26
+ raise res.exception_class.new(res) unless res.continue?
27
+ res.string.split[1]
28
+ end
29
+
30
+ # @param arg [String] message to server
31
+ # @return [Net::SMTP::Response] response from server
32
+ def finish(arg)
33
+ res = smtp.get_response arg
34
+ raise SMTPAuthenticationError.new(res) unless res.success?
35
+ res
36
+ end
37
+
38
+ # @param str [String]
39
+ # @return [String] Base64 encoded string
40
+ def base64_encode(str)
41
+ # expects "str" may not become too long
42
+ [str].pack('m0')
43
+ end
44
+ end
45
+ end
46
+ end
data/lib/net/smtp.rb CHANGED
@@ -1,4 +1,5 @@
1
1
  # frozen_string_literal: true
2
+
2
3
  # = net/smtp.rb
3
4
  #
4
5
  # Copyright (c) 1999-2007 Yukihiro Matsumoto.
@@ -12,21 +13,16 @@
12
13
  # This program is free software. You can re-distribute and/or
13
14
  # modify this program under the same terms as Ruby itself.
14
15
  #
15
- # $Id$
16
- #
17
16
  # See Net::SMTP for documentation.
18
17
  #
19
18
 
20
19
  require 'net/protocol'
21
- require 'digest/md5'
22
- require 'timeout'
23
20
  begin
24
21
  require 'openssl'
25
22
  rescue LoadError
26
23
  end
27
24
 
28
25
  module Net
29
-
30
26
  # Module mixed in to all SMTP error classes
31
27
  module SMTPError
32
28
  # This *class* is a module for backward compatibility.
@@ -40,7 +36,7 @@ module Net
40
36
  @message = message
41
37
  else
42
38
  @response = nil
43
- @message = message || response
39
+ @message = message || response
44
40
  end
45
41
  end
46
42
 
@@ -84,7 +80,14 @@ module Net
84
80
  #
85
81
  # This library provides functionality to send internet
86
82
  # mail via SMTP, the Simple Mail Transfer Protocol. For details of
87
- # SMTP itself, see [RFC2821] (http://www.ietf.org/rfc/rfc2821.txt).
83
+ # SMTP itself, see [RFC5321] (http://www.ietf.org/rfc/rfc5321.txt).
84
+ # This library also implements SMTP authentication, which is often
85
+ # necessary for message composers to submit messages to their
86
+ # outgoing SMTP server, see
87
+ # [RFC6409](http://www.ietf.org/rfc/rfc6503.txt),
88
+ # and [SMTPUTF8](http://www.ietf.org/rfc/rfc6531.txt), which is
89
+ # necessary to send messages to/from addresses containing characters
90
+ # outside the ASCII range.
88
91
  #
89
92
  # == What is This Library NOT?
90
93
  #
@@ -94,7 +97,7 @@ module Net
94
97
  # {RubyGems.org}[https://rubygems.org/] or {The Ruby
95
98
  # Toolbox}[https://www.ruby-toolbox.com/].
96
99
  #
97
- # FYI: the official documentation on internet mail is: [RFC2822] (http://www.ietf.org/rfc/rfc2822.txt).
100
+ # FYI: the official specification on internet mail is: [RFC5322] (http://www.ietf.org/rfc/rfc5322.txt).
98
101
  #
99
102
  # == Examples
100
103
  #
@@ -184,9 +187,7 @@ module Net
184
187
  # user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
185
188
  #
186
189
  class SMTP < Protocol
187
- VERSION = "0.3.2"
188
-
189
- Revision = %q$Revision$.split[1]
190
+ VERSION = "0.4.0"
190
191
 
191
192
  # The default SMTP port number, 25.
192
193
  def SMTP.default_port
@@ -209,7 +210,7 @@ module Net
209
210
 
210
211
  def SMTP.default_ssl_context(ssl_context_params = nil)
211
212
  context = OpenSSL::SSL::SSLContext.new
212
- context.set_params(ssl_context_params ? ssl_context_params : {})
213
+ context.set_params(ssl_context_params || {})
213
214
  context
214
215
  end
215
216
 
@@ -280,7 +281,7 @@ module Net
280
281
  attr_accessor :esmtp
281
282
 
282
283
  # +true+ if the SMTP object uses ESMTP (which it does by default).
283
- alias :esmtp? :esmtp
284
+ alias esmtp? esmtp
284
285
 
285
286
  # true if server advertises STARTTLS.
286
287
  # You cannot get valid value before opening SMTP session.
@@ -627,12 +628,7 @@ module Net
627
628
  private
628
629
 
629
630
  def tcp_socket(address, port)
630
- begin
631
- Socket.tcp address, port, nil, nil, connect_timeout: @open_timeout
632
- rescue Errno::ETIMEDOUT #raise Net:OpenTimeout instead for compatibility with previous versions
633
- raise Net::OpenTimeout, "Timeout to open TCP connection to "\
634
- "#{address}:#{port} (exceeds #{@open_timeout} seconds)"
635
- end
631
+ TCPSocket.open address, port
636
632
  end
637
633
 
638
634
  def do_start(helo_domain, user, secret, authtype)
@@ -641,7 +637,9 @@ module Net
641
637
  check_auth_method(authtype || DEFAULT_AUTH_TYPE)
642
638
  check_auth_args user, secret
643
639
  end
644
- s = tcp_socket(@address, @port)
640
+ s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
641
+ tcp_socket(@address, @port)
642
+ end
645
643
  logging "Connection opened: #{@address}:#{@port}"
646
644
  @socket = new_internet_message_io(tls? ? tlsconnect(s, @ssl_context_tls) : s)
647
645
  check_response critical { recv_response() }
@@ -708,6 +706,18 @@ module Net
708
706
  @socket = nil
709
707
  end
710
708
 
709
+ def requires_smtputf8(address)
710
+ if address.kind_of? Address
711
+ !address.address.ascii_only?
712
+ else
713
+ !address.ascii_only?
714
+ end
715
+ end
716
+
717
+ def any_require_smtputf8(addresses)
718
+ addresses.any?{ |a| requires_smtputf8(a) }
719
+ end
720
+
711
721
  #
712
722
  # Message Sending
713
723
  #
@@ -751,7 +761,9 @@ module Net
751
761
  # * IOError
752
762
  #
753
763
  def send_message(msgstr, from_addr, *to_addrs)
764
+ to_addrs.flatten!
754
765
  raise IOError, 'closed session' unless @socket
766
+ from_addr = Address.new(from_addr, 'SMTPUTF8') if any_require_smtputf8(to_addrs) && capable?('SMTPUTF8')
755
767
  mailfrom from_addr
756
768
  rcptto_list(to_addrs) {data msgstr}
757
769
  end
@@ -804,7 +816,9 @@ module Net
804
816
  # * IOError
805
817
  #
806
818
  def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream
819
+ to_addrs.flatten!
807
820
  raise IOError, 'closed session' unless @socket
821
+ from_addr = Address.new(from_addr, 'SMTPUTF8') if any_require_smtputf8(to_addrs) && capable?('SMTPUTF8')
808
822
  mailfrom from_addr
809
823
  rcptto_list(to_addrs) {data(&block)}
810
824
  end
@@ -815,52 +829,19 @@ module Net
815
829
  # Authentication
816
830
  #
817
831
 
818
- public
819
-
820
832
  DEFAULT_AUTH_TYPE = :plain
821
833
 
822
834
  def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
823
835
  check_auth_method authtype
824
836
  check_auth_args user, secret
825
- public_send auth_method(authtype), user, secret
826
- end
827
-
828
- def auth_plain(user, secret)
829
- check_auth_args user, secret
830
- res = critical {
831
- get_response('AUTH PLAIN ' + base64_encode("\0#{user}\0#{secret}"))
832
- }
833
- check_auth_response res
834
- res
835
- end
836
-
837
- def auth_login(user, secret)
838
- check_auth_args user, secret
839
- res = critical {
840
- check_auth_continue get_response('AUTH LOGIN')
841
- check_auth_continue get_response(base64_encode(user))
842
- get_response(base64_encode(secret))
843
- }
844
- check_auth_response res
845
- res
846
- end
847
-
848
- def auth_cram_md5(user, secret)
849
- check_auth_args user, secret
850
- res = critical {
851
- res0 = get_response('AUTH CRAM-MD5')
852
- check_auth_continue res0
853
- crammed = cram_md5_response(secret, res0.cram_md5_challenge)
854
- get_response(base64_encode("#{user} #{crammed}"))
855
- }
856
- check_auth_response res
857
- res
837
+ authenticator = Authenticator.auth_class(authtype).new(self)
838
+ authenticator.auth(user, secret)
858
839
  end
859
840
 
860
841
  private
861
842
 
862
843
  def check_auth_method(type)
863
- unless respond_to?(auth_method(type), true)
844
+ unless Authenticator.auth_class(type)
864
845
  raise ArgumentError, "wrong authentication type #{type}"
865
846
  end
866
847
  end
@@ -878,31 +859,6 @@ module Net
878
859
  end
879
860
  end
880
861
 
881
- def base64_encode(str)
882
- # expects "str" may not become too long
883
- [str].pack('m0')
884
- end
885
-
886
- IMASK = 0x36
887
- OMASK = 0x5c
888
-
889
- # CRAM-MD5: [RFC2195]
890
- def cram_md5_response(secret, challenge)
891
- tmp = Digest::MD5.digest(cram_secret(secret, IMASK) + challenge)
892
- Digest::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
893
- end
894
-
895
- CRAM_BUFSIZE = 64
896
-
897
- def cram_secret(secret, mask)
898
- secret = Digest::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
899
- buf = secret.ljust(CRAM_BUFSIZE, "\0")
900
- 0.upto(buf.size - 1) do |i|
901
- buf[i] = (buf[i].ord ^ mask).chr
902
- end
903
- buf
904
- end
905
-
906
862
  #
907
863
  # SMTP command dispatcher
908
864
  #
@@ -929,29 +885,20 @@ module Net
929
885
 
930
886
  # +from_addr+ is +String+ or +Net::SMTP::Address+
931
887
  def mailfrom(from_addr)
932
- addr = Address.new(from_addr)
888
+ addr = if requires_smtputf8(from_addr) && capable?("SMTPUTF8")
889
+ Address.new(from_addr, "SMTPUTF8")
890
+ else
891
+ Address.new(from_addr)
892
+ end
933
893
  getok((["MAIL FROM:<#{addr.address}>"] + addr.parameters).join(' '))
934
894
  end
935
895
 
936
896
  def rcptto_list(to_addrs)
937
897
  raise ArgumentError, 'mail destination not given' if to_addrs.empty?
938
- ok_users = []
939
- unknown_users = []
940
898
  to_addrs.flatten.each do |addr|
941
- begin
942
- rcptto addr
943
- rescue SMTPAuthenticationError
944
- unknown_users << addr.to_s.dump
945
- else
946
- ok_users << addr
947
- end
948
- end
949
- raise ArgumentError, 'mail destination not given' if ok_users.empty?
950
- ret = yield
951
- unless unknown_users.empty?
952
- raise SMTPAuthenticationError, "failed to deliver for #{unknown_users.join(', ')}"
899
+ rcptto addr
953
900
  end
954
- ret
901
+ yield
955
902
  end
956
903
 
957
904
  # +to_addr+ is +String+ or +Net::SMTP::Address+
@@ -1014,6 +961,12 @@ module Net
1014
961
  getok('QUIT')
1015
962
  end
1016
963
 
964
+ def get_response(reqline)
965
+ validate_line reqline
966
+ @socket.writeline reqline
967
+ recv_response()
968
+ end
969
+
1017
970
  private
1018
971
 
1019
972
  def validate_line(line)
@@ -1033,12 +986,6 @@ module Net
1033
986
  res
1034
987
  end
1035
988
 
1036
- def get_response(reqline)
1037
- validate_line reqline
1038
- @socket.writeline reqline
1039
- recv_response()
1040
- end
1041
-
1042
989
  def recv_response
1043
990
  buf = ''.dup
1044
991
  while true
@@ -1071,18 +1018,6 @@ module Net
1071
1018
  end
1072
1019
  end
1073
1020
 
1074
- def check_auth_response(res)
1075
- unless res.success?
1076
- raise SMTPAuthenticationError.new(res)
1077
- end
1078
- end
1079
-
1080
- def check_auth_continue(res)
1081
- unless res.continue?
1082
- raise res.exception_class.new(res)
1083
- end
1084
- end
1085
-
1086
1021
  # This class represents a response received by the SMTP server. Instances
1087
1022
  # of this class are created by the SMTP class; they should not be directly
1088
1023
  # created by the user. For more information on SMTP responses, view
@@ -1184,17 +1119,21 @@ module Net
1184
1119
  @parameters = address.parameters
1185
1120
  else
1186
1121
  @address = address
1187
- @parameters = (args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}
1122
+ @parameters = []
1188
1123
  end
1124
+ @parameters = (parameters + args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}.uniq
1189
1125
  end
1190
1126
 
1191
1127
  def to_s
1192
1128
  @address
1193
1129
  end
1194
1130
  end
1195
-
1196
1131
  end # class SMTP
1197
1132
 
1198
1133
  SMTPSession = SMTP # :nodoc:
1134
+ end
1199
1135
 
1136
+ require_relative 'smtp/authenticator'
1137
+ Dir.glob("#{__dir__}/smtp/auth_*.rb") do |r|
1138
+ require_relative r
1200
1139
  end
metadata CHANGED
@@ -1,14 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-smtp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.2
4
+ version: 0.4.0
5
5
  platform: ruby
6
6
  authors:
7
7
  - Yukihiro Matsumoto
8
8
  autorequire:
9
9
  bindir: bin
10
10
  cert_chain: []
11
- date: 2022-09-28 00:00:00.000000000 Z
11
+ date: 2023-09-20 00:00:00.000000000 Z
12
12
  dependencies:
13
13
  - !ruby/object:Gem::Dependency
14
14
  name: net-protocol
@@ -32,8 +32,13 @@ extensions: []
32
32
  extra_rdoc_files: []
33
33
  files:
34
34
  - LICENSE.txt
35
+ - NEWS.md
36
+ - README.md
35
37
  - lib/net/smtp.rb
36
- - net-smtp.gemspec
38
+ - lib/net/smtp/auth_cram_md5.rb
39
+ - lib/net/smtp/auth_login.rb
40
+ - lib/net/smtp/auth_plain.rb
41
+ - lib/net/smtp/authenticator.rb
37
42
  homepage: https://github.com/ruby/net-smtp
38
43
  licenses:
39
44
  - Ruby
@@ -56,7 +61,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
56
61
  - !ruby/object:Gem::Version
57
62
  version: '0'
58
63
  requirements: []
59
- rubygems_version: 3.4.0.dev
64
+ rubygems_version: 3.5.0.dev
60
65
  signing_key:
61
66
  specification_version: 4
62
67
  summary: Simple Mail Transfer Protocol client library for Ruby.
data/net-smtp.gemspec DELETED
@@ -1,33 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- name = File.basename(__FILE__, ".gemspec")
4
- version = ["lib", Array.new(name.count("-"), "..").join("/")].find do |dir|
5
- break File.foreach(File.join(__dir__, dir, "#{name.tr('-', '/')}.rb")) do |line|
6
- /^\s*VERSION\s*=\s*"(.*)"/ =~ line and break $1
7
- end rescue nil
8
- end
9
-
10
- Gem::Specification.new do |spec|
11
- spec.name = name
12
- spec.version = version
13
- spec.authors = ["Yukihiro Matsumoto"]
14
- spec.email = ["matz@ruby-lang.org"]
15
-
16
- spec.summary = %q{Simple Mail Transfer Protocol client library for Ruby.}
17
- spec.description = %q{Simple Mail Transfer Protocol client library for Ruby.}
18
- spec.homepage = "https://github.com/ruby/net-smtp"
19
- spec.licenses = ["Ruby", "BSD-2-Clause"]
20
- spec.required_ruby_version = ">= 2.6.0"
21
-
22
- spec.metadata["homepage_uri"] = spec.homepage
23
- spec.metadata["source_code_uri"] = spec.homepage
24
-
25
- spec.files = %w[
26
- LICENSE.txt
27
- lib/net/smtp.rb
28
- net-smtp.gemspec
29
- ]
30
- spec.require_paths = ["lib"]
31
-
32
- spec.add_dependency "net-protocol"
33
- end