cmd/cli: do not allow running start command if pin code set

While at it, also emitting a better error message when pin code was set
but users do not provide --pin flag.
This commit is contained in:
Cuong Manh Le
2024-02-19 15:26:10 +07:00
committed by Cuong Manh Le
parent 583718f234
commit dabbf2037b
2 changed files with 34 additions and 8 deletions
+27 -6
View File
@@ -259,6 +259,13 @@ func initCLI() {
return return
} }
// If pin code was set, do not allow running start command.
if status, _ := s.Status(); status == service.StatusRunning {
if err := checkDeactivationPin(s); isCheckDeactivationPinErr(err) {
os.Exit(deactivationPinInvalidExitCode)
}
}
if router.Name() != "" && iface != "" { if router.Name() != "" && iface != "" {
mainLog.Load().Debug().Msg("cleaning up router before installing") mainLog.Load().Debug().Msg("cleaning up router before installing")
_ = p.router.Cleanup() _ = p.router.Cleanup()
@@ -393,7 +400,7 @@ func initCLI() {
return return
} }
initLogging() initLogging()
if err := checkDeactivationPin(s); errors.Is(err, errInvalidDeactivationPin) { if err := checkDeactivationPin(s); isCheckDeactivationPinErr(err) {
os.Exit(deactivationPinInvalidExitCode) os.Exit(deactivationPinInvalidExitCode)
} }
if doTasks([]task{{s.Stop, true}}) { if doTasks([]task{{s.Stop, true}}) {
@@ -552,7 +559,7 @@ NOTE: Uninstalling will set DNS to values provided by DHCP.`,
if iface == "" { if iface == "" {
iface = "auto" iface = "auto"
} }
if err := checkDeactivationPin(s); errors.Is(err, errInvalidDeactivationPin) { if err := checkDeactivationPin(s); isCheckDeactivationPinErr(err) {
os.Exit(deactivationPinInvalidExitCode) os.Exit(deactivationPinInvalidExitCode)
} }
uninstall(p, s) uninstall(p, s)
@@ -834,7 +841,7 @@ func RunMobile(appConfig *AppConfig, appCallback *AppCallback, stopCh chan struc
// CheckDeactivationPin checks if deactivation pin is valid // CheckDeactivationPin checks if deactivation pin is valid
func CheckDeactivationPin(pin int64) int { func CheckDeactivationPin(pin int64) int {
deactivationPin = pin deactivationPin = pin
if err := checkDeactivationPin(nil); errors.Is(err, errInvalidDeactivationPin) { if err := checkDeactivationPin(nil); isCheckDeactivationPinErr(err) {
return deactivationPinInvalidExitCode return deactivationPinInvalidExitCode
} }
return 0 return 0
@@ -2146,6 +2153,9 @@ const deactivationPinInvalidExitCode = 126
// errInvalidDeactivationPin indicates that the deactivation pin is invalid. // errInvalidDeactivationPin indicates that the deactivation pin is invalid.
var errInvalidDeactivationPin = errors.New("deactivation pin is invalid") var errInvalidDeactivationPin = errors.New("deactivation pin is invalid")
// errRequiredDeactivationPin indicates that the deactivation pin is required but not provided by users.
var errRequiredDeactivationPin = errors.New("deactivation pin is required to stop or uninstall the service")
// checkDeactivationPin validates if the deactivation pin matches one in ControlD config. // checkDeactivationPin validates if the deactivation pin matches one in ControlD config.
func checkDeactivationPin(s service.Service) error { func checkDeactivationPin(s service.Service) error {
dir, err := socketDir() dir, err := socketDir()
@@ -2164,13 +2174,24 @@ func checkDeactivationPin(s service.Service) error {
} }
data, _ := json.Marshal(&deactivationRequest{Pin: deactivationPin}) data, _ := json.Marshal(&deactivationRequest{Pin: deactivationPin})
resp, _ := cc.post(deactivationPath, bytes.NewReader(data)) resp, _ := cc.post(deactivationPath, bytes.NewReader(data))
if resp != nil && resp.StatusCode == http.StatusOK { if resp != nil {
return nil // valid pin switch resp.StatusCode {
case http.StatusBadRequest:
mainLog.Load().Error().Msg(errRequiredDeactivationPin.Error())
return errRequiredDeactivationPin // pin is required
case http.StatusOK:
return nil // valid pin
}
} }
mainLog.Load().Error().Msg("deactivation pin is invalid") mainLog.Load().Error().Msg(errInvalidDeactivationPin.Error())
return errInvalidDeactivationPin return errInvalidDeactivationPin
} }
// isCheckDeactivationPinErr reports whether there is an error during check deactivation pin process.
func isCheckDeactivationPinErr(err error) bool {
return errors.Is(err, errInvalidDeactivationPin) || errors.Is(err, errRequiredDeactivationPin)
}
// ensureUninstall ensures that s.Uninstall will remove ctrld service from system completely. // ensureUninstall ensures that s.Uninstall will remove ctrld service from system completely.
func ensureUninstall(s service.Service) error { func ensureUninstall(s service.Service) error {
maxAttempts := 10 maxAttempts := 10
+7 -2
View File
@@ -160,9 +160,14 @@ func (p *prog) registerControlServerHandler() {
mainLog.Load().Err(err).Msg("invalid deactivation request") mainLog.Load().Err(err).Msg("invalid deactivation request")
return return
} }
code := http.StatusBadRequest
if req.Pin == cdDeactivationPin { code := http.StatusForbidden
switch req.Pin {
case cdDeactivationPin:
code = http.StatusOK code = http.StatusOK
case defaultDeactivationPin:
// If the pin code was set, but users do not provide --pin, return proper code to client.
code = http.StatusBadRequest
} }
w.WriteHeader(code) w.WriteHeader(code)
})) }))