Commit 099630a2 authored by jplang's avatar jplang

Support self-signed LDAPS connections (#29606).

Patch by Gregor Schmidt.

git-svn-id: https://svn.redmine.org/redmine/trunk@17505 e93f8b46-1217-0410-a6f0-8f06a7374b81
parent 2cf6f147
......@@ -43,6 +43,7 @@ class AuthSource < ActiveRecord::Base
'attr_mail',
'onthefly_register',
'tls',
'verify_peer',
'filter',
'timeout'
......
......@@ -37,6 +37,14 @@ class AuthSourceLdap < AuthSource
before_validation :strip_ldap_attributes
safe_attributes 'ldap_mode'
LDAP_MODES = [
:ldap,
:ldaps_verify_none,
:ldaps_verify_peer
]
def initialize(attributes=nil, *args)
super
self.port = 389 if self.port == 0
......@@ -101,6 +109,31 @@ class AuthSourceLdap < AuthSource
raise AuthSourceException.new(e.message)
end
def ldap_mode
case
when tls && verify_peer
:ldaps_verify_peer
when tls && !verify_peer
:ldaps_verify_none
else
:ldap
end
end
def ldap_mode=(ldap_mode)
case ldap_mode.try(:to_sym)
when :ldaps_verify_peer
self.tls = true
self.verify_peer = true
when :ldaps_verify_none
self.tls = true
self.verify_peer = false
else
self.tls = false
self.verify_peer = false
end
end
private
def with_timeout(&block)
......@@ -143,9 +176,18 @@ class AuthSourceLdap < AuthSource
def initialize_ldap_con(ldap_user, ldap_password)
options = { :host => self.host,
:port => self.port,
:encryption => (self.tls ? :simple_tls : nil)
:port => self.port
}
if tls
options[:encryption] = {
:method => :simple_tls,
# Always provide non-empty tls_options, to make sure, that all
# OpenSSL::SSL::SSLContext::DEFAULT_PARAMS as well as the default cert
# store are used.
:tls_options => { :verify_mode => verify_peer? ? OpenSSL::SSL::VERIFY_PEER : OpenSSL::SSL::VERIFY_NONE }
}
end
options.merge!(:auth => { :method => :simple, :username => ldap_user, :password => ldap_password }) unless ldap_user.blank? && ldap_password.blank?
Net::LDAP.new options
end
......
......@@ -3,7 +3,11 @@
<div class="box tabular">
<p><%= f.text_field :name, :required => true %></p>
<p><%= f.text_field :host, :required => true %></p>
<p><%= f.text_field :port, :required => true, :size => 6 %> <%= f.check_box :tls, :no_label => true %> LDAPS</p>
<p>
<%= f.text_field :port, :required => true, :size => 6 %>
<%= f.select :ldap_mode, AuthSourceLdap::LDAP_MODES.map { |m| [l("label_#{m}"), m] }, :no_label => true %>
<em class="info ldaps_warning"><%= l("label_ldaps_warning") %></em>
</p>
<p><%= f.text_field :account %></p>
<p><%= f.password_field :account_password, :label => :field_password,
:name => 'dummy_password',
......
......@@ -608,7 +608,11 @@ de:
label_latest_compatible_version: Letzte kompatible Version
label_latest_revision: Aktuellste Revision
label_latest_revision_plural: Aktuellste Revisionen
label_ldap: LDAP
label_ldap_authentication: LDAP-Authentifizierung
label_ldaps_verify_none: LDAPS (ohne Zertifikatsprüfung)
label_ldaps_verify_peer: LDAPS
label_ldaps_warning: Es wird empfohlen, eine verschlüsselte LDAPS-Verbindung mit Zertifikatsprüfung zu verwenden, um Manipulationen während der Authentifizierung zu verhindern.
label_less_or_equal: "<="
label_less_than_ago: vor weniger als
label_link: Link
......
......@@ -892,7 +892,11 @@ en:
label_general: General
label_scm: SCM
label_plugins: Plugins
label_ldap: LDAP
label_ldap_authentication: LDAP authentication
label_ldaps_verify_none: LDAPS (without certificate check)
label_ldaps_verify_peer: LDAPS
label_ldaps_warning: It is recommended to use an encrypted LDAPS connection with certificate check to prevent any manipulation during the authentication process.
label_downloads_abbr: D/L
label_optional_description: Optional description
label_add_another_file: Add another file
......
class AddVerifyPeerToAuthSources < ActiveRecord::Migration[5.2]
def change
change_table :auth_sources do |t|
t.boolean :verify_peer, default: true, null: false
end
end
end
......@@ -857,6 +857,12 @@ function keepAnchorOnSignIn(form){
return true;
}
$(function ($) {
$('#auth_source_ldap_mode').change(function () {
$('.ldaps_warning').toggle($(this).val() != 'ldaps_verify_peer');
}).change();
});
$(document).ready(setupAjaxIndicator);
$(document).ready(hideOnLoad);
$(document).ready(addFormObserversForDoubleSubmit);
......
......@@ -40,6 +40,8 @@ class AuthSourceLdapTest < ActiveSupport::TestCase
assert_nil auth_source.attr_mail
assert_equal false, auth_source.onthefly_register
assert_equal false, auth_source.tls
assert_equal true, auth_source.verify_peer
assert_equal :ldap, auth_source.ldap_mode
assert_nil auth_source.filter
assert_nil auth_source.timeout
end
......@@ -77,6 +79,42 @@ class AuthSourceLdapTest < ActiveSupport::TestCase
assert a.valid?
end
test 'ldap_mode setter sets tls and verify_peer' do
a = AuthSourceLdap.new
a.ldap_mode = 'ldaps_verify_peer'
assert a.tls
assert a.verify_peer
a.ldap_mode = 'ldaps_verify_none'
assert a.tls
assert !a.verify_peer
a.ldap_mode = 'ldap'
assert !a.tls
assert !a.verify_peer
end
test 'ldap_mode getter reads from tls and verify_peer' do
a = AuthSourceLdap.new
a.tls = true
a.verify_peer = true
assert_equal :ldaps_verify_peer, a.ldap_mode
a.tls = true
a.verify_peer = false
assert_equal :ldaps_verify_none, a.ldap_mode
a.tls = false
a.verify_peer = false
assert_equal :ldap, a.ldap_mode
a.tls = false
a.verify_peer = true
assert_equal :ldap, a.ldap_mode
end
if ldap_configured?
test '#authenticate with a valid LDAP user should return the user attributes' do
auth = AuthSourceLdap.find(1)
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment