|
@@ -34,6 +34,7 @@ import (
|
|
|
|
|
|
const (
|
|
|
logSender = "utils"
|
|
|
+ osWindows = "windows"
|
|
|
)
|
|
|
|
|
|
// IsStringInSlice searches a string in a slice and returns true if the string is found
|
|
@@ -373,7 +374,7 @@ func IsFileInputValid(fileInput string) bool {
|
|
|
// the -l flag will be ignored and the -c flag will get the value `C:\ProgramData\SFTPGO" -l sftpgo.log`
|
|
|
// since the backslash after SFTPGO escape the double quote. This is definitely a bad user input
|
|
|
func CleanDirInput(dirInput string) string {
|
|
|
- if runtime.GOOS == "windows" {
|
|
|
+ if runtime.GOOS == osWindows {
|
|
|
for strings.HasSuffix(dirInput, "\"") {
|
|
|
dirInput = strings.TrimSuffix(dirInput, "\"")
|
|
|
}
|
|
@@ -414,7 +415,7 @@ func HTTPListenAndServe(srv *http.Server, address string, port int, isTLS bool,
|
|
|
var listener net.Listener
|
|
|
var err error
|
|
|
|
|
|
- if filepath.IsAbs(address) && runtime.GOOS != "windows" {
|
|
|
+ if filepath.IsAbs(address) && runtime.GOOS != osWindows {
|
|
|
if !IsFileInputValid(address) {
|
|
|
return fmt.Errorf("invalid socket address %#v", address)
|
|
|
}
|
|
@@ -427,6 +428,7 @@ func HTTPListenAndServe(srv *http.Server, address string, port int, isTLS bool,
|
|
|
|
|
|
listener, err = net.Listen("unix", address)
|
|
|
} else {
|
|
|
+ CheckTCP4Port(port)
|
|
|
listener, err = net.Listen("tcp", fmt.Sprintf("%s:%d", address, port))
|
|
|
}
|
|
|
if err != nil {
|
|
@@ -462,7 +464,7 @@ func GetTLSCiphersFromNames(cipherNames []string) []uint16 {
|
|
|
// This can be verified using openssl x509 -in cert.crt -text -noout
|
|
|
func EncodeTLSCertToPem(tlsCert *x509.Certificate) (string, error) {
|
|
|
if len(tlsCert.Raw) == 0 {
|
|
|
- return "", errors.New("Invalid x509 certificate, no der contents")
|
|
|
+ return "", errors.New("invalid x509 certificate, no der contents")
|
|
|
}
|
|
|
publicKeyBlock := pem.Block{
|
|
|
Type: "CERTIFICATE",
|
|
@@ -470,3 +472,20 @@ func EncodeTLSCertToPem(tlsCert *x509.Certificate) (string, error) {
|
|
|
}
|
|
|
return string(pem.EncodeToMemory(&publicKeyBlock)), nil
|
|
|
}
|
|
|
+
|
|
|
+// CheckTCP4Port quits the app if bind to the given IPv4 port.
|
|
|
+// This is a ugly hack to avoid to bind on an already used port.
|
|
|
+// It is required on Windows only.
|
|
|
+// https://github.com/golang/go/issues/45150
|
|
|
+func CheckTCP4Port(port int) {
|
|
|
+ if runtime.GOOS != osWindows {
|
|
|
+ return
|
|
|
+ }
|
|
|
+ listener, err := net.Listen("tcp4", fmt.Sprintf(":%d", port))
|
|
|
+ if err != nil {
|
|
|
+ logger.ErrorToConsole("unable to bind tcp4 address: %v", err)
|
|
|
+ logger.Error(logSender, "", "unable to bind tcp4 address: %v", err)
|
|
|
+ os.Exit(1)
|
|
|
+ }
|
|
|
+ listener.Close()
|
|
|
+}
|