11package kvm
22
33import (
4+ "context"
45 "crypto/tls"
56 "encoding/pem"
7+ "errors"
68 "fmt"
79 "net/http"
10+ "sync"
811
912 "github.com/jetkvm/kvm/internal/websecure"
1013)
@@ -31,6 +34,10 @@ type TLSState struct {
3134}
3235
3336func initCertStore () {
37+ if certStore != nil {
38+ logger .Warnf ("TLS store already initialized, it should not be initialized again" )
39+ return
40+ }
3441 certStore = websecure .NewCertStore (tlsStorePath )
3542 certStore .LoadCertificates ()
3643
@@ -87,10 +94,18 @@ func getTLSState() TLSState {
8794}
8895
8996func setTLSState (s TLSState ) error {
97+ var isChanged = false
98+
9099 switch s .Mode {
91100 case "disabled" :
101+ if config .TLSMode != "" {
102+ isChanged = true
103+ }
92104 config .TLSMode = ""
93105 case "custom" :
106+ if config .TLSMode == "" {
107+ isChanged = true
108+ }
94109 // parse pem to cert and key
95110 err , _ := certStore .ValidateAndSaveCertificate (webSecureCustomCertificateName , s .Certificate , s .PrivateKey , true )
96111 // warn doesn't matter as ... we don't know the hostname yet
@@ -99,15 +114,47 @@ func setTLSState(s TLSState) error {
99114 }
100115 config .TLSMode = "custom"
101116 case "self-signed" :
117+ if config .TLSMode == "" {
118+ isChanged = true
119+ }
102120 config .TLSMode = "self-signed"
103121 default :
104122 return fmt .Errorf ("invalid TLS mode: %s" , s .Mode )
105123 }
124+
125+ if ! isChanged {
126+ logger .Tracef ("TLS enabled state is not changed, not starting/stopping websecure server" )
127+ return nil
128+ }
129+
130+ if config .TLSMode == "" {
131+ logger .Tracef ("Stopping websecure server, as TLS mode is disabled" )
132+ stopWebSecureServer ()
133+ } else {
134+ logger .Tracef ("Starting websecure server, as TLS mode is enabled" )
135+ startWebSecureServer ()
136+ }
137+
106138 return nil
107139}
108140
141+ var (
142+ startTLS = make (chan struct {})
143+ stopTLS = make (chan struct {})
144+ tlsServiceLock = sync.Mutex {}
145+ tlsStarted = false
146+ )
147+
109148// RunWebSecureServer runs a web server with TLS.
110- func RunWebSecureServer () {
149+ func runWebSecureServer () {
150+ tlsServiceLock .Lock ()
151+ defer tlsServiceLock .Unlock ()
152+
153+ tlsStarted = true
154+ defer func () {
155+ tlsStarted = false
156+ }()
157+
111158 r := setupRouter ()
112159
113160 server := & http.Server {
@@ -120,8 +167,42 @@ func RunWebSecureServer() {
120167 },
121168 }
122169 logger .Infof ("Starting websecure server on %s" , webSecureListen )
170+
171+ go func () {
172+ for _ = range stopTLS {
173+ logger .Infof ("Shutting down websecure server" )
174+ server .Shutdown (context .Background ())
175+ }
176+ }()
177+
123178 err := server .ListenAndServeTLS ("" , "" )
124- if err != nil {
179+ if ! errors . Is ( err , http . ErrServerClosed ) {
125180 panic (err )
126181 }
127182}
183+
184+ func stopWebSecureServer () {
185+ if ! tlsStarted {
186+ logger .Warnf ("Websecure server is not running, not stopping it" )
187+ return
188+ }
189+ stopTLS <- struct {}{}
190+ }
191+
192+ func startWebSecureServer () {
193+ if tlsStarted {
194+ logger .Warnf ("Websecure server is already running, not starting it again" )
195+ return
196+ }
197+ startTLS <- struct {}{}
198+ }
199+
200+ func RunWebSecureServer () {
201+ for _ = range startTLS {
202+ logger .Tracef ("Starting websecure server, as we have received a start signal" )
203+ if certStore == nil {
204+ initCertStore ()
205+ }
206+ go runWebSecureServer ()
207+ }
208+ }
0 commit comments