31 local xmlns_sasl ='urn:ietf:params:xml:ns:xmpp-sasl'; |
31 local xmlns_sasl ='urn:ietf:params:xml:ns:xmpp-sasl'; |
32 local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind'; |
32 local xmlns_bind ='urn:ietf:params:xml:ns:xmpp-bind'; |
33 local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; |
33 local xmlns_stanzas ='urn:ietf:params:xml:ns:xmpp-stanzas'; |
34 |
34 |
35 local new_sasl = require "util.sasl".new; |
35 local new_sasl = require "util.sasl".new; |
|
36 |
|
37 default_authentication_profile = { |
|
38 plain = function(username, realm) |
|
39 return usermanager_get_password(username, realm), true; |
|
40 end |
|
41 }; |
36 |
42 |
37 local function build_reply(status, ret, err_msg) |
43 local function build_reply(status, ret, err_msg) |
38 local reply = st.stanza(status, {xmlns = xmlns_sasl}); |
44 local reply = st.stanza(status, {xmlns = xmlns_sasl}); |
39 if status == "challenge" then |
45 if status == "challenge" then |
40 log("debug", "%s", ret or ""); |
46 log("debug", "%s", ret or ""); |
99 return session.send(build_reply("failure", "invalid-mechanism")); |
105 return session.send(build_reply("failure", "invalid-mechanism")); |
100 end |
106 end |
101 elseif stanza.attr.mechanism == "ANONYMOUS" then |
107 elseif stanza.attr.mechanism == "ANONYMOUS" then |
102 return session.send(build_reply("failure", "mechanism-too-weak")); |
108 return session.send(build_reply("failure", "mechanism-too-weak")); |
103 end |
109 end |
104 session.sasl_handler = new_sasl(stanza.attr.mechanism, session.host, credentials_callback); |
110 local valid_mechanism = session.sasl_handler:select(stanza.attr.mechanism); |
105 if not session.sasl_handler then |
111 if not valid_mechanism then |
106 return session.send(build_reply("failure", "invalid-mechanism")); |
112 return session.send(build_reply("failure", "invalid-mechanism")); |
107 end |
113 end |
108 elseif not session.sasl_handler then |
114 elseif not session.sasl_handler then |
109 return; -- FIXME ignoring out of order stanzas because ejabberd does |
115 return; -- FIXME ignoring out of order stanzas because ejabberd does |
110 end |
116 end |
116 session.sasl_handler = nil; |
122 session.sasl_handler = nil; |
117 session.send(build_reply("failure", "incorrect-encoding")); |
123 session.send(build_reply("failure", "incorrect-encoding")); |
118 return; |
124 return; |
119 end |
125 end |
120 end |
126 end |
121 local status, ret, err_msg = session.sasl_handler:feed(text); |
127 local status, ret, err_msg = session.sasl_handler:process(text); |
122 handle_status(session, status); |
128 handle_status(session, status); |
123 local s = build_reply(status, ret, err_msg); |
129 local s = build_reply(status, ret, err_msg); |
124 log("debug", "sasl reply: %s", tostring(s)); |
130 log("debug", "sasl reply: %s", tostring(s)); |
125 session.send(s); |
131 session.send(s); |
126 end |
132 end |
136 function (session, features) |
142 function (session, features) |
137 if not session.username then |
143 if not session.username then |
138 if secure_auth_only and not session.secure then |
144 if secure_auth_only and not session.secure then |
139 return; |
145 return; |
140 end |
146 end |
|
147 session.sasl_handler = new_sasl(session.host, default_authentication_profile); |
141 features:tag("mechanisms", mechanisms_attr); |
148 features:tag("mechanisms", mechanisms_attr); |
142 -- TODO: Provide PLAIN only if TLS is active, this is a SHOULD from the introduction of RFC 4616. This behavior could be overridden via configuration but will issuing a warning or so. |
149 -- TODO: Provide PLAIN only if TLS is active, this is a SHOULD from the introduction of RFC 4616. This behavior could be overridden via configuration but will issuing a warning or so. |
143 if config.get(session.host or "*", "core", "anonymous_login") then |
150 if config.get(session.host or "*", "core", "anonymous_login") then |
144 features:tag("mechanism"):text("ANONYMOUS"):up(); |
151 features:tag("mechanism"):text("ANONYMOUS"):up(); |
145 else |
152 else |
146 mechanisms = usermanager_get_supported_methods(session.host or "*"); |
153 for k, v in pairs(session.sasl_handler:mechanisms()) do |
147 for k, v in pairs(mechanisms) do |
154 features:tag("mechanism"):text(v):up(); |
148 features:tag("mechanism"):text(k):up(); |
|
149 end |
155 end |
150 end |
156 end |
151 features:up(); |
157 features:up(); |
152 else |
158 else |
153 features:tag("bind", bind_attr):tag("required"):up():up(); |
159 features:tag("bind", bind_attr):tag("required"):up():up(); |