Mercurial > prosody-hg
comparison plugins/mod_tls.lua @ 6054:7a5ddbaf758d
Merge 0.9->0.10
| author | Matthew Wild <mwild1@gmail.com> |
|---|---|
| date | Wed, 02 Apr 2014 17:41:38 +0100 |
| parents | ef11b8bab405 |
| children | 66fb7b7c668d |
comparison
equal
deleted
inserted
replaced
| 6053:2f93a04564b2 | 6054:7a5ddbaf758d |
|---|---|
| 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 local config = require "core.configmanager"; | 9 local config = require "core.configmanager"; |
| 27 local c2s_feature = st.stanza("starttls", starttls_attr); | 27 local c2s_feature = st.stanza("starttls", starttls_attr); |
| 28 local s2s_feature = st.stanza("starttls", starttls_attr); | 28 local s2s_feature = st.stanza("starttls", starttls_attr); |
| 29 if c2s_require_encryption then c2s_feature:tag("required"):up(); end | 29 if c2s_require_encryption then c2s_feature:tag("required"):up(); end |
| 30 if s2s_require_encryption then s2s_feature:tag("required"):up(); end | 30 if s2s_require_encryption then s2s_feature:tag("required"):up(); end |
| 31 | 31 |
| 32 local global_ssl_ctx = prosody.global_ssl_ctx; | |
| 33 | |
| 34 local hosts = prosody.hosts; | 32 local hosts = prosody.hosts; |
| 35 local host = hosts[module.host]; | 33 local host = hosts[module.host]; |
| 36 | 34 |
| 35 local ssl_ctx_c2s, ssl_ctx_s2sout, ssl_ctx_s2sin; | |
| 36 do | |
| 37 local function get_ssl_cfg(typ) | |
| 38 local cfg_key = (typ and typ.."_" or "").."ssl"; | |
| 39 local ssl_config = config.rawget(module.host, cfg_key); | |
| 40 if not ssl_config then | |
| 41 local base_host = module.host:match("%.(.*)"); | |
| 42 ssl_config = config.get(base_host, cfg_key); | |
| 43 end | |
| 44 return ssl_config or typ and get_ssl_cfg(); | |
| 45 end | |
| 46 | |
| 47 local ssl_config, err = get_ssl_cfg("c2s"); | |
| 48 ssl_ctx_c2s, err = create_context(host.host, "server", ssl_config); -- for incoming client connections | |
| 49 if err then module:log("error", "Error creating context for c2s: %s", err); end | |
| 50 | |
| 51 ssl_config = get_ssl_cfg("s2s"); | |
| 52 ssl_ctx_s2sin, err = create_context(host.host, "server", ssl_config); -- for incoming server connections | |
| 53 ssl_ctx_s2sout = create_context(host.host, "client", ssl_config); -- for outgoing server connections | |
| 54 if err then module:log("error", "Error creating context for s2s: %s", err); end -- Both would have the same issue | |
| 55 end | |
| 56 | |
| 37 local function can_do_tls(session) | 57 local function can_do_tls(session) |
| 58 if not session.conn.starttls then | |
| 59 return false; | |
| 60 elseif session.ssl_ctx then | |
| 61 return true; | |
| 62 end | |
| 38 if session.type == "c2s_unauthed" then | 63 if session.type == "c2s_unauthed" then |
| 39 return session.conn.starttls and host.ssl_ctx_in; | 64 session.ssl_ctx = ssl_ctx_c2s; |
| 40 elseif session.type == "s2sin_unauthed" and allow_s2s_tls then | 65 elseif session.type == "s2sin_unauthed" and allow_s2s_tls then |
| 41 return session.conn.starttls and host.ssl_ctx_in; | 66 session.ssl_ctx = ssl_ctx_s2sin; |
| 42 elseif session.direction == "outgoing" and allow_s2s_tls then | 67 elseif session.direction == "outgoing" and allow_s2s_tls then |
| 43 return session.conn.starttls and host.ssl_ctx; | 68 session.ssl_ctx = ssl_ctx_s2sout; |
| 69 else | |
| 70 return false; | |
| 44 end | 71 end |
| 45 return false; | 72 return session.ssl_ctx; |
| 46 end | 73 end |
| 47 | 74 |
| 48 -- Hook <starttls/> | 75 -- Hook <starttls/> |
| 49 module:hook("stanza/urn:ietf:params:xml:ns:xmpp-tls:starttls", function(event) | 76 module:hook("stanza/urn:ietf:params:xml:ns:xmpp-tls:starttls", function(event) |
| 50 local origin = event.origin; | 77 local origin = event.origin; |
| 51 if can_do_tls(origin) then | 78 if can_do_tls(origin) then |
| 52 (origin.sends2s or origin.send)(starttls_proceed); | 79 (origin.sends2s or origin.send)(starttls_proceed); |
| 53 origin:reset_stream(); | 80 origin:reset_stream(); |
| 54 local host = origin.to_host or origin.host; | 81 origin.conn:starttls(origin.ssl_ctx); |
| 55 local ssl_ctx = host and hosts[host].ssl_ctx_in or global_ssl_ctx; | |
| 56 origin.conn:starttls(ssl_ctx); | |
| 57 origin.log("debug", "TLS negotiation started for %s...", origin.type); | 82 origin.log("debug", "TLS negotiation started for %s...", origin.type); |
| 58 origin.secure = false; | 83 origin.secure = false; |
| 59 else | 84 else |
| 60 origin.log("warn", "Attempt to start TLS, but TLS is not available on this %s connection", origin.type); | 85 origin.log("warn", "Attempt to start TLS, but TLS is not available on this %s connection", origin.type); |
| 61 (origin.sends2s or origin.send)(starttls_failure); | 86 (origin.sends2s or origin.send)(starttls_failure); |
| 89 end, 500); | 114 end, 500); |
| 90 | 115 |
| 91 module:hook_stanza(xmlns_starttls, "proceed", function (session, stanza) | 116 module:hook_stanza(xmlns_starttls, "proceed", function (session, stanza) |
| 92 module:log("debug", "Proceeding with TLS on s2sout..."); | 117 module:log("debug", "Proceeding with TLS on s2sout..."); |
| 93 session:reset_stream(); | 118 session:reset_stream(); |
| 94 local ssl_ctx = session.from_host and hosts[session.from_host].ssl_ctx or global_ssl_ctx; | 119 session.conn:starttls(session.ssl_ctx); |
| 95 session.conn:starttls(ssl_ctx); | |
| 96 session.secure = false; | 120 session.secure = false; |
| 97 return true; | 121 return true; |
| 98 end); | 122 end); |
| 99 | |
| 100 local function assert_log(ret, err) | |
| 101 if not ret then | |
| 102 module:log("error", "Unable to initialize TLS: %s", err); | |
| 103 end | |
| 104 return ret; | |
| 105 end | |
| 106 | |
| 107 function module.load() | |
| 108 local ssl_config = config.rawget(module.host, "ssl"); | |
| 109 if not ssl_config then | |
| 110 local base_host = module.host:match("%.(.*)"); | |
| 111 ssl_config = config.get(base_host, "ssl"); | |
| 112 end | |
| 113 host.ssl_ctx = assert_log(create_context(host.host, "client", ssl_config)); -- for outgoing connections | |
| 114 host.ssl_ctx_in = assert_log(create_context(host.host, "server", ssl_config)); -- for incoming connections | |
| 115 end | |
| 116 | |
| 117 function module.unload() | |
| 118 host.ssl_ctx = nil; | |
| 119 host.ssl_ctx_in = nil; | |
| 120 end |
