| 1 | local verse = require "verse"; |
| 2 | |
| 3 | local xmlns_tls = "urn:ietf:params:xml:ns:xmpp-tls"; |
| 4 | |
| 5 | function verse.plugins.tls(stream) |
| 6 | local function handle_features(features_stanza) |
| 7 | if stream.authenticated then return; end |
| 8 | if features_stanza:get_child("starttls", xmlns_tls) and stream.conn.starttls then |
| 9 | stream:debug("Negotiating TLS..."); |
| 10 | stream:send(verse.stanza("starttls", { xmlns = xmlns_tls })); |
| 11 | return true; |
| 12 | elseif not stream.conn.starttls and not stream.secure then |
| 13 | stream:warn("SSL library (LuaSec) not loaded, so TLS not available"); |
| 14 | elseif not stream.secure then |
| 15 | stream:debug("Server doesn't offer TLS :("); |
| 16 | end |
| 17 | end |
| 18 | local function handle_tls(tls_status) |
| 19 | if tls_status.name == "proceed" then |
| 20 | stream:debug("Server says proceed, handshake starting..."); |
| 21 | local sslctx = verse.tls_builder(".") |
| 22 | :apply({mode="client", protocol="sslv23", options="no_sslv2",capath="/etc/ssl/certs"}) |
| 23 | :apply(stream.ssl or {}); |
| 24 | stream.conn:starttls(sslctx:build(), true); |
| 25 | end |
| 26 | end |
| 27 | local function handle_status(new_status) |
| 28 | if new_status == "ssl-handshake-complete" then |
| 29 | stream.secure = true; |
| 30 | stream:debug("Re-opening stream..."); |
| 31 | stream:reopen(); |
| 32 | end |
| 33 | end |
| 34 | stream:hook("stream-features", handle_features, 400); |
| 35 | stream:hook("stream/"..xmlns_tls, handle_tls); |
| 36 | stream:hook("status", handle_status, 400); |
| 37 | |
| 38 | return true; |
| 39 | end |