net-smtp 0.3.3 → 0.4.0

Sign up to get free protection for your applications and to get access to all the features.
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
2
  SHA256:
3
- metadata.gz: 314f553cc9e988f56b964e62836e95e323974b6a66c26e2f02d1e6a7cc08e886
4
- data.tar.gz: 43a203a0622f49e2fb32a6c8bc0f644cb703e3bc3bc1f25aa114434c1a9cc8e5
3
+ metadata.gz: 0af9f3ec513aec9b2c9e9b59c086858e3ab6dfe4b66dced534439f3229661327
4
+ data.tar.gz: 307cd96a3a772e525294153b4e36d20fc7722cac80855a40cd9a2d0e11a21694
5
5
  SHA512:
6
- metadata.gz: 486381bf1eee2cbd7cb4f12ca0253ee5b06fc2b1a012b3786bda9b30456c338c5de40889e639275cfcf22a83064d7c468aa06c8e21438adb1d1ab2133a3933eb
7
- data.tar.gz: 97659f9e6505ea3aa10db92d5a99dc39d01ca55468ca28934b77061ccedd7ce74d8652927304ddf7fe4a21622e3572cca3bb92f19bae3a1b004bc7909783b530
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.3"
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.3
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-10-29 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