-
Notifications
You must be signed in to change notification settings - Fork 9
/
key_check.rb
57 lines (47 loc) · 1.8 KB
/
key_check.rb
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
require 'chef/knife'
module Kallistec
class KeyCheck < Chef::Knife
deps do
require 'openssl'
end
banner 'knife key check CLIENT PATH_TO_private_key_file'
def run
unless @client_name = name_args[0] and @private_key_file = name_args[1]
show_usage
exit 1
end
@private_key_file = File.expand_path(@private_key_file)
unless File.exist?(@private_key_file)
ui.error "No such file for private key: #{@private_key_file}"
exit 1
end
@auth_creds = Chef::REST::AuthCredentials.new(@client_name, @private_key_file)
@private_key = @auth_creds.key
#extract the public key from the private key:
@public_key_from_local = @private_key.public_key
@public_key_from_server = fetch_public_from_server
if @public_key_from_local.to_s == @public_key_from_server.to_s
ui.msg "Match."
ui.msg "#{@private_key_file} is a valid key for client #{@client_name}"
else
ui.error "Mismatch:"
ui.error "#{@private_key_file} is not a valid key for client #{@client_name}"
ui.msg "Public key extracted from private key:\n#{@public_key_from_local}"
ui.msg "Public key from server:\n#{@public_key_from_server}"
exit 1
end
end
def fetch_public_from_server
api_client = Chef::REST.new(Chef::Config[:chef_server_url])
client_info = api_client.get_rest("clients/#{@client_name}")
if client_info.has_key?("certificate")
OpenSSL::X509::Certificate.new(client_info["certificate"]).public_key
elsif client_info.has_key?("public_key")
OpenSSL::PKey::RSA.new(client_info["public_key"])
else
ui.error "The server did not return a cert or public key for this client, cannot verify key."
exit 1
end
end
end
end