From 1f226aafea6b633dfff9681bb4b0a8b347fcb398 Mon Sep 17 00:00:00 2001 From: Paul B Date: Fri, 14 Sep 2018 13:38:02 +0200 Subject: [PATCH] github(login): Add a way to read ~/.netrc.gpg encrypted files I usually don't store authentication information in plain text in my home directory. Instead most of my secrets are stored in *.gpg files which can be read by relevant applications if my GPG key has been unlocked in my X session. The current implementation of travis.rb only reads ~/.netrc for `--auto` logins. It would be nice for the cli to also be able to read `~/.netrc.gpg` file. This PR adds a system (`Open3.capture3`) call to the `gpg` binary because users using `*.gpg` files would probably always have the binary available in their path. Thanks! --- lib/travis/tools/github.rb | 30 ++++++++++++++++++++++++++++-- 1 file changed, 28 insertions(+), 2 deletions(-) diff --git a/lib/travis/tools/github.rb b/lib/travis/tools/github.rb index 74e023b8..482feff3 100644 --- a/lib/travis/tools/github.rb +++ b/lib/travis/tools/github.rb @@ -2,6 +2,7 @@ require 'yaml' require 'json' require 'gh' +require 'open3' module Travis module Tools @@ -171,7 +172,7 @@ def keychain_login end def netrc - file(netrc_path, []) do |contents| + gpg_file_or_file(netrc_path, []) do |contents| contents.scan(/^\s*(\S+)\s+(\S+)\s*$/).inject([]) do |mapping, (key, value)| mapping << {} if key == "machine" mapping.last[key] = value if mapping.last @@ -282,12 +283,37 @@ def security(type, key, arg, name) raise e if explode end + def gpg_file_or_file(path, default = nil) + gpg_path = File.expand_path("#{path}.gpg") + + if File.file?(gpg_path) + path &&= gpg_path + else + path &&= File.expand_path(path) + end + + file(path, default) + end + def file(path, default = nil) path &&= File.expand_path(path) @file ||= {} @file[path] ||= if path and File.readable?(path) debug "reading #{path}" - yield File.read(path) + if path.end_with?(".gpg") + stdout_str, stderr_str, status = Open3.capture3("gpg", "-d", path) + if status.success? + yield stdout_str + else + debug "unable to decrypt #{path} file because of:" + debug stderr_str + unencrypted_path = path.sub(/#{File.extname(path)}$/, '') + debug "falling back to reading #{unencrypted_path}" + yield File.read(unencrypted_path) + end + else + yield File.read(path) + end end @file[path] || default rescue => e