Skip to content

Instantly share code, notes, and snippets.

@devilankur18
Created February 22, 2016 19:32
Show Gist options
  • Save devilankur18/41dcaa8c3f2e01015855 to your computer and use it in GitHub Desktop.
Save devilankur18/41dcaa8c3f2e01015855 to your computer and use it in GitHub Desktop.
ejabberd external auth rails ruby script
#!/usr/bin/env ruby
require 'logger'
require 'rest_client'
require 'rexml/document'
include REXML
$stdout.sync = true
$stdin.sync = true
path = "/var/log/ejabberd/auth.log"
file = File.open(path, File::WRONLY | File::APPEND | File::CREAT)
file.sync = true
$logger = Logger.new(file)
$logger.level = Logger::DEBUG
$logger.info "#{Process.pid}: Starting ejabberd authentication service"
# config_file = '/etc/ejabberd/ssconfig.cfg'
def getOption(option)
config_file = '/usr/local/etc/ejabberd/ejabberd.yml'
output = "Undefined"
File.open(config_file, 'r') do |f1|
while line = f1.gets
line = line.gsub(/\n/,'')
if line.match(/^#/)
#Comments
elsif line.match(/^#{option}/)
output = line.gsub(/#{option}/,'')
break
end
end
end
$logger.debug "#{option} : #{output}"
return output
end
$cookie_name = getOption("cookie_name=")
$force_ssl = getOption("force_ssl=")
if $force_ssl=="true"
$http="https"
else
$http="http"
end
def auth(username,domain,password)
#[TEST ONLY] Allow everybody
#return true
#[TEST] Admin password
#if username == "admin" and password == "pass"
# return true
#end
accessByPasswordUrl = $http + "://" + getWebDomainUrlFromDomain(domain) + "/users/sign_in"
begin
response = RestClient.post accessByPasswordUrl, :user => { :email => username , :password => password }
return response.code == 201
rescue => e
if e.class.name == "RestClient::Found" &&
e.http_code == 302 &&
e.http_body =~ /home/
return true
end
$logger.error "#{Process.pid}: Exception in auth(username, password)"
$logger.error "#{Process.pid}: #{e.class.name}: #{e.message}"
return false
end
end
def authByCookie(username, domain, cookie)
begin
accessByCookieUrl = $http + "://" + getWebDomainUrlFromDomain(domain) + "/api/me"
response = RestClient.get accessByCookieUrl, :cookies => {:"#{$cookie_name}" => cookie}
doc = REXML::Document.new(response.body)
slug = ""
doc.elements.each('user/slug') do |ele|
slug = ele.text
end
if username != "" and username == slug
return true
else
return false
end
rescue => e
unless e.class.name == "RestClient::Unauthorized" and e.message == "401 Unauthorized"
$logger.error "#{Process.pid}: Exception in authByCookie(username, cookie)"
$logger.error "#{Process.pid}: #{e.class.name}: #{e.message}"
end
return false
end
end
def validateParameters(username,domain,password)
if !username or !password or !domain
return false
end
if (username.gsub(/\s+/, "")=="") or (password.gsub(/\s+/, "")=="") or (domain.gsub(/\s+/, "")=="")
return false
end
return true
end
def getWebDomainUrlFromDomain(domain)
web_domain = getOption(domain + "=");
if (web_domain != "Undefined")
return web_domain
else
return domain
end
end
loop do
begin
$logger.debug "Staring loop"
$stdin.eof? # wait for input
# start = Time.now
msg = $stdin.read(2)
length = msg.unpack('n').first
msg = $stdin.read(length)
cmd, *data = msg.split(":")
$logger.info "#{Process.pid}: Incoming Request: '#{cmd}'"
success = case cmd
when "auth"
$logger.info "#{Process.pid}: Authenticating #{data[0]}@#{data[1]}"
#Parameters basic validation: validateParameters(username,domain,password)
if !validateParameters(data[0],data[1],data[2])
$logger.info "#{Process.pid}: Invalid parameters"
return false
end
#Select authorization condition for LOGIN
#Authentication methods: user/password or user/cookie
password = data[2]
if password.split(">>")[0]=="AuthenticationByCookie"
cookie = password.split(">>")[1]
$logger.info "#{Process.pid}: With userJid #{data[0]}@#{data[1]} and cookie #{cookie}"
authByCookie(data[0], data[1], cookie)
else
$logger.info "#{Process.pid}: With userJid #{data[0]}@#{data[1]} and password ******"
#$logger.info "#{Process.pid}: With userJid #{data[0]}@#{data[1]} and password #{data[2]}"
auth(data[0], data[1], data[2])
end
when "isuser"
$logger.info "#{Process.pid}: Isuser with userJid: #{data[0]}@#{data[1]}"
#Authorization condition for ISUSER (Add buddys)
true
else
false
end
bool = success ? 1 : 0
$stdout.write [2, bool].pack("nn")
$logger.info "#{Process.pid}: Response: #{success ? "success" : "failure"}"
rescue => e
$logger.error "#{Process.pid}: #{e.class.name}: #{e.message}"
$logger.error "#{Process.pid}: " + e.backtrace.join("\n\t")
$logger.error "#{Process.pid}: Finish process"
break
end
end
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment