1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-02-04 17:47:00 +03:00

bug #847: Refactor X509CloudAuth

This commit is contained in:
Daniel Molina 2011-10-28 13:14:47 +02:00
parent 1f53b712cb
commit d80d81280d
2 changed files with 37 additions and 81 deletions

View File

@ -29,7 +29,7 @@ class CloudAuth
AUTH_CORE_MODULES = {
"cipher" => [ 'server_cipher_auth', 'ServerCipherAuth' ],
"x509" => [ 'server_x509_auth', 'ServerX509Auth' ]
}
}
# Default interval for timestamps. Tokens will be generated using the same
# timestamp for this interval of time.
@ -60,17 +60,20 @@ class CloudAuth
else
core_auth =AUTH_CORE_MODULES["cipher"]
end
begin
require core_auth[0]
@server_auth = Kernel.const_get(core_auth[1]).new_client
token = @server_auth.login_token(expiration_time)
@oneadmin_client ||= OpenNebula::Client.new(token, @conf[:one_xmlrpc])
rescue => e
raise e.message
end
end
def client(username)
token = @server_auth.login_token(expiration_time,username)
token = @server_auth.login_token(expiration_time,username)
Client.new(token,@conf[:one_xmlrpc])
end
@ -86,10 +89,8 @@ class CloudAuth
@token_expiration_time
end
def get_password(username, non_public_user=false)
token = @server_auth.login_token(expiration_time)
@oneadmin_client ||= OpenNebula::Client.new(token, @conf[:one_xmlrpc])
# If @user_pool is not defined it will retrieve it from OpenNebula
def get_userpool
if @user_pool.nil?
@user_pool ||= OpenNebula::UserPool.new(@oneadmin_client)
@ -99,12 +100,23 @@ class CloudAuth
end
end
@user_pool
end
def get_password(username, non_public_user=false)
if non_public_user == true
xp="USER[NAME=\"#{username}\" and AUTH_DRIVER!=\"public\"]/PASSWORD"
else
xp="USER[NAME=\"#{username}\"]/PASSWORD"
end
return @user_pool[xp]
return get_userpool[xp]
end
# Gets the username associated with a password
# password:: _String_ the password
# [return] _Hash_ with the username
def get_username(password)
return get_userpool["USER[contains(PASSWORD, \"#{password}\")]/NAME"]
end
end

View File

@ -15,90 +15,34 @@
#--------------------------------------------------------------------------- #
module X509CloudAuth
# Gets the username associated with a password
# password:: _String_ the password
# [return] _Hash_ with the username
def get_username(password)
token = @server_auth.login_token(expiration_time)
@oneadmin_client ||= OpenNebula::Client.new(token, @conf[:one_xmlrpc])
if @user_pool.nil?
@user_pool ||= OpenNebula::UserPool.new(@oneadmin_client)
rc = @user_pool.info
if OpenNebula.is_error?(rc)
raise rc.message
end
end
username = @user_pool["USER[PASSWORD=\"#{password}\"]/NAME"]
return username if (username != nil)
# Check if the DN is part of a |-separted multi-DN password
user_elts = Array.new
@user_pool.each {|e| user_elts << e['PASSWORD']}
multiple_users = user_elts.select {|e| e=~ /\|/ }
matched = nil
multiple_users.each do |e|
e.to_s.split('|').each do |w|
if (w == password)
matched=e
break
end
end
break if matched
end
if matched
password = matched.to_s
end
return @user_pool["USER[PASSWORD=\"#{password}\"]/NAME"]
end
def auth(env, params={})
failed = 'Authentication failed. '
# For https, the web service should be set to include the user cert in the environment.
cert_line = env['HTTP_SSL_CLIENT_CERT']
cert_line = nil if cert_line == '(null)' # For Apache mod_ssl
cert_line = env['HTTP_SSL_CLIENT_CERT']
cert_line = nil if cert_line == '(null)' # For Apache mod_ssl
chain_index = 0
# Use the https credentials for authentication
require 'server_x509_auth'
while cert_line
# Use the https credentials for authentication
unless cert_line.nil?
begin
cert_array=cert_line.scan(/([^\s]*)\s/)
cert_array = cert_array[2..-2]
cert_array.unshift('-----BEGIN CERTIFICATE-----')
cert_array.push('-----END CERTIFICATE-----')
cert_pem = cert_array.join("\n")
cert = OpenSSL::X509::Certificate.new(cert_pem)
m = cert_line.match(/(-+BEGIN CERTIFICATE-+)([^-]*)(-+END CERTIFICATE-+)/)
cert_s = "#{m[1]}#{m[2].gsub(' ',"\n")}#{m[3]}"
cert = OpenSSL::X509::Certificate.new(cert_s)
rescue
raise failed + "Could not create X509 certificate from " + cert_line
raise "Could not create X509 certificate from " + cert_line
end
# Password should be DN with whitespace removed.
subjectname = cert.subject.to_s.delete("\s")
begin
username = get_username(subjectname)
rescue
username = nil
end
username = get_username(cert.subject.to_s.delete("\s"))
break if username
return username if username
chain_dn = (!chain_dn ? "" : chain_dn) + "\n" + subjectname
chain_index = !chain_index ? 0 : chain_index + 1
cert_line = env["HTTP_SSL_CLIENT_CERT_CHAIN_#{chain_index}"]
cert_line = nil if cert_line == '(null)' # For Apache mod_ssl
cert_line = env["HTTP_SSL_CLIENT_CERT_CHAIN_#{chain_index}"]
cert_line = nil if cert_line == '(null)' # For Apache mod_ssl
chain_index += 1
else
raise "Username not found in certificate chain "
end
if !cert_line
msg = ""
msg << failed
msg << "Username not found in certificate chain "
msg << chain_dn if chain_dn
raise msg
end
return username
return nil
end
end