very bad registration system for XMPP
You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
 
 

157 lines
4.9 KiB

require_relative 'hyde/hyde'
require 'xmpp4r'
require 'net/smtp'
require 'json'
require 'uri'
require 'openssl'
shitlist_f = File.open(Dir.pwd+"/providers.json", "r")
SHITLIST = shitlist_f.read
shitlist_f.close
def norxondor_gorgonax(email)
# Step 1:
return false unless email.match URI::MailTo::EMAIL_REGEXP
# Step 2:
return false unless (SHITLIST.include? "\"#{(email.match /(?<=@)[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?(?:\.[a-zA-Z0-9](?:[a-zA-Z0-9-]{0,61}[a-zA-Z0-9])?)*\z/)[0]}\"")
return true
end
config_file = File.new Dir.pwd+"/.config.json", "r"
CONFIG = JSON.load(config_file)
config_file.close
SERVER_NAME = CONFIG["service_name"]
SMTP_SERVER = CONFIG["server"]
SMTP_PORT = CONFIG["port"]
SMTP_USER = CONFIG["user"]
SMTP_PASS = CONFIG["pass"]
SMTP_TLS = CONFIG["tls"]
SMTP_AUTH = CONFIG["auth"].to_sym
JABBER_SERVER = CONFIG["jabber-server"]
JABBER_HOST = CONFIG['jabber-host']
JABBER_PORT = CONFIG['jabber-port']
HTTP_SERVER_ROOT = CONFIG['http-server-root']
RATELIMIT = CONFIG['ratelimit']
HTTP_PORT = CONFIG['http-port']
Pending = {}
Pending_by_username = {}
Recent = {}
# Get root path to redirect to
def myroot(req)
if req.ssl? then
return "https://#{HTTP_SERVER_ROOT}"
else
return "http://#{HTTP_SERVER_ROOT}"
end
end
# Send email with given SMTP config
def sendmail(code,email)
smtp = Net::SMTP.new(SMTP_SERVER, SMTP_PORT)
msg_headers = ''
msg_headers << "From: #{SMTP_USER}\r\n"
msg_headers << "To: #{email}\r\n"
msg_headers << "Subject: #{SERVER_NAME} email verification\r\n"
msg_headers << "Date: "+Time.now.to_s+"\r\n"
msg = msg_headers + "\r\nTo finish your account registration, enter the following code: \"#{code}\"\r\n"
SMTP_TLS ? smtp.enable_tls : smtp.disable_tls
puts(smtp.start "localhost", SMTP_USER, SMTP_PASS, SMTP_AUTH)
puts(smtp.send_message msg, SMTP_USER, [email])
end
# Main API server
server = Hyde::Server.new Host: "192.168.1.27", Port: HTTP_PORT do
remap Dir.pwd
index ['index.html']
serve "index.html"
# Serve static shit
path "register" do
preprocess do |ctx|
puts "#{ctx.request.remote_ip} is registering"
puts Dir.pwd+"/static/index.html"
end
remap Dir.pwd+"/static/"
index ['index.html']
serve "*.html"
end
# API itself
path "api" do
# First step
post 'register' do |ctx|
# Where to redirect to
server_uri = myroot ctx.request
# Pending user info and validation key
key = (1..32).map { |x| "0123456789ABCDEF"[(rand()*15).round] }.join
user = ctx.request.query['user']
password = ctx.request.query['password']
email = ctx.request.query['email']
# Expiration is 2 hours from now
expires_on = Time.now+60*60*2
# Match query parameters against given rules
unless user.match /^[\w_-]+$/ and
norxondor_gorgonax(email) and
password.match /^.{8,}$/ then
redirect server_uri+"/register/error.html"
end
# Bounce if user is already pending registration
if Pending_by_username[user] then
redirect server_uri+"/register/error.html"
end
# Bounce if email is recent
email_digest = OpenSSL::Digest.digest("sha256",email)
if Recent[email_digest] then
if Time.now < (Recent[email_digest]+RATELIMIT) then
redirect server_uri+"/register/ratelimit.html"
end
end
# Lock registration for pending user
Pending_by_username[user] = Pending[key] = {
"user" => user,
"password" => password,
"expires_on" => expires_on
}
# Record recent emails that tried registering
Recent[email_digest] = Time.now
begin
# Send email to validate
sendmail(key,email)
redirect server_uri+"/register/validate.html"
rescue Exception => e
# Couldn't send email - delete pending account info
Pending_by_username.delete (Pending.delete key)["user"]
redirect server_uri+"/register/error.html"
end
end
# Second step
post 'validate' do |ctx|
# Where to redirect to
server_uri = myroot ctx.request
# Validation key
key = ctx.request.query['key']
# If validation key matches a user
if Pending.has_key? key then
# ... and if it's not expired
if Pending[key]["expires_on"] < Time.now then
# key has expired
puts "#{ctx.request.remote_ip} expired"
redirect server_uri+"/register/error.html"
end
# register the user
cl = Jabber::Client.new(Jabber::JID.new(Pending[key]["user"]+"@"+JABBER_SERVER))
cl.connect JABBER_HOST, JABBER_PORT
cl.register(Pending[key]["password"])
cl.close
puts "#{ctx.request.remote_ip} successfully verified"
redirect server_uri+"/register/success.html"
else
# key is invalid
puts "#{ctx.request.remote_ip} failed to verify"
redirect server_uri+"/register/error.html"
end
end
end
end
server.start