Skip to content

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP

Loading…

Fix: can't login when login or dn is in UTF-8 #87

Closed
wants to merge 3 commits into from

4 participants

@graudeejs

I wrote simple patch to fix issue, when some data (login or dn) is in UTF-8.
Without this patch you won't be able to login in this case.

For example I had situation when devise_ldap_authenticatable tried and failed with cn=graudējs,dc=example,dc=com or cn=graudeejs,ou=piemērs,dc=example,dc=com

To avoid problems you need to force BINARY encoding for data that you send to ldap

@cairo140
Collaborator

Thanks for the patch! A couple questions.

  1. have you considered 1.8 compatibility? afaik, String#force_encoding is 1.9 only.
  2. have you identified the fundamental flaw that prevents you from sending strings encoded in UTF-8 over the wire? I get the impression that, if this is indeed a library issue, it may well take place at the net/ldap layer instead of at ours. That's not to rule out the appropriateness of a fix here, but I'd just like to understand if it's a flaw in our code that's causing this.
  3. why are you force encoding rather than transcoding via #encode?

Thanks for the submitting the patch. I look forward to merging it so others can enjoy it once we resolve the compatibility issue and once I educate myself a bit more over the methodology and rationale.

@graudeejs

1) No. Sorry didn't even thought about it. We use 1.9 only.
2) Actually you're right, the flaw is more like in net/ldap, I have Class which is syncing users from/to ldap and all fields that have UTF-8 need to be forced to be BINARY before sending, and to UTF-8 when they are received. Perhaps net/ldap should be patched instead.
3) I'm pretty new to Ruby. Google told me about force_encoding, didn't know about #encode.

@kwent

Pull request very helpful. I clone @graudeejs repository and users login with non latin characters works now !

You have to implements this as soon as possible in the official repo...

@cschiewek cschiewek closed this
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
This page is out of date. Refresh to see the latest.
Showing with 26 additions and 9 deletions.
  1. +26 −9 lib/devise_ldap_authenticatable/ldap_adapter.rb
View
35 lib/devise_ldap_authenticatable/ldap_adapter.rb
@@ -5,7 +5,9 @@ module Devise
module LdapAdapter
def self.valid_credentials?(login, password_plaintext)
- options = {:login => login,
+ bin_login = login.clone
+ bin_login.force_encoding('BINARY')
+ options = {:login => bin_login,
:password => password_plaintext,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}
@@ -15,8 +17,14 @@ def self.valid_credentials?(login, password_plaintext)
end
def self.update_password(login, new_password)
- options = {:login => login,
- :new_password => new_password,
+ bin_login = login.clone
+ bin_login.force_encoding('BINARY')
+
+ bin_new_password = new_password.clone
+ bin_new_password.force_encoding('BINARY')
+
+ options = {:login => bin_login,
+ :new_password => bin_new_password,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}
@@ -29,7 +37,9 @@ def self.update_own_password(login, new_password, current_password)
end
def self.ldap_connect(login)
- options = {:login => login,
+ bin_login = login.clone
+ bin_login.force_encoding('BINARY')
+ options = {:login => bin_login,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:admin => ::Devise.ldap_use_admin_to_bind}
@@ -49,7 +59,9 @@ def self.get_dn(login)
end
def self.set_ldap_param(login, param, new_value, password = nil)
- options = { :login => login,
+ bin_login = login.clone
+ bin_login.force_encoding('BINARY')
+ options = { :login => bin_login,
:ldap_auth_username_builder => ::Devise.ldap_auth_username_builder,
:password => password }
@@ -101,15 +113,18 @@ def set_param(param, new_value)
def dn
DeviseLdapAuthenticatable::Logger.send("LDAP dn lookup: #{@attribute}=#{@login}")
ldap_entry = search_for_login
- if ldap_entry.nil?
+ bin_dn = if ldap_entry.nil?
@ldap_auth_username_builder.call(@attribute,@login,@ldap)
else
ldap_entry.dn
end
+ bin_dn.force_encoding('BINARY')
end
def ldap_param_value(param)
- filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
+ bin_login = @login.to_s.clone
+ bin_login.force_encoding('BINARY')
+ filter = Net::LDAP::Filter.eq(@attribute.to_s, bin_login)
ldap_entry = nil
@ldap.search(:filter => filter) {|entry| ldap_entry = entry}
@@ -219,8 +234,10 @@ def valid_login?
#
# @return [Object] the LDAP entry found; nil if not found
def search_for_login
- DeviseLdapAuthenticatable::Logger.send("LDAP search for login: #{@attribute}=#{@login}")
- filter = Net::LDAP::Filter.eq(@attribute.to_s, @login.to_s)
+ bin_login = @login.to_s.clone
+ bin_login.force_encoding('BINARY')
+ DeviseLdapAuthenticatable::Logger.send("LDAP search for login: #{@attribute}=#{bin_login}")
+ filter = Net::LDAP::Filter.eq(@attribute.to_s, bin_login)
ldap_entry = nil
@ldap.search(:filter => filter) {|entry| ldap_entry = entry}
ldap_entry
Something went wrong with that request. Please try again.