plugins/mod_saslauth.lua
author Matthew Wild <mwild1@gmail.com>
Wed, 01 May 2013 13:54:00 +0100
branchs2s
changeset 5558 774ab5f2efa6
parent 120 ef964468f174
child 278 770a78cd38d7
child 281 826308c07627
permissions -rw-r--r--
Close 's2s' branch
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_sasl = require "util.sasl".new;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    17
48
d0505310aec5 Use xmlns for matching auth tag too
Matthew Wild <mwild1@gmail.com>
parents: 46
diff changeset
    18
add_handler("c2s_unauthed", "auth", xmlns_sasl,
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    19
		function (session, stanza)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    20
			if not session.sasl_handler then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    21
				session.sasl_handler = new_sasl(stanza.attr.mechanism, 
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    22
					function (username, password)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    23
						-- onAuth
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    24
						require "core.usermanager"
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    25
						if usermanager_validate_credentials(session.host, username, password) then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    26
							return true;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    27
						end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    28
						return false;
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    29
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    30
					function (username)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    31
						-- onSuccess
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    32
						local success, err = sessionmanager.make_authenticated(session, username);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    33
						if not success then
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    34
							sessionmanager.destroy_session(session);
52
93e468eb2ffb Fix for destruction of unauthed SASL sessions
Matthew Wild <mwild1@gmail.com>
parents: 48
diff changeset
    35
							return;
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    36
						end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    37
						session.sasl_handler = nil;
99
ba08b8a4eeef Abstract connections with "connection listeners"
Matthew Wild <mwild1@gmail.com>
parents: 52
diff changeset
    38
						session:reset_stream();
38
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    39
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    40
					function (reason)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    41
						-- onFail
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    42
						log("debug", "SASL failure, reason: %s", reason);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    43
					end,
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    44
					function (stanza)
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    45
						-- onWrite
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    46
						log("debug", "SASL writes: %s", tostring(stanza));
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    47
						send(session, stanza);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    48
					end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    49
				);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    50
				session.sasl_handler:feed(stanza);	
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    51
			else
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    52
				error("Client tried to negotiate SASL again", 0);
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    53
			end
Matthew Wild <mwild1@gmail.com>
parents:
diff changeset
    54
			
46
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    55
		end);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    56
		
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    57
add_event_hook("stream-features", 
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    58
					function (session, features)												
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    59
						if not session.username then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    60
							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
    61
								t_insert(features, "<mechanism>PLAIN</mechanism>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    62
							t_insert(features, "</mechanisms>");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    63
						else
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    64
							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
    65
							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
    66
						end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    67
						--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
    68
					end);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    69
					
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    70
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
    71
		function (session, stanza)
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    72
			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
    73
			local resource;
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    74
			if stanza.attr.type == "set" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    75
				local bind = stanza.tags[1];
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    76
				
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    77
				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
    78
					resource = bind:child_with_name("resource");
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    79
					if resource then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    80
						resource = resource[1];
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    81
					end
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
			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
    85
			if not success then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    86
				local reply = st.reply(stanza);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    87
				reply.attr.type = "error";
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    88
				if err == "conflict" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    89
					reply:tag("error", { type = "modify" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    90
						:tag("conflict", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    91
				elseif err == "constraint" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    92
					reply:tag("error", { type = "cancel" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    93
						:tag("resource-constraint", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    94
				elseif err == "auth" then
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    95
					reply:tag("error", { type = "cancel" })
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    96
						:tag("not-allowed", { xmlns = xmlns_stanzas });
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    97
				end
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    98
				send(session, reply);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
    99
			else
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   100
				local reply = st.reply(stanza);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   101
				reply:tag("bind", { xmlns = xmlns_bind})
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   102
					:tag("jid"):text(session.full_jid);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   103
				send(session, reply);
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   104
			end
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
		
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   107
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
   108
		function (session, stanza)
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   109
			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
   110
			send(session, st.reply(stanza));
d6b3f9dbb624 Resource binding, XMPP sessions (whatever they're for...)
Matthew Wild <mwild1@gmail.com>
parents: 38
diff changeset
   111
		end);