Software /
code /
prosody
Comparison
plugins/mod_s2s/mod_s2s.lua @ 5776:bd0ff8ae98a8
Remove all trailing whitespace
author | Florian Zeitz <florob@babelmonkeys.de> |
---|---|
date | Fri, 09 Aug 2013 17:48:21 +0200 |
parent | 5770:7722372aa087 |
child | 5800:3a48acbcb7f3 |
comparison
equal
deleted
inserted
replaced
5775:a6c2b8933507 | 5776:bd0ff8ae98a8 |
---|---|
1 -- Prosody IM | 1 -- Prosody IM |
2 -- Copyright (C) 2008-2010 Matthew Wild | 2 -- Copyright (C) 2008-2010 Matthew Wild |
3 -- Copyright (C) 2008-2010 Waqas Hussain | 3 -- Copyright (C) 2008-2010 Waqas Hussain |
4 -- | 4 -- |
5 -- This project is MIT/X11 licensed. Please see the | 5 -- This project is MIT/X11 licensed. Please see the |
6 -- COPYING file in the source package for more information. | 6 -- COPYING file in the source package for more information. |
7 -- | 7 -- |
8 | 8 |
9 module:set_global(); | 9 module:set_global(); |
153 end | 153 end |
154 | 154 |
155 -- Stream is authorised, and ready for normal stanzas | 155 -- Stream is authorised, and ready for normal stanzas |
156 function mark_connected(session) | 156 function mark_connected(session) |
157 local sendq, send = session.sendq, session.sends2s; | 157 local sendq, send = session.sendq, session.sends2s; |
158 | 158 |
159 local from, to = session.from_host, session.to_host; | 159 local from, to = session.from_host, session.to_host; |
160 | 160 |
161 session.log("info", "%s s2s connection %s->%s complete", session.direction, from, to); | 161 session.log("info", "%s s2s connection %s->%s complete", session.direction, from, to); |
162 | 162 |
163 local event_data = { session = session }; | 163 local event_data = { session = session }; |
164 if session.type == "s2sout" then | 164 if session.type == "s2sout" then |
165 fire_global_event("s2sout-established", event_data); | 165 fire_global_event("s2sout-established", event_data); |
171 end; | 171 end; |
172 | 172 |
173 fire_global_event("s2sin-established", event_data); | 173 fire_global_event("s2sin-established", event_data); |
174 hosts[to].events.fire_event("s2sin-established", event_data); | 174 hosts[to].events.fire_event("s2sin-established", event_data); |
175 end | 175 end |
176 | 176 |
177 if session.direction == "outgoing" then | 177 if session.direction == "outgoing" then |
178 if sendq then | 178 if sendq then |
179 session.log("debug", "sending %d queued stanzas across new outgoing connection to %s", #sendq, session.to_host); | 179 session.log("debug", "sending %d queued stanzas across new outgoing connection to %s", #sendq, session.to_host); |
180 for i, data in ipairs(sendq) do | 180 for i, data in ipairs(sendq) do |
181 send(data[1]); | 181 send(data[1]); |
182 sendq[i] = nil; | 182 sendq[i] = nil; |
183 end | 183 end |
184 session.sendq = nil; | 184 session.sendq = nil; |
185 end | 185 end |
186 | 186 |
187 session.ip_hosts = nil; | 187 session.ip_hosts = nil; |
188 session.srv_hosts = nil; | 188 session.srv_hosts = nil; |
189 end | 189 end |
190 end | 190 end |
191 | 191 |
216 session.hosts[host].authed = true; | 216 session.hosts[host].authed = true; |
217 else | 217 else |
218 return false; | 218 return false; |
219 end | 219 end |
220 session.log("debug", "connection %s->%s is now authenticated for %s", session.from_host, session.to_host, host); | 220 session.log("debug", "connection %s->%s is now authenticated for %s", session.from_host, session.to_host, host); |
221 | 221 |
222 mark_connected(session); | 222 mark_connected(session); |
223 | 223 |
224 return true; | 224 return true; |
225 end | 225 end |
226 | 226 |
227 --- Helper to check that a session peer's certificate is valid | 227 --- Helper to check that a session peer's certificate is valid |
228 local function check_cert_status(session) | 228 local function check_cert_status(session) |
275 | 275 |
276 local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; | 276 local xmlns_xmpp_streams = "urn:ietf:params:xml:ns:xmpp-streams"; |
277 | 277 |
278 function stream_callbacks.streamopened(session, attr) | 278 function stream_callbacks.streamopened(session, attr) |
279 local send = session.sends2s; | 279 local send = session.sends2s; |
280 | 280 |
281 session.version = tonumber(attr.version) or 0; | 281 session.version = tonumber(attr.version) or 0; |
282 | 282 |
283 -- TODO: Rename session.secure to session.encrypted | 283 -- TODO: Rename session.secure to session.encrypted |
284 if session.secure == false then | 284 if session.secure == false then |
285 session.secure = true; | 285 session.secure = true; |
286 | 286 |
287 local sock = session.conn:socket(); | 287 local sock = session.conn:socket(); |
296 end | 296 end |
297 end | 297 end |
298 | 298 |
299 if session.direction == "incoming" then | 299 if session.direction == "incoming" then |
300 -- Send a reply stream header | 300 -- Send a reply stream header |
301 | 301 |
302 -- Validate to/from | 302 -- Validate to/from |
303 local to, from = nameprep(attr.to), nameprep(attr.from); | 303 local to, from = nameprep(attr.to), nameprep(attr.from); |
304 if not to and attr.to then -- COMPAT: Some servers do not reliably set 'to' (especially on stream restarts) | 304 if not to and attr.to then -- COMPAT: Some servers do not reliably set 'to' (especially on stream restarts) |
305 session:close({ condition = "improper-addressing", text = "Invalid 'to' address" }); | 305 session:close({ condition = "improper-addressing", text = "Invalid 'to' address" }); |
306 return; | 306 return; |
307 end | 307 end |
308 if not from and attr.from then -- COMPAT: Some servers do not reliably set 'from' (especially on stream restarts) | 308 if not from and attr.from then -- COMPAT: Some servers do not reliably set 'from' (especially on stream restarts) |
309 session:close({ condition = "improper-addressing", text = "Invalid 'from' address" }); | 309 session:close({ condition = "improper-addressing", text = "Invalid 'from' address" }); |
310 return; | 310 return; |
311 end | 311 end |
312 | 312 |
313 -- Set session.[from/to]_host if they have not been set already and if | 313 -- Set session.[from/to]_host if they have not been set already and if |
314 -- this session isn't already authenticated | 314 -- this session isn't already authenticated |
315 if session.type == "s2sin_unauthed" and from and not session.from_host then | 315 if session.type == "s2sin_unauthed" and from and not session.from_host then |
316 session.from_host = from; | 316 session.from_host = from; |
317 elseif from ~= session.from_host then | 317 elseif from ~= session.from_host then |
322 session.to_host = to; | 322 session.to_host = to; |
323 elseif to ~= session.to_host then | 323 elseif to ~= session.to_host then |
324 session:close({ condition = "improper-addressing", text = "New stream 'to' attribute does not match original" }); | 324 session:close({ condition = "improper-addressing", text = "New stream 'to' attribute does not match original" }); |
325 return; | 325 return; |
326 end | 326 end |
327 | 327 |
328 -- For convenience we'll put the sanitised values into these variables | 328 -- For convenience we'll put the sanitised values into these variables |
329 to, from = session.to_host, session.from_host; | 329 to, from = session.to_host, session.from_host; |
330 | 330 |
331 session.streamid = uuid_gen(); | 331 session.streamid = uuid_gen(); |
332 (session.log or log)("debug", "Incoming s2s received %s", st.stanza("stream:stream", attr):top_tag()); | 332 (session.log or log)("debug", "Incoming s2s received %s", st.stanza("stream:stream", attr):top_tag()); |
333 if to then | 333 if to then |
334 if not hosts[to] then | 334 if not hosts[to] then |
335 -- Attempting to connect to a host we don't serve | 335 -- Attempting to connect to a host we don't serve |
360 end | 360 end |
361 | 361 |
362 session:open_stream(session.to_host, session.from_host) | 362 session:open_stream(session.to_host, session.from_host) |
363 if session.version >= 1.0 then | 363 if session.version >= 1.0 then |
364 local features = st.stanza("stream:features"); | 364 local features = st.stanza("stream:features"); |
365 | 365 |
366 if to then | 366 if to then |
367 hosts[to].events.fire_event("s2s-stream-features", { origin = session, features = features }); | 367 hosts[to].events.fire_event("s2s-stream-features", { origin = session, features = features }); |
368 else | 368 else |
369 (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or "unknown host"); | 369 (session.log or log)("warn", "No 'to' on stream header from %s means we can't offer any features", from or "unknown host"); |
370 end | 370 end |
371 | 371 |
372 log("debug", "Sending stream features: %s", tostring(features)); | 372 log("debug", "Sending stream features: %s", tostring(features)); |
373 send(features); | 373 send(features); |
374 end | 374 end |
375 elseif session.direction == "outgoing" then | 375 elseif session.direction == "outgoing" then |
376 -- If we are just using the connection for verifying dialback keys, we won't try and auth it | 376 -- If we are just using the connection for verifying dialback keys, we won't try and auth it |
394 session.sends2s(tostring(data)); | 394 session.sends2s(tostring(data)); |
395 send_buffer[i] = nil; | 395 send_buffer[i] = nil; |
396 end | 396 end |
397 end | 397 end |
398 session.send_buffer = nil; | 398 session.send_buffer = nil; |
399 | 399 |
400 -- If server is pre-1.0, don't wait for features, just do dialback | 400 -- If server is pre-1.0, don't wait for features, just do dialback |
401 if session.version < 1.0 then | 401 if session.version < 1.0 then |
402 if not session.dialback_verifying then | 402 if not session.dialback_verifying then |
403 hosts[session.from_host].events.fire_event("s2sout-authenticate-legacy", { origin = session }); | 403 hosts[session.from_host].events.fire_event("s2sout-authenticate-legacy", { origin = session }); |
404 else | 404 else |
487 end | 487 end |
488 end | 488 end |
489 | 489 |
490 session.sends2s("</stream:stream>"); | 490 session.sends2s("</stream:stream>"); |
491 function session.sends2s() return false; end | 491 function session.sends2s() return false; end |
492 | 492 |
493 local reason = remote_reason or (reason and (reason.text or reason.condition)) or reason; | 493 local reason = remote_reason or (reason and (reason.text or reason.condition)) or reason; |
494 session.log("info", "%s s2s stream %s->%s closed: %s", session.direction, session.from_host or "(unknown host)", session.to_host or "(unknown host)", reason or "stream closed"); | 494 session.log("info", "%s s2s stream %s->%s closed: %s", session.direction, session.from_host or "(unknown host)", session.to_host or "(unknown host)", reason or "stream closed"); |
495 | 495 |
496 -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote | 496 -- Authenticated incoming stream may still be sending us stanzas, so wait for </stream:stream> from remote |
497 local conn = session.conn; | 497 local conn = session.conn; |
498 if reason == nil and not session.notopen and session.type == "s2sin" then | 498 if reason == nil and not session.notopen and session.type == "s2sin" then |
499 add_task(stream_close_timeout, function () | 499 add_task(stream_close_timeout, function () |
500 if not session.destroyed then | 500 if not session.destroyed then |
530 | 530 |
531 -- Session initialization logic shared by incoming and outgoing | 531 -- Session initialization logic shared by incoming and outgoing |
532 local function initialize_session(session) | 532 local function initialize_session(session) |
533 local stream = new_xmpp_stream(session, stream_callbacks); | 533 local stream = new_xmpp_stream(session, stream_callbacks); |
534 session.stream = stream; | 534 session.stream = stream; |
535 | 535 |
536 session.notopen = true; | 536 session.notopen = true; |
537 | 537 |
538 function session.reset_stream() | 538 function session.reset_stream() |
539 session.notopen = true; | 539 session.notopen = true; |
540 session.stream:reset(); | 540 session.stream:reset(); |
541 end | 541 end |
542 | 542 |
543 session.open_stream = session_open_stream; | 543 session.open_stream = session_open_stream; |
544 | 544 |
545 local filter = session.filter; | 545 local filter = session.filter; |
546 function session.data(data) | 546 function session.data(data) |
547 data = filter("bytes/in", data); | 547 data = filter("bytes/in", data); |
548 if data then | 548 if data then |
549 local ok, err = stream:feed(data); | 549 local ok, err = stream:feed(data); |
594 if t then | 594 if t then |
595 return w(conn, t); | 595 return w(conn, t); |
596 end | 596 end |
597 end | 597 end |
598 end | 598 end |
599 | 599 |
600 initialize_session(session); | 600 initialize_session(session); |
601 else -- Outgoing session connected | 601 else -- Outgoing session connected |
602 session:open_stream(session.from_host, session.to_host); | 602 session:open_stream(session.from_host, session.to_host); |
603 end | 603 end |
604 session.ip = conn:ip(); | 604 session.ip = conn:ip(); |
608 local session = sessions[conn]; | 608 local session = sessions[conn]; |
609 if session then | 609 if session then |
610 session.data(data); | 610 session.data(data); |
611 end | 611 end |
612 end | 612 end |
613 | 613 |
614 function listener.onstatus(conn, status) | 614 function listener.onstatus(conn, status) |
615 if status == "ssl-handshake-complete" then | 615 if status == "ssl-handshake-complete" then |
616 local session = sessions[conn]; | 616 local session = sessions[conn]; |
617 if session and session.direction == "outgoing" then | 617 if session and session.direction == "outgoing" then |
618 session.log("debug", "Sending stream header..."); | 618 session.log("debug", "Sending stream header..."); |
656 if not must_secure and secure_domains[host] then | 656 if not must_secure and secure_domains[host] then |
657 must_secure = true; | 657 must_secure = true; |
658 elseif must_secure and insecure_domains[host] then | 658 elseif must_secure and insecure_domains[host] then |
659 must_secure = false; | 659 must_secure = false; |
660 end | 660 end |
661 | 661 |
662 if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then | 662 if must_secure and (session.cert_chain_status ~= "valid" or session.cert_identity_status ~= "valid") then |
663 module:log("warn", "Forbidding insecure connection to/from %s", host); | 663 module:log("warn", "Forbidding insecure connection to/from %s", host); |
664 if session.direction == "incoming" then | 664 if session.direction == "incoming" then |
665 session:close({ condition = "not-authorized", text = "Your server's certificate is invalid, expired, or not trusted by "..session.to_host }); | 665 session:close({ condition = "not-authorized", text = "Your server's certificate is invalid, expired, or not trusted by "..session.to_host }); |
666 else -- Close outgoing connections without warning | 666 else -- Close outgoing connections without warning |