summaryrefslogtreecommitdiff
path: root/lib
diff options
context:
space:
mode:
authorelijah <elijah@riseup.net>2013-05-19 22:28:01 -0700
committerelijah <elijah@riseup.net>2013-05-19 22:28:01 -0700
commitf9d6b218be3bdbb2d3c544849b2ab92348d0e394 (patch)
tree71cd7ab6e5e9ffb4571b555324ada743c3d29387 /lib
parent5d2e69ad4f2b6214df52c617f5e6cb23d9f40944 (diff)
many related changes -- allow command line configs, validate addresses, overhaul bootstrap.
Diffstat (limited to 'lib')
-rw-r--r--lib/nickserver.rb1
-rw-r--r--lib/nickserver/config.rb2
-rw-r--r--lib/nickserver/daemon.rb15
-rw-r--r--lib/nickserver/email_address.rb25
-rw-r--r--lib/nickserver/server.rb32
-rw-r--r--lib/nickserver/version.rb2
6 files changed, 63 insertions, 14 deletions
diff --git a/lib/nickserver.rb b/lib/nickserver.rb
index 9e6464e..951dae9 100644
--- a/lib/nickserver.rb
+++ b/lib/nickserver.rb
@@ -1,6 +1,7 @@
require "nickserver/version"
require "nickserver/config"
+require "nickserver/email_address"
require "nickserver/couch/fetch_key"
diff --git a/lib/nickserver/config.rb b/lib/nickserver/config.rb
index b283d8b..be401f5 100644
--- a/lib/nickserver/config.rb
+++ b/lib/nickserver/config.rb
@@ -18,6 +18,8 @@ module Nickserver
attr_accessor :pid_file
attr_accessor :user
attr_accessor :log_file
+ attr_accessor :domain
+ attr_accessor :domains
attr_accessor :loaded
attr_accessor :verbose
diff --git a/lib/nickserver/daemon.rb b/lib/nickserver/daemon.rb
index e0bd527..651c6ce 100644
--- a/lib/nickserver/daemon.rb
+++ b/lib/nickserver/daemon.rb
@@ -67,7 +67,7 @@ module Nickserver
create_pid_file(Config.pid_file, Config.user)
catch_interrupt
redirect_output
- drop_permissions_to(Config.user)
+ drop_permissions_to(Config.user) if Config.user
File.umask 0000
yield
end
@@ -77,7 +77,7 @@ module Nickserver
File.open file, 'w' do |f|
f.write("#{Process.pid}\n")
end
- FileUtils.chown(user, nil, file)
+ FileUtils.chown(user, nil, file) if Process::Sys.getuid == 0
rescue Errno::EACCES
bail "insufficient permission to create to pid file `#{file}`"
rescue Errno::ENOENT
@@ -207,13 +207,22 @@ module Nickserver
when 'status' then ARGV.shift; @command = :status
when 'version' then ARGV.shift; @command = :version
when '--verbose' then ARGV.shift; Config.versbose = true
- when /^-/ then usage("Unknown option: #{ARGV[0].inspect}")
+ when /^-/ then override_default_config(ARGV.shift, ARGV.shift)
else break
end
end
usage("Missing command") unless @command
end
+ def override_default_config(flag, value)
+ flag = flag.sub /^--/, ''
+ if Config.respond_to?("#{flag}=")
+ Config.send("#{flag}=", value)
+ else
+ usage("Unknown option: --#{flag}")
+ end
+ end
+
#
# COMMANDS
#
diff --git a/lib/nickserver/email_address.rb b/lib/nickserver/email_address.rb
new file mode 100644
index 0000000..26053a2
--- /dev/null
+++ b/lib/nickserver/email_address.rb
@@ -0,0 +1,25 @@
+#
+# This rather crazy regexp is from here: http://code.iamcal.com/php/rfc822/
+# Licensed GPLv3
+#
+# It is too liberal, allowing "!@x" as a valid address, for example, but it does
+# follow the specification rather closely.
+#
+
+module Nickserver
+ EmailAddress = begin
+ qtext = '[^\\x0d\\x22\\x5c\\x80-\\xff]'
+ dtext = '[^\\x0d\\x5b-\\x5d\\x80-\\xff]'
+ atom = '[^\\x00-\\x20\\x22\\x28\\x29\\x2c\\x2e\\x3a-\\x3c\\x3e\\x40\\x5b-\\x5d\\x7f-\\xff]+'
+ quoted_pair = '\\x5c[\\x00-\\x7f]'
+ domain_literal = "\\x5b(?:#{dtext}|#{quoted_pair})*\\x5d"
+ quoted_string = "\\x22(?:#{qtext}|#{quoted_pair})*\\x22"
+ domain_ref = atom
+ sub_domain = "(?:#{domain_ref}|#{domain_literal})"
+ word = "(?:#{atom}|#{quoted_string})"
+ domain = "#{sub_domain}(?:\\x2e#{sub_domain})*"
+ local_part = "#{word}(?:\\x2e#{word})*"
+ addr_spec = "#{local_part}\\x40#{domain}"
+ /\A#{addr_spec}\z/n
+ end
+end
diff --git a/lib/nickserver/server.rb b/lib/nickserver/server.rb
index 0bda4f1..2f4d4f0 100644
--- a/lib/nickserver/server.rb
+++ b/lib/nickserver/server.rb
@@ -21,7 +21,7 @@ module Nickserver
#
def self.start(opts={})
Nickserver::Config.load
- options = {:host => '0.0.0.0', :port => Nickserver::Config.port}.merge(opts)
+ options = {:host => '0.0.0.0', :port => Nickserver::Config.port.to_i}.merge(opts)
EM.start_server options[:host], options[:port], Nickserver::Server
end
@@ -34,6 +34,8 @@ module Nickserver
uid = get_uid_from_request
if uid.nil?
send_not_found
+ elsif uid !~ EmailAddress
+ send_error("Not a valid address")
else
send_key(uid)
end
@@ -42,11 +44,11 @@ module Nickserver
private
def send_error(msg = "not supported")
- send_response(:status => 500, :content => msg)
+ send_response(:status => 500, :content => "500 #{msg}\n")
end
- def send_not_found(msg = "404 Not Found")
- send_response(:status => 404, :content => msg)
+ def send_not_found(msg = "Not Found")
+ send_response(:status => 404, :content => "404 #{msg}\n")
end
def send_response(opts = {})
@@ -100,14 +102,24 @@ module Nickserver
# Return true if the user address is for a user of this service provider.
# e.g. if the provider is example.org, then alice@example.org returns true.
#
- # Currently, we rely on whatever hostname the client voluntarily specifies
- # in the headers of the http request.
+ # If 'domain' is not configured, we rely on the Host header of the HTTP request.
#
def local_address?(uid)
- hostname = @http_headers.split(/\0/).grep(/^Host: /).first.split(':')[1].strip.sub(/^nicknym\./, '')
- return uid =~ /^.*@#{Regexp.escape(hostname)}$/
- #rescue
- # false
+ uid_domain = uid.sub(/^.*@(.*)$/, "\\1")
+ if Config.domain
+ return uid_domain == Config.domain
+ else
+ # no domain configured, use Host header
+ host_header = @http_headers.split(/\0/).grep(/^Host: /).first
+ if host_header.nil?
+ send_error("HTTP request must include a Host header.")
+ else
+ host = host_header.split(':')[1].strip.sub(/^nicknym\./, '')
+ return uid_domain == host
+ end
+ end
+ rescue
+ return false
end
end
end \ No newline at end of file
diff --git a/lib/nickserver/version.rb b/lib/nickserver/version.rb
index 6e86d39..1910fe1 100644
--- a/lib/nickserver/version.rb
+++ b/lib/nickserver/version.rb
@@ -1,3 +1,3 @@
module Nickserver
- VERSION = "0.2.0"
+ VERSION = "0.2.1"
end