namespace :ssh do
desc "Install your public key on a remote server."
task :install_public_key do
begin
require 'rubygems'
require 'net/ssh'
require 'net/scp'
require 'highline'
rescue LoadError
abort "There was a problem loading net-ssh, net-scp, or highline. Please make sure you have them installed via RubyGems."
end
unless discovered_key = %w[id_rsa id_dsa identity].detect { |f| File.exists?("#{ENV['HOME']}/.ssh/#{f}.pub") }
abort <<-EOS
I wasn't able to discover your public key. I tried to find id_rsa.pub, id_dsa.pub,
or identity.pub in "#{ENV['HOME']}/.ssh". You can hard code the path to the file by
passing public_key_path via the command line.
EOS
end
h = HighLine.new
not_blank = Proc.new { |s| !s.empty? }
def not_blank.to_s; "not blank"; end
h.say "I need some information to SSH into the server."
hostname = h.ask("Remote Hostname: ") { |q| q.validate = not_blank }
username = h.ask("Username, enter for default: ") { |q| q.default = ENV["USER"] }
password = h.ask("Password: ") { |q| q.echo = "*" }
public_key_path = "#{ENV['HOME']}/.ssh/#{discovered_key}.pub"
begin
Net::SSH.start(hostname, username, :password => password) do |ssh|
puts "Uploading your public key... "
ssh.scp.upload! public_key_path, "my_public_key"
puts "Creating '.ssh' directory in your home directory"
ssh.exec!("mkdir .ssh")
puts "Concatenating your public key into the authorized_keys file"
ssh.exec!("cat my_public_key >> .ssh/authorized_keys")
puts "Removing your public key"
ssh.exec!("rm my_public_key")
puts "Setting permissions on .ssh"
ssh.exec!("chmod 700 .ssh")
puts "Setting permissions on your authorized_keys file"
ssh.exec!("chmod 600 .ssh/authorized_keys")
puts "\nAll done! Enjoy your new, potentially password-free login."
end
rescue Net::SSH::AuthenticationFailed
puts "\nWhat we've got here... is a failure to communicate. There was a problem authenticating you."
end
end
end