Skip to content

Commit

Permalink
Merge pull request kubernetes#18158 from alessandrocapanna/fix-mask-e…
Browse files Browse the repository at this point in the history
…nv-on-start

fix: updated regex on validateNetwork to support special characters.
  • Loading branch information
spowelljr authored Mar 28, 2024
2 parents a133e0a + 89f58c8 commit 68ed09b
Show file tree
Hide file tree
Showing 5 changed files with 145 additions and 109 deletions.
36 changes: 2 additions & 34 deletions pkg/minikube/node/config.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"

"github.com/spf13/viper"
Expand All @@ -38,46 +36,16 @@ import (
"k8s.io/minikube/pkg/minikube/out/register"
"k8s.io/minikube/pkg/minikube/reason"
"k8s.io/minikube/pkg/minikube/style"
"k8s.io/minikube/pkg/util"
"k8s.io/minikube/pkg/util/lock"
)

func maskProxyPassword(v string) string {
parts := strings.Split(v, "=")
// Is it an attribution variable?
if len(parts) == 2 {
key := strings.ToUpper(parts[0])
// Is it a proxy setting?
if key == "HTTP_PROXY" || key == "HTTPS_PROXY" {
proxyValue := parts[1]
// Proxy variable values SHOULD have a value like
// https(s)://<whatever>
proxyAddressParts := strings.Split(proxyValue, "://")
if len(proxyAddressParts) == 2 {
proxyURL := ""
proxyURL = proxyAddressParts[1]
// Let's store the username, the URL and and optional port address
pattern := `([^:]+):.+(@[\w\.]+)(:\d+)?`
regexpPattern := regexp.MustCompile(pattern)
matches := regexpPattern.FindStringSubmatch(proxyURL)
mask := "*****"
if len(matches) == 4 {
proxyValue = fmt.Sprintf("%s://%s:%s%s%s", proxyAddressParts[0], matches[1], mask, matches[2], matches[3])
} else if len(matches) == 3 {
proxyValue = fmt.Sprintf("%s//%s:%s@%s", proxyAddressParts[0], matches[1], mask, matches[2])
}
}
v = key + "=" + proxyValue
}
}
return v
}

func showVersionInfo(k8sVersion string, cr cruntime.Manager) {
version, _ := cr.Version()
register.Reg.SetStep(register.PreparingKubernetes)
out.Step(cr.Style(), "Preparing Kubernetes {{.k8sVersion}} on {{.runtime}} {{.runtimeVersion}} ...", out.V{"k8sVersion": k8sVersion, "runtime": cr.Name(), "runtimeVersion": version})
for _, v := range config.DockerOpt {
v = maskProxyPassword(v)
v = util.MaskProxyPasswordWithKey(v)
out.Infof("opt {{.docker_option}}", out.V{"docker_option": v})
}
for _, v := range config.DockerEnv {
Expand Down
72 changes: 0 additions & 72 deletions pkg/minikube/node/config_test.go

This file was deleted.

4 changes: 1 addition & 3 deletions pkg/minikube/node/start.go
Original file line number Diff line number Diff line change
Expand Up @@ -767,9 +767,7 @@ func validateNetwork(h *host.Host, r command.Runner, imageRepository string) (st
k = strings.ToUpper(k) // let's get the key right away to mask password from output
// If http(s)_proxy contains password, let's not splatter on the screen
if k == "HTTP_PROXY" || k == "HTTPS_PROXY" {
pattern := `//(\w+):\w+@`
regexpPattern := regexp.MustCompile(pattern)
v = regexpPattern.ReplaceAllString(v, "//$1:*****@")
v = util.MaskProxyPassword(v)
}
out.Infof("{{.key}}={{.value}}", out.V{"key": k, "value": v})
ipExcluded := proxy.IsIPExcluded(ip) // Skip warning if minikube ip is already in NO_PROXY
Expand Down
40 changes: 40 additions & 0 deletions pkg/util/utils.go
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,9 @@ import (
"os"
"os/user"
"path/filepath"
"regexp"
"strconv"
"strings"

"github.com/blang/semver/v4"
units "github.com/docker/go-units"
Expand Down Expand Up @@ -123,3 +125,41 @@ func RemoveDuplicateStrings(initial []string) []string {
}
return result
}

// MaskProxyPassword masks the password in a proxy URL
func MaskProxyPassword(proxyURL string) string {
// Proxy variable values SHOULD have a value like
// https(s)://<whatever>
parts := strings.Split(proxyURL, "://")
if len(parts) == 2 {
proxyAddress := parts[1]
// Let's store the username, the URL and an optional port address
pattern := `([^:]+):.+(@[\w\.]+)(:\d+)?`
re := regexp.MustCompile(pattern)
matches := re.FindStringSubmatch(proxyAddress)
mask := "*****"
switch len(matches) {
case 4:
return fmt.Sprintf("%s://%s:%s%s%s", parts[0], matches[1], mask, matches[2], matches[3])
case 3:
return fmt.Sprintf("%s//%s:%s@%s", parts[0], matches[1], mask, matches[2])
}
}
return proxyURL
}

// MaskProxyPasswordWithKey masks the password in a proxy URL specified by a key-value pair
func MaskProxyPasswordWithKey(v string) string {
parts := strings.Split(v, "=")
// Is it an attribution variable?
if len(parts) == 2 {
key := strings.ToUpper(parts[0])
// Is it a proxy setting?
if key == "HTTP_PROXY" || key == "HTTPS_PROXY" {
proxyValue := parts[1]
maskedProxyValue := MaskProxyPassword(proxyValue)
return key + "=" + maskedProxyValue
}
}
return v
}
102 changes: 102 additions & 0 deletions pkg/util/utils_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -208,3 +208,105 @@ func TestRemoveDuplicateStrings(t *testing.T) {
})
}
}

func TestMaskProxyPassword(t *testing.T) {
type dockerOptTest struct {
input string
output string
}
var tests = []dockerOptTest{
{
input: "cats",
output: "cats",
},
{
input: "myDockerOption=value",
output: "myDockerOption=value",
},
{
input: "http://minikube.sigs.k8s.io",
output: "http://minikube.sigs.k8s.io",
},
{
input: "http://[email protected]:8080",
output: "http://[email protected]:8080",
},
{
input: "https://mary:[email protected]:8080",
output: "https://mary:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://jdoe:%n0tRe@al:[email protected]:8080",
output: "http://jdoe:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://jo@han:n0tRe@al:&[email protected]:8080",
output: "http://jo@han:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://k@r3n!:an0th3erF@akeP@[email protected]",
output: "http://k@r3n!:*****@minikube.sigs.k8s.io",
},
{
input: "https://fr@ank5t3in:an0th3erF@akeP@[email protected]",
output: "https://fr@ank5t3in:*****@minikube.sigs.k8s.io",
},
}
for _, test := range tests {
got := MaskProxyPassword(test.input)
if got != test.output {
t.Errorf("MaskProxyPassword(\"%v\"): got %v, expected %v", test.input, got, test.output)
}
}
}

func TestMaskProxyPasswordWithKey(t *testing.T) {
type dockerOptTest struct {
input string
output string
}
var tests = []dockerOptTest{
{
input: "cats",
output: "cats",
},
{
input: "myDockerOption=value",
output: "myDockerOption=value",
},
{
input: "http_proxy=http://minikube.sigs.k8s.io",
output: "HTTP_PROXY=http://minikube.sigs.k8s.io",
},
{
input: "https_proxy=http://[email protected]:8080",
output: "HTTPS_PROXY=http://[email protected]:8080",
},
{
input: "https_proxy=https://mary:[email protected]:8080",
output: "HTTPS_PROXY=https://mary:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jdoe:%n0tRe@al:[email protected]:8080",
output: "HTTP_PROXY=http://jdoe:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jo@han:n0tRe@al:&[email protected]:8080",
output: "HTTP_PROXY=http://jo@han:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://k@r3n!:an0th3erF@akeP@[email protected]",
output: "HTTP_PROXY=http://k@r3n!:*****@minikube.sigs.k8s.io",
},
{
input: "https_proxy=https://fr@ank5t3in:an0th3erF@akeP@[email protected]",
output: "HTTPS_PROXY=https://fr@ank5t3in:*****@minikube.sigs.k8s.io",
},
}
for _, test := range tests {
got := MaskProxyPasswordWithKey(test.input)
if got != test.output {
t.Errorf("MaskProxyPasswordWithKey(\"%v\"): got %v, expected %v", test.input, got, test.output)
}
}
}

0 comments on commit 68ed09b

Please sign in to comment.