simple-gnupg-keyserver 1.3.0 → 2.0.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- 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: []
|