summaryrefslogtreecommitdiff
path: root/lib/nickserver/hkp
diff options
context:
space:
mode:
authorAzul <azul@riseup.net>2016-05-25 13:13:30 +0200
committerAzul <azul@riseup.net>2016-05-25 14:13:30 +0200
commit8a81429f0eb8aa5041d47557d0c5b5359bb959e6 (patch)
tree10f5d3db69883c685408edc3365d1e762f13e322 /lib/nickserver/hkp
parent5c0fa0fb7b10820f2956807cb457421bf1e00708 (diff)
copy over all files from rewritten attempt
I started a nickserver from scratch to implement the things that are independent of our choice of stack (eventmachine or other). This commit copies them over and tests both things in parallel.
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