blob: 865d4769ade25a904eb9dfe32fae5a4da78cbb3d (
plain)
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
|
require 'nickserver/hkp'
require 'nickserver/hkp/key_info'
#
# Simple parser for Hkp KeyInfo responses.
#
# Focus is on simple here. Trying to avoid state and sideeffects.
# Parsing a response with 12 keys and validating them takes 2ms.
# So no need for memoization and making things more complex.
module Nickserver::Hkp
class VIndexResponse
# for this regexp to work, the source text must end in a trailing "\n",
# which the output of sks does.
MATCH_PUB_KEY = /(^pub:.+?\n(^uid:.+?\n)+)/m
# hkp_response -- raw output from a vindex hkp query (machine readable)
def initialize(nick, hkp_response)
@nick = nick.to_s
@vindex_result = hkp_response[:body]
end
def status
if keys.empty?
error_status
else
200
end
end
def keys
key_infos.reject { |key| error_for_key(key) }
end
def msg
if errors.any?
error_messages.join "\n"
else
"Could not fetch keyinfo."
end
end
protected
attr_reader :vindex_result, :nick
def error_status
if errors.any?
500
else
404
end
end
def errors
key_infos.map{|key| error_for_key(key) }.compact
end
def error_messages
key_infos.map do |key|
err = error_for_key(key)
error_message(key, err)
end.compact
end
def key_infos
all_key_infos.select do |key_info|
key_info.uids.include?(nick)
end
end
def all_key_infos
@all_key_infos ||= vindex_result.scan(MATCH_PUB_KEY).map do |match|
KeyInfo.new(match[0])
end
end
def error_message(key, err)
"Ignoring key #{key.keyid} for #{nick}: #{err}" if err
end
def error_for_key(key)
if key.keylen < 2048
"key length is too short."
elsif key.expired?
"key expired."
elsif key.revoked?
"key revoked."
elsif key.disabled?
"key disabled."
elsif key.expirationdate && key.expirationdate < Time.now
"key expired"
end
end
end
end
|