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