mirror of
https://github.com/OpenNebula/one.git
synced 2025-03-22 18:50:08 +03:00
L #-: Fix previous Lint (#2741)
This commit is contained in:
parent
335f4cee6d
commit
b251cf45df
@ -20,117 +20,121 @@ require 'fileutils'
|
||||
require 'open3'
|
||||
require 'tempfile'
|
||||
|
||||
# SSH key authentication class. It can be used as a driver for auth_mad
|
||||
# as auth method is defined. It also holds some helper methods to be used
|
||||
# by oneauth command
|
||||
class OpenNebula::SshAuth
|
||||
module OpenNebula
|
||||
|
||||
# Initialize SshAuth object
|
||||
#
|
||||
# @param [Hash] default options for path
|
||||
# @option options [String] :public_key public key for the user
|
||||
# @option options [String] :private_key key private key for the user.
|
||||
def initialize(options = {})
|
||||
@private_key = nil
|
||||
@public_key = nil
|
||||
# SSH key authentication class. It can be used as a driver for auth_mad
|
||||
# as auth method is defined. It also holds some helper methods to be used
|
||||
# by oneauth command
|
||||
class SshAuth
|
||||
|
||||
# Initialize the private key
|
||||
if options[:private_key]
|
||||
begin
|
||||
@private_key = File.read(options[:private_key])
|
||||
rescue StandardError => e
|
||||
raise "Cannot read #{options[:private_key]}\n #{e}"
|
||||
# Initialize SshAuth object
|
||||
#
|
||||
# @param [Hash] default options for path
|
||||
# @option options [String] :public_key public key for the user
|
||||
# @option options [String] :private_key key private key for the user.
|
||||
def initialize(options = {})
|
||||
@private_key = nil
|
||||
@public_key = nil
|
||||
|
||||
# Initialize the private key
|
||||
if options[:private_key]
|
||||
begin
|
||||
@private_key = File.read(options[:private_key])
|
||||
rescue StandardError => e
|
||||
raise "Cannot read #{options[:private_key]}\n #{e}"
|
||||
end
|
||||
|
||||
begin
|
||||
@private_key_rsa = OpenSSL::PKey::RSA.new(@private_key)
|
||||
rescue OpenSSL::PKey::RSAError
|
||||
private_key_pem = openssh_to_pem(@private_key)
|
||||
@private_key_rsa = OpenSSL::PKey::RSA.new(private_key_pem)
|
||||
end
|
||||
end
|
||||
|
||||
# Initialize the public key
|
||||
if options[:public_key]
|
||||
@public_key = options[:public_key]
|
||||
elsif !@private_key.nil?
|
||||
# Init ssh keys using private key. public key is extracted in a
|
||||
# format compatible with openssl. The public key does not contain
|
||||
# "---- BEGIN/END PUBLIC KEY ----" and is in a single line
|
||||
@public_key = @private_key_rsa.public_key.to_pem.split("\n")
|
||||
@public_key = @public_key.reject {|l| l.match(/PUBLIC KEY/) }.join('')
|
||||
end
|
||||
|
||||
if @private_key.nil? && @public_key.nil?
|
||||
raise 'You have to define at least one of the keys'
|
||||
end
|
||||
|
||||
@public_key_rsa = OpenSSL::PKey::RSA.new(Base64.decode64(@public_key))
|
||||
end
|
||||
|
||||
# Creates a login token for ssh authentication.
|
||||
# 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_token(user, expire = 3600)
|
||||
expire ||= 3600
|
||||
|
||||
return encrypt("#{user}:#{Time.now.to_i + expire.to_i}")
|
||||
end
|
||||
|
||||
# Returns a valid password string to create a user using this auth driver.
|
||||
# In this case the ssh public key.
|
||||
def password
|
||||
@public_key
|
||||
end
|
||||
|
||||
# Checks the proxy created with the login method
|
||||
def authenticate(user, token)
|
||||
begin
|
||||
@private_key_rsa = OpenSSL::PKey::RSA.new(@private_key)
|
||||
rescue OpenSSL::PKey::RSAError
|
||||
private_key_pem = openssh_to_pem(@private_key)
|
||||
@private_key_rsa = OpenSSL::PKey::RSA.new(private_key_pem)
|
||||
token_plain = decrypt(token)
|
||||
t_user, time = token_plain.split(':')
|
||||
|
||||
return 'invalid credentials' unless user == t_user
|
||||
return 'ssh proxy expired, login again to renew it' if Time.now.to_i >= time.to_i
|
||||
|
||||
return true
|
||||
rescue StandardError
|
||||
return 'error'
|
||||
end
|
||||
end
|
||||
|
||||
# Initialize the public key
|
||||
if options[:public_key]
|
||||
@public_key = options[:public_key]
|
||||
elsif !@private_key.nil?
|
||||
# Init ssh keys using private key. public key is extracted in a
|
||||
# format compatible with openssl. The public key does not contain
|
||||
# "---- BEGIN/END PUBLIC KEY ----" and is in a single line
|
||||
@public_key = @private_key_rsa.public_key.to_pem.split("\n")
|
||||
@public_key = @public_key.reject {|l| l.match(/PUBLIC KEY/) }.join('')
|
||||
private
|
||||
|
||||
def openssh_to_pem(private_key)
|
||||
temp_file = Tempfile.new('private_key')
|
||||
|
||||
File.write(temp_file.path, private_key)
|
||||
|
||||
# Use ssh-keygen to convert the key
|
||||
command = "ssh-keygen -p -N '' -m PEM -f #{temp_file.path}"
|
||||
|
||||
_out, err, status = Open3.capture3(command)
|
||||
|
||||
raise "Failed to convert key: #{err}" unless status.success?
|
||||
|
||||
pem_key = File.read(temp_file.path)
|
||||
return pem_key
|
||||
ensure
|
||||
temp_file.close
|
||||
temp_file.unlink if temp_file
|
||||
end
|
||||
|
||||
if @private_key.nil? && @public_key.nil?
|
||||
raise 'You have to define at least one of the keys'
|
||||
###########################################################################
|
||||
# Methods to handle ssh keys
|
||||
###########################################################################
|
||||
# Encrypts data with the private key of the user and returns
|
||||
# base 64 encoded output in a single line
|
||||
def encrypt(data)
|
||||
Base64.encode64(@private_key_rsa.private_encrypt(data)).gsub!("\n", '').strip
|
||||
end
|
||||
|
||||
@public_key_rsa = OpenSSL::PKey::RSA.new(Base64.decode64(@public_key))
|
||||
end
|
||||
|
||||
# Creates a login token for ssh authentication.
|
||||
# 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_token(user, expire = 3600)
|
||||
expire ||= 3600
|
||||
|
||||
return encrypt("#{user}:#{Time.now.to_i + expire.to_i}")
|
||||
end
|
||||
|
||||
# Returns a valid password string to create a user using this auth driver.
|
||||
# In this case the ssh public key.
|
||||
def password
|
||||
@public_key
|
||||
end
|
||||
|
||||
# Checks the proxy created with the login method
|
||||
def authenticate(user, token)
|
||||
begin
|
||||
token_plain = decrypt(token)
|
||||
t_user, time = token_plain.split(':')
|
||||
|
||||
return 'invalid credentials' unless user == t_user
|
||||
return 'ssh proxy expired, login again to renew it' if Time.now.to_i >= time.to_i
|
||||
|
||||
return true
|
||||
rescue StandardError
|
||||
return 'error'
|
||||
# Decrypts base 64 encoded data with pub_key (public key)
|
||||
def decrypt(data)
|
||||
@public_key_rsa.public_decrypt(Base64.decode64(data))
|
||||
end
|
||||
end
|
||||
|
||||
private
|
||||
|
||||
def openssh_to_pem(private_key)
|
||||
temp_file = Tempfile.new('private_key')
|
||||
|
||||
File.write(temp_file.path, private_key)
|
||||
|
||||
# Use ssh-keygen to convert the key
|
||||
command = "ssh-keygen -p -N '' -m PEM -f #{temp_file.path}"
|
||||
|
||||
_out, err, status = Open3.capture3(command)
|
||||
|
||||
raise "Failed to convert key: #{err}" unless status.success?
|
||||
|
||||
pem_key = File.read(temp_file.path)
|
||||
return pem_key
|
||||
ensure
|
||||
temp_file.close
|
||||
temp_file.unlink if temp_file
|
||||
end
|
||||
|
||||
###########################################################################
|
||||
# Methods to handle ssh keys
|
||||
###########################################################################
|
||||
# Encrypts data with the private key of the user and returns
|
||||
# base 64 encoded output in a single line
|
||||
def encrypt(data)
|
||||
Base64.encode64(@private_key_rsa.private_encrypt(data)).gsub!("\n", '').strip
|
||||
end
|
||||
|
||||
# Decrypts base 64 encoded data with pub_key (public key)
|
||||
def decrypt(data)
|
||||
@public_key_rsa.public_decrypt(Base64.decode64(data))
|
||||
end
|
||||
|
||||
end
|
||||
|
Loading…
x
Reference in New Issue
Block a user