net-smtp 0.1.0 → 0.2.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: 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