Difference between revisions of "Integration/XMPP/Prosody"

From diaspora* project wiki
Jump to: navigation, search
(Edited English, added code markup.)
Line 2: Line 2:
 
= Integrating Prosody with Diaspora =
 
= Integrating Prosody with Diaspora =
  
Here you will find all you need to install and setup a Prosody XMPP server integrated with Diaspora users database.
+
Here you will find all you need to install and set up a Prosody XMPP server integrated with your Diaspora user database.
This tutorial was developed using Debain 7 but it probably will work well for all GNU Distributions.  
+
This tutorial was developed using Debain 7 but it will probably work well for all GNU Distributions.  
There is several steps and configurations you will need to do, so watch it carefully.
+
There are several steps and configurations you will need to perform, so read the instructions carefully.
  
 
= Understanding =
 
= Understanding =
  
The main goal is setup '''Prosody''' to be capable to compare the password received by the XMPP Client with the hashed password stored on '''Diaspora''' database.
+
The main goal is to set up '''Prosody''' to be capable of comparing the password received by the XMPP client with the hashed password stored on your pod's '''Diaspora''' database.
'''Diaspora''' password hash is done with bcrypt library, so we need to patch '''Prosody''' to do the same with the received password. To do so, we need to install a modified [https://code.google.com/p/prosody-modules/wiki/mod_auth_sql - mod_auth_sql] module available below.
+
'''Diaspora''''s password hash is done with the <tt>bcrypt</tt> library, so we need to patch '''Prosody''' to do the same with the received password. To do so, we need to install a modified [https://code.google.com/p/prosody-modules/wiki/mod_auth_sql - <tt>mod_auth_sql</tt>] module, available below.
  
On this setup '''Prosody''' will use it's own SQL database to store users data like friends, etc. and it will connect on '''Diaspora''' database just to compare passwords. Then two database configurations will be required.
+
In this setup '''Prosody''' will use its own SQL database to store users' data, such as friends, etc. It will connect to the '''Diaspora''' database just to compare passwords. Then two database configurations will be required.
  
 
Follow the tutorial and this should work well.
 
Follow the tutorial and this should work well.
Line 17: Line 17:
 
= SQL =
 
= SQL =
  
Before install '''Prosody''' create a database and user for it. You can do it on the same '''Diaspora''' SQL Server.
+
Before installing '''Prosody''', create a database and a user for it. You can do it on the same '''Diaspora''' SQL server.
Just as '''Diaspora''' you can choose between '''MySQL''' or '''PostgreSQL'''.
+
Just as with '''Diaspora''', you can choose between '''MySQL''' or '''PostgreSQL'''.
  
 
= Prosody =
 
= Prosody =
  
Prosody is a modern XMPP communication server. It aims to be easy to set up and configure, and efficient with system resources. Additionally, for developers it aims to be easy to extend and give a flexible system on which to rapidly develop added functionality, or prototype new protocols.
+
Prosody is a modern XMPP communication server. It aims to be easy to set up and configure, and efficient with system resources. Additionally, it aims to be easy for developers to extend and to provide a flexible system on which to rapidly develop added functionality, or prototype new protocols.
 
* [http://prosody.im Prosody] - XMPP Server
 
* [http://prosody.im Prosody] - XMPP Server
  
 
== Installing Prosody ==
 
== Installing Prosody ==
  
To install '''Prosody''' follow the official instructions described on their official site - [http://prosody.im/download/start - Download]
+
To install '''Prosody''', follow the official instructions described on their official site - [http://prosody.im/download/start - Download]
  
Once '''Prosody''' is installed ten you can proceed.
+
Once '''Prosody''' is installed, you can proceed.
  
== Setup prosody.cfg.lua ==
+
== Set up <tt>prosody.cfg.lua</tt> ==
  
Separated by topics here you have what you need to do on this file:
+
Here is what you need to do to this file, separated under headings:
  
=== modules_enabled ===
+
=== <tt>modules_enabled</tt> ===
  
 
* Disable
 
* Disable
Line 50: Line 50:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
=== Setup and configure SQL ===
+
=== Set up and configure SQL ===
  
The default auth method is '''internal''' and it must be replaced by '''sql'''. But '''sql''' require some configurations like SQL Server, database, user and password to access '''Diaspora''' and '''Prosody''' databases.
+
The default auth method is <tt>internal</tt> and it must be replaced by <tt>sql</tt>. But <tt>sql</tt> requires configuration of SQL server, database, user and password to access '''Diaspora''' and '''Prosody''' databases.
  
 
* Modify
 
* Modify
Line 66: Line 66:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''MySQL Setup'''
+
'''MySQL setup'''
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 73: Line 73:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
'''PostgreSQL Setup'''
+
'''PostgreSQL setup'''
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 80: Line 80:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
* sql
+
* <tt>sql</tt>
  
This is the '''Prosody''' database setup where '''Prosody''' will store users friends lists and it's personal setup. The database user must have wright permission on this;
+
This is the '''Prosody''' database setup in which '''Prosody''' will store users' friend lists and its own setup. The database user must have write permission on this file:
  
* sql_dsp
+
* <tt>sql_dsp</tt>
  
This is the '''Diaspora''' database setup where '''Prosody''' will search the user password. The database user only need read permission.
+
This is the '''Diaspora''' database setup in which '''Prosody''' will search the user password. The database user only needs read permission.
  
=== Setup c2s_require_encryption ===
+
=== Set up <tt>c2s_require_encryption</tt> ===
  
Change it to true, like this:
+
Modify:
  
 
<syntaxhighlight lang="bash">
 
<syntaxhighlight lang="bash">
Line 102: Line 102:
 
</syntaxhighlight>
 
</syntaxhighlight>
  
Replace "your POD domain.foo" by your POD domain. This is very important!
+
Replace <tt>your POD domain.foo</tt> with your pod's domain. This is very important!
  
  
== Modified mod_auth_sql ==
+
== Modify <tt>mod_auth_sql</tt> ==
  
Below you get the entire '''mod_auth_sql''' file.
+
Below you get the entire <tt>mod_auth_sql</tt> file, create a file called <tt>mod_auth_sql</tt> in the '''Prosody''' module's directory and paste the following into it:
Create a file called '''mod_auth_sql''' on '''Prosody''' modules directory and paste this in it.
+
 
On Debian 7 this is '''/usr/lib/prosody/modules/'''.
+
In Debian 7 this directory is <tt>/usr/lib/prosody/modules/</tt>.
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 289: Line 289:
 
== Install bcrypt Lua lib ==
 
== Install bcrypt Lua lib ==
  
The modified '''mod_auth_sql''' require bcrypt lib available. To have so, ru the command below to install it
+
The modified <tt>mod_auth_sql</tt> requires <tt>bcrypt lib</tt> available. To have so, <tt>ru</tt> the command below to install it:
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 297: Line 297:
 
== Restart Prosody ==
 
== Restart Prosody ==
  
To end it all, just restart '''Prosody'''
+
To complete the setup, just restart '''Prosody''':
  
 
<syntaxhighlight lang="lua">
 
<syntaxhighlight lang="lua">
Line 305: Line 305:
 
= Testing =
 
= Testing =
  
Just use your favorite XMMP Client to connect on your '''Diaspora''' POD using your regular account and password.
+
Just use your favorite XMMP client to connect to your '''Diaspora''' pod using your regular Diaspora account and password.

Revision as of 20:24, 26 June 2014

Integrating Prosody with Diaspora

Here you will find all you need to install and set up a Prosody XMPP server integrated with your Diaspora user database. This tutorial was developed using Debain 7 but it will probably work well for all GNU Distributions. There are several steps and configurations you will need to perform, so read the instructions carefully.

Understanding

The main goal is to set up Prosody to be capable of comparing the password received by the XMPP client with the hashed password stored on your pod's Diaspora database. Diaspora's password hash is done with the bcrypt library, so we need to patch Prosody to do the same with the received password. To do so, we need to install a modified - mod_auth_sql module, available below.

In this setup Prosody will use its own SQL database to store users' data, such as friends, etc. It will connect to the Diaspora database just to compare passwords. Then two database configurations will be required.

Follow the tutorial and this should work well.

SQL

Before installing Prosody, create a database and a user for it. You can do it on the same Diaspora SQL server. Just as with Diaspora, you can choose between MySQL or PostgreSQL.

Prosody

Prosody is a modern XMPP communication server. It aims to be easy to set up and configure, and efficient with system resources. Additionally, it aims to be easy for developers to extend and to provide a flexible system on which to rapidly develop added functionality, or prototype new protocols.

Installing Prosody

To install Prosody, follow the official instructions described on their official site - - Download

Once Prosody is installed, you can proceed.

Set up prosody.cfg.lua

Here is what you need to do to this file, separated under headings:

modules_enabled

  • Disable
"saslauth"
  • Enable
"bosh"
"legacyauth"

Set up and configure SQL

The default auth method is internal and it must be replaced by sql. But sql requires configuration of SQL server, database, user and password to access Diaspora and Prosody databases.

  • Modify
authentication = "sql"
  • Add
storage = "sql"

MySQL setup

sql = { driver = "MySQL", database = "prosody_xmpp", username = "prosody_xmpp", password = "pass", host = "localhost" }
sql_dsp = { driver = "MySQL", database = "diaspora_production", username = "diaspora", password = "pass", host = "localhost" }

PostgreSQL setup

sql = { driver = "PostgreSQL", database = "prosody_xmpp", username = "prosody_xmpp", password = "pass", host = "localhost" }
sql_dsp = { driver = "PostgreSQL", database = "diaspora_production", username = "diaspora", password = "pass", host = "localhost" }
  • sql

This is the Prosody database setup in which Prosody will store users' friend lists and its own setup. The database user must have write permission on this file:

  • sql_dsp

This is the Diaspora database setup in which Prosody will search the user password. The database user only needs read permission.

Set up c2s_require_encryption

Modify:

c2s_require_encryption = true

Add to the file

VirtualHost "your POD domain.foo"

Replace your POD domain.foo with your pod's domain. This is very important!


Modify mod_auth_sql

Below you get the entire mod_auth_sql file, create a file called mod_auth_sql in the Prosody module's directory and paste the following into it:

In Debian 7 this directory is /usr/lib/prosody/modules/.

-- Simple SQL Authentication module for Prosody IM
-- Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com>
-- Copyright (C) 2011 Waqas Hussain <waqas20@gmail.com>
--
-- Modified by Anahuac de Paula Gil - anahuac@anahuac.eu
-- This will make prosody able to use Diaspora database users and passwords
-- 25/05/2014

local log = require "util.logger".init("auth_sql");
local new_sasl = require "util.sasl".new;
local DBI = require "DBI"

local connection;
local params = module:get_option("auth_sql", module:get_option("sql_dsp"));

local resolve_relative_path = require "core.configmanager".resolve_relative_path;

local function test_connection()
        if not connection then return nil; end
        if connection:ping() then
                return true;
        else
                module:log("debug", "Database connection closed");
                connection = nil;
        end
end
local function connect()
        if not test_connection() then
                prosody.unlock_globals();
                local dbh, err = DBI.Connect(
                        params.driver, params.database,
                        params.username, params.password,
                        params.host, params.port
                );
                prosody.lock_globals();
                if not dbh then
                        module:log("debug", "Database connection failed: %s", tostring(err));
                        return nil, err;
                end
                module:log("debug", "Successfully connected to database");
                dbh:autocommit(true); -- don't run in transaction
                connection = dbh;
                return connection;
        end
end

do -- process options to get a db connection
        params = params or { driver = "SQLite3" };

        if params.driver == "SQLite3" then
                params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite");
        end

        assert(params.driver and params.database, "Both the SQL driver and the database need to be specified");

        assert(connect());
end

local function getsql(sql, ...)
        if params.driver == "PostgreSQL" then
                sql = sql:gsub("`", "\"");
        end
        if not test_connection() then connect(); end
        -- do prepared statement stuff
        local stmt, err = connection:prepare(sql);
        if not stmt and not test_connection() then error("connection failed"); end
        if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
        -- run query
        local ok, err = stmt:execute(...);
        if not ok and not test_connection() then error("connection failed"); end
        if not ok then return nil, err; end

        return stmt;
end

local function mydebug(value,file)
        fho,err = io.open("/tmp/" .. file,"w")
        fho:write(value)
        fho:write("\n")
        fho:close()
end

local function mydebug2(value)
        fho,err = io.open("/tmp/teste2","w")
        fho:write(value)
        fho:write("\n")
        fho:close()
end

local function getsql_dsp(sql, ...)
        if params.driver == "PostgreSQL" then
                sql = sql:gsub("`", "\"");
        end
        if not test_connection() then connect(); end
        -- do prepared statement stuff
        local stmt, err = connection:prepare(sql);
        if not stmt and not test_connection() then error("connection failed"); end
        if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end
        -- run query
        local ok, err = stmt:execute(...);
        if not ok and not test_connection() then error("connection failed"); end
        if not ok then return nil, err; end

        return stmt;
end


local function get_password(username)
        local stmt, err = getsql_dsp("SELECT encrypted_password FROM users WHERE username = '" .. username .. "'");
        if stmt then
                for row in stmt:rows(true) do
                        return row.encrypted_password;
                end
        end
end


provider = {};

function provider.test_password(username, password)
        local bcrypt = require( "bcrypt" )

        -- pepper imported from diaspora/config/initializers/devise.rb
        local pepper = "065eb8798b181ff0ea2c5c16aee0ff8b70e04e2ee6bd6e08b49da46924223e39127d5335e466207d42bf2a045c12be5f90e92012a4f05f7fc6d9f3c875f4c95b"
        -- adding pepper to the regular password
        local pw_plus_pepper = password .. pepper

        -- Getting password from Diaspora database
        local pw_stored_dsp = get_password(username)

        -- Comparing password. If fail aborts
        return password and assert( bcrypt.verify( pw_plus_pepper, pw_stored_dsp ))

        --return password and get_password(username) == password;
end
function provider.get_password(username)
        return get_password(username);
end
function provider.set_password(username, password)
        return nil, "Setting password is not supported.";
end
function provider.user_exists(username)
        return get_password(username) and true;
end
function provider.create_user(username, password)
        return nil, "Account creation/modification not supported.";
end
function provider.get_sasl_handler()
        local profile = {
                plain = function(sasl, username, realm)
                        local password = get_password(username);
                        if not password then return "", nil; end
                        return password, true;
                end
        };
        return new_sasl(module.host, profile);
end

function provider.users()
        local stmt, err = getsql_dsp("SELECT username FROM user", module.host);
        if stmt then
                local next, state = stmt:rows(true)
                return function()
                        for row in next, state do
                                return row.username;
                        end
                end
        end
        return stmt, err;
end


module:provides("auth", provider);

Install bcrypt Lua lib

The modified mod_auth_sql requires bcrypt lib available. To have so, ru the command below to install it:

luarocks install bcrypt

Restart Prosody

To complete the setup, just restart Prosody:

/etc/init.d/prosody restart

Testing

Just use your favorite XMMP client to connect to your Diaspora pod using your regular Diaspora account and password.