net-smtp 0.1.0 → 0.2.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: 78828322ead199854db6be7e42250f1a185f13979020922e49c9865c499c7305
4
- data.tar.gz: 88387d583063d1ee6478621d4e2d622582f09a7b7a11f50e9bd067575da8ba35
3
+ metadata.gz: f36274dfebf0d3d7960904ebb1ea198c7a6864adeed057c4095aa59607e0b965
4
+ data.tar.gz: c6a5037aae097aca70103a76eb496472541b62286b23299389b368000abb403f
5
5
  SHA512:
6
- metadata.gz: fc0c2ba9462420db511321f9206db5035ecc3778e9e4b526634c7a98ffbc089bae94f4056a4385582f2cfe734a15f9ce8724f355cdbfbeb0c299fa3331d2f9e0
7
- data.tar.gz: 86b82c9b891c41fea7829ea8c201835930cf3ba93966b51c636d56aeb54f9e132d530264b9b2b93a42364cfe5d841b287df4173a56b9541ca22f3c0f9bbb4b60
6
+ metadata.gz: e407c785d6f9f7eaf9a243b4be97cadf94485f00027f161f418ad7727a6a968a4e84398e1c797d3066947168c3ec3472f48b77825663b5848072581240097ff8
7
+ data.tar.gz: 155b3aaf44e0c39d6084bcded6ca3b17c53679a256214053e0d021c02c5fa2a4e503ca61cea2cc44749b1dbecaab390d5cbc7ab3209429be4b08c8cbb0f2766b
@@ -0,0 +1,24 @@
1
+ name: test
2
+
3
+ on: [push, pull_request]
4
+
5
+ jobs:
6
+ build:
7
+ name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
+ strategy:
9
+ matrix:
10
+ ruby: [ 2.7, 2.6, 2.5, head ]
11
+ os: [ ubuntu-latest, macos-latest ]
12
+ runs-on: ${{ matrix.os }}
13
+ steps:
14
+ - uses: actions/checkout@master
15
+ - name: Set up Ruby
16
+ uses: ruby/setup-ruby@v1
17
+ with:
18
+ ruby-version: ${{ matrix.ruby }}
19
+ - name: Install dependencies
20
+ run: |
21
+ gem install bundler --no-document
22
+ bundle install
23
+ - name: Run test
24
+ run: rake test
data/NEWS.md ADDED
@@ -0,0 +1,44 @@
1
+ # NEWS
2
+
3
+ ## Version 0.2.0 (2020-11-15)
4
+
5
+ ### Incompatible changes
6
+
7
+ * Verify the server's certificate by default.
8
+ If you don't want verification, specify `start(tls_verify: false)`.
9
+ <https://github.com/ruby/net-smtp/pull/12>
10
+
11
+ * Use STARTTLS by default if possible.
12
+ If you don't want starttls, specify:
13
+ ```
14
+ smtp = Net::SMTP.new(hostname, port)
15
+ smtp.disable_starttls
16
+ smtp.start do |s|
17
+ s.send_message ....
18
+ end
19
+ ```
20
+ <https://github.com/ruby/net-smtp/pull/9>
21
+
22
+ ### Improvements
23
+
24
+ * Net::SMTP.start and Net::SMTP#start arguments are keyword arguments.
25
+ ```
26
+ start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil) { |smtp| ... }
27
+ ```
28
+ `password` is an alias of `secret`.
29
+ <https://github.com/ruby/net-smtp/pull/7>
30
+
31
+ * Add `tls_hostname` parameter to `start()`.
32
+ If you want to use a different hostname than the certificate for the connection, you can specify the certificate hostname with `tls_hostname`.
33
+ <https://github.com/ruby/net-smtp/pull/14>
34
+
35
+ * Add SNI support to net/smtp <https://github.com/ruby/net-smtp/pull/4>
36
+
37
+ ### Fixes
38
+
39
+ * enable_starttls before disable_tls causes an error. <https://github.com/ruby/net-smtp/pull/10>
40
+ * TLS should not check the hostname when verify_mode is disabled. <https://github.com/ruby/net-smtp/pull/6>
41
+
42
+ ## Version 0.1.0 (2019-12-03)
43
+
44
+ This is the first release of net-smtp gem.
data/README.md CHANGED
@@ -94,4 +94,4 @@ To install this gem onto your local machine, run `bundle exec rake install`. To
94
94
 
95
95
  ## Contributing
96
96
 
97
- Bug reports and pull requests are welcome on GitHub at https://github.com/hsbt/net-smtp.
97
+ Bug reports and pull requests are welcome on GitHub at https://github.com/ruby/net-smtp.
@@ -146,8 +146,8 @@ module Net
146
146
  # The SMTP server will judge whether it should send or reject
147
147
  # the SMTP session by inspecting the HELO domain.
148
148
  #
149
- # Net::SMTP.start('your.smtp.server', 25,
150
- # 'mail.from.domain') { |smtp| ... }
149
+ # Net::SMTP.start('your.smtp.server', 25
150
+ # helo: 'mail.from.domain') { |smtp| ... }
151
151
  #
152
152
  # === SMTP Authentication
153
153
  #
@@ -157,17 +157,18 @@ module Net
157
157
  # SMTP.start/SMTP#start.
158
158
  #
159
159
  # # PLAIN
160
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
161
- # 'Your Account', 'Your Password', :plain)
160
+ # Net::SMTP.start('your.smtp.server', 25
161
+ # user: 'Your Account', secret: 'Your Password', authtype: :plain)
162
162
  # # LOGIN
163
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
164
- # 'Your Account', 'Your Password', :login)
163
+ # Net::SMTP.start('your.smtp.server', 25
164
+ # user: 'Your Account', secret: 'Your Password', authtype: :login)
165
165
  #
166
166
  # # CRAM MD5
167
- # Net::SMTP.start('your.smtp.server', 25, 'mail.from.domain',
168
- # 'Your Account', 'Your Password', :cram_md5)
167
+ # Net::SMTP.start('your.smtp.server', 25
168
+ # user: 'Your Account', secret: 'Your Password', authtype: :cram_md5)
169
169
  #
170
170
  class SMTP < Protocol
171
+ VERSION = "0.2.0"
171
172
 
172
173
  Revision = %q$Revision$.split[1]
173
174
 
@@ -190,8 +191,13 @@ module Net
190
191
  alias default_ssl_port default_tls_port
191
192
  end
192
193
 
193
- def SMTP.default_ssl_context
194
- OpenSSL::SSL::SSLContext.new
194
+ def SMTP.default_ssl_context(verify_peer=true)
195
+ context = OpenSSL::SSL::SSLContext.new
196
+ context.verify_mode = verify_peer ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE
197
+ store = OpenSSL::X509::Store.new
198
+ store.set_default_paths
199
+ context.cert_store = store
200
+ context
195
201
  end
196
202
 
197
203
  #
@@ -217,8 +223,9 @@ module Net
217
223
  @error_occurred = false
218
224
  @debug_output = nil
219
225
  @tls = false
220
- @starttls = false
221
- @ssl_context = nil
226
+ @starttls = :auto
227
+ @ssl_context_tls = nil
228
+ @ssl_context_starttls = nil
222
229
  end
223
230
 
224
231
  # Provide human-readable stringification of class state.
@@ -293,11 +300,11 @@ module Net
293
300
  # Enables SMTP/TLS (SMTPS: SMTP over direct TLS connection) for
294
301
  # this object. Must be called before the connection is established
295
302
  # to have any effect. +context+ is a OpenSSL::SSL::SSLContext object.
296
- def enable_tls(context = SMTP.default_ssl_context)
303
+ def enable_tls(context = nil)
297
304
  raise 'openssl library not installed' unless defined?(OpenSSL)
298
- raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls
305
+ raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @starttls == :always
299
306
  @tls = true
300
- @ssl_context = context
307
+ @ssl_context_tls = context
301
308
  end
302
309
 
303
310
  alias enable_ssl enable_tls
@@ -306,7 +313,7 @@ module Net
306
313
  # connection is established to have any effect.
307
314
  def disable_tls
308
315
  @tls = false
309
- @ssl_context = nil
316
+ @ssl_context_tls = nil
310
317
  end
311
318
 
312
319
  alias disable_ssl disable_tls
@@ -330,27 +337,27 @@ module Net
330
337
 
331
338
  # Enables SMTP/TLS (STARTTLS) for this object.
332
339
  # +context+ is a OpenSSL::SSL::SSLContext object.
333
- def enable_starttls(context = SMTP.default_ssl_context)
340
+ def enable_starttls(context = nil)
334
341
  raise 'openssl library not installed' unless defined?(OpenSSL)
335
342
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
336
343
  @starttls = :always
337
- @ssl_context = context
344
+ @ssl_context_starttls = context
338
345
  end
339
346
 
340
347
  # Enables SMTP/TLS (STARTTLS) for this object if server accepts.
341
348
  # +context+ is a OpenSSL::SSL::SSLContext object.
342
- def enable_starttls_auto(context = SMTP.default_ssl_context)
349
+ def enable_starttls_auto(context = nil)
343
350
  raise 'openssl library not installed' unless defined?(OpenSSL)
344
351
  raise ArgumentError, "SMTPS and STARTTLS is exclusive" if @tls
345
352
  @starttls = :auto
346
- @ssl_context = context
353
+ @ssl_context_starttls = context
347
354
  end
348
355
 
349
356
  # Disables SMTP/TLS (STARTTLS) for this object. Must be called
350
357
  # before the connection is established to have any effect.
351
358
  def disable_starttls
352
359
  @starttls = false
353
- @ssl_context = nil
360
+ @ssl_context_starttls = nil
354
361
  end
355
362
 
356
363
  # The address of the SMTP server to connect to.
@@ -400,12 +407,16 @@ module Net
400
407
  # SMTP session control
401
408
  #
402
409
 
410
+ #
411
+ # :call-seq:
412
+ # start(address, port = nil, helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
413
+ # start(address, port = nil, helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
403
414
  #
404
415
  # Creates a new Net::SMTP object and connects to the server.
405
416
  #
406
417
  # This method is equivalent to:
407
418
  #
408
- # Net::SMTP.new(address, port).start(helo_domain, account, password, authtype)
419
+ # Net::SMTP.new(address, port).start(helo: helo_domain, user: account, secret: password, authtype: authtype, tls_verify: flag, tls_hostname: hostname)
409
420
  #
410
421
  # === Example
411
422
  #
@@ -435,6 +446,9 @@ module Net
435
446
  # or other authentication token; and +authtype+ is the authentication
436
447
  # type, one of :plain, :login, or :cram_md5. See the discussion of
437
448
  # SMTP Authentication in the overview notes.
449
+ # If +tls_verify+ is true, verify the server's certificate. The default is true.
450
+ # If the hostname in the server certificate is different from +address+,
451
+ # it can be specified with +tls_hostname+.
438
452
  #
439
453
  # === Errors
440
454
  #
@@ -449,10 +463,16 @@ module Net
449
463
  # * Net::ReadTimeout
450
464
  # * IOError
451
465
  #
452
- def SMTP.start(address, port = nil, helo = 'localhost',
453
- user = nil, secret = nil, authtype = nil,
454
- &block) # :yield: smtp
455
- new(address, port).start(helo, user, secret, authtype, &block)
466
+ def SMTP.start(address, port = nil, *args, helo: nil,
467
+ user: nil, secret: nil, password: nil, authtype: nil,
468
+ tls_verify: true, tls_hostname: nil,
469
+ &block)
470
+ raise ArgumentError, "wrong number of arguments (given #{args.size + 2}, expected 1..6)" if args.size > 4
471
+ helo ||= args[0] || 'localhost'
472
+ user ||= args[1]
473
+ secret ||= password || args[2]
474
+ authtype ||= args[3]
475
+ new(address, port).start(helo: helo, user: user, secret: secret, authtype: authtype, tls_verify: tls_verify, tls_hostname: tls_hostname, &block)
456
476
  end
457
477
 
458
478
  # +true+ if the SMTP session has been started.
@@ -460,6 +480,10 @@ module Net
460
480
  @started
461
481
  end
462
482
 
483
+ #
484
+ # :call-seq:
485
+ # start(helo: 'localhost', user: nil, secret: nil, authtype: nil, tls_verify: true, tls_hostname: nil) { |smtp| ... }
486
+ # start(helo = 'localhost', user = nil, secret = nil, authtype = nil) { |smtp| ... }
463
487
  #
464
488
  # Opens a TCP connection and starts the SMTP session.
465
489
  #
@@ -473,6 +497,9 @@ module Net
473
497
  # the type of authentication to attempt; it must be one of
474
498
  # :login, :plain, and :cram_md5. See the notes on SMTP Authentication
475
499
  # in the overview.
500
+ # If +tls_verify+ is true, verify the server's certificate. The default is true.
501
+ # If the hostname in the server certificate is different from +address+,
502
+ # it can be specified with +tls_hostname+.
476
503
  #
477
504
  # === Block Usage
478
505
  #
@@ -487,7 +514,7 @@ module Net
487
514
  #
488
515
  # require 'net/smtp'
489
516
  # smtp = Net::SMTP.new('smtp.mail.server', 25)
490
- # smtp.start(helo_domain, account, password, authtype) do |smtp|
517
+ # smtp.start(helo: helo_domain, user: account, secret: password, authtype: authtype) do |smtp|
491
518
  # smtp.send_message msgstr, 'from@example.com', ['dest@example.com']
492
519
  # end
493
520
  #
@@ -511,8 +538,20 @@ module Net
511
538
  # * Net::ReadTimeout
512
539
  # * IOError
513
540
  #
514
- def start(helo = 'localhost',
515
- user = nil, secret = nil, authtype = nil) # :yield: smtp
541
+ def start(*args, helo: nil,
542
+ user: nil, secret: nil, password: nil, authtype: nil, tls_verify: true, tls_hostname: nil)
543
+ raise ArgumentError, "wrong number of arguments (given #{args.size}, expected 0..4)" if args.size > 4
544
+ helo ||= args[0] || 'localhost'
545
+ user ||= args[1]
546
+ secret ||= password || args[2]
547
+ authtype ||= args[3]
548
+ if @tls && @ssl_context_tls.nil?
549
+ @ssl_context_tls = SMTP.default_ssl_context(tls_verify)
550
+ end
551
+ if @starttls && @ssl_context_starttls.nil?
552
+ @ssl_context_starttls = SMTP.default_ssl_context(tls_verify)
553
+ end
554
+ @tls_hostname = tls_hostname
516
555
  if block_given?
517
556
  begin
518
557
  do_start helo, user, secret, authtype
@@ -549,16 +588,16 @@ module Net
549
588
  tcp_socket(@address, @port)
550
589
  end
551
590
  logging "Connection opened: #{@address}:#{@port}"
552
- @socket = new_internet_message_io(tls? ? tlsconnect(s) : s)
591
+ @socket = new_internet_message_io(tls? ? tlsconnect(s, @ssl_context_tls) : s)
553
592
  check_response critical { recv_response() }
554
593
  do_helo helo_domain
555
- if starttls_always? or (capable_starttls? and starttls_auto?)
594
+ if ! tls? and (starttls_always? or (capable_starttls? and starttls_auto?))
556
595
  unless capable_starttls?
557
596
  raise SMTPUnsupportedCommand,
558
597
  "STARTTLS is not supported on this server"
559
598
  end
560
599
  starttls
561
- @socket = new_internet_message_io(tlsconnect(s))
600
+ @socket = new_internet_message_io(tlsconnect(s, @ssl_context_starttls))
562
601
  # helo response may be different after STARTTLS
563
602
  do_helo helo_domain
564
603
  end
@@ -576,14 +615,15 @@ module Net
576
615
  OpenSSL::SSL::SSLSocket.new socket, context
577
616
  end
578
617
 
579
- def tlsconnect(s)
618
+ def tlsconnect(s, context)
580
619
  verified = false
581
- s = ssl_socket(s, @ssl_context)
620
+ s = ssl_socket(s, context)
582
621
  logging "TLS connection started"
583
622
  s.sync_close = true
623
+ s.hostname = @tls_hostname || @address if s.respond_to? :hostname=
584
624
  ssl_socket_connect(s, @open_timeout)
585
- if @ssl_context.verify_mode != OpenSSL::SSL::VERIFY_NONE
586
- s.post_connection_check(@address)
625
+ if context.verify_mode && context.verify_mode != OpenSSL::SSL::VERIFY_NONE
626
+ s.post_connection_check(@tls_hostname || @address)
587
627
  end
588
628
  verified = true
589
629
  s
@@ -831,9 +871,6 @@ module Net
831
871
  end
832
872
 
833
873
  def mailfrom(from_addr)
834
- if $SAFE > 0
835
- raise SecurityError, 'tainted from_addr' if from_addr.tainted?
836
- end
837
874
  getok("MAIL FROM:<#{from_addr}>")
838
875
  end
839
876
 
@@ -859,9 +896,6 @@ module Net
859
896
  end
860
897
 
861
898
  def rcptto(to_addr)
862
- if $SAFE > 0
863
- raise SecurityError, 'tainted to_addr' if to_addr.tainted?
864
- end
865
899
  getok("RCPT TO:<#{to_addr}>")
866
900
  end
867
901
 
@@ -1048,7 +1082,7 @@ module Net
1048
1082
  return {} unless @string[3, 1] == '-'
1049
1083
  h = {}
1050
1084
  @string.lines.drop(1).each do |line|
1051
- k, *v = line[4..-1].chomp.split
1085
+ k, *v = line[4..-1].split(' ')
1052
1086
  h[k] = v
1053
1087
  end
1054
1088
  h
@@ -1,23 +1,29 @@
1
- lib = File.expand_path("lib", __dir__)
2
- $LOAD_PATH.unshift(lib) unless $LOAD_PATH.include?(lib)
3
- require "net/smtp/version"
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
4
9
 
5
10
  Gem::Specification.new do |spec|
6
- spec.name = "net-smtp"
7
- spec.version = Net::SMTP::VERSION
8
- spec.authors = ["Hiroshi SHIBATA"]
9
- spec.email = ["hsbt@ruby-lang.org"]
11
+ spec.name = name
12
+ spec.version = version
13
+ spec.authors = ["Yukihiro Matsumoto"]
14
+ spec.email = ["matz@ruby-lang.org"]
10
15
 
11
16
  spec.summary = %q{Simple Mail Transfer Protocol client library for Ruby.}
12
17
  spec.description = %q{Simple Mail Transfer Protocol client library for Ruby.}
13
18
  spec.homepage = "https://github.com/ruby/net-smtp"
14
19
  spec.license = "BSD-2-Clause"
20
+ spec.required_ruby_version = ">= 2.5.0"
15
21
 
16
22
  spec.metadata["homepage_uri"] = spec.homepage
17
23
  spec.metadata["source_code_uri"] = spec.homepage
18
24
 
19
25
  spec.files = Dir.chdir(File.expand_path('..', __FILE__)) do
20
- `git ls-files -z`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
26
+ `git ls-files -z 2>/dev/null`.split("\x0").reject { |f| f.match(%r{^(test|spec|features)/}) }
21
27
  end
22
28
  spec.bindir = "exe"
23
29
  spec.executables = spec.files.grep(%r{^exe/}) { |f| File.basename(f) }
metadata CHANGED
@@ -1,32 +1,32 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-smtp
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.1.0
4
+ version: 0.2.0
5
5
  platform: ruby
6
6
  authors:
7
- - Hiroshi SHIBATA
8
- autorequire:
7
+ - Yukihiro Matsumoto
8
+ autorequire:
9
9
  bindir: exe
10
10
  cert_chain: []
11
- date: 2019-11-06 00:00:00.000000000 Z
11
+ date: 2020-11-14 00:00:00.000000000 Z
12
12
  dependencies: []
13
13
  description: Simple Mail Transfer Protocol client library for Ruby.
14
14
  email:
15
- - hsbt@ruby-lang.org
15
+ - matz@ruby-lang.org
16
16
  executables: []
17
17
  extensions: []
18
18
  extra_rdoc_files: []
19
19
  files:
20
+ - ".github/workflows/test.yml"
20
21
  - ".gitignore"
21
- - ".travis.yml"
22
22
  - Gemfile
23
23
  - LICENSE.txt
24
+ - NEWS.md
24
25
  - README.md
25
26
  - Rakefile
26
27
  - bin/console
27
28
  - bin/setup
28
29
  - lib/net/smtp.rb
29
- - lib/net/smtp/version.rb
30
30
  - net-smtp.gemspec
31
31
  homepage: https://github.com/ruby/net-smtp
32
32
  licenses:
@@ -34,7 +34,7 @@ licenses:
34
34
  metadata:
35
35
  homepage_uri: https://github.com/ruby/net-smtp
36
36
  source_code_uri: https://github.com/ruby/net-smtp
37
- post_install_message:
37
+ post_install_message:
38
38
  rdoc_options: []
39
39
  require_paths:
40
40
  - lib
@@ -42,15 +42,15 @@ required_ruby_version: !ruby/object:Gem::Requirement
42
42
  requirements:
43
43
  - - ">="
44
44
  - !ruby/object:Gem::Version
45
- version: '0'
45
+ version: 2.5.0
46
46
  required_rubygems_version: !ruby/object:Gem::Requirement
47
47
  requirements:
48
48
  - - ">="
49
49
  - !ruby/object:Gem::Version
50
50
  version: '0'
51
51
  requirements: []
52
- rubygems_version: 3.0.3
53
- signing_key:
52
+ rubygems_version: 3.2.0.rc.1
53
+ signing_key:
54
54
  specification_version: 4
55
55
  summary: Simple Mail Transfer Protocol client library for Ruby.
56
56
  test_files: []
@@ -1,7 +0,0 @@
1
- ---
2
- sudo: false
3
- language: ruby
4
- cache: bundler
5
- rvm:
6
- - 2.6.3
7
- before_install: gem install bundler -v 2.0.2
@@ -1,5 +0,0 @@
1
- module Net
2
- module SMTP
3
- VERSION = "0.1.0"
4
- end
5
- end