Created
February 22, 2016 19:32
-
-
Save devilankur18/41dcaa8c3f2e01015855 to your computer and use it in GitHub Desktop.
ejabberd external auth rails ruby script
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
#!/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