#!/usr/bin/ruby

# password store management tool

# Copyright (c) 2008, 2009, 2011, 2013 Peter Palfrader <peter@palfrader.org>
# Copyright (c) 2014 Fastly
#
# Permission is hereby granted, free of charge, to any person obtaining
# a copy of this software and associated documentation files (the
# "Software"), to deal in the Software without restriction, including
# without limitation the rights to use, copy, modify, merge, publish,
# distribute, sublicense, and/or sell copies of the Software, and to
# permit persons to whom the Software is furnished to do so, subject to
# the following conditions:
#
# The above copyright notice and this permission notice shall be
# included in all copies or substantial portions of the Software.
#
# THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
# EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
# MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
# NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
# LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
# OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
# WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.

require 'optparse'
require 'thread'
require 'tempfile'

require 'yaml'
Thread.abort_on_exception = true

GNUPG = "gpg"
GROUP_PATTERN = "@[a-zA-Z0-9_-]+"
USER_PATTERN = "[a-zA-Z0-9:_-]+"
$program_name = File.basename($0, '.*')
CONFIG_FILE = ENV['HOME']+ "/.pws.yaml"

$editor = ENV['EDITOR']
if $editor == nil
  %w{/usr/bin/sensible-editor /usr/bin/editor /usr/bin/vi}.each do |editor|
    if FileTest.executable?(editor)
      $editor = editor
      break
    end
  end
end
if $editor == nil
  STDERR.puts "Cannot find an editor"
  exit(1)
end

class GnuPG
  @@my_keys = nil
  @@my_fprs = nil
  @@keyid_fpr_mapping = {}
  @@extra_args = []

  def GnuPG.extra_args=(val)
    @@extra_args = val
  end

  def GnuPG.readwrite3(intxt, infd, stdoutfd, stderrfd, statusfd=nil)
    outtxt, stderrtxt, statustxt = ''
    thread_in = Thread.new {
      infd.print intxt
      infd.close
    }
    thread_out = Thread.new {
      outtxt = stdoutfd.read
      stdoutfd.close
    }
    thread_err = Thread.new {
      errtxt = stderrfd.read
      stderrfd.close
    }
    thread_status = Thread.new {
      statustxt = statusfd.read
      statusfd.close
    } if (statusfd)

    thread_in.join
    thread_out.join
    thread_err.join
    thread_status.join if thread_status

    return outtxt, stderrtxt, statustxt
  end

  def GnuPG.open3call(cmd, intxt, args, require_success = false, do_status=true)
    inR, inW = IO.pipe
    outR, outW = IO.pipe
    errR, errW = IO.pipe
    statR, statW = IO.pipe if do_status

    pid = Kernel.fork do
      inW.close
      outR.close
      errR.close
      statR.close if do_status
      STDIN.reopen(inR)
      STDOUT.reopen(outW)
      STDERR.reopen(errW)
      fds = {
        STDIN=>inR,
        STDOUT=>outW,
        STDERR=>errW,
      }
      begin
        if do_status
          fds[statW.fileno] = statW
          exec(cmd, "--status-fd=#{statW.fileno}", *(@@extra_args + args), fds)
        else
          exec(cmd, *(@@extra_args + args), fds)
        end
      rescue Exception => e
        outW.puts("[PWSEXECERROR]: #{e}")
        exit(1)
      end
      raise ("Calling gnupg failed")
    end
    inR.close
    outW.close
    errW.close
    if do_status
      statW.close
      (outtxt, stderrtxt, statustxt) = readwrite3(intxt, inW, outR, errR, statR);
    else
      (outtxt, stderrtxt) = readwrite3(intxt, inW, outR, errR);
    end
    wpid, status = Process.waitpid2 pid
    throw "Unexpected pid: #{pid} vs #{wpid}" unless pid == wpid
    throw "Process has not exited!?" unless status.exited?
    if (require_success and status.exitstatus != 0)
      STDERR.puts "#{cmd} call did not exit sucessfully."
      STDERR.puts "output on stdout:"
      STDERR.puts outtxt
      STDERR.puts "output on stderr:"
      STDERR.puts stderrtxt
      if do_status
        STDERR.puts "output on statusfd:"
        STDERR.puts statustxt
      end
      exit(1)
    end
    if m=/^\[PWSEXECERROR\]: (.*)/.match(outtxt) then
      STDERR.puts "Could not run GnuPG: #{m[1]}"
      exit(1)
    end
    if do_status
      return outtxt, stderrtxt, statustxt, status.exitstatus
    else
      return outtxt, stderrtxt, status.exitstatus
    end
  end

  def GnuPG.gpgcall(intxt, args, require_success = false)
    return open3call(GNUPG, intxt, args, require_success)
  end

  def GnuPG.init_keys()
    return if @@my_keys
    (outtxt, stderrtxt, statustxt) = GnuPG.gpgcall('', %w{--fast-list-mode --with-colons --with-fingerprint --list-secret-keys}, true)
    @@my_keys = []
    @@my_fprs = []
    outtxt.split("\n").each do |line|
      parts = line.split(':')
      if (parts[0] == "ssb" or parts[0] == "sec")
        @@my_keys.push parts[4]
      elsif (parts[0] == "fpr")
        @@my_fprs.push parts[9]
      end
    end
  end
  # This is for my private keys, so we can tell if a file is encrypted to us
  def GnuPG.get_my_keys()
    init_keys
    @@my_keys
  end
  # And this is for my private keys also, so we can tell if we are encrypting to ourselves
  def GnuPG.get_my_fprs()
    init_keys
    @@my_fprs
  end

  # This maps public keyids to fingerprints, so we can figure
  # out if a file that is encrypted to a bunch of keys is
  # encrypted to the fingerprints it should be encrypted to
  def GnuPG.get_fpr_from_keyid(keyid)
    fpr = @@keyid_fpr_mapping[keyid]
    # this can be null, if we tried to find the fpr but failed to find the key in our keyring
    unless fpr
      STDERR.puts "Warning: No key found for keyid #{keyid}"
    end
    return fpr
  end
  def GnuPG.get_fprs_from_keyids(keyids)
    learn_fingerprints_from_keyids(keyids)
    return keyids.collect{ |k| get_fpr_from_keyid(k) or "unknown" }
  end

  # this is to load the keys we will soon be asking about into
  # our keyid-fpr-mapping hash
  def GnuPG.learn_fingerprints_from_keyids(keyids)
    need_to_learn = keyids.reject{ |k| @@keyid_fpr_mapping.has_key?(k) }
    if need_to_learn.size > 0
      # we can't use --fast-list-mode here because GnuPG is broken
      # and does not show elmo's fingerprint in a call like
      # gpg --with-colons --fast-list-mode --with-fingerprint --list-key D7C3F131AB2A91F5
      args = %w{--with-colons --with-fingerprint --list-keys}
      args.push("--keyring=./.keyring", "--no-default-keyring") if FileTest.exists?(".keyring")
      args.concat need_to_learn
      (outtxt, stderrtxt, statustxt) = GnuPG.gpgcall('', args)

      pub = nil
      fpr = nil
      outtxt.split("\n").each do |line|
        parts = line.split(':')
        if (parts[0] == "pub")
          pub = parts[4]
          fpr = nil
        elsif (parts[0] == "fpr") and fpr.nil?
          fpr = parts[9]
          @@keyid_fpr_mapping[pub] = fpr
        elsif (parts[0] == "sub")
          @@keyid_fpr_mapping[parts[4]] = fpr
        end
      end
    end
    need_to_learn.reject{ |k| @@keyid_fpr_mapping.has_key?(k) }.each { |k| @@keyid_fpr_mapping[k] = nil }
  end
end

def read_input(query, default_yes=true)
  if default_yes
    append = '[Y/n]'
  else
    append = '[y/N]'
  end

  while true
    print "#{query} #{append} "
    begin
      i = STDIN.readline.chomp.downcase
    rescue EOFError
      return default_yes
    end
    if i==""
      return default_yes
    elsif i=="y"
      return true
    elsif i=="n"
      return false
    end
  end
end

class GroupConfig
  attr_reader :dirname

  def initialize(dirname=".", trusted_users=nil)
    @dirname = dirname
    if trusted_users
      @trusted_users_source = trusted_users
      load_deprecated_trusted_users()
    elsif FileTest.exists?(CONFIG_FILE)
      t = {}
      begin
        yaml = YAML::load_file(CONFIG_FILE)
        yaml["trusted_users"].each do |k,v|
            t[File.expand_path(k)] = v
        end
        @trusted_users_source = CONFIG_FILE
        d = File.expand_path(dirname)
        while d != "/"
          if t.include?(d)
            @trusted_users = t[d]
            @dirname = d
            break
          end
          d = File.split(d)[0]
        end
        if @trusted_users.nil? or d == "/"
          raise ("Could not find #{File.expand_path(dirname)} or its parents in configuration file #{CONFIG_FILE}")
        end
      rescue Psych::SyntaxError, ArgumentError => e
        raise("Could not parse YAML: #{e.message}")
      end
    else
      @trusted_users_source = ENV['HOME']+'/.pws-trusted-users'
      load_deprecated_trusted_users()
    end
    parse_file
    expand_groups
  end

  def load_deprecated_trusted_users()
    begin
      f = File.open(@trusted_users_source)
    rescue Exception => e
      raise e
    end

    trusted = []
    f.readlines.each do |line|
      line.chomp!
      next if line =~ /^$/
      next if line =~ /^#/

      trusted.push line
    end
    @trusted_users = trusted
  end

  def verify(content)
    args = []
    args.push "--keyring=#{@dirname}/.keyring" if FileTest.exists?(File.join(@dirname, ".keyring"))
    (outtxt, stderrtxt, statustxt, exitstatus) = GnuPG.gpgcall(content, args)
    goodsig = false
    validsig = nil
    statustxt.split("\n").each do |line|
      if m = /^\[GNUPG:\] GOODSIG/.match(line)
        goodsig = true
      elsif m = /^\[GNUPG:\] VALIDSIG \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ \S+ ([0-9A-F]+)/.match(line)
        validsig = m[1]
      end
    end

    if not goodsig
      STDERR.puts ".users file is not signed properly.  GnuPG said on stdout:"
      STDERR.puts outtxt
      STDERR.puts "and on stderr:"
      STDERR.puts stderrtxt
      STDERR.puts "and via statusfd:"
      STDERR.puts statustxt
      raise "Not goodsig"
    end

    if not @trusted_users.include?(validsig)
      raise ".users file is signed by #{validsig} which is not in #{@trusted_users_source}"
    end

    if not exitstatus==0
      raise "gpg verify failed for .users file"
    end

    return outtxt
  end

  def parse_file
    begin
      f = File.open(File.join(@dirname, '.users'))
    rescue Exception => e
      raise e
    end

    users = f.read
    f.close

    users = verify(users)

    @users = {}
    @groups = {}

    lno = 0
    users.split("\n").each do |line|
      lno = lno+1
      next if line =~ /^$/
      next if line =~ /^#/
      if (m = /^(#{USER_PATTERN})\s*=\s*([0-9A-Fa-f]{40})\s*$/.match line)
        user = m[1]
        fpr = m[2]
        if @users.has_key?(user)
          STDERR.puts "User #{user} redefined at line #{lno}!"
          exit(1)
        end
        @users[user] = fpr
      elsif (m = /^(#{GROUP_PATTERN})\s*=\s*(.*)$/.match line)
        group = m[1]
        members = m[2].strip
        if @groups.has_key?(group)
          STDERR.puts "Group #{group} redefined at line #{lno}!"
          exit(1)
        end
        members = members.split(/[\t ,]+/)
        @groups[group] = { "members" => members }
      end
    end
  end

  def is_group(name)
    return (name =~ /^@/)
  end
  def check_exists(x, whence, fatal=true)
    ok=true
    if is_group(x)
      ok=false unless (@groups.has_key?(x))
    else
      ok=false unless @users.has_key?(x)
    end
    unless ok
      STDERR.puts( (fatal ? "Error: " : "Warning: ") + "#{whence} contains unknown member #{x}")
      exit(1) if fatal
    end
    return ok
  end
  def expand_groups
    @groups.each_pair do |groupname, group|
      group['members'].each do |member|
        check_exists(member, "Group #{groupname}")
      end
      group['members_to_do'] = group['members'].clone
    end

    while true
      had_progress = false
      all_expanded = true
      @groups.each_pair do |groupname, group|
        group['keys'] = [] unless group['keys']

        still_contains_groups = false
        group['members_to_do'].clone.each do |member|
          if is_group(member)
            if @groups[member]['members_to_do'].size == 0
              group['keys'].concat @groups[member]['keys']
              group['members_to_do'].delete(member)
              had_progress = true
            else
              still_contains_groups = true
            end
          else
            group['keys'].push @users[member]
            group['members_to_do'].delete(member)
            had_progress = true
          end
        end
        all_expanded = false if still_contains_groups
      end
      break if all_expanded
      unless had_progress
        cyclic_groups = @groups.keys.reject{|name| @groups[name]['members_to_do'].size == 0}.join(", ")
        STDERR.puts "Cyclic group memberships in #{cyclic_groups}?"
        exit(1)
      end
    end
  end

  def expand_targets(targets)
    fprs = []
    ok = true
    targets.each do |t|
      unless check_exists(t, "access line", false)
        ok = false
        next
      end
      if is_group(t)
        fprs.concat @groups[t]['keys']
      else
        fprs.push @users[t]
      end
    end
    return ok, fprs.uniq
  end

  def get_users()
    return @users
  end
end

class EncryptedData
  attr_reader :accessible, :encrypted, :readable, :readers

  def EncryptedData.determine_readable(readers)
    GnuPG.get_my_keys.each do |keyid|
      return true if readers.include?(keyid)
    end
    return false
  end

  def EncryptedData.list_readers(statustxt)
    readers = []
    statustxt.split("\n").each do |line|
      m = /^\[GNUPG:\] ENC_TO ([0-9A-F]+)/.match line
      next unless m
      readers.push m[1]
    end
    return readers
  end

  def EncryptedData.targets(text)
    text.split("\n").each do |line|
      if /^(#|---)/.match line
        next
      end
      m = /^access: "?((?:(?:#{GROUP_PATTERN}|#{USER_PATTERN}),?\s*)+)"?/.match line
      return [] unless m
      return m[1].strip.split(/[\t ,]+/)
    end
  end


  def initialize(encrypted_content, label, keyring_directory = ".", ignore_decrypt_errors = false)
    @ignore_decrypt_errors = ignore_decrypt_errors
    @label = label
    @keyring_dir = keyring_directory

    @encrypted_content = encrypted_content
    (outtxt, stderrtxt, statustxt) = GnuPG.gpgcall(@encrypted_content, %w{--with-colons --no-options --no-default-keyring --secret-keyring=/dev/null --keyring=/dev/null})
    @encrypted = !(statustxt =~ /\[GNUPG:\] NODATA/)
    if @encrypted
      @readers = EncryptedData.list_readers(statustxt)
      @readable = EncryptedData.determine_readable(@readers)
    end
  end

  def decrypt
    (outtxt, stderrtxt, statustxt, exitstatus) = GnuPG.gpgcall(@encrypted_content, %w{--decrypt})
    if !@ignore_decrypt_errors and exitstatus != 0
      proceed = read_input("Warning: gpg returned non-zero exit status #{exitstatus} when decrypting #{@label}.  Proceed?", false)
      exit(0) unless proceed
    elsif !@ignore_decrypt_errors and outtxt.length == 0
      proceed = read_input("Warning: #{@label} decrypted to an empty file.  Proceed?")
      exit(0) unless proceed
    end

    return outtxt
  end

  def encrypt(content, recipients)
    args = recipients.collect{ |r| "--recipient=#{r}"}
    args.push "--trust-model=always"
    args.push("--keyring=#{@keyring_dir}/.keyring", "--no-default-keyring") if FileTest.exists?("#{@keyring_dir}/.keyring")
    args.push "--armor"
    args.push "--encrypt"
    (outtxt, stderrtxt, statustxt, exitstatus) = GnuPG.gpgcall(content, args)

    invalid = []
    statustxt.split("\n").each do |line|
      m = /^\[GNUPG:\] INV_RECP \S+ ([0-9A-F]+)/.match line
      next unless m
      invalid.push m[1]
    end
    if invalid.size > 0
      again = read_input("Warning: the following recipients are invalid: #{invalid.join(", ")}. Try again (or proceed)?")
      return false if again
    end
    if outtxt.length == 0
      tryagain = read_input("Error: #{@label} encrypted to an empty file.  Edit again (or exit)?")
      return false if tryagain
      exit(0)
    end
    if exitstatus != 0
      proceed = read_input("Warning: gpg returned non-zero exit status #{exitstatus} when encrypting #{@label}. Said:\n#{stderrtxt}\n#{statustxt}\n\nProceed (or try again)?")
      return false unless proceed
    end

    return true, outtxt
  end


  def determine_encryption_targets(content)
    targets = EncryptedData.targets(content)
    if targets.size == 0
      tryagain = read_input("Warning: Did not find targets to encrypt to in header.  Try again (or exit)?", true)
      return false if tryagain
      exit(0)
    end

    ok, expanded = @groupconfig.expand_targets(targets)
    if (expanded.size == 0)
      tryagain = read_input("Errors in access header.  Edit again (or exit)?", true)
      return false if tryagain
      exit(0)
    elsif (not ok)
      tryagain = read_input("Warnings in access header.  Edit again (or continue)?", true)
      return false if tryagain
    end

    to_me = false
    GnuPG.get_my_fprs.each do |fpr|
      if expanded.include?(fpr)
        to_me = true
        break
      end
    end
    unless to_me
      tryagain = read_input("File is not being encrypted to you.  Edit again (or continue)?", true)
      return false if tryagain
    end

    return true, expanded
  end

end

class EncryptedFile < EncryptedData
  def initialize(filename, new=false, trusted_file=nil)
    @groupconfig = GroupConfig.new(dirname=File.dirname(filename), trusted_users=trusted_file)
    @new = new
    if @new
      @readers = []
    end

    @filename = filename
    @accessible = FileTest.readable?(filename)
    @filename = filename

    if @accessible
      encrypted_content = File.read(filename)
    else
      encrypted_content = nil
    end
    super(encrypted_content, filename, @groupconfig.dirname, @new)
  end

  def write_back(content, targets)
    ok, encrypted = encrypt(content, targets)
    return false unless ok

    File.open(@filename,"w").write(encrypted)
    return true
  end
end

class Ls
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} ls [<directory> ...]"
    io.puts parser.summarize
    io.puts "Lists the contents of the given directory/directories, or the current"
    io.puts "directory if none is given.  For each file show whether it is PGP-encrypted"
    io.puts "file, and if yes whether we can read it."
    exit(code)
  end

  def ls_dir(dirname)
    begin
      dir = Dir.open(dirname)
    rescue Exception => e
      STDERR.puts e
      return
    end
    puts "#{dirname}:"
    Dir.chdir(dirname) do
      unless FileTest.exists?(".users")
        STDERR.puts "The .users file does not exists here.  This is not a password store, is it?"
        exit(1)
      end
      dir.sort.each do |filename|
        next if (filename =~ /^\./) and not (@all >= 3)
        stat = File::Stat.new(filename)
        if stat.symlink?
          puts "(sym)      #{filename}" if (@all >= 2)
        elsif stat.directory?
          puts "(dir)      #{filename}" if (@all >= 2)
        elsif !stat.file?
          puts "(other)    #{filename}" if (@all >= 2)
        else
          f = EncryptedFile.new(filename)
          if !f.accessible
            puts "(!perm)    #{filename}"
          elsif !f.encrypted
            puts "(file)     #{filename}" if (@all >= 2)
          elsif f.readable
            puts "(ok)       #{filename}"
          else
            puts "(locked)   #{filename}" if (@all >= 1)
          end
        end
      end
    end
  end

  def initialize()
    @all = 0
    ARGV.options do |opts|
      opts.on_tail("-h", "--help" , "Display this help screen") { help(opts) }
      opts.on_tail("-a", "--all" , "Show all files (use up to 3 times to show even more than all)") { @all = @all+1 }
      opts.parse!
    end

    dirs = ARGV
    dirs.push('.') unless dirs.size > 0
    dirs.each { |dir| ls_dir(dir) }
  end
end

class Ed
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} ed <filename>"
    io.puts parser.summarize
    io.puts "Decrypts the file, spawns an editor, and encrypts it again"
    exit(code)
  end

  def do_edit(content)
    oldsize = content.length

    tempfile = Tempfile.open('pws')
    tempfile.puts content
    tempfile.flush
    system($editor, tempfile.path)
    status = $?
    throw "Process has not exited!?" unless status.exited?
    unless status.exitstatus == 0
      proceed = read_input("Warning: Editor did not exit successfully (exit code #{status.exitstatus}.  Proceed?")
      exit(0) unless proceed
    end

    # some editors do not write new content in place, but instead
    # make a new file and more it in the old file's place.
    begin
      reopened = File.open(tempfile.path, "r+")
    rescue Exception => e
      STDERR.puts e
      exit(1)
    end
    content = reopened.read

    # zero the file, well, both of them.
    newsize = content.length
    clearsize = (newsize > oldsize) ? newsize : oldsize

    [tempfile, reopened].each do |f|
      f.seek(0, IO::SEEK_SET)
      f.print "\0"*clearsize
      f.fsync
    end
    reopened.close
    tempfile.close(true)

    return content
  end

  def edit(filename)
    encrypted_file = EncryptedFile.new(filename, @new)
    if !@new and !encrypted_file.readable && !@force
      STDERR.puts "#{filename} is probably not readable"
      exit(1)
    end

    encrypted_to = GnuPG.get_fprs_from_keyids(encrypted_file.readers).sort

    content = encrypted_file.decrypt
    original_content = content
    while true
      content = do_edit(content)

      if content.length == 0
        proceed = read_input("Warning: Content is now empty.  Proceed?")
        exit(0) unless proceed
      end

      ok, targets = encrypted_file.determine_encryption_targets(content)
      next unless ok

      if (original_content == content && ! @reencrypt_on_change)
        if (targets.sort == encrypted_to)
          exit(0)
        else
          STDERR.puts("Notice: list of keys changed -- re-encryption recommended.  Run #{$program_name} rc #{filename}")
          exit(0)
        end
      end

      success = encrypted_file.write_back(content, targets)
      break if success
    end
  end

  def initialize(reencrypt_on_change=false)
    ARGV.options do |opts|
      opts.on_tail("-h", "--help" , "Display this help screen") { help(opts) }
      opts.on_tail("-n", "--new" , "Edit new file") { |new| @new=new }
      opts.on_tail("-f", "--force" , "Spawn an editor even if the file is probably not readable") { |force| @force=force }
      opts.parse!
    end
    help(ARGV.options, 1, STDERR) if ARGV.length != 1
    filename = ARGV.shift

    if @new
      if FileTest.exists?(filename)
        STDERR.puts "#{filename} does exist"
        exit(1)
      end
    else
      if !FileTest.exists?(filename)
        STDERR.puts "#{filename} does not exist"
        exit(1)
      elsif !FileTest.file?(filename)
        STDERR.puts "#{filename} is not a regular file"
        exit(1)
      elsif !FileTest.readable?(filename)
        STDERR.puts "#{filename} is not accessible (unix perms)"
        exit(1)
      end
    end

    @reencrypt_on_change = reencrypt_on_change

    dirname = File.dirname(filename)
    basename = File.basename(filename)
    Dir.chdir(dirname) {
      edit(basename)
    }
  end
end

class Reencrypt < Ed
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} rc <filename>"
    io.puts parser.summarize
    io.puts "Reencrypts the file"
    exit(code)
  end
  def do_edit(content)
    return content
  end
  def initialize()
    super(true)
  end
end

class Get
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} get <filename> <query>"
    io.puts parser.summarize
    io.puts "Decrypts the file, fetches a key and outputs it to stdout."
    io.puts "The file must be in YAML format."
    io.puts "query is a query, formatted like /host/users/root"
    exit(code)
  end

  def get(filename, what)
    encrypted_file = EncryptedFile.new(filename, @new)
    if !encrypted_file.readable
      STDERR.puts "#{filename} is probably not readable"
      exit(1)
    end

    begin
      yaml = YAML::load(encrypted_file.decrypt)
    rescue Psych::SyntaxError, ArgumentError => e
      STDERR.puts "Could not parse YAML: #{e.message}"
      exit(1)
    end

    require 'pp'

    a = what.split("/")[1..-1]
    hit = yaml
    if a.nil?
      # q = /, so print top level keys
      puts "Keys:"
      hit.keys.each do |k|
        puts "- #{k}"
      end
      return
    end
    a.each do |k|
      hit = hit[k]
    end
    if hit.nil?
      STDERR.puts("No such key or invalid lookup expression")
    elsif hit.respond_to?(:keys)
      puts "Keys:"
      hit.keys.each do |k|
        puts "- #{k}"
      end
    else
        puts hit
    end
  end

  def initialize()
    ARGV.options do |opts|
      opts.on_tail("-h", "--help" , "Display this help screen") { help(opts) }
      opts.parse!
    end
    help(ARGV.options, 1, STDERR) if ARGV.length != 2
    filename = ARGV.shift
    what = ARGV.shift

    if !FileTest.exists?(filename)
      STDERR.puts "#{filename} does not exist"
      exit(1)
    elsif !FileTest.file?(filename)
      STDERR.puts "#{filename} is not a regular file"
      exit(1)
    elsif !FileTest.readable?(filename)
      STDERR.puts "#{filename} is not accessible (unix perms)"
      exit(1)
    end

    dirname = File.dirname(filename)
    basename = File.basename(filename)
    Dir.chdir(dirname) {
      get(basename, what)
    }
  end
end

class KeyringUpdater
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} update-keyring"
    io.puts parser.summarize
    io.puts "Updates the local .keyring file"
    exit(code)
  end

  def initialize()
    ARGV.options do |opts|
      opts.on_tail("-h", "--help" , "Display this help screen") { help(opts) }
      opts.parse!
    end
    help(ARGV.options, 1, STDERR) if ARGV.length > 1

    groupconfig = GroupConfig.new
    users = groupconfig.get_users()

    File.open('.keyring', 'w') do |keyring|
      users.each_pair() do |uid, keyid|
        user_keyfile = File.join('keys', "#{uid}.key")
        if File.file?(user_keyfile)
          keyring.write(File.read(user_keyfile))
        else
          puts "No key file found for user " + uid
        end
      end
    end

  end
end

class GitDiff
  def help(parser, code=0, io=STDOUT)
    io.puts "Usage: #{$program_name} gitdiff <commit> <file>"
    io.puts parser.summarize
    io.puts "Shows a diff between the version of <file> in your directory and the"
    io.puts "version in git at <commit> (or HEAD).  Requires that your tree be git"
    io.puts "managed, obviously."
    exit(code)
  end

  def check_readable(e, label)
    if !e.readable && !@force
      STDERR.puts "#{label} is probably not readable."
      exit(1)
    end
  end

  def get_file_at_commit()
    label = @commit+':'+@filename
    (encrypted_content, stderrtxt, exitcode) = GnuPG.open3call('git', '', ['show', label], require_success=true, do_status=false)
    data = EncryptedData.new(encrypted_content, label)
    check_readable(data, label)
    return data.decrypt
  end

  def get_file_current()
    data = EncryptedFile.new(@filename)
    check_readable(data, @filename)
    return data.decrypt
  end

  def diff()
    old = get_file_at_commit()
    cur = get_file_current()

    t1 = Tempfile.open('pws')
    t1.puts old
    t1.flush

    t2 = Tempfile.open('pws')
    t2.puts cur
    t2.flush

    system("diff", "-u", t1.path, t2.path)

    t1.seek(0, IO::SEEK_SET)
    t1.print "\0"*old.length
    t1.fsync
    t1.close(true)

    t2.seek(0, IO::SEEK_SET)
    t2.print "\0"*cur.length
    t2.fsync
    t2.close(true)
  end

  def initialize()
    ARGV.options do |opts|
      opts.on_tail("-h", "--help" , "Display this help screen") { help(opts) }
      opts.on_tail("-f", "--force" , "Do it even if the file is probably not readable") { |force| @force=force }
      opts.parse!
    end

    if ARGV.length == 1
      @commit = 'HEAD'
      @filename = ARGV.shift
    elsif ARGV.length == 2
      @commit = ARGV.shift
      @filename = ARGV.shift
    else
      help(ARGV.options, 1, STDERR) 
    end

    diff()
  end
end


def help(code=0, io=STDOUT)
  io.puts "Usage: #{$program_name} ed"
  io.puts "       #{$program_name} rc"
  io.puts "       #{$program_name} ls"
  io.puts "       #{$program_name} gitdiff"
  io.puts "       #{$program_name} update-keyring"
  io.puts "       #{$program_name} help"
  io.puts "Call #{$program_name} <command> --help for additional options/parameters"
  exit(code)
end


def parse_command
  case ARGV.shift
    when 'ls' then Ls.new
    when 'ed' then Ed.new
    when 'rc' then Reencrypt.new
    when 'gitdiff' then GitDiff.new
    when 'get' then Get.new
    when 'update-keyring' then KeyringUpdater.new
    when 'help' then
      case ARGV.length
        when 0 then help
        when 1 then
          ARGV.push "--help"
          parse_command
        else help(1, STDERR)
      end
    else
      help(1, STDERR)
  end
end

if __FILE__ == $0
  begin
    parse_command
  rescue RuntimeError => e
    STDERR.puts e.message
    exit(1)
  end
end

# vim:set shiftwidth=2:
# vim:set et:
# vim:set ts=2:
