#!/usr/bin/ruby # Rye -- A CLI for some handy SSH tools # # If your reading this via the rdocs you won't be able to see the code # See: http://github.com/delano/rye/blob/master/bin/rye # # Usage: rye # $:.unshift File.join(File.dirname(__FILE__), '..', 'lib') require 'rubygems' require 'stringio' require 'yaml' require 'drydock' require 'rye' include Drydock global :p, :path, String, "A directory containing SSH private keys or the path to a private key" before do |obj| # Load private keys if specified if obj.global.path keys = Rye.find_private_keys(obj.global.path) Rye.add_keys(keys) end end after do end desc "Add your public keys to one or more remote machines" option :u, :user, String, "Username" argv :hostname command :authorize do |obj| raise "You must specify a host" unless obj.argv.hostname opts = { :debug => nil, :auth_methods => %w(publickey hostbased) } opts[:user] = obj.option.user if obj.option.user obj.argv.each do |hostname| puts "Authorizing #{rbox.opts[:user]}@#{hostname}" rbox = Rye::Box.new(hostname, opts).connect puts "Added public keys for: ", rbox.authorize_keys puts "Now try: " << "ssh #{rbox.opts[:user]}@#{hostname}" end end command_alias :authorize, :authorise desc "Add your public keys to your current account on this machine" command :authorize_local do |obj| user = Rye.sysinfo.user puts "Authorizing #{user}@localhost" rbox = Rye::Box.new('localhost').connect puts "Added public keys for: ", rbox.authorize_keys_local puts "Now try: " << "ssh #{user}@localhost" end command_alias :local_authorize, :local_authorise desc "Generate a public key from a private key" desc "Fetch the host keys for remote machines (suitable for your ~/.ssh/known_hosts file)" usage "rye hostkey HOSTNAME [HOSTNAME2 HOSTNAME3 ...]" argv :hostname command :hostkeys do |obj| raise "You must specify a host" unless obj.argv.hostname ret = Rye.remote_host_keys(obj.argv.hostname) STDERR.puts $/, ret.stderr, $/ puts ret.stdout end command_alias :hostkeys, :hostkey desc "Display your private keys" command :keys do |obj| Rye.keys.each do |key| puts key.join(' ') end end desc "Display your public SSH keys" usage "rye pubkeys [--pem] [KEYPATH]" option :p, :pem, "Output in PEM format" argv :keypath command :pubkeys do |obj| keys = obj.argv.empty? ? Rye.keys.collect { |k| k[2] } : obj.argv keys.each do |path| STDERR.puts "# Public SSH key for #{path}" k = Rye::Key.from_file(path) puts obj.option.pem ? k.public_key.to_pem : k.public_key.to_ssh2 end end command_alias :pubkeys, :pubkey default :keys debug :off # We call Drydock specifically otherwise it will run at_exit. Rye also # uses at_exit for shutting down the ssh-agent. Ruby executes at_exit # blocks in reverse order so if Drydock is required first, it's block # will run after Rye shuts down the ssh-agent. begin Drydock.run!(ARGV, STDIN) if Drydock.run? && !Drydock.has_run? rescue => ex STDERR.puts "ERROR (#{ex.class.to_s}): #{ex.message}" STDERR.puts ex.backtrace if Drydock.debug? end