net-smtp 0.3.2 → 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: 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