Class: SSH::Ident::AgentManager

Inherits:
Object
  • Object
show all
Defined in:
lib/ssh/ident/agent_manager.rb

Overview

ssh agent manager

Instance Method Summary collapse

Constructor Details

#initialize(options = {}) ⇒ AgentManager

Returns a new instance of AgentManager.



10
11
12
13
14
15
16
17
# File 'lib/ssh/ident/agent_manager.rb', line 10

def initialize(options = {})
  @config = Config.new
  @identity = options[:identity]
  @identity ||= find_identity
  @agent_file = agent_file
  start_agent unless agent_running?
  load_needed_keys
end

Instance Method Details

#agent_fileObject



19
20
21
22
23
24
25
26
# File 'lib/ssh/ident/agent_manager.rb', line 19

def agent_file
  agent_path = @config.get('DIR_AGENTS')
  unless File.directory?(agent_path)
    FileUtils.mkdir_p agent_path
    FileUtils.chmod 0700, agent_path
  end
  File.join(agent_path, "agent-#{@identity}-#{Socket.gethostname}")
end

#agent_loaded_keysObject



73
74
75
76
77
78
79
80
81
# File 'lib/ssh/ident/agent_manager.rb', line 73

def agent_loaded_keys
  fingerprints = []
  result = ShellCmd.new(command: 'ssh-add -l', agent_file: @agent_file, output: true).run
  return fingerprints if result.nil?
  result.split("\n").each do |line|
    fingerprints << line.split(' ')[1]
  end
  fingerprints
end

#agent_running?Boolean

Returns:

  • (Boolean)


28
29
30
31
32
33
# File 'lib/ssh/ident/agent_manager.rb', line 28

def agent_running?
  return false unless File.exist?(@agent_file)
  result = ShellCmd.new(command: 'ssh-add -l', agent_file: @agent_file).run
  return false if result.nil?
  true
end

#find_identityObject



35
36
37
38
39
# File 'lib/ssh/ident/agent_manager.rb', line 35

def find_identity
  env_indentity = ENV['SSH_IDENTITY']
  return env_indentity if env_indentity && !env_indentity.empty?
  @config.get('DEFAULT_IDENTITY')
end

#find_keysObject



41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
# File 'lib/ssh/ident/agent_manager.rb', line 41

def find_keys
  @identity ||= find_identity
  search_dir = []
  search_dir << File.join(File.expand_path(@config.get('DIR_IDENTITIES')), @identity)
  if ENV['USER'] && @identity.eql?(ENV['USER'])
    search_dir << File.expand_path("#{ENV['HOME']}/.ssh")
  end
  keys = {}
  search_dir.each do |search|
    Dir.glob("#{search}/*") do |key_file|
      key = File.basename(key_file, '.*')
      keys[key] ||= {}
      if key_file.end_with?('.pem')
        ShellCmd.new(command: "ssh-keygen -yf #{key_file} > #{key_file}.pub", output: true) unless File.exist?("#{key_file}.pub")
        keys[key][:private] = key_file
        keys[key][:public] = "#{key_file}.pub"
      elsif key_file.end_with?('.pub')
        keys[key][:public] = key_file
      else
        keys[key][:private] = key_file
      end
    end
  end
  keys.select { |_k, v| v.key?(:private) && v.key?(:public) }
end

#key_fingerprint(key_file) ⇒ Object



67
68
69
70
71
# File 'lib/ssh/ident/agent_manager.rb', line 67

def key_fingerprint(key_file)
  output = ShellCmd.new(command: "ssh-keygen -l -f #{key_file}").run
  return nil unless output
  output.split(' ')[1]
end

#load_needed_keysObject



83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/ssh/ident/agent_manager.rb', line 83

def load_needed_keys
  loaded_keys = agent_loaded_keys
  keys_to_add = []
  find_keys.each do |_key, prop|
    unless loaded_keys.include?(key_fingerprint(prop[:public]))
      keys_to_add << prop[:private]
    end
  end
  if keys_to_add.size > 0
    ShellCmd.new(command: "ssh-add #{@config.get('SSH_ADD_OPTIONS')} #{keys_to_add.join(' ')}",
        agent_file: @agent_file).run
  end
end

#start_agentObject



97
98
99
100
# File 'lib/ssh/ident/agent_manager.rb', line 97

def start_agent
  puts "agent file is #{@agent_file}"
  ShellCmd.new(command: "ssh-agent > #{@agent_file}", own_env: true, output: true).run
end