hashview / hashview-old

A web front-end for password cracking and analytics
http://www.hashview.io
GNU General Public License v3.0
622 stars 133 forks source link

Implement Authentication over LDAP #465

Open pcrossy opened 5 years ago

pcrossy commented 5 years ago

It would be nice if you would implement the support of LDAP authentication for Hashview.

Script-Nomad commented 5 years ago

Seconding this feature request

ccammilleri commented 5 years ago

This wouldn't be too hard, but isn't a priority for the core devs at the moment.

If anyone wants to tackle it, here are some engineering notes:

  1. add configurations options for ldap in settings table
  2. add an auth_type field in the users table. have it default to local auth and allow ldap. add presentation options on user create in UI
  3. use require net/ldap
  4. on login, if user auth_type is ldap, perform ldap auth with: ldap = Net::LDAP.new host: (config_options['ldap_server']).to_s, port: 636, encryption: :simple_tls, auth: { method: :simple, username: user, password: params[:password] }
lucamemini commented 5 years ago

Very very "rough" patch

--- /opt/hashview/routes/login.rb       2019-09-04 11:47:54.340115590 +0000
+++ hashview/routes/login.rb    2018-04-04 08:32:24.494833647 +0000
@@ -34,6 +35,36 @@

   @user = User.first(username: params[:username])

+  if ! @user
+       #puts "OK!!"
+       ldap = Net::LDAP.new :host => 'YOUR_LDAP_ADDRESS',:port => 389,:base => "dc=YOUR_DC,dc=YOUR_DC"
+       ldap.auth "CN=YOUR_USER,DC=YOUR_DC,DC=YOUR_DC", 'YOUR_PASS'
+       if ldap.bind
+           puts "bind search: ok"
+           ldap.search( base: "DC=YOUR_DC,DC=YOUR_D", filter: Net::LDAP::Filter.eq( "uid", username ), return_result: true ) do |entry|
+                ldap.auth entry.dn, params[:password]
+               if ldap.bind
+                   puts "LDAP valid user, creating MySQL value"
+                   puts entry.mail
+                   new_user = User.new
+                   new_user.username = params[:username]
+                   new_user.password = params[:password]
+                   new_user.email = entry.mail unless entry.mail.nil? || entry.mail.empty?
+                   new_user.id = User.last[:id].to_i + 1
+                   new_user.save
+
+                   @user = User.first(username: params[:username])
+               else
+                   puts "Invalid username or password on LDAP Server"
+               end
+           end
+       else
+            puts "bind search: failed"
+       end
+  end
+
+
+
   if @user
     usern = User.authenticate(params['username'], params['password'])
--- /opt/hashview/models/master.rb      2019-09-04 11:47:54.316115213 +0000
+++ hashview/models/master.rb   2018-04-04 08:24:35.700639772 +0000
@@ -2,6 +2,7 @@
 require 'sequel'
 require 'bcrypt'
 require 'rotp'
+require 'net/ldap'

 Sequel::Model.plugin :json_serializer

@@ -43,12 +44,36 @@
   end

   def self.authenticate(username, pass)
+    ldap = Net::LDAP.new :host => 'YOUR_LDAP_ADDRESS',:port => 389,:base => "dc=YOUR_DC,dc=YOUR_DC"
     user = User.first(username: username)
-    if user.mfa
-      return user.username if pass == ROTP::TOTP.new(user.auth_secret).now.to_s
-    elsif user
-      return user.username if BCrypt::Password.new(user.hashed_password) == pass
+    
+    user_not_valid = User.first(username: "user_not_valid")
+
+    ldap.auth "CN=YOUR_USER,DC=YOUR_DC,DC=YOUR_DC", 'YOUR_PASS'
+    if ldap.bind
+        puts "bind search: ok"
+       ldap.search( base: "DC=YOUR_DC,DC=YOUR_D", filter: Net::LDAP::Filter.eq( "uid", username ), return_result: true ) do |entry|
+           ldap.auth entry.dn, pass
+            if ldap.bind
+                puts "bind  ok"
+
+               @users = User.where(username: username ).all
+               if @users.empty?
+                   puts "User doesn't exit on mysql"
+                   return user_not_valid
+               else
+                   puts "User exit on mysql"
+                    return user.username
+               end
+            else
+               return user_not_valid
+            end
+       end
+    else
+        puts "bind search: failed"
+       return user_not_valid
     end
+
   end

   def self.create_test_user(attrs = {})

And then append gem 'net-ldap' in yout Gemfile :-)

ciao l.