simple-gnupg-keyserver 1.3.0 → 2.0.0
Sign up to get free protection for your applications and to get access to all the features.
- data/.gitignore +5 -1
- data/History.txt +0 -2
- data/Manifest.txt +4 -1
- data/README.rdoc +45 -40
- data/Rakefile +1 -0
- data/lib/simpleHKP/echo.rb +49 -8
- data/lib/simpleHKP/identities.rb +240 -0
- data/lib/simpleHKP/keys.rb +239 -0
- data/lib/simpleHKP/server.rb +349 -0
- data/lib/simpleHKP.rb +10 -489
- metadata +13 -9
data/lib/simpleHKP.rb
CHANGED
@@ -1,8 +1,3 @@
|
|
1
|
-
require 'uri'
|
2
|
-
require 'open3'
|
3
|
-
require 'pp'
|
4
|
-
require 'fileutils'
|
5
|
-
|
6
1
|
# This code was inspired by:
|
7
2
|
# Sebi2020's Informatikonline Easy-HKP
|
8
3
|
# https://github.com/Sebi2020/easy-hkp
|
@@ -39,492 +34,18 @@ require 'fileutils'
|
|
39
34
|
# TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE
|
40
35
|
# SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
|
41
36
|
|
42
|
-
|
43
|
-
|
44
|
-
|
45
|
-
|
46
|
-
|
47
|
-
lastKey['colonData'].gsub!(/\\x3a/,':') if
|
48
|
-
lastKey.has_key?('colonData')
|
49
|
-
pp lastKey if @debug
|
50
|
-
@keyLookupData[lastKey['keyID']] = lastKey unless
|
51
|
-
lastKey.empty? || lastKey['keyID'].empty?
|
52
|
-
end
|
53
|
-
|
54
|
-
def loadKeys
|
55
|
-
@keyLookupData = Hash.new
|
56
|
-
puts "SimpleHKP: loading keys" if @debug
|
57
|
-
gpg2cmd = "gpg2 --homedir #{@keyDir} --with-fingerprint --with-colons --list-sigs"
|
58
|
-
puts gpg2cmd if @debug
|
59
|
-
lastKey = Hash.new
|
60
|
-
IO.popen(gpg2cmd, 'r').readlines.each do | aLine |
|
61
|
-
next if aLine =~ /^tru/
|
62
|
-
if aLine =~ /^pub/ then
|
63
|
-
saveLastKey(lastKey)
|
64
|
-
lastKey = Hash.new
|
65
|
-
keyData = aLine.split(/:/)
|
66
|
-
lastKey['userID'] = keyData[9].gsub(/\\x3a/,':') # user ID
|
67
|
-
lastKey['keyID'] = keyData[4] # key ID
|
68
|
-
lastKey['algorithm'] = keyData[3] # key type (algorithm)
|
69
|
-
lastKey['len'] = keyData[2] # key length
|
70
|
-
lastKey['created'] = keyData[5] # creation date
|
71
|
-
lastKey['expires'] = keyData[6] # expiration date
|
72
|
-
lastKey['flags'] = keyData[1] # flags
|
73
|
-
lastKey['colonData'] = aLine
|
74
|
-
next
|
75
|
-
end
|
76
|
-
lastKey['userID'] = aLine.split(/:/)[9].gsub(/\\x3a/,':') if
|
77
|
-
aLine =~ /^uid/ && lastKey['userID'].empty?
|
78
|
-
lastKey['colonData'] << aLine
|
79
|
-
end
|
80
|
-
saveLastKey(lastKey)
|
81
|
-
@keyLookupData.each_pair do | key, value |
|
82
|
-
value['humanData'] = `gpg2 --list-sig #{key}`
|
83
|
-
end
|
84
|
-
pp @keyLookupData if @debug
|
85
|
-
puts "SimpleHKP: finished loading keys" if @debug
|
86
|
-
end
|
87
|
-
|
88
|
-
def loadHtml
|
89
|
-
puts "SimpleHKP: loading html partials" if @debug
|
90
|
-
Dir.chdir(@htmlDir) do
|
91
|
-
@headerHtml = "<html><head>"
|
92
|
-
@headerHtml << " <title>#{@title}</title>\n"
|
93
|
-
@headerHtml << "</head><body class=\"simpleHKP-body\">\n"
|
94
|
-
@headerHtml << "<p><a href=\"/\">#{@title}</a></p>"
|
95
|
-
@headerHtml = File.open('header.html','r').read if
|
96
|
-
File.exists?('header.html')
|
97
|
-
puts @headerHtml if @debug
|
98
|
-
|
99
|
-
@defaultBody = ""
|
100
|
-
@defaultBody << "<h1 class=\"simpleHKP-welcome\">Welcome to SimpleHKP</h1>\n"
|
101
|
-
@defaultBody << "<ul class=\"simpleHKP-tasksList\">\n"
|
102
|
-
@defaultBody << " <li class=\"simpleHKP-taskItem\"><a href=\"lookup?op=form\">Search</a></li>\n"
|
103
|
-
@defaultBody << " <li class=\"simpleHKP-taskItem\"><a href=\"add\">Upload new key</a></li>\n"
|
104
|
-
@defaultBody << " <li class=\"simpleHKP-taskItem\"><a href=\"reload\">Reload existing keys</a></li>\n"
|
105
|
-
@defaultBody << "</ul>\n"
|
106
|
-
@defaultBody = File.open('defaultBody.html','r').read if
|
107
|
-
File.exists?('defaultBody.html')
|
108
|
-
puts @defaultBody if @debug
|
109
|
-
|
110
|
-
@lookupForm = ""
|
111
|
-
@lookupForm << "<div class=\"simpleHKP-lookupFormDiv\">\n"
|
112
|
-
@lookupForm << " <h1 class=\"simpleHKP-lookupFormTitle\">Search GnuPG keys</h1>\n"
|
113
|
-
@lookupForm << " <form action=\"lookup\" method=\"get\" id=\"simpleHKP-lookupForm\">\n"
|
114
|
-
@lookupForm << " <input type=\"text\" name=\"search\" size=\"80\" />\n"
|
115
|
-
@lookupForm << " <input type=\"hidden\" name=\"op\" value=\"index\" />\n"
|
116
|
-
@lookupForm << " <input type=\"submit\" value=\"Search\" />\n"
|
117
|
-
@lookupForm << " </form>\n"
|
118
|
-
@lookupForm << "</div>\n"
|
119
|
-
@lookupForm = File.open('lookupForm.html','r').read if
|
120
|
-
File.exists?('lookupForm.html')
|
121
|
-
puts @lookupForm if @debug
|
122
|
-
|
123
|
-
@uploadForm = ""
|
124
|
-
@uploadForm << "<div class=\"simpleHKP-uploadFormDiv\">\n"
|
125
|
-
@uploadForm << " <h1 class=\"simpleHKP-uploadFormTitle\">Paste GnuPG key to be uploaded below</h1>\n"
|
126
|
-
@uploadForm << " <form action=\"add\" method=\"post\" id=\"simpleHKP-uploadForm\">\n"
|
127
|
-
@uploadForm << " <textarea name=\"keytext\" form=\"simpleHKP-uploadForm\" rows = \"30\" cols=\"70\" ></textarea>\n"
|
128
|
-
@uploadForm << " <input type=\"submit\" value=\"Upload\" />\n"
|
129
|
-
@uploadForm << " </form>\n"
|
130
|
-
@uploadForm << "</div>\n"
|
131
|
-
@uploadForm = File.open('uploadForm.html','r').read if
|
132
|
-
File.exists?('uploadForm.html')
|
133
|
-
puts @uploadForm if @debug
|
134
|
-
|
135
|
-
@footer = "</body></html>\n"
|
136
|
-
@footer = File.open('footer.html','r').read if
|
137
|
-
File.exists?('footer.html')
|
138
|
-
puts @footer if @debug
|
139
|
-
end
|
140
|
-
puts "SimpleHKP: finished loading html partials" if @debug
|
141
|
-
end
|
142
|
-
|
143
|
-
def initialize(options = {})
|
144
|
-
#
|
145
|
-
# setup the default options
|
146
|
-
#
|
147
|
-
defaultOptions = {
|
148
|
-
'debug' => false,
|
149
|
-
'title' => 'SimpleHKP',
|
150
|
-
'simpleHKPdir' => 'simpleHKP',
|
151
|
-
'keyDir' => 'keys',
|
152
|
-
'mediaDir' => 'media',
|
153
|
-
'htmlDir' => 'html',
|
154
|
-
'mimeMap' => {
|
155
|
-
'css' => 'text/css',
|
156
|
-
'html' => 'text/html',
|
157
|
-
'js' => 'text/javascript'
|
158
|
-
}
|
159
|
-
}
|
160
|
-
#
|
161
|
-
# merge the options mimeMap into the default options mimeMap
|
162
|
-
#
|
163
|
-
defaultOptions['mimeMap'].merge!(delete(options['mimeMap'])) if
|
164
|
-
options.has_key?('mimeMap')
|
165
|
-
#
|
166
|
-
# merge in the rest of the options into the default options
|
167
|
-
#
|
168
|
-
@options = defaultOptions.merge(options)
|
169
|
-
#
|
170
|
-
# setup the required variables
|
171
|
-
#
|
172
|
-
@debug = @options['debug']
|
173
|
-
@title = @options['title']
|
174
|
-
@baseDir = @options['simpleHKPdir']
|
175
|
-
@keyDir = @baseDir+'/'+@options['keyDir']
|
176
|
-
@mediaDir = @baseDir+'/'+@options['mediaDir']
|
177
|
-
@htmlDir = @baseDir+'/'+@options['htmlDir']
|
178
|
-
@mimeMap = @options['mimeMap']
|
179
|
-
if @debug then
|
180
|
-
puts "SimpleHKP options:"
|
181
|
-
pp @options
|
182
|
-
end
|
183
|
-
#
|
184
|
-
# ensure the required directories all exist
|
185
|
-
#
|
186
|
-
FileUtils.mkdir_p(@keyDir)
|
187
|
-
FileUtils.chmod(0700, @keyDir)
|
188
|
-
FileUtils.mkdir_p(@mediaDir)
|
189
|
-
FileUtils.mkdir_p(@htmlDir)
|
190
|
-
#
|
191
|
-
# load the existing keys and the html partials
|
192
|
-
loadKeys
|
193
|
-
loadHtml
|
194
|
-
end
|
195
|
-
|
196
|
-
def ppEnv(env)
|
197
|
-
Dir.pwd+' '+
|
198
|
-
# '['+URI.decode_www_form(env["rack.input"].rewind.read).pretty_inspect+']'+
|
199
|
-
env.pretty_inspect
|
200
|
-
end
|
201
|
-
|
202
|
-
def replyInternalError(env, exception)
|
203
|
-
@statusCode = 500
|
204
|
-
@body << @headerHtml
|
205
|
-
@body << "<p>Internal server error!</p>\n"
|
206
|
-
@body << "<pre>#{exception}</pre>\n" if @debug
|
207
|
-
@body << @footer
|
208
|
-
if @debug then
|
209
|
-
puts "\n\n-------------------------------------------------------------"
|
210
|
-
puts exception
|
211
|
-
puts "-------------------------------------------------------------"
|
212
|
-
puts ppEnv(env)
|
213
|
-
puts "-------------------------------------------------------------\n\n"
|
214
|
-
end
|
215
|
-
end
|
216
|
-
|
217
|
-
def replyNotImplemented
|
218
|
-
@statusCode = 501
|
219
|
-
@body << @headerHtml
|
220
|
-
@body << '<p>Not implemented!<p>'
|
221
|
-
@body << @footer
|
222
|
-
end
|
223
|
-
|
224
|
-
def replyBadRequest(message)
|
225
|
-
@statusCode = 400
|
226
|
-
@body << @headerHtml
|
227
|
-
@body << '<p>Bad request!</p>'
|
228
|
-
@body << "<p>#{message}</p>"
|
229
|
-
@body << @footer
|
230
|
-
end
|
231
|
-
|
232
|
-
def replyNotFound
|
233
|
-
@statusCode = 404
|
234
|
-
@body << @headerHtml
|
235
|
-
@body << '<p>Not found!</p>'
|
236
|
-
@body << @footer
|
237
|
-
end
|
238
|
-
|
239
|
-
def replyDefaultBody
|
240
|
-
@body << @headerHtml
|
241
|
-
@body << @defaultBody
|
242
|
-
@body << @footer
|
243
|
-
end
|
244
|
-
|
245
|
-
def replyLookupForm
|
246
|
-
@body << @headerHtml
|
247
|
-
@body << @lookupForm
|
248
|
-
@body << @footer
|
249
|
-
end
|
250
|
-
|
251
|
-
def replyUploadForm
|
252
|
-
@body << @headerHtml
|
253
|
-
@body << @uploadForm
|
254
|
-
@body << @footer
|
255
|
-
end
|
256
|
-
|
257
|
-
def replyFile(env)
|
258
|
-
fileName = env['REQUEST_PATH'].sub(/^.*\/media\//,'')
|
259
|
-
if File.exists?(fileName) then
|
260
|
-
fileExt = File.extname(fileName).sub(/^\./,'')
|
261
|
-
@header['Content-Type'] = @mimeMap[fileExt] if
|
262
|
-
@mimeMap.has_key?(fileExt)
|
263
|
-
@body << File.open(fileName,'r').read
|
264
|
-
end
|
265
|
-
end
|
266
|
-
|
267
|
-
def storeKey(env)
|
268
|
-
#
|
269
|
-
# decode the post data
|
270
|
-
#
|
271
|
-
keys = URI.decode_www_form(env['rack.input'].read)
|
272
|
-
#
|
273
|
-
# ensure we are being sent a key
|
274
|
-
#
|
275
|
-
return replyBadRequest("No keytext field in post data") unless
|
276
|
-
keys[0][0] =~ /keytext/
|
277
|
-
pp keys[0][1] if @debug
|
278
|
-
#
|
279
|
-
# send the key data through gpg2 to import it
|
280
|
-
#
|
281
|
-
gpgStdErr = ""
|
282
|
-
Open3.popen3("gpg2 --homedir #{@keyDir} --import") do | stdin, stdout, stderr, wait_thread |
|
283
|
-
stdin.write(keys[0][1])
|
284
|
-
stdin.close
|
285
|
-
gpgStdErr = stderr.read
|
286
|
-
end
|
287
|
-
#
|
288
|
-
# check to see if the key has already been imported and/or changed
|
289
|
-
#
|
290
|
-
puts "[[#{gpgStdErr}]]" if @debug
|
291
|
-
keyChanged = "changed"
|
292
|
-
if gpgStdErr =~ /not\s+changed/ then
|
293
|
-
keyChanged = "unchanged"
|
294
|
-
else
|
295
|
-
# something has changed to re-load the keys
|
296
|
-
loadKeys
|
297
|
-
end
|
298
|
-
#
|
299
|
-
# send the key data through gpg2 (again ;-( to extract the keyID
|
300
|
-
#
|
301
|
-
gpgKeyData = ""
|
302
|
-
IO.popen('gpg2 --with-fingerprint --with-colons -', 'r+') do | pipe |
|
303
|
-
puts 'gpg2 --with-fingerprint --with-colons -' if @debug
|
304
|
-
pipe.write(keys[0][1])
|
305
|
-
pipe.close_write
|
306
|
-
gpgKeyData = pipe.read
|
307
|
-
end
|
308
|
-
puts gpgKeyData if @debug
|
309
|
-
#
|
310
|
-
# look for the keyID of the public key
|
311
|
-
#
|
312
|
-
keyID = nil
|
313
|
-
gpgKeyData.each_line do | aLine |
|
314
|
-
keyData = aLine.split(/:/)
|
315
|
-
next unless keyData[0] =~ /pub/
|
316
|
-
keyID = keyData[4]
|
317
|
-
break
|
318
|
-
end
|
319
|
-
return replyBadRequest("No keyID found in gpg2 result using uploaded keytext data") if keyID.nil?
|
320
|
-
#
|
321
|
-
# return OK
|
322
|
-
#
|
323
|
-
@statusCode = 200
|
324
|
-
@body << @headerHtml
|
325
|
-
@body << "<h1 class=\"simpleHKP-storedKey\">Stored key: [#{keyID}]</h1>"
|
326
|
-
@body << "<p>key #{keyChanged}</p>"
|
327
|
-
@body << "<h2 class=\"simpleHKP-keyDataKeyID\">Key data for key: [#{keyID}]</h2>"
|
328
|
-
@body << '<pre class="simpleHKP-keyData">'+@keyLookupData[keyID]['colonData']+"</pre>\n"
|
329
|
-
@body << '<pre class="simpleHKP-keyData">'+@keyLookupData[keyID]['humanData']+"</pre>\n"
|
330
|
-
@body << @footer
|
331
|
-
end
|
332
|
-
|
333
|
-
def lookUpKey(queryString)
|
334
|
-
return replyBadRequest("No search field in queryString") unless
|
335
|
-
queryString.has_key?('search')
|
336
|
-
#
|
337
|
-
# normalize the search string
|
338
|
-
#
|
339
|
-
searchString = queryString['search']
|
340
|
-
searchString.gsub!(/0x/,'')
|
341
|
-
searchRegexp = Regexp.new(searchString,
|
342
|
-
Regexp::IGNORECASE | Regexp::MULTILINE)
|
343
|
-
puts searchRegexp if @debug
|
344
|
-
#
|
345
|
-
# (linearly) look through the hash of known keys
|
346
|
-
# looking for the FIRST match
|
347
|
-
#
|
348
|
-
keyID = nil
|
349
|
-
@keyLookupData.each_pair do | key, keyData |
|
350
|
-
next unless keyData['colonData'] =~ searchRegexp
|
351
|
-
puts "FOUND #{key} (#{keyData})" if @debug
|
352
|
-
keyID = key
|
353
|
-
break
|
354
|
-
end
|
355
|
-
return replyNotFound if keyID.nil?
|
356
|
-
|
357
|
-
if queryString.has_key?('options') &&
|
358
|
-
queryString['options'] == 'mr' then
|
359
|
-
#
|
360
|
-
# return the key data in machine readable format
|
361
|
-
#
|
362
|
-
@header = {
|
363
|
-
'Content-Type' => 'application/pgp-keys; charset=utf-8',
|
364
|
-
'Content-Disposition' =>
|
365
|
-
'attachment; filename=' + keyID
|
366
|
-
}
|
367
|
-
puts @header if @debug
|
368
|
-
@body << `gpg2 --homedir #{@keyDir} --armor --export #{keyID}`
|
369
|
-
else
|
370
|
-
#
|
371
|
-
# return the key data for a human to read
|
372
|
-
#
|
373
|
-
@body << @headerHtml
|
374
|
-
@body << @lookupForm
|
375
|
-
@body << '<h1 class="simpleHKP-keyAsckeyId">Key: '+keyID+'</h1>'
|
376
|
-
@body << '<h2 class="simpleHKP-keyDataTitle">Key data:</h2>'
|
377
|
-
@body << '<pre class="simpleHKP-keyData">'
|
378
|
-
@body << @keyLookupData[keyID]['humanData']
|
379
|
-
@body << '</pre>'
|
380
|
-
@body << '<h2 class="simpleHKP-keyAscTitle">Key contents:</h2>'
|
381
|
-
@body << '<pre class="simpleHKP-keyAsc">'
|
382
|
-
@body << `gpg2 --homedir #{@keyDir} --armor --export #{keyID}`
|
383
|
-
@body << '</pre>'
|
384
|
-
@body << @footer
|
385
|
-
end
|
386
|
-
end
|
387
|
-
|
388
|
-
def indexKeys(queryString)
|
389
|
-
return replyBadRequest("No search field in queryString") unless
|
390
|
-
queryString.has_key?('search')
|
391
|
-
#
|
392
|
-
# normalize the search string
|
393
|
-
#
|
394
|
-
searchString = queryString['search']
|
395
|
-
searchString.gsub!(/0x/,'')
|
396
|
-
searchRegexp = Regexp.new(searchString,
|
397
|
-
Regexp::IGNORECASE | Regexp::MULTILINE)
|
398
|
-
puts searchRegexp if @debug
|
399
|
-
#
|
400
|
-
# accumulate the keyIDs of any keys that match the serach
|
401
|
-
#
|
402
|
-
keys = Array.new
|
403
|
-
@keyLookupData.each_pair do | key, keyData |
|
404
|
-
next unless keyData['colonData'] =~ searchRegexp
|
405
|
-
puts "FOUND #{key} (#{keyData})" if @debug
|
406
|
-
keys.push(key)
|
407
|
-
end
|
37
|
+
require 'uri'
|
38
|
+
require 'open3'
|
39
|
+
require 'pp'
|
40
|
+
require 'fileutils'
|
41
|
+
require 'safe_yaml'
|
408
42
|
|
409
|
-
|
410
|
-
|
411
|
-
|
412
|
-
# return a machine readable list of the keys found
|
413
|
-
#
|
414
|
-
@header = { 'Content-Type' => 'text/plain' }
|
415
|
-
@body << "info:1:#{keys.size}\n"
|
416
|
-
keys.each do | aKey |
|
417
|
-
next unless @keyLookupData.has_key?(aKey)
|
418
|
-
keyData = @keyLookupData[aKey]
|
419
|
-
pubData = [ "pub" ]
|
420
|
-
pubData << aKey
|
421
|
-
pubData << keyData['algorithm']
|
422
|
-
pubData << keyData['len']
|
423
|
-
pubData << keyData['created']
|
424
|
-
pubData << keyData['expires']
|
425
|
-
pubData << keyData['flags']
|
426
|
-
@body << pubData.join(':')
|
427
|
-
@body << "\n"
|
428
|
-
uidData = [ "uid" ]
|
429
|
-
uidData << keyData['userID'].gsub(/:/, '\x3a')
|
430
|
-
uidData << keyData['created']
|
431
|
-
uidData << keyData['expires']
|
432
|
-
uidData << keyData['flags']
|
433
|
-
@body << uidData.join(':')
|
434
|
-
@body << "\n"
|
435
|
-
end
|
436
|
-
else
|
437
|
-
#
|
438
|
-
# return a (simple) human readable list of the keys found
|
439
|
-
#
|
440
|
-
@body << @headerHtml
|
441
|
-
@body << @lookupForm
|
442
|
-
@body << '<h1 class="simpleHKP-searchString">Keys matching: ['+searchString+']</h1><ul class="simpleHKP-searchList">'
|
443
|
-
keys.each do | aKey |
|
444
|
-
next unless @keyLookupData.has_key?(aKey)
|
445
|
-
keyData = @keyLookupData[aKey]
|
446
|
-
keyStr = " <li class=\"simpleHKP-searchItem\"><a href=\"lookup?op=get&search=#{aKey}\">#{aKey}: "
|
447
|
-
keyStr << keyData['userID']
|
448
|
-
keyStr << "</a></li>\n"
|
449
|
-
@body << keyStr
|
450
|
-
end
|
451
|
-
@body << '</ul>'
|
452
|
-
@body << @footer
|
453
|
-
end
|
454
|
-
pp @body if @debug
|
455
|
-
end
|
43
|
+
require 'simpleHKP/keys'
|
44
|
+
require 'simpleHKP/identities'
|
45
|
+
require 'simpleHKP/server'
|
456
46
|
|
457
|
-
|
458
|
-
queryHash = Hash.new
|
459
|
-
URI.decode_www_form(env['QUERY_STRING']).each do | aKeyValue |
|
460
|
-
queryHash[aKeyValue[0]] = aKeyValue[1]
|
461
|
-
end
|
462
|
-
queryHash
|
463
|
-
end
|
47
|
+
module SimpleHKP
|
464
48
|
|
465
|
-
|
466
|
-
#
|
467
|
-
# initialize the response parts
|
468
|
-
#
|
469
|
-
@statusCode = 200
|
470
|
-
@header = {"Content-Type" => "text/html; charset=utf-8"}
|
471
|
-
@body = Array.new
|
472
|
-
#
|
473
|
-
# decode the request
|
474
|
-
#
|
475
|
-
begin
|
476
|
-
puts ppEnv(env) if @debug
|
477
|
-
case env['REQUEST_METHOD']
|
478
|
-
when 'POST'
|
479
|
-
case env['REQUEST_PATH']
|
480
|
-
when /add$/i
|
481
|
-
storeKey(env)
|
482
|
-
else
|
483
|
-
replyNotImplemented
|
484
|
-
end
|
485
|
-
when 'GET'
|
486
|
-
case env['REQUEST_PATH']
|
487
|
-
when /add$/i
|
488
|
-
replyUploadForm
|
489
|
-
when /lookup$/i
|
490
|
-
queryString = decodeQueryString(env)
|
491
|
-
if queryString.has_key?('op') then
|
492
|
-
case queryString['op']
|
493
|
-
when /get/i
|
494
|
-
lookUpKey(queryString)
|
495
|
-
when /index/i
|
496
|
-
indexKeys(queryString)
|
497
|
-
else
|
498
|
-
replyLookupForm
|
499
|
-
end
|
500
|
-
else
|
501
|
-
replyBadRequest("No op field in queryString")
|
502
|
-
end
|
503
|
-
when /media\//i
|
504
|
-
replyFile(env)
|
505
|
-
when /reload$/i
|
506
|
-
loadKeys
|
507
|
-
loadHtml
|
508
|
-
replyDefaultBody
|
509
|
-
else
|
510
|
-
replyDefaultBody
|
511
|
-
end
|
512
|
-
else
|
513
|
-
replyBadRequest("Unknown request method")
|
514
|
-
end
|
515
|
-
rescue Exception => exception
|
516
|
-
replyInternalError(env, exception)
|
517
|
-
end
|
518
|
-
#
|
519
|
-
# send the response
|
520
|
-
#
|
521
|
-
if @debug then
|
522
|
-
puts "SimpleHKP reply:"
|
523
|
-
pp @statusCode
|
524
|
-
pp @header
|
525
|
-
puts @body.join("\n")
|
526
|
-
end
|
527
|
-
[ @statusCode, @header, @body.flatten ]
|
528
|
-
end
|
49
|
+
VERSION = "2.0.0"
|
529
50
|
|
530
51
|
end
|
metadata
CHANGED
@@ -1,7 +1,7 @@
|
|
1
1
|
--- !ruby/object:Gem::Specification
|
2
2
|
name: simple-gnupg-keyserver
|
3
3
|
version: !ruby/object:Gem::Version
|
4
|
-
version:
|
4
|
+
version: 2.0.0
|
5
5
|
prerelease:
|
6
6
|
platform: ruby
|
7
7
|
authors:
|
@@ -9,7 +9,7 @@ authors:
|
|
9
9
|
autorequire:
|
10
10
|
bindir: bin
|
11
11
|
cert_chain: []
|
12
|
-
date: 2015-03-
|
12
|
+
date: 2015-03-15 00:00:00.000000000 Z
|
13
13
|
dependencies:
|
14
14
|
- !ruby/object:Gem::Dependency
|
15
15
|
name: rdoc
|
@@ -43,12 +43,12 @@ dependencies:
|
|
43
43
|
- - ~>
|
44
44
|
- !ruby/object:Gem::Version
|
45
45
|
version: '3.13'
|
46
|
-
description: ! "SimpleHKP is a simple Ruby/rack based GnuPG
|
47
|
-
|
48
|
-
|
49
|
-
|
50
|
-
|
51
|
-
|
46
|
+
description: ! "SimpleHKP is a simple Ruby/rack based GnuPG extendedHKP key and \nidentity
|
47
|
+
server packaged as a standard Ruby Gem. \n\nAs such it conforms to an {extended
|
48
|
+
\nversion}[http://stephengaito.github.io/rGem-simple-gnupg-keyserver/] of \n{the
|
49
|
+
OpenPGP HTTP Keyserver Protocol (HKP) \n(draft-shaw-openpgp-hkp-00.txt)}[http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00].\n\nThe
|
50
|
+
{associated \ndocumentation}[https://stephengaito.github.io/rGem-simple-gnupg-keyserver]
|
51
|
+
\nprovides more detail."
|
52
52
|
email:
|
53
53
|
- stephen@perceptisys.co.uk
|
54
54
|
executables: []
|
@@ -65,6 +65,9 @@ files:
|
|
65
65
|
- Rakefile
|
66
66
|
- lib/simpleHKP.rb
|
67
67
|
- lib/simpleHKP/echo.rb
|
68
|
+
- lib/simpleHKP/identities.rb
|
69
|
+
- lib/simpleHKP/keys.rb
|
70
|
+
- lib/simpleHKP/server.rb
|
68
71
|
homepage: https://github.com/stephengaito/rGem-simple-gnupg-keyserver
|
69
72
|
licenses:
|
70
73
|
- MIT
|
@@ -91,5 +94,6 @@ rubyforge_project:
|
|
91
94
|
rubygems_version: 1.8.23
|
92
95
|
signing_key:
|
93
96
|
specification_version: 3
|
94
|
-
summary: SimpleHKP is a simple Ruby/rack based GnuPG
|
97
|
+
summary: SimpleHKP is a simple Ruby/rack based GnuPG extendedHKP key and identity
|
98
|
+
server packaged as a standard Ruby Gem
|
95
99
|
test_files: []
|