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