net-ldap 0.16.0 → 0.18.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.
Files changed (73) hide show
  1. checksums.yaml +5 -5
  2. data/History.rdoc +64 -0
  3. data/README.rdoc +18 -6
  4. data/lib/net/ber/core_ext.rb +6 -6
  5. data/lib/net/ber.rb +2 -2
  6. data/lib/net/ldap/auth_adapter/gss_spnego.rb +2 -2
  7. data/lib/net/ldap/auth_adapter/sasl.rb +1 -1
  8. data/lib/net/ldap/auth_adapter/simple.rb +1 -1
  9. data/lib/net/ldap/connection.rb +23 -16
  10. data/lib/net/ldap/dataset.rb +1 -3
  11. data/lib/net/ldap/dn.rb +14 -22
  12. data/lib/net/ldap/entry.rb +11 -2
  13. data/lib/net/ldap/error.rb +2 -26
  14. data/lib/net/ldap/filter.rb +10 -3
  15. data/lib/net/ldap/instrumentation.rb +2 -2
  16. data/lib/net/ldap/password.rb +7 -5
  17. data/lib/net/ldap/pdu.rb +1 -1
  18. data/lib/net/ldap/version.rb +1 -1
  19. data/lib/net/ldap.rb +40 -17
  20. data/lib/net/snmp.rb +1 -1
  21. data/lib/net-ldap.rb +1 -1
  22. metadata +16 -106
  23. data/.gitignore +0 -9
  24. data/.rubocop.yml +0 -20
  25. data/.rubocop_todo.yml +0 -753
  26. data/.travis.yml +0 -33
  27. data/CONTRIBUTING.md +0 -54
  28. data/Gemfile +0 -2
  29. data/Rakefile +0 -23
  30. data/net-ldap.gemspec +0 -37
  31. data/script/changelog +0 -47
  32. data/script/generate-fixture-ca +0 -48
  33. data/script/install-openldap +0 -134
  34. data/script/package +0 -7
  35. data/script/release +0 -16
  36. data/test/ber/core_ext/test_array.rb +0 -22
  37. data/test/ber/core_ext/test_string.rb +0 -25
  38. data/test/ber/test_ber.rb +0 -153
  39. data/test/fixtures/ca/ca.info +0 -4
  40. data/test/fixtures/ca/cacert.pem +0 -24
  41. data/test/fixtures/ca/cakey.pem +0 -190
  42. data/test/fixtures/openldap/memberof.ldif +0 -33
  43. data/test/fixtures/openldap/retcode.ldif +0 -76
  44. data/test/fixtures/openldap/slapd.conf.ldif +0 -67
  45. data/test/fixtures/seed.ldif +0 -374
  46. data/test/integration/test_add.rb +0 -28
  47. data/test/integration/test_ber.rb +0 -30
  48. data/test/integration/test_bind.rb +0 -244
  49. data/test/integration/test_delete.rb +0 -31
  50. data/test/integration/test_open.rb +0 -88
  51. data/test/integration/test_password_modify.rb +0 -80
  52. data/test/integration/test_return_codes.rb +0 -38
  53. data/test/integration/test_search.rb +0 -77
  54. data/test/support/vm/openldap/.gitignore +0 -1
  55. data/test/support/vm/openldap/README.md +0 -64
  56. data/test/support/vm/openldap/Vagrantfile +0 -34
  57. data/test/test_auth_adapter.rb +0 -15
  58. data/test/test_dn.rb +0 -44
  59. data/test/test_entry.rb +0 -65
  60. data/test/test_filter.rb +0 -223
  61. data/test/test_filter_parser.rb +0 -24
  62. data/test/test_helper.rb +0 -74
  63. data/test/test_ldap.rb +0 -114
  64. data/test/test_ldap_connection.rb +0 -491
  65. data/test/test_ldif.rb +0 -104
  66. data/test/test_password.rb +0 -10
  67. data/test/test_rename.rb +0 -77
  68. data/test/test_search.rb +0 -39
  69. data/test/test_snmp.rb +0 -119
  70. data/test/test_ssl_ber.rb +0 -40
  71. data/test/testdata.ldif +0 -101
  72. data/testserver/ldapserver.rb +0 -209
  73. data/testserver/testdata.ldif +0 -101
checksums.yaml CHANGED
@@ -1,7 +1,7 @@
1
1
  ---
2
- SHA1:
3
- metadata.gz: d4f923e6ac7f10fc49fff6cfc20271a5eb318360
4
- data.tar.gz: 1967da0f521b403b511ad50760baa18fa9cc6dd5
2
+ SHA256:
3
+ metadata.gz: c8d5def02bd0ce6b44457f5c1c7983f8730131a1a7082b3765791b14a0ee576b
4
+ data.tar.gz: 41a50fda89f8c8e7a6a1c182e894181d910367a356c67f031dec8072e1544e3e
5
5
  SHA512:
6
- metadata.gz: '09bbb19ba3dba954202b1cb94aad491eb64e30a9582cc2c99e2b7ee6cc4cb79da7117bf2cbfc33a0ec851913fe15e76ef91534f92cc87cfe973e28fb1d8c03e1'
7
- data.tar.gz: d01aab8d40574cbe7ea738dd0698b092072894ac5c1af9238a9f527651f16dc786e787234d80af116b547137b033fd8966c9c9dc7a48b93c9646f8a274dec677
6
+ metadata.gz: c5ae1310f3668a7f12f4817ede1cdd9310b8b262a40f41639d29e6cf0ba105f3bd6df8f6b892abed3924b03987c18f0e3f0c9bb2c848ed9d33a4662d53783f83
7
+ data.tar.gz: f2b4573b1af8db1dd16b9b31202a53edd08829d399fb94bd27cb400b8b1246929dca87744bd5156c4910a4fd53a4c4689a3917258d165e472135fbf50afceb7c
data/History.rdoc CHANGED
@@ -1,3 +1,67 @@
1
+ === Net::LDAP 0.18.0
2
+ * Fix escaping of # and space in attrs #408
3
+ * Add support to use SNI #406
4
+ * Drop Ruby 2.5 and JRuby 9.2 from CI tests
5
+ * Bump rubocop to 1.48.1
6
+ * Update CI for TruffleRuby 22
7
+
8
+ === Net::LDAP 0.17.1
9
+ * Fixed shebang of bash #385
10
+ * Omit some tests for now until we update our CA cert #386
11
+ * Add Ruby 3.0 support #388
12
+ * Add TruffleRuby 21.0.0 to CI #389
13
+ * Correct a typo in an error message #391
14
+ * Enable bundler caching for travis #390
15
+ * Fix circular require while loading lib/net/ldap/entry.rb and lib/net/ldap/dataset.rb #392
16
+ * Handle nil value in GetbyteForSSLSocket::getbyte #306
17
+
18
+ === Net::LDAP 0.17.0
19
+ * Added private recursive_delete as alternative to DELETE_TREE #268
20
+ * Test suite updates #373 #376 #377
21
+ * Use Base64.strict_encode64 and SSHA256 #303
22
+ * Remove deprecated ConnectionRefusedError #366
23
+ * Added method to get a duplicate of the internal Hash #286
24
+ * remove a circular require #380
25
+ * fix LdapServerAsnSyntax compile #379
26
+ * Implement '==' operator for entries #381
27
+ * fix for undefined method for write exception #383
28
+
29
+ === Net::LDAP 0.16.3
30
+
31
+ * Add Net::LDAP::InvalidDNError #371
32
+ * Use require_relative instead of require #360
33
+ * Address some warnings and fix JRuby test omissions #365
34
+ * Bump rake dev dependency to 12.3 #359
35
+ * Enable rubocop in ci #251
36
+ * Enhance rubocop configuration and test syntax #344
37
+ * CI: Drop rbx-2, uninstallable #364
38
+ * Fix RuboCop warnings #312
39
+ * Fix wrong error class #305
40
+ * CONTRIBUTING.md: Repair link to Issues #309
41
+ * Make the generate() method more idiomatic... #326
42
+ * Make encode_sort_controls() more idiomatic... #327
43
+ * Make the instrument() method more idiomatic... #328
44
+ * Fix uninitialised Net::LDAP::LdapPduError #338
45
+ * README.rdoc: Use SVG build badge #310
46
+ * Update TravisCI config to inclue Ruby 2.7 #346
47
+ * add explicit ** to silence Ruby 2.7 warning #342
48
+ * Support parsing filters with attribute tags #345
49
+ * Bump rubocop development dependency version #336
50
+ * Add link to generated and hosted documentation on rubydoc #319
51
+ * Fix 'uninitialized constant Net::LDAP::PDU::LdapPduError' error #317
52
+ * simplify encoding logic: no more chomping required #362
53
+
54
+ === Net::LDAP 0.16.2
55
+
56
+ * Net::LDAP#open does not cache bind result {#334}[https://github.com/ruby-ldap/ruby-net-ldap/pull/334]
57
+ * Fix CI build {#333}[https://github.com/ruby-ldap/ruby-net-ldap/pull/333]
58
+ * Fix to "undefined method 'result_code'" {#308}[https://github.com/ruby-ldap/ruby-net-ldap/pull/308]
59
+ * Fixed Exception: incompatible character encodings: ASCII-8BIT and UTF-8 in filter.rb {#285}[https://github.com/ruby-ldap/ruby-net-ldap/pull/285]
60
+
61
+ === Net::LDAP 0.16.1
62
+
63
+ * Send DN and newPassword with password_modify request {#271}[https://github.com/ruby-ldap/ruby-net-ldap/pull/271]
64
+
1
65
  === Net::LDAP 0.16.0
2
66
 
3
67
  * Sasl fix {#281}[https://github.com/ruby-ldap/ruby-net-ldap/pull/281]
data/README.rdoc CHANGED
@@ -1,4 +1,6 @@
1
- = Net::LDAP for Ruby {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.png" />}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
1
+ = Net::LDAP for Ruby
2
+ {<img src="https://badge.fury.io/rb/net-ldap.svg" alt="Gem Version" />}[https://badge.fury.io/rb/net-ldap]
3
+ {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.svg" />}[https://travis-ci.org/ruby-ldap/ruby-net-ldap]
2
4
 
3
5
  == Description
4
6
 
@@ -21,7 +23,7 @@ the most recent LDAP RFCs (4510–4519, plus portions of 4520–4532).
21
23
 
22
24
  == Synopsis
23
25
 
24
- See Net::LDAP for documentation and usage samples.
26
+ See {Net::LDAP on rubydoc.info}[https://www.rubydoc.info/github/ruby-ldap/ruby-net-ldap] for documentation and usage samples.
25
27
 
26
28
  == Requirements
27
29
 
@@ -53,16 +55,26 @@ This task will run the test suite and the
53
55
  rake rubotest
54
56
 
55
57
  CI takes too long? If your local box supports
56
- {Vagrant}[https://www.vagrantup.com/], you can run most of the tests
57
- in a VM on your local box. For more details and setup instructions, see
58
- {test/support/vm/openldap/README.md}[https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md]
58
+ {Docker}[https://www.docker.com/], you can also run integration tests locally.
59
+ Simply run:
60
+
61
+ script/ldap-docker
62
+ INTEGRATION=openldap rake test
63
+
64
+ Or, use {Docker Compose}[https://docs.docker.com/compose/]. See docker-compose.yml for available Ruby versions.
65
+
66
+ docker-compose run ci-2.7
67
+
68
+ CAVEAT: you need to add the following line to /etc/hosts
69
+ 127.0.0.1 ldap.example.org
70
+ 127.0.0.1 cert.mismatch.example.org
59
71
 
60
72
  == Release
61
73
 
62
74
  This section is for gem maintainers to cut a new version of the gem.
63
75
 
64
76
  * Check out a new branch `release-VERSION`
65
- * Update lib/net/ldap/version.rb to next version number X.X.X following {semver}(http://semver.org/).
77
+ * Update lib/net/ldap/version.rb to next version number X.X.X following {semver}[http://semver.org/].
66
78
  * Update `History.rdoc`. Get latest changes with `script/changelog`
67
79
  * Open a pull request with these changes for review
68
80
  * After merging, on the master branch, run `script/release`
@@ -1,5 +1,5 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- require 'net/ber/ber_parser'
2
+ require_relative 'ber_parser'
3
3
  # :stopdoc:
4
4
  class IO
5
5
  include Net::BER::BERParser
@@ -19,35 +19,35 @@ end
19
19
  module Net::BER::Extensions # :nodoc:
20
20
  end
21
21
 
22
- require 'net/ber/core_ext/string'
22
+ require_relative 'core_ext/string'
23
23
  # :stopdoc:
24
24
  class String
25
25
  include Net::BER::BERParser
26
26
  include Net::BER::Extensions::String
27
27
  end
28
28
 
29
- require 'net/ber/core_ext/array'
29
+ require_relative 'core_ext/array'
30
30
  # :stopdoc:
31
31
  class Array
32
32
  include Net::BER::Extensions::Array
33
33
  end
34
34
  # :startdoc:
35
35
 
36
- require 'net/ber/core_ext/integer'
36
+ require_relative 'core_ext/integer'
37
37
  # :stopdoc:
38
38
  class Integer
39
39
  include Net::BER::Extensions::Integer
40
40
  end
41
41
  # :startdoc:
42
42
 
43
- require 'net/ber/core_ext/true_class'
43
+ require_relative 'core_ext/true_class'
44
44
  # :stopdoc:
45
45
  class TrueClass
46
46
  include Net::BER::Extensions::TrueClass
47
47
  end
48
48
  # :startdoc:
49
49
 
50
- require 'net/ber/core_ext/false_class'
50
+ require_relative 'core_ext/false_class'
51
51
  # :stopdoc:
52
52
  class FalseClass
53
53
  include Net::BER::Extensions::FalseClass
data/lib/net/ber.rb CHANGED
@@ -1,5 +1,5 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
- require 'net/ldap/version'
2
+ require_relative 'ldap/version'
3
3
 
4
4
  module Net # :nodoc:
5
5
  ##
@@ -349,4 +349,4 @@ module Net::BER
349
349
  Null = Net::BER::BerIdentifiedNull.new
350
350
  end
351
351
 
352
- require 'net/ber/core_ext'
352
+ require_relative 'ber/core_ext'
@@ -1,5 +1,5 @@
1
- require 'net/ldap/auth_adapter'
2
- require 'net/ldap/auth_adapter/sasl'
1
+ require_relative '../auth_adapter'
2
+ require_relative 'sasl'
3
3
 
4
4
  module Net
5
5
  class LDAP
@@ -1,4 +1,4 @@
1
- require 'net/ldap/auth_adapter'
1
+ require_relative '../auth_adapter'
2
2
 
3
3
  module Net
4
4
  class LDAP
@@ -1,4 +1,4 @@
1
- require 'net/ldap/auth_adapter'
1
+ require_relative '../auth_adapter'
2
2
 
3
3
  module Net
4
4
  class LDAP
@@ -33,9 +33,10 @@ class Net::LDAP::Connection #:nodoc:
33
33
  def prepare_socket(server, timeout=nil)
34
34
  socket = server[:socket]
35
35
  encryption = server[:encryption]
36
+ hostname = server[:host]
36
37
 
37
38
  @conn = socket
38
- setup_encryption(encryption, timeout) if encryption
39
+ setup_encryption(encryption, timeout, hostname) if encryption
39
40
  end
40
41
 
41
42
  def open_connection(server)
@@ -74,7 +75,8 @@ class Net::LDAP::Connection #:nodoc:
74
75
 
75
76
  module GetbyteForSSLSocket
76
77
  def getbyte
77
- getc.ord
78
+ c = getc
79
+ c && c.ord
78
80
  end
79
81
  end
80
82
 
@@ -85,7 +87,7 @@ class Net::LDAP::Connection #:nodoc:
85
87
  end
86
88
  end
87
89
 
88
- def self.wrap_with_ssl(io, tls_options = {}, timeout=nil)
90
+ def self.wrap_with_ssl(io, tls_options = {}, timeout=nil, hostname=nil)
89
91
  raise Net::LDAP::NoOpenSSLError, "OpenSSL is unavailable" unless Net::LDAP::HasOpenSSL
90
92
 
91
93
  ctx = OpenSSL::SSL::SSLContext.new
@@ -95,6 +97,7 @@ class Net::LDAP::Connection #:nodoc:
95
97
  ctx.set_params(tls_options) unless tls_options.empty?
96
98
 
97
99
  conn = OpenSSL::SSL::SSLSocket.new(io, ctx)
100
+ conn.hostname = hostname
98
101
 
99
102
  begin
100
103
  if timeout
@@ -147,11 +150,11 @@ class Net::LDAP::Connection #:nodoc:
147
150
  # communications, as with simple_tls. Thanks for Kouhei Sutou for
148
151
  # generously contributing the :start_tls path.
149
152
  #++
150
- def setup_encryption(args, timeout=nil)
153
+ def setup_encryption(args, timeout=nil, hostname=nil)
151
154
  args[:tls_options] ||= {}
152
155
  case args[:method]
153
156
  when :simple_tls
154
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
157
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
155
158
  # additional branches requiring server validation and peer certs, etc.
156
159
  # go here.
157
160
  when :start_tls
@@ -169,7 +172,7 @@ class Net::LDAP::Connection #:nodoc:
169
172
 
170
173
  raise Net::LDAP::StartTLSError,
171
174
  "start_tls failed: #{pdu.result_code}" unless pdu.result_code.zero?
172
- @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout)
175
+ @conn = self.class.wrap_with_ssl(@conn, args[:tls_options], timeout, hostname)
173
176
  else
174
177
  raise Net::LDAP::EncMethodUnsupportedError, "unsupported encryption method #{args[:method]}"
175
178
  end
@@ -181,7 +184,7 @@ class Net::LDAP::Connection #:nodoc:
181
184
  # have to call it, but perhaps it will come in handy someday.
182
185
  #++
183
186
  def close
184
- return if @conn.nil?
187
+ return if !defined?(@conn) || @conn.nil?
185
188
  @conn.close
186
189
  @conn = nil
187
190
  end
@@ -300,7 +303,7 @@ class Net::LDAP::Connection #:nodoc:
300
303
  control[2] = (control[2] == true).to_ber
301
304
  control.to_ber_sequence
302
305
  end
303
- sort_control = [
306
+ [
304
307
  Net::LDAP::LDAPControls::SORT_REQUEST.to_ber,
305
308
  false.to_ber,
306
309
  sort_control_values.to_ber_sequence.to_s.to_ber,
@@ -467,6 +470,10 @@ class Net::LDAP::Connection #:nodoc:
467
470
  end
468
471
  end
469
472
 
473
+ if result_pdu.nil?
474
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing"
475
+ end
476
+
470
477
  # count number of pages of results
471
478
  payload[:page_count] ||= 0
472
479
  payload[:page_count] += 1
@@ -592,11 +599,11 @@ class Net::LDAP::Connection #:nodoc:
592
599
 
593
600
  ext_seq = [Net::LDAP::PasswdModifyOid.to_ber_contextspecific(0)]
594
601
 
595
- unless args[:old_password].nil?
596
- pwd_seq = [args[:old_password].to_ber(0x81)]
597
- pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
598
- ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
599
- end
602
+ pwd_seq = []
603
+ pwd_seq << dn.to_ber(0x80)
604
+ pwd_seq << args[:old_password].to_ber(0x81) unless args[:old_password].nil?
605
+ pwd_seq << args[:new_password].to_ber(0x82) unless args[:new_password].nil?
606
+ ext_seq << pwd_seq.to_ber_sequence.to_ber(0x81)
600
607
 
601
608
  request = ext_seq.to_ber_appsequence(Net::LDAP::PDU::ExtendedRequest)
602
609
 
@@ -606,7 +613,7 @@ class Net::LDAP::Connection #:nodoc:
606
613
  pdu = queued_read(message_id)
607
614
 
608
615
  if !pdu || pdu.app_tag != Net::LDAP::PDU::ExtendedResponse
609
- raise Net::LDAP::ResponseMissingError, "response missing or invalid"
616
+ raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
610
617
  end
611
618
 
612
619
  pdu
@@ -686,7 +693,7 @@ class Net::LDAP::Connection #:nodoc:
686
693
  #
687
694
  # Typically a TCPSocket, but can be a OpenSSL::SSL::SSLSocket
688
695
  def socket
689
- return @conn if defined? @conn
696
+ return @conn if defined?(@conn) && !@conn.nil?
690
697
 
691
698
  # First refactoring uses the existing methods open_connection and
692
699
  # prepare_socket to set @conn. Next cleanup would centralize connection
@@ -706,7 +713,7 @@ class Net::LDAP::Connection #:nodoc:
706
713
  # Wrap around Socket.tcp to normalize with other Socket initializers
707
714
  class DefaultSocket
708
715
  def self.new(host, port, socket_opts = {})
709
- Socket.tcp(host, port, socket_opts)
716
+ Socket.tcp(host, port, **socket_opts)
710
717
  end
711
718
  end
712
719
  end # class Connection
@@ -103,7 +103,7 @@ class Net::LDAP::Dataset < Hash
103
103
  # with the conversion of
104
104
  def from_entry(entry)
105
105
  dataset = Net::LDAP::Dataset.new
106
- hash = { }
106
+ hash = {}
107
107
  entry.each_attribute do |attribute, value|
108
108
  next if attribute == :dn
109
109
  hash[attribute] = value
@@ -164,5 +164,3 @@ class Net::LDAP::Dataset < Hash
164
164
  end
165
165
  end
166
166
  end
167
-
168
- require 'net/ldap/entry' unless defined? Net::LDAP::Entry
data/lib/net/ldap/dn.rb CHANGED
@@ -57,19 +57,19 @@ class Net::LDAP::DN
57
57
  state = :key_oid
58
58
  key << char
59
59
  when ' ' then state = :key
60
- else raise "DN badly formed"
60
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
61
61
  end
62
62
  when :key_normal then
63
63
  case char
64
64
  when '=' then state = :value
65
65
  when 'a'..'z', 'A'..'Z', '0'..'9', '-', ' ' then key << char
66
- else raise "DN badly formed"
66
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
67
67
  end
68
68
  when :key_oid then
69
69
  case char
70
70
  when '=' then state = :value
71
71
  when '0'..'9', '.', ' ' then key << char
72
- else raise "DN badly formed"
72
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
73
73
  end
74
74
  when :value then
75
75
  case char
@@ -110,7 +110,7 @@ class Net::LDAP::DN
110
110
  when '0'..'9', 'a'..'f', 'A'..'F' then
111
111
  state = :value_normal
112
112
  value << "#{hex_buffer}#{char}".to_i(16).chr
113
- else raise "DN badly formed"
113
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
114
114
  end
115
115
  when :value_quoted then
116
116
  case char
@@ -132,7 +132,7 @@ class Net::LDAP::DN
132
132
  when '0'..'9', 'a'..'f', 'A'..'F' then
133
133
  state = :value_quoted
134
134
  value << "#{hex_buffer}#{char}".to_i(16).chr
135
- else raise "DN badly formed"
135
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
136
136
  end
137
137
  when :value_hexstring then
138
138
  case char
@@ -145,14 +145,14 @@ class Net::LDAP::DN
145
145
  yield key.string.strip, value.string.rstrip
146
146
  key = StringIO.new
147
147
  value = StringIO.new;
148
- else raise "DN badly formed"
148
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
149
149
  end
150
150
  when :value_hexstring_hex then
151
151
  case char
152
152
  when '0'..'9', 'a'..'f', 'A'..'F' then
153
153
  state = :value_hexstring
154
154
  value << char
155
- else raise "DN badly formed"
155
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
156
156
  end
157
157
  when :value_end then
158
158
  case char
@@ -162,14 +162,14 @@ class Net::LDAP::DN
162
162
  yield key.string.strip, value.string.rstrip
163
163
  key = StringIO.new
164
164
  value = StringIO.new;
165
- else raise "DN badly formed"
165
+ else raise Net::LDAP::InvalidDNError, "DN badly formed"
166
166
  end
167
- else raise "Fell out of state machine"
167
+ else raise Net::LDAP::InvalidDNError, "Fell out of state machine"
168
168
  end
169
169
  end
170
170
 
171
171
  # Last pair
172
- raise "DN badly formed" unless
172
+ raise Net::LDAP::InvalidDNError, "DN badly formed" unless
173
173
  [:value, :value_normal, :value_hexstring, :value_end].include? state
174
174
 
175
175
  yield key.string.strip, value.string.rstrip
@@ -192,27 +192,19 @@ class Net::LDAP::DN
192
192
  # http://tools.ietf.org/html/rfc2253 section 2.4 lists these exceptions
193
193
  # for dn values. All of the following must be escaped in any normal string
194
194
  # using a single backslash ('\') as escape.
195
- ESCAPES = {
196
- ',' => ',',
197
- '+' => '+',
198
- '"' => '"',
199
- '\\' => '\\',
200
- '<' => '<',
201
- '>' => '>',
202
- ';' => ';',
203
- }
195
+ ESCAPES = %w[, + " \\ < > ;]
204
196
 
205
- # Compiled character class regexp using the keys from the above hash, and
197
+ # Compiled character class regexp using the values from the above list, and
206
198
  # checking for a space or # at the start, or space at the end, of the
207
199
  # string.
208
200
  ESCAPE_RE = Regexp.new("(^ |^#| $|[" +
209
- ESCAPES.keys.map { |e| Regexp.escape(e) }.join +
201
+ ESCAPES.map { |e| Regexp.escape(e) }.join +
210
202
  "])")
211
203
 
212
204
  ##
213
205
  # Escape a string for use in a DN value
214
206
  def self.escape(string)
215
- string.gsub(ESCAPE_RE) { |char| "\\" + ESCAPES[char] }
207
+ string.gsub(ESCAPE_RE) { |char| "\\" + char }
216
208
  end
217
209
 
218
210
  ##
@@ -133,6 +133,13 @@ class Net::LDAP::Entry
133
133
  @myhash.keys
134
134
  end
135
135
 
136
+ ##
137
+ # Creates a duplicate of the internal Hash containing the attributes
138
+ # of the entry.
139
+ def to_h
140
+ @myhash.dup
141
+ end
142
+
136
143
  ##
137
144
  # Accesses each of the attributes present in the Entry.
138
145
  #
@@ -187,6 +194,8 @@ class Net::LDAP::Entry
187
194
  sym.to_s[-1] == ?=
188
195
  end
189
196
  private :setter?
190
- end # class Entry
191
197
 
192
- require 'net/ldap/dataset' unless defined? Net::LDAP::Dataset
198
+ def ==(other)
199
+ other.instance_of?(self.class) && @myhash == other.to_h
200
+ end
201
+ end # class Entry
@@ -1,38 +1,13 @@
1
1
  class Net::LDAP
2
- class LdapError < StandardError
3
- def message
4
- "Deprecation warning: Net::LDAP::LdapError is no longer used. Use Net::LDAP::Error or rescue one of it's subclasses. \n" + super
5
- end
6
- end
7
-
8
2
  class Error < StandardError; end
9
3
 
10
4
  class AlreadyOpenedError < Error; end
11
5
  class SocketError < Error; end
12
- class ConnectionRefusedError < Error;
13
- def initialize(*args)
14
- warn_deprecation_message
15
- super
16
- end
17
-
18
- def message
19
- warn_deprecation_message
20
- super
21
- end
22
-
23
- private
24
-
25
- def warn_deprecation_message
26
- warn "Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead."
27
- end
28
- end
29
6
  class ConnectionError < Error
30
7
  def self.new(errors)
31
8
  error = errors.first.first
32
9
  if errors.size == 1
33
- if error.kind_of? Errno::ECONNREFUSED
34
- return Net::LDAP::ConnectionRefusedError.new(error.message)
35
- end
10
+ return error if error.is_a? Errno::ECONNREFUSED
36
11
 
37
12
  return Net::LDAP::Error.new(error.message)
38
13
  end
@@ -60,6 +35,7 @@ class Net::LDAP
60
35
  class ResponseTypeInvalidError < Error; end
61
36
  class ResponseMissingOrInvalidError < Error; end
62
37
  class EmptyDNError < Error; end
38
+ class InvalidDNError < Error; end
63
39
  class HashTypeUnsupportedError < Error; end
64
40
  class OperatorError < Error; end
65
41
  class SubstringFilterError < Error; end
@@ -490,7 +490,7 @@ class Net::LDAP::Filter
490
490
  when :eq
491
491
  if @right == "*" # presence test
492
492
  @left.to_s.to_ber_contextspecific(7)
493
- elsif @right =~ /[*]/ # substring
493
+ elsif @right.to_s =~ /[*]/ # substring
494
494
  # Parsing substrings is a little tricky. We use String#split to
495
495
  # break a string into substrings delimited by the * (star)
496
496
  # character. But we also need to know whether there is a star at the
@@ -645,8 +645,15 @@ class Net::LDAP::Filter
645
645
 
646
646
  ##
647
647
  # Converts escaped characters (e.g., "\\28") to unescaped characters
648
+ # @note slawson20170317: Don't attempt to unescape 16 byte binary data which we assume are objectGUIDs
649
+ # The binary form of 5936AE79-664F-44EA-BCCB-5C39399514C6 triggers a BINARY -> UTF-8 conversion error
648
650
  def unescape(right)
649
- right.to_s.gsub(/\\([a-fA-F\d]{2})/) { [$1.hex].pack("U") }
651
+ right = right.to_s
652
+ if right.length == 16 && right.encoding == Encoding::BINARY
653
+ right
654
+ else
655
+ right.to_s.gsub(/\\([a-fA-F\d]{2})/) { [$1.hex].pack("U") }
656
+ end
650
657
  end
651
658
  private :unescape
652
659
 
@@ -748,7 +755,7 @@ class Net::LDAP::Filter
748
755
  # This parses a given expression inside of parentheses.
749
756
  def parse_filter_branch(scanner)
750
757
  scanner.scan(/\s*/)
751
- if token = scanner.scan(/[-\w:.]*[\w]/)
758
+ if token = scanner.scan(/[-\w:.;]*[\w]/)
752
759
  scanner.scan(/\s*/)
753
760
  if op = scanner.scan(/<=|>=|!=|:=|=/)
754
761
  scanner.scan(/\s*/)
@@ -12,8 +12,8 @@ module Net::LDAP::Instrumentation
12
12
  def instrument(event, payload = {})
13
13
  payload = (payload || {}).dup
14
14
  if instrumentation_service
15
- instrumentation_service.instrument(event, payload) do |payload|
16
- payload[:result] = yield(payload) if block_given?
15
+ instrumentation_service.instrument(event, payload) do |instr_payload|
16
+ instr_payload[:result] = yield(instr_payload) if block_given?
17
17
  end
18
18
  else
19
19
  yield(payload) if block_given?
@@ -1,5 +1,6 @@
1
1
  # -*- ruby encoding: utf-8 -*-
2
2
  require 'digest/sha1'
3
+ require 'digest/sha2'
3
4
  require 'digest/md5'
4
5
  require 'base64'
5
6
  require 'securerandom'
@@ -19,20 +20,21 @@ class Net::LDAP::Password
19
20
  # * Should we provide sha1 as a synonym for sha1? I vote no because then
20
21
  # should you also provide ssha1 for symmetry?
21
22
  #
22
- attribute_value = ""
23
23
  def generate(type, str)
24
24
  case type
25
25
  when :md5
26
- attribute_value = '{MD5}' + Base64.encode64(Digest::MD5.digest(str)).chomp!
26
+ '{MD5}' + Base64.strict_encode64(Digest::MD5.digest(str))
27
27
  when :sha
28
- attribute_value = '{SHA}' + Base64.encode64(Digest::SHA1.digest(str)).chomp!
28
+ '{SHA}' + Base64.strict_encode64(Digest::SHA1.digest(str))
29
29
  when :ssha
30
30
  salt = SecureRandom.random_bytes(16)
31
- attribute_value = '{SSHA}' + Base64.encode64(Digest::SHA1.digest(str + salt) + salt).chomp!
31
+ '{SSHA}' + Base64.strict_encode64(Digest::SHA1.digest(str + salt) + salt)
32
+ when :ssha256
33
+ salt = SecureRandom.random_bytes(16)
34
+ '{SSHA256}' + Base64.strict_encode64(Digest::SHA256.digest(str + salt) + salt)
32
35
  else
33
36
  raise Net::LDAP::HashTypeUnsupportedError, "Unsupported password-hash type (#{type})"
34
37
  end
35
- return attribute_value
36
38
  end
37
39
  end
38
40
  end
data/lib/net/ldap/pdu.rb CHANGED
@@ -123,7 +123,7 @@ class Net::LDAP::PDU
123
123
  when ExtendedResponse
124
124
  parse_extended_response(ber_object[1])
125
125
  else
126
- raise LdapPduError.new("unknown pdu-type: #{@app_tag}")
126
+ raise Error.new("unknown pdu-type: #{@app_tag}")
127
127
  end
128
128
 
129
129
  parse_controls(ber_object[2]) if ber_object[2]
@@ -1,5 +1,5 @@
1
1
  module Net
2
2
  class LDAP
3
- VERSION = "0.16.0"
3
+ VERSION = "0.18.0"
4
4
  end
5
5
  end