From c6d2272ddb370b9731e17b06fa08971e6cda5202 Mon Sep 17 00:00:00 2001 From: elijah Date: Sun, 14 Oct 2012 03:02:06 -0700 Subject: added add-user command --- lib/leap_cli/commands/compile.rb | 2 +- lib/leap_cli/commands/init.rb | 2 +- lib/leap_cli/commands/pre.rb | 4 +- lib/leap_cli/commands/user.rb | 106 +++++++++++++++++++++++++++++++++ lib/leap_cli/commands/util.rb | 125 +++++++++++++++++++++++++++++++++++++++ 5 files changed, 235 insertions(+), 4 deletions(-) create mode 100644 lib/leap_cli/commands/user.rb create mode 100644 lib/leap_cli/commands/util.rb (limited to 'lib/leap_cli/commands') diff --git a/lib/leap_cli/commands/compile.rb b/lib/leap_cli/commands/compile.rb index 8764e52..3e9d42d 100644 --- a/lib/leap_cli/commands/compile.rb +++ b/lib/leap_cli/commands/compile.rb @@ -5,7 +5,7 @@ module LeapCli command :compile do |c| c.action do |global_options,options,args| manager.load(Path.provider) - Path.ensure_dir(Path.hiera) + ensure_dir(Path.hiera) manager.export(Path.hiera) end end diff --git a/lib/leap_cli/commands/init.rb b/lib/leap_cli/commands/init.rb index 75cc876..de43a45 100644 --- a/lib/leap_cli/commands/init.rb +++ b/lib/leap_cli/commands/init.rb @@ -7,7 +7,7 @@ module LeapCli c.action do |global_options,options,args| directory = args.first unless directory && directory.any? - help_now! "Directory name is required." + help! "Directory name is required." end directory = File.expand_path(directory) if File.exists?(directory) diff --git a/lib/leap_cli/commands/pre.rb b/lib/leap_cli/commands/pre.rb index 2281bf6..ada6a6a 100644 --- a/lib/leap_cli/commands/pre.rb +++ b/lib/leap_cli/commands/pre.rb @@ -7,7 +7,7 @@ module LeapCli desc 'Verbosity level 0..2' arg_name 'level' - default_value '0' + default_value '1' flag [:v, :verbose] desc 'Specify the root directory' @@ -30,7 +30,7 @@ module LeapCli if Path.ok? true else - fail!("Could not find the root directory. Change current working directory or try --root") + bail!("Could not find the root directory. Change current working directory or try --root") end end diff --git a/lib/leap_cli/commands/user.rb b/lib/leap_cli/commands/user.rb new file mode 100644 index 0000000..af59074 --- /dev/null +++ b/lib/leap_cli/commands/user.rb @@ -0,0 +1,106 @@ +require 'gpgme' + +# +# notes: +# +# file ~/.gnupg/00440025.asc +# /home/elijah/.gnupg/00440025.asc: PGP public key block +# +# file ~/.ssh/id_rsa.pub +# /home/elijah/.ssh/id_rsa.pub: OpenSSH RSA public key +# + +module LeapCli + module Commands + + desc 'adds a new trusted sysadmin' + arg_name '', :optional => false, :multiple => false + command :'add-user' do |c| + + c.switch 'self', :desc => 'lets you choose among your public keys', :negatable => false + c.flag 'ssh-pub-key', :desc => 'SSH public key file for this new user' + c.flag 'pgp-pub-key', :desc => 'OpenPGP public key file for this new user' + + c.action do |global_options,options,args| + username = args.first + if !username.any? && !options[:self] + help! "Either 'username' or --self is required." + end + + ssh_pub_key = nil + pgp_pub_key = nil + + if options['ssh-pub-key'] + ssh_pub_key = read_file!(options['ssh-pub-key']) + end + if options['pgp-pub-key'] + pgp_pub_key = read_file!(options['pgp-pub-key']) + end + + if options[:self] + username ||= `whoami`.strip + ssh_pub_key ||= pick_ssh_key + pgp_pub_key ||= pick_pgp_key + end + + assert!(ssh_pub_key, 'Sorry, could not find SSH public key.') + assert!(pgp_pub_key, 'Sorry, could not find OpenPGP public key.') + + if ssh_pub_key + write_file!(:user_ssh, username, ssh_pub_key) + end + if pgp_pub_key + write_file!(:user_pgp, username, pgp_pub_key) + end + end + end + + # + # let the the user choose among the ssh public keys that we encounter, or just pick the key if there is only one. + # + def pick_ssh_key + assert_bin! 'ssh-add' + ssh_fingerprints = `ssh-add -l`.split("\n").compact + assert! ssh_fingerprints.any?, 'Sorry, could not find any SSH public key for you. Have you run ssh-keygen?' + + if ssh_fingerprints.length > 1 + key_index = numbered_choice_menu('Choose your SSH public key', ssh_fingerprints) do |key, i| + say("#{i+1}. #{key}") + end + else + key_index = 0 + end + + ssh_keys = `ssh-add -L`.split("\n").compact + return ssh_keys[key_index] + end + + # + # let the the user choose among the gpg public keys that we encounter, or just pick the key if there is only one. + # + def pick_pgp_key + secret_keys = GPGME::Key.find(:secret) + + assert_bin! 'gpg' + assert! secret_keys.any?, 'Sorry, could not find any OpenPGP keys for you.' + + if secret_keys.length > 1 + key_index = numbered_choice_menu('Choose your OpenPGP public key', secret_keys) do |key, i| + key_info = key.to_s.split("\n")[0..1].map{|line| line.sub(/^\s*(sec|uid)\s*/,'')}.join(' -- ') + say("#{i+1}. #{key_info}") + end + else + key_index = 0 + end + + key_id = secret_keys[key_index].sha + + # can't use this, it includes signatures: + #puts GPGME::Key.export(key_id, :armor => true, :export_options => :export_minimal) + + # export with signatures removed: + return `gpg --armor --export-options export-minimal --export #{key_id}`.strip + end + + end +end \ No newline at end of file diff --git a/lib/leap_cli/commands/util.rb b/lib/leap_cli/commands/util.rb new file mode 100644 index 0000000..ad4f01c --- /dev/null +++ b/lib/leap_cli/commands/util.rb @@ -0,0 +1,125 @@ +module LeapCli + module Commands + extend self + extend LeapCli::Util +# # +# # keeps prompting the user for a numbered choice, until they pick a good one or bail out. +# # +# # block is yielded and is responsible for rendering the choices. +# # + def numbered_choice_menu(msg, items, &block) + while true + say("\n" + msg + ':') + items.each_with_index &block + say("q. quit") + index = ask("number 1-#{items.length}> ") + if index.empty? + next + elsif index =~ /q/ + bail! + else + i = index.to_i - 1 + if i < 0 || i >= items.length + bail! + else + return i + end + end + end + end + +# # +# # read a file, exit if the file doesn't exist. +# # +# def read_file!(file_path) +# if !File.exists?(file_path) +# bail!("File '%s' does not exist." % file_path) +# else +# File.readfile(file_path) +# end +# end + +# ## +# ## LOGGING +# ## + +# def log0(message=nil, &block) +# if message +# puts message +# elsif block +# puts yield(block) +# end +# end + +# def log1(message=nil, &block) +# if LeapCli.log_level > 0 +# if message +# puts message +# elsif block +# puts yield(block) +# end +# end +# end + +# def log2(message=nil, &block) +# if LeapCli.log_level > 1 +# if message +# puts message +# elsif block +# puts yield(block) +# end +# end +# end + +# def progress(message) +# log1(" * " + message) +# end + +# ## +# ## QUITTING +# ## + +# # +# # quit and print help +# # +# def help!(message=nil) +# ENV['GLI_DEBUG'] = "false" +# help_now!(message) +# #say("ERROR: " + message) +# end + +# # +# # quit with a message that we are bailing out. +# # +# def bail!(message="") +# say(message) +# say("Bailing out.") +# raise SystemExit.new +# #ENV['GLI_DEBUG'] = "false" +# #exit_now!(message) +# end + +# # +# # quit with no message +# # +# def quit!(message='') +# say(message) +# raise SystemExit.new +# end + +# # +# # bails out with message if assertion is false. +# # +# def assert!(boolean, message) +# bail!(message) unless boolean +# end + +# # +# # assert that the command is available +# # +# def assert_bin!(cmd_name) +# assert! `which #{cmd_name}`.strip.any?, "Sorry, bailing out, the command '%s' is not installed." % cmd_name +# end + + end +end -- cgit v1.2.3