Skip to content

Instantly share code, notes, and snippets.

@rb2k
Created December 26, 2009 02:52
Show Gist options
  • Star 0 You must be signed in to star a gist
  • Fork 0 You must be signed in to fork a gist
  • Save rb2k/263821 to your computer and use it in GitHub Desktop.
Save rb2k/263821 to your computer and use it in GitHub Desktop.
require "rubygems"
require "sinatra"
require "pstore"
require "openssl"
require "base64"
configure do
set :data_store, PStore.new("users.pstore")
end
helpers do
def sendpeers
"<Friend Base64Key='123451234512345' nick='NARF_TEST' />"
end
end
get '/community' do
puts "received get request"
#let's check if there is a key
if params["base64key"].nil?
puts "No key received!"
error(400, "No key provided.")
else
puts "The requests key is #{params["base64key"]}"
end
base64key = params["base64key"]
options.data_store.transaction do
if options.data_store[base64key].nil?
error(401, "Unauthorized")
else
#let's update the clients IP
options.data_store[base64key][:last_ip] = @env['REMOTE_ADDR']
end
if params["resp"].nil?
#no response found --> create and ask a challenge
my_challenge = rand(16777215)
options.data_store[base64key]["challenge"] = my_challenge
return "CHALLENGE #{my_challenge}"
else
#response found, let's check if it's the right one
if options.data_store[base64key]["challenge"].nil?
error(401, "No recent challenge for key")
else
#save the challenge to a variable...
my_challenge = options.data_store[base64key]["challenge"]
#...and delete it from the store
options.data_store[base64key]["challenge"] = nil
begin
my_public_key = OpenSSL::PKey::RSA.new("-----BEGIN PUBLIC KEY-----\n#{base64key}-----END PUBLIC KEY-----\n")
rescue Exception
error(400, "Error decoding key")
end
begin
decoded_response = Base64.decode64(params["resp"])
rescue Exception
error(400, "Error decoding response")
end
begin
if (my_public_key.ssh_do_verify(decoded_response, my_challenge)) #(sig, data)
return_value << "<?xml version='1.0'?>\n"
return_value << "<CommunityServerResponse>\n"
if params[:refresh].nil?
return_value << "<RefreshInterval>#{params[:refresh]}</RefreshInterval>";
end
return_value << "<FriendList>\n"
return_value << sendpeers()
return_value << "</FriendList>\n"
return_value << "</CommunityServerResponse>"
end
rescue Exception
error(400, "Something went wrong")
end
end
end
end
post '/community' do
puts "received post request"
#let's check if there is a key
if params["base64key"].nil?
puts "No key received!"
error(400, "No key provided.")
else
puts "The requests key is #{params["base64key"]}"
end
if params["nick"].nil?
puts "No key received!"
error(400, "No nickname provided.")
else
puts "The nickname is #{params["nick"]}"
end
#put the params into nice little variables
base64key = params["base64key"]
nickname = params["nick"]
#write data to the pstore file
options.data_store.transaction do
if options.data_store[base64key].nil?
options.data_store[base64key] = {:nickname => nickname, :last_ip => @env['REMOTE_ADDR']}
puts "Added user to pstore"
return "REGISTRATION_OK"
else
return "REGISTRATION_DUPLICATE"
puts "User was already in pstore"
end
end
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment