From 84ab4c2bd5a66fdf682dd9d543692236fd969a9c Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 18:44:21 -0700 Subject: [PATCH 01/39] fix iptables blackholing for macOS --- script/install-openldap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/install-openldap b/script/install-openldap index efb0cbaa..2d551109 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -110,6 +110,6 @@ chmod g+r /etc/ssl/private/ldap01_slapd_key.pem chmod o-r /etc/ssl/private/ldap01_slapd_key.pem # Drop packets on a secondary port used to specific timeout tests -iptables -A OUTPUT -p tcp -j DROP --dport 8389 +iptables -A INPUT -p tcp -j DROP --dport 8389 service slapd restart From 7b2bb0284d3df4bfeb0b56f114bf1aad6dc90a0d Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 19:13:55 -0700 Subject: [PATCH 02/39] new fixture CA, now with private key --- script/install-openldap | 37 ++++++++++++++++++++++--------------- test/fixtures/ca/ca.info | 4 ++++ test/fixtures/ca/cacert.pem | 18 ++++++++++++++++++ test/fixtures/ca/cakey.pem | 27 +++++++++++++++++++++++++++ 4 files changed, 71 insertions(+), 15 deletions(-) create mode 100644 test/fixtures/ca/ca.info create mode 100644 test/fixtures/ca/cacert.pem create mode 100644 test/fixtures/ca/cakey.pem diff --git a/script/install-openldap b/script/install-openldap index 2d551109..f356b61a 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -48,20 +48,20 @@ chown -R openldap.openldap /var/lib/ldap rm -rf $TMPDIR # SSL +export CA_CERT="/etc/ssl/certs/cacert.pem" +export CA_KEY="/etc/ssl/private/cakey.pem" +export CA_INFO="/etc/ssl/ca.info" -sh -c "certtool --generate-privkey > /etc/ssl/private/cakey.pem" +# If you ever need to regenerate these... +# certtool --generate-privkey > /path/to/cakey.pem +# certtool --generate-self-signed \ +# --load-privkey /path/to/cakey.pem +# --template /path/to/ca.info +# --outfile /path/to/cacert.pem -sh -c "cat > /etc/ssl/ca.info < /etc/ssl/ldap01.info <> /etc/hosts +grep ldap02 /etc/hosts || echo "127.0.0.1 ldap02.example.com" >> /etc/hosts +grep bogus /etc/hosts || echo "127.0.0.1 bogus.example.com" >> /etc/hosts + service slapd restart diff --git a/test/fixtures/ca/ca.info b/test/fixtures/ca/ca.info new file mode 100644 index 00000000..c0fd3629 --- /dev/null +++ b/test/fixtures/ca/ca.info @@ -0,0 +1,4 @@ +cn = rubyldap +ca +cert_signing_key +expiration_days = 7200 diff --git a/test/fixtures/ca/cacert.pem b/test/fixtures/ca/cacert.pem new file mode 100644 index 00000000..c4f5b0fc --- /dev/null +++ b/test/fixtures/ca/cacert.pem @@ -0,0 +1,18 @@ +-----BEGIN CERTIFICATE----- +MIIC7zCCAdegAwIBAgIMV7ur2wQbbBBUX/gBMA0GCSqGSIb3DQEBCwUAMBMxETAP +BgNVBAMTCHJ1YnlsZGFwMB4XDTE2MDgyMzAxNTAxOVoXDTM2MDUxMDAxNTAxOVow +EzERMA8GA1UEAxMIcnVieWxkYXAwggEiMA0GCSqGSIb3DQEBAQUAA4IBDwAwggEK +AoIBAQDIXIIUk/PJ8UnmthzX1ZC5pej7qwQDILA/o4/EkU1rBfGkHNhJihzOoW+1 +QjixcxjVM8pZXM0+bkOr/UY4ymqQnnW7a8U6Rc1+4Mhz7jKtjChfjWkAX857alL7 +2F5M1pUBvQ1WdXXFOwO0vyDT54UzkFMr/lvKXrd4/kNJYQE87+B0igICEDocFLO3 +SchtH0YpSzE80b0Fn1O1noS3LU9Eo+XsMoBMHVVrKOb/Yzs5Z1hfPrHOpB+z3VTe +4/LcbbcMoc20Ypjq+kamuYo6uGoy0lzgmgwQgJtmxl8EhsIrZuUw80yJZqi3bLht +8UZbVM1dV1/Hh7danmlWqZnI579FAgMBAAGjQzBBMA8GA1UdEwEB/wQFMAMBAf8w +DwYDVR0PAQH/BAUDAwcEADAdBgNVHQ4EFgQUZ4HlXJgf2tIxLhDOB07SC200XG8w +DQYJKoZIhvcNAQELBQADggEBAIee6oT01p6e300scQTo/VPELf14ebrZXDqtJ7HR +egHZRrSzyQgxnnyFfoazG9bmgX/xgDvH8CxW4Q7OHH2ybGA5z2FfK+uSAjKHPR2y +8EjAKfQUDo0CBlcU0otvk8KhyNmu3sbCO6QGlnDDnWo78UDOdfeflvCp4HH+wdnU +ZSKTxaJe7BbBPMm6VZGhqa4O7MOOiupcGUt0emsyA1mVixkhr+6/aO2FLdiXwclX +GhYBZg5xxbM5Hn8LbjfRsaqCjBpOXLKnuUGDQSQj1TtRFzRuiGU4tHpoBnQGCYNa +bhFP7hjfwcjKUSizHM89KugrVgpnDh6oKn+xrhSdcKTmlag= +-----END CERTIFICATE----- diff --git a/test/fixtures/ca/cakey.pem b/test/fixtures/ca/cakey.pem new file mode 100644 index 00000000..325f36c7 --- /dev/null +++ b/test/fixtures/ca/cakey.pem @@ -0,0 +1,27 @@ +-----BEGIN RSA PRIVATE KEY----- +MIIEowIBAAKCAQEAyFyCFJPzyfFJ5rYc19WQuaXo+6sEAyCwP6OPxJFNawXxpBzY +SYoczqFvtUI4sXMY1TPKWVzNPm5Dq/1GOMpqkJ51u2vFOkXNfuDIc+4yrYwoX41p +AF/Oe2pS+9heTNaVAb0NVnV1xTsDtL8g0+eFM5BTK/5byl63eP5DSWEBPO/gdIoC +AhA6HBSzt0nIbR9GKUsxPNG9BZ9TtZ6Ety1PRKPl7DKATB1Vayjm/2M7OWdYXz6x +zqQfs91U3uPy3G23DKHNtGKY6vpGprmKOrhqMtJc4JoMEICbZsZfBIbCK2blMPNM +iWaot2y4bfFGW1TNXVdfx4e3Wp5pVqmZyOe/RQIDAQABAoIBAALhQYVmMwTeEP/d +8kAv86qXdefYJ3CcEax4f2KF7CTzqut+9qTn9U4LB/4E+6ehTeQSoH/0U4boMtTQ +CShb0HhPrsWI4QbbZf7C4F66N8RC1Xm6IJ4+wksH1jWEgKZ+Fxo1S3HIsm6pUH5S +mPgyxbleA7QILe2UuvJkRTdSy5/ClGROTXAZfA7NE/yL+cUjAOyQfxs/SxcMwnxK +phGZaAfYRpvExtRO9CAdlmkC9RgYWOdC/r7wHehpY7fi/FqBd46w+AV3ougKGt9r +yOEcXVrJRQtDR5UWivUOs34MCPQa2T+XHn/WLgeWE6bNaw5SyLr4oolb10Iue+Hw +v23W5oECgYEA7rEE7/6rTkHodVI9wrYg007WDQmeR6Y0gwiX6oGQpftXExfHjHio +yr0qwbL/UOFkWfJ8ORNXa6hHIDfxI2Kkg7vgt8SaLK8c0zhszJpcYmAx63Kk+BUO +/S863Ptz28rGmXJxjo5GYUHR7rjvRefauV6SSUo9rbocFcyeV/UlXpUCgYEA1uPx +TSXt2MBRiGp+E4tNPj+16QaF+4ety3+a4vlsY2ALejkjC3I5Lf1s4b0SW6eEn/U2 +PYFzm3FqsDqYhSas64b2s3Cw8x2yQ7rCD3SKGoiJqUSPwLkZjgUXC1gDaMkJXzEX +L9yBEBVfNRYCCk4EY/Wz1C5gJ4PFtLb8NbXGofECgYEAr506PsEmlItVVoxNuGZ7 +vDxyrGD5PUoBtK6r5vOw0w4bQIbsYGOd/Jw1SxJBWuaaCLupveyHE0RaIFBIcHpx +BCNE8LALpvinwpfvJJIlipOv5sUQrx3/SzRmoJO46GtGtztGZVY0XfYpWPRjxxER +EfWMt7ORsbIOW9OSZLCO8AkCgYA1c/HcDOlDF2OwmTzPQ8FtEJABbPv6+18B1bYD +a6PIfGWee4P6HumWRQnGhS+B2QOmfmqFliPZsLanK4ww4tP0qlfHfuqlLufe7R/E +lGqd+wSzNDjF6cUvjJiU28nNUOSh5yYrY6A/DfHm1JihU5LIAqA+0WJdseuF7laC +TbshIQKBgGhwjXS/A0twYMTZwc/H/JGik8yBXK/GZ4BAlIv5hryRmKMbik8sLtEF +Lq/Jt9qsQ6Zob2XZFAi+vZJykvX0ySxngHEOkiHxwyQNQTEfBPifFPkOIKhVKt9t +D4w2FfF4Bai36Wdaa97VXiBBgafIe7z5VDJXRS2HK9SHuYH3kmJu +-----END RSA PRIVATE KEY----- From 21373615cae10c3123d415d83938a65dee410b43 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 19:19:35 -0700 Subject: [PATCH 03/39] vagrant fix for macOS v Linux? --- test/integration/test_bind.rb | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index b7fa35bc..e6eb89b4 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -10,7 +10,9 @@ def test_bind_timeout error = assert_raise Net::LDAP::Error do @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1") end - assert_equal('Connection timed out - user specified timeout', error.message) + msgs = ['Operation timed out - user specified timeout', + 'Connection timed out - user specified timeout'] + assert_send([msgs, :include?, error.message]) end def test_bind_anonymous_fail From 38b6147ac77f0e071df2b93002d30fde95d40a6c Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 19:26:07 -0700 Subject: [PATCH 04/39] helper should use the new CA --- test/test_helper.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/test_helper.rb b/test/test_helper.rb index cd34017c..580a2916 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -14,7 +14,7 @@ if File.exist?("/etc/ssl/certs/cacert.pem") "/etc/ssl/certs/cacert.pem" else - File.expand_path("fixtures/cacert.pem", File.dirname(__FILE__)) + File.expand_path("fixtures/ca/cacert.pem", File.dirname(__FILE__)) end end From b42e931359ec2c42efb8bc72a37209a59d7ea816 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 19:42:17 -0700 Subject: [PATCH 05/39] rubocop fix --- lib/net/ldap/connection.rb | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 05f676cc..ef8341ae 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -392,12 +392,11 @@ def search(args = nil) # should collect this into a private helper to clarify the structure query_limit = 0 if size > 0 - if paged - query_limit = (((size - n_results) < 126) ? (size - - n_results) : 0) - else - query_limit = size - end + query_limit = if paged + (((size - n_results) < 126) ? (size - n_results) : 0) + else + size + end end request = [ From 22eaf7caf0e5800a7517688760dc807c5f7de230 Mon Sep 17 00:00:00 2001 From: "jean-pierre.vanriel" Date: Fri, 15 Jan 2016 01:26:10 +0200 Subject: [PATCH 06/39] cherry pick from https://github.com/ruby-ldap/ruby-net-ldap/pull/259 --- lib/net/ldap/connection.rb | 3 +++ 1 file changed, 3 insertions(+) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index ef8341ae..a89da562 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -52,6 +52,9 @@ def open_connection(server) hosts.each do |host, port| begin prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout) + if encryption[:tls_options][:verify_mode] != OpenSSL::SSL::VERIFY_NONE + @conn.post_connection_check(host) + end return rescue Net::LDAP::Error, SocketError, SystemCallError, OpenSSL::SSL::SSLError => e From d7b36d1c8e9f8457e9aca4fa1ea0c7929baab5b6 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 20:38:47 -0700 Subject: [PATCH 07/39] check that the encryption hash is defined before using it --- lib/net/ldap/connection.rb | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index a89da562..43ff72c9 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -52,7 +52,8 @@ def open_connection(server) hosts.each do |host, port| begin prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout) - if encryption[:tls_options][:verify_mode] != OpenSSL::SSL::VERIFY_NONE + if encryption && encryption[:tls_options] && + encryption[:tls_options][:verify_mode] != OpenSSL::SSL::VERIFY_NONE @conn.post_connection_check(host) end return From 748f1b9fae8cf7947930578b0dcf4250bce3d9bf Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 20:47:52 -0700 Subject: [PATCH 08/39] add tests for cert/hostname mismatch --- test/integration/test_bind.rb | 25 ++++++++++++++++++++++++- 1 file changed, 24 insertions(+), 1 deletion(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index e6eb89b4..2c2c71fb 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -37,8 +37,31 @@ def test_bind_tls_with_cafile end def test_bind_tls_with_verify_none - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(:verify_mode => OpenSSL::SSL::VERIFY_NONE) + @ldap.host = '127.0.0.1' + @ldap.port = 9389 + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_NONE, + ) @ldap.encryption(method: :start_tls, tls_options: tls_options) assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect end + + def test_bind_tls_with_bad_hostname + @ldap.host = '127.0.0.1' + @ldap.port = 9389 + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ca_file => CA_FILE, + ) + @ldap.encryption(method: :start_tls, tls_options: tls_options) + error = assert_raise Net::LDAP::Error do + @ldap.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + end + assert_equal( + "hostname \"#{@ldap.host}\" does not match the server certificate", + error.message, + ) + end end From 9bab5a5d49bfd7747fa8996009a7b9c14c34e52d Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 20:48:18 -0700 Subject: [PATCH 09/39] stupid portforwarding tricks for local testing --- script/install-openldap | 12 ++++++++++++ test/support/vm/openldap/Vagrantfile | 1 + 2 files changed, 13 insertions(+) diff --git a/script/install-openldap b/script/install-openldap index f356b61a..935af304 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -79,6 +79,15 @@ signing_key expiration_days = 3650 EOF" +# The integration server may be accessed by IP address, in which case +# we want some of the IPs included in the cert. We skip loopback (127.0.0.1) +# because that's the IP we use in the integration test for cert name mismatches. +ADDRS=$(ifconfig -a | grep 'inet addr:' | cut -f 2 -d : | cut -f 1 -d ' ') +for ip in $ADDRS; do + if [ "x$ip" = 'x127.0.0.1' ]; then continue; fi + echo "ip_address = $ip" >> /etc/ssl/ldap01.info +done + # Create the server certificate certtool --generate-certificate \ --load-privkey /etc/ssl/private/ldap01_slapd_key.pem \ @@ -114,6 +123,9 @@ chmod o-r /etc/ssl/private/ldap01_slapd_key.pem # Drop packets on a secondary port used to specific timeout tests iptables -A INPUT -p tcp -j DROP --dport 8389 +# Forward a port for Vagrant +iptables -t nat -A PREROUTING -p tcp --dport 9389 -j REDIRECT --to-port 389 + # fix up /etc/hosts for cert validation grep ldap01 /etc/hosts || echo "127.0.0.1 ldap01.example.com" >> /etc/hosts grep ldap02 /etc/hosts || echo "127.0.0.1 ldap02.example.com" >> /etc/hosts diff --git a/test/support/vm/openldap/Vagrantfile b/test/support/vm/openldap/Vagrantfile index 96233e92..1f375e76 100644 --- a/test/support/vm/openldap/Vagrantfile +++ b/test/support/vm/openldap/Vagrantfile @@ -10,6 +10,7 @@ Vagrant.configure(VAGRANTFILE_API_VERSION) do |config| config.vm.box = "hashicorp/precise64" config.vm.network "private_network", type: :dhcp + config.vm.network "forwarded_port", guest: 389, host: 9389 config.ssh.forward_agent = true From 381fdf4fed5c39d36ada17ec8b2f07b3165cd003 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 20:54:02 -0700 Subject: [PATCH 10/39] omit example --- test/integration/test_bind.rb | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 2c2c71fb..9efb8479 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -64,4 +64,9 @@ def test_bind_tls_with_bad_hostname error.message, ) end + + def test_bind_tls_with_good_hostname + omit_if true + assert_true false + end end From fd1c8237f6523e3164f718e0773053670cd170a0 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:12:04 -0700 Subject: [PATCH 11/39] doc tweak --- README.rdoc | 9 +++------ test/support/vm/openldap/README.md | 27 +++++++++++++++++++++++++-- 2 files changed, 28 insertions(+), 8 deletions(-) diff --git a/README.rdoc b/README.rdoc index 53e2d468..df27b969 100644 --- a/README.rdoc +++ b/README.rdoc @@ -52,12 +52,9 @@ This task will run the test suite and the rake rubotest -To run the integration tests against an LDAP server: - - cd test/support/vm/openldap - vagrant up - cd ../../../.. - INTEGRATION=openldap bundle exec rake rubotest +CI takes too long? If your local box supports +{Vagrant}(https://www.vagrantup.com/), you can run most of the tests +in a VM on your local box. For more details and setup instructions, see {test/support/vm/openldap/README.md}(https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md) == Release diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md index a2769567..31a17cda 100644 --- a/test/support/vm/openldap/README.md +++ b/test/support/vm/openldap/README.md @@ -1,8 +1,27 @@ # Local OpenLDAP Integration Testing -Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration tests against OpenLDAP locally. +Set up a [Vagrant](http://www.vagrantup.com/) VM to run integration +tests against OpenLDAP locally. *NOTE*: To support some of the SSL tests, +Vagrant forwards localhost port 9389 to VM host port 9389. The port mapping +goes away when you run `vagrant destroy`. -To run integration tests locally: +## Install Vagrant + +*NOTE*: The Vagrant gem (`gem install vagrant`) is +[no longer supported](https://www.vagrantup.com/docs/installation/) + +If you use Homebrew on macOS: +``` bash +$ brew update +$ brew cask install virtualbox +$ brew cask install vagrant +$ brew cask install vagrant-manager +``` + +Installing Vagrant and virtualbox on other operating systems is left +as an exercise to the reader. + +## Run the tests ``` bash # start VM (from the correct directory) @@ -27,6 +46,10 @@ $ export INTEGRATION_HOST=$ip # now run tests without having to set ENV variables $ time bundle exec rake + +# Once you're all done +$ cd test/support/vm/openldap +$ vagrant destroy ``` You may need to `gem install vagrant` first in order to provision the VM. From 7593af13d61a3976619febb7a02bc84706d33559 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:14:53 -0700 Subject: [PATCH 12/39] too many markdown syntaxes --- README.rdoc | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/README.rdoc b/README.rdoc index df27b969..f1b1ea36 100644 --- a/README.rdoc +++ b/README.rdoc @@ -53,8 +53,9 @@ This task will run the test suite and the rake rubotest CI takes too long? If your local box supports -{Vagrant}(https://www.vagrantup.com/), you can run most of the tests -in a VM on your local box. For more details and setup instructions, see {test/support/vm/openldap/README.md}(https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md) +{Vagrant}[https://www.vagrantup.com/], you can run most of the tests +in a VM on your local box. For more details and setup instructions, see +{test/support/vm/openldap/README.md}[https://github.com/ruby-ldap/ruby-net-ldap/tree/master/test/support/vm/openldap/README.md] == Release From 052f90d29fc28ba406db44e713a47b13c3139d9e Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:16:05 -0700 Subject: [PATCH 13/39] remove stale reference to gem --- test/support/vm/openldap/README.md | 2 -- 1 file changed, 2 deletions(-) diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md index 31a17cda..9b37ed5e 100644 --- a/test/support/vm/openldap/README.md +++ b/test/support/vm/openldap/README.md @@ -51,5 +51,3 @@ $ time bundle exec rake $ cd test/support/vm/openldap $ vagrant destroy ``` - -You may need to `gem install vagrant` first in order to provision the VM. From ca4e39078848b04e071b2b1a17039fdb35607bca Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:43:00 -0700 Subject: [PATCH 14/39] extra ldap object for multiple host tests --- test/test_helper.rb | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/test/test_helper.rb b/test/test_helper.rb index 580a2916..b1c2e07d 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -62,5 +62,13 @@ def setup search_domains: %w(dc=rubyldap,dc=com), uid: 'uid', instrumentation_service: @service + + @ldap_multi = Net::LDAP.new \ + hosts: [['ldap01.example.com', 389], ['ldap02.example.com', 389]], + admin_user: 'uid=admin,dc=rubyldap,dc=com', + admin_password: 'passworD1', + search_domains: %w(dc=rubyldap,dc=com), + uid: 'uid', + instrumentation_service: @service end end From c6a465fbb86707ed6315a4871927d59bc033a20c Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:43:44 -0700 Subject: [PATCH 15/39] add multi-host SSL checks --- test/integration/test_bind.rb | 73 +++++++++++++++++++++++++++++++++-- 1 file changed, 70 insertions(+), 3 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 9efb8479..7c3ed59b 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -65,8 +65,75 @@ def test_bind_tls_with_bad_hostname ) end - def test_bind_tls_with_good_hostname - omit_if true - assert_true false + def test_bind_tls_with_valid_hostname + @ldap.host = 'localhost' + @ldap.port = 9389 + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ca_file => CA_FILE, + ) + @ldap.encryption(method: :start_tls, tls_options: tls_options) + assert @ldap.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + @ldap.get_operation_result.inspect + end + + # The following depend on /etc/hosts hacking. + # We can do that on CI, but it's less than cool on people's dev boxes + def test_bind_tls_with_multiple_hosts + omit_unless ENV['TRAVIS'] == 'true' + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ca_file => CA_FILE, + ) + @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) + assert @ldap_multi.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + @ldap_multi.get_operation_result.inspect + end + + def test_bind_tls_with_multiple_bogus_hosts + omit_unless ENV['TRAVIS'] == 'true' + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_PEER, + :ca_file => CA_FILE, + ) + @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) + error = assert_raise Net::LDAP::Error do + @ldap_multi.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + end + assert_equal("TODO - fix this", + error.message) + end + + def test_bind_tls_with_multiple_bogus_hosts_no_verification + omit_unless ENV['TRAVIS'] == 'true' + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :verify_mode => OpenSSL::SSL::VERIFY_NONE, + ) + @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) + assert @ldap_multi.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + @ldap_multi.get_operation_result.inspect + end + + def test_bind_tls_with_multiple_bogus_hosts_ca_check_only + omit_unless ENV['TRAVIS'] == 'true' + tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( + :ca_file => CA_FILE, + ) + @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) + assert @ldap_multi.bind(method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1") + @ldap_multi.get_operation_result.inspect end end From 1300bc0944a019b8f21431433dbb64c15f80a1aa Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 21:53:36 -0700 Subject: [PATCH 16/39] include "localhost" as valid cert name --- script/install-openldap | 1 + 1 file changed, 1 insertion(+) diff --git a/script/install-openldap b/script/install-openldap index 935af304..83a09153 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -73,6 +73,7 @@ organization = Example Company cn = ldap01.example.com dns_name = ldap01.example.com dns_name = ldap02.example.com +dns_name = localhost tls_www_server encryption_key signing_key From 440ce7f01126983c5e368322e531db60007faedf Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 22:36:29 -0700 Subject: [PATCH 17/39] tidy up the TLS tests --- test/integration/test_bind.rb | 120 ++++++++++++++++++---------------- test/test_helper.rb | 16 ++--- 2 files changed, 70 insertions(+), 66 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 7c3ed59b..a0738f16 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -2,13 +2,14 @@ class TestBindIntegration < LDAPIntegrationTestCase def test_bind_success - assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end def test_bind_timeout @ldap.port = 8389 error = assert_raise Net::LDAP::Error do - @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1") + @ldap.bind BIND_CREDS end msgs = ['Operation timed out - user specified timeout', 'Connection timed out - user specified timeout'] @@ -16,7 +17,8 @@ def test_bind_timeout end def test_bind_anonymous_fail - refute @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: ""), @ldap.get_operation_result.inspect + refute @ldap.bind(BIND_CREDS.merge(password: '')), + @ldap.get_operation_result.inspect result = @ldap.get_operation_result assert_equal Net::LDAP::ResultCodeUnwillingToPerform, result.code @@ -27,37 +29,40 @@ def test_bind_anonymous_fail end def test_bind_fail - refute @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "not my password"), @ldap.get_operation_result.inspect + refute @ldap.bind(BIND_CREDS.merge(password: "not my password")), + @ldap.get_operation_result.inspect end def test_bind_tls_with_cafile - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge(:ca_file => CA_FILE) - @ldap.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(ca_file: CA_FILE), + ) + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end def test_bind_tls_with_verify_none @ldap.host = '127.0.0.1' @ldap.port = 9389 - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_NONE, + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE), ) - @ldap.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap.bind(method: :simple, username: "uid=user1,ou=People,dc=rubyldap,dc=com", password: "passworD1"), @ldap.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end def test_bind_tls_with_bad_hostname @ldap.host = '127.0.0.1' @ldap.port = 9389 - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_PEER, - :ca_file => CA_FILE, + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE), ) - @ldap.encryption(method: :start_tls, tls_options: tls_options) error = assert_raise Net::LDAP::Error do - @ldap.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") + @ldap.bind BIND_CREDS end assert_equal( "hostname \"#{@ldap.host}\" does not match the server certificate", @@ -68,44 +73,43 @@ def test_bind_tls_with_bad_hostname def test_bind_tls_with_valid_hostname @ldap.host = 'localhost' @ldap.port = 9389 - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_PEER, - :ca_file => CA_FILE, + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE), ) - @ldap.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") - @ldap.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end # The following depend on /etc/hosts hacking. # We can do that on CI, but it's less than cool on people's dev boxes def test_bind_tls_with_multiple_hosts omit_unless ENV['TRAVIS'] == 'true' - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_PEER, - :ca_file => CA_FILE, + + @ldap.host = nil + @ldap.hosts = [['ldap01.example.com', 389], ['ldap02.example.com', 389]] + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE), ) - @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap_multi.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") - @ldap_multi.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end def test_bind_tls_with_multiple_bogus_hosts omit_unless ENV['TRAVIS'] == 'true' - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_PEER, - :ca_file => CA_FILE, + + @ldap.host = nil + @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE), ) - @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] - @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) error = assert_raise Net::LDAP::Error do - @ldap_multi.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") + @ldap.bind BIND_CREDS end assert_equal("TODO - fix this", error.message) @@ -113,27 +117,27 @@ def test_bind_tls_with_multiple_bogus_hosts def test_bind_tls_with_multiple_bogus_hosts_no_verification omit_unless ENV['TRAVIS'] == 'true' - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :verify_mode => OpenSSL::SSL::VERIFY_NONE, + + @ldap.host = nil + @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE), ) - @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] - @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap_multi.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") - @ldap_multi.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end def test_bind_tls_with_multiple_bogus_hosts_ca_check_only omit_unless ENV['TRAVIS'] == 'true' - tls_options = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge( - :ca_file => CA_FILE, + + @ldap.host = nil + @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(ca_file: CA_FILE), ) - @ldap_multi.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] - @ldap_multi.encryption(method: :start_tls, tls_options: tls_options) - assert @ldap_multi.bind(method: :simple, - username: "uid=user1,ou=People,dc=rubyldap,dc=com", - password: "passworD1") - @ldap_multi.get_operation_result.inspect + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect end end diff --git a/test/test_helper.rb b/test/test_helper.rb index b1c2e07d..0a976be4 100644 --- a/test/test_helper.rb +++ b/test/test_helper.rb @@ -18,6 +18,14 @@ end end +BIND_CREDS = { + method: :simple, + username: "uid=user1,ou=People,dc=rubyldap,dc=com", + password: "passworD1", +}.freeze + +TLS_OPTS = OpenSSL::SSL::SSLContext::DEFAULT_PARAMS.merge({}).freeze + if RUBY_VERSION < "2.0" class String def b @@ -62,13 +70,5 @@ def setup search_domains: %w(dc=rubyldap,dc=com), uid: 'uid', instrumentation_service: @service - - @ldap_multi = Net::LDAP.new \ - hosts: [['ldap01.example.com', 389], ['ldap02.example.com', 389]], - admin_user: 'uid=admin,dc=rubyldap,dc=com', - admin_password: 'passworD1', - search_domains: %w(dc=rubyldap,dc=com), - uid: 'uid', - instrumentation_service: @service end end From 199f429bcf3b5cf13e075eb99d63a87e3b9188a6 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 22:45:43 -0700 Subject: [PATCH 18/39] fix up to look like https://github.com/ruby-ldap/ruby-net-ldap/pull/259#discussion-diff-57030107 --- lib/net/ldap/connection.rb | 11 ++++++++--- 1 file changed, 8 insertions(+), 3 deletions(-) diff --git a/lib/net/ldap/connection.rb b/lib/net/ldap/connection.rb index 43ff72c9..4f311748 100644 --- a/lib/net/ldap/connection.rb +++ b/lib/net/ldap/connection.rb @@ -52,9 +52,14 @@ def open_connection(server) hosts.each do |host, port| begin prepare_socket(server.merge(socket: @socket_class.new(host, port, socket_opts)), timeout) - if encryption && encryption[:tls_options] && - encryption[:tls_options][:verify_mode] != OpenSSL::SSL::VERIFY_NONE - @conn.post_connection_check(host) + if encryption + if encryption[:tls_options] && + encryption[:tls_options][:verify_mode] && + encryption[:tls_options][:verify_mode] == OpenSSL::SSL::VERIFY_NONE + warn "not verifying SSL hostname of LDAPS server '#{host}:#{port}'" + else + @conn.post_connection_check(host) + end end return rescue Net::LDAP::Error, SocketError, SystemCallError, From caf191102f5d04cb1e4222b6b75c15a44470134e Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 22:49:16 -0700 Subject: [PATCH 19/39] remove useless test CA --- test/fixtures/cacert.pem | 20 -------------------- 1 file changed, 20 deletions(-) delete mode 100644 test/fixtures/cacert.pem diff --git a/test/fixtures/cacert.pem b/test/fixtures/cacert.pem deleted file mode 100644 index f8b134e1..00000000 --- a/test/fixtures/cacert.pem +++ /dev/null @@ -1,20 +0,0 @@ ------BEGIN CERTIFICATE----- -MIIDRzCCAf+gAwIBAgIEVHpbmjANBgkqhkiG9w0BAQsFADATMREwDwYDVQQDEwhy -dWJ5bGRhcDAeFw0xNDExMjkyMzQ5NDZaFw0xNTExMjkyMzQ5NDZaMBMxETAPBgNV -BAMTCHJ1YnlsZGFwMIIBUjANBgkqhkiG9w0BAQEFAAOCAT8AMIIBOgKCATEA4pKe -cDCNuL53fkpO/WSAS+gmMTsOs+oOK71kZlk2QT/MBz8TxC6m358qCADjnXcMVVxa -ySQbQlVKZMkIvLNciZbiLDgC5II0NbHACNa8rqenoKRjS4J9W3OhA8EmnXn/Me+8 -uMCI9tfnKNRZYdkQZlra4I+Idn+xYfl/5q5b/7ZjPS2zY/585hFEYE+5vfOZVBSU -3HMNSeuJvTehLv7dD7aQfXNM4cRgHXequkJQ/HLLFAO4AgJ+LJrFWpj7GWz3crgr -9G5px4T78wJH3NQiOsG6UBXPw8c4T+Z6GAWX2l1zs1gZsaiCVbAraqK3404lL7yp -+ThbsW3ifzgNPhmjScXBLdbEDrrAKosW7kkTOGzxiMCBmNlj2SKhcztoduAtfF1f -Fs2Jk8MRTHwO8ThD7wIDAQABo0MwQTAPBgNVHRMBAf8EBTADAQH/MA8GA1UdDwEB -/wQFAwMHBAAwHQYDVR0OBBYEFJDm67ekyFu4/Z7VcO6Vk/5pinGcMA0GCSqGSIb3 -DQEBCwUAA4IBMQDHeEPzfYRtjynpUKyrtxx/6ZVOfCLuz4eHkBZggz/pJacDCv/a -I//W03XCk8RWq/fWVVUzvxXgPwnYcw992PLM7XW81zp6ruRUDWooYnjHZZz3bRhe -kC4QvM2mZhcsMVmhmWWKZn81qXgVdUY1XNRhk87cuXjF/UTpEieFvWAsCUkFZkqB -AmySCuI/FuPaauT1YAltkIlYAEIGNJGZDMf2BTVUQpXhTXeS9/AZWLNDBwiq+fwo -YYnsr9MnBXCEmg1gVSR/Ay2AZmbYfiYtb5kU8uq2lSWAUb4LX6HZl82wo3OilrJ2 -WXl6Qf+Fcy4qqkRt4AKHjtzizpEDCOVYuuG0Zoy+QnxNXRsEzpb8ymnJFrcgYfk/ -6Lv2gWAFl5FqCZp7gBWg55eL2coT4C+mbNTF ------END CERTIFICATE----- From c801132db0a692acabe56dd50c57ef6e80b2f1af Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 23:16:47 -0700 Subject: [PATCH 20/39] only use tcp/9389 with vagrant, use the right exception for bad TLS connections --- test/integration/test_bind.rb | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index a0738f16..d034b1fd 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -44,7 +44,7 @@ def test_bind_tls_with_cafile def test_bind_tls_with_verify_none @ldap.host = '127.0.0.1' - @ldap.port = 9389 + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE), @@ -55,13 +55,13 @@ def test_bind_tls_with_verify_none def test_bind_tls_with_bad_hostname @ldap.host = '127.0.0.1' - @ldap.port = 9389 + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE), ) - error = assert_raise Net::LDAP::Error do + error = assert_raise Net::LDAP::ConnectionRefusedError do @ldap.bind BIND_CREDS end assert_equal( @@ -72,7 +72,7 @@ def test_bind_tls_with_bad_hostname def test_bind_tls_with_valid_hostname @ldap.host = 'localhost' - @ldap.port = 9389 + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, @@ -108,7 +108,7 @@ def test_bind_tls_with_multiple_bogus_hosts tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE), ) - error = assert_raise Net::LDAP::Error do + error = assert_raise Net::LDAP::ConnectionRefusedError do @ldap.bind BIND_CREDS end assert_equal("TODO - fix this", From 80bab6c769329f1d7b9c0ec246f3056fd0eeeeae Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 23:19:41 -0700 Subject: [PATCH 21/39] handle both exceptions --- test/integration/test_bind.rb | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index d034b1fd..a046e2ec 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -61,7 +61,8 @@ def test_bind_tls_with_bad_hostname tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE), ) - error = assert_raise Net::LDAP::ConnectionRefusedError do + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionRefusedError do @ldap.bind BIND_CREDS end assert_equal( @@ -108,7 +109,8 @@ def test_bind_tls_with_multiple_bogus_hosts tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, ca_file: CA_FILE), ) - error = assert_raise Net::LDAP::ConnectionRefusedError do + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionRefusedError do @ldap.bind BIND_CREDS end assert_equal("TODO - fix this", From eeb7a6d0ab591bba045d9765ba5313089db67b0a Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 23:31:49 -0700 Subject: [PATCH 22/39] single vs multiple hosts throw different exceptions --- test/integration/test_bind.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index a046e2ec..3938973a 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -110,7 +110,7 @@ def test_bind_tls_with_multiple_bogus_hosts ca_file: CA_FILE), ) error = assert_raise Net::LDAP::Error, - Net::LDAP::ConnectionRefusedError do + Net::LDAP::ConnectionError do @ldap.bind BIND_CREDS end assert_equal("TODO - fix this", From c5f212605f0cfbe6d162d527089f67ad614fab0d Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 23:45:51 -0700 Subject: [PATCH 23/39] more TLS tests around merging vs not merging the default options --- test/integration/test_bind.rb | 52 +++++++++++++++++++++++++++++++---- 1 file changed, 46 insertions(+), 6 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 3938973a..c54809c7 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -42,7 +42,18 @@ def test_bind_tls_with_cafile @ldap.get_operation_result.inspect end - def test_bind_tls_with_verify_none + def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes + @ldap.host = '127.0.0.1' + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' + @ldap.encryption( + method: :start_tls, + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE }, + ) + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect + end + + def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes @ldap.host = '127.0.0.1' @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( @@ -53,13 +64,13 @@ def test_bind_tls_with_verify_none @ldap.get_operation_result.inspect end - def test_bind_tls_with_bad_hostname + def test_bind_tls_with_bad_hostname_verify_peer_ca_fails @ldap.host = '127.0.0.1' @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, - tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, - ca_file: CA_FILE), + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE }, ) error = assert_raise Net::LDAP::Error, Net::LDAP::ConnectionRefusedError do @@ -71,7 +82,24 @@ def test_bind_tls_with_bad_hostname ) end - def test_bind_tls_with_valid_hostname + def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails + @ldap.host = '127.0.0.1' + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' + @ldap.encryption( + method: :start_tls, + tls_options: TLS_OPTS.merge(ca_file: CA_FILE), + ) + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionRefusedError do + @ldap.bind BIND_CREDS + end + assert_equal( + "hostname \"#{@ldap.host}\" does not match the server certificate", + error.message, + ) + end + + def test_bind_tls_with_valid_hostname_default_opts_passes @ldap.host = 'localhost' @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( @@ -83,6 +111,18 @@ def test_bind_tls_with_valid_hostname @ldap.get_operation_result.inspect end + def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes + @ldap.host = 'localhost' + @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' + @ldap.encryption( + method: :start_tls, + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER, + ca_file: CA_FILE }, + ) + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect + end + # The following depend on /etc/hosts hacking. # We can do that on CI, but it's less than cool on people's dev boxes def test_bind_tls_with_multiple_hosts @@ -137,7 +177,7 @@ def test_bind_tls_with_multiple_bogus_hosts_ca_check_only @ldap.hosts = [['127.0.0.1', 389], ['bogus.example.com', 389]] @ldap.encryption( method: :start_tls, - tls_options: TLS_OPTS.merge(ca_file: CA_FILE), + tls_options: { ca_file: CA_FILE }, ) assert @ldap.bind(BIND_CREDS), @ldap.get_operation_result.inspect From d2ba5e6801d745f5a169ab102788d67c57e15f05 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Mon, 22 Aug 2016 23:54:31 -0700 Subject: [PATCH 24/39] fix bogus multi-host check --- test/integration/test_bind.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index c54809c7..0caf24e9 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -153,8 +153,8 @@ def test_bind_tls_with_multiple_bogus_hosts Net::LDAP::ConnectionError do @ldap.bind BIND_CREDS end - assert_equal("TODO - fix this", - error.message) + assert_equal("Unable to connect to any given server: ", + error.message.split("\n").shift) end def test_bind_tls_with_multiple_bogus_hosts_no_verification From 41881aa2efe6e4c00365b36680abb40f81983423 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 00:00:14 -0700 Subject: [PATCH 25/39] remove vagrant port override, because $INTEGRATION_PORT --- test/integration/test_bind.rb | 6 ------ test/support/vm/openldap/README.md | 3 +++ 2 files changed, 3 insertions(+), 6 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 0caf24e9..5ba5237e 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -44,7 +44,6 @@ def test_bind_tls_with_cafile def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes @ldap.host = '127.0.0.1' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: { verify_mode: OpenSSL::SSL::VERIFY_NONE }, @@ -55,7 +54,6 @@ def test_bind_tls_with_bad_hostname_verify_none_no_ca_passes def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes @ldap.host = '127.0.0.1' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_NONE), @@ -66,7 +64,6 @@ def test_bind_tls_with_bad_hostname_verify_none_no_ca_opt_merge_passes def test_bind_tls_with_bad_hostname_verify_peer_ca_fails @ldap.host = '127.0.0.1' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER, @@ -84,7 +81,6 @@ def test_bind_tls_with_bad_hostname_verify_peer_ca_fails def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails @ldap.host = '127.0.0.1' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(ca_file: CA_FILE), @@ -101,7 +97,6 @@ def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails def test_bind_tls_with_valid_hostname_default_opts_passes @ldap.host = 'localhost' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER, @@ -113,7 +108,6 @@ def test_bind_tls_with_valid_hostname_default_opts_passes def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes @ldap.host = 'localhost' - @ldap.port = 9389 unless ENV['TRAVIS'] == 'true' @ldap.encryption( method: :start_tls, tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER, diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md index 9b37ed5e..e8b9ff92 100644 --- a/test/support/vm/openldap/README.md +++ b/test/support/vm/openldap/README.md @@ -34,6 +34,9 @@ $ ip=$(vagrant ssh -- "ifconfig eth1 | grep -o -E '[0-9]+\.[0-9]+\.[0-9]+\.[0-9] # change back to root project directory $ cd ../../../.. +# set the TCP port for testing +$ export INTEGRATION_PORT=9389 + # run all tests, including integration tests $ time INTEGRATION=openldap INTEGRATION_HOST=$ip bundle exec rake From 19f9c7da13c937d27405609686f51213eccef8fb Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 00:09:32 -0700 Subject: [PATCH 26/39] more no-merge-default-opts tests, done properly --- test/integration/test_bind.rb | 26 +++++++++++++++++++++++--- 1 file changed, 23 insertions(+), 3 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 5ba5237e..55979e6b 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -95,6 +95,22 @@ def test_bind_tls_with_bad_hostname_ca_default_opt_merge_fails ) end + def test_bind_tls_with_bad_hostname_ca_no_opt_merge_fails + @ldap.host = '127.0.0.1' + @ldap.encryption( + method: :start_tls, + tls_options: { ca_file: CA_FILE }, + ) + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionRefusedError do + @ldap.bind BIND_CREDS + end + assert_equal( + "hostname \"#{@ldap.host}\" does not match the server certificate", + error.message, + ) + end + def test_bind_tls_with_valid_hostname_default_opts_passes @ldap.host = 'localhost' @ldap.encryption( @@ -164,7 +180,7 @@ def test_bind_tls_with_multiple_bogus_hosts_no_verification @ldap.get_operation_result.inspect end - def test_bind_tls_with_multiple_bogus_hosts_ca_check_only + def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails omit_unless ENV['TRAVIS'] == 'true' @ldap.host = nil @@ -173,7 +189,11 @@ def test_bind_tls_with_multiple_bogus_hosts_ca_check_only method: :start_tls, tls_options: { ca_file: CA_FILE }, ) - assert @ldap.bind(BIND_CREDS), - @ldap.get_operation_result.inspect + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionError do + @ldap.bind BIND_CREDS + end + assert_equal("Unable to connect to any given server: ", + error.message.split("\n").shift) end end From 3c18b1e438fd566ee3b25a781dbb7818bcf38d4b Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 15:39:05 -0700 Subject: [PATCH 27/39] more docs about vagrant setup --- test/support/vm/openldap/README.md | 12 ++++++++++-- 1 file changed, 10 insertions(+), 2 deletions(-) diff --git a/test/support/vm/openldap/README.md b/test/support/vm/openldap/README.md index e8b9ff92..f79f4dc6 100644 --- a/test/support/vm/openldap/README.md +++ b/test/support/vm/openldap/README.md @@ -8,7 +8,9 @@ goes away when you run `vagrant destroy`. ## Install Vagrant *NOTE*: The Vagrant gem (`gem install vagrant`) is -[no longer supported](https://www.vagrantup.com/docs/installation/) +[no longer supported](https://www.vagrantup.com/docs/installation/). If you've +previously installed it, run `gem uninstall vagrant`. If you're an rbenv +user, you probably want to follow that up with `rbenv rehash; hash -r`. If you use Homebrew on macOS: ``` bash @@ -16,10 +18,12 @@ $ brew update $ brew cask install virtualbox $ brew cask install vagrant $ brew cask install vagrant-manager +$ vagrant plugin install vagrant-vbguest ``` Installing Vagrant and virtualbox on other operating systems is left -as an exercise to the reader. +as an exercise to the reader. Note the `vagrant-vbguest` plugin is required +to update the VirtualBox guest extensions in the guest VM image. ## Run the tests @@ -54,3 +58,7 @@ $ time bundle exec rake $ cd test/support/vm/openldap $ vagrant destroy ``` + +If at any point your VM appears to have broken itself, `vagrant destroy` +from the `test/support/vm/openldap` directory will blow it away. You can +then do `vagrant up` and start over. From 0f51b5680c273bc19d751ed7cdd87d3c30eedfce Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 16:04:59 -0700 Subject: [PATCH 28/39] add script to generate fixture --- script/generate-fixture-ca | 48 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 48 insertions(+) create mode 100755 script/generate-fixture-ca diff --git a/script/generate-fixture-ca b/script/generate-fixture-ca new file mode 100755 index 00000000..89eb3d8d --- /dev/null +++ b/script/generate-fixture-ca @@ -0,0 +1,48 @@ +#!/bin/bash + +BASE_PATH=$( cd "`dirname $0`/../test/fixtures/ca" && pwd ) +cd "${BASE_PATH}" || exit 4 + +USAGE=$( cat << EOS +Usage: + $0 --regenerate + +Generates a new self-signed CA, for integration testing. This should only need +to be run if you are writing new TLS/SSL tests, and need to generate +additional fixtuer CAs. + +This script uses the GnuTLS certtool CLI. If you are on macOS, +'brew install gnutls', and it will be installed as 'gnutls-certtool'. +Apple unfortunately ships with an incompatible /usr/bin/certtool that does +different things. +EOS +) + +if [ "x$1" != 'x--regenerate' ]; then + echo "${USAGE}" + exit 1 +fi + +TOOL=`type -p certtool` +if [ "$(uname)" = "Darwin" ]; then + TOOL=`type -p gnutls-certtool` + if [ ! -x "${TOOL}" ]; then + echo "Sorry, Darwin requires gnutls-certtool; try `brew install gnutls`" + exit 2 + fi +fi + +if [ ! -x "${TOOL}" ]; then + echo "Sorry, no certtool found!" + exit 3 +fi +export TOOL + + +${TOOL} --generate-privkey > ./cakey.pem +${TOOL} --generate-self-signed \ + --load-privkey ./cakey.pem \ + --template ./ca.info \ + --outfile ./cacert.pem + +echo "cert and private key generated! Don't forget to check them in" From 02a29ea52651918ef1d37af34b1e41d90042209f Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 16:05:20 -0700 Subject: [PATCH 29/39] use script-generated fixture CA --- test/fixtures/ca/cacert.pem | 38 ++++--- test/fixtures/ca/cakey.pem | 213 +++++++++++++++++++++++++++++++----- 2 files changed, 210 insertions(+), 41 deletions(-) diff --git a/test/fixtures/ca/cacert.pem b/test/fixtures/ca/cacert.pem index c4f5b0fc..0218dd8a 100644 --- a/test/fixtures/ca/cacert.pem +++ b/test/fixtures/ca/cacert.pem @@ -1,18 +1,24 @@ -----BEGIN CERTIFICATE----- -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 +jDj/ -----END CERTIFICATE----- diff --git a/test/fixtures/ca/cakey.pem b/test/fixtures/ca/cakey.pem index 325f36c7..d75ab299 100644 --- a/test/fixtures/ca/cakey.pem +++ b/test/fixtures/ca/cakey.pem @@ -1,27 +1,190 @@ +Public Key Info: + Public Key Algorithm: RSA + Key Security Level: High (3072 bits) + +modulus: + 00:c6:7b:dc:33:88:61:d9:26:12:1f:f8:81:0a:4a:4d + 6d:a5:3f:4c:bb:b6:20:b1:4c:23:ae:5b:ad:be:4a:0e + d5:0e:8a:f9:a9:93:01:50:d7:8b:33:df:d4:35:52:0e + 96:4f:e7:e0:9f:04:ec:e7:86:02:cc:b0:fb:eb:43:4d + b0:e2:ac:79:ff:a5:fd:2f:ec:c9:70:c9:3c:8d:33:58 + 48:a8:f9:b8:82:a9:2b:9d:84:ed:4a:24:6b:28:0c:5d + e6:aa:ae:83:ce:34:69:28:24:86:62:54:68:1d:6d:67 + d3:bd:c7:df:4e:6f:05:3a:1c:ed:5d:46:cc:ac:c5:c9 + 36:29:c5:b2:87:06:1c:4a:0c:34:df:1b:be:a8:00:c8 + 6e:3e:0c:51:e8:2b:82:f4:73:a7:90:8c:4e:27:64:10 + a1:89:e6:5d:4a:15:21:68:1a:55:ee:bd:aa:48:d6:cf + c3:ae:dc:bc:02:ae:13:39:a5:e7:c9:95:d5:91:75:17 + bd:d4:6b:c8:0f:59:71:c4:7d:47:b6:18:47:c6:d0:d9 + d1:ab:ab:06:6e:c0:d8:7b:f0:c8:2b:10:bb:01:9f:3d + b9:d6:45:dd:66:57:36:b3:e1:bd:72:a3:65:3e:e7:8f + 07:0c:41:e9:a7:b3:87:4d:3d:0d:24:d9:5e:2f:01:0f + 29:0f:ca:fc:42:f6:fa:e4:58:92:a2:95:21:55:a1:90 + b3:00:27:20:c4:b5:0e:71:6a:f3:c0:10:28:94:ca:21 + 76:c1:b8:cc:2e:68:d3:52:b3:a4:7f:a9:34:b6:44:39 + 35:c3:e0:86:a5:15:c0:83:bf:b5:49:7e:4d:29:da:c4 + b2:ed:48:68:00:40:fe:d4:3f:cc:a2:a4:38:b2:c9:68 + 3d:20:89:7d:70:78:15:66:35:e1:5c:2b:12:28:4f:7e + 15:4b:9f:5e:12:de:40:3e:63:dc:82:e2:67:c7:e6:81 + ac:0f:53:2f:34:8e:ef:cf:1a:a4:13:74:e2:51:80:99 + 1d: + +public exponent: + 01:00:01: + +private exponent: + 1d:0d:9a:50:ec:c0:ad:e1:75:bb:ba:4b:61:2f:39:20 + 38:95:08:6d:5d:9e:71:75:5c:af:b3:f9:bd:a5:e7:7f + e6:4e:0f:77:73:ee:38:60:24:9f:26:3f:50:c2:bf:21 + df:76:68:99:be:45:d3:29:f9:94:ee:bf:21:53:cb:b6 + 7d:a7:93:80:09:53:03:45:dc:c2:a6:a2:37:64:f1:a2 + 49:21:ac:91:6b:a3:d7:bd:d2:62:0c:ec:a6:83:10:e7 + a7:ca:3d:be:dc:4b:1c:36:24:79:96:33:5b:43:5d:74 + 50:0e:46:b0:9b:6d:9f:71:06:89:a5:c8:65:ed:d9:a3 + 15:00:3c:3e:a9:75:50:9d:72:cb:c9:aa:e1:ba:a3:9c + 07:77:14:32:30:d4:4d:65:f4:7c:23:1d:79:84:9b:2e + 9a:19:df:43:ed:cd:e3:08:1f:d5:ff:6b:42:98:36:f7 + 44:cc:48:b4:f7:b8:16:b3:23:37:8d:b8:22:3f:8a:86 + db:71:b3:85:2d:6d:42:44:b7:dc:c1:36:e0:c4:0f:fe + cb:76:84:81:e2:83:f5:82:76:a9:7b:35:d5:44:00:d1 + 1a:fc:ef:b9:a4:2b:62:aa:f8:56:eb:60:e5:16:33:f1 + 28:e1:da:91:50:e3:a4:c7:d6:30:21:cf:04:07:cd:8c + b6:9e:b0:a7:6c:96:57:2e:09:5b:39:26:d0:60:be:e3 + 90:59:a3:8e:e7:6e:3f:62:7e:b4:2a:e1:8f:00:37:7a + 83:9e:7a:9c:d2:ae:ba:50:84:73:65:3a:64:95:d8:48 + f9:fd:0e:c3:5b:6e:08:3b:c5:c9:1c:29:55:bb:67:e8 + fa:50:40:30:2a:d1:b7:cf:54:a8:f0:f0:76:89:ad:19 + e7:a0:3a:56:6c:75:c5:bc:d8:46:ce:1e:66:f2:61:96 + 11:e4:57:cc:52:ff:e4:ed:6b:2c:ce:78:15:ba:b7:ed + 31:f2:68:88:79:bf:7c:29:3c:2f:66:71:0b:09:b7:41 + + +prime1: + 00:fd:c2:37:b9:6f:77:88:51:a2:f7:4f:c2:3c:a4:57 + bf:ba:71:14:f3:61:f4:39:78:22:3d:bc:d8:d2:4e:c0 + 4b:9e:c2:6d:38:a8:21:e2:70:1a:96:48:95:18:85:01 + 46:fb:62:a4:81:09:f8:2a:3a:87:78:07:5d:93:54:ce + 2a:51:b3:51:6f:61:0a:2e:9d:b0:51:37:e3:13:bd:81 + 23:2b:61:53:fa:ac:08:dc:a0:e6:63:a3:b0:cc:cf:73 + 1d:65:b7:11:bc:29:70:fb:72:ea:63:9d:67:02:d6:35 + 24:13:1d:bc:72:fb:9e:3d:ab:0b:57:6e:bd:a1:51:56 + f9:bc:96:15:74:a3:31:16:c6:b8:98:1b:0a:a2:59:7c + c8:b7:14:b8:5b:f3:2e:26:b4:f0:46:c4:3d:27:dd:41 + 31:52:a7:15:a8:af:6a:98:a5:9c:20:17:f9:1d:54:54 + ff:10:91:a3:a5:ca:ac:63:e7:16:2b:71:3c:3a:cd:4f + ed: + +prime2: + 00:c8:3c:a8:9f:8a:db:42:b5:8d:cf:2a:a1:2f:e5:73 + 05:de:30:d8:17:b9:5c:9d:08:60:02:c9:66:9d:88:50 + ac:cd:0f:b5:47:b4:a8:73:3b:7d:65:79:bf:4c:6f:d0 + e2:03:ed:d4:28:4e:00:07:23:00:01:4f:05:de:9b:44 + 1a:84:ae:09:4a:d6:ed:61:5d:77:e2:fa:13:99:4c:b7 + 76:72:3d:f8:53:93:69:78:e8:bd:26:cb:b0:f9:01:f4 + 1d:20:4f:60:f5:ab:3c:19:85:73:34:f3:ec:d2:67:ef + 56:b8:5d:93:73:8e:d9:3e:28:ff:87:f5:4a:26:fa:b1 + ae:c6:d3:9d:03:e3:fd:c2:24:48:af:85:2a:8e:3b:5b + 93:07:38:91:21:ae:49:cb:6d:e3:30:81:15:ed:65:eb + dc:01:df:3b:9d:43:fd:a6:e1:df:ef:ad:22:42:34:f1 + 3f:81:5e:57:0a:e0:56:94:f2:2a:00:d0:cc:c5:50:67 + f1: + +coefficient: + 00:bd:23:8c:2e:a7:7b:6b:1e:85:77:db:7d:77:f6:e5 + b0:15:c6:e1:9e:35:57:72:df:35:6d:93:89:7f:83:9f + 63:7f:08:0a:b3:d4:ba:63:9b:10:7f:0f:d3:55:e9:38 + cf:90:37:3d:85:3d:a7:97:8c:33:f2:c2:b1:38:2b:db + 39:ca:a8:d0:23:d7:89:cc:8d:02:7d:61:9b:b6:04:69 + 14:e8:c9:84:34:36:6c:fb:84:58:cc:9a:53:74:a4:42 + bd:1d:25:1b:ba:82:c0:fb:23:2c:90:bb:35:4b:5b:b0 + 98:d0:ab:9d:61:6e:ea:e8:84:e7:a7:6c:ae:1b:2c:00 + cb:0f:1a:f8:e2:7c:fd:42:1a:e2:13:52:c7:50:fa:65 + c9:5f:ed:40:a8:7f:46:0e:ce:f6:56:83:6f:0e:8e:39 + f8:33:5f:83:de:be:be:ef:8c:66:ad:16:c8:ec:98:d4 + b2:b2:55:66:a2:9e:27:6a:84:f1:31:07:e8:bf:a7:a7 + bd: + +exp1: + 00:b6:50:0c:53:19:07:8b:14:03:fe:a4:fa:0b:31:93 + ad:b7:18:b9:91:a6:c5:9d:68:77:49:5d:dd:75:33:89 + 2a:8b:54:6a:be:32:e5:ad:57:17:72:f3:90:d2:fd:f4 + 0d:f8:5c:45:8e:44:08:5c:e6:92:1f:a5:43:10:af:f4 + 33:29:61:a8:d7:59:a3:c4:1c:1c:ea:2d:39:e3:1b:da + a4:d6:ec:e5:36:0a:d5:8f:15:b6:90:cd:b1:1f:64:c7 + f2:cd:fa:3a:2e:b2:a3:6e:b4:80:3b:b3:81:a7:e3:18 + 68:e3:a7:10:96:97:ba:77:d9:e4:9b:1b:7f:f8:5f:85 + 1a:85:e8:5a:5f:e3:43:48:76:db:76:c4:ae:de:37:66 + d4:99:dc:b4:1b:b3:da:6b:8a:c1:ba:46:11:1e:0b:f3 + 63:a9:5b:4b:cf:56:c0:42:0d:71:df:08:fa:3c:9d:33 + 37:d1:c2:a1:0d:63:50:79:b2:34:16:60:13:82:b7:b1 + 7d: + +exp2: + 00:98:38:2c:c4:24:4e:2c:b7:52:17:a4:43:a6:e2:99 + ff:62:fa:e4:bb:9c:49:40:83:66:61:97:f3:af:5c:3a + 60:32:ff:77:03:0c:de:65:c3:5a:bf:72:bf:2f:7f:6d + 5e:f4:37:af:69:f8:69:e3:03:03:74:fb:3a:ee:10:40 + c4:9c:0a:a5:bb:c4:09:ef:53:9b:d8:eb:dd:4c:53:da + c0:6b:76:9a:ba:06:3d:4f:12:37:01:30:25:d8:16:59 + 1a:6f:3e:88:ea:19:83:75:af:52:76:75:dc:99:d3:33 + 4a:4c:9b:ae:85:51:99:ea:bc:46:0d:78:36:27:cd:ba + 97:b0:44:9c:7f:a1:a9:7e:16:11:3f:85:4f:65:92:d0 + 39:c4:6a:87:42:00:79:ce:f1:39:9d:dc:f3:eb:65:e8 + d8:76:7f:da:94:e2:64:08:a2:7b:97:7b:99:a8:95:10 + b5:03:46:d1:8a:ce:22:63:d6:78:81:e8:39:52:e2:9e + 31: + + +Public Key ID: 53:BD:74:A4:81:ED:37:A2:A2:EE:ED:45:23:14:8F:A8:2D:8C:27:BA +Public key's random art: ++--[ RSA 3072]----+ +| . o. . | +| . +...+ | +| . o o.+ . | +| o o . . .ooo | +| o = . S o..o . | +| . o . .+.. | +|. . .. | +| . .. . | +|E oo.o | ++-----------------+ + -----BEGIN RSA PRIVATE KEY----- -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 -----END RSA PRIVATE KEY----- From 7de633526b319d54d361265ac22e66bab492e709 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 16:17:57 -0700 Subject: [PATCH 30/39] describe where fixture CA comes from; also indent --- script/install-openldap | 14 ++++++-------- 1 file changed, 6 insertions(+), 8 deletions(-) diff --git a/script/install-openldap b/script/install-openldap index 83a09153..9eea3039 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -52,12 +52,10 @@ export CA_CERT="/etc/ssl/certs/cacert.pem" export CA_KEY="/etc/ssl/private/cakey.pem" export CA_INFO="/etc/ssl/ca.info" -# If you ever need to regenerate these... -# certtool --generate-privkey > /path/to/cakey.pem -# certtool --generate-self-signed \ -# --load-privkey /path/to/cakey.pem -# --template /path/to/ca.info -# --outfile /path/to/cacert.pem +# The self-signed fixture CA cert & key are generated by +# `script/generate-fiuxture-ca` and checked into version control. +# You shouldn't need to muck with these unless you're writing more +# TLS/SSL integration tests, and need special magic values in the cert. cp "${SEED_PATH}/ca/cacert.pem" "${CA_CERT}" cp "${SEED_PATH}/ca/cakey.pem" "${CA_KEY}" @@ -65,8 +63,8 @@ cp "${SEED_PATH}/ca/ca.info" "${CA_INFO}" # Make a private key for the server: certtool --generate-privkey \ ---bits 1024 \ ---outfile /etc/ssl/private/ldap01_slapd_key.pem + --bits 1024 \ + --outfile /etc/ssl/private/ldap01_slapd_key.pem sh -c "cat > /etc/ssl/ldap01.info < Date: Tue, 23 Aug 2016 16:21:52 -0700 Subject: [PATCH 31/39] linter quoting complaint --- script/install-openldap | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/script/install-openldap b/script/install-openldap index 9eea3039..22c4d856 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -2,8 +2,8 @@ set -e set -x -BASE_PATH="$( cd `dirname $0`/../test/fixtures/openldap && pwd )" -SEED_PATH="$( cd `dirname $0`/../test/fixtures && pwd )" +BASE_PATH=$( cd "`dirname $0`/../test/fixtures/openldap" && pwd ) +SEED_PATH=$( cd "`dirname $0`/../test/fixtures" && pwd ) dpkg -s slapd time ldap-utils gnutls-bin ssl-cert > /dev/null ||\ DEBIAN_FRONTEND=noninteractive apt-get update -y --force-yes && \ From 3aebc3d906d4817c5262765ccb0c1a3490a6e5d6 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 17:02:25 -0700 Subject: [PATCH 32/39] test that no tls_options means we get the system CA bundle --- test/integration/test_bind.rb | 23 +++++++++++++++++++++++ 1 file changed, 23 insertions(+) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 55979e6b..6c906487 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -133,6 +133,19 @@ def test_bind_tls_with_valid_hostname_just_verify_peer_ca_passes @ldap.get_operation_result.inspect end + def test_bind_tls_with_bogus_hostname_system_ca_fails + @ldap.host = '127.0.0.1' + @ldap.encryption(method: :start_tls, tls_options: {}) + error = assert_raise Net::LDAP::Error, + Net::LDAP::ConnectionRefusedError do + @ldap.bind BIND_CREDS + end + assert_equal( + "hostname \"#{@ldap.host}\" does not match the server certificate", + error.message, + ) + end + # The following depend on /etc/hosts hacking. # We can do that on CI, but it's less than cool on people's dev boxes def test_bind_tls_with_multiple_hosts @@ -196,4 +209,14 @@ def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails assert_equal("Unable to connect to any given server: ", error.message.split("\n").shift) end + + # This test is CI-only because we can't add the fixture CA + # to the system CA store on people's dev boxes. + def test_bind_tls_valid_hostname_system_ca_on_travis_passes + omit_unless ENV['TRAVIS'] == 'true' + + @ldap.encryption(method: :start_tls, tls_options: {}) + assert @ldap.bind(BIND_CREDS), + @ldap.get_operation_result.inspect + end end From 4e5a8e7e0a52642a5e25ca75c99f8b322da35226 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 17:48:34 -0700 Subject: [PATCH 33/39] improve system store tests --- test/integration/test_bind.rb | 24 +++++++++++++++++++++++- 1 file changed, 23 insertions(+), 1 deletion(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index 6c906487..bd1281e2 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -215,8 +215,30 @@ def test_bind_tls_with_multiple_bogus_hosts_ca_check_only_fails def test_bind_tls_valid_hostname_system_ca_on_travis_passes omit_unless ENV['TRAVIS'] == 'true' - @ldap.encryption(method: :start_tls, tls_options: {}) + @ldap.encryption( + method: :start_tls, + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, + ) assert @ldap.bind(BIND_CREDS), @ldap.get_operation_result.inspect end + + # Inverse of the above! Don't run this on Travis, only on Vagrant. + # Since Vagrant's hypervisor *won't* have the CA in the system + # x509 store, we can assume validation will fail + def test_bind_tls_valid_hostname_system_on_vagrant_fails + omit_if ENV['TRAVIS'] == 'true' + + @ldap.encryption( + method: :start_tls, + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, + ) + error = assert_raise Net::LDAP::Error do + @ldap.bind BIND_CREDS + end + assert_equal( + "SSL_connect returned=1 errno=0 state=error: certificate verify failed", + error.message, + ) + end end From 0a8c09940a008fafba72337423cccb1ec97d8f60 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 17:52:47 -0700 Subject: [PATCH 34/39] use default tls opts for validation --- test/integration/test_bind.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index bd1281e2..a3fecf3f 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -217,7 +217,7 @@ def test_bind_tls_valid_hostname_system_ca_on_travis_passes @ldap.encryption( method: :start_tls, - tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER), ) assert @ldap.bind(BIND_CREDS), @ldap.get_operation_result.inspect @@ -231,7 +231,7 @@ def test_bind_tls_valid_hostname_system_on_vagrant_fails @ldap.encryption( method: :start_tls, - tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, + tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER), ) error = assert_raise Net::LDAP::Error do @ldap.bind BIND_CREDS From 8ed4dca1f1db95dd6d264b733288d40e70cbc355 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 18:17:18 -0700 Subject: [PATCH 35/39] properly add the fixture CA to CI system store --- script/install-openldap | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/script/install-openldap b/script/install-openldap index 22c4d856..77af4924 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -48,9 +48,8 @@ chown -R openldap.openldap /var/lib/ldap rm -rf $TMPDIR # SSL -export CA_CERT="/etc/ssl/certs/cacert.pem" -export CA_KEY="/etc/ssl/private/cakey.pem" -export CA_INFO="/etc/ssl/ca.info" +export CA_CERT="/usr/local/share/ca-certificates/rubyldap-ca.crt" +export CA_KEY="/etc/ssl/private/rubyldap-ca.key" # The self-signed fixture CA cert & key are generated by # `script/generate-fiuxture-ca` and checked into version control. @@ -59,7 +58,9 @@ export CA_INFO="/etc/ssl/ca.info" cp "${SEED_PATH}/ca/cacert.pem" "${CA_CERT}" cp "${SEED_PATH}/ca/cakey.pem" "${CA_KEY}" -cp "${SEED_PATH}/ca/ca.info" "${CA_INFO}" + +# actually add the fake CA to the system store +update-ca-certificates # Make a private key for the server: certtool --generate-privkey \ From efd354a83bcd8f13c89cd40ac7b694c06574f266 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 18:51:56 -0700 Subject: [PATCH 36/39] names matter --- script/install-openldap | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/script/install-openldap b/script/install-openldap index 77af4924..3e391d87 100755 --- a/script/install-openldap +++ b/script/install-openldap @@ -59,7 +59,7 @@ export CA_KEY="/etc/ssl/private/rubyldap-ca.key" cp "${SEED_PATH}/ca/cacert.pem" "${CA_CERT}" cp "${SEED_PATH}/ca/cakey.pem" "${CA_KEY}" -# actually add the fake CA to the system store +# actually add the fixture CA to the system store update-ca-certificates # Make a private key for the server: From 09262743e03e950cc6acb947765856de4c754909 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 18:53:31 -0700 Subject: [PATCH 37/39] don't need the whole default hash for a verify? --- test/integration/test_bind.rb | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/test/integration/test_bind.rb b/test/integration/test_bind.rb index a3fecf3f..bd1281e2 100644 --- a/test/integration/test_bind.rb +++ b/test/integration/test_bind.rb @@ -217,7 +217,7 @@ def test_bind_tls_valid_hostname_system_ca_on_travis_passes @ldap.encryption( method: :start_tls, - tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER), + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, ) assert @ldap.bind(BIND_CREDS), @ldap.get_operation_result.inspect @@ -231,7 +231,7 @@ def test_bind_tls_valid_hostname_system_on_vagrant_fails @ldap.encryption( method: :start_tls, - tls_options: TLS_OPTS.merge(verify_mode: OpenSSL::SSL::VERIFY_PEER), + tls_options: { verify_mode: OpenSSL::SSL::VERIFY_PEER }, ) error = assert_raise Net::LDAP::Error do @ldap.bind BIND_CREDS From 72ba381853e71620e9a82071eff522a144dd10df Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 19:36:37 -0700 Subject: [PATCH 38/39] add docs on how to actually validate an LDAP server cert --- lib/net/ldap.rb | 84 ++++++++++++++++++++++++++++--------------------- 1 file changed, 48 insertions(+), 36 deletions(-) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index a79d6c55..69440c90 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -476,61 +476,73 @@ def self.result2string(code) #:nodoc: # specify a treebase. If you give a treebase value in any particular # call to #search, that value will override any treebase value you give # here. + # * :force_no_page => Set to true to prevent paged results even if your + # server says it supports them. This is a fix for MS Active Directory + # * :instrumentation_service => An object responsible for instrumenting + # operations, compatible with ActiveSupport::Notifications' public API. # * :encryption => specifies the encryption to be used in communicating # with the LDAP server. The value must be a Hash containing additional # parameters, which consists of two keys: # method: - :simple_tls or :start_tls - # options: - Hash of options for that method + # tls_options: - Hash of options for that method # The :simple_tls encryption method encrypts all communications # with the LDAP server. It completely establishes SSL/TLS encryption with # the LDAP server before any LDAP-protocol data is exchanged. There is no # plaintext negotiation and no special encryption-request controls are # sent to the server. The :simple_tls option is the simplest, easiest # way to encrypt communications between Net::LDAP and LDAP servers. - # It's intended for cases where you have an implicit level of trust in the - # authenticity of the LDAP server. No validation of the LDAP server's SSL - # certificate is performed. This means that :simple_tls will not produce - # errors if the LDAP server's encryption certificate is not signed by a - # well-known Certification Authority. If you get communications or - # protocol errors when using this option, check with your LDAP server - # administrator. Pay particular attention to the TCP port you are - # connecting to. It's impossible for an LDAP server to support plaintext - # LDAP communications and simple TLS connections on the same port. - # The standard TCP port for unencrypted LDAP connections is 389, but the - # standard port for simple-TLS encrypted connections is 636. Be sure you - # are using the correct port. - # + # If you get communications or protocol errors when using this option, + # check with your LDAP server administrator. Pay particular attention + # to the TCP port you are connecting to. It's impossible for an LDAP + # server to support plaintext LDAP communications and simple TLS + # connections on the same port. The standard TCP port for unencrypted + # LDAP connections is 389, but the standard port for simple-TLS + # encrypted connections is 636. Be sure you are using the correct port. # The :start_tls like the :simple_tls encryption method also encrypts all # communcations with the LDAP server. With the exception that it operates # over the standard TCP port. # - # In order to verify certificates and enable other TLS options, the - # :tls_options hash can be passed alongside :simple_tls or :start_tls. - # This hash contains any options that can be passed to - # OpenSSL::SSL::SSLContext#set_params(). The most common options passed - # should be OpenSSL::SSL::SSLContext::DEFAULT_PARAMS, or the :ca_file option, - # which contains a path to a Certificate Authority file (PEM-encoded). - # - # Example for a default setup without custom settings: - # { - # :method => :simple_tls, - # :tls_options => OpenSSL::SSL::SSLContext::DEFAULT_PARAMS - # } + # To validate the LDAP server's certificate (a security must if you're + # talking over the public internet), you need to set :tls_options + # something like this... # - # Example for specifying a CA-File and only allowing TLSv1.1 connections: - # - # { - # :method => :start_tls, - # :tls_options => { :ca_file => "/etc/cafile.pem", :ssl_version => "TLSv1_1" } + # Net::LDAP.new( + # # ... set host, bind dn, etc ... + # encryption: { + # method: :simple_tls, + # tls_options: { OpenSSL::SSL::SSLContext::DEFAULT_PARAMS }, # } - # * :force_no_page => Set to true to prevent paged results even if your - # server says it supports them. This is a fix for MS Active Directory - # * :instrumentation_service => An object responsible for instrumenting - # operations, compatible with ActiveSupport::Notifications' public API. + # ) + # + # The above will use the operating system-provided store of CA + # certificates to validate your LDAP server's cert. + # If cert validation fails, it'll happen during the #bind + # whenever you first try to open a connection to the server. + # Those methods will throw Net::LDAP::ConnectionError with + # a message about certificate verify failing. If your + # LDAP server's certificate is signed by DigiCert, Comodo, etc., + # you're probably good. If you've got a self-signed cert but it's + # been added to the host's OS-maintained CA store (e.g. on Debian + # add foobar.crt to /usr/local/share/ca-certificates/ and run + # `update-ca-certificates`), then the cert should pass validation. + # To ignore the OS's CA store, put your CA in a PEM-encoded file and... + # + # encryption: { + # method: :simple_tls, + # tls_options: { ca_file: '/path/to/my-little-ca.pem', + # ssl_version: 'TLSv1_1' }, + # } + # + # As you might guess, the above example also fails the connection + # if the client can't negotiate TLS v1.1. + # tls_options is ultimately passed to OpenSSL::SSL::SSLContext#set_params + # For more details, see + # http://ruby-doc.org/stdlib-2.0.0/libdoc/openssl/rdoc/OpenSSL/SSL/SSLContext.html # # Instantiating a Net::LDAP object does not result in network # traffic to the LDAP server. It simply stores the connection and binding - # parameters in the object. + # parameters in the object. That's why Net::LDAP.new doesn't throw + # cert validation errors itself; #bind does instead. def initialize(args = {}) @host = args[:host] || DefaultHost @port = args[:port] || DefaultPort From 435332d8235960c0081f91784aeb2b33ad059e31 Mon Sep 17 00:00:00 2001 From: Tom Maher Date: Tue, 23 Aug 2016 19:58:24 -0700 Subject: [PATCH 39/39] whoops, DEFAULT_PARAMS is already a hash --- lib/net/ldap.rb | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/lib/net/ldap.rb b/lib/net/ldap.rb index 69440c90..f7a98ef5 100644 --- a/lib/net/ldap.rb +++ b/lib/net/ldap.rb @@ -510,7 +510,7 @@ def self.result2string(code) #:nodoc: # # ... set host, bind dn, etc ... # encryption: { # method: :simple_tls, - # tls_options: { OpenSSL::SSL::SSLContext::DEFAULT_PARAMS }, + # tls_options: OpenSSL::SSL::SSLContext::DEFAULT_PARAMS, # } # ) #