plugins/mod_saslauth.lua
author Matthew Wild <mwild1@gmail.com>
Sat, 04 Oct 2008 02:15:13 +0100
changeset 46 d6b3f9dbb624
parent 38 3fdfd6e0cb4e
child 48 d0505310aec5
permissions -rw-r--r--
Resource binding, XMPP sessions (whatever they're for...)
Ignore whitespace changes - Everywhere: Within whitespace: At end of lines:
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     1
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     2
local st = require "util.stanza";
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     3
local send = require "core.sessionmanager".send_to_session;
46
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
     4
local sm_bind_resource = require "core.sessionmanager".bind_resource;
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     5
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     6
local usermanager_validate_credentials = require "core.usermanager".validate_credentials;
46
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
     7
local t_concat, t_insert = table.concat, table.insert;
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     8
local tostring = tostring;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
     9
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    10
local log = require "util.logger".init("mod_saslauth");
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    11
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    12
local xmlns_sasl ='urn:ietf:params:xml:ns:xmpp-sasl';
46
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    13
local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind';
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    14
local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas';
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    15
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    16
local new_connhandler = require "net.connhandlers".new;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
local new_sasl = require "util.sasl".new;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    18
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
add_handler("c2s_unauthed", "auth",
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
		function (session, stanza)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
			if not session.sasl_handler then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
				session.sasl_handler = new_sasl(stanza.attr.mechanism, 
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
					function (username, password)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
						-- onAuth
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
						require "core.usermanager"
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
						if usermanager_validate_credentials(session.host, username, password) then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
							return true;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
						end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
						return false;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
					function (username)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
						-- onSuccess
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
						local success, err = sessionmanager.make_authenticated(session, username);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
						if not success then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    35
							sessionmanager.destroy_session(session);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
						end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
						session.sasl_handler = nil;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    38
						session.connhandler = new_connhandler("xmpp-client", session);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
						session.notopen = true;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
					function (reason)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
						-- onFail
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
						log("debug", "SASL failure, reason: %s", reason);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
					function (stanza)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
						-- onWrite
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
						log("debug", "SASL writes: %s", tostring(stanza));
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
						send(session, stanza);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
					end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
				);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
				session.sasl_handler:feed(stanza);	
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
			else
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
				error("Client tried to negotiate SASL again", 0);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
			end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    55
			
46
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    56
		end);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    57
		
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    58
add_event_hook("stream-features", 
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    59
					function (session, features)												
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    60
						if not session.username then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    61
							t_insert(features, "<mechanisms xmlns='urn:ietf:params:xml:ns:xmpp-sasl'>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    62
								t_insert(features, "<mechanism>PLAIN</mechanism>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    63
							t_insert(features, "</mechanisms>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    64
						else
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    65
							t_insert(features, "<bind xmlns='urn:ietf:params:xml:ns:xmpp-bind'><required/></bind>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    66
							t_insert(features, "<session xmlns='urn:ietf:params:xml:ns:xmpp-session'/>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    67
						end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    68
						--send [[<register xmlns="http://jabber.org/features/iq-register"/> ]]
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    69
					end);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    70
					
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    71
add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-bind", 
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    72
		function (session, stanza)
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    73
			log("debug", "Client tried to bind to a resource");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    74
			local resource;
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    75
			if stanza.attr.type == "set" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    76
				local bind = stanza.tags[1];
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    77
				
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    78
				if bind and bind.attr.xmlns == xmlns_bind then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    79
					resource = bind:child_with_name("resource");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    80
					if resource then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    81
						resource = resource[1];
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    82
					end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    83
				end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    84
			end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    85
			local success, err = sm_bind_resource(session, resource);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    86
			if not success then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    87
				local reply = st.reply(stanza);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    88
				reply.attr.type = "error";
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    89
				if err == "conflict" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    90
					reply:tag("error", { type = "modify" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    91
						:tag("conflict", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    92
				elseif err == "constraint" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    93
					reply:tag("error", { type = "cancel" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    94
						:tag("resource-constraint", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    95
				elseif err == "auth" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    96
					reply:tag("error", { type = "cancel" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    97
						:tag("not-allowed", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    98
				end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    99
				send(session, reply);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   100
			else
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   101
				local reply = st.reply(stanza);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   102
				reply:tag("bind", { xmlns = xmlns_bind})
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   103
					:tag("jid"):text(session.full_jid);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   104
				send(session, reply);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   105
			end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   106
		end);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   107
		
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   108
add_iq_handler("c2s", "urn:ietf:params:xml:ns:xmpp-session", 
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   109
		function (session, stanza)
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   110
			log("debug", "Client tried to bind to a resource");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   111
			send(session, st.reply(stanza));
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   112
		end);