refactor(util): Move maskProxyPassword to pkg/util, update references & tests, introduced MaskProxyPasswordWithKey

refactor(util): Move maskProxyPassword to pkg/util, update references & tests, introduced MaskProxyPasswordWithKey
pull/18158/head
alessandrocapanna 2024-02-13 01:03:25 +01:00
parent ed5eb17033
commit 89f58c8e24
No known key found for this signature in database
GPG Key ID: 87373A16434A0547
5 changed files with 145 additions and 109 deletions

View File

@ -21,9 +21,7 @@ import (
"os"
"os/exec"
"path/filepath"
"regexp"
"strconv"
"strings"
"sync"
"github.com/spf13/viper"
@ -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 {

View File

@ -1,72 +0,0 @@
/*
Copyright 2016 The Kubernetes Authors All rights reserved.
Licensed under the Apache License, Version 2.0 (the "License");
you may not use this file except in compliance with the License.
You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
*/
package node
import (
"testing"
)
func Test_maskProxyPassword(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://jdoe@minikube.sigs.k8s.io:8080",
output: "HTTPS_PROXY=http://jdoe@minikube.sigs.k8s.io:8080",
},
{
input: "https_proxy=https://mary:iam$Fake!password@minikube.sigs.k8s.io:8080",
output: "HTTPS_PROXY=https://mary:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jdoe:%n0tRe@al:Password!@minikube.sigs.k8s.io:8080",
output: "HTTP_PROXY=http://jdoe:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jo@han:n0tRe@al:&Password!@minikube.sigs.k8s.io:8080",
output: "HTTP_PROXY=http://jo@han:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://k@r3n!:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
output: "HTTP_PROXY=http://k@r3n!:*****@minikube.sigs.k8s.io",
},
{
input: "https_proxy=https://fr@ank5t3in:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
output: "HTTPS_PROXY=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)
}
}
}

View File

@ -748,9 +748,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

View File

@ -21,7 +21,9 @@ import (
"os"
"os/user"
"path/filepath"
"regexp"
"strconv"
"strings"
"github.com/blang/semver/v4"
units "github.com/docker/go-units"
@ -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
}

View File

@ -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://jdoe@minikube.sigs.k8s.io:8080",
output: "http://jdoe@minikube.sigs.k8s.io:8080",
},
{
input: "https://mary:iam$Fake!password@minikube.sigs.k8s.io:8080",
output: "https://mary:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://jdoe:%n0tRe@al:Password!@minikube.sigs.k8s.io:8080",
output: "http://jdoe:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://jo@han:n0tRe@al:&Password!@minikube.sigs.k8s.io:8080",
output: "http://jo@han:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http://k@r3n!:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
output: "http://k@r3n!:*****@minikube.sigs.k8s.io",
},
{
input: "https://fr@ank5t3in:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
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://jdoe@minikube.sigs.k8s.io:8080",
output: "HTTPS_PROXY=http://jdoe@minikube.sigs.k8s.io:8080",
},
{
input: "https_proxy=https://mary:iam$Fake!password@minikube.sigs.k8s.io:8080",
output: "HTTPS_PROXY=https://mary:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jdoe:%n0tRe@al:Password!@minikube.sigs.k8s.io:8080",
output: "HTTP_PROXY=http://jdoe:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://jo@han:n0tRe@al:&Password!@minikube.sigs.k8s.io:8080",
output: "HTTP_PROXY=http://jo@han:*****@minikube.sigs.k8s.io:8080",
},
{
input: "http_proxy=http://k@r3n!:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
output: "HTTP_PROXY=http://k@r3n!:*****@minikube.sigs.k8s.io",
},
{
input: "https_proxy=https://fr@ank5t3in:an0th3erF@akeP@55word@minikube.sigs.k8s.io",
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)
}
}
}