Software /
code /
prosody-modules
Annotate
mod_auth_sql/mod_auth_sql.lua @ 455:52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Sat, 15 Oct 2011 13:43:37 +0200 |
parent | 399:4e0d36941ba1 |
child | 461:bbea8081c865 |
rev | line source |
---|---|
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
1 -- Simple SQL Authentication module for Prosody IM |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
2 -- Copyright (C) 2011 Tomasz Sterna <tomek@xiaoka.com> |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
3 -- Copyright (C) 2011 Waqas Hussain <waqas20@gmail.com> |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
4 -- |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
5 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
6 local log = require "util.logger".init("auth_sql"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
7 local new_sasl = require "util.sasl".new; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
8 local nodeprep = require "util.encodings".stringprep.nodeprep; |
398 | 9 local DBI = require "DBI" |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
10 local crypt = require "crypt"; |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
11 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
12 local connection; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
13 local params = module:get_option("sql"); |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
14 local host = module.host; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
15 local realm = module:get_option_string("realm", host); |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
16 local mitm_mode = module:get_option_boolean("mitm_mode"); |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
17 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
18 local resolve_relative_path = require "core.configmanager".resolve_relative_path; |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
19 local datamanager = require "util.datamanager"; |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
20 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
21 local function test_connection() |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
22 if not connection then return nil; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
23 if connection:ping() then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
24 return true; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
25 else |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
26 module:log("debug", "Database connection closed"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
27 connection = nil; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
28 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
29 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
30 local function connect() |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
31 if not test_connection() then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
32 prosody.unlock_globals(); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
33 local dbh, err = DBI.Connect( |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
34 params.driver, params.database, |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
35 params.username, params.password, |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
36 params.host, params.port |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
37 ); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
38 prosody.lock_globals(); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
39 if not dbh then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
40 module:log("debug", "Database connection failed: %s", tostring(err)); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
41 return nil, err; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
42 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
43 module:log("debug", "Successfully connected to database"); |
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
44 dbh:autocommit(true); -- don't run in transaction |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
45 connection = dbh; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
46 return connection; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
47 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
48 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
49 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
50 do -- process options to get a db connection |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
51 params = params or { driver = "SQLite3" }; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
52 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
53 if params.driver == "SQLite3" then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
54 params.database = resolve_relative_path(prosody.paths.data or ".", params.database or "prosody.sqlite"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
55 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
56 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
57 assert(params.driver and params.database, "Both the SQL driver and the database need to be specified"); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
58 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
59 assert(connect()); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
60 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
61 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
62 local function getsql(sql, ...) |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
63 if params.driver == "PostgreSQL" then |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
64 sql = sql:gsub("`", "\""); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
65 end |
371
c416db434e5b
Do not run in transaction.
Tomasz Sterna <tomek@xiaoka.com>
parents:
367
diff
changeset
|
66 if not test_connection() then connect(); end |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
67 -- do prepared statement stuff |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
68 local stmt, err = connection:prepare(sql); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
69 if not stmt and not test_connection() then error("connection failed"); end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
70 if not stmt then module:log("error", "QUERY FAILED: %s %s", err, debug.traceback()); return nil, err; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
71 -- run query |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
72 local ok, err = stmt:execute(...); |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
73 if not ok and not test_connection() then error("connection failed"); end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
74 if not ok then return nil, err; end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
75 |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
76 return stmt; |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
77 end |
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
78 |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
79 local function get_password(username) |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
80 local stmt, err = getsql("SELECT `password` FROM `users` WHERE `email`=?", username .. "@" .. realm); |
399
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
81 if stmt then |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
82 for row in stmt:rows(true) do |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
83 return row.password; |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
84 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
85 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
86 end |
4e0d36941ba1
mod_auth_sql: More cleanup.
Waqas Hussain <waqas20@gmail.com>
parents:
398
diff
changeset
|
87 |
398 | 88 provider = { name = "sql" }; |
367
a6dee73a11e7
Implemented password and user existence check in mod_auth_sql
Tomasz Sterna <tomek@xiaoka.com>
parents:
366
diff
changeset
|
89 |
398 | 90 function provider.test_password(username, password) |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
91 local local_data = datamanager.load(username, realm, "accounts") or {}; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
92 if data.password == password then return true end |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
93 local dirty; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
94 local hash = data.crypted_password; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
95 if not hash then |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
96 hash = get_password(username); |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
97 if hash then |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
98 data.crypted_password = hash; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
99 dirty = true; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
100 else |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
101 return false |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
102 end |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
103 end |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
104 local ok = password and crypt(password, hash) == password; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
105 if ok and mitm_mode then |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
106 local_data.password = password; |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
107 dirty = true |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
108 end |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
109 if dirty then |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
110 datamanager.store(username, realm, "accounts", local_data); |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
111 end |
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
112 return ok |
398 | 113 end |
114 function provider.get_password(username) | |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
115 return nil, "Getting password is not supported."; |
398 | 116 end |
117 function provider.set_password(username, password) | |
118 return nil, "Setting password is not supported."; | |
354
f24998ec7f8d
Implemented basic SQL authentication module.
Tomasz Sterna <tomek@xiaoka.com>
parents:
diff
changeset
|
119 end |
398 | 120 function provider.user_exists(username) |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
121 return datamanager.load(username, realm, "accounts") or get_password(username) and true; |
398 | 122 end |
123 function provider.create_user(username, password) | |
124 return nil, "Account creation/modification not supported."; | |
125 end | |
126 function provider.get_sasl_handler() | |
127 local profile = { | |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
128 plain_test = function(sasl, username, password, realm) |
398 | 129 local prepped_username = nodeprep(username); |
130 if not prepped_username then | |
131 module:log("debug", "NODEprep failed on username: %s", username); | |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
132 return nil; |
398 | 133 end |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
134 return provider.test_password(prepped_username, password); |
398 | 135 end |
136 }; | |
455
52f2188ec47d
mod_default_vcard: Sets initial vCard from data enterd on registration
Kim Alvefur <zash@zash.se>
parents:
399
diff
changeset
|
137 return new_sasl(host, profile); |
398 | 138 end |
139 | |
140 module:add_item("auth-provider", provider); |