Files
sing-box-extended-mirror/cmd/sing-box/cmd_api_openvpn_cancel.go
T
2026-08-30 17:41:45 +08:00

62 lines
1.7 KiB
Go

package main
import (
"context"
"os"
"github.com/sagernet/sing-box/daemon"
E "github.com/sagernet/sing/common/exceptions"
"github.com/spf13/cobra"
)
var commandAPIOpenVPNCancelFlagEndpoint string
var commandAPIOpenVPNCancel = &cobra.Command{
Use: "cancel",
Short: "Cancel the pending OpenVPN challenge and stop the client",
Args: cobra.NoArgs,
RunE: func(cmd *cobra.Command, args []string) error {
return runAPIOpenVPNCancel()
},
}
func init() {
commandAPIOpenVPNCancel.Flags().StringVar(&commandAPIOpenVPNCancelFlagEndpoint, "endpoint", "", "OpenVPN endpoint tag (default: the only configured endpoint)")
commandAPIOpenVPN.AddCommand(commandAPIOpenVPNCancel)
}
func runAPIOpenVPNCancel() error {
clientConn, client, err := createAPIClient()
if err != nil {
return err
}
defer clientConn.Close()
ctx, cancel := context.WithCancel(globalCtx)
defer cancel()
_, endpoints, err := subscribeOpenVPNStatus(ctx, client)
if err != nil {
return err
}
endpointStatus, err := resolveVPNEndpoint(endpoints, commandAPIOpenVPNCancelFlagEndpoint, "openvpn")
if err != nil {
return err
}
endpointTag := endpointStatus.GetEndpointTag()
challenge := endpointStatus.GetChallenge()
if challenge == nil {
return E.New("no pending authentication challenge on ", endpointTag)
}
_, err = client.CancelOpenVPNChallenge(ctx, &daemon.OpenVPNChallengeCancel{
EndpointTag: endpointTag,
ChallengeID: challenge.GetId(),
})
if err != nil {
return err
}
// sing-openvpn treats a canceled challenge as terminal: unlike OpenConnect, the client does not
// reconnect afterwards.
os.Stdout.WriteString(endpointTag + ": authentication challenge canceled; the client has stopped\n")
return nil
}