diff options
author | Kim Alvefur <zash@zash.se> | 2021-07-13 14:20:24 +0200 |
---|---|---|
committer | Kim Alvefur <zash@zash.se> | 2021-07-13 14:20:24 +0200 |
commit | 9615fcca979a796bf9f7b7ba2ba6d1381806e454 (patch) | |
tree | f1499c955139cf277ed61944d5df2abd582416b2 | |
parent | b313c33a8ea13fd6ccde8c94c254173d87c9f9c4 (diff) | |
download | prosody-9615fcca979a796bf9f7b7ba2ba6d1381806e454.tar.gz prosody-9615fcca979a796bf9f7b7ba2ba6d1381806e454.zip |
net.server_epoll: Factor out TLS initialization into a method
So there's :startls(), :inittls() and :tlshandshake()
:starttls() prepares for plain -> TLS upgrade and ensures that the
(unencrypted) write buffer is drained before proceeding.
:inittls() wraps the connection and does things like SNI, DANE etc.
:tlshandshake() steps the TLS negotiation forward until it completes
-rw-r--r-- | net/server_epoll.lua | 96 |
1 files changed, 51 insertions, 45 deletions
diff --git a/net/server_epoll.lua b/net/server_epoll.lua index ec27861c..f7a7dafa 100644 --- a/net/server_epoll.lua +++ b/net/server_epoll.lua @@ -561,8 +561,8 @@ function interface:starttls(tls_ctx) if self.ondrain == interface.starttls then self.ondrain = nil; end - self.onwritable = interface.tlshandshake; - self.onreadable = interface.tlshandshake; + self.onwritable = interface.inittls; + self.onreadable = interface.inittls; self:set(true, true); self:setreadtimeout(cfg.ssl_handshake_timeout); self:setwritetimeout(cfg.ssl_handshake_timeout); @@ -570,52 +570,55 @@ function interface:starttls(tls_ctx) end end -function interface:tlshandshake() - self:setwritetimeout(false); - self:setreadtimeout(false); - if not self._tls then - self._tls = true; - self:debug("Starting TLS now"); - self:del(); - self:updatenames(); -- Can't getpeer/sockname after wrap() - local ok, conn, err = pcall(luasec.wrap, self.conn, self.tls_ctx); - if not ok then - conn, err = ok, conn; - self:debug("Failed to initialize TLS: %s", err); - end - if not conn then - self:on("disconnect", err); - self:destroy(); - return conn, err; - end - conn:settimeout(0); - self.conn = conn; - if conn.sni then - if self.servername then - conn:sni(self.servername); - elseif self._server and type(self._server.hosts) == "table" and next(self._server.hosts) ~= nil then - conn:sni(self._server.hosts, true); - end +function interface:inittls(tls_ctx) + if self._tls then return end + if tls_ctx then self.tls_ctx = tls_ctx; end + self._tls = true; + self:debug("Starting TLS now"); + self:del(); + self:updatenames(); -- Can't getpeer/sockname after wrap() + local ok, conn, err = pcall(luasec.wrap, self.conn, self.tls_ctx); + if not ok then + conn, err = ok, conn; + self:debug("Failed to initialize TLS: %s", err); + end + if not conn then + self:on("disconnect", err); + self:destroy(); + return conn, err; + end + conn:settimeout(0); + self.conn = conn; + if conn.sni then + if self.servername then + conn:sni(self.servername); + elseif self._server and type(self._server.hosts) == "table" and next(self._server.hosts) ~= nil then + conn:sni(self._server.hosts, true); end - if self.extra and self.extra.tlsa and conn.settlsa then - -- TODO Error handling - if not conn:setdane(self.servername or self.extra.dane_hostname) then - self:debug("Could not enable DANE on connection"); - else - self:debug("Enabling DANE with %d TLSA records", #self.extra.tlsa); - self:noise("DANE hostname is %q", self.servername or self.extra.dane_hostname); - for _, tlsa in ipairs(self.extra.tlsa) do - self:noise("TLSA: %q", tlsa); - conn:settlsa(tlsa.use, tlsa.select, tlsa.match, tlsa.data); - end + end + if self.extra and self.extra.tlsa and conn.settlsa then + -- TODO Error handling + if not conn:setdane(self.servername or self.extra.dane_hostname) then + self:debug("Could not enable DANE on connection"); + else + self:debug("Enabling DANE with %d TLSA records", #self.extra.tlsa); + self:noise("DANE hostname is %q", self.servername or self.extra.dane_hostname); + for _, tlsa in ipairs(self.extra.tlsa) do + self:noise("TLSA: %q", tlsa); + conn:settlsa(tlsa.use, tlsa.select, tlsa.match, tlsa.data); end end - self:on("starttls"); - self.ondrain = nil; - self.onwritable = interface.tlshandshake; - self.onreadable = interface.tlshandshake; - return self:init(); end + self:on("starttls"); + self.ondrain = nil; + self.onwritable = interface.tlshandshake; + self.onreadable = interface.tlshandshake; + return self:init(); +end + +function interface:tlshandshake() + self:setwritetimeout(false); + self:setreadtimeout(false); self:noise("Continuing TLS handshake"); local ok, err = self.conn:dohandshake(); if ok then @@ -697,7 +700,10 @@ function interface:onacceptable() client:debug("New connection %s on server %s", client, self); if self.tls_direct then client:add(true, true); - client:starttls(self.tls_ctx); + if client:inittls(self.tls_ctx) then + client:setreadtimeout(cfg.ssl_handshake_timeout); + client:setwritetimeout(cfg.ssl_handshake_timeout); + end else client:add(true, false); client:onconnect(); |