1
0
mirror of https://github.com/OpenNebula/one.git synced 2025-03-22 18:50:08 +03:00

feature : Add PROXY_PATH constant

This commit is contained in:
Daniel Molina 2011-08-23 16:24:03 +02:00
parent e7e96a9fab
commit f0e959c77e
3 changed files with 78 additions and 83 deletions
src/authm_mad/remotes

@ -24,6 +24,8 @@ require 'fileutils'
# as auth method is defined. It also holds some helper methods to be used
# by oneauth command
class SshAuth
PROXY_PATH = ENV['HOME']+'/.one/one_ssh'
attr_reader :public_key
# Initialize SshAuth object
@ -64,33 +66,28 @@ class SshAuth
# By default it is valid for 1 hour but it can be changed to any number
# of seconds with expire parameter (in seconds)
def login(user, expire=3600)
expire ||= 3600
# Init proxy file path and creates ~/.one directory if needed
proxy_dir=ENV['HOME']+'/.one'
proxy_dir = File.dirname(PROXY_PATH)
begin
FileUtils.mkdir_p(proxy_dir)
rescue Errno::EEXIST
end
proxy_path = proxy_dir + '/one_ssh'
# Generate security token
time = Time.now.to_i + expire
time = Time.now.to_i + expire.to_i
secret_plain = "#{user}:#{time}"
secret_crypted = encrypt(secret_plain)
proxy = "#{user}:ssh:#{secret_crypted}"
file = File.open(proxy_path, "w")
file = File.open(PROXY_PATH, "w")
file.write(proxy)
file.close
# Help string
puts "export ONE_AUTH=#{ENV['HOME']}/.one/one_ssh"
secret_crypted
end
@ -99,7 +96,7 @@ class SshAuth
begin
token_plain = decrypt(token)
_user, time = token_plain.split(':')
if user == _user
if Time.now.to_i >= time.to_i
return "ssh proxy expired, login again to renew it"
@ -114,12 +111,13 @@ class SshAuth
end
end
private
private
###########################################################################
# Methods to handle ssh keys
###########################################################################
# Encrypts data with the private key of the user and returns
# base 64 encoded output in a single line
# base 64 encoded output in a single line
def encrypt(data)
rsa=OpenSSL::PKey::RSA.new(@private_key)
Base64::encode64(rsa.private_encrypt(data)).gsub!(/\n/, '').strip

@ -22,6 +22,9 @@ require 'fileutils'
# as auth method is defined. It also holds some helper methods to be used
# by oneauth command
class X509Auth
PROXY_PATH = ENV['HOME']+'/.one/one_x509'
attr_reader :dn
# Initialize x509Auth object
#
@ -42,7 +45,7 @@ class X509Auth
if @options[:key]
@key = OpenSSL::PKey::RSA.new(@options[:key])
end
end
end
###########################################################################
@ -53,50 +56,45 @@ class X509Auth
# By default it is valid for 1 hour but it can be changed to any number
# of seconds with expire parameter (in seconds)
def login(user, expire=3600)
expire ||= 3600
# Init proxy file path and creates ~/.one directory if needed
# Set instance variables
proxy_dir=ENV['HOME']+'/.one'
proxy_dir = File.dirname(PROXY_PATH)
begin
FileUtils.mkdir_p(proxy_dir)
rescue Errno::EEXIST
end
one_proxy_path = proxy_dir + '/one_x509'
#Create the x509 proxy
time = Time.now.to_i+expire
text_to_sign = "#{user}:#{@dn}:#{time}"
signed_text = encrypt(text_to_sign)
token = "#{signed_text}:#{@cert.to_pem}"
token = "#{signed_text}:#{@cert.to_pem}"
token64 = Base64::encode64(token).strip.delete!("\n")
proxy="#{user}:x509:#{token64}"
file = File.open(one_proxy_path, "w")
file = File.open(PROXY_PATH, "w")
file.write(proxy)
file.close
# Help string
puts "export ONE_AUTH=#{ENV['HOME']}/.one/one_x509"
token64
end
###########################################################################
# Server side
###########################################################################
# auth method for auth_mad
def authenticate(user, pass, token)
def authenticate(user, pass, token)
begin
validate
plain = decrypt(token)
_user, subject, time_expire = plain.split(':')
if (user != _user)
@ -112,22 +110,22 @@ class X509Auth
return e.message
end
end
private
###########################################################################
# Methods to encrpyt/decrypt keys
###########################################################################
# Encrypts data with the private key of the user and returns
# base 64 encoded output in a single line
# base 64 encoded output in a single line
def encrypt(data)
return nil if !@key
Base64::encode64(@key.private_encrypt(data)).delete!("\n").strip
end
# Decrypts base 64 encoded data with pub_key (public key)
def decrypt(data)
def decrypt(data)
@cert.public_key.public_decrypt(Base64::decode64(data))
end
end
###########################################################################
# Validate the user certificate
@ -138,10 +136,10 @@ private
# Check start time and end time of certificate
if @cert.not_before > now || @cert.not_after < now
raise failed + "Certificate not valid. Current time is " +
raise failed + "Certificate not valid. Current time is " +
now.localtime.to_s + "."
end
# Check the rest of the certificate chain if specified
if !@options[:ca_dir]
return
@ -149,24 +147,24 @@ private
begin
signee = @cert
begin
ca_hash = signee.issuer.hash.to_s(16)
ca_path = @options[:ca_dir] + '/' + ca_hash + '.0'
ca_cert = OpenSSL::X509::Certificate.new(File.read(ca_path))
if !((signee.issuer.to_s == ca_cert.subject.to_s) &&
if !((signee.issuer.to_s == ca_cert.subject.to_s) &&
(signee.verify(ca_cert.public_key)))
raise failed + signee.subject.to_s + " with issuer " +
signee.issuer.to_s + " was not verified by " +
raise failed + signee.subject.to_s + " with issuer " +
signee.issuer.to_s + " was not verified by " +
ca.subject.to_s + "."
end
signee = ca_cert
end while ca_cert.subject.to_s != ca_cert.issuer.to_s
rescue
raise
raise
end
end
end

@ -18,19 +18,20 @@ require 'openssl'
require 'base64'
require 'fileutils'
# Authentication class based on x509 proxy certificate.
# Authentication class based on x509 proxy certificate.
class X509ProxyAuth
PROXY_PATH = ENV['HOME']+'/.one/one_x509_proxy'
# Initialize x509ProxyAuth object
#
# @param [Hash] default options for path
# @option options [String] :proxy ($X509_PROXY_CERT)
# @option options [String] :proxy ($X509_PROXY_CERT)
# proxy cert for the user
# @option options [String] :proxy_cert (nil)
# @option options [String] :proxy_cert (nil)
# public cert of a user proxy
# @option options [String] :user_cert (nil)
# @option options [String] :user_cert (nil)
# user cert, used to generate the proxy
# @option options [String] :ca_dir (/etc/grid-security/certificates)
# @option options [String] :ca_dir (/etc/grid-security/certificates)
# trusted CA directory. If nil it will not be used to verify
# certificates
def initialize(options={})
@ -53,33 +54,33 @@ class X509ProxyAuth
proxy_cert_txt = rc[0]
user_cert_txt = rc[1]
rc = proxy.match(/-+BEGIN RSA PRIVATE KEY-+\n([^-]*)\n-+END RSA PRIVATE KEY-+/)
proxy_key_txt = rc[1]
end
if !proxy_cert_txt || !user_cert_txt
raise "Can not get user or proxy certificates"
end
@proxy_cert = OpenSSL::X509::Certificate.new(proxy_cert_txt)
@user_cert = OpenSSL::X509::Certificate.new(user_cert_txt)
@dn = @user_cert.subject.to_s
if proxy_ket_txt
@poxy_key = OpenSSL::PKey::RSA.new(proxy_key_txt)
end
# Load configuration file
#@auth_conf_path = ETC_LOCATION+'/auth/auth.conf'
#if File.readable?(@auth_conf_path)
# config = File.read(@auth_conf_path)
# config = YAML::load(config_data)
# @options.merge!(config)
#end
#end
end
###########################################################################
@ -90,47 +91,45 @@ class X509ProxyAuth
def login(user)
# Init proxy file path and creates ~/.one directory if needed
# Set instance variables
proxy_dir=ENV['HOME']+'/.one'
proxy_dir=File.dirname(PROXY_PATH)
begin
FileUtils.mkdir_p(proxy_dir)
rescue Errno::EEXIST
end
one_proxy_path = proxy_dir + '/one_x509_proxy'
#Generate token for authentication
text_to_sign = "#{user}:#{@dn}"
signed_text = encrypt(text_to_sign)
token = "#{signed_text}:#{@proxy_cert.to_pem}:#{@user_cert.to_pem}"
token = "#{signed_text}:#{@proxy_cert.to_pem}:#{@user_cert.to_pem}"
token64 = Base64::encode64(token).strip.delete!("\n")
proxy="#{user}:grid:#{token64}"
file = File.open(one_proxy_path, "w")
file = File.open(PROXY_PATH, "w")
file.write(proxy)
file.close
# Help string
puts "export ONE_AUTH=#{ENV['HOME']}/.one/one_grid"
puts "export ONE_AUTH=#{ENV['HOME']}/.one/one_x509_proxy"
token64
end
###########################################################################
# Server side
###########################################################################
# auth method for auth_mad
def authenticate(user, pass, token)
def authenticate(user, pass, token)
begin
validate_chain
plain = decrypt(token)
_user, subject = plain.split(':')
if (user != _user)
@ -149,14 +148,14 @@ private
# Methods to encrpyt/decrypt keys
###########################################################################
# Encrypts data with the private key of the user and returns
# base 64 encoded output in a single line
# base 64 encoded output in a single line
def encrypt(data)
return nil if !@proxy_key
Base64::encode64(@proxy_key.private_encrypt(data)).delete!("\n").strip
end
# Decrypts base 64 encoded data with pub_key (public key)
def decrypt(data)
def decrypt(data)
@proxy_cert.public_key.public_decrypt(Base64::decode64(data))
end
@ -169,22 +168,22 @@ private
# Check start time and end time of proxy
if @proxy_cert.not_before > now || @proxy_cert.not_after < now
raise failed + "Certificate not valid. Current time is " +
raise failed + "Certificate not valid. Current time is " +
now.localtime.to_s + "."
end
# Check that the issuer of the proxy is the same user as in the user certificate
if @proxy_cert.issuer.to_s != @user_cert.subject.to_s
raise failed + "Proxy with issuer " + @proxy_cert.issuer.to_s +
raise failed + "Proxy with issuer " + @proxy_cert.issuer.to_s +
" does not match user " + @dn
end
# Check that the user signed the proxy
if !@proxy_cert.verify(@user_cert.public_key)
raise "Proxy with subject " + @proxy_cert.subject.to_s +
raise "Proxy with subject " + @proxy_cert.subject.to_s +
" was not verified by " + @dn + "."
end
# Check the rest of the certificate chain if specified
if !@options[:ca_dir]
return
@ -192,24 +191,24 @@ private
begin
signee = @user_cert
begin
ca_hash = signee.issuer.hash.to_s(16)
ca_path = @options[:ca_dir] + '/' + ca_hash + '.0'
ca_cert = OpenSSL::X509::Certificate.new(File.read(ca_path))
if !((signee.issuer.to_s == ca_cert.subject.to_s) &&
if !((signee.issuer.to_s == ca_cert.subject.to_s) &&
(signee.verify(ca_cert.public_key)))
raise failed + signee.subject.to_s + " with issuer " +
signee.issuer.to_s + " was not verified by " +
raise failed + signee.subject.to_s + " with issuer " +
signee.issuer.to_s + " was not verified by " +
ca.subject.to_s + "."
end
signee = ca_cert
end while ca_cert.subject.to_s != ca_cert.issuer.to_s
rescue
raise
raise
end
end
end