summaryrefslogtreecommitdiff
path: root/lib/nickserver/hkp
diff options
context:
space:
mode:
Diffstat (limited to 'lib/nickserver/hkp')
-rw-r--r--lib/nickserver/hkp/fetch_key.rb2
-rw-r--r--lib/nickserver/hkp/fetch_key_info.rb2
-rw-r--r--lib/nickserver/hkp/key_info.rb2
-rw-r--r--lib/nickserver/hkp/parse_key_info.rb4
-rw-r--r--lib/nickserver/hkp/v_index_response.rb96
5 files changed, 101 insertions, 5 deletions
diff --git a/lib/nickserver/hkp/fetch_key.rb b/lib/nickserver/hkp/fetch_key.rb
index 44621d3..55eeefa 100644
--- a/lib/nickserver/hkp/fetch_key.rb
+++ b/lib/nickserver/hkp/fetch_key.rb
@@ -5,7 +5,7 @@ require 'em-http'
# http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00
#
-module Nickserver; module HKP
+module Nickserver; module Hkp
class FetchKey
include EM::Deferrable
diff --git a/lib/nickserver/hkp/fetch_key_info.rb b/lib/nickserver/hkp/fetch_key_info.rb
index 2448bb1..b7481d0 100644
--- a/lib/nickserver/hkp/fetch_key_info.rb
+++ b/lib/nickserver/hkp/fetch_key_info.rb
@@ -4,7 +4,7 @@ require 'em-http'
# used to fetch an array of KeyInfo objects that match the given uid.
#
-module Nickserver; module HKP
+module Nickserver; module Hkp
class FetchKeyInfo
include EM::Deferrable
diff --git a/lib/nickserver/hkp/key_info.rb b/lib/nickserver/hkp/key_info.rb
index adb75d8..dc0443c 100644
--- a/lib/nickserver/hkp/key_info.rb
+++ b/lib/nickserver/hkp/key_info.rb
@@ -9,7 +9,7 @@ require 'cgi'
# format definition of machine readable index output is here:
# http://tools.ietf.org/html/draft-shaw-openpgp-hkp-00#section-5.2
#
-module Nickserver; module HKP
+module Nickserver; module Hkp
class KeyInfo
attr_accessor :uids, :keyid, :algo, :keylen, :creationdate, :expirationdate, :flags
diff --git a/lib/nickserver/hkp/parse_key_info.rb b/lib/nickserver/hkp/parse_key_info.rb
index 8934829..d8abe4f 100644
--- a/lib/nickserver/hkp/parse_key_info.rb
+++ b/lib/nickserver/hkp/parse_key_info.rb
@@ -1,11 +1,11 @@
#
-# Simple parser for HKP KeyInfo responses.
+# 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; module HKP
+module Nickserver; module Hkp
class ParseKeyInfo
# for this regexp to work, the source text must end in a trailing "\n",
diff --git a/lib/nickserver/hkp/v_index_response.rb b/lib/nickserver/hkp/v_index_response.rb
new file mode 100644
index 0000000..865d476
--- /dev/null
+++ b/lib/nickserver/hkp/v_index_response.rb
@@ -0,0 +1,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