Software /
code /
prosody
Comparison
net/server_epoll.lua @ 11672:79f8e29e88a0
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
author | Kim Alvefur <zash@zash.se> |
---|---|
date | Tue, 13 Jul 2021 14:20:24 +0200 |
parent | 11671:4e4e26e3df8d |
child | 11673:3ab8496579f1 |
comparison
equal
deleted
inserted
replaced
11671:4e4e26e3df8d | 11672:79f8e29e88a0 |
---|---|
559 self:set(nil, true); -- make sure wantwrite is set | 559 self:set(nil, true); -- make sure wantwrite is set |
560 else | 560 else |
561 if self.ondrain == interface.starttls then | 561 if self.ondrain == interface.starttls then |
562 self.ondrain = nil; | 562 self.ondrain = nil; |
563 end | 563 end |
564 self.onwritable = interface.tlshandshake; | 564 self.onwritable = interface.inittls; |
565 self.onreadable = interface.tlshandshake; | 565 self.onreadable = interface.inittls; |
566 self:set(true, true); | 566 self:set(true, true); |
567 self:setreadtimeout(cfg.ssl_handshake_timeout); | 567 self:setreadtimeout(cfg.ssl_handshake_timeout); |
568 self:setwritetimeout(cfg.ssl_handshake_timeout); | 568 self:setwritetimeout(cfg.ssl_handshake_timeout); |
569 self:debug("Prepared to start TLS"); | 569 self:debug("Prepared to start TLS"); |
570 end | 570 end |
571 end | 571 end |
572 | 572 |
573 function interface:inittls(tls_ctx) | |
574 if self._tls then return end | |
575 if tls_ctx then self.tls_ctx = tls_ctx; end | |
576 self._tls = true; | |
577 self:debug("Starting TLS now"); | |
578 self:del(); | |
579 self:updatenames(); -- Can't getpeer/sockname after wrap() | |
580 local ok, conn, err = pcall(luasec.wrap, self.conn, self.tls_ctx); | |
581 if not ok then | |
582 conn, err = ok, conn; | |
583 self:debug("Failed to initialize TLS: %s", err); | |
584 end | |
585 if not conn then | |
586 self:on("disconnect", err); | |
587 self:destroy(); | |
588 return conn, err; | |
589 end | |
590 conn:settimeout(0); | |
591 self.conn = conn; | |
592 if conn.sni then | |
593 if self.servername then | |
594 conn:sni(self.servername); | |
595 elseif self._server and type(self._server.hosts) == "table" and next(self._server.hosts) ~= nil then | |
596 conn:sni(self._server.hosts, true); | |
597 end | |
598 end | |
599 if self.extra and self.extra.tlsa and conn.settlsa then | |
600 -- TODO Error handling | |
601 if not conn:setdane(self.servername or self.extra.dane_hostname) then | |
602 self:debug("Could not enable DANE on connection"); | |
603 else | |
604 self:debug("Enabling DANE with %d TLSA records", #self.extra.tlsa); | |
605 self:noise("DANE hostname is %q", self.servername or self.extra.dane_hostname); | |
606 for _, tlsa in ipairs(self.extra.tlsa) do | |
607 self:noise("TLSA: %q", tlsa); | |
608 conn:settlsa(tlsa.use, tlsa.select, tlsa.match, tlsa.data); | |
609 end | |
610 end | |
611 end | |
612 self:on("starttls"); | |
613 self.ondrain = nil; | |
614 self.onwritable = interface.tlshandshake; | |
615 self.onreadable = interface.tlshandshake; | |
616 return self:init(); | |
617 end | |
618 | |
573 function interface:tlshandshake() | 619 function interface:tlshandshake() |
574 self:setwritetimeout(false); | 620 self:setwritetimeout(false); |
575 self:setreadtimeout(false); | 621 self:setreadtimeout(false); |
576 if not self._tls then | |
577 self._tls = true; | |
578 self:debug("Starting TLS now"); | |
579 self:del(); | |
580 self:updatenames(); -- Can't getpeer/sockname after wrap() | |
581 local ok, conn, err = pcall(luasec.wrap, self.conn, self.tls_ctx); | |
582 if not ok then | |
583 conn, err = ok, conn; | |
584 self:debug("Failed to initialize TLS: %s", err); | |
585 end | |
586 if not conn then | |
587 self:on("disconnect", err); | |
588 self:destroy(); | |
589 return conn, err; | |
590 end | |
591 conn:settimeout(0); | |
592 self.conn = conn; | |
593 if conn.sni then | |
594 if self.servername then | |
595 conn:sni(self.servername); | |
596 elseif self._server and type(self._server.hosts) == "table" and next(self._server.hosts) ~= nil then | |
597 conn:sni(self._server.hosts, true); | |
598 end | |
599 end | |
600 if self.extra and self.extra.tlsa and conn.settlsa then | |
601 -- TODO Error handling | |
602 if not conn:setdane(self.servername or self.extra.dane_hostname) then | |
603 self:debug("Could not enable DANE on connection"); | |
604 else | |
605 self:debug("Enabling DANE with %d TLSA records", #self.extra.tlsa); | |
606 self:noise("DANE hostname is %q", self.servername or self.extra.dane_hostname); | |
607 for _, tlsa in ipairs(self.extra.tlsa) do | |
608 self:noise("TLSA: %q", tlsa); | |
609 conn:settlsa(tlsa.use, tlsa.select, tlsa.match, tlsa.data); | |
610 end | |
611 end | |
612 end | |
613 self:on("starttls"); | |
614 self.ondrain = nil; | |
615 self.onwritable = interface.tlshandshake; | |
616 self.onreadable = interface.tlshandshake; | |
617 return self:init(); | |
618 end | |
619 self:noise("Continuing TLS handshake"); | 622 self:noise("Continuing TLS handshake"); |
620 local ok, err = self.conn:dohandshake(); | 623 local ok, err = self.conn:dohandshake(); |
621 if ok then | 624 if ok then |
622 local info = self.conn.info and self.conn:info(); | 625 local info = self.conn.info and self.conn:info(); |
623 if type(info) == "table" then | 626 if type(info) == "table" then |
695 end | 698 end |
696 local client = wrapsocket(conn, self, nil, self.listeners); | 699 local client = wrapsocket(conn, self, nil, self.listeners); |
697 client:debug("New connection %s on server %s", client, self); | 700 client:debug("New connection %s on server %s", client, self); |
698 if self.tls_direct then | 701 if self.tls_direct then |
699 client:add(true, true); | 702 client:add(true, true); |
700 client:starttls(self.tls_ctx); | 703 if client:inittls(self.tls_ctx) then |
704 client:setreadtimeout(cfg.ssl_handshake_timeout); | |
705 client:setwritetimeout(cfg.ssl_handshake_timeout); | |
706 end | |
701 else | 707 else |
702 client:add(true, false); | 708 client:add(true, false); |
703 client:onconnect(); | 709 client:onconnect(); |
704 client:onreadable(); | 710 client:onreadable(); |
705 end | 711 end |