net-ldap 0.16.0 → 0.18.0

Sign up to get free protection for your applications and to get access to all the features.
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