Pull request: home: fix tls config comparison
Closes #3411. Squashed commit of the following: commit 42deaa1ca804429a5c523641997b4e8d453952e6 Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Tue Aug 3 19:47:32 2021 +0300 home: imp code commit a69f6469e5e76e17c83537f7a763f047201fd15a Author: Ainar Garipov <A.Garipov@AdGuard.COM> Date: Tue Aug 3 18:54:59 2021 +0300 home: fix tls config comparison
This commit is contained in:
parent
c14bde280e
commit
5c2ead5f60
|
@ -19,6 +19,7 @@ import (
|
||||||
"sync"
|
"sync"
|
||||||
"time"
|
"time"
|
||||||
|
|
||||||
|
"github.com/AdguardTeam/AdGuardHome/internal/dnsforward"
|
||||||
"github.com/AdguardTeam/golibs/errors"
|
"github.com/AdguardTeam/golibs/errors"
|
||||||
"github.com/AdguardTeam/golibs/log"
|
"github.com/AdguardTeam/golibs/log"
|
||||||
"github.com/google/go-cmp/cmp"
|
"github.com/google/go-cmp/cmp"
|
||||||
|
@ -30,9 +31,9 @@ var tlsWebHandlersRegistered = false
|
||||||
// TLSMod - TLS module object
|
// TLSMod - TLS module object
|
||||||
type TLSMod struct {
|
type TLSMod struct {
|
||||||
certLastMod time.Time // last modification time of the certificate file
|
certLastMod time.Time // last modification time of the certificate file
|
||||||
conf tlsConfigSettings
|
|
||||||
confLock sync.Mutex
|
|
||||||
status tlsConfigStatus
|
status tlsConfigStatus
|
||||||
|
confLock sync.Mutex
|
||||||
|
conf tlsConfigSettings
|
||||||
}
|
}
|
||||||
|
|
||||||
// Create TLS module
|
// Create TLS module
|
||||||
|
@ -209,8 +210,8 @@ type tlsConfigStatus struct {
|
||||||
|
|
||||||
// field ordering is important -- yaml fields will mirror ordering from here
|
// field ordering is important -- yaml fields will mirror ordering from here
|
||||||
type tlsConfig struct {
|
type tlsConfig struct {
|
||||||
tlsConfigSettings `json:",inline"`
|
|
||||||
tlsConfigStatus `json:",inline"`
|
tlsConfigStatus `json:",inline"`
|
||||||
|
tlsConfigSettings `json:",inline"`
|
||||||
}
|
}
|
||||||
|
|
||||||
func (t *TLSMod) handleTLSStatus(w http.ResponseWriter, _ *http.Request) {
|
func (t *TLSMod) handleTLSStatus(w http.ResponseWriter, _ *http.Request) {
|
||||||
|
@ -247,6 +248,41 @@ func (t *TLSMod) handleTLSValidate(w http.ResponseWriter, r *http.Request) {
|
||||||
marshalTLS(w, data)
|
marshalTLS(w, data)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (t *TLSMod) setConfig(newConf tlsConfigSettings, status tlsConfigStatus) (restartHTTPS bool) {
|
||||||
|
t.confLock.Lock()
|
||||||
|
defer t.confLock.Unlock()
|
||||||
|
|
||||||
|
// Reset the DNSCrypt data before comparing, since we currently do not
|
||||||
|
// accept these from the frontend.
|
||||||
|
//
|
||||||
|
// TODO(a.garipov): Define a custom comparer for dnsforward.TLSConfig.
|
||||||
|
newConf.DNSCryptConfigFile = t.conf.DNSCryptConfigFile
|
||||||
|
newConf.PortDNSCrypt = t.conf.PortDNSCrypt
|
||||||
|
if !cmp.Equal(t.conf, newConf, cmp.AllowUnexported(dnsforward.TLSConfig{})) {
|
||||||
|
log.Info("tls config has changed, restarting https server")
|
||||||
|
restartHTTPS = true
|
||||||
|
} else {
|
||||||
|
log.Info("tls config has not changed")
|
||||||
|
}
|
||||||
|
|
||||||
|
// Note: don't do just `t.conf = data` because we must preserve all other members of t.conf
|
||||||
|
t.conf.Enabled = newConf.Enabled
|
||||||
|
t.conf.ServerName = newConf.ServerName
|
||||||
|
t.conf.ForceHTTPS = newConf.ForceHTTPS
|
||||||
|
t.conf.PortHTTPS = newConf.PortHTTPS
|
||||||
|
t.conf.PortDNSOverTLS = newConf.PortDNSOverTLS
|
||||||
|
t.conf.PortDNSOverQUIC = newConf.PortDNSOverQUIC
|
||||||
|
t.conf.CertificateChain = newConf.CertificateChain
|
||||||
|
t.conf.CertificatePath = newConf.CertificatePath
|
||||||
|
t.conf.CertificateChainData = newConf.CertificateChainData
|
||||||
|
t.conf.PrivateKey = newConf.PrivateKey
|
||||||
|
t.conf.PrivateKeyPath = newConf.PrivateKeyPath
|
||||||
|
t.conf.PrivateKeyData = newConf.PrivateKeyData
|
||||||
|
t.status = status
|
||||||
|
|
||||||
|
return restartHTTPS
|
||||||
|
}
|
||||||
|
|
||||||
func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
|
func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
|
||||||
data, err := unmarshalTLS(r)
|
data, err := unmarshalTLS(r)
|
||||||
if err != nil {
|
if err != nil {
|
||||||
|
@ -266,42 +302,28 @@ func (t *TLSMod) handleTLSConfigure(w http.ResponseWriter, r *http.Request) {
|
||||||
tlsConfigStatus: t.status,
|
tlsConfigStatus: t.status,
|
||||||
}
|
}
|
||||||
marshalTLS(w, data2)
|
marshalTLS(w, data2)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
status = validateCertificates(string(data.CertificateChainData), string(data.PrivateKeyData), data.ServerName)
|
|
||||||
restartHTTPS := false
|
|
||||||
|
|
||||||
t.confLock.Lock()
|
status = validateCertificates(string(data.CertificateChainData), string(data.PrivateKeyData), data.ServerName)
|
||||||
if !cmp.Equal(t.conf, data) {
|
|
||||||
log.Printf("tls config settings have changed, will restart HTTPS server")
|
restartHTTPS := t.setConfig(data, status)
|
||||||
restartHTTPS = true
|
|
||||||
}
|
|
||||||
// Note: don't do just `t.conf = data` because we must preserve all other members of t.conf
|
|
||||||
t.conf.Enabled = data.Enabled
|
|
||||||
t.conf.ServerName = data.ServerName
|
|
||||||
t.conf.ForceHTTPS = data.ForceHTTPS
|
|
||||||
t.conf.PortHTTPS = data.PortHTTPS
|
|
||||||
t.conf.PortDNSOverTLS = data.PortDNSOverTLS
|
|
||||||
t.conf.PortDNSOverQUIC = data.PortDNSOverQUIC
|
|
||||||
t.conf.CertificateChain = data.CertificateChain
|
|
||||||
t.conf.CertificatePath = data.CertificatePath
|
|
||||||
t.conf.CertificateChainData = data.CertificateChainData
|
|
||||||
t.conf.PrivateKey = data.PrivateKey
|
|
||||||
t.conf.PrivateKeyPath = data.PrivateKeyPath
|
|
||||||
t.conf.PrivateKeyData = data.PrivateKeyData
|
|
||||||
t.status = status
|
|
||||||
t.confLock.Unlock()
|
|
||||||
t.setCertFileTime()
|
t.setCertFileTime()
|
||||||
onConfigModified()
|
onConfigModified()
|
||||||
|
|
||||||
err = reconfigureDNSServer()
|
err = reconfigureDNSServer()
|
||||||
if err != nil {
|
if err != nil {
|
||||||
httpError(w, http.StatusInternalServerError, "%s", err)
|
httpError(w, http.StatusInternalServerError, "%s", err)
|
||||||
|
|
||||||
return
|
return
|
||||||
}
|
}
|
||||||
|
|
||||||
data2 := tlsConfig{
|
data2 := tlsConfig{
|
||||||
tlsConfigSettings: data,
|
tlsConfigSettings: data,
|
||||||
tlsConfigStatus: t.status,
|
tlsConfigStatus: t.status,
|
||||||
}
|
}
|
||||||
|
|
||||||
marshalTLS(w, data2)
|
marshalTLS(w, data2)
|
||||||
if f, ok := w.(http.Flusher); ok {
|
if f, ok := w.(http.Flusher); ok {
|
||||||
f.Flush()
|
f.Flush()
|
||||||
|
|
Loading…
Reference in New Issue