Compare commits
3 Commits
98847ffc51
...
master
Author | SHA1 | Date |
---|---|---|
Yessiest | 9eccd6b74a | |
Yessiest | a1bcbd8402 | |
Yessiest | d580c2cba1 |
|
@ -0,0 +1,21 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title> jabber.adastra7.net </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1> But what is a jabber? </h1>
|
||||||
|
<hr />
|
||||||
|
<p> <blockquote>
|
||||||
|
Extensible Messaging and Presence Protocol (<a href="https://xmpp.org">XMPP</a>, originally named <a href="https://xmpp.org">Jabber</a>) is an open communication protocol designed for instant messaging (IM), presence information, and contact list maintenance.
|
||||||
|
</blockquote> </p>
|
||||||
|
<h2> What's a good client for it? </h2>
|
||||||
|
<p>
|
||||||
|
Generally speaking, Gajim is the most modern one, Dyno is the most stable one, and Conversations (or forks like Blabber.im) are the most stable and feature rich ones for Android.
|
||||||
|
</p>
|
||||||
|
<h2> How do i log in? </h2>
|
||||||
|
<p>
|
||||||
|
First, you need to <a href="/register">register</a> your account. Then you can log in with your credentials, such as username@adastra7.net (this is what is called a JID, not an email address) and your password of choice. Your client shuold automatically connect to adastra7.net at port 5222.
|
||||||
|
</p>
|
||||||
|
</body>
|
||||||
|
</html>
|
File diff suppressed because one or more lines are too long
78
sentry.rb
78
sentry.rb
|
@ -3,10 +3,21 @@ require 'xmpp4r'
|
||||||
require 'net/smtp'
|
require 'net/smtp'
|
||||||
require 'json'
|
require 'json'
|
||||||
require 'uri'
|
require 'uri'
|
||||||
|
require 'openssl'
|
||||||
|
|
||||||
norxondor_gorgonax = URI::MailTo::EMAIL_REGEXP
|
shitlist_f = File.open(Dir.pwd+"/providers.json", "r")
|
||||||
|
SHITLIST = shitlist_f.read
|
||||||
CONFIG = JSON.load_file(Dir.pwd+"/.config.json")
|
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"]
|
SERVER_NAME = CONFIG["service_name"]
|
||||||
SMTP_SERVER = CONFIG["server"]
|
SMTP_SERVER = CONFIG["server"]
|
||||||
|
@ -14,14 +25,20 @@ SMTP_PORT = CONFIG["port"]
|
||||||
SMTP_USER = CONFIG["user"]
|
SMTP_USER = CONFIG["user"]
|
||||||
SMTP_PASS = CONFIG["pass"]
|
SMTP_PASS = CONFIG["pass"]
|
||||||
SMTP_TLS = CONFIG["tls"]
|
SMTP_TLS = CONFIG["tls"]
|
||||||
SMTP_STARTTLS = CONFIG["starttls"]
|
|
||||||
SMTP_AUTH = CONFIG["auth"].to_sym
|
SMTP_AUTH = CONFIG["auth"].to_sym
|
||||||
JABBER_SERVER = CONFIG["jabber-server"]
|
JABBER_SERVER = CONFIG["jabber-server"]
|
||||||
|
JABBER_HOST = CONFIG['jabber-host']
|
||||||
|
JABBER_PORT = CONFIG['jabber-port']
|
||||||
HTTP_SERVER_ROOT = CONFIG['http-server-root']
|
HTTP_SERVER_ROOT = CONFIG['http-server-root']
|
||||||
|
RATELIMIT = CONFIG['ratelimit']
|
||||||
|
HTTP_PORT = CONFIG['http-port']
|
||||||
|
|
||||||
Pending = {}
|
Pending = {}
|
||||||
Pending_by_username = {}
|
Pending_by_username = {}
|
||||||
|
|
||||||
|
Recent = {}
|
||||||
|
|
||||||
|
# Get root path to redirect to
|
||||||
def myroot(req)
|
def myroot(req)
|
||||||
if req.ssl? then
|
if req.ssl? then
|
||||||
return "https://#{HTTP_SERVER_ROOT}"
|
return "https://#{HTTP_SERVER_ROOT}"
|
||||||
|
@ -30,9 +47,7 @@ def myroot(req)
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
||||||
def register(username,password)
|
# Send email with given SMTP config
|
||||||
cl = Jabber::Client.new(Jabber::JID.new(
|
|
||||||
|
|
||||||
def sendmail(code,email)
|
def sendmail(code,email)
|
||||||
smtp = Net::SMTP.new(SMTP_SERVER, SMTP_PORT)
|
smtp = Net::SMTP.new(SMTP_SERVER, SMTP_PORT)
|
||||||
msg_headers = ''
|
msg_headers = ''
|
||||||
|
@ -42,12 +57,16 @@ def sendmail(code,email)
|
||||||
msg_headers << "Date: "+Time.now.to_s+"\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"
|
msg = msg_headers + "\r\nTo finish your account registration, enter the following code: \"#{code}\"\r\n"
|
||||||
SMTP_TLS ? smtp.enable_tls : smtp.disable_tls
|
SMTP_TLS ? smtp.enable_tls : smtp.disable_tls
|
||||||
SMTP_STARTTLS ? smtp.enable_starttls : smtp.disable_starttls
|
|
||||||
puts(smtp.start "localhost", SMTP_USER, SMTP_PASS, SMTP_AUTH)
|
puts(smtp.start "localhost", SMTP_USER, SMTP_PASS, SMTP_AUTH)
|
||||||
puts(smtp.send_message msg, SMTP_USER, [email])
|
puts(smtp.send_message msg, SMTP_USER, [email])
|
||||||
end
|
end
|
||||||
|
|
||||||
server = Hyde::Server.new Port: 8001 do
|
# 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
|
path "register" do
|
||||||
preprocess do |ctx|
|
preprocess do |ctx|
|
||||||
puts "#{ctx.request.remote_ip} is registering"
|
puts "#{ctx.request.remote_ip} is registering"
|
||||||
|
@ -57,51 +76,78 @@ server = Hyde::Server.new Port: 8001 do
|
||||||
index ['index.html']
|
index ['index.html']
|
||||||
serve "*.html"
|
serve "*.html"
|
||||||
end
|
end
|
||||||
|
# API itself
|
||||||
path "api" do
|
path "api" do
|
||||||
|
# First step
|
||||||
post 'register' do |ctx|
|
post 'register' do |ctx|
|
||||||
|
# Where to redirect to
|
||||||
server_uri = myroot ctx.request
|
server_uri = myroot ctx.request
|
||||||
# Add pending user
|
# Pending user info and validation key
|
||||||
key = (1..32).map { |x| "0123456789ABCDEF"[(rand()*15).round] }.join
|
key = (1..32).map { |x| "0123456789ABCDEF"[(rand()*15).round] }.join
|
||||||
user = ctx.request.query['user']
|
user = ctx.request.query['user']
|
||||||
password = ctx.request.query['password']
|
password = ctx.request.query['password']
|
||||||
email = ctx.request.query['email']
|
email = ctx.request.query['email']
|
||||||
|
# Expiration is 2 hours from now
|
||||||
expires_on = Time.now+60*60*2
|
expires_on = Time.now+60*60*2
|
||||||
|
# Match query parameters against given rules
|
||||||
unless user.match /^[\w_-]+$/ and
|
unless user.match /^[\w_-]+$/ and
|
||||||
email.match norxondor_gorgonax and
|
norxondor_gorgonax(email) and
|
||||||
password.match /^.{8,}$/ then
|
password.match /^.{8,}$/ then
|
||||||
redirect server_uri+"/register/error.html"
|
redirect server_uri+"/register/error.html"
|
||||||
end
|
end
|
||||||
|
# Bounce if user is already pending registration
|
||||||
if Pending_by_username[user] then
|
if Pending_by_username[user] then
|
||||||
redirect server_uri+"/register/error.html"
|
redirect server_uri+"/register/error.html"
|
||||||
end
|
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] = {
|
Pending_by_username[user] = Pending[key] = {
|
||||||
"user" => user,
|
"user" => user,
|
||||||
"password" => password,
|
"password" => password,
|
||||||
"expires_on" => expires_on
|
"expires_on" => expires_on
|
||||||
}
|
}
|
||||||
|
# Record recent emails that tried registering
|
||||||
|
Recent[email_digest] = Time.now
|
||||||
begin
|
begin
|
||||||
|
# Send email to validate
|
||||||
sendmail(key,email)
|
sendmail(key,email)
|
||||||
redirect server_uri+"/register/validate.html"
|
redirect server_uri+"/register/validate.html"
|
||||||
rescue Exception => e
|
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"
|
redirect server_uri+"/register/error.html"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
# Second step
|
||||||
post 'validate' do |ctx|
|
post 'validate' do |ctx|
|
||||||
|
# Where to redirect to
|
||||||
server_uri = myroot ctx.request
|
server_uri = myroot ctx.request
|
||||||
|
# Validation key
|
||||||
key = ctx.request.query['key']
|
key = ctx.request.query['key']
|
||||||
|
# If validation key matches a user
|
||||||
if Pending.has_key? key then
|
if Pending.has_key? key then
|
||||||
if Pending[key].expires_on < Time.now then
|
# ... and if it's not expired
|
||||||
puts "#{Pending.delete key} expired"
|
if Pending[key]["expires_on"] < Time.now then
|
||||||
|
# key has expired
|
||||||
|
puts "#{ctx.request.remote_ip} expired"
|
||||||
redirect server_uri+"/register/error.html"
|
redirect server_uri+"/register/error.html"
|
||||||
end
|
end
|
||||||
|
# register the user
|
||||||
cl = Jabber::Client.new(Jabber::JID.new(Pending[key]["user"]+"@"+JABBER_SERVER))
|
cl = Jabber::Client.new(Jabber::JID.new(Pending[key]["user"]+"@"+JABBER_SERVER))
|
||||||
cl.connect
|
cl.connect JABBER_HOST, JABBER_PORT
|
||||||
cl.register(Pending[key]["password"])
|
cl.register(Pending[key]["password"])
|
||||||
cl.close
|
cl.close
|
||||||
puts "#{Pending[key]} successfully verified"
|
puts "#{ctx.request.remote_ip} successfully verified"
|
||||||
redirect server_uri+"/register/success.html"
|
redirect server_uri+"/register/success.html"
|
||||||
else
|
else
|
||||||
puts "#{Pending[key]} failed to verify"
|
# key is invalid
|
||||||
|
puts "#{ctx.request.remote_ip} failed to verify"
|
||||||
redirect server_uri+"/register/error.html"
|
redirect server_uri+"/register/error.html"
|
||||||
end
|
end
|
||||||
end
|
end
|
||||||
|
|
|
@ -0,0 +1,12 @@
|
||||||
|
<!DOCTYPE html>
|
||||||
|
<html>
|
||||||
|
<head>
|
||||||
|
<title> Registration form </title>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
<h1> Oops! </h1>
|
||||||
|
<hr />
|
||||||
|
<p> You have been ratelimited! </p>
|
||||||
|
</body>
|
||||||
|
</html>
|
||||||
|
|
Loading…
Reference in New Issue