#!/usr/bin/env python3 # A little tool to encrypt/decrypt git secrets. Kinda like password-store, but more purpose specific and portable. import logging import os import sys import subprocess keys = [ "63DFE737F078657CC8A51C00C29ADD73B3563D82", # q3k "482FF104C29294AD1CAF827BA43890A3DE74ECC7", # inf "F07205946C07EEB2041A72FBC60C64879534F768", # cz2 "0879F9FCA1C836677BB808C870FD60197E195C26", # implr ] logger = logging.getLogger(__name__) def encrypt(src, dst): cmd = ['gpg' , '--encrypt', '--armor', '--batch', '--yes', '--output', dst] for k in keys: cmd.append('--recipient') cmd.append(k) cmd.append(src) subprocess.check_call(cmd) def decrypt(src, dst): cmd = ['gpg', '--decrypt', '--batch', '--yes', '--output', dst, src] subprocess.check_call(cmd) class SecretStoreMissing(Exception): pass class SecretStore(object): def __init__(self, plain_root, cipher_root): self.proot = plain_root self.croot = cipher_root def exists(self, suffix): p = os.path.join(self.proot, suffix) c = os.path.join(self.croot, suffix) return os.path.exists(c) or os.path.exists(p) def plaintext(self, suffix): p = os.path.join(self.proot, suffix) c = os.path.join(self.croot, suffix) has_p = os.path.exists(p) has_c = os.path.exists(c) if has_c and has_p and os.path.getctime(p) < os.path.getctime(c): logger.info("Decrypting {} ({})...".format(suffix, c)) decrypt(c, p) return p def open(self, suffix, mode, *a, **kw): p = os.path.join(self.proot, suffix) c = os.path.join(self.croot, suffix) if 'w' in mode: return open(p, mode, *a, **kw) if not self.exists(suffix): raise SecretStoreMissing("Secret {} does not exist".format(suffix)) if not os.path.exists(p) or os.path.getctime(p) < os.path.getctime(c): logger.info("Decrypting {} ({})...".format(suffix, c)) decrypt(c, p) return open(p, mode, *a, **kw) def main(): if len(sys.argv) < 3 or sys.argv[1] not in ('encrypt', 'decrypt'): sys.stderr.write("Usage: {} encrypt/decrypt file\n".format(sys.argv[0])) sys.stderr.flush() return 1 action = sys.argv[1] src = sys.argv[2] if action == 'encrypt': encrypt(src, '-') else: decrypt(src, '-') if __name__ == '__main__': sys.exit(main() or 0)