Skip to content
This repository has been archived by the owner on Aug 29, 2018. It is now read-only.

[origin_ui_112] Kerberos principal support #481

Merged
merged 2 commits into from Oct 24, 2013
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
43 changes: 29 additions & 14 deletions lib/rhc/commands/sshkey.rb
Expand Up @@ -43,25 +43,40 @@ def show(name)
summary 'Add SSH key to your account'
syntax '<name> <path to SSH key file>'
argument :name, 'Name for this key', []
argument :key, 'SSH public key filepath', []
argument :key, 'SSH public key filepath', [], :optional => true
option ['--confirm'], 'Bypass key validation'
def add(name, key)
type, content, comment = ssh_key_triple_for(key)

# validate the user input before sending it to the server
begin
Net::SSH::KeyFactory.load_data_public_key "#{type} #{content}"
rescue NotImplementedError, OpenSSL::PKey::PKeyError, Net::SSH::Exception => e
debug e.inspect
if options.confirm
warn 'The key you are uploading is not recognized. You may not be able to authenticate to your application through Git or SSH.'
else
raise ::RHC::KeyDataInvalidException.new("File '#{key}' does not appear to be a recognizable key file (#{e}). You may specify the '--confirm' flag to add the key anyway.")
option ['--type TYPE'], 'Provide the key type directly if no key file is given'
option ['--content CONTENT'], 'Provide the key content directly if no key file is given'
def add(name, key_path=nil)

if key_path
type, content, comment = ssh_key_triple_for(key_path)
elsif options[:type].present? and options[:content].present?
type = options[:type]
content = options[:content]
else
raise ArgumentError, "You must either provide a key file, or the key type and content"
end

if type == 'krb5-principal'
# TODO: validate krb5?
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Hrm... this seems smelly. Not sure what else you can do, but it's a bit wierd.

else
# validate the user input before sending it to the server
begin
Net::SSH::KeyFactory.load_data_public_key "#{type} #{content}"
rescue NotImplementedError, OpenSSL::PKey::PKeyError, Net::SSH::Exception => e
debug e.inspect
if options.confirm
warn 'The key you are uploading is not recognized. You may not be able to authenticate to your application through Git or SSH.'
else
raise ::RHC::KeyDataInvalidException.new("File '#{key_path}' does not appear to be a recognizable key file (#{e}). You may specify the '--confirm' flag to add the key anyway.") if key_path
raise ::RHC::KeyDataInvalidException.new("The provided type and content does not appear to be a recognizable key (#{e}). You may specify the '--confirm' flag to add the key anyway.")
end
end
end

rest_client.add_key(name, content, type)
results { say "SSH key #{key} has been added as '#{name}'" }
results { say key_path ? "SSH key #{key_path} has been added as '#{name}'" : "SSH key '#{name}' has been added" }

0
end
Expand Down
2 changes: 1 addition & 1 deletion lib/rhc/output_helpers.rb
Expand Up @@ -97,7 +97,7 @@ def display_cart(cart, *properties)
end

def display_key(key, *properties)
properties = [:fingerprint, :visible_to_ssh?] if properties.empty?
properties = [:fingerprint, :principal, :visible_to_ssh?] if properties.empty?
say format_table(
properties.include?(:name) ? nil : format_key_header(key),
get_properties(key, *properties),
Expand Down
16 changes: 14 additions & 2 deletions lib/rhc/rest/key.rb
Expand Up @@ -3,6 +3,14 @@ module Rest
class Key < Base
define_attr :name, :type, :content

def is_ssh?
type != 'krb5-principal'
end

def is_kerberos?
type == 'krb5-principal'
end

def update(type, content)
debug "Updating key #{self.name}"
rest_method "UPDATE", :type => type, :content => content
Expand All @@ -14,17 +22,21 @@ def destroy
end
alias :delete :destroy

def principal
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Feels smelly but not sure what you can do. I think part of the problem is that the client code assumes that SSH keys can be passed to Openssl and just work - maybe we should relax that a bit. Hard to say.

content if is_kerberos?
end

def fingerprint
@fingerprint ||= begin
public_key = Net::SSH::KeyFactory.load_data_public_key("#{type} #{content}")
public_key.fingerprint
rescue NotImplementedError, OpenSSL::PKey::PKeyError => e
'Invalid key'
end
end if is_ssh?
end

def visible_to_ssh?
Net::SSH::Authentication::Agent.connect.identities.
is_ssh? and Net::SSH::Authentication::Agent.connect.identities.
find{ |i| fingerprint == i.fingerprint }.present? rescue false
end
end
Expand Down
3 changes: 2 additions & 1 deletion lib/rhc/rest/mock.rb
Expand Up @@ -616,7 +616,8 @@ def initialize(client, login)
@login = login
@keys = [
MockRestKey.new(client, 'mockkey1', 'ssh-rsa', 'AAAAB3NzaC1yc2EAAAADAQABAAABAQDNK8xT3O+kSltmCMsSqBfAgheB3YFJ9Y0ESJnFjFASVxH70AcCQAgdQSD/r31+atYShJdP7f0AMWiQUTw2tK434XSylnZWEyIR0V+j+cyOPdVQlns6D5gPOnOtweFF0o18YulwCOK8Q1H28GK8qyWhLe0FcMmxtKbbQgaVRvQdXZz4ThzutCJOyJm9xVb93+fatvwZW76oLLvfFJcJSOK2sgW7tJM2A83bm4mwixFDF7wO/+C9WA+PgPKJUIjvy1gZjBhRB+3b58vLOnYhPOgMNruJwzB+wJ3pg8tLJEjxSbHyyoi6OqMBs4BVV7LdzvwTDxEjcgtHVvaVNXgO5iRX'),
MockRestKey.new(client, 'mockkey2', 'ssh-dsa', 'AAAAB3NzaC1kc3MAAACBAPaaFj6Xjrjd8Dc4AAkJe0HigqaXMxj/87xHoV+nPgerHIceJWhPUWdW40lSASrgpAV9Eq4zzD+L19kgYdbMw0vSX5Cj3XtNOsow9MmMxFsYjTxCv4eSs/rLdGPaYZ5GVRPDu8tN42Bm8lj5o+ky3HzwW+mkQMZwcADQIgqtn6QhAAAAFQCirDfIMf/JoMOFf8CTnsTKWw/0zwAAAIAIQp6t2sLIp1d2TBfd/qLjOJA10rPADcnhBzWB/cd/oFJ8a/2nmxeSPR5Ov18T6itWqbKwvZw2UC0MrXoYbgcfVNP/ym1bCd9rB5hu1sg8WO4JIxA/47PZooT6PwTKVxHuENEzQyJL2o6ZJq+wuV0taLvm6IaM5TAZuEJ2p4TC/gAAAIBpLcVXZREa7XLY55nyidt/+UC+PxpjhPHOHbzL1OvWEaumN4wcJk/JZPppgXX9+WDkTm1SD891U0cXnGMTP0OZOHkOUHF2ZcfUe7p9kX4WjHs0OccoxV0Lny6MC4DjalJyaaEbijJHSUX3QlLcBOlPHJWpEpvWQ9P8AN4PokiGzA==')
MockRestKey.new(client, 'mockkey2', 'ssh-dsa', 'AAAAB3NzaC1kc3MAAACBAPaaFj6Xjrjd8Dc4AAkJe0HigqaXMxj/87xHoV+nPgerHIceJWhPUWdW40lSASrgpAV9Eq4zzD+L19kgYdbMw0vSX5Cj3XtNOsow9MmMxFsYjTxCv4eSs/rLdGPaYZ5GVRPDu8tN42Bm8lj5o+ky3HzwW+mkQMZwcADQIgqtn6QhAAAAFQCirDfIMf/JoMOFf8CTnsTKWw/0zwAAAIAIQp6t2sLIp1d2TBfd/qLjOJA10rPADcnhBzWB/cd/oFJ8a/2nmxeSPR5Ov18T6itWqbKwvZw2UC0MrXoYbgcfVNP/ym1bCd9rB5hu1sg8WO4JIxA/47PZooT6PwTKVxHuENEzQyJL2o6ZJq+wuV0taLvm6IaM5TAZuEJ2p4TC/gAAAIBpLcVXZREa7XLY55nyidt/+UC+PxpjhPHOHbzL1OvWEaumN4wcJk/JZPppgXX9+WDkTm1SD891U0cXnGMTP0OZOHkOUHF2ZcfUe7p9kX4WjHs0OccoxV0Lny6MC4DjalJyaaEbijJHSUX3QlLcBOlPHJWpEpvWQ9P8AN4PokiGzA=='),
MockRestKey.new(client, 'mockkey3', 'krb5-principal', 'mockuser@mockdomain')
]
end

Expand Down
37 changes: 37 additions & 0 deletions spec/rhc/commands/sshkey_spec.rb
Expand Up @@ -14,7 +14,13 @@
let(:arguments) { %w[sshkey list --noprompt --config test.conf -l test@test.foo -p password --trace] }

it { expect { run }.to exit_with_code(0) }

it { run_output.should match(/mockkey1 \(type: ssh-rsa\)/) }
it { run_output.should match(/Fingerprint:.*0f:ce:86:80:df:a0:81:ca:db:f1:a7:0c:70:85:ce:00/) }

it { run_output.should match(/mockkey3 \(type: krb5-principal\)/) }
it { run_output.should match(/Principal:.* mockuser@mockdomain/) }
it { run_output.should_not match(/Fingerprint:.*Invalid key/) }
end
end

Expand Down Expand Up @@ -44,6 +50,17 @@
end
end

context "when adding a valid key via command line arguments" do
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar --type ssh-rsa --content AAAAB3NzaC1yc2EAAAADAQABAAABAQCnCOqK7/mmvZ9AtCAerxjAasJ1rSpfuWT4vNm1+O/Fh0Di3chTWjY9a0M2hEnqkqnVG589L9CqCUeT0kdc3Vgw3JEcacSUr1z7tLr9kO+p/D5lSdQYzDGGRFOZ0H6lc/y8iNxWV1VO/sJvKx6cr5zvKIn8Q6GvhVNOxlai0IOb9FJxLGK95GLpZ+elzh8Tc9giy7KfwheAwhV2JoF9uRltE5JP/CNs7w/E29i1Z+jlueuu8RVotLmhSVNJm91Ey7OCtoI1iBE0Wv/SucFe32Qi08RWTM/MaGGz93KQNOVRGjNkosJjPmP1qU6WGBfliDkJAZXB0b6sEcnx1fbVikwZ] }

it 'adds the key' do
keys = rest_client.sshkeys
num_keys = keys.length
expect { run }.to exit_with_code(0)
rest_client.sshkeys.length.should == num_keys + 1
end
end

context "when adding an invalid key" do
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }

Expand Down Expand Up @@ -79,6 +96,18 @@
end
end

context "when adding an invalid key via command line arguments" do
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar --type ssh-rsa --content abcdef] }

it "fails to add the key" do
keys = rest_client.sshkeys
num_keys = keys.length
expect { run }.to exit_with_code(128)
expect { run_output.should match(/Name:.* mockkey/) }
rest_client.sshkeys.length.should == num_keys
end
end

context "when adding an invalid key with --confirm" do
let(:arguments) { %w[sshkey add --noprompt --confirm --config test.conf -l test@test.foo -p password foobar id_rsa.pub] }

Expand Down Expand Up @@ -123,6 +152,14 @@
end

end

context "when adding a key without correct arguments" do
let(:arguments) { %w[sshkey add --noprompt --config test.conf -l test@test.foo -p password foobar] }

it "exits with argument error" do
expect { run }.to exit_with_code(1)
end
end
end

describe "remove" do
Expand Down