Class: Confman::Access

Inherits:
Object
  • Object
show all
Defined in:
lib/confman/access.rb

Instance Attribute Summary collapse

Instance Method Summary collapse

Constructor Details

#initialize(api = Confman.api) ⇒ Access



7
8
9
# File 'lib/confman/access.rb', line 7

def initialize(api = Confman.api)
  self.api = api
end

Instance Attribute Details

#apiObject

Returns the value of attribute api.



5
6
7
# File 'lib/confman/access.rb', line 5

def api
  @api
end

Instance Method Details

#authorized_keys_locationObject



76
77
78
79
80
# File 'lib/confman/access.rb', line 76

def authorized_keys_location
  ssh_dir = "#{ENV["HOME"]}/.ssh"
  FileUtils.mkdir_p(ssh_dir) unless File.exists?(ssh_dir)
  return "#{ssh_dir}/authorized_keys"
end

#decrypt(encrypted_data) ⇒ Object



82
83
84
85
86
87
88
89
90
91
92
93
94
95
# File 'lib/confman/access.rb', line 82

def decrypt(encrypted_data)
  encrypted_data = Base64.decode64(encrypted_data)
  if encrypted_data =~ /^0A/
    cipher = OpenSSL::Cipher::Cipher.new('aes-256-cbc')
    cipher.decrypt
    cipher.key = rsa.public_decrypt(encrypted_data[2, 128])
    cipher.iv  = rsa.public_decrypt(encrypted_data[130, 128])
    data = cipher.update(encrypted_data[258..-1])
    data << cipher.final
    return data
  else
    raise "invalid data found"
  end
end

#extract_keys(file = authorized_keys_location) ⇒ Object



11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
# File 'lib/confman/access.rb', line 11

def extract_keys(file = authorized_keys_location)
  r = { :manual_keys => [], :users => {} } 
  return r unless File.exists?(file)
  File.readlines(file).each do |key|
    key.chomp!
    if key =~ /^#\sAM\s([^=]+)=(.*)$/
      r[$1.to_sym] = $2
    elsif key =~ /^environment=\"AM_USER=([^\"]+)\"\s(.*)$/
      r[:users][$1] ||= []
      r[:users][$1].push($2)

    elsif key =~ /^ssh-/
      r[:manual_keys].push(key.chomp)
    end
  end
  r
end

#request_new_keysObject



102
103
104
105
106
107
108
109
110
111
112
113
114
# File 'lib/confman/access.rb', line 102

def request_new_keys
  begin
    results, response = Confman.api.request(:get, "computing_resources/access_keys", {})
  rescue RestClient::Conflict
    STDERR.puts("This instance has no key. Please run 'confman init' as root to reset your key for this instance")
    return nil
  end

  results.update(JSON.parse(decrypt(results[:data])))
  results.symbolize_keys!
  results.delete(:data)
  return results
end

#reset_keysObject



57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
# File 'lib/confman/access.rb', line 57

def reset_keys
  current_keys = extract_keys
  new_keys = request_new_keys 

  keys_changed = current_keys[:users].keys.sort != new_keys[:users].keys.sort
  current_keys[:users].each do |user, ssh_keys|
    keys_changed = true if ssh_keys.sort != new_keys[:users][user].sort
  end unless keys_changed

  if keys_changed
    new_keys[:manual_keys] = current_keys[:manual_keys]

    new_authorized_keys_file = "#{authorized_keys_location}.#{Time.now.to_i}"
    save_keys(new_keys, new_authorized_keys_file)
    FileUtils.cp(new_authorized_keys_file, authorized_keys_location)
  end

end

#rsaObject



97
98
99
100
# File 'lib/confman/access.rb', line 97

def rsa
  @rsa ||= OpenSSL::PKey::RSA.new(File.read("#{self.api.config_dir}/.asym.key"))
  @rsa
end

#save_keys(key_info, file = "#{authorized_keys_location}.#{Time.now.to_i}") ⇒ Object



29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
# File 'lib/confman/access.rb', line 29

def save_keys(key_info, file = "#{authorized_keys_location}.#{Time.now.to_i}")
  File.open(file, "w") do |fh|
    key_info.each do |attribute, value|

      if attribute == :manual_keys
        key_info[attribute].each do |k|
          fh.puts k
        end

      elsif attribute == :users
        key_info[attribute].each do |u, keys|
          keys.each do |k|
            fh.puts("environment=\"AM_USER=#{u}\" #{k}")
          end
        end

      else
        fh.puts("# AM #{attribute}=#{value}")
      end

    end
  end

  File.chmod(0600, file)

  file
end