Validate gateway arguments (#4376)

Fixes #4355
master
Krishna Srinivas 7 years ago committed by Harshavardhana
parent 145328ac9f
commit 2c56788f8d
  1. 43
      cmd/gateway-main.go
  2. 33
      cmd/gateway-main_test.go

@ -21,6 +21,7 @@ import (
"fmt" "fmt"
"net/url" "net/url"
"os" "os"
"runtime"
"strings" "strings"
"github.com/gorilla/mux" "github.com/gorilla/mux"
@ -181,6 +182,36 @@ func parseGatewayEndpoint(arg string) (endPoint string, secure bool, err error)
} }
} }
// Validate gateway arguments.
func validateGatewayArguments(serverAddr, endpointAddr string) error {
if err := CheckLocalServerAddr(serverAddr); err != nil {
return err
}
if runtime.GOOS == "darwin" {
_, port := mustSplitHostPort(serverAddr)
// On macOS, if a process already listens on LOCALIPADDR:PORT, net.Listen() falls back
// to IPv6 address i.e minio will start listening on IPv6 address whereas another
// (non-)minio process is listening on IPv4 of given port.
// To avoid this error situation we check for port availability only for macOS.
if err := checkPortAvailability(port); err != nil {
return err
}
}
if endpointAddr != "" {
// Reject the endpoint if it points to the gateway handler itself.
sameTarget, err := sameLocalAddrs(endpointAddr, serverAddr)
if err != nil {
return err
}
if sameTarget {
return errors.New("endpoint points to the local gateway")
}
}
return nil
}
// Handler for 'minio gateway'. // Handler for 'minio gateway'.
func gatewayMain(ctx *cli.Context) { func gatewayMain(ctx *cli.Context) {
if !ctx.Args().Present() || ctx.Args().First() == "help" { if !ctx.Args().Present() || ctx.Args().First() == "help" {
@ -207,17 +238,11 @@ func gatewayMain(ctx *cli.Context) {
backendType := ctx.Args().Get(0) backendType := ctx.Args().Get(0)
// Second argument is the endpoint address (optional) // Second argument is the endpoint address (optional)
endpointAddr := ctx.Args().Get(1) endpointAddr := ctx.Args().Get(1)
// Third argument is the address flag
serverAddr := ctx.String("address") serverAddr := ctx.String("address")
if endpointAddr != "" { err := validateGatewayArguments(serverAddr, endpointAddr)
// Reject the endpoint if it points to the gateway handler itself. fatalIf(err, "Invalid argument")
sameTarget, err := sameLocalAddrs(endpointAddr, serverAddr)
fatalIf(err, "Unable to compare server and endpoint addresses.")
if sameTarget {
fatalIf(errors.New("endpoint points to the local gateway"), "Endpoint url is not allowed")
}
}
// Second argument is endpoint. If no endpoint is specified then the // Second argument is endpoint. If no endpoint is specified then the
// gateway implementation should use a default setting. // gateway implementation should use a default setting.

@ -18,6 +18,7 @@ package cmd
import ( import (
"os" "os"
"strings"
"testing" "testing"
) )
@ -73,3 +74,35 @@ func TestSetBrowserFromEnv(t *testing.T) {
} }
os.Setenv("MINIO_BROWSER", browser) os.Setenv("MINIO_BROWSER", browser)
} }
// Test validateGatewayArguments
func TestValidateGatewayArguments(t *testing.T) {
nonLoopBackIPs := localIP4.FuncMatch(func(ip string, matchString string) bool {
return !strings.HasPrefix(ip, "127.")
}, "")
if len(nonLoopBackIPs) == 0 {
t.Fatalf("No non-loop back IP address found for this host")
}
nonLoopBackIP := nonLoopBackIPs.ToSlice()[0]
testCases := []struct {
serverAddr string
endpointAddr string
valid bool
}{
{":9000", "http://localhost:9001", true},
{":9000", "http://google.com", true},
{"123.123.123.123:9000", "http://localhost:9000", false},
{":9000", "http://localhost:9000", false},
{":9000", nonLoopBackIP + ":9000", false},
}
for i, test := range testCases {
err := validateGatewayArguments(test.serverAddr, test.endpointAddr)
if test.valid && err != nil {
t.Errorf("Test %d expected not to return error but got %s", i+1, err)
}
if !test.valid && err == nil {
t.Errorf("Test %d expected to fail but it did not", i+1)
}
}
}

Loading…
Cancel
Save