# password store management tool
-# Copyright (c) 2008, 2009 Peter Palfrader <peter@palfrader.org>
+# 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
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
@@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 = ''
STDERR.reopen(errW)
begin
if do_status
- exec(cmd, "--status-fd=#{statW.fileno}", *args)
+ exec(cmd, "--status-fd=#{statW.fileno}", *@@extra_args, *args)
else
exec(cmd, *args)
end
end
class GroupConfig
- def initialize
+ def initialize(dirname=".", trusted_users=nil)
+ @dirname = dirname
+ if trusted_users
+ @trusted_users = load_trusted_users(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 = t[File.expand_path(dirname)]
+ if @trusted_users.nil?
+ raise ("Could not find #{File.expand_path(dirname)} in configuration file #{CONFIG_FILE}")
+ end
+ rescue Psych::SyntaxError, ArgumentError => e
+ raise("Could not parse YAML: #{e.message}")
+ end
+ else
+ @trusted_users = load_trusted_users(ENV['HOME']+'/.pws-trusted-users')
+ end
parse_file
expand_groups
end
- def verify(content)
+ def load_trusted_users(trusted_users_file)
begin
- f = File.open(ENV['HOME']+'/.pws-trusted-users')
+ f = File.open(trusted_users_file)
rescue Exception => e
- STDERR.puts e
- exit(1)
+ raise e
end
trusted = []
trusted.push line
end
+ trusted
+ end
+
+ def verify(content)
args = []
args.push "--keyring=./.keyring" if FileTest.exists?(".keyring")
STDERR.puts stderrtxt
STDERR.puts "and via statusfd:"
STDERR.puts statustxt
- exit(1)
+ raise "Not goodsig"
end
- if not trusted.include?(validsig)
- STDERR.puts ".users file is signed by #{validsig} which is not in ~/.pws-trusted-users"
- exit(1)
+ if not @trusted_users.include?(validsig)
+ raise ".users file is signed by #{validsig} which is not in #{@trusted_users}"
end
if not exitstatus==0
- STDERR.puts "gpg verify failed for .users file"
- exit(1)
+ raise "gpg verify failed for .users file"
end
return outtxt
def parse_file
begin
- f = File.open('.users')
+ f = File.open(File.join(@dirname, '.users'))
rescue Exception => e
- STDERR.puts e
- exit(1)
+ raise e
end
users = f.read
had_progress = false
all_expanded = true
@groups.each_pair do |groupname, group|
- group['keys'] = [] unless group['keys']
+ group['keys'] = [] unless group['keys']
still_contains_groups = false
group['members_to_do'].clone.each do |member|
end
class EncryptedFile < EncryptedData
- def initialize(filename, new=false)
- @groupconfig = GroupConfig.new
+ def initialize(filename, new=false, trusted_file=nil)
+ @groupconfig = GroupConfig.new(dirname=File.dirname(filename), trusted_users=trusted_file)
@new = new
if @new
@readers = []