1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
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
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
|
#
# A wrapper around OpenSSL::PKey::RSA instances to provide a better api for dealing with SSH keys.
#
#
require 'net/ssh'
require 'forwardable'
module LeapCli
class SshKey
extend Forwardable
attr_accessor :filename
attr_accessor :comment
##
## CLASS METHODS
##
def self.load(arg1, arg2=nil)
key = nil
if arg1.is_a? OpenSSL::PKey::RSA
key = SshKey.new arg1
elsif arg1.is_a? String
if arg1 =~ /^ssh-/
type, data = arg1.split(' ')
key = SshKey.new load_from_data(data, type)
elsif File.exists? arg1
key = SshKey.new load_from_file(arg1)
key.filename = arg1
else
key = SshKey.new load_from_data(arg1, arg2)
end
end
return key
end
def self.load_from_file(filename)
public_key = nil
private_key = nil
begin
public_key = Net::SSH::KeyFactory.load_public_key(filename)
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
begin
private_key = Net::SSH::KeyFactory.load_private_key(filename)
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
end
end
public_key || private_key
end
def self.load_from_data(data, type='ssh-rsa')
public_key = nil
private_key = nil
begin
public_key = Net::SSH::KeyFactory.load_data_public_key("#{type} #{data}")
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
begin
private_key = Net::SSH::KeyFactory.load_data_private_key("#{type} #{data}")
rescue NotImplementedError, Net::SSH::Exception, OpenSSL::PKey::PKeyError
end
end
public_key || private_key
end
##
## INSTANCE METHODS
##
public
def initialize(rsa_key)
@key = rsa_key
end
def_delegator :@key, :fingerprint, :fingerprint
def_delegator :@key, :public?, :public?
def_delegator :@key, :private?, :private?
def_delegator :@key, :ssh_type, :type
def_delegator :@key, :public_encrypt, :public_encrypt
def_delegator :@key, :public_decrypt, :public_decrypt
def_delegator :@key, :private_encrypt, :private_encrypt
def_delegator :@key, :private_decrypt, :private_decrypt
def_delegator :@key, :params, :params
def_delegator :@key, :to_text, :to_text
def public_key
SshKey.new(@key.public_key)
end
def private_key
SshKey.new(@key.private_key)
end
#
# not sure if this will always work, but is seems to for now.
#
def bits
Net::SSH::Buffer.from(:key, @key).to_s.split("\001\000").last.size * 8
end
def summary
"%s %s %s (%s)" % [self.type, self.bits, self.fingerprint, self.filename || self.comment || '']
end
def to_s
self.type + " " + self.key
end
def key
[Net::SSH::Buffer.from(:key, @key).to_s].pack("m*").gsub(/\s/, "")
end
def ==(other_key)
return false if other_key.nil?
return false if self.class != other_key.class
return self.to_text == other_key.to_text
end
def in_known_hosts?(*identifiers)
identifiers.each do |identifier|
Net::SSH::KnownHosts.search_for(identifier).each do |key|
return true if self == key
end
end
return false
end
end
end
|