1#!/usr/bin/env python3 2# -*- coding: utf-8 -*- 3 4from __future__ import absolute_import, division, unicode_literals 5 6import gpg 7import os.path 8import subprocess 9import sys 10 11from groups import group_lists 12 13# Copyright (C) 2018 Ben McGinnes <ben@gnupg.org> 14# 15# This program is free software; you can redistribute it and/or modify it under 16# the terms of the GNU General Public License as published by the Free Software 17# Foundation; either version 2 of the License, or (at your option) any later 18# version. 19# 20# This program is free software; you can redistribute it and/or modify it under 21# the terms of the GNU Lesser General Public License as published by the Free 22# Software Foundation; either version 2.1 of the License, or (at your option) 23# any later version. 24# 25# This program is distributed in the hope that it will be useful, but WITHOUT 26# ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or FITNESS 27# FOR A PARTICULAR PURPOSE. See the GNU General Public License and the GNU 28# Lesser General Public License for more details. 29# 30# You should have received a copy of the GNU General Public License and the GNU 31# Lesser General Public along with this program; if not, see 32# <https://www.gnu.org/licenses/>. 33 34print(""" 35This script applies a local signature or certification to every key in a group. 36 37Usage: local-sign-group.py <group name> [signing keyid] [gnupg homedir] 38""") 39 40c = gpg.Context(armor=True) 41mkfpr = None 42defkey_fpr = None 43enckey_fpr = None 44to_certify = [] 45 46if len(sys.argv) >= 4: 47 clique = sys.argv[1] 48 sigkey = sys.argv[2] 49 homedir = sys.argv[3] 50elif len(sys.argv) == 3: 51 clique = sys.argv[1] 52 sigkey = sys.argv[2] 53 homedir = input("Enter the GPG configuration directory path (optional): ") 54elif len(sys.argv) == 2: 55 clique = sys.argv[1] 56 sigkey = input("Enter the key ID to sign with (conditionally optional): ") 57 homedir = input("Enter the GPG configuration directory path (optional): ") 58else: 59 clique = input("Enter the group matching the key(s) to locally sign: ") 60 sigkey = input("Enter the key ID to sign with (conditionally optional): ") 61 homedir = input("Enter the GPG configuration directory path (optional): ") 62 63if len(homedir) == 0: 64 homedir = None 65elif homedir.startswith("~"): 66 userdir = os.path.expanduser(homedir) 67 if os.path.exists(userdir) is True: 68 homedir = os.path.realpath(userdir) 69 else: 70 homedir = None 71else: 72 homedir = os.path.realpath(homedir) 73 74if homedir is not None and os.path.exists(homedir) is False: 75 homedir = None 76elif homedir is not None and os.path.exists(homedir) is True: 77 if os.path.isdir(homedir) is False: 78 homedir = None 79 else: 80 pass 81 82if homedir is not None: 83 c.home_dir = homedir 84else: 85 pass 86 87if len(sigkey) == 0: 88 sigkey = None 89else: 90 pass 91 92if sys.platform == "win32": 93 gpgconfcmd = "gpgconf.exe --list-options gpg" 94else: 95 gpgconfcmd = "gpgconf --list-options gpg" 96 97try: 98 lines = subprocess.getoutput(gpgconfcmd).splitlines() 99except: 100 process = subprocess.Popen(gpgconfcmd.split(), stdout=subprocess.PIPE) 101 procom = process.communicate() 102 if sys.version_info[0] == 2: 103 lines = procom[0].splitlines() 104 else: 105 lines = procom[0].decode().splitlines() 106 107for i in range(len(lines)): 108 if lines[i].startswith("default-key") is True: 109 dline = lines[i] 110 elif lines[i].startswith("encrypt-to") is True: 111 eline = lines[i] 112 else: 113 pass 114 115defkey_fpr = dline.split(":")[-1].replace('"', '').split(',')[0].upper() 116enckey_fpr = eline.split(":")[-1].replace('"', '').split(',')[0].upper() 117 118try: 119 dkey = c.keylist(pattern=defkey_fpr, secret=True) 120 dk = list(dkey) 121except Exception as de: 122 print(de) 123 dk = None 124 print("No valid default key.") 125 126try: 127 ekey = c.keylist(pattern=defkey_fpr, secret=True) 128 ek = list(ekey) 129except Exception as ee: 130 print(ee) 131 ek = None 132 print("No valid always encrypt to key.") 133 134if sigkey is not None: 135 mykey = c.keylist(pattern=sigkey, secret=True) 136 mk = list(mykey) 137 mkfpr = mk[0].fpr.upper() 138 c.signers = mk 139else: 140 if dk is None and ek is not None: 141 c.signers = ek 142 else: 143 pass 144 145for group in group_lists: 146 if group[0] == clique: 147 for logrus in group[1]: 148 khole = c.keylist(pattern=logrus) 149 k = list(khole) 150 to_certify.append(k[0].fpr.upper()) 151 else: 152 pass 153 154if mkfpr is not None: 155 if to_certify.count(mkfpr) > 0: 156 for n in range(to_certify.count(mkfpr)): 157 to_certify.remove(mkfpr) 158 else: 159 pass 160else: 161 pass 162 163if defkey_fpr is not None: 164 if to_certify.count(defkey_fpr) > 0: 165 for n in range(to_certify.count(defkey_fpr)): 166 to_certify.remove(defkey_fpr) 167 else: 168 pass 169else: 170 pass 171 172if enckey_fpr is not None: 173 if to_certify.count(enckey_fpr) > 0: 174 for n in range(to_certify.count(enckey_fpr)): 175 to_certify.remove(enckey_fpr) 176 else: 177 pass 178else: 179 pass 180 181for fpr in to_certify: 182 key = c.get_key(fpr) 183 c.key_sign(key, uids=None, expires_in=False, local=True) 184