mirror of
https://github.com/OpenNebula/one.git
synced 2025-04-01 06:50:25 +03:00
Added support for X509 authorization in econe server.
This commit is contained in:
parent
ac71f33c15
commit
aee86437c3
@ -88,7 +88,12 @@ class CloudServer
|
||||
# [return] an OpenNebula client session
|
||||
def one_client_user(name, password)
|
||||
client = Client.new("dummy:dummy")
|
||||
client.one_auth = "#{name}:#{password}"
|
||||
if name=="dummy"
|
||||
#STDERR.puts "#{password}"
|
||||
client.one_auth = "#{password}"
|
||||
else
|
||||
client.one_auth = "#{name}:#{password}"
|
||||
end
|
||||
|
||||
return client
|
||||
end
|
||||
@ -101,7 +106,37 @@ class CloudServer
|
||||
return @user_pool["USER[NAME=\"#{name}\"]/PASSWORD"]
|
||||
end
|
||||
|
||||
|
||||
# Gets the username associated with a password
|
||||
# password:: _String_ the password
|
||||
# [return] _Hash_ with the username
|
||||
def get_username(password)
|
||||
@user_pool.info
|
||||
#STDERR.puts 'the password is ' + password
|
||||
#STDERR.puts @user_pool["User[PASSWORD=\"#{password}\"]"]
|
||||
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
|
||||
puts("The password is " + password)
|
||||
return @user_pool["USER[PASSWORD=\"#{password}\"]/NAME"]
|
||||
end
|
||||
|
||||
# Finds out if a port is available on ip
|
||||
# ip:: _String_ IP address where the port to check is
|
||||
# port:: _String_ port to find out whether is open
|
||||
|
@ -86,34 +86,88 @@ class EC2QueryServer < CloudServer
|
||||
# params:: of the request
|
||||
# [return] true if authenticated
|
||||
def authenticate(params,env)
|
||||
password = get_user_password(params['AWSAccessKeyId'])
|
||||
return nil if !password
|
||||
|
||||
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
|
||||
|
||||
if cert_line == nil
|
||||
# Use the secret key for authentication.
|
||||
|
||||
password = get_user_password(params['AWSAccessKeyId'])
|
||||
return nil if !password
|
||||
|
||||
signature = case params['SignatureVersion']
|
||||
when "1" then signature_version_1(params.clone, password)
|
||||
when "2" then signature_version_2(params,
|
||||
password,
|
||||
env,
|
||||
true,
|
||||
false)
|
||||
end
|
||||
|
||||
if params['Signature']==signature
|
||||
return one_client_user(params['AWSAccessKeyId'], password)
|
||||
else
|
||||
if params['SignatureVersion']=="2"
|
||||
signature = signature_version_2(params,
|
||||
signature = case params['SignatureVersion']
|
||||
when "1" then signature_version_1(params.clone, password)
|
||||
when "2" then signature_version_2(params,
|
||||
password,
|
||||
env,
|
||||
false,
|
||||
true,
|
||||
false)
|
||||
if params['Signature']==signature
|
||||
return one_client_user(params['AWSAccessKeyId'], password)
|
||||
end
|
||||
|
||||
if params['Signature']==signature
|
||||
return one_client_user(params['AWSAccessKeyId'], password)
|
||||
else
|
||||
if params['SignatureVersion']=="2"
|
||||
signature = signature_version_2(params,
|
||||
password,
|
||||
env,
|
||||
false,
|
||||
false)
|
||||
if params['Signature']==signature
|
||||
return one_client_user(params['AWSAccessKeyId'], password)
|
||||
end
|
||||
end
|
||||
end
|
||||
end
|
||||
|
||||
return nil
|
||||
return nil
|
||||
else
|
||||
# Use the https credentials for authentication
|
||||
require 'server_auth'
|
||||
while cert_line
|
||||
begin
|
||||
cert_array=cert_line.scan(/([^\s]*)\s/)
|
||||
cert_array = cert_array[2..-3]
|
||||
cert_array.unshift('-----BEGIN CERTIFICATE-----')
|
||||
cert_array.push('-----END CERTIFICATE-----')
|
||||
cert_pem = cert_array.join("\n")
|
||||
#cert_pem = cert_line.scan(/(-+BEGIN CERTIFICATE-+\n[^-]*\n-+END CERTIFICATE-+)/)
|
||||
cert = OpenSSL::X509::Certificate.new(cert_pem)
|
||||
rescue
|
||||
raise failed + "Could not create X509 certificate from " + cert_line
|
||||
end
|
||||
# Password should be DN with whitespace removed.
|
||||
subjectname = cert.subject.to_s.delete("\s")
|
||||
#STDERR.puts 'the cert is' + cert.subject.to_s
|
||||
begin
|
||||
username = get_username(subjectname)
|
||||
rescue
|
||||
username = nil
|
||||
end
|
||||
#STDERR.puts "the username is " + username
|
||||
break 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
|
||||
end
|
||||
|
||||
if !cert_line
|
||||
raise failed + "Username not found in certificate chain " + chain_dn
|
||||
end
|
||||
|
||||
auth = ServerAuth.new
|
||||
|
||||
login = auth.login_token(username, subjectname, 300)
|
||||
|
||||
STDERR.puts login
|
||||
|
||||
return one_client_user("dummy", login)
|
||||
|
||||
end
|
||||
end
|
||||
|
||||
|
||||
|
@ -70,7 +70,13 @@ set :port, $econe_server.config[:port]
|
||||
##############################################################################
|
||||
|
||||
before do
|
||||
@client = $econe_server.authenticate(params,env)
|
||||
#STDERR.puts Time.now.strftime("%d/%b/%Y %H:%M:%S")
|
||||
begin
|
||||
@client = $econe_server.authenticate(params,env)
|
||||
rescue => e
|
||||
#STDERR.puts Time.now.strftime("%d/%b/%Y %H:%M:%S") + ' Exception in authentication. ' + e.to_s
|
||||
@client = nil
|
||||
end
|
||||
|
||||
if @client.nil?
|
||||
error 400, error_xml("AuthFailure", 0)
|
||||
|
Loading…
x
Reference in New Issue
Block a user