mod_tls: Fixed an extra :up() in s2s stream feature generation.
[prosody.git] / plugins / mod_tls.lua
1 -- Prosody IM
2 -- Copyright (C) 2008-2009 Matthew Wild
3 -- Copyright (C) 2008-2009 Waqas Hussain
4 -- 
5 -- This project is MIT/X11 licensed. Please see the
6 -- COPYING file in the source package for more information.
7 --
8
9 local st = require "util.stanza";
10
11 local xmlns_stream = 'http://etherx.jabber.org/streams';
12 local xmlns_starttls = 'urn:ietf:params:xml:ns:xmpp-tls';
13
14 local secure_auth_only = module:get_option("c2s_require_encryption") or module:get_option("require_encryption");
15 local secure_s2s_only = module:get_option("s2s_require_encryption");
16
17 module:add_handler("c2s_unauthed", "starttls", xmlns_starttls,
18                 function (session, stanza)
19                         if session.conn.starttls then
20                                 session.send(st.stanza("proceed", { xmlns = xmlns_starttls }));
21                                 session:reset_stream();
22                                 if session.host and hosts[session.host].ssl_ctx_in then
23                                         session.conn.set_sslctx(hosts[session.host].ssl_ctx_in);
24                                 end
25                                 session.conn.starttls();
26                                 session.log("info", "TLS negotiation started...");
27                                 session.secure = false;
28                         else
29                                 session.log("warn", "Attempt to start TLS, but TLS is not available on this connection");
30                                 (session.sends2s or session.send)(st.stanza("failure", { xmlns = xmlns_starttls }));
31                                 session:close();
32                         end
33                 end);
34                 
35 module:add_handler("s2sin_unauthed", "starttls", xmlns_starttls,
36                 function (session, stanza)
37                         if session.conn.starttls then
38                                 session.sends2s(st.stanza("proceed", { xmlns = xmlns_starttls }));
39                                 session:reset_stream();
40                                 if session.to_host and hosts[session.to_host].ssl_ctx_in then
41                                         session.conn.set_sslctx(hosts[session.to_host].ssl_ctx_in);
42                                 end
43                                 session.conn.starttls();
44                                 session.log("info", "TLS negotiation started for incoming s2s...");
45                                 session.secure = false;
46                         else
47                                 session.log("warn", "Attempt to start TLS, but TLS is not available on this s2s connection");
48                                 (session.sends2s or session.send)(st.stanza("failure", { xmlns = xmlns_starttls }));
49                                 session:close();
50                         end
51                 end);
52
53
54 local starttls_attr = { xmlns = xmlns_starttls };
55 module:add_event_hook("stream-features", 
56                 function (session, features)
57                         if session.conn.starttls then
58                                 features:tag("starttls", starttls_attr);
59                                 if secure_auth_only then
60                                         features:tag("required"):up():up();
61                                 else
62                                         features:up();
63                                 end
64                         end
65                 end);
66
67 module:hook("s2s-stream-features", 
68                 function (data)
69                         local session, features = data.session, data.features;
70                         if session.to_host and session.conn.starttls then
71                                 features:tag("starttls", starttls_attr);
72                                 if secure_s2s_only then
73                                         features:tag("required"):up():up();
74                                 else
75                                         features:up();
76                                 end
77                         end
78                 end);
79
80 -- For s2sout connections, start TLS if we can
81 module:hook_stanza(xmlns_stream, "features",
82                 function (session, stanza)
83                         module:log("debug", "Received features element");
84                         if session.conn.starttls and stanza:child_with_ns(xmlns_starttls) then
85                                 module:log("%s is offering TLS, taking up the offer...", session.to_host);
86                                 session.sends2s("<starttls xmlns='"..xmlns_starttls.."'/>");
87                                 return true;
88                         end
89                 end, 500);
90
91 module:hook_stanza(xmlns_starttls, "proceed",
92                 function (session, stanza)
93                         module:log("debug", "Proceeding with TLS on s2sout...");
94                         local format, to_host, from_host = string.format, session.to_host, session.from_host;
95                         session:reset_stream();
96                         session.conn.starttls(true);
97                         session.secure = false;
98                         return true;
99                 end);