Gentoo Archives: gentoo-commits

From: Brian Dolbec <dolsen@g.o>
To: gentoo-commits@l.g.o
Subject: [gentoo-commits] proj/gentoo-keys:master commit in: gkeys-gen/etc/, gkeys/gkeys/, gkeys-gen/bin/, gkeys-gen/gkeygen/
Date: Thu, 01 Jan 2015 17:45:00
Message-Id: 1420079991.8be6c1ff9d7717d82d8d6e088899af6a749dc9ef.dolsen@gentoo
1 commit: 8be6c1ff9d7717d82d8d6e088899af6a749dc9ef
2 Author: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
3 AuthorDate: Tue Dec 30 19:40:31 2014 +0000
4 Commit: Brian Dolbec <dolsen <AT> gentoo <DOT> org>
5 CommitDate: Thu Jan 1 02:39:51 2015 +0000
6 URL: http://sources.gentoo.org/gitweb/?p=proj/gentoo-keys.git;a=commit;h=8be6c1ff
7
8 gkeys-gen: Initial migration to use gkeys.base.CliBase class
9
10 Add a new gkeys-gen specific config file extension to gkeys.conf.
11 Change gpghome to use the configured gpg-home setting.
12 Remove default SPEC and GPG_CONF settings, use configured ones.
13 bin/gkey-gen update exit.
14
15 ---
16 gkeys-gen/bin/gkey-gen | 5 +-
17 gkeys-gen/etc/gkeys-gen.conf | 29 ++++++++++++
18 gkeys-gen/gkeygen/actions.py | 100 +++++++++++++++++++++++----------------
19 gkeys-gen/gkeygen/cli.py | 110 +++++++++++--------------------------------
20 gkeys/gkeys/base.py | 2 +-
21 5 files changed, 120 insertions(+), 126 deletions(-)
22
23 diff --git a/gkeys-gen/bin/gkey-gen b/gkeys-gen/bin/gkey-gen
24 index e322f11..9acfc88 100755
25 --- a/gkeys-gen/bin/gkey-gen
26 +++ b/gkeys-gen/bin/gkey-gen
27 @@ -47,4 +47,7 @@ if 'ROOT' in os.environ:
28 root = os.environ['ROOT']
29
30 main = Main(root=root)
31 -main()
32 +success = main()
33 +
34 +# exit is boolean opposite normal True/False
35 +sys.exit(not success)
36
37 diff --git a/gkeys-gen/etc/gkeys-gen.conf b/gkeys-gen/etc/gkeys-gen.conf
38 new file mode 100644
39 index 0000000..d67f10a
40 --- /dev/null
41 +++ b/gkeys-gen/etc/gkeys-gen.conf
42 @@ -0,0 +1,29 @@
43 +# Gentoo-keys configuration file
44 +#
45 +
46 +[gkeys-gen]
47 +
48 +
49 +gpg-home = %(user-dir)s/gpghome
50 +
51 +
52 +[spec]
53 +
54 +glep-63 = %(user-dir)s/glep63.spec'
55 +
56 +default-spec = glep-63
57 +
58 +
59 +[spec-urls]
60 +
61 +glep-63 = https://api.gentoo.org/gentoo-keys/specs/glep63.spec
62 +
63 +
64 +[gpg-configs]
65 +
66 +glep-63 = %(user-dir)s/glep63-gpg-conf.skel
67 +
68 +
69 +[gpg-urls]
70 +
71 +glep-63 = https://api.gentoo.org/gentoo-keys/specs/glep63-gpg-conf.skel
72
73 diff --git a/gkeys-gen/gkeygen/actions.py b/gkeys-gen/gkeygen/actions.py
74 index e33ebb8..b3aecb9 100644
75 --- a/gkeys-gen/gkeygen/actions.py
76 +++ b/gkeys-gen/gkeygen/actions.py
77 @@ -26,10 +26,35 @@ else:
78
79 from gkeys.fileops import ensure_dirs
80
81 -Available_Actions = ["genkey"]
82
83 -GPG_CONF = "https://api.gentoo.org/gentoo-keys/specs/glep63-gpg-conf.skel"
84 -SPEC = "https://api.gentoo.org/gentoo-keys/specs/glep63.spec"
85 +Available_Actions = ["gen-key"]
86 +
87 +Action_Options = {
88 + 'gen-key': ['dest'],
89 +}
90 +
91 +Action_Map = {
92 + 'gen-key': 'genkey',
93 +}
94 +
95 +
96 +LARRY = """
97 + ____________________
98 + < Generating GPG key >
99 + --------------------
100 + \ ^__^
101 + \ (oo)\_______
102 + (__)\ )\/
103 + ||----w |
104 + || ||"""
105 +
106 +GPG_INFO_STRING = """
107 + GPG key info:
108 + Full Name: %s,
109 + Email: %s,
110 + Fingerprint: %s
111 + """
112 +
113
114 class Actions(object):
115
116 @@ -38,16 +63,18 @@ class Actions(object):
117 self.output = output
118 self.logger = logger
119
120 +
121 def genkey(self, args):
122 '''Key generation action'''
123 - if not args.homedir:
124 - gpghome = os.path.join(os.getcwd(), 'gpghome')
125 + messages = []
126 + if not args.destination:
127 + gpghome = self.config.get_key('gkeys-gen', 'gpg-home')
128 else:
129 - if os.path.exists(args.homedir):
130 - gpghome = os.path.join(args.homedir, 'gpghome')
131 + if os.path.exists(args.destination):
132 + gpghome = os.path.join(args.destination, 'gpghome')
133 else:
134 - self.output("Aborting... %s path does not exist." % args.homedir)
135 - return False
136 + messages.extend(['', "Aborting... %s path does not exist." % args.destination])
137 + return (False, messages)
138 self.logger.debug("MAIN: _action_genkey; setting gpghome destination: %s" % gpghome)
139 self.logger.debug("MAIN: _action_genkey; args= %s" % str(args))
140 key_params = self.get_input()
141 @@ -55,68 +82,59 @@ class Actions(object):
142 while ack not in ["y", "yes", "n", "no"]:
143 ack = py_input("Continue?[y/n]: ").lower()
144 if ack in ["n", "no"]:
145 - self.output("\nKey generation aborted.")
146 - return False
147 + messages.extend(['', "\nKey generation aborted."])
148 + return (False. messages)
149 elif ack in ["y", "yes"]:
150 # Set the environment to custom gpg directory
151 os.environ['GNUPGHOME'] = gpghome
152 gpghome_full_path = os.path.abspath(gpghome)
153 self.logger.info("MAIN: _action_genkey; create custom gpg directory: %s" % gpghome_full_path)
154 - self.output("\n* Creating gpg folder at %s" % gpghome_full_path)
155 + self.output(["\n* Creating gpg folder at %s" % gpghome_full_path])
156 ensure_dirs(gpghome)
157 # Copy default gpg-conf.skel and append glep63 requirements
158 - self.output("* Creating gpg.conf file at %s" % gpghome_full_path)
159 + self.output(["* Creating gpg.conf file at %s" % gpghome_full_path])
160 newgpgconfpath = os.path.join(gpghome, 'gpg.conf')
161 shutil.copy('/usr/share/gnupg/gpg-conf.skel', newgpgconfpath)
162 with open(newgpgconfpath, 'a') as conf:
163 - for line in urlopen(GPG_CONF):
164 + for line in urlopen(self.config.defaults['gpg.conf-url']):
165 conf.write(_unicode(line))
166 # Key generation
167 ctx = gpgme.Context()
168 self.logger.info("MAIN: _action_genkey: Generating GPG key...")
169 - self.output("""
170 - ____________________
171 - < Generating GPG key >
172 - --------------------
173 - \ ^__^
174 - \ (oo)\_______
175 - (__)\ )\/
176 - ||----w |
177 - || ||""")
178 - self.output("\n* Give the password for the key. (Pick a strong one)\n")
179 + self.output([LARRY])
180 + self.output(["* Give the password for the key. (Pick a strong one)",
181 + " Please surf the internet, type on your keyboard, etc. ",
182 + " This helps the random number generator work effectively"])
183 try:
184 result = ctx.genkey(key_params)
185 except gpgme.GpgmeError:
186 self.logger.debug("MAIN: _action_genkey: Aborting... No given password.")
187 - self.output("Aborting... No given password.")
188 - return False
189 + messages.extend(['', "Aborting... No given password."])
190 + return (False, messages)
191 key = ctx.get_key(result.fpr, True)
192 self.logger.debug("MAIN: _action_genkey: Generated key: %s - %s"
193 % (key.uids[0].uid, key.subkeys[0].fpr))
194 - self.output("Your new GLEP 63 based OpenPGP key has been created in %s" % gpghome_full_path)
195 - self.output("""
196 - GPG key info:
197 - Full Name: %s,
198 - Email: %s,
199 - Fingerprint: %s
200 - """ % (key.uids[0].name, key.uids[0].email,
201 - key.subkeys[0].fpr))
202 - self.output("In order to use your new key, place the new gpghome to your ~/.gnupg folder by running the following command:\n"
203 + self.output(["Your new GLEP 63 based OpenPGP key has been created in %s" % gpghome_full_path])
204 + self.output([GPG_INFO_STRING % (key.uids[0].name, key.uids[0].email,
205 + key.subkeys[0].fpr)])
206 + self.output(["In order to use your new key, place the new gpghome to your ~/.gnupg folder by running the following command:\n"
207 " mv %s ~/.gnupg\n"
208 "Important: If you have another old key in ~/.gnupg please make sure you backup it up first.\n\n"
209 "Please read the FAQ for post-generation steps that are available in: \n"
210 - "https://wiki.gentoo.org/wiki/Project:Gentoo-keys/Generating_GLEP_63_based_OpenPGP_keys\n" % gpghome_full_path)
211 - return True
212 + "https://wiki.gentoo.org/wiki/Project:Gentoo-keys/Generating_GLEP_63_based_OpenPGP_keys\n" % gpghome_full_path])
213 + return (True, messages)
214 +
215
216 def get_input(self):
217 '''Interactive user input'''
218 - self.output("\nGPG key creator based on GLEP 63\n"
219 - "(https://wiki.gentoo.org/wiki/GLEP:63)\n")
220 + self.output(["\nGPG key creator based on GLEP 63\n"
221 + "(https://wiki.gentoo.org/wiki/GLEP:63)\n"])
222 name = py_input("Give your Full Name: ")
223 email = py_input("Give your Email: ")
224 while not re.match(r'[\w.-]+@[\w.-]+', email):
225 - self.output("\nBad email input. Try again.")
226 + self.output(["\nBad email input. Try again."])
227 email = py_input("Give your Email: ")
228 print("\nReview:\n Full Name: %s\n Email: %s\n" % (name, email))
229 - key_properties = urlopen(SPEC).read()
230 + key_properties = urlopen(self.config.defaults['key-spec-url']).read()
231 return _unicode(key_properties).format(name, email)
232 +
233
234 diff --git a/gkeys-gen/gkeygen/cli.py b/gkeys-gen/gkeygen/cli.py
235 index e05ea1e..818dbbd 100644
236 --- a/gkeys-gen/gkeygen/cli.py
237 +++ b/gkeys-gen/gkeygen/cli.py
238 @@ -4,14 +4,17 @@
239 from __future__ import print_function
240
241
242 -import sys
243 import argparse
244 +import os
245 +import sys
246
247 from gkeys.config import GKeysConfig
248 from gkeys.log import log_levels, set_logger
249 -from gkeygen.actions import Actions, Available_Actions
250 +from gkeys.base import CliBase
251 +from gkeygen.actions import Actions, Available_Actions, Action_Options, Action_Map
252
253 -class Main(object):
254 +
255 +class Main(CliBase):
256 '''Main command line interface class'''
257
258
259 @@ -22,10 +25,19 @@ class Main(object):
260 @param config: optional GKeysConfig instance, For API use
261 @param print_results: optional boolean, for API use
262 """
263 + CliBase.__init__(self)
264 self.root = root or "/"
265 self.config = config or GKeysConfig(root=root)
266 - self.print_results = print_results
267 - self.args = None
268 + self.config.options['print_results'] = print_results
269 + self.cli_config = {
270 + 'Actions': Actions,
271 + 'Available_Actions': Available_Actions,
272 + 'Action_Options': Action_Options,
273 + 'Action_Map': Action_Map,
274 + 'prog': 'gkeys-gen',
275 + 'description': 'Gentoo Keys GPG key generator program',
276 + 'epilog': '''CAUTION: adding UNTRUSTED keys can be HAZARDOUS to your system!'''
277 + }
278
279
280 def __call__(self, args=None):
281 @@ -35,82 +47,14 @@ class Main(object):
282 Defaults to sys.argv[1:]
283 """
284 if args:
285 - self.run(self.parse_args(args))
286 + ok = self.setup(args, configs)
287 + if ok:
288 + return self.run(self.parse_args(args))
289 else:
290 - self.run(self.parse_args(sys.argv[1:]))
291 -
292 -
293 - def parse_args(self, args):
294 - '''Parse a list of aruments
295 -
296 - @param args: list
297 - @returns argparse.Namespace object
298 - '''
299 - #logger.debug('MAIN: parse_args; args: %s' % args)
300 - actions = Available_Actions
301 - parser = argparse.ArgumentParser(
302 - prog='gkeys-gen',
303 - description='Gentoo Keys GPG key generator program',
304 - epilog='''Caution: adding untrusted keys to these keyrings can
305 - be hazardous to your system!''')
306 - # actions
307 - parser.add_argument('action', choices=actions, nargs='?',
308 - default='genkey', help='Generate GPG key based on GLEP 63')
309 - # options
310 - parser.add_argument('-c', '--config', dest='config', default=None,
311 - help='The path to an alternate config file')
312 - parser.add_argument('-D', '--debug', default='DEBUG',
313 - choices=list(log_levels),
314 - help='The logging level to set for the logfile')
315 - parser.add_argument('-H', '--homedir', dest='homedir', default=None,
316 - help='The destination for the generated key')
317 - parser.add_argument('-m', '--mail', dest='mail', default=None,
318 - help='The email address to search for')
319 - parser.add_argument('-n', '--nick', dest='nick', default=None,
320 - help='The nick or user id (uid) to search for')
321 - parser.add_argument('-N', '--name', dest='name', default=None,
322 - help='The name to search for')
323 - return parser.parse_args(args)
324 -
325 -
326 - def run(self, args):
327 - '''Run the args passed in
328 -
329 - @param args: list or argparse.Namespace object
330 - '''
331 - global logger
332 - message = None
333 - if not args:
334 - message = "Main: run; invalid args argument passed in"
335 - if isinstance(args, list):
336 - args = self.parse_args(args)
337 - if args.config:
338 - self.config.defaults['config'] = args.config
339 - # now make it load the config file
340 - self.config.read_config()
341 -
342 - # establish our logger and update it in the imported files
343 - logger = set_logger('gkeys-gen', self.config['logdir'], args.debug,
344 - dirmode=int(self.config.get_key('permissions', 'directories'),0),
345 - filemask=int(self.config.get_key('permissions', 'files'),0))
346 - #config.logger = logger
347 -
348 - if message:
349 - logger.error(message)
350 -
351 - # now that we have a logger, record the alternate config setting
352 - if args.config:
353 - logger.debug("Main: run; Found alternate config request: %s"
354 - % args.config)
355 -
356 - # establish our actions instance
357 - self.actions = Actions(self.config, print, logger)
358 -
359 - logger.info("Begin running action: %s" % args.action)
360 -
361 - # run the action
362 - func = getattr(self.actions, '%s' % args.action)
363 -
364 - logger.debug('Main: run; Found action: %s' % args.action)
365 - results = func(args)
366 - return results
367 + args = self.parse_args(sys.argv[1:])
368 + configs = [os.path.join(self.config['configdir'],'gkeys.conf'),
369 + os.path.join(self.config['configdir'],'gkeys-gen.conf')]
370 + ok = self.setup(args, configs)
371 + if ok:
372 + return self.run(args)
373 + return False
374
375 diff --git a/gkeys/gkeys/base.py b/gkeys/gkeys/base.py
376 index 052d45f..6e53f87 100644
377 --- a/gkeys/gkeys/base.py
378 +++ b/gkeys/gkeys/base.py
379 @@ -302,7 +302,7 @@ class CliBase(object):
380
381
382 @staticmethod
383 - def output_results(results, header):
384 + def output_results(results, header=None):
385 # super simple output for the time being
386 if header:
387 print(header)