class Nucleus::SSHHandler

Attributes

key_file[R]

Public Class Methods

new(custom_ssh_key_file = nil) click to toggle source

Setup the SSHHandler. @param [String] custom_ssh_key_file path to the key file @return [Nucleus::SSHHandler] the created instance

# File lib/nucleus/core/common/ssh_handler.rb, line 10
def initialize(custom_ssh_key_file = nil)
  @custom_ssh_key_file = custom_ssh_key_file
  @key_file = @custom_ssh_key_file
  @key_file_history = []
  @agent_file_history = []

  if custom_ssh_key_file
    # file must not be accessible by others, otherwise usage will be forbidden by git.
    FileUtils.chmod(0600, custom_ssh_key_file) if OS.unix?
    cache_public_key
  end

  # create the initial agent / key combination
  create_agent_key_combo
end

Public Instance Methods

cleanup() click to toggle source

Cleanup all created tmp files. Usually to be invoked before shutdown.

# File lib/nucleus/core/common/ssh_handler.rb, line 37
def cleanup
  @agent_file_history.each { |af| FileUtils.rm_f(af) }
  @key_file_history.each { |kf| FileUtils.rm_f(kf) }
end
public_key() click to toggle source

Get the public key that shall be used for authentication. Furthermore, the method assures that the agent, which was registered in the GIT_SSH variable, is available. @return [String] ssh public key in full format (type, value, comment)

# File lib/nucleus/core/common/ssh_handler.rb, line 29
def public_key
  return @public_key if File.exist?(@agent_file) && File.exist?(@key_file)
  # create the agent and key if at least one file does not exist (anymore)
  create_agent_key_combo
  @public_key
end

Private Instance Methods

add_history_entry() click to toggle source
# File lib/nucleus/core/common/ssh_handler.rb, line 95
def add_history_entry
  @key_file_history.push(@key_file) unless @custom_ssh_key_file
  @agent_file_history.push(@agent_file)
end
cache_public_key() click to toggle source
# File lib/nucleus/core/common/ssh_handler.rb, line 100
def cache_public_key
  @public_key = SSHKey.new(File.read(@key_file), comment: 'Nucleus').ssh_public_key
rescue
  msg = "Invalid custom SSH key '#{@key_file}', must be of type ssh-rsa."
  STDERR.puts msg
  raise Nucleus::StartupError.new(msg, Nucleus::ExitCodes::INVALID_SSH_KEY)
end
create_agent() click to toggle source
# File lib/nucleus/core/common/ssh_handler.rb, line 77
def create_agent
  # use uuid so that more than one instance can run at the same time
  @agent_file = File.expand_path(File.join(Dir.tmpdir, 'nucleus', 'ssh', 'agent', SecureRandom.uuid))
  # windows requires the extension, otherwise git complains that it can't spawn such a file
  @agent_file = "#{@agent_file}.bat" if OS.windows?
  # make sure agent file path exists
  FileUtils.mkdir_p(File.dirname(@agent_file))

  # adapt the agent file to OS specific requirements
  if OS.unix?
    File.write(@agent_file, "ssh -i #{@key_file} -o UserKnownHostsFile=/dev/null -o StrictHostKeyChecking=no $*")
    FileUtils.chmod(0700, @agent_file)
  else
    File.write(@agent_file, "@echo off\r\nssh -i #{@key_file} -o UserKnownHostsFile=NUL "\
      '-o StrictHostKeyChecking=no %*')
  end
end
create_agent_key_combo() click to toggle source
# File lib/nucleus/core/common/ssh_handler.rb, line 44
def create_agent_key_combo
  log.debug('(Re-) creating the nucleus ssh agent')

  # create a new private key
  create_private_key

  # save the agent file
  create_agent

  # add to history so that it will be cleaned up
  add_history_entry

  # finally apply the custom SSH script
  Git.configure { |config| config.git_ssh = @agent_file }
end
create_private_key() click to toggle source
# File lib/nucleus/core/common/ssh_handler.rb, line 60
def create_private_key
  # only create a new tmp key if no custom key location was specified
  return if @custom_ssh_key_file

  log.debug('Create new private key file')
  @key_file = File.expand_path(File.join(Dir.tmpdir, 'nucleus', 'ssh', 'key', "#{SecureRandom.uuid}.pem"))
  # make sure key file path exists
  FileUtils.mkdir_p(File.dirname(@key_file))

  # generates default key of type RSA and with 2048 bits
  File.write(@key_file, SSHKey.generate(type: 'RSA', bits: 2048, comment: 'tmp_key_4_nucleus').private_key)
  cache_public_key

  # file must not be accessible by others, otherwise usage will be forbidden by git.
  FileUtils.chmod(0600, @key_file) if OS.unix?
end