net-imap 0.3.4 → 0.5.6

Sign up to get free protection for your applications and to get access to all the features.
Files changed (71) hide show
  1. checksums.yaml +4 -4
  2. data/BSDL +22 -0
  3. data/COPYING +56 -0
  4. data/Gemfile +14 -0
  5. data/LICENSE.txt +3 -22
  6. data/README.md +25 -8
  7. data/Rakefile +0 -7
  8. data/docs/styles.css +72 -23
  9. data/lib/net/imap/authenticators.rb +26 -57
  10. data/lib/net/imap/command_data.rb +74 -54
  11. data/lib/net/imap/config/attr_accessors.rb +75 -0
  12. data/lib/net/imap/config/attr_inheritance.rb +90 -0
  13. data/lib/net/imap/config/attr_type_coercion.rb +61 -0
  14. data/lib/net/imap/config.rb +470 -0
  15. data/lib/net/imap/data_encoding.rb +21 -9
  16. data/lib/net/imap/data_lite.rb +226 -0
  17. data/lib/net/imap/deprecated_client_options.rb +142 -0
  18. data/lib/net/imap/errors.rb +27 -1
  19. data/lib/net/imap/esearch_result.rb +180 -0
  20. data/lib/net/imap/fetch_data.rb +597 -0
  21. data/lib/net/imap/flags.rb +1 -1
  22. data/lib/net/imap/response_data.rb +250 -440
  23. data/lib/net/imap/response_parser/parser_utils.rb +245 -0
  24. data/lib/net/imap/response_parser.rb +1867 -1184
  25. data/lib/net/imap/sasl/anonymous_authenticator.rb +69 -0
  26. data/lib/net/imap/sasl/authentication_exchange.rb +139 -0
  27. data/lib/net/imap/sasl/authenticators.rb +122 -0
  28. data/lib/net/imap/sasl/client_adapter.rb +123 -0
  29. data/lib/net/imap/{authenticators/cram_md5.rb → sasl/cram_md5_authenticator.rb} +24 -14
  30. data/lib/net/imap/sasl/digest_md5_authenticator.rb +342 -0
  31. data/lib/net/imap/sasl/external_authenticator.rb +83 -0
  32. data/lib/net/imap/sasl/gs2_header.rb +80 -0
  33. data/lib/net/imap/{authenticators/login.rb → sasl/login_authenticator.rb} +28 -18
  34. data/lib/net/imap/sasl/oauthbearer_authenticator.rb +199 -0
  35. data/lib/net/imap/sasl/plain_authenticator.rb +101 -0
  36. data/lib/net/imap/sasl/protocol_adapters.rb +101 -0
  37. data/lib/net/imap/sasl/scram_algorithm.rb +58 -0
  38. data/lib/net/imap/sasl/scram_authenticator.rb +287 -0
  39. data/lib/net/imap/sasl/stringprep.rb +6 -66
  40. data/lib/net/imap/sasl/xoauth2_authenticator.rb +106 -0
  41. data/lib/net/imap/sasl.rb +148 -44
  42. data/lib/net/imap/sasl_adapter.rb +20 -0
  43. data/lib/net/imap/search_result.rb +146 -0
  44. data/lib/net/imap/sequence_set.rb +1565 -0
  45. data/lib/net/imap/stringprep/nameprep.rb +70 -0
  46. data/lib/net/imap/stringprep/saslprep.rb +69 -0
  47. data/lib/net/imap/stringprep/saslprep_tables.rb +96 -0
  48. data/lib/net/imap/stringprep/tables.rb +146 -0
  49. data/lib/net/imap/stringprep/trace.rb +85 -0
  50. data/lib/net/imap/stringprep.rb +159 -0
  51. data/lib/net/imap/uidplus_data.rb +244 -0
  52. data/lib/net/imap/vanished_data.rb +56 -0
  53. data/lib/net/imap.rb +2090 -823
  54. data/net-imap.gemspec +7 -8
  55. data/rakelib/benchmarks.rake +91 -0
  56. data/rakelib/rfcs.rake +2 -0
  57. data/rakelib/saslprep.rake +4 -4
  58. data/rakelib/string_prep_tables_generator.rb +84 -60
  59. data/sample/net-imap.rb +167 -0
  60. metadata +45 -49
  61. data/.github/dependabot.yml +0 -6
  62. data/.github/workflows/test.yml +0 -31
  63. data/.gitignore +0 -10
  64. data/benchmarks/stringprep.yml +0 -65
  65. data/benchmarks/table-regexps.yml +0 -39
  66. data/lib/net/imap/authenticators/digest_md5.rb +0 -115
  67. data/lib/net/imap/authenticators/plain.rb +0 -41
  68. data/lib/net/imap/authenticators/xoauth2.rb +0 -20
  69. data/lib/net/imap/sasl/saslprep.rb +0 -55
  70. data/lib/net/imap/sasl/saslprep_tables.rb +0 -98
  71. data/lib/net/imap/sasl/stringprep_tables.rb +0 -153
metadata CHANGED
@@ -1,15 +1,14 @@
1
1
  --- !ruby/object:Gem::Specification
2
2
  name: net-imap
3
3
  version: !ruby/object:Gem::Version
4
- version: 0.3.4
4
+ version: 0.5.6
5
5
  platform: ruby
6
6
  authors:
7
7
  - Shugo Maeda
8
8
  - nicholas a. evans
9
- autorequire:
10
9
  bindir: exe
11
10
  cert_chain: []
12
- date: 2022-12-23 00:00:00.000000000 Z
11
+ date: 2025-02-07 00:00:00.000000000 Z
13
12
  dependencies:
14
13
  - !ruby/object:Gem::Dependency
15
14
  name: net-protocol
@@ -39,75 +38,73 @@ dependencies:
39
38
  - - ">="
40
39
  - !ruby/object:Gem::Version
41
40
  version: '0'
42
- - !ruby/object:Gem::Dependency
43
- name: digest
44
- requirement: !ruby/object:Gem::Requirement
45
- requirements:
46
- - - ">="
47
- - !ruby/object:Gem::Version
48
- version: '0'
49
- type: :development
50
- prerelease: false
51
- version_requirements: !ruby/object:Gem::Requirement
52
- requirements:
53
- - - ">="
54
- - !ruby/object:Gem::Version
55
- version: '0'
56
- - !ruby/object:Gem::Dependency
57
- name: strscan
58
- requirement: !ruby/object:Gem::Requirement
59
- requirements:
60
- - - ">="
61
- - !ruby/object:Gem::Version
62
- version: '0'
63
- type: :development
64
- prerelease: false
65
- version_requirements: !ruby/object:Gem::Requirement
66
- requirements:
67
- - - ">="
68
- - !ruby/object:Gem::Version
69
- version: '0'
70
41
  description: Ruby client api for Internet Message Access Protocol
71
42
  email:
72
43
  - shugo@ruby-lang.org
73
- - nick@ekenosen.net
44
+ - nick@rubinick.dev
74
45
  executables: []
75
46
  extensions: []
76
47
  extra_rdoc_files: []
77
48
  files:
78
- - ".github/dependabot.yml"
79
- - ".github/workflows/test.yml"
80
- - ".gitignore"
49
+ - BSDL
50
+ - COPYING
81
51
  - Gemfile
82
52
  - LICENSE.txt
83
53
  - README.md
84
54
  - Rakefile
85
- - benchmarks/stringprep.yml
86
- - benchmarks/table-regexps.yml
87
55
  - docs/styles.css
88
56
  - lib/net/imap.rb
89
57
  - lib/net/imap/authenticators.rb
90
- - lib/net/imap/authenticators/cram_md5.rb
91
- - lib/net/imap/authenticators/digest_md5.rb
92
- - lib/net/imap/authenticators/login.rb
93
- - lib/net/imap/authenticators/plain.rb
94
- - lib/net/imap/authenticators/xoauth2.rb
95
58
  - lib/net/imap/command_data.rb
59
+ - lib/net/imap/config.rb
60
+ - lib/net/imap/config/attr_accessors.rb
61
+ - lib/net/imap/config/attr_inheritance.rb
62
+ - lib/net/imap/config/attr_type_coercion.rb
96
63
  - lib/net/imap/data_encoding.rb
64
+ - lib/net/imap/data_lite.rb
65
+ - lib/net/imap/deprecated_client_options.rb
97
66
  - lib/net/imap/errors.rb
67
+ - lib/net/imap/esearch_result.rb
68
+ - lib/net/imap/fetch_data.rb
98
69
  - lib/net/imap/flags.rb
99
70
  - lib/net/imap/response_data.rb
100
71
  - lib/net/imap/response_parser.rb
72
+ - lib/net/imap/response_parser/parser_utils.rb
101
73
  - lib/net/imap/sasl.rb
102
- - lib/net/imap/sasl/saslprep.rb
103
- - lib/net/imap/sasl/saslprep_tables.rb
74
+ - lib/net/imap/sasl/anonymous_authenticator.rb
75
+ - lib/net/imap/sasl/authentication_exchange.rb
76
+ - lib/net/imap/sasl/authenticators.rb
77
+ - lib/net/imap/sasl/client_adapter.rb
78
+ - lib/net/imap/sasl/cram_md5_authenticator.rb
79
+ - lib/net/imap/sasl/digest_md5_authenticator.rb
80
+ - lib/net/imap/sasl/external_authenticator.rb
81
+ - lib/net/imap/sasl/gs2_header.rb
82
+ - lib/net/imap/sasl/login_authenticator.rb
83
+ - lib/net/imap/sasl/oauthbearer_authenticator.rb
84
+ - lib/net/imap/sasl/plain_authenticator.rb
85
+ - lib/net/imap/sasl/protocol_adapters.rb
86
+ - lib/net/imap/sasl/scram_algorithm.rb
87
+ - lib/net/imap/sasl/scram_authenticator.rb
104
88
  - lib/net/imap/sasl/stringprep.rb
105
- - lib/net/imap/sasl/stringprep_tables.rb
89
+ - lib/net/imap/sasl/xoauth2_authenticator.rb
90
+ - lib/net/imap/sasl_adapter.rb
91
+ - lib/net/imap/search_result.rb
92
+ - lib/net/imap/sequence_set.rb
93
+ - lib/net/imap/stringprep.rb
94
+ - lib/net/imap/stringprep/nameprep.rb
95
+ - lib/net/imap/stringprep/saslprep.rb
96
+ - lib/net/imap/stringprep/saslprep_tables.rb
97
+ - lib/net/imap/stringprep/tables.rb
98
+ - lib/net/imap/stringprep/trace.rb
99
+ - lib/net/imap/uidplus_data.rb
100
+ - lib/net/imap/vanished_data.rb
106
101
  - net-imap.gemspec
102
+ - rakelib/benchmarks.rake
107
103
  - rakelib/rdoc.rake
108
104
  - rakelib/rfcs.rake
109
105
  - rakelib/saslprep.rake
110
106
  - rakelib/string_prep_tables_generator.rb
107
+ - sample/net-imap.rb
111
108
  homepage: https://github.com/ruby/net-imap
112
109
  licenses:
113
110
  - Ruby
@@ -115,7 +112,7 @@ licenses:
115
112
  metadata:
116
113
  homepage_uri: https://github.com/ruby/net-imap
117
114
  source_code_uri: https://github.com/ruby/net-imap
118
- post_install_message:
115
+ changelog_uri: https://github.com/ruby/net-imap/releases
119
116
  rdoc_options: []
120
117
  require_paths:
121
118
  - lib
@@ -123,15 +120,14 @@ required_ruby_version: !ruby/object:Gem::Requirement
123
120
  requirements:
124
121
  - - ">="
125
122
  - !ruby/object:Gem::Version
126
- version: 2.6.0
123
+ version: 3.1.0
127
124
  required_rubygems_version: !ruby/object:Gem::Requirement
128
125
  requirements:
129
126
  - - ">="
130
127
  - !ruby/object:Gem::Version
131
128
  version: '0'
132
129
  requirements: []
133
- rubygems_version: 3.4.0.dev
134
- signing_key:
130
+ rubygems_version: 3.6.2
135
131
  specification_version: 4
136
132
  summary: Ruby client api for Internet Message Access Protocol
137
133
  test_files: []
@@ -1,6 +0,0 @@
1
- version: 2
2
- updates:
3
- - package-ecosystem: 'github-actions'
4
- directory: '/'
5
- schedule:
6
- interval: 'weekly'
@@ -1,31 +0,0 @@
1
- name: ubuntu
2
-
3
- on: [push, pull_request]
4
-
5
- jobs:
6
- build:
7
- name: build (${{ matrix.ruby }} / ${{ matrix.os }})
8
- strategy:
9
- matrix:
10
- ruby: [ head, '3.1', '3.0', '2.7' ]
11
- os: [ ubuntu-latest, macos-latest ]
12
- experimental: [false]
13
- include:
14
- # - ruby: 2.6
15
- # os: ubuntu-latest
16
- # experimental: true
17
- - ruby: 2.6
18
- os: macos-latest
19
- experimental: false
20
- runs-on: ${{ matrix.os }}
21
- continue-on-error: ${{ matrix.experimental }}
22
- steps:
23
- - uses: actions/checkout@v3
24
- - name: Set up Ruby
25
- uses: ruby/setup-ruby@v1
26
- with:
27
- ruby-version: ${{ matrix.ruby }}
28
- - name: Install dependencies
29
- run: bundle install
30
- - name: Run test
31
- run: rake test
data/.gitignore DELETED
@@ -1,10 +0,0 @@
1
- /.bundle/
2
- /.yardoc
3
- /_yardoc/
4
- /coverage/
5
- /doc/
6
- /pkg/
7
- /rfcs
8
- /spec/reports/
9
- /tmp/
10
- /Gemfile.lock
@@ -1,65 +0,0 @@
1
- ---
2
- prelude: |
3
- begin
4
- require "mongo" # gem install mongo
5
- require "idn" # gem install idn-ruby
6
- rescue LoadError
7
- warn "You must 'gem install mongo idn-ruby' for this benchmark."
8
- raise
9
- end
10
-
11
- MStrPrep = Mongo::Auth::StringPrep
12
-
13
- # this indirection will slow it down a little bit
14
- def mongo_saslprep(string)
15
- MStrPrep.prepare(string,
16
- MStrPrep::Profiles::SASL::MAPPINGS,
17
- MStrPrep::Profiles::SASL::PROHIBITED,
18
- normalize: true,
19
- bidi: true)
20
- rescue Mongo::Error::FailedStringPrepValidation
21
- nil
22
- end
23
-
24
- $LOAD_PATH.unshift "./lib"
25
- require "net/imap"
26
- def net_imap_saslprep(string)
27
- Net::IMAP::SASL::SASLprep.saslprep string, exception: false
28
- end
29
-
30
- def libidn_saslprep(string)
31
- IDN::Stringprep.with_profile(string, "SASLprep")
32
- rescue IDN::Stringprep::StringprepError
33
- nil
34
- end
35
-
36
- benchmark:
37
- - net_imap_saslprep "I\u00ADX" # RFC example 1. IX
38
- - net_imap_saslprep "user" # RFC example 2. user
39
- - net_imap_saslprep "USER" # RFC example 3. user
40
- - net_imap_saslprep "\u00aa" # RFC example 4. a
41
- - net_imap_saslprep "\u2168" # RFC example 5. IX
42
- - net_imap_saslprep "\u0007" # RFC example 6. Error - prohibited character
43
- - net_imap_saslprep "\u0627\u0031" # RFC example 7. Error - bidirectional check
44
- - net_imap_saslprep "I\u2000X" # map to space: I X
45
- - net_imap_saslprep "a longer string, e.g. a password"
46
-
47
- - libidn_saslprep "I\u00ADX" # RFC example 1. IX
48
- - libidn_saslprep "user" # RFC example 2. user
49
- - libidn_saslprep "USER" # RFC example 3. user
50
- - libidn_saslprep "\u00aa" # RFC example 4. a
51
- - libidn_saslprep "\u2168" # RFC example 5. IX
52
- - libidn_saslprep "\u0007" # RFC example 6. Error - prohibited character
53
- - libidn_saslprep "\u0627\u0031" # RFC example 7. Error - bidirectional check
54
- - libidn_saslprep "I\u2000X" # map to space: I X
55
- - libidn_saslprep "a longer string, e.g. a password"
56
-
57
- - mongo_saslprep "I\u00ADX" # RFC example 1. IX
58
- - mongo_saslprep "user" # RFC example 2. user
59
- - mongo_saslprep "USER" # RFC example 3. user
60
- - mongo_saslprep "\u00aa" # RFC example 4. a
61
- - mongo_saslprep "\u2168" # RFC example 5. IX
62
- - mongo_saslprep "\u0007" # RFC example 6. Error - prohibited character
63
- - mongo_saslprep "\u0627\u0031" # RFC example 7. Error - bidirectional check
64
- - mongo_saslprep "I\u2000X" # map to space: I X
65
- - mongo_saslprep "a longer string, e.g. a password"
@@ -1,39 +0,0 @@
1
- prelude: |
2
- require "json"
3
- require "set"
4
-
5
- all_codepoints = (0..0x10ffff).map{_1.chr("UTF-8") rescue nil}.compact
6
-
7
- rfc3454_tables = Dir["rfcs/rfc3454*.json"]
8
- .first
9
- .then{File.read _1}
10
- .then{JSON.parse _1}
11
- titles = rfc3454_tables.delete("titles")
12
-
13
- sets = rfc3454_tables
14
- .transform_values{|t|t.keys rescue t}
15
- .transform_values{|table|
16
- table
17
- .map{_1.split(?-).map{|i|Integer i, 16}}
18
- .flat_map{_2 ? (_1.._2).to_a : _1}
19
- .to_set
20
- }
21
-
22
- TABLE_A1_SET = sets.fetch "A.1"
23
- ASSIGNED_3_2 = /\p{AGE=3.2}/
24
- UNASSIGNED_3_2 = /\P{AGE=3.2}/
25
- TABLE_A1_REGEX = /(?-mix:[\u{0000}-\u{001f}\u{007f}-\u{00a0}\u{0340}-\u{0341}\u{06dd}\u{070f}\u{1680}\u{180e}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{3000}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{feff}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0001}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}])|(?-mix:\p{Cs})/.freeze
26
-
27
- benchmark:
28
-
29
- # matches A.1
30
- - script: "all_codepoints.grep(TABLE_A1_SET)"
31
- - script: "all_codepoints.grep(TABLE_A1_REGEX)"
32
- - script: "all_codepoints.grep(UNASSIGNED_3_2)"
33
- - script: "all_codepoints.grep_v(ASSIGNED_3_2)"
34
-
35
- # doesn't match A.1
36
- - script: "all_codepoints.grep_v(TABLE_A1_SET)"
37
- - script: "all_codepoints.grep_v(TABLE_A1_REGEX)"
38
- - script: "all_codepoints.grep_v(UNASSIGNED_3_2)"
39
- - script: "all_codepoints.grep(ASSIGNED_3_2)"
@@ -1,115 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Net::IMAP authenticator for the "`DIGEST-MD5`" SASL mechanism type, specified
4
- # in RFC2831(https://tools.ietf.org/html/rfc2831). See Net::IMAP#authenticate.
5
- #
6
- # == Deprecated
7
- #
8
- # "+DIGEST-MD5+" has been deprecated by
9
- # {RFC6331}[https://tools.ietf.org/html/rfc6331] and should not be relied on for
10
- # security. It is included for compatibility with existing servers.
11
- class Net::IMAP::DigestMD5Authenticator
12
- def process(challenge)
13
- case @stage
14
- when STAGE_ONE
15
- @stage = STAGE_TWO
16
- sparams = {}
17
- c = StringScanner.new(challenge)
18
- while c.scan(/(?:\s*,)?\s*(\w+)=("(?:[^\\"]+|\\.)*"|[^,]+)\s*/)
19
- k, v = c[1], c[2]
20
- if v =~ /^"(.*)"$/
21
- v = $1
22
- if v =~ /,/
23
- v = v.split(',')
24
- end
25
- end
26
- sparams[k] = v
27
- end
28
-
29
- raise Net::IMAP::DataFormatError, "Bad Challenge: '#{challenge}'" unless c.eos?
30
- raise Net::IMAP::Error, "Server does not support auth (qop = #{sparams['qop'].join(',')})" unless sparams['qop'].include?("auth")
31
-
32
- response = {
33
- :nonce => sparams['nonce'],
34
- :username => @user,
35
- :realm => sparams['realm'],
36
- :cnonce => Digest::MD5.hexdigest("%.15f:%.15f:%d" % [Time.now.to_f, rand, Process.pid.to_s]),
37
- :'digest-uri' => 'imap/' + sparams['realm'],
38
- :qop => 'auth',
39
- :maxbuf => 65535,
40
- :nc => "%08d" % nc(sparams['nonce']),
41
- :charset => sparams['charset'],
42
- }
43
-
44
- response[:authzid] = @authname unless @authname.nil?
45
-
46
- # now, the real thing
47
- a0 = Digest::MD5.digest( [ response.values_at(:username, :realm), @password ].join(':') )
48
-
49
- a1 = [ a0, response.values_at(:nonce,:cnonce) ].join(':')
50
- a1 << ':' + response[:authzid] unless response[:authzid].nil?
51
-
52
- a2 = "AUTHENTICATE:" + response[:'digest-uri']
53
- a2 << ":00000000000000000000000000000000" if response[:qop] and response[:qop] =~ /^auth-(?:conf|int)$/
54
-
55
- response[:response] = Digest::MD5.hexdigest(
56
- [
57
- Digest::MD5.hexdigest(a1),
58
- response.values_at(:nonce, :nc, :cnonce, :qop),
59
- Digest::MD5.hexdigest(a2)
60
- ].join(':')
61
- )
62
-
63
- return response.keys.map {|key| qdval(key.to_s, response[key]) }.join(',')
64
- when STAGE_TWO
65
- @stage = nil
66
- # if at the second stage, return an empty string
67
- if challenge =~ /rspauth=/
68
- return ''
69
- else
70
- raise ResponseParseError, challenge
71
- end
72
- else
73
- raise ResponseParseError, challenge
74
- end
75
- end
76
-
77
- def initialize(user, password, authname = nil, warn_deprecation: true)
78
- if warn_deprecation
79
- warn "WARNING: DIGEST-MD5 SASL mechanism was deprecated by RFC6331."
80
- # TODO: recommend SCRAM instead.
81
- end
82
- require "digest/md5"
83
- require "strscan"
84
- @user, @password, @authname = user, password, authname
85
- @nc, @stage = {}, STAGE_ONE
86
- end
87
-
88
-
89
- private
90
-
91
- STAGE_ONE = :stage_one
92
- STAGE_TWO = :stage_two
93
-
94
- def nc(nonce)
95
- if @nc.has_key? nonce
96
- @nc[nonce] = @nc[nonce] + 1
97
- else
98
- @nc[nonce] = 1
99
- end
100
- return @nc[nonce]
101
- end
102
-
103
- # some responses need quoting
104
- def qdval(k, v)
105
- return if k.nil? or v.nil?
106
- if %w"username authzid realm nonce cnonce digest-uri qop".include? k
107
- v = v.gsub(/([\\"])/, "\\\1")
108
- return '%s="%s"' % [k, v]
109
- else
110
- return '%s=%s' % [k, v]
111
- end
112
- end
113
-
114
- Net::IMAP.add_authenticator "DIGEST-MD5", self
115
- end
@@ -1,41 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- # Authenticator for the "+PLAIN+" SASL mechanism, specified in
4
- # RFC4616[https://tools.ietf.org/html/rfc4616]. See Net::IMAP#authenticate.
5
- #
6
- # +PLAIN+ authentication sends the password in cleartext.
7
- # RFC3501[https://tools.ietf.org/html/rfc3501] encourages servers to disable
8
- # cleartext authentication until after TLS has been negotiated.
9
- # RFC8314[https://tools.ietf.org/html/rfc8314] recommends TLS version 1.2 or
10
- # greater be used for all traffic, and deprecate cleartext access ASAP. +PLAIN+
11
- # can be secured by TLS encryption.
12
- class Net::IMAP::PlainAuthenticator
13
-
14
- def process(data)
15
- return "#@authzid\0#@username\0#@password"
16
- end
17
-
18
- # :nodoc:
19
- NULL = -"\0".b
20
-
21
- private
22
-
23
- # +username+ is the authentication identity, the identity whose +password+ is
24
- # used. +username+ is referred to as +authcid+ by
25
- # RFC4616[https://tools.ietf.org/html/rfc4616].
26
- #
27
- # +authzid+ is the authorization identity (identity to act as). It can
28
- # usually be left blank. When +authzid+ is left blank (nil or empty string)
29
- # the server will derive an identity from the credentials and use that as the
30
- # authorization identity.
31
- def initialize(username, password, authzid: nil)
32
- raise ArgumentError, "username contains NULL" if username&.include?(NULL)
33
- raise ArgumentError, "password contains NULL" if password&.include?(NULL)
34
- raise ArgumentError, "authzid contains NULL" if authzid&.include?(NULL)
35
- @username = username
36
- @password = password
37
- @authzid = authzid
38
- end
39
-
40
- Net::IMAP.add_authenticator "PLAIN", self
41
- end
@@ -1,20 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- class Net::IMAP::XOauth2Authenticator
4
- def process(_data)
5
- build_oauth2_string(@user, @oauth2_token)
6
- end
7
-
8
- private
9
-
10
- def initialize(user, oauth2_token)
11
- @user = user
12
- @oauth2_token = oauth2_token
13
- end
14
-
15
- def build_oauth2_string(user, oauth2_token)
16
- format("user=%s\1auth=Bearer %s\1\1", user, oauth2_token)
17
- end
18
-
19
- Net::IMAP.add_authenticator 'XOAUTH2', self
20
- end
@@ -1,55 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- require_relative "saslprep_tables"
4
-
5
- module Net::IMAP::SASL
6
-
7
- # SASLprep#saslprep can be used to prepare a string according to [RFC4013].
8
- #
9
- # \SASLprep maps characters three ways: to nothing, to space, and Unicode
10
- # normalization form KC. \SASLprep prohibits codepoints from nearly all
11
- # standard StringPrep tables (RFC3454, Appendix "C"), and uses \StringPrep's
12
- # standard bidirectional characters requirements (Appendix "D"). \SASLprep
13
- # also uses \StringPrep's definition of "Unassigned" codepoints (Appendix "A").
14
- module SASLprep
15
-
16
- # Used to short-circuit strings that don't need preparation.
17
- ASCII_NO_CTRLS = /\A[\x20-\x7e]*\z/u.freeze
18
-
19
- module_function
20
-
21
- # Prepares a UTF-8 +string+ for comparison, using the \SASLprep profile
22
- # RFC4013 of the StringPrep algorithm RFC3454.
23
- #
24
- # By default, prohibited strings will return +nil+. When +exception+ is
25
- # +true+, a StringPrepError describing the violation will be raised.
26
- #
27
- # When +stored+ is +true+, "unassigned" codepoints will be prohibited. For
28
- # \StringPrep and the \SASLprep profile, "unassigned" refers to Unicode 3.2,
29
- # and not later versions. See RFC3454 §7 for more information.
30
- #
31
- def saslprep(str, stored: false, exception: false)
32
- return str if ASCII_NO_CTRLS.match?(str) # raises on incompatible encoding
33
- str = str.encode("UTF-8") # also dups (and raises for invalid encoding)
34
- str.gsub!(MAP_TO_SPACE, " ")
35
- str.gsub!(MAP_TO_NOTHING, "")
36
- str.unicode_normalize!(:nfkc)
37
- # These regexps combine the prohibited and bidirectional checks
38
- return str unless str.match?(stored ? PROHIBITED_STORED : PROHIBITED)
39
- return nil unless exception
40
- # raise helpful errors to indicate *why* it failed:
41
- tables = stored ? TABLES_PROHIBITED_STORED : TABLES_PROHIBITED
42
- StringPrep.check_prohibited! str, *tables, bidi: true, profile: "SASLprep"
43
- raise StringPrep::InvalidStringError.new(
44
- "unknown error", string: string, profile: "SASLprep"
45
- )
46
- rescue ArgumentError, Encoding::CompatibilityError => ex
47
- if /invalid byte sequence|incompatible encoding/.match? ex.message
48
- return nil unless exception
49
- raise StringPrepError.new(ex.message, string: str, profile: "saslprep")
50
- end
51
- raise ex
52
- end
53
-
54
- end
55
- end
@@ -1,98 +0,0 @@
1
- # frozen_string_literal: true
2
-
3
- #--
4
- # This file is generated from RFC3454, by rake. Don't edit directly.
5
- #++
6
-
7
- module Net::IMAP::SASL
8
-
9
- module SASLprep
10
-
11
- # RFC4013 §2.1 Mapping - mapped to space
12
- # * non-ASCII space characters (\StringPrep\[\"C.1.2\"]) that can be
13
- # mapped to SPACE (U+0020), and
14
- #
15
- # Equal to \StringPrep\[\"C.1.2\"].
16
- # Redefined here to avoid loading the StringPrep module.
17
- MAP_TO_SPACE = /[\u200b\p{Zs}&&[^ ]]/.freeze
18
-
19
- # RFC4013 §2.1 Mapping - mapped to nothing
20
- # the "commonly mapped to nothing" characters (\StringPrep\[\"B.1\"])
21
- # that can be mapped to nothing.
22
- #
23
- # Equal to \StringPrep\[\"B.1\"].
24
- # Redefined here to avoid loading the StringPrep module.
25
- MAP_TO_NOTHING = /[\u{00ad 034f 1806 2060 feff}\u{180b}-\u{180d}\u{200b}-\u{200d}\u{fe00}-\u{fe0f}]/.freeze
26
-
27
- # RFC4013 §2.3 Prohibited Output::
28
- # * Non-ASCII space characters — \StringPrep\[\"C.1.2\"]
29
- # * ASCII control characters — \StringPrep\[\"C.2.1\"]
30
- # * Non-ASCII control characters — \StringPrep\[\"C.2.2\"]
31
- # * Private Use characters — \StringPrep\[\"C.3\"]
32
- # * Non-character code points — \StringPrep\[\"C.4\"]
33
- # * Surrogate code points — \StringPrep\[\"C.5\"]
34
- # * Inappropriate for plain text characters — \StringPrep\[\"C.6\"]
35
- # * Inappropriate for canonical representation characters — \StringPrep\[\"C.7\"]
36
- # * Change display properties or deprecated characters — \StringPrep\[\"C.8\"]
37
- # * Tagging characters — \StringPrep\[\"C.9\"]
38
- TABLES_PROHIBITED = ["C.1.2", "C.2.1", "C.2.2", "C.3", "C.4", "C.5", "C.6", "C.7", "C.8", "C.9"].freeze
39
-
40
- # Adds unassigned (by Unicode 3.2) codepoints to TABLES_PROHIBITED.
41
- #
42
- # RFC4013 §2.5 Unassigned Code Points::
43
- # This profile specifies the \StringPrep\[\"A.1\"] table as its list of
44
- # unassigned code points.
45
- TABLES_PROHIBITED_STORED = ["A.1", *TABLES_PROHIBITED].freeze
46
-
47
- # Matches codepoints prohibited by RFC4013 §2.3.
48
- #
49
- # See TABLES_PROHIBITED.
50
- #
51
- # Equal to +Regexp.union+ of the TABLES_PROHIBITED tables. Redefined
52
- # here to avoid loading the StringPrep module unless necessary.
53
- PROHIBITED_OUTPUT = /[\u{06dd 070f 1680 180e 3000 feff e0001}\u{0000}-\u{001f}\u{007f}-\u{00a0}\u{0340}-\u{0341}\u{2000}-\u{200f}\u{2028}-\u{202f}\u{205f}-\u{2063}\u{206a}-\u{206f}\u{2ff0}-\u{2ffb}\u{e000}-\u{f8ff}\u{fdd0}-\u{fdef}\u{fff9}-\u{ffff}\u{1d173}-\u{1d17a}\u{1fffe}-\u{1ffff}\u{2fffe}-\u{2ffff}\u{3fffe}-\u{3ffff}\u{4fffe}-\u{4ffff}\u{5fffe}-\u{5ffff}\u{6fffe}-\u{6ffff}\u{7fffe}-\u{7ffff}\u{8fffe}-\u{8ffff}\u{9fffe}-\u{9ffff}\u{afffe}-\u{affff}\u{bfffe}-\u{bffff}\u{cfffe}-\u{cffff}\u{dfffe}-\u{dffff}\u{e0020}-\u{e007f}\u{efffe}-\u{10ffff}\p{Cs}]/.freeze
54
-
55
- # RFC4013 §2.5 Unassigned Code Points::
56
- # This profile specifies the \StringPrep\[\"A.1\"] table as its list of
57
- # unassigned code points.
58
- UNASSIGNED = /\p{^AGE=3.2}/.freeze
59
-
60
- # Matches codepoints prohibited by RFC4013 §2.3 and §2.5.
61
- #
62
- # See TABLES_PROHIBITED_STORED.
63
- PROHIBITED_OUTPUT_STORED = Regexp.union(
64
- UNASSIGNED, PROHIBITED_OUTPUT
65
- ).freeze
66
-
67
- # Bidirectional Characters [StringPrep, §6]
68
- BIDI_FAILURE = /(?mx-i: # RandALCat followed by LCat
69
- (?<r_and_al_cat>[\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}])
70
- .*?
71
- (?<l_cat>[\u{00aa 00b5 00ba 02ee 037a 0386 038c 0589 0903 0950 09b2 09d7 0a5e 0a83 0a8d 0ac9 0ad0 0ae0 0b40 0b57 0b83 0b9c 0bd7 0cbe 0cde 0d57 0dbd 0e84 0e8a 0e8d 0ea5 0ea7 0ebd 0ec6 0f36 0f38 0f7f 0f85 0fcf 102c 1031 1038 10fb 1248 1258 1288 12b0 12c0 1310 17dc 1f59 1f5b 1f5d 1fbe 200e 2071 207f 2102 2107 2115 2124 2126 2128 2395 1d4a2 1d4bb 1d546}\u{0041}-\u{005a}\u{0061}-\u{007a}\u{00c0}-\u{00d6}\u{00d8}-\u{00f6}\u{00f8}-\u{0220}\u{0222}-\u{0233}\u{0250}-\u{02ad}\u{02b0}-\u{02b8}\u{02bb}-\u{02c1}\u{02d0}-\u{02d1}\u{02e0}-\u{02e4}\u{0388}-\u{038a}\u{038e}-\u{03a1}\u{03a3}-\u{03ce}\u{03d0}-\u{03f5}\u{0400}-\u{0482}\u{048a}-\u{04ce}\u{04d0}-\u{04f5}\u{04f8}-\u{04f9}\u{0500}-\u{050f}\u{0531}-\u{0556}\u{0559}-\u{055f}\u{0561}-\u{0587}\u{0905}-\u{0939}\u{093d}-\u{0940}\u{0949}-\u{094c}\u{0958}-\u{0961}\u{0964}-\u{0970}\u{0982}-\u{0983}\u{0985}-\u{098c}\u{098f}-\u{0990}\u{0993}-\u{09a8}\u{09aa}-\u{09b0}\u{09b6}-\u{09b9}\u{09be}-\u{09c0}\u{09c7}-\u{09c8}\u{09cb}-\u{09cc}\u{09dc}-\u{09dd}\u{09df}-\u{09e1}\u{09e6}-\u{09f1}\u{09f4}-\u{09fa}\u{0a05}-\u{0a0a}\u{0a0f}-\u{0a10}\u{0a13}-\u{0a28}\u{0a2a}-\u{0a30}\u{0a32}-\u{0a33}\u{0a35}-\u{0a36}\u{0a38}-\u{0a39}\u{0a3e}-\u{0a40}\u{0a59}-\u{0a5c}\u{0a66}-\u{0a6f}\u{0a72}-\u{0a74}\u{0a85}-\u{0a8b}\u{0a8f}-\u{0a91}\u{0a93}-\u{0aa8}\u{0aaa}-\u{0ab0}\u{0ab2}-\u{0ab3}\u{0ab5}-\u{0ab9}\u{0abd}-\u{0ac0}\u{0acb}-\u{0acc}\u{0ae6}-\u{0aef}\u{0b02}-\u{0b03}\u{0b05}-\u{0b0c}\u{0b0f}-\u{0b10}\u{0b13}-\u{0b28}\u{0b2a}-\u{0b30}\u{0b32}-\u{0b33}\u{0b36}-\u{0b39}\u{0b3d}-\u{0b3e}\u{0b47}-\u{0b48}\u{0b4b}-\u{0b4c}\u{0b5c}-\u{0b5d}\u{0b5f}-\u{0b61}\u{0b66}-\u{0b70}\u{0b85}-\u{0b8a}\u{0b8e}-\u{0b90}\u{0b92}-\u{0b95}\u{0b99}-\u{0b9a}\u{0b9e}-\u{0b9f}\u{0ba3}-\u{0ba4}\u{0ba8}-\u{0baa}\u{0bae}-\u{0bb5}\u{0bb7}-\u{0bb9}\u{0bbe}-\u{0bbf}\u{0bc1}-\u{0bc2}\u{0bc6}-\u{0bc8}\u{0bca}-\u{0bcc}\u{0be7}-\u{0bf2}\u{0c01}-\u{0c03}\u{0c05}-\u{0c0c}\u{0c0e}-\u{0c10}\u{0c12}-\u{0c28}\u{0c2a}-\u{0c33}\u{0c35}-\u{0c39}\u{0c41}-\u{0c44}\u{0c60}-\u{0c61}\u{0c66}-\u{0c6f}\u{0c82}-\u{0c83}\u{0c85}-\u{0c8c}\u{0c8e}-\u{0c90}\u{0c92}-\u{0ca8}\u{0caa}-\u{0cb3}\u{0cb5}-\u{0cb9}\u{0cc0}-\u{0cc4}\u{0cc7}-\u{0cc8}\u{0cca}-\u{0ccb}\u{0cd5}-\u{0cd6}\u{0ce0}-\u{0ce1}\u{0ce6}-\u{0cef}\u{0d02}-\u{0d03}\u{0d05}-\u{0d0c}\u{0d0e}-\u{0d10}\u{0d12}-\u{0d28}\u{0d2a}-\u{0d39}\u{0d3e}-\u{0d40}\u{0d46}-\u{0d48}\u{0d4a}-\u{0d4c}\u{0d60}-\u{0d61}\u{0d66}-\u{0d6f}\u{0d82}-\u{0d83}\u{0d85}-\u{0d96}\u{0d9a}-\u{0db1}\u{0db3}-\u{0dbb}\u{0dc0}-\u{0dc6}\u{0dcf}-\u{0dd1}\u{0dd8}-\u{0ddf}\u{0df2}-\u{0df4}\u{0e01}-\u{0e30}\u{0e32}-\u{0e33}\u{0e40}-\u{0e46}\u{0e4f}-\u{0e5b}\u{0e81}-\u{0e82}\u{0e87}-\u{0e88}\u{0e94}-\u{0e97}\u{0e99}-\u{0e9f}\u{0ea1}-\u{0ea3}\u{0eaa}-\u{0eab}\u{0ead}-\u{0eb0}\u{0eb2}-\u{0eb3}\u{0ec0}-\u{0ec4}\u{0ed0}-\u{0ed9}\u{0edc}-\u{0edd}\u{0f00}-\u{0f17}\u{0f1a}-\u{0f34}\u{0f3e}-\u{0f47}\u{0f49}-\u{0f6a}\u{0f88}-\u{0f8b}\u{0fbe}-\u{0fc5}\u{0fc7}-\u{0fcc}\u{1000}-\u{1021}\u{1023}-\u{1027}\u{1029}-\u{102a}\u{1040}-\u{1057}\u{10a0}-\u{10c5}\u{10d0}-\u{10f8}\u{1100}-\u{1159}\u{115f}-\u{11a2}\u{11a8}-\u{11f9}\u{1200}-\u{1206}\u{1208}-\u{1246}\u{124a}-\u{124d}\u{1250}-\u{1256}\u{125a}-\u{125d}\u{1260}-\u{1286}\u{128a}-\u{128d}\u{1290}-\u{12ae}\u{12b2}-\u{12b5}\u{12b8}-\u{12be}\u{12c2}-\u{12c5}\u{12c8}-\u{12ce}\u{12d0}-\u{12d6}\u{12d8}-\u{12ee}\u{12f0}-\u{130e}\u{1312}-\u{1315}\u{1318}-\u{131e}\u{1320}-\u{1346}\u{1348}-\u{135a}\u{1361}-\u{137c}\u{13a0}-\u{13f4}\u{1401}-\u{1676}\u{1681}-\u{169a}\u{16a0}-\u{16f0}\u{1700}-\u{170c}\u{170e}-\u{1711}\u{1720}-\u{1731}\u{1735}-\u{1736}\u{1740}-\u{1751}\u{1760}-\u{176c}\u{176e}-\u{1770}\u{1780}-\u{17b6}\u{17be}-\u{17c5}\u{17c7}-\u{17c8}\u{17d4}-\u{17da}\u{17e0}-\u{17e9}\u{1810}-\u{1819}\u{1820}-\u{1877}\u{1880}-\u{18a8}\u{1e00}-\u{1e9b}\u{1ea0}-\u{1ef9}\u{1f00}-\u{1f15}\u{1f18}-\u{1f1d}\u{1f20}-\u{1f45}\u{1f48}-\u{1f4d}\u{1f50}-\u{1f57}\u{1f5f}-\u{1f7d}\u{1f80}-\u{1fb4}\u{1fb6}-\u{1fbc}\u{1fc2}-\u{1fc4}\u{1fc6}-\u{1fcc}\u{1fd0}-\u{1fd3}\u{1fd6}-\u{1fdb}\u{1fe0}-\u{1fec}\u{1ff2}-\u{1ff4}\u{1ff6}-\u{1ffc}\u{210a}-\u{2113}\u{2119}-\u{211d}\u{212a}-\u{212d}\u{212f}-\u{2131}\u{2133}-\u{2139}\u{213d}-\u{213f}\u{2145}-\u{2149}\u{2160}-\u{2183}\u{2336}-\u{237a}\u{249c}-\u{24e9}\u{3005}-\u{3007}\u{3021}-\u{3029}\u{3031}-\u{3035}\u{3038}-\u{303c}\u{3041}-\u{3096}\u{309d}-\u{309f}\u{30a1}-\u{30fa}\u{30fc}-\u{30ff}\u{3105}-\u{312c}\u{3131}-\u{318e}\u{3190}-\u{31b7}\u{31f0}-\u{321c}\u{3220}-\u{3243}\u{3260}-\u{327b}\u{327f}-\u{32b0}\u{32c0}-\u{32cb}\u{32d0}-\u{32fe}\u{3300}-\u{3376}\u{337b}-\u{33dd}\u{33e0}-\u{33fe}\u{3400}-\u{4db5}\u{4e00}-\u{9fa5}\u{a000}-\u{a48c}\u{ac00}-\u{d7a3}\u{e000}-\u{fa2d}\u{fa30}-\u{fa6a}\u{fb00}-\u{fb06}\u{fb13}-\u{fb17}\u{ff21}-\u{ff3a}\u{ff41}-\u{ff5a}\u{ff66}-\u{ffbe}\u{ffc2}-\u{ffc7}\u{ffca}-\u{ffcf}\u{ffd2}-\u{ffd7}\u{ffda}-\u{ffdc}\u{10300}-\u{1031e}\u{10320}-\u{10323}\u{10330}-\u{1034a}\u{10400}-\u{10425}\u{10428}-\u{1044d}\u{1d000}-\u{1d0f5}\u{1d100}-\u{1d126}\u{1d12a}-\u{1d166}\u{1d16a}-\u{1d172}\u{1d183}-\u{1d184}\u{1d18c}-\u{1d1a9}\u{1d1ae}-\u{1d1dd}\u{1d400}-\u{1d454}\u{1d456}-\u{1d49c}\u{1d49e}-\u{1d49f}\u{1d4a5}-\u{1d4a6}\u{1d4a9}-\u{1d4ac}\u{1d4ae}-\u{1d4b9}\u{1d4bd}-\u{1d4c0}\u{1d4c2}-\u{1d4c3}\u{1d4c5}-\u{1d505}\u{1d507}-\u{1d50a}\u{1d50d}-\u{1d514}\u{1d516}-\u{1d51c}\u{1d51e}-\u{1d539}\u{1d53b}-\u{1d53e}\u{1d540}-\u{1d544}\u{1d54a}-\u{1d550}\u{1d552}-\u{1d6a3}\u{1d6a8}-\u{1d7c9}\u{20000}-\u{2a6d6}\u{2f800}-\u{2fa1d}\u{f0000}-\u{ffffd}\u{100000}-\u{10fffd}\p{Cs}])
72
- | # RandALCat preceded by LCat
73
- \g<l_cat> .*? \g<r_and_al_cat>
74
- ) | (?mx-i: # contains RandALCat but doesn't start with RandALCat
75
- \A(?<not_r_nor_al>(?-mix:[^\u{05be 05c0 05c3 061b 061f 06dd 0710 07b1 200f fb1d fb3e}\u{05d0}-\u{05ea}\u{05f0}-\u{05f4}\u{0621}-\u{063a}\u{0640}-\u{064a}\u{066d}-\u{066f}\u{0671}-\u{06d5}\u{06e5}-\u{06e6}\u{06fa}-\u{06fe}\u{0700}-\u{070d}\u{0712}-\u{072c}\u{0780}-\u{07a5}\u{fb1f}-\u{fb28}\u{fb2a}-\u{fb36}\u{fb38}-\u{fb3c}\u{fb40}-\u{fb41}\u{fb43}-\u{fb44}\u{fb46}-\u{fbb1}\u{fbd3}-\u{fd3d}\u{fd50}-\u{fd8f}\u{fd92}-\u{fdc7}\u{fdf0}-\u{fdfc}\u{fe70}-\u{fe74}\u{fe76}-\u{fefc}]))
76
- .*?
77
- g<r_and_al_cat>
78
- | # contains RandALCat but doesn't end with RandALCat
79
- \g<r_and_al_cat> .*? \g<not_r_nor_al>\z
80
- )/mx.freeze
81
-
82
- # Matches strings prohibited by RFC4013 §2.3 and §2.4.
83
- #
84
- # This checks prohibited output and bidirectional characters.
85
- PROHIBITED = Regexp.union(
86
- PROHIBITED_OUTPUT, BIDI_FAILURE,
87
- )
88
-
89
- # Matches strings prohibited by RFC4013 §2.3, §2.4, and §2.5.
90
- #
91
- # This checks prohibited output, bidirectional characters, and
92
- # unassigned codepoints.
93
- PROHIBITED_STORED = Regexp.union(
94
- PROHIBITED_OUTPUT_STORED, BIDI_FAILURE,
95
- )
96
-
97
- end
98
- end