1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
|
#
#-*- coding:utf-8 -*-
"""
Gentoo-Keys - gkeygen/actions.py
Primary API interface module
@copyright: 2014 by Pavlos Ratis <dastergon@gentoo.org>
@license: GNU GPL2, see COPYING for details
"""
import gpgme
import os
import re
import shutil
import sys
from collections import OrderedDict
if sys.version_info[0] >= 3:
from urllib.request import urlopen
py_input = input
_unicode = str
else:
from urllib2 import urlopen
py_input = raw_input
_unicode = unicode
from gkeys.fileops import ensure_dirs
from gkeys import log
Action_Map = OrderedDict([
('gen-key', {
'func': 'genkey',
'options': ['spec', 'dest'],
'desc': '''Generate a gpg key using a spec file''',
'long_desc': '''Generate a gpg key using a spec file''',
'example': '''$ gkeys-gen gen-key
GPG key creator
Spec file..: glep-63-recommended
Homepage...: https://wiki.gentoo.org/wiki/GLEP:63
Give your Full Name: Foo Barr
Give your Email: foo@barr.net
Review:
Full Name: Foo Barr
Email: foo@barr.net
Continue?[y/n]: y
* Creating gpg folder at /home/brian/gkeys-user/gpghome
* Creating gpg.conf file at /home/brian/gkeys-user/gpghome
____________________
< Generating GPG key >
--------------------
\ ^__^
\ (oo)\_______
(__)\ )\/
||----w |
|| ||
* Give the password for the key. (Pick a strong one)
Please surf the internet, type on your keyboard, etc.
This helps the random number generator work effectively
Your new GLEP 63 based OpenPGP key has been created in /home/brian/gkeys-user/gpghome
GPG key info:
Full Name: Foo Barr,
Email: foo@barr.net,
Fingerprint: CF8F369903999538F79287497AD8F5FEF19A7A69
In order to use your new key, place the new gpghome to your ~/.gnupg folder by running the following command:
mv /home/brian/gkeys-user/gpghome ~/.gnupg
Important: If you have another old key in ~/.gnupg please make sure you backup it up first.
Please read the FAQ for post-generation steps that are available in:
https://wiki.gentoo.org/wiki/Project:Gentoo-keys/Generating_GLEP_63_based_OpenPGP_keys
''',
}),
('list-specs', {
'func': 'list_specs',
'options': [],
'desc': '''List spec file definitions (spec names) found in the config''',
'long_desc': '''List spec file definitions (spec names) found in the config.
The default-spec setting when the pkg was installed is set to glep-63-recommended.''',
'example': '''$ gkeys-gen list-specs
Gkey task results:
Specs defined: glep-63, default-spec, glep-63-recommended
''',
}),
])
Available_Actions = ['gen-key', 'list-specs']
LARRY = """
____________________
< Generating GPG key >
--------------------
\ ^__^
\ (oo)\_______
(__)\ )\/
||----w |
|| ||"""
GPG_INFO_STRING = """
GPG key info:
Full Name: %s,
Email: %s,
Fingerprint: %s
"""
class Actions(object):
def __init__(self, config, output=None, logger=None):
self.config = config
self.output = output
self.logger = logger
def configure_config_file(self,args, gpghome):
'''Creates the config file'''
newgpgconfpath = os.path.join(gpghome, 'gpg.conf')
defaultpath = '/usr/share/gnupg/gpg-conf.skel'
file_exists = False
while not file_exists:
skelconfpath = py_input("Path of default gpg configuration file to use (default: %s) " %defaultpath)
if len(skelconfpath) <= 0:
skelconfpath = defaultpath
file_exists = os.path.exists(skelconfpath)
shutil.copy(skelconfpath, newgpgconfpath)
with open(newgpgconfpath, 'a') as conf:
for line in urlopen(self.config.get_key('gpg-urls', args.spec)):
conf.write(_unicode(line.decode('utf-8')))
def genkey(self, args):
'''Generate a gpg key using a spec file'''
messages = []
if not args.destination:
gpghome = self.config.get_key('gkeys-gen', 'gpg-home')
else:
if os.path.exists(args.destination):
gpghome = os.path.join(args.destination, 'gpghome')
else:
messages.extend(['', "Aborting... %s path does not exist." % args.destination])
return (False, messages)
self.logger.debug("MAIN: _action_genkey; setting gpghome destination: %s" % gpghome)
self.logger.debug("MAIN: _action_genkey; args= %s" % str(args))
if not args.spec:
args.spec = self.config.get_key('spec', 'default-spec')
key_params = self.get_input(args)
ack = None
while ack not in ["y", "yes", "n", "no"]:
ack = py_input("Continue?[y/n]: ").lower()
if ack in ["n", "no"]:
messages.extend(['', "\nKey generation aborted."])
return (False, messages)
elif ack in ["y", "yes"]:
# Set the environment to custom gpg directory
os.environ['GNUPGHOME'] = gpghome
gpghome_full_path = os.path.abspath(gpghome)
self.logger.info("MAIN: _action_genkey; create custom gpg directory: %s" % gpghome_full_path)
self.output(["\n* Creating gpg folder at %s" % gpghome_full_path])
ensure_dirs(gpghome)
# Copy default gpg-conf.skel and append glep63 requirements
self.configure_config_file(args, gpghome)
# Key generation
ctx = gpgme.Context()
self.logger.info("MAIN: _action_genkey: Generating GPG key...")
self.output([LARRY])
self.output(["* Give the password for the key. (Pick a strong one)",
" Please surf the internet, type on your keyboard, etc. ",
" This helps the random number generator work effectively"])
try:
result = ctx.genkey(key_params)
except gpgme.GpgmeError as e:
self.logger.debug("MAIN: _action_genkey: GpgmeError: %s" % str(e))
self.logger.debug("MAIN: _action_genkey: Aborting... Gpgme errored out.")
messages.extend(['', "Aborting... Gpgme reported an error.\n",
" GpgmeError: %s\n" % str(e),
" See the log file for details: %s" % log.logname])
return (False, messages)
key = ctx.get_key(result.fpr, True)
self.logger.debug("MAIN: _action_genkey: Generated key: %s - %s"
% (key.uids[0].uid, key.subkeys[0].fpr))
self.output(["Your new GLEP 63 based OpenPGP key has been created in %s" % gpghome_full_path])
self.output([GPG_INFO_STRING % (key.uids[0].name, key.uids[0].email,
key.subkeys[0].fpr)])
self.output(["In order to use your new key, place the new gpghome to your ~/.gnupg folder by running the following command:",
" mv %s ~/.gnupg" % gpghome_full_path,
"Important: If you have another old key in ~/.gnupg please make sure you backup it up first.\n",
"Please read the FAQ for post-generation steps that are available in:",
"https://wiki.gentoo.org/wiki/Project:Gentoo-keys/Generating_GLEP_63_based_OpenPGP_keys"])
return (True, messages)
def get_input(self, args):
'''Interactive user input'''
self.output(['', "GPG key creator",
" Spec file..: %s" % args.spec,
" Homepage...: %s"
% self.config.get_key('spec-homepage', args.spec),
])
name = py_input("Give your Full Name: ")
email = py_input("Give your Email: ")
while not re.match(r'[\w.-]+@[\w.-]+', email):
self.output(["\nBad email input. Try again."])
email = py_input("Give your Email: ")
print("\nReview:\n Full Name: %s\n Email: %s\n" % (name, email))
url = self.config.get_key('spec-urls', args.spec)
key_properties = urlopen(url).read()
return _unicode(key_properties.decode('utf-8')).format(name, email)
def list_specs(self, args):
'''List seed file definitions found in the config'''
specs = list(self.config.get_key('spec'))
return (True, {"Specs defined: %s\n"
% (", ".join(specs)): True})
|