net-smtp 0.3.4 → 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: 381881c1c73159461e4ad7e484a3a092d5809d9cb8ef8440fb765429b53b409f
4
- data.tar.gz: 1b2e706ba5b167822fdd440751446a05c03f0a03d029c5c44a35979f25bf9e37
3
+ metadata.gz: 0af9f3ec513aec9b2c9e9b59c086858e3ab6dfe4b66dced534439f3229661327
4
+ data.tar.gz: 307cd96a3a772e525294153b4e36d20fc7722cac80855a40cd9a2d0e11a21694
5
5
  SHA512:
6
- metadata.gz: 8255edb1e048be3d7ccff1ca6a3abb39f7691a8d09763ba35f5e13690e61af12e08a44c82142423585b8dcef250b80d23d5c04f1b074be881c33398fcd0fb72d
7
- data.tar.gz: 6a3f390d9f4b46209bca54e7c4389a57478160de58185f290dfbb6aca603c48eeea455b3d2331d35f0b476c3522ce1076d2fe5dd67ffa8e73f1f80e5de90c464
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,8 +13,6 @@
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
 
@@ -21,14 +20,9 @@ require 'net/protocol'
21
20
  begin
22
21
  require 'openssl'
23
22
  rescue LoadError
24
- begin
25
- require 'digest/md5'
26
- rescue LoadError
27
- end
28
23
  end
29
24
 
30
25
  module Net
31
-
32
26
  # Module mixed in to all SMTP error classes
33
27
  module SMTPError
34
28
  # This *class* is a module for backward compatibility.
@@ -42,7 +36,7 @@ module Net
42
36
  @message = message
43
37
  else
44
38
  @response = nil
45
- @message = message || response
39
+ @message = message || response
46
40
  end
47
41
  end
48
42
 
@@ -86,7 +80,14 @@ module Net
86
80
  #
87
81
  # This library provides functionality to send internet
88
82
  # mail via SMTP, the Simple Mail Transfer Protocol. For details of
89
- # 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.
90
91
  #
91
92
  # == What is This Library NOT?
92
93
  #
@@ -96,7 +97,7 @@ module Net
96
97
  # {RubyGems.org}[https://rubygems.org/] or {The Ruby
97
98
  # Toolbox}[https://www.ruby-toolbox.com/].
98
99
  #
99
- # 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).
100
101
  #
101
102
  # == Examples
102
103
  #
@@ -186,9 +187,7 @@ module Net
186
187
  # user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
187
188
  #
188
189
  class SMTP < Protocol
189
- VERSION = "0.3.4"
190
-
191
- Revision = %q$Revision$.split[1]
190
+ VERSION = "0.4.0"
192
191
 
193
192
  # The default SMTP port number, 25.
194
193
  def SMTP.default_port
@@ -211,7 +210,7 @@ module Net
211
210
 
212
211
  def SMTP.default_ssl_context(ssl_context_params = nil)
213
212
  context = OpenSSL::SSL::SSLContext.new
214
- context.set_params(ssl_context_params ? ssl_context_params : {})
213
+ context.set_params(ssl_context_params || {})
215
214
  context
216
215
  end
217
216
 
@@ -282,7 +281,7 @@ module Net
282
281
  attr_accessor :esmtp
283
282
 
284
283
  # +true+ if the SMTP object uses ESMTP (which it does by default).
285
- alias :esmtp? :esmtp
284
+ alias esmtp? esmtp
286
285
 
287
286
  # true if server advertises STARTTLS.
288
287
  # You cannot get valid value before opening SMTP session.
@@ -628,23 +627,8 @@ module Net
628
627
 
629
628
  private
630
629
 
631
- def digest_class
632
- @digest_class ||= if defined?(OpenSSL::Digest)
633
- OpenSSL::Digest
634
- elsif defined?(::Digest)
635
- ::Digest
636
- else
637
- raise '"openssl" or "digest" library is required'
638
- end
639
- end
640
-
641
630
  def tcp_socket(address, port)
642
- begin
643
- Socket.tcp address, port, nil, nil, connect_timeout: @open_timeout
644
- rescue Errno::ETIMEDOUT #raise Net:OpenTimeout instead for compatibility with previous versions
645
- raise Net::OpenTimeout, "Timeout to open TCP connection to "\
646
- "#{address}:#{port} (exceeds #{@open_timeout} seconds)"
647
- end
631
+ TCPSocket.open address, port
648
632
  end
649
633
 
650
634
  def do_start(helo_domain, user, secret, authtype)
@@ -653,7 +637,9 @@ module Net
653
637
  check_auth_method(authtype || DEFAULT_AUTH_TYPE)
654
638
  check_auth_args user, secret
655
639
  end
656
- s = tcp_socket(@address, @port)
640
+ s = Timeout.timeout(@open_timeout, Net::OpenTimeout) do
641
+ tcp_socket(@address, @port)
642
+ end
657
643
  logging "Connection opened: #{@address}:#{@port}"
658
644
  @socket = new_internet_message_io(tls? ? tlsconnect(s, @ssl_context_tls) : s)
659
645
  check_response critical { recv_response() }
@@ -720,6 +706,18 @@ module Net
720
706
  @socket = nil
721
707
  end
722
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
+
723
721
  #
724
722
  # Message Sending
725
723
  #
@@ -763,7 +761,9 @@ module Net
763
761
  # * IOError
764
762
  #
765
763
  def send_message(msgstr, from_addr, *to_addrs)
764
+ to_addrs.flatten!
766
765
  raise IOError, 'closed session' unless @socket
766
+ from_addr = Address.new(from_addr, 'SMTPUTF8') if any_require_smtputf8(to_addrs) && capable?('SMTPUTF8')
767
767
  mailfrom from_addr
768
768
  rcptto_list(to_addrs) {data msgstr}
769
769
  end
@@ -816,7 +816,9 @@ module Net
816
816
  # * IOError
817
817
  #
818
818
  def open_message_stream(from_addr, *to_addrs, &block) # :yield: stream
819
+ to_addrs.flatten!
819
820
  raise IOError, 'closed session' unless @socket
821
+ from_addr = Address.new(from_addr, 'SMTPUTF8') if any_require_smtputf8(to_addrs) && capable?('SMTPUTF8')
820
822
  mailfrom from_addr
821
823
  rcptto_list(to_addrs) {data(&block)}
822
824
  end
@@ -827,52 +829,19 @@ module Net
827
829
  # Authentication
828
830
  #
829
831
 
830
- public
831
-
832
832
  DEFAULT_AUTH_TYPE = :plain
833
833
 
834
834
  def authenticate(user, secret, authtype = DEFAULT_AUTH_TYPE)
835
835
  check_auth_method authtype
836
836
  check_auth_args user, secret
837
- public_send auth_method(authtype), user, secret
838
- end
839
-
840
- def auth_plain(user, secret)
841
- check_auth_args user, secret
842
- res = critical {
843
- get_response('AUTH PLAIN ' + base64_encode("\0#{user}\0#{secret}"))
844
- }
845
- check_auth_response res
846
- res
847
- end
848
-
849
- def auth_login(user, secret)
850
- check_auth_args user, secret
851
- res = critical {
852
- check_auth_continue get_response('AUTH LOGIN')
853
- check_auth_continue get_response(base64_encode(user))
854
- get_response(base64_encode(secret))
855
- }
856
- check_auth_response res
857
- res
858
- end
859
-
860
- def auth_cram_md5(user, secret)
861
- check_auth_args user, secret
862
- res = critical {
863
- res0 = get_response('AUTH CRAM-MD5')
864
- check_auth_continue res0
865
- crammed = cram_md5_response(secret, res0.cram_md5_challenge)
866
- get_response(base64_encode("#{user} #{crammed}"))
867
- }
868
- check_auth_response res
869
- res
837
+ authenticator = Authenticator.auth_class(authtype).new(self)
838
+ authenticator.auth(user, secret)
870
839
  end
871
840
 
872
841
  private
873
842
 
874
843
  def check_auth_method(type)
875
- unless respond_to?(auth_method(type), true)
844
+ unless Authenticator.auth_class(type)
876
845
  raise ArgumentError, "wrong authentication type #{type}"
877
846
  end
878
847
  end
@@ -890,31 +859,6 @@ module Net
890
859
  end
891
860
  end
892
861
 
893
- def base64_encode(str)
894
- # expects "str" may not become too long
895
- [str].pack('m0')
896
- end
897
-
898
- IMASK = 0x36
899
- OMASK = 0x5c
900
-
901
- # CRAM-MD5: [RFC2195]
902
- def cram_md5_response(secret, challenge)
903
- tmp = digest_class::MD5.digest(cram_secret(secret, IMASK) + challenge)
904
- digest_class::MD5.hexdigest(cram_secret(secret, OMASK) + tmp)
905
- end
906
-
907
- CRAM_BUFSIZE = 64
908
-
909
- def cram_secret(secret, mask)
910
- secret = digest_class::MD5.digest(secret) if secret.size > CRAM_BUFSIZE
911
- buf = secret.ljust(CRAM_BUFSIZE, "\0")
912
- 0.upto(buf.size - 1) do |i|
913
- buf[i] = (buf[i].ord ^ mask).chr
914
- end
915
- buf
916
- end
917
-
918
862
  #
919
863
  # SMTP command dispatcher
920
864
  #
@@ -941,29 +885,20 @@ module Net
941
885
 
942
886
  # +from_addr+ is +String+ or +Net::SMTP::Address+
943
887
  def mailfrom(from_addr)
944
- 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
945
893
  getok((["MAIL FROM:<#{addr.address}>"] + addr.parameters).join(' '))
946
894
  end
947
895
 
948
896
  def rcptto_list(to_addrs)
949
897
  raise ArgumentError, 'mail destination not given' if to_addrs.empty?
950
- ok_users = []
951
- unknown_users = []
952
898
  to_addrs.flatten.each do |addr|
953
- begin
954
- rcptto addr
955
- rescue SMTPAuthenticationError
956
- unknown_users << addr.to_s.dump
957
- else
958
- ok_users << addr
959
- end
899
+ rcptto addr
960
900
  end
961
- raise ArgumentError, 'mail destination not given' if ok_users.empty?
962
- ret = yield
963
- unless unknown_users.empty?
964
- raise SMTPAuthenticationError, "failed to deliver for #{unknown_users.join(', ')}"
965
- end
966
- ret
901
+ yield
967
902
  end
968
903
 
969
904
  # +to_addr+ is +String+ or +Net::SMTP::Address+
@@ -1026,6 +961,12 @@ module Net
1026
961
  getok('QUIT')
1027
962
  end
1028
963
 
964
+ def get_response(reqline)
965
+ validate_line reqline
966
+ @socket.writeline reqline
967
+ recv_response()
968
+ end
969
+
1029
970
  private
1030
971
 
1031
972
  def validate_line(line)
@@ -1045,12 +986,6 @@ module Net
1045
986
  res
1046
987
  end
1047
988
 
1048
- def get_response(reqline)
1049
- validate_line reqline
1050
- @socket.writeline reqline
1051
- recv_response()
1052
- end
1053
-
1054
989
  def recv_response
1055
990
  buf = ''.dup
1056
991
  while true
@@ -1083,18 +1018,6 @@ module Net
1083
1018
  end
1084
1019
  end
1085
1020
 
1086
- def check_auth_response(res)
1087
- unless res.success?
1088
- raise SMTPAuthenticationError.new(res)
1089
- end
1090
- end
1091
-
1092
- def check_auth_continue(res)
1093
- unless res.continue?
1094
- raise res.exception_class.new(res)
1095
- end
1096
- end
1097
-
1098
1021
  # This class represents a response received by the SMTP server. Instances
1099
1022
  # of this class are created by the SMTP class; they should not be directly
1100
1023
  # created by the user. For more information on SMTP responses, view
@@ -1196,17 +1119,21 @@ module Net
1196
1119
  @parameters = address.parameters
1197
1120
  else
1198
1121
  @address = address
1199
- @parameters = (args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}
1122
+ @parameters = []
1200
1123
  end
1124
+ @parameters = (parameters + args + [kw_args]).map{|param| Array(param)}.flatten(1).map{|param| Array(param).compact.join('=')}.uniq
1201
1125
  end
1202
1126
 
1203
1127
  def to_s
1204
1128
  @address
1205
1129
  end
1206
1130
  end
1207
-
1208
1131
  end # class SMTP
1209
1132
 
1210
1133
  SMTPSession = SMTP # :nodoc:
1134
+ end
1211
1135
 
1136
+ require_relative 'smtp/authenticator'
1137
+ Dir.glob("#{__dir__}/smtp/auth_*.rb") do |r|
1138
+ require_relative r
1212
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.4
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: 2024-01-05 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.3.27
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