net-ldap 0.11 → 0.12.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.
Potentially problematic release.
This version of net-ldap might be problematic. Click here for more details.
- checksums.yaml +4 -4
- data/.travis.yml +7 -4
- data/History.rdoc +18 -0
- data/README.rdoc +13 -4
- data/Rakefile +0 -1
- data/lib/net/ber.rb +5 -3
- data/lib/net/ldap.rb +18 -0
- data/lib/net/ldap/auth_adapter.rb +29 -0
- data/lib/net/ldap/auth_adapter/gss_spnego.rb +40 -0
- data/lib/net/ldap/auth_adapter/sasl.rb +60 -0
- data/lib/net/ldap/auth_adapter/simple.rb +34 -0
- data/lib/net/ldap/connection.rb +48 -147
- data/lib/net/ldap/error.rb +35 -1
- data/lib/net/ldap/filter.rb +1 -1
- data/lib/net/ldap/version.rb +1 -1
- data/net-ldap.gemspec +1 -0
- data/script/changelog +47 -0
- data/script/install-openldap +30 -29
- data/test/test_auth_adapter.rb +11 -0
- data/test/test_filter_parser.rb +4 -0
- data/test/test_helper.rb +1 -1
- data/test/test_ldap.rb +7 -0
- data/test/test_ldap_connection.rb +56 -0
- metadata +24 -3
checksums.yaml
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
---
|
2
2
|
SHA1:
|
3
|
-
metadata.gz:
|
4
|
-
data.tar.gz:
|
3
|
+
metadata.gz: 8c96669822fdcf032465b410615500b91a2f31ec
|
4
|
+
data.tar.gz: 643738d3f05ae5469ef1eb773326d5943eacf923
|
5
5
|
SHA512:
|
6
|
-
metadata.gz:
|
7
|
-
data.tar.gz:
|
6
|
+
metadata.gz: 6a7a455c387b73745d6da20d890181c20776562751f0c4bd43b9eb9a7ad9d2637771e1dfdaecbeb7e951ba25bca9859219e32e1154a88eed12e162152f47df0e
|
7
|
+
data.tar.gz: e92116ed732575ba7f0f05fb52f1148bd9c432de28cd3d0391b72835a091294dd7fe260c3b5aa1c96266b31edc9dd861cedd5d6066f57520dfb5c19e05a7b727
|
data/.travis.yml
CHANGED
@@ -2,25 +2,28 @@ language: ruby
|
|
2
2
|
rvm:
|
3
3
|
- 1.9.3
|
4
4
|
- 2.0.0
|
5
|
-
- 2.1
|
5
|
+
- 2.1
|
6
|
+
- 2.2
|
6
7
|
# optional
|
8
|
+
- ruby-head
|
7
9
|
- jruby-19mode
|
8
|
-
-
|
10
|
+
- jruby-head
|
9
11
|
- rbx-2
|
10
12
|
|
11
13
|
env:
|
12
14
|
- INTEGRATION=openldap
|
13
15
|
|
14
16
|
install:
|
15
|
-
- if [ "$INTEGRATION" = "openldap" ]; then
|
17
|
+
- if [ "$INTEGRATION" = "openldap" ]; then sudo script/install-openldap; fi
|
16
18
|
- bundle install
|
17
19
|
|
18
20
|
script: bundle exec rake ci
|
19
21
|
|
20
22
|
matrix:
|
21
23
|
allow_failures:
|
24
|
+
- rvm: ruby-head
|
22
25
|
- rvm: jruby-19mode
|
23
|
-
- rvm:
|
26
|
+
- rvm: jruby-head
|
24
27
|
- rvm: rbx-2
|
25
28
|
fast_finish: true
|
26
29
|
|
data/History.rdoc
CHANGED
@@ -1,3 +1,21 @@
|
|
1
|
+
=== Net::LDAP 0.12.0
|
2
|
+
|
3
|
+
* DRY up connection handling logic {#224}[https://github.com/ruby-ldap/ruby-net-ldap/pull/224]
|
4
|
+
* Define auth adapters {#226}[https://github.com/ruby-ldap/ruby-net-ldap/pull/226]
|
5
|
+
* add slash to attribute value filter {#225}[https://github.com/ruby-ldap/ruby-net-ldap/pull/225]
|
6
|
+
* Add the ability to provide a list of hosts for a connection {#223}[https://github.com/ruby-ldap/ruby-net-ldap/pull/223]
|
7
|
+
* Specify the port of LDAP server by giving INTEGRATION_PORT {#221}[https://github.com/ruby-ldap/ruby-net-ldap/pull/221]
|
8
|
+
* Correctly set BerIdentifiedString values to UTF-8 {#212}[https://github.com/ruby-ldap/ruby-net-ldap/pull/212]
|
9
|
+
* Raise Net::LDAP::ConnectionRefusedError when new connection is refused. {#213}[https://github.com/ruby-ldap/ruby-net-ldap/pull/213]
|
10
|
+
* obscure auth password upon #inspect, added test, closes #216 {#217}[https://github.com/ruby-ldap/ruby-net-ldap/pull/217]
|
11
|
+
* Fixing incorrect error class name {#207}[https://github.com/ruby-ldap/ruby-net-ldap/pull/207]
|
12
|
+
* Travis update {#205}[https://github.com/ruby-ldap/ruby-net-ldap/pull/205]
|
13
|
+
* Remove obsolete rbx-19mode from Travis {#204}[https://github.com/ruby-ldap/ruby-net-ldap/pull/204]
|
14
|
+
* mv "sudo" from script/install-openldap to .travis.yml {#199}[https://github.com/ruby-ldap/ruby-net-ldap/pull/199]
|
15
|
+
* Remove meaningless shebang {#200}[https://github.com/ruby-ldap/ruby-net-ldap/pull/200]
|
16
|
+
* Fix Travis CI build {#202}[https://github.com/ruby-ldap/ruby-net-ldap/pull/202]
|
17
|
+
* README.rdoc: fix travis link {#195}[https://github.com/ruby-ldap/ruby-net-ldap/pull/195]
|
18
|
+
|
1
19
|
=== Net::LDAP 0.11
|
2
20
|
* Major enhancements:
|
3
21
|
* #183 Specific errors subclassing Net::LDAP::Error
|
data/README.rdoc
CHANGED
@@ -1,4 +1,4 @@
|
|
1
|
-
= Net::LDAP for Ruby {<img src="https://travis-ci.org/ruby-ldap/ruby-net-ldap.png" />}[https://travis-ci.org/
|
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]
|
2
2
|
|
3
3
|
== Description
|
4
4
|
|
@@ -37,6 +37,14 @@ sources.
|
|
37
37
|
|
38
38
|
Simply require either 'net-ldap' or 'net/ldap'.
|
39
39
|
|
40
|
+
== Extensions
|
41
|
+
|
42
|
+
This library focuses on the core LDAP RFCs referenced in the description.
|
43
|
+
However, we recognize there are commonly used extensions to the spec that are
|
44
|
+
useful. If there is another library which handles it, we list it here.
|
45
|
+
|
46
|
+
* {resolv-srv}[https://rubygems.org/gems/resolv-srv]: Support RFC2782 SRV record lookup and failover
|
47
|
+
|
40
48
|
== Develop
|
41
49
|
|
42
50
|
This task will run the test suite and the
|
@@ -55,10 +63,11 @@ To run the integration tests against an LDAP server:
|
|
55
63
|
|
56
64
|
This section is for gem maintainers to cut a new version of the gem.
|
57
65
|
|
66
|
+
* Check out a new branch `release-VERSION`
|
58
67
|
* Update lib/net/ldap/version.rb to next version number X.X.X following {semver}(http://semver.org/).
|
59
|
-
* Update `History.rdoc`. Get latest changes with `
|
60
|
-
|
61
|
-
*
|
68
|
+
* Update `History.rdoc`. Get latest changes with `script/changelog`
|
69
|
+
* Open a pull request with these changes for review
|
70
|
+
* After merging, on the master branch, run `script/release`
|
62
71
|
|
63
72
|
:include: Contributors.rdoc
|
64
73
|
|
data/Rakefile
CHANGED
data/lib/net/ber.rb
CHANGED
@@ -296,9 +296,11 @@ end
|
|
296
296
|
class Net::BER::BerIdentifiedString < String
|
297
297
|
attr_accessor :ber_identifier
|
298
298
|
def initialize args
|
299
|
-
super
|
300
|
-
|
301
|
-
|
299
|
+
super begin
|
300
|
+
args.respond_to?(:encode) ? args.encode('UTF-8') : args
|
301
|
+
rescue
|
302
|
+
args
|
303
|
+
end
|
302
304
|
end
|
303
305
|
end
|
304
306
|
|
data/lib/net/ldap.rb
CHANGED
@@ -27,6 +27,12 @@ require 'net/ldap/instrumentation'
|
|
27
27
|
require 'net/ldap/connection'
|
28
28
|
require 'net/ldap/version'
|
29
29
|
require 'net/ldap/error'
|
30
|
+
require 'net/ldap/auth_adapter'
|
31
|
+
require 'net/ldap/auth_adapter/simple'
|
32
|
+
require 'net/ldap/auth_adapter/sasl'
|
33
|
+
|
34
|
+
Net::LDAP::AuthAdapter.register([:simple, :anon, :anonymous], Net::LDAP::AuthAdapter::Simple)
|
35
|
+
Net::LDAP::AuthAdapter.register(:sasl, Net::LDAP::AuthAdapter::Sasl)
|
30
36
|
|
31
37
|
# == Quick-start for the Impatient
|
32
38
|
# === Quick Example of a user-authentication against an LDAP directory:
|
@@ -432,6 +438,7 @@ class Net::LDAP
|
|
432
438
|
|
433
439
|
attr_accessor :host
|
434
440
|
attr_accessor :port
|
441
|
+
attr_accessor :hosts
|
435
442
|
attr_accessor :base
|
436
443
|
|
437
444
|
# Instantiate an object of type Net::LDAP to perform directory operations.
|
@@ -440,6 +447,8 @@ class Net::LDAP
|
|
440
447
|
# described below. The following arguments are supported:
|
441
448
|
# * :host => the LDAP server's IP-address (default 127.0.0.1)
|
442
449
|
# * :port => the LDAP server's TCP port (default 389)
|
450
|
+
# * :hosts => an enumerable of pairs of hosts and corresponding ports with
|
451
|
+
# which to attempt opening connections (default [[host, port]])
|
443
452
|
# * :auth => a Hash containing authorization parameters. Currently
|
444
453
|
# supported values include: {:method => :anonymous} and {:method =>
|
445
454
|
# :simple, :username => your_user_name, :password => your_password }
|
@@ -468,6 +477,7 @@ class Net::LDAP
|
|
468
477
|
def initialize(args = {})
|
469
478
|
@host = args[:host] || DefaultHost
|
470
479
|
@port = args[:port] || DefaultPort
|
480
|
+
@hosts = args[:hosts]
|
471
481
|
@verbose = false # Make this configurable with a switch on the class.
|
472
482
|
@auth = args[:auth] || DefaultAuth
|
473
483
|
@base = args[:base] || DefaultTreebase
|
@@ -1195,6 +1205,13 @@ class Net::LDAP
|
|
1195
1205
|
@server_caps[:supportedcontrol].include?(Net::LDAP::LDAPControls::PAGED_RESULTS)
|
1196
1206
|
end
|
1197
1207
|
|
1208
|
+
# Mask auth password
|
1209
|
+
def inspect
|
1210
|
+
inspected = super
|
1211
|
+
inspected.gsub! @auth[:password], "*******" if @auth[:password]
|
1212
|
+
inspected
|
1213
|
+
end
|
1214
|
+
|
1198
1215
|
private
|
1199
1216
|
|
1200
1217
|
# Yields an open connection if there is one, otherwise establishes a new
|
@@ -1223,6 +1240,7 @@ class Net::LDAP
|
|
1223
1240
|
Net::LDAP::Connection.new \
|
1224
1241
|
:host => @host,
|
1225
1242
|
:port => @port,
|
1243
|
+
:hosts => @hosts,
|
1226
1244
|
:encryption => @encryption,
|
1227
1245
|
:instrumentation_service => @instrumentation_service
|
1228
1246
|
end
|
@@ -0,0 +1,29 @@
|
|
1
|
+
module Net
|
2
|
+
class LDAP
|
3
|
+
class AuthAdapter
|
4
|
+
def self.register(names, adapter)
|
5
|
+
names = Array(names)
|
6
|
+
@adapters ||= {}
|
7
|
+
names.each do |name|
|
8
|
+
@adapters[name] = adapter
|
9
|
+
end
|
10
|
+
end
|
11
|
+
|
12
|
+
def self.[](name)
|
13
|
+
a = @adapters[name]
|
14
|
+
if a.nil?
|
15
|
+
raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (#{name})"
|
16
|
+
end
|
17
|
+
return a
|
18
|
+
end
|
19
|
+
|
20
|
+
def initialize(conn)
|
21
|
+
@connection = conn
|
22
|
+
end
|
23
|
+
|
24
|
+
def bind
|
25
|
+
raise "bind method must be overwritten"
|
26
|
+
end
|
27
|
+
end
|
28
|
+
end
|
29
|
+
end
|
@@ -0,0 +1,40 @@
|
|
1
|
+
require 'net/ldap/auth_adapter'
|
2
|
+
require 'net/ldap/auth_adapter/sasl'
|
3
|
+
|
4
|
+
module Net
|
5
|
+
class LDAP
|
6
|
+
module AuthAdapers
|
7
|
+
#--
|
8
|
+
# PROVISIONAL, only for testing SASL implementations. DON'T USE THIS YET.
|
9
|
+
# Uses Kohei Kajimoto's Ruby/NTLM. We have to find a clean way to
|
10
|
+
# integrate it without introducing an external dependency.
|
11
|
+
#
|
12
|
+
# This authentication method is accessed by calling #bind with a :method
|
13
|
+
# parameter of :gss_spnego. It requires :username and :password
|
14
|
+
# attributes, just like the :simple authentication method. It performs a
|
15
|
+
# GSS-SPNEGO authentication with the server, which is presumed to be a
|
16
|
+
# Microsoft Active Directory.
|
17
|
+
#++
|
18
|
+
class GSS_SPNEGO < Net::LDAP::AuthAdapter
|
19
|
+
def bind(auth)
|
20
|
+
require 'ntlm'
|
21
|
+
|
22
|
+
user, psw = [auth[:username] || auth[:dn], auth[:password]]
|
23
|
+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
|
24
|
+
|
25
|
+
nego = proc { |challenge|
|
26
|
+
t2_msg = NTLM::Message.parse(challenge)
|
27
|
+
t3_msg = t2_msg.response({ :user => user, :password => psw },
|
28
|
+
{ :ntlmv2 => true })
|
29
|
+
t3_msg.serialize
|
30
|
+
}
|
31
|
+
|
32
|
+
Net::LDAP::AuthAdapter::Sasl.new(@connection).
|
33
|
+
bind(:method => :sasl, :mechanism => "GSS-SPNEGO",
|
34
|
+
:initial_credential => NTLM::Message::Type1.new.serialize,
|
35
|
+
:challenge_response => nego)
|
36
|
+
end
|
37
|
+
end
|
38
|
+
end
|
39
|
+
end
|
40
|
+
end
|
@@ -0,0 +1,60 @@
|
|
1
|
+
require 'net/ldap/auth_adapter'
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class LDAP
|
5
|
+
class AuthAdapter
|
6
|
+
class Sasl < Net::LDAP::AuthAdapter
|
7
|
+
#--
|
8
|
+
# Required parameters: :mechanism, :initial_credential and
|
9
|
+
# :challenge_response
|
10
|
+
#
|
11
|
+
# Mechanism is a string value that will be passed in the SASL-packet's
|
12
|
+
# "mechanism" field.
|
13
|
+
#
|
14
|
+
# Initial credential is most likely a string. It's passed in the initial
|
15
|
+
# BindRequest that goes to the server. In some protocols, it may be empty.
|
16
|
+
#
|
17
|
+
# Challenge-response is a Ruby proc that takes a single parameter and
|
18
|
+
# returns an object that will typically be a string. The
|
19
|
+
# challenge-response block is called when the server returns a
|
20
|
+
# BindResponse with a result code of 14 (saslBindInProgress). The
|
21
|
+
# challenge-response block receives a parameter containing the data
|
22
|
+
# returned by the server in the saslServerCreds field of the LDAP
|
23
|
+
# BindResponse packet. The challenge-response block may be called multiple
|
24
|
+
# times during the course of a SASL authentication, and each time it must
|
25
|
+
# return a value that will be passed back to the server as the credential
|
26
|
+
# data in the next BindRequest packet.
|
27
|
+
#++
|
28
|
+
def bind(auth)
|
29
|
+
mech, cred, chall = auth[:mechanism], auth[:initial_credential],
|
30
|
+
auth[:challenge_response]
|
31
|
+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
|
32
|
+
|
33
|
+
message_id = @connection.next_msgid
|
34
|
+
|
35
|
+
n = 0
|
36
|
+
loop {
|
37
|
+
sasl = [mech.to_ber, cred.to_ber].to_ber_contextspecific(3)
|
38
|
+
request = [
|
39
|
+
Net::LDAP::Connection::LdapVersion.to_ber, "".to_ber, sasl
|
40
|
+
].to_ber_appsequence(Net::LDAP::PDU::BindRequest)
|
41
|
+
|
42
|
+
@connection.send(:write, request, nil, message_id)
|
43
|
+
pdu = @connection.queued_read(message_id)
|
44
|
+
|
45
|
+
if !pdu || pdu.app_tag != Net::LDAP::PDU::BindResult
|
46
|
+
raise Net::LDAP::NoBindResultError, "no bind result"
|
47
|
+
end
|
48
|
+
|
49
|
+
return pdu unless pdu.result_code == Net::LDAP::ResultCodeSaslBindInProgress
|
50
|
+
raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
|
51
|
+
|
52
|
+
cred = chall.call(pdu.result_server_sasl_creds)
|
53
|
+
}
|
54
|
+
|
55
|
+
raise Net::LDAP::SASLChallengeOverflowError, "why are we here?"
|
56
|
+
end
|
57
|
+
end
|
58
|
+
end
|
59
|
+
end
|
60
|
+
end
|
@@ -0,0 +1,34 @@
|
|
1
|
+
require 'net/ldap/auth_adapter'
|
2
|
+
|
3
|
+
module Net
|
4
|
+
class LDAP
|
5
|
+
class AuthAdapter
|
6
|
+
class Simple < AuthAdapter
|
7
|
+
def bind(auth)
|
8
|
+
user, psw = if auth[:method] == :simple
|
9
|
+
[auth[:username] || auth[:dn], auth[:password]]
|
10
|
+
else
|
11
|
+
["", ""]
|
12
|
+
end
|
13
|
+
|
14
|
+
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
|
15
|
+
|
16
|
+
message_id = @connection.next_msgid
|
17
|
+
request = [
|
18
|
+
Net::LDAP::Connection::LdapVersion.to_ber, user.to_ber,
|
19
|
+
psw.to_ber_contextspecific(0)
|
20
|
+
].to_ber_appsequence(Net::LDAP::PDU::BindRequest)
|
21
|
+
|
22
|
+
@connection.send(:write, request, nil, message_id)
|
23
|
+
pdu = @connection.queued_read(message_id)
|
24
|
+
|
25
|
+
if !pdu || pdu.app_tag != Net::LDAP::PDU::BindResult
|
26
|
+
raise Net::LDAP::NoBindResultError, "no bind result"
|
27
|
+
end
|
28
|
+
|
29
|
+
pdu
|
30
|
+
end
|
31
|
+
end
|
32
|
+
end
|
33
|
+
end
|
34
|
+
end
|
data/lib/net/ldap/connection.rb
CHANGED
@@ -9,23 +9,42 @@ class Net::LDAP::Connection #:nodoc:
|
|
9
9
|
def initialize(server)
|
10
10
|
@instrumentation_service = server[:instrumentation_service]
|
11
11
|
|
12
|
-
|
13
|
-
|
14
|
-
|
15
|
-
|
16
|
-
|
17
|
-
raise Net::LDAP::Error, "Server #{server[:host]} refused connection on port #{server[:port]}."
|
18
|
-
rescue Errno::EHOSTUNREACH => error
|
19
|
-
raise Net::LDAP::Error, "Host #{server[:host]} was unreachable (#{error.message})"
|
20
|
-
rescue Errno::ETIMEDOUT
|
21
|
-
raise Net::LDAP::Error, "Connection to #{server[:host]} timed out."
|
12
|
+
if server[:socket]
|
13
|
+
prepare_socket(server)
|
14
|
+
else
|
15
|
+
server[:hosts] = [[server[:host], server[:port]]] if server[:hosts].nil?
|
16
|
+
open_connection(server)
|
22
17
|
end
|
23
18
|
|
24
|
-
if
|
25
|
-
|
19
|
+
yield self if block_given?
|
20
|
+
end
|
21
|
+
|
22
|
+
def prepare_socket(server)
|
23
|
+
socket = server[:socket]
|
24
|
+
encryption = server[:encryption]
|
25
|
+
|
26
|
+
@conn = socket
|
27
|
+
setup_encryption encryption if encryption
|
28
|
+
end
|
29
|
+
|
30
|
+
def open_connection(server)
|
31
|
+
hosts = server[:hosts]
|
32
|
+
encryption = server[:encryption]
|
33
|
+
|
34
|
+
errors = []
|
35
|
+
hosts.each do |host, port|
|
36
|
+
begin
|
37
|
+
prepare_socket(server.merge(socket: TCPSocket.new(host, port)))
|
38
|
+
return
|
39
|
+
rescue Net::LDAP::Error, SocketError, SystemCallError,
|
40
|
+
OpenSSL::SSL::SSLError => e
|
41
|
+
# Ensure the connection is closed in the event a setup failure.
|
42
|
+
close
|
43
|
+
errors << [e, host, port]
|
44
|
+
end
|
26
45
|
end
|
27
46
|
|
28
|
-
|
47
|
+
raise Net::LDAP::ConnectionError.new(errors)
|
29
48
|
end
|
30
49
|
|
31
50
|
module GetbyteForSSLSocket
|
@@ -63,18 +82,18 @@ class Net::LDAP::Connection #:nodoc:
|
|
63
82
|
end
|
64
83
|
|
65
84
|
#--
|
66
|
-
# Helper method called only from
|
67
|
-
# successfully-opened @conn instance variable, which is a TCP
|
68
|
-
# Depending on the received arguments, we establish SSL,
|
69
|
-
# replacing the value of @conn accordingly. Don't generate any
|
70
|
-
# if no encryption is requested. DO raise Net::LDAP::Error objects
|
71
|
-
# is requested and we have trouble setting it up. That includes
|
72
|
-
# is not set up on the machine. (Question: how does the Ruby
|
73
|
-
# wrapper react in that case?) DO NOT filter exceptions raised by the
|
74
|
-
# OpenSSL library. Let them pass back to the user. That should make it
|
75
|
-
#
|
76
|
-
#
|
77
|
-
#
|
85
|
+
# Helper method called only from prepare_socket or open_connection, and only
|
86
|
+
# after we have a successfully-opened @conn instance variable, which is a TCP
|
87
|
+
# connection. Depending on the received arguments, we establish SSL,
|
88
|
+
# potentially replacing the value of @conn accordingly. Don't generate any
|
89
|
+
# errors here if no encryption is requested. DO raise Net::LDAP::Error objects
|
90
|
+
# if encryption is requested and we have trouble setting it up. That includes
|
91
|
+
# if OpenSSL is not set up on the machine. (Question: how does the Ruby
|
92
|
+
# OpenSSL wrapper react in that case?) DO NOT filter exceptions raised by the
|
93
|
+
# OpenSSL library. Let them pass back to the user. That should make it easier
|
94
|
+
# for us to debug the problem reports. Presumably (hopefully?) that will also
|
95
|
+
# produce recognizable errors if someone tries to use this on a machine
|
96
|
+
# without OpenSSL.
|
78
97
|
#
|
79
98
|
# The simple_tls method is intended as the simplest, stupidest, easiest
|
80
99
|
# solution for people who want nothing more than encrypted comms with the
|
@@ -124,6 +143,7 @@ class Net::LDAP::Connection #:nodoc:
|
|
124
143
|
# have to call it, but perhaps it will come in handy someday.
|
125
144
|
#++
|
126
145
|
def close
|
146
|
+
return if @conn.nil?
|
127
147
|
@conn.close
|
128
148
|
@conn = nil
|
129
149
|
end
|
@@ -218,130 +238,11 @@ class Net::LDAP::Connection #:nodoc:
|
|
218
238
|
def bind(auth)
|
219
239
|
instrument "bind.net_ldap_connection" do |payload|
|
220
240
|
payload[:method] = meth = auth[:method]
|
221
|
-
|
222
|
-
|
223
|
-
elsif meth == :sasl
|
224
|
-
bind_sasl(auth)
|
225
|
-
elsif meth == :gss_spnego
|
226
|
-
bind_gss_spnego(auth)
|
227
|
-
else
|
228
|
-
raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (#{meth})"
|
229
|
-
end
|
241
|
+
adapter = Net::LDAP::AuthAdapter[meth]
|
242
|
+
adapter.new(self).bind(auth)
|
230
243
|
end
|
231
244
|
end
|
232
245
|
|
233
|
-
#--
|
234
|
-
# Implements a simple user/psw authentication. Accessed by calling #bind
|
235
|
-
# with a method of :simple or :anonymous.
|
236
|
-
#++
|
237
|
-
def bind_simple(auth)
|
238
|
-
user, psw = if auth[:method] == :simple
|
239
|
-
[auth[:username] || auth[:dn], auth[:password]]
|
240
|
-
else
|
241
|
-
["", ""]
|
242
|
-
end
|
243
|
-
|
244
|
-
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
|
245
|
-
|
246
|
-
message_id = next_msgid
|
247
|
-
request = [
|
248
|
-
LdapVersion.to_ber, user.to_ber,
|
249
|
-
psw.to_ber_contextspecific(0)
|
250
|
-
].to_ber_appsequence(Net::LDAP::PDU::BindRequest)
|
251
|
-
|
252
|
-
write(request, nil, message_id)
|
253
|
-
pdu = queued_read(message_id)
|
254
|
-
|
255
|
-
if !pdu || pdu.app_tag != Net::LDAP::PDU::BindResult
|
256
|
-
raise Net::LDAP::NoBindResultError, "no bind result"
|
257
|
-
end
|
258
|
-
|
259
|
-
pdu
|
260
|
-
end
|
261
|
-
|
262
|
-
#--
|
263
|
-
# Required parameters: :mechanism, :initial_credential and
|
264
|
-
# :challenge_response
|
265
|
-
#
|
266
|
-
# Mechanism is a string value that will be passed in the SASL-packet's
|
267
|
-
# "mechanism" field.
|
268
|
-
#
|
269
|
-
# Initial credential is most likely a string. It's passed in the initial
|
270
|
-
# BindRequest that goes to the server. In some protocols, it may be empty.
|
271
|
-
#
|
272
|
-
# Challenge-response is a Ruby proc that takes a single parameter and
|
273
|
-
# returns an object that will typically be a string. The
|
274
|
-
# challenge-response block is called when the server returns a
|
275
|
-
# BindResponse with a result code of 14 (saslBindInProgress). The
|
276
|
-
# challenge-response block receives a parameter containing the data
|
277
|
-
# returned by the server in the saslServerCreds field of the LDAP
|
278
|
-
# BindResponse packet. The challenge-response block may be called multiple
|
279
|
-
# times during the course of a SASL authentication, and each time it must
|
280
|
-
# return a value that will be passed back to the server as the credential
|
281
|
-
# data in the next BindRequest packet.
|
282
|
-
#++
|
283
|
-
def bind_sasl(auth)
|
284
|
-
mech, cred, chall = auth[:mechanism], auth[:initial_credential],
|
285
|
-
auth[:challenge_response]
|
286
|
-
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (mech && cred && chall)
|
287
|
-
|
288
|
-
message_id = next_msgid
|
289
|
-
|
290
|
-
n = 0
|
291
|
-
loop {
|
292
|
-
sasl = [mech.to_ber, cred.to_ber].to_ber_contextspecific(3)
|
293
|
-
request = [
|
294
|
-
LdapVersion.to_ber, "".to_ber, sasl
|
295
|
-
].to_ber_appsequence(Net::LDAP::PDU::BindRequest)
|
296
|
-
|
297
|
-
write(request, nil, message_id)
|
298
|
-
pdu = queued_read(message_id)
|
299
|
-
|
300
|
-
if !pdu || pdu.app_tag != Net::LDAP::PDU::BindResult
|
301
|
-
raise Net::LDAP::NoBindResultError, "no bind result"
|
302
|
-
end
|
303
|
-
|
304
|
-
return pdu unless pdu.result_code == Net::LDAP::ResultCodeSaslBindInProgress
|
305
|
-
raise Net::LDAP::SASLChallengeOverflowError, "sasl-challenge overflow" if ((n += 1) > MaxSaslChallenges)
|
306
|
-
|
307
|
-
cred = chall.call(pdu.result_server_sasl_creds)
|
308
|
-
}
|
309
|
-
|
310
|
-
raise Net::LDAP::SASLChallengeOverflowError, "why are we here?"
|
311
|
-
end
|
312
|
-
private :bind_sasl
|
313
|
-
|
314
|
-
#--
|
315
|
-
# PROVISIONAL, only for testing SASL implementations. DON'T USE THIS YET.
|
316
|
-
# Uses Kohei Kajimoto's Ruby/NTLM. We have to find a clean way to
|
317
|
-
# integrate it without introducing an external dependency.
|
318
|
-
#
|
319
|
-
# This authentication method is accessed by calling #bind with a :method
|
320
|
-
# parameter of :gss_spnego. It requires :username and :password
|
321
|
-
# attributes, just like the :simple authentication method. It performs a
|
322
|
-
# GSS-SPNEGO authentication with the server, which is presumed to be a
|
323
|
-
# Microsoft Active Directory.
|
324
|
-
#++
|
325
|
-
def bind_gss_spnego(auth)
|
326
|
-
require 'ntlm'
|
327
|
-
|
328
|
-
user, psw = [auth[:username] || auth[:dn], auth[:password]]
|
329
|
-
raise Net::LDAP::BindingInformationInvalidError, "Invalid binding information" unless (user && psw)
|
330
|
-
|
331
|
-
nego = proc { |challenge|
|
332
|
-
t2_msg = NTLM::Message.parse(challenge)
|
333
|
-
t3_msg = t2_msg.response({ :user => user, :password => psw },
|
334
|
-
{ :ntlmv2 => true })
|
335
|
-
t3_msg.serialize
|
336
|
-
}
|
337
|
-
|
338
|
-
bind_sasl(:method => :sasl, :mechanism => "GSS-SPNEGO",
|
339
|
-
:initial_credential => NTLM::Message::Type1.new.serialize,
|
340
|
-
:challenge_response => nego)
|
341
|
-
end
|
342
|
-
private :bind_gss_spnego
|
343
|
-
|
344
|
-
|
345
246
|
#--
|
346
247
|
# Allow the caller to specify a sort control
|
347
248
|
#
|
@@ -652,7 +553,7 @@ class Net::LDAP::Connection #:nodoc:
|
|
652
553
|
pdu = queued_read(message_id)
|
653
554
|
|
654
555
|
if !pdu || pdu.app_tag != Net::LDAP::PDU::AddResponse
|
655
|
-
raise Net::LDAP::
|
556
|
+
raise Net::LDAP::ResponseMissingOrInvalidError, "response missing or invalid"
|
656
557
|
end
|
657
558
|
|
658
559
|
pdu
|
data/lib/net/ldap/error.rb
CHANGED
@@ -9,7 +9,41 @@ class Net::LDAP
|
|
9
9
|
|
10
10
|
class AlreadyOpenedError < Error; end
|
11
11
|
class SocketError < Error; end
|
12
|
-
class ConnectionRefusedError < Error;
|
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
|
+
def warn_deprecation_message
|
25
|
+
warn "Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead."
|
26
|
+
end
|
27
|
+
end
|
28
|
+
class ConnectionError < Error
|
29
|
+
def self.new(errors)
|
30
|
+
error = errors.first.first
|
31
|
+
if errors.size == 1
|
32
|
+
if error.kind_of? Errno::ECONNREFUSED
|
33
|
+
return Net::LDAP::ConnectionRefusedError.new(error.message)
|
34
|
+
end
|
35
|
+
|
36
|
+
return Net::LDAP::Error.new(error.message)
|
37
|
+
end
|
38
|
+
|
39
|
+
super
|
40
|
+
end
|
41
|
+
|
42
|
+
def initialize(errors)
|
43
|
+
message = "Unable to connect to any given server: \n #{errors.map { |e, h, p| "#{e.class}: #{e.message} (#{h}:#{p})" }.join("\n ")}"
|
44
|
+
super(message)
|
45
|
+
end
|
46
|
+
end
|
13
47
|
class NoOpenSSLError < Error; end
|
14
48
|
class NoStartTLSResultError < Error; end
|
15
49
|
class NoSearchBaseError < Error; end
|
data/lib/net/ldap/filter.rb
CHANGED
@@ -752,7 +752,7 @@ class Net::LDAP::Filter
|
|
752
752
|
scanner.scan(/\s*/)
|
753
753
|
if op = scanner.scan(/<=|>=|!=|:=|=/)
|
754
754
|
scanner.scan(/\s*/)
|
755
|
-
if value = scanner.scan(/(?:[-\[\]{}\w
|
755
|
+
if value = scanner.scan(/(?:[-\[\]{}\w*.+\/:@=,#\$%&!'^~\s\xC3\x80-\xCA\xAF]|[^\x00-\x7F]|\\[a-fA-F\d]{2})+/u)
|
756
756
|
# 20100313 AZ: Assumes that "(uid=george*)" is the same as
|
757
757
|
# "(uid=george* )". The standard doesn't specify, but I can find
|
758
758
|
# no examples that suggest otherwise.
|
data/lib/net/ldap/version.rb
CHANGED
data/net-ldap.gemspec
CHANGED
@@ -32,4 +32,5 @@ the most recent LDAP RFCs (4510-4519, plutions of 4520-4532).}
|
|
32
32
|
s.add_development_dependency("flexmock", "~> 1.3")
|
33
33
|
s.add_development_dependency("rake", "~> 10.0")
|
34
34
|
s.add_development_dependency("rubocop", "~> 0.28.0")
|
35
|
+
s.add_development_dependency("test-unit")
|
35
36
|
end
|
data/script/changelog
ADDED
@@ -0,0 +1,47 @@
|
|
1
|
+
#!/bin/bash
|
2
|
+
# Usage: script/changelog [-r <repo>] [-b <base>] [-h <head>]
|
3
|
+
#
|
4
|
+
# repo: BASE string of GitHub REPOsitory url. e.g. "user_or_org/REPOsitory". Defaults to git remote url.
|
5
|
+
# base: git ref to compare from. e.g. "v1.3.1". Defaults to latest git tag.
|
6
|
+
# head: git ref to compare to. Defaults to "HEAD".
|
7
|
+
#
|
8
|
+
# Generate a changelog preview from pull requests merged between `base` and
|
9
|
+
# `head`.
|
10
|
+
#
|
11
|
+
# https://github.com/jch/release-scripts/blob/master/changelog
|
12
|
+
set -e
|
13
|
+
|
14
|
+
[ $# -eq 0 ] && set -- --help
|
15
|
+
while [[ $# > 1 ]]
|
16
|
+
do
|
17
|
+
key="$1"
|
18
|
+
case $key in
|
19
|
+
-r|--repo)
|
20
|
+
repo="$2"
|
21
|
+
shift
|
22
|
+
;;
|
23
|
+
-b|--base)
|
24
|
+
base="$2"
|
25
|
+
shift
|
26
|
+
;;
|
27
|
+
-h|--head)
|
28
|
+
head="$2"
|
29
|
+
shift
|
30
|
+
;;
|
31
|
+
*)
|
32
|
+
;;
|
33
|
+
esac
|
34
|
+
shift
|
35
|
+
done
|
36
|
+
|
37
|
+
repo="${repo:-$(git remote -v | grep push | awk '{print $2}' | cut -d'/' -f4- | sed 's/\.git//')}"
|
38
|
+
base="${base:-$(git tag -l | sort -t. -k 1,1n -k 2,2n -k 3,3n | tail -n 1)}"
|
39
|
+
head="${head:-HEAD}"
|
40
|
+
api_url="https://api.github.com"
|
41
|
+
|
42
|
+
# get merged PR's. Better way is to query the API for these, but this is easier
|
43
|
+
for pr in $(git log --oneline $base..$head | grep "Merge pull request" | awk '{gsub("#",""); print $5}')
|
44
|
+
do
|
45
|
+
# frustrated with trying to pull out the right values, fell back to ruby
|
46
|
+
curl -s "$api_url/repos/$repo/pulls/$pr" | ruby -rjson -e 'pr=JSON.parse(STDIN.read); puts "* #{pr[%q(title)]} {##{pr[%q(number)]}}[#{pr[%q(html_url)]}]"'
|
47
|
+
done
|
data/script/install-openldap
CHANGED
@@ -6,68 +6,69 @@ BASE_PATH="$( cd `dirname $0`/../test/fixtures/openldap && pwd )"
|
|
6
6
|
SEED_PATH="$( cd `dirname $0`/../test/fixtures && pwd )"
|
7
7
|
|
8
8
|
dpkg -s slapd time ldap-utils gnutls-bin ssl-cert > /dev/null ||\
|
9
|
-
DEBIAN_FRONTEND=noninteractive
|
9
|
+
DEBIAN_FRONTEND=noninteractive apt-get update -y --force-yes && \
|
10
|
+
DEBIAN_FRONTEND=noninteractive apt-get install -y --force-yes slapd time ldap-utils gnutls-bin ssl-cert
|
10
11
|
|
11
|
-
|
12
|
+
/etc/init.d/slapd stop
|
12
13
|
|
13
14
|
TMPDIR=$(mktemp -d)
|
14
15
|
cd $TMPDIR
|
15
16
|
|
16
17
|
# Delete data and reconfigure.
|
17
|
-
|
18
|
-
|
19
|
-
|
20
|
-
|
21
|
-
|
18
|
+
cp -v /var/lib/ldap/DB_CONFIG ./DB_CONFIG
|
19
|
+
rm -rf /etc/ldap/slapd.d/*
|
20
|
+
rm -rf /var/lib/ldap/*
|
21
|
+
cp -v ./DB_CONFIG /var/lib/ldap/DB_CONFIG
|
22
|
+
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/slapd.conf.ldif
|
22
23
|
# Load memberof and ref-int overlays and configure them.
|
23
|
-
|
24
|
+
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/memberof.ldif
|
24
25
|
# Load retcode overlay and configure
|
25
|
-
|
26
|
+
slapadd -F /etc/ldap/slapd.d -b "cn=config" -l $BASE_PATH/retcode.ldif
|
26
27
|
|
27
28
|
# Add base domain.
|
28
|
-
|
29
|
+
slapadd -F /etc/ldap/slapd.d <<EOM
|
29
30
|
dn: dc=rubyldap,dc=com
|
30
31
|
objectClass: top
|
31
32
|
objectClass: domain
|
32
33
|
dc: rubyldap
|
33
34
|
EOM
|
34
35
|
|
35
|
-
|
36
|
-
|
36
|
+
chown -R openldap.openldap /etc/ldap/slapd.d
|
37
|
+
chown -R openldap.openldap /var/lib/ldap
|
37
38
|
|
38
|
-
|
39
|
+
/etc/init.d/slapd start
|
39
40
|
|
40
41
|
# Import seed data.
|
41
42
|
# NOTE: use ldapadd in order for memberOf and refint to apply, instead of:
|
42
|
-
# cat $SEED_PATH/seed.ldif |
|
43
|
-
/usr/bin/time
|
43
|
+
# cat $SEED_PATH/seed.ldif | slapadd -F /etc/ldap/slapd.d
|
44
|
+
/usr/bin/time ldapadd -x -D "cn=admin,dc=rubyldap,dc=com" -w passworD1 \
|
44
45
|
-h localhost -p 389 \
|
45
46
|
-f $SEED_PATH/seed.ldif
|
46
47
|
|
47
|
-
|
48
|
+
rm -rf $TMPDIR
|
48
49
|
|
49
50
|
# SSL
|
50
51
|
|
51
|
-
|
52
|
+
sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem"
|
52
53
|
|
53
|
-
|
54
|
+
sh -c "cat > /etc/ssl/ca.info <<EOF
|
54
55
|
cn = rubyldap
|
55
56
|
ca
|
56
57
|
cert_signing_key
|
57
58
|
EOF"
|
58
59
|
|
59
60
|
# Create the self-signed CA certificate:
|
60
|
-
|
61
|
+
certtool --generate-self-signed \
|
61
62
|
--load-privkey /etc/ssl/private/cakey.pem \
|
62
63
|
--template /etc/ssl/ca.info \
|
63
64
|
--outfile /etc/ssl/certs/cacert.pem
|
64
65
|
|
65
66
|
# Make a private key for the server:
|
66
|
-
|
67
|
+
certtool --generate-privkey \
|
67
68
|
--bits 1024 \
|
68
69
|
--outfile /etc/ssl/private/ldap01_slapd_key.pem
|
69
70
|
|
70
|
-
|
71
|
+
sh -c "cat > /etc/ssl/ldap01.info <<EOF
|
71
72
|
organization = Example Company
|
72
73
|
cn = ldap01.example.com
|
73
74
|
tls_www_server
|
@@ -77,14 +78,14 @@ expiration_days = 3650
|
|
77
78
|
EOF"
|
78
79
|
|
79
80
|
# Create the server certificate
|
80
|
-
|
81
|
+
certtool --generate-certificate \
|
81
82
|
--load-privkey /etc/ssl/private/ldap01_slapd_key.pem \
|
82
83
|
--load-ca-certificate /etc/ssl/certs/cacert.pem \
|
83
84
|
--load-ca-privkey /etc/ssl/private/cakey.pem \
|
84
85
|
--template /etc/ssl/ldap01.info \
|
85
86
|
--outfile /etc/ssl/certs/ldap01_slapd_cert.pem
|
86
87
|
|
87
|
-
|
88
|
+
ldapmodify -Y EXTERNAL -H ldapi:/// <<EOF | true
|
88
89
|
dn: cn=config
|
89
90
|
add: olcTLSCACertificateFile
|
90
91
|
olcTLSCACertificateFile: /etc/ssl/certs/cacert.pem
|
@@ -101,11 +102,11 @@ EOF
|
|
101
102
|
# protected by TLS/SSL whereas LDAPS, like HTTPS, is a distinct
|
102
103
|
# encrypted-from-the-start protocol that operates over TCP port 636. But we
|
103
104
|
# enable it for testing here.
|
104
|
-
|
105
|
+
sed -i -e 's|^SLAPD_SERVICES="\(.*\)"|SLAPD_SERVICES="ldap:/// ldapi:/// ldaps:///"|' /etc/default/slapd
|
105
106
|
|
106
|
-
|
107
|
-
|
108
|
-
|
109
|
-
|
107
|
+
adduser openldap ssl-cert
|
108
|
+
chgrp ssl-cert /etc/ssl/private/ldap01_slapd_key.pem
|
109
|
+
chmod g+r /etc/ssl/private/ldap01_slapd_key.pem
|
110
|
+
chmod o-r /etc/ssl/private/ldap01_slapd_key.pem
|
110
111
|
|
111
|
-
|
112
|
+
service slapd restart
|
@@ -0,0 +1,11 @@
|
|
1
|
+
require 'test_helper'
|
2
|
+
|
3
|
+
class TestAuthAdapter < Test::Unit::TestCase
|
4
|
+
def test_undefined_auth_adapter
|
5
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with('ldap.example.com', 379).once.and_return(nil)
|
6
|
+
conn = Net::LDAP::Connection.new(host: 'ldap.example.com', port: 379)
|
7
|
+
assert_raise Net::LDAP::AuthMethodUnsupportedError, "Unsupported auth method (foo)" do
|
8
|
+
conn.bind(method: :foo)
|
9
|
+
end
|
10
|
+
end
|
11
|
+
end
|
data/test/test_filter_parser.rb
CHANGED
@@ -14,6 +14,10 @@ class TestFilterParser < Test::Unit::TestCase
|
|
14
14
|
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(cn=[{something}])")
|
15
15
|
end
|
16
16
|
|
17
|
+
def test_slash
|
18
|
+
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(departmentNumber=FOO//BAR/FOO)")
|
19
|
+
end
|
20
|
+
|
17
21
|
def test_colons
|
18
22
|
assert_kind_of Net::LDAP::Filter, Net::LDAP::Filter::FilterParser.parse("(ismemberof=cn=edu:berkeley:app:calmessages:deans,ou=campus groups,dc=berkeley,dc=edu)")
|
19
23
|
end
|
data/test/test_helper.rb
CHANGED
@@ -56,7 +56,7 @@ class LDAPIntegrationTestCase < Test::Unit::TestCase
|
|
56
56
|
@service = MockInstrumentationService.new
|
57
57
|
@ldap = Net::LDAP.new \
|
58
58
|
host: ENV.fetch('INTEGRATION_HOST', 'localhost'),
|
59
|
-
port: 389,
|
59
|
+
port: ENV.fetch('INTEGRATION_PORT', 389),
|
60
60
|
admin_user: 'uid=admin,dc=rubyldap,dc=com',
|
61
61
|
admin_password: 'passworD1',
|
62
62
|
search_domains: %w(dc=rubyldap,dc=com),
|
data/test/test_ldap.rb
CHANGED
@@ -57,4 +57,11 @@ class TestLDAPInstrumentation < Test::Unit::TestCase
|
|
57
57
|
assert_equal "(uid=user1)", payload[:filter]
|
58
58
|
assert_equal result.size, payload[:size]
|
59
59
|
end
|
60
|
+
|
61
|
+
def test_obscure_auth
|
62
|
+
password = "opensesame"
|
63
|
+
assert_include(@subject.inspect, "anonymous")
|
64
|
+
@subject.auth "joe_user", password
|
65
|
+
assert_not_include(@subject.inspect, password)
|
66
|
+
end
|
60
67
|
end
|
@@ -1,6 +1,52 @@
|
|
1
1
|
require_relative 'test_helper'
|
2
2
|
|
3
3
|
class TestLDAPConnection < Test::Unit::TestCase
|
4
|
+
def capture_stderr
|
5
|
+
stderr, $stderr = $stderr, StringIO.new
|
6
|
+
yield
|
7
|
+
$stderr.string
|
8
|
+
ensure
|
9
|
+
$stderr = stderr
|
10
|
+
end
|
11
|
+
|
12
|
+
def test_list_of_hosts_with_first_host_successful
|
13
|
+
hosts = [
|
14
|
+
['test.mocked.com', 636],
|
15
|
+
['test2.mocked.com', 636],
|
16
|
+
['test3.mocked.com', 636],
|
17
|
+
]
|
18
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[0]).once.and_return(nil)
|
19
|
+
flexmock(TCPSocket).should_receive(:new).ordered.never
|
20
|
+
Net::LDAP::Connection.new(:hosts => hosts)
|
21
|
+
end
|
22
|
+
|
23
|
+
def test_list_of_hosts_with_first_host_failure
|
24
|
+
hosts = [
|
25
|
+
['test.mocked.com', 636],
|
26
|
+
['test2.mocked.com', 636],
|
27
|
+
['test3.mocked.com', 636],
|
28
|
+
]
|
29
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[0]).once.and_raise(SocketError)
|
30
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[1]).once.and_return(nil)
|
31
|
+
flexmock(TCPSocket).should_receive(:new).ordered.never
|
32
|
+
Net::LDAP::Connection.new(:hosts => hosts)
|
33
|
+
end
|
34
|
+
|
35
|
+
def test_list_of_hosts_with_all_hosts_failure
|
36
|
+
hosts = [
|
37
|
+
['test.mocked.com', 636],
|
38
|
+
['test2.mocked.com', 636],
|
39
|
+
['test3.mocked.com', 636],
|
40
|
+
]
|
41
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[0]).once.and_raise(SocketError)
|
42
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[1]).once.and_raise(SocketError)
|
43
|
+
flexmock(TCPSocket).should_receive(:new).ordered.with(*hosts[2]).once.and_raise(SocketError)
|
44
|
+
flexmock(TCPSocket).should_receive(:new).ordered.never
|
45
|
+
assert_raise Net::LDAP::ConnectionError do
|
46
|
+
Net::LDAP::Connection.new(:hosts => hosts)
|
47
|
+
end
|
48
|
+
end
|
49
|
+
|
4
50
|
def test_unresponsive_host
|
5
51
|
assert_raise Net::LDAP::Error do
|
6
52
|
Net::LDAP::Connection.new(:host => 'test.mocked.com', :port => 636)
|
@@ -14,6 +60,16 @@ class TestLDAPConnection < Test::Unit::TestCase
|
|
14
60
|
end
|
15
61
|
end
|
16
62
|
|
63
|
+
def test_connection_refused
|
64
|
+
flexmock(TCPSocket).should_receive(:new).and_raise(Errno::ECONNREFUSED)
|
65
|
+
stderr = capture_stderr do
|
66
|
+
assert_raise Net::LDAP::ConnectionRefusedError do
|
67
|
+
Net::LDAP::Connection.new(:host => 'test.mocked.com', :port => 636)
|
68
|
+
end
|
69
|
+
end
|
70
|
+
assert_equal("Deprecation warning: Net::LDAP::ConnectionRefused will be deprecated. Use Errno::ECONNREFUSED instead.\n", stderr)
|
71
|
+
end
|
72
|
+
|
17
73
|
def test_raises_unknown_exceptions
|
18
74
|
error = Class.new(StandardError)
|
19
75
|
flexmock(TCPSocket).should_receive(:new).and_raise(error)
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: net-ldap
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 0.12.0
|
5
5
|
platform: ruby
|
6
6
|
authors:
|
7
7
|
- Francis Cianfrocca
|
@@ -13,7 +13,7 @@ authors:
|
|
13
13
|
autorequire:
|
14
14
|
bindir: bin
|
15
15
|
cert_chain: []
|
16
|
-
date: 2015-
|
16
|
+
date: 2015-10-27 00:00:00.000000000 Z
|
17
17
|
dependencies:
|
18
18
|
- !ruby/object:Gem::Dependency
|
19
19
|
name: flexmock
|
@@ -57,6 +57,20 @@ dependencies:
|
|
57
57
|
- - "~>"
|
58
58
|
- !ruby/object:Gem::Version
|
59
59
|
version: 0.28.0
|
60
|
+
- !ruby/object:Gem::Dependency
|
61
|
+
name: test-unit
|
62
|
+
requirement: !ruby/object:Gem::Requirement
|
63
|
+
requirements:
|
64
|
+
- - ">="
|
65
|
+
- !ruby/object:Gem::Version
|
66
|
+
version: '0'
|
67
|
+
type: :development
|
68
|
+
prerelease: false
|
69
|
+
version_requirements: !ruby/object:Gem::Requirement
|
70
|
+
requirements:
|
71
|
+
- - ">="
|
72
|
+
- !ruby/object:Gem::Version
|
73
|
+
version: '0'
|
60
74
|
description: |-
|
61
75
|
Net::LDAP for Ruby (also called net-ldap) implements client access for the
|
62
76
|
Lightweight Directory Access Protocol (LDAP), an IETF standard protocol for
|
@@ -106,6 +120,10 @@ files:
|
|
106
120
|
- lib/net/ber/core_ext/string.rb
|
107
121
|
- lib/net/ber/core_ext/true_class.rb
|
108
122
|
- lib/net/ldap.rb
|
123
|
+
- lib/net/ldap/auth_adapter.rb
|
124
|
+
- lib/net/ldap/auth_adapter/gss_spnego.rb
|
125
|
+
- lib/net/ldap/auth_adapter/sasl.rb
|
126
|
+
- lib/net/ldap/auth_adapter/simple.rb
|
109
127
|
- lib/net/ldap/connection.rb
|
110
128
|
- lib/net/ldap/dataset.rb
|
111
129
|
- lib/net/ldap/dn.rb
|
@@ -118,6 +136,7 @@ files:
|
|
118
136
|
- lib/net/ldap/version.rb
|
119
137
|
- lib/net/snmp.rb
|
120
138
|
- net-ldap.gemspec
|
139
|
+
- script/changelog
|
121
140
|
- script/install-openldap
|
122
141
|
- script/package
|
123
142
|
- script/release
|
@@ -139,6 +158,7 @@ files:
|
|
139
158
|
- test/support/vm/openldap/.gitignore
|
140
159
|
- test/support/vm/openldap/README.md
|
141
160
|
- test/support/vm/openldap/Vagrantfile
|
161
|
+
- test/test_auth_adapter.rb
|
142
162
|
- test/test_dn.rb
|
143
163
|
- test/test_entry.rb
|
144
164
|
- test/test_filter.rb
|
@@ -177,7 +197,7 @@ required_rubygems_version: !ruby/object:Gem::Requirement
|
|
177
197
|
version: '0'
|
178
198
|
requirements: []
|
179
199
|
rubyforge_project:
|
180
|
-
rubygems_version: 2.2.
|
200
|
+
rubygems_version: 2.2.3
|
181
201
|
signing_key:
|
182
202
|
specification_version: 4
|
183
203
|
summary: Net::LDAP for Ruby (also called net-ldap) implements client access for the
|
@@ -202,6 +222,7 @@ test_files:
|
|
202
222
|
- test/support/vm/openldap/.gitignore
|
203
223
|
- test/support/vm/openldap/README.md
|
204
224
|
- test/support/vm/openldap/Vagrantfile
|
225
|
+
- test/test_auth_adapter.rb
|
205
226
|
- test/test_dn.rb
|
206
227
|
- test/test_entry.rb
|
207
228
|
- test/test_filter.rb
|