diff --git a/.github/workflows/go-lint.yml b/.github/workflows/go-lint.yml index 620ed17..527839c 100644 --- a/.github/workflows/go-lint.yml +++ b/.github/workflows/go-lint.yml @@ -32,6 +32,11 @@ jobs: check-latest: true cache: true + - name: Install golangci-lint (revive replaces golint) + run: | + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b "$(go env GOPATH)/bin" v2.4.0 + golangci-lint version + - name: Build and test (Linux) if: matrix.os == 'ubuntu-latest' env: diff --git a/.github/workflows/go-verify.yml b/.github/workflows/go-verify.yml index 1b99bb3..a131c55 100644 --- a/.github/workflows/go-verify.yml +++ b/.github/workflows/go-verify.yml @@ -33,6 +33,8 @@ jobs: CGO_ENABLED: 0 GO111MODULE: on run: | + sudo apt-get update -qq + sudo apt-get install -y jq sudo sysctl net.ipv6.conf.all.disable_ipv6=0 sudo sysctl net.ipv6.conf.default.disable_ipv6=0 make verify diff --git a/.golangci.yml b/.golangci.yml index 5648022..51e3be4 100644 --- a/.golangci.yml +++ b/.golangci.yml @@ -1,35 +1,45 @@ +# golangci-lint v2 config — preserves the linters from the original v1 file: +# golint -> revive, gosimple -> staticcheck, deadcode/structcheck -> unused, +# gofmt/goimports -> formatters, typecheck is always enabled in v2. +version: "2" + linters-settings: - golint: + revive: min-confidence: 0 - misspell: locale: US +run: + timeout: 10m + build-tags: + - kqueue + linters: - disable-all: true + default: none enable: - - typecheck - - goimports - - misspell - govet - - golint + - misspell - ineffassign - - gosimple - - deadcode - - structcheck + - staticcheck + - unused - gomodguard + - revive + exclusions: + paths: + - pkg/rpc + - pkg/argon2 + generated: lax + +formatters: + enable: - gofmt + - goimports + exclusions: + paths: + - pkg/rpc + - pkg/argon2 issues: - exclude-use-default: false - exclude: - - should have a package comment - - error strings should not be capitalized or end with punctuation or a newline - -run: - skip-dirs: - - pkg/rpc - - pkg/argon2 - -service: - golangci-lint-version: 1.20.0 # use the fixed version to not introduce new linters unexpectedly + exclude-rules: + - text: should have a package comment + - text: error strings should not be capitalized or end with punctuation or a newline diff --git a/Makefile b/Makefile index 0cc17df..d4e49ca 100644 --- a/Makefile +++ b/Makefile @@ -5,6 +5,10 @@ LDFLAGS := $(shell go run buildscripts/gen-ldflags.go) GOARCH := $(shell go env GOARCH) GOOS := $(shell go env GOOS) +# v2.4.0+ is required for Go 1.25 export data format support. +GOLANGCI_VERSION ?= v2.4.0 +GOLANGCI_LINT := $(GOPATH)/bin/golangci-lint + VERSION ?= $(shell git describe --tags) TAG ?= "minio/minio:$(VERSION)" @@ -16,7 +20,10 @@ checks: getdeps: @mkdir -p ${GOPATH}/bin - @which golangci-lint 1>/dev/null || (echo "Installing golangci-lint" && curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin v1.27.0) + @if [ ! -x "$(GOLANGCI_LINT)" ] || ! $(GOLANGCI_LINT) version 2>/dev/null | grep -qE 'version 2\.'; then \ + echo "Installing golangci-lint $(GOLANGCI_VERSION)"; \ + curl -sSfL https://raw.githubusercontent.com/golangci/golangci-lint/master/install.sh | sh -s -- -b $(GOPATH)/bin $(GOLANGCI_VERSION); \ + fi @which msgp 1>/dev/null || (echo "Installing msgp" && go get github.com/tinylib/msgp@v1.1.3) @which stringer 1>/dev/null || (echo "Installing stringer" && go get golang.org/x/tools/cmd/stringer) @@ -31,8 +38,8 @@ check-gen: lint: @echo "Running $@ check" - @GO111MODULE=on ${GOPATH}/bin/golangci-lint cache clean - @GO111MODULE=on ${GOPATH}/bin/golangci-lint run --build-tags kqueue --timeout=10m --config ./.golangci.yml + @GO111MODULE=on $(GOLANGCI_LINT) cache clean + @GO111MODULE=on $(GOLANGCI_LINT) run --config ./.golangci.yml # Builds minio, runs the verifiers then runs the tests. check: test diff --git a/buildscripts/verify-build.sh b/buildscripts/verify-build.sh index 3f54678..5b1de23 100755 --- a/buildscripts/verify-build.sh +++ b/buildscripts/verify-build.sh @@ -34,6 +34,11 @@ export SECRET_KEY="minio123" export ENABLE_HTTPS=0 export GO111MODULE=on export GOGC=25 +export MINIO_CI_CD=1 +export MINIO_ROOT_USER="$ACCESS_KEY" +export MINIO_ROOT_PASSWORD="$SECRET_KEY" +export MC_HOST_verify="http://${ACCESS_KEY}:${SECRET_KEY}@${SERVER_ENDPOINT}/" +export MC_HOST_verify_ipv6="http://${ACCESS_KEY}:${SECRET_KEY}@[::1]:9000/" MINIO_CONFIG_DIR="$WORK_DIR/.minio" MINIO=( "$PWD/minio" --config-dir "$MINIO_CONFIG_DIR" ) @@ -43,22 +48,90 @@ FILE_65_MB="$MINT_DATA_DIR/datafile-65-MB" FUNCTIONAL_TESTS="$WORK_DIR/functional-tests.sh" +# Legacy MinIO admin API uses set-user-or-group-policy; mc master uses policy attach. +# Pin mc to a release whose functional-tests still use `admin policy set`. +MC_RELEASE="${MC_RELEASE:-RELEASE.2022-05-09T04-08-26Z}" + +function wait_minio_ready() { + local alias="${1:-verify}" + if "${WORK_DIR}/mc" ready --insecure "${alias}" 2>/dev/null; then + return 0 + fi + # Older mc releases have no 'ready' subcommand; poll health instead. + local i=0 + while [ "$i" -lt 60 ]; do + if curl -sf "http://${SERVER_ENDPOINT}/minio/health/live" >/dev/null 2>&1; then + return 0 + fi + i=$((i + 1)) + sleep 1 + done + return 1 +} + +function install_mc_and_tests() { + local mc_build_dir="mc-$RANDOM" + echo "fetching mc ${MC_RELEASE} (functional-tests)..." + mkdir -p "${mc_build_dir}" + if ! (cd "${mc_build_dir}" && git init -q . && git remote add origin https://github.com/minio/mc && git fetch --depth 1 origin tag "${MC_RELEASE}" && git checkout -q FETCH_HEAD); then + echo "failed to clone https://github.com/minio/mc at ${MC_RELEASE}" + purge "${mc_build_dir}" + exit 1 + fi + + local mc_os mc_arch mc_url + mc_os=$(go env GOOS) + mc_arch=$(go env GOARCH) + mc_url="https://dl.min.io/client/mc/release/${mc_os}-${mc_arch}/archive/mc.${MC_RELEASE}" + echo "downloading mc binary from ${mc_url}..." + if curl -sfL --connect-timeout 30 --max-time 300 -o "$WORK_DIR/mc" "$mc_url" || wget -q -T 30 -O "$WORK_DIR/mc" "$mc_url"; then + chmod +x "$WORK_DIR/mc" + elif command -v docker >/dev/null 2>&1 && docker pull -q "minio/mc:${MC_RELEASE}" >/dev/null 2>&1; then + echo "downloading mc binary failed, extracting from minio/mc:${MC_RELEASE} docker image" + local mc_cid="mc-extract-$$" + docker create --name "${mc_cid}" "minio/mc:${MC_RELEASE}" >/dev/null + docker cp "${mc_cid}:/usr/bin/mc" "$WORK_DIR/mc" + docker rm "${mc_cid}" >/dev/null + chmod +x "$WORK_DIR/mc" + else + echo "downloading mc binary failed, building ${MC_RELEASE} from source" + rm -f "${mc_build_dir}/go.sum" + if ! (cd "${mc_build_dir}" && go build -mod=mod -o "$WORK_DIR/mc"); then + purge "${mc_build_dir}" + exit 1 + fi + fi + + cp "${mc_build_dir}/functional-tests.sh" "$FUNCTIONAL_TESTS" + purge "${mc_build_dir}" + echo "mc ${MC_RELEASE} installed" +} + function start_minio_fs() { - "${MINIO[@]}" server "${WORK_DIR}/fs-disk" >"$WORK_DIR/fs-minio.log" 2>&1 & + export MINIO_ROOT_USER=$ACCESS_KEY + export MINIO_ROOT_PASSWORD=$SECRET_KEY + "${MINIO[@]}" server --address 127.0.0.1:9000 "${WORK_DIR}/fs-disk" >"$WORK_DIR/fs-minio.log" 2>&1 & + wait_minio_ready verify sleep 10 } function start_minio_erasure() { - "${MINIO[@]}" server "${WORK_DIR}/erasure-disk1" "${WORK_DIR}/erasure-disk2" "${WORK_DIR}/erasure-disk3" "${WORK_DIR}/erasure-disk4" >"$WORK_DIR/erasure-minio.log" 2>&1 & + export MINIO_ROOT_USER=$ACCESS_KEY + export MINIO_ROOT_PASSWORD=$SECRET_KEY + "${MINIO[@]}" server --address 127.0.0.1:9000 "${WORK_DIR}/erasure-disk1" "${WORK_DIR}/erasure-disk2" "${WORK_DIR}/erasure-disk3" "${WORK_DIR}/erasure-disk4" >"$WORK_DIR/erasure-minio.log" 2>&1 & + wait_minio_ready verify sleep 15 } function start_minio_erasure_sets() { + export MINIO_ROOT_USER=$ACCESS_KEY + export MINIO_ROOT_PASSWORD=$SECRET_KEY export MINIO_ENDPOINTS="${WORK_DIR}/erasure-disk-sets{1...32}" - "${MINIO[@]}" server > "$WORK_DIR/erasure-minio-sets.log" 2>&1 & + "${MINIO[@]}" server --address 127.0.0.1:9000 > "$WORK_DIR/erasure-minio-sets.log" 2>&1 & + wait_minio_ready verify sleep 15 } @@ -67,9 +140,9 @@ function start_minio_pool_erasure_sets() export MINIO_ROOT_USER=$ACCESS_KEY export MINIO_ROOT_PASSWORD=$SECRET_KEY export MINIO_ENDPOINTS="http://127.0.0.1:9000${WORK_DIR}/pool-disk-sets{1...4} http://127.0.0.1:9001${WORK_DIR}/pool-disk-sets{5...8}" - "${MINIO[@]}" server --address ":9000" > "$WORK_DIR/pool-minio-9000.log" 2>&1 & - "${MINIO[@]}" server --address ":9001" > "$WORK_DIR/pool-minio-9001.log" 2>&1 & - + "${MINIO[@]}" server --address 127.0.0.1:9000 > "$WORK_DIR/pool-minio-9000.log" 2>&1 & + "${MINIO[@]}" server --address 127.0.0.1:9001 > "$WORK_DIR/pool-minio-9001.log" 2>&1 & + wait_minio_ready verify sleep 40 } @@ -80,7 +153,7 @@ function start_minio_pool_erasure_sets_ipv6() export MINIO_ENDPOINTS="http://[::1]:9000${WORK_DIR}/pool-disk-sets{1...4} http://[::1]:9001${WORK_DIR}/pool-disk-sets{5...8}" "${MINIO[@]}" server --address="[::1]:9000" > "$WORK_DIR/pool-minio-ipv6-9000.log" 2>&1 & "${MINIO[@]}" server --address="[::1]:9001" > "$WORK_DIR/pool-minio-ipv6-9001.log" 2>&1 & - + wait_minio_ready verify_ipv6 sleep 40 } @@ -90,9 +163,9 @@ function start_minio_dist_erasure() export MINIO_ROOT_PASSWORD=$SECRET_KEY export MINIO_ENDPOINTS="http://127.0.0.1:9000${WORK_DIR}/dist-disk1 http://127.0.0.1:9001${WORK_DIR}/dist-disk2 http://127.0.0.1:9002${WORK_DIR}/dist-disk3 http://127.0.0.1:9003${WORK_DIR}/dist-disk4" for i in $(seq 0 3); do - "${MINIO[@]}" server --address ":900${i}" > "$WORK_DIR/dist-minio-900${i}.log" 2>&1 & + "${MINIO[@]}" server --address 127.0.0.1:900${i} > "$WORK_DIR/dist-minio-900${i}.log" 2>&1 & done - + wait_minio_ready verify sleep 40 } @@ -100,16 +173,19 @@ function run_test_fs() { start_minio_fs - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" + echo "minio server log:" cat "$WORK_DIR/fs-minio.log" fi - rm -f "$WORK_DIR/fs-minio.log" + rm -f "$WORK_DIR/fs-minio.log" "$WORK_DIR/functional-tests.log" return "$rv" } @@ -118,16 +194,19 @@ function run_test_erasure_sets() { start_minio_erasure_sets - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" + echo "minio server log:" cat "$WORK_DIR/erasure-minio-sets.log" fi - rm -f "$WORK_DIR/erasure-minio-sets.log" + rm -f "$WORK_DIR/erasure-minio-sets.log" "$WORK_DIR/functional-tests.log" return "$rv" } @@ -136,13 +215,15 @@ function run_test_pool_erasure_sets() { start_minio_pool_erasure_sets - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" for i in $(seq 0 1); do echo "server$i log:" cat "$WORK_DIR/pool-minio-900$i.log" @@ -152,6 +233,7 @@ function run_test_pool_erasure_sets() for i in $(seq 0 1); do rm -f "$WORK_DIR/pool-minio-900$i.log" done + rm -f "$WORK_DIR/functional-tests.log" return "$rv" } @@ -162,13 +244,17 @@ function run_test_pool_erasure_sets_ipv6() export SERVER_ENDPOINT="[::1]:9000" - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} + + export SERVER_ENDPOINT="127.0.0.1:9000" - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" for i in $(seq 0 1); do echo "server$i log:" cat "$WORK_DIR/pool-minio-ipv6-900$i.log" @@ -178,6 +264,7 @@ function run_test_pool_erasure_sets_ipv6() for i in $(seq 0 1); do rm -f "$WORK_DIR/pool-minio-ipv6-900$i.log" done + rm -f "$WORK_DIR/functional-tests.log" return "$rv" } @@ -186,16 +273,19 @@ function run_test_erasure() { start_minio_erasure - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" + echo "minio server log:" cat "$WORK_DIR/erasure-minio.log" fi - rm -f "$WORK_DIR/erasure-minio.log" + rm -f "$WORK_DIR/erasure-minio.log" "$WORK_DIR/functional-tests.log" return "$rv" } @@ -204,13 +294,15 @@ function run_test_dist_erasure() { start_minio_dist_erasure - (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") - rv=$? + (cd "$WORK_DIR" && "$FUNCTIONAL_TESTS") | tee "$WORK_DIR/functional-tests.log" + rv=${PIPESTATUS[0]} - pkill minio + pkill minio || true sleep 3 if [ "$rv" -ne 0 ]; then + echo "functional-tests output:" + cat "$WORK_DIR/functional-tests.log" echo "server1 log:" cat "$WORK_DIR/dist-minio-9000.log" echo "server2 log:" @@ -221,7 +313,7 @@ function run_test_dist_erasure() cat "$WORK_DIR/dist-minio-9003.log" fi - rm -f "$WORK_DIR/dist-minio-9000.log" "$WORK_DIR/dist-minio-9001.log" "$WORK_DIR/dist-minio-9002.log" "$WORK_DIR/dist-minio-9003.log" + rm -f "$WORK_DIR/dist-minio-9000.log" "$WORK_DIR/dist-minio-9001.log" "$WORK_DIR/dist-minio-9002.log" "$WORK_DIR/dist-minio-9003.log" "$WORK_DIR/functional-tests.log" return "$rv" } @@ -238,17 +330,7 @@ function __init__() mkdir -p "$MINIO_CONFIG_DIR" mkdir -p "$MINT_DATA_DIR" - MC_BUILD_DIR="mc-$RANDOM" - if ! git clone --quiet https://github.com/minio/mc "$MC_BUILD_DIR"; then - echo "failed to download https://github.com/minio/mc" - purge "${MC_BUILD_DIR}" - exit 1 - fi - - (cd "${MC_BUILD_DIR}" && go build -o "$WORK_DIR/mc") - - # remove mc source. - purge "${MC_BUILD_DIR}" + install_mc_and_tests shred -n 1 -s 1M - 1>"$FILE_1_MB" 2>/dev/null shred -n 1 -s 65M - 1>"$FILE_65_MB" 2>/dev/null @@ -256,11 +338,6 @@ function __init__() ## version is purposefully set to '3' for minio to migrate configuration file echo '{"version": "3", "credential": {"accessKey": "minio", "secretKey": "minio123"}, "region": "us-east-1"}' > "$MINIO_CONFIG_DIR/config.json" - if ! wget -q -O "$FUNCTIONAL_TESTS" https://raw.githubusercontent.com/minio/mc/master/functional-tests.sh; then - echo "failed to download https://raw.githubusercontent.com/minio/mc/master/functional-tests.sh" - exit 1 - fi - sed -i 's|-sS|-sSg|g' "$FUNCTIONAL_TESTS" chmod a+x "$FUNCTIONAL_TESTS" } diff --git a/buildscripts/verify-healing.sh b/buildscripts/verify-healing.sh index 9d5ce55..c8eb2f0 100755 --- a/buildscripts/verify-healing.sh +++ b/buildscripts/verify-healing.sh @@ -29,6 +29,10 @@ MINIO_CONFIG_DIR="$WORK_DIR/.minio" MINIO=( "$PWD/minio" --config-dir "$MINIO_CONFIG_DIR" server ) export GOGC=25 +export MINIO_CI_CD=1 +export MINIO_ROOT_USER=minio +export MINIO_ROOT_PASSWORD=minio123 +export MINIO_ALLOW_PUBLIC_BIND=on function start_minio_3_node() { export MINIO_ROOT_USER=minio diff --git a/cmd/config/constants.go b/cmd/config/constants.go index 0551519..012c60f 100644 --- a/cmd/config/constants.go +++ b/cmd/config/constants.go @@ -44,4 +44,8 @@ const ( EnvEndpoints = "MINIO_ENDPOINTS" // legacy EnvWorm = "MINIO_WORM" // legacy EnvRegion = "MINIO_REGION" // legacy + + // Production hardening: explicit opt-in for insecure defaults. + EnvAllowDefaultCredentials = "MINIO_ALLOW_DEFAULT_CREDENTIALS" + EnvAllowPublicBind = "MINIO_ALLOW_PUBLIC_BIND" ) diff --git a/cmd/config/errors.go b/cmd/config/errors.go index 9070f66..5d46672 100644 --- a/cmd/config/errors.go +++ b/cmd/config/errors.go @@ -155,6 +155,21 @@ var ( `In distributed server mode, access and secret keys should be specified via environment variables MINIO_ROOT_USER and MINIO_ROOT_PASSWORD respectively`, ) + ErrDefaultCredentialsNotAllowed = newErrFn( + "Default credentials are not allowed", + "Set strong root credentials before starting the server", + `Refusing to start with factory default credentials (minioadmin). Set MINIO_ROOT_USER and MINIO_ROOT_PASSWORD. +For local development only, set MINIO_ALLOW_DEFAULT_CREDENTIALS=on`, + ) + + ErrPublicBindNotAllowed = newErrFn( + "Public API bind is not allowed", + "Bind to a specific address or explicitly allow listening on all interfaces", + `Refusing to listen on all interfaces (e.g. :9000 or 0.0.0.0:9000) without explicit approval. +Use --address 127.0.0.1:9000 for local development, or bind to a private IP in production. +When running in a container with restricted network access, set MINIO_ALLOW_PUBLIC_BIND=on`, + ) + ErrInvalidErasureEndpoints = newErrFn( "Invalid endpoint(s) in erasure mode", "Please provide correct combination of local/remote paths", diff --git a/cmd/gateway-main.go b/cmd/gateway-main.go index 3acf441..ba7c5b4 100644 --- a/cmd/gateway-main.go +++ b/cmd/gateway-main.go @@ -137,6 +137,9 @@ func ValidateGatewayArguments(serverAddr, endpointAddr string) error { if err := CheckLocalServerAddr(serverAddr); err != nil { return err } + if err := validatePublicBind(serverAddr); err != nil { + return err + } if endpointAddr != "" { // Reject the endpoint if it points to the gateway handler itself. @@ -371,5 +374,7 @@ func StartGateway(ctx *cli.Context, gw Gateway) { printGatewayStartupMessage(getAPIEndpoints(), gatewayName) } + checkDefaultCredentials() + handleSignals() } diff --git a/cmd/gateway-main_test.go b/cmd/gateway-main_test.go index ddef8f7..e6c4ca9 100644 --- a/cmd/gateway-main_test.go +++ b/cmd/gateway-main_test.go @@ -111,11 +111,12 @@ func TestValidateGatewayArguments(t *testing.T) { endpointAddr string valid bool }{ - {":9000", "http://localhost:9001", true}, - {":9000", "http://google.com", true}, + {"127.0.0.1:9000", "http://localhost:9001", true}, + {"127.0.0.1:9000", "http://google.com", true}, {"123.123.123.123:9000", "http://localhost:9000", false}, - {":9000", "http://localhost:9000", false}, - {":9000", nonLoopBackIP + ":9000", false}, + {"127.0.0.1:9000", "http://localhost:9000", false}, + {"127.0.0.1:9000", nonLoopBackIP + ":9000", false}, + {":9000", "http://localhost:9001", false}, } for i, test := range testCases { err := ValidateGatewayArguments(test.serverAddr, test.endpointAddr) diff --git a/cmd/production-security.go b/cmd/production-security.go new file mode 100644 index 0000000..eb5a393 --- /dev/null +++ b/cmd/production-security.go @@ -0,0 +1,94 @@ +/* + * MinIO Cloud Storage, (C) 2026 bindoffice + * + * 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 cmd + +import ( + "net" + + "github.com/bindoffice/minio/cmd/config" + "github.com/bindoffice/minio/cmd/logger" + "github.com/bindoffice/minio/pkg/auth" + "github.com/bindoffice/minio/pkg/env" + xnet "github.com/bindoffice/minio/pkg/net" +) + +// isWildcardListenAddr reports whether serverAddr listens on every local interface +// (e.g. ":9000", "0.0.0.0:9000", "[::]:9000"). +func isWildcardListenAddr(serverAddr string) bool { + host, err := xnet.ParseHost(serverAddr) + if err != nil { + return false + } + if host.Name == "" { + return true + } + return host.Name == net.IPv4zero.String() || host.Name == net.IPv6zero.String() +} + +func envFlagEnabled(key string) bool { + v := env.Get(key, "") + if v == "" { + return false + } + enabled, err := config.ParseBool(v) + return err == nil && enabled +} + +// validatePublicBind returns an error when the API would listen on all interfaces +// without an explicit operator opt-in. +func validatePublicBind(serverAddr string) error { + if !isWildcardListenAddr(serverAddr) { + return nil + } + if envFlagEnabled(config.EnvAllowPublicBind) { + return nil + } + return config.ErrPublicBindNotAllowed(nil) +} + +// checkPublicBind aborts startup when validatePublicBind fails. +func checkPublicBind(serverAddr string) { + if err := validatePublicBind(serverAddr); err != nil { + logger.Fatal(err, + "Refusing to listen on all interfaces ("+serverAddr+"); use --address 127.0.0.1:9000 for local dev or set MINIO_ALLOW_PUBLIC_BIND=on when network access is restricted") + } + if isWildcardListenAddr(serverAddr) { + logger.StartupMessage("WARNING: API is listening on all interfaces (" + serverAddr + "). Restrict network access with a firewall or bind to a private address.") + } +} + +// validateDefaultCredentials returns an error when root still uses factory defaults. +func validateDefaultCredentials() error { + if !globalActiveCred.Equal(auth.DefaultCredentials) { + return nil + } + if envFlagEnabled(config.EnvAllowDefaultCredentials) { + return nil + } + return config.ErrDefaultCredentialsNotAllowed(nil) +} + +// checkDefaultCredentials aborts startup when validateDefaultCredentials fails. +func checkDefaultCredentials() { + if err := validateDefaultCredentials(); err != nil { + logger.Fatal(err, + "Refusing to start with default credentials '"+auth.DefaultAccessKey+"'; set MINIO_ROOT_USER and MINIO_ROOT_PASSWORD") + } + if globalActiveCred.Equal(auth.DefaultCredentials) { + logger.StartupMessage("WARNING: default root credentials are in use; set MINIO_ROOT_USER and MINIO_ROOT_PASSWORD before production deployment") + } +} diff --git a/cmd/production-security_test.go b/cmd/production-security_test.go new file mode 100644 index 0000000..0048433 --- /dev/null +++ b/cmd/production-security_test.go @@ -0,0 +1,77 @@ +/* + * MinIO Cloud Storage, (C) 2026 bindoffice + * + * 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 cmd + +import ( + "testing" + + "github.com/bindoffice/minio/cmd/config" + "github.com/bindoffice/minio/pkg/auth" +) + +func TestIsWildcardListenAddr(t *testing.T) { + tests := []struct { + addr string + want bool + }{ + {":9000", true}, + {"0.0.0.0:9000", true}, + {"[::]:9000", true}, + {"127.0.0.1:9000", false}, + {"[::1]:9000", false}, + {"10.0.0.5:9000", false}, + {"localhost:9000", false}, + } + for _, tt := range tests { + if got := isWildcardListenAddr(tt.addr); got != tt.want { + t.Errorf("isWildcardListenAddr(%q) = %v, want %v", tt.addr, got, tt.want) + } + } +} + +func TestValidatePublicBind(t *testing.T) { + t.Setenv(config.EnvAllowPublicBind, "") + if err := validatePublicBind(":9000"); err == nil { + t.Fatal("expected error for wildcard bind without opt-in") + } + t.Setenv(config.EnvAllowPublicBind, config.EnableOn) + if err := validatePublicBind(":9000"); err != nil { + t.Fatalf("expected opt-in to allow wildcard bind, got %v", err) + } + if err := validatePublicBind("127.0.0.1:9000"); err != nil { + t.Fatalf("loopback bind should be allowed, got %v", err) + } +} + +func TestValidateDefaultCredentials(t *testing.T) { + prev := globalActiveCred + t.Cleanup(func() { globalActiveCred = prev }) + + globalActiveCred = auth.DefaultCredentials + t.Setenv(config.EnvAllowDefaultCredentials, "") + if err := validateDefaultCredentials(); err == nil { + t.Fatal("expected error for default credentials without opt-in") + } + t.Setenv(config.EnvAllowDefaultCredentials, config.EnableOn) + if err := validateDefaultCredentials(); err != nil { + t.Fatalf("expected opt-in to allow default credentials, got %v", err) + } + globalActiveCred = auth.Credentials{AccessKey: "customuser", SecretKey: "custompass12"} + if err := validateDefaultCredentials(); err != nil { + t.Fatalf("custom credentials should be allowed, got %v", err) + } +} diff --git a/cmd/server-main.go b/cmd/server-main.go index f9ea71f..04369a0 100644 --- a/cmd/server-main.go +++ b/cmd/server-main.go @@ -35,10 +35,8 @@ import ( xhttp "github.com/bindoffice/minio/cmd/http" "github.com/bindoffice/minio/cmd/logger" "github.com/bindoffice/minio/cmd/rest" - "github.com/bindoffice/minio/pkg/auth" "github.com/bindoffice/minio/pkg/bucket/bandwidth" "github.com/bindoffice/minio/pkg/certs" - "github.com/bindoffice/minio/pkg/color" "github.com/bindoffice/minio/pkg/env" "github.com/bindoffice/minio/pkg/fips" "github.com/bindoffice/minio/pkg/madmin" @@ -117,6 +115,7 @@ func serverHandleCmdArgs(ctx *cli.Context) { handleCommonCmdArgs(ctx) logger.FatalIf(CheckLocalServerAddr(globalCLIContext.Addr), "Unable to validate passed arguments") + checkPublicBind(globalCLIContext.Addr) var err error var setupType SetupType @@ -553,10 +552,7 @@ func serverMain(ctx *cli.Context) { // Prints the formatted startup message, if err is not nil then it prints additional information as well. printStartupMessage(getAPIEndpoints(), err) - if globalActiveCred.Equal(auth.DefaultCredentials) { - msg := fmt.Sprintf("Detected default credentials '%s', please change the credentials immediately using 'MINIO_ROOT_USER' and 'MINIO_ROOT_PASSWORD'", globalActiveCred) - logger.StartupMessage(color.RedBold(msg)) - } + checkDefaultCredentials() <-globalOSSignalCh } diff --git a/go.mod b/go.mod index afce104..e49518d 100644 --- a/go.mod +++ b/go.mod @@ -1,6 +1,6 @@ module github.com/bindoffice/minio -go 1.22 +go 1.25.11 require ( cloud.google.com/go/storage v1.30.1 @@ -19,8 +19,8 @@ require ( github.com/djherbis/atime v1.0.0 github.com/dswarbrick/smart v0.0.0-20190505152634-909a45200d6d github.com/dustin/go-humanize v1.0.0 - github.com/eclipse/paho.mqtt.golang v1.3.0 - github.com/fatih/color v1.10.0 + github.com/eclipse/paho.mqtt.golang v1.5.1 + github.com/fatih/color v1.16.0 github.com/fatih/structs v1.1.0 github.com/go-ldap/ldap/v3 v3.2.4 github.com/go-sql-driver/mysql v1.5.0 @@ -38,8 +38,8 @@ require ( github.com/klauspost/readahead v1.3.1 github.com/klauspost/reedsolomon v1.9.11 github.com/lib/pq v1.9.0 - github.com/mattn/go-colorable v0.1.8 - github.com/mattn/go-isatty v0.0.12 + github.com/mattn/go-colorable v0.1.13 + github.com/mattn/go-isatty v0.0.20 github.com/miekg/dns v1.1.35 github.com/minio/cli v1.22.0 github.com/minio/highwayhash v1.0.2 @@ -76,9 +76,9 @@ require ( go.etcd.io/etcd/api/v3 v3.5.17 go.etcd.io/etcd/client/v3 v3.5.17 go.uber.org/zap v1.17.0 - golang.org/x/crypto v0.31.0 - golang.org/x/net v0.33.0 - golang.org/x/sys v0.28.0 + golang.org/x/crypto v0.51.0 + golang.org/x/net v0.55.0 + golang.org/x/sys v0.45.0 google.golang.org/api v0.126.0 gopkg.in/yaml.v2 v2.4.0 ) @@ -107,11 +107,11 @@ require ( github.com/google/s2a-go v0.1.4 // indirect github.com/googleapis/enterprise-certificate-proxy v0.2.3 // indirect github.com/googleapis/gax-go/v2 v2.11.0 // indirect - github.com/gorilla/websocket v1.4.2 // indirect + github.com/gorilla/websocket v1.5.3 // indirect github.com/hashicorp/errwrap v1.0.0 // indirect - github.com/hashicorp/go-cleanhttp v0.5.1 // indirect + github.com/hashicorp/go-cleanhttp v0.5.2 // indirect github.com/hashicorp/go-multierror v1.0.0 // indirect - github.com/hashicorp/go-retryablehttp v0.5.4 // indirect + github.com/hashicorp/go-retryablehttp v0.7.7 // indirect github.com/hashicorp/go-rootcerts v1.0.1 // indirect github.com/hashicorp/go-sockaddr v1.0.2 // indirect github.com/hashicorp/go-uuid v1.0.2 // indirect @@ -150,8 +150,8 @@ require ( go.uber.org/atomic v1.7.0 // indirect go.uber.org/multierr v1.6.0 // indirect golang.org/x/oauth2 v0.21.0 // indirect - golang.org/x/sync v0.10.0 // indirect - golang.org/x/text v0.21.0 // indirect + golang.org/x/sync v0.20.0 // indirect + golang.org/x/text v0.37.0 // indirect golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 // indirect golang.org/x/xerrors v0.0.0-20220907171357-04be3eba64a2 // indirect google.golang.org/appengine v1.6.7 // indirect diff --git a/go.sum b/go.sum index 7ee69b9..64ddb69 100644 --- a/go.sum +++ b/go.sum @@ -104,8 +104,8 @@ github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21 h1:YEetp8 github.com/eapache/go-xerial-snappy v0.0.0-20180814174437-776d5712da21/go.mod h1:+020luEh2TKB4/GOp8oxxtq0Daoen/Cii55CzbTV6DU= github.com/eapache/queue v1.1.0 h1:YOEu7KNc61ntiQlcEeUIoDTJ2o8mQznoNvUhiigpIqc= github.com/eapache/queue v1.1.0/go.mod h1:6eCeP0CKFpHLu8blIFXhExK/dRa7WDZfr6jVFPTqq+I= -github.com/eclipse/paho.mqtt.golang v1.3.0 h1:MU79lqr3FKNKbSrGN7d7bNYqh8MwWW7Zcx0iG+VIw9I= -github.com/eclipse/paho.mqtt.golang v1.3.0/go.mod h1:eTzb4gxwwyWpqBUHGQZ4ABAV7+Jgm1PklsYT/eo8Hcc= +github.com/eclipse/paho.mqtt.golang v1.5.1 h1:/VSOv3oDLlpqR2Epjn1Q7b2bSTplJIeV2ISgCl2W7nE= +github.com/eclipse/paho.mqtt.golang v1.5.1/go.mod h1:1/yJCneuyOoCOzKSsOTUc0AJfpsItBGWvYpBLimhArU= github.com/envoyproxy/go-control-plane v0.9.0/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.1-0.20191026205805-5f8ba28d4473/go.mod h1:YTl/9mNaCwkRvm6d1a2C3ymFceY/DCBVvsKhRF0iEA4= github.com/envoyproxy/go-control-plane v0.9.4/go.mod h1:6rpuAdCZL397s3pYoYcLgu1mIlRU8Am5FuJP05cCM98= @@ -114,8 +114,8 @@ github.com/envoyproxy/go-control-plane v0.9.10-0.20210907150352-cf90f659a021/go. github.com/envoyproxy/protoc-gen-validate v0.1.0/go.mod h1:iSmxcyjqTsJpI2R4NaDN7+kN2VEUnK/pcBlmesArF7c= github.com/fatih/color v1.7.0/go.mod h1:Zm6kSWBoL9eyXnKyktHP6abPY2pDugNf5KwzbycvMj4= github.com/fatih/color v1.9.0/go.mod h1:eQcE1qtQxscV5RaZvpXrrb8Drkc3/DdQ+uUYCNjL+zU= -github.com/fatih/color v1.10.0 h1:s36xzo75JdqLaaWoiEHk767eHiwo0598uUxyfiPkDsg= -github.com/fatih/color v1.10.0/go.mod h1:ELkj/draVOlAH/xkhN6mQ50Qd0MPOk5AAr3maGEBuJM= +github.com/fatih/color v1.16.0 h1:zmkK9Ngbjj+K0yRhTVONQh1p/HknKYSlNT+vZCzyokM= +github.com/fatih/color v1.16.0/go.mod h1:fL2Sau1YI5c0pdGEVCbKQbLXB6edEj1ZgiY4NijnWvE= github.com/fatih/structs v1.1.0 h1:Q7juDM0QtcnhCpeyLGQKyg4TOIghuNXrkL32pHAUMxo= github.com/fatih/structs v1.1.0/go.mod h1:9NiDSp5zOcgEDl+j00MP/WkGVPOlPRLejGD8Ga6PJ7M= github.com/felixge/httpsnoop v1.0.1 h1:lvB5Jl89CsZtGIWuTcDM1E/vkVs49/Ml7JJe07l8SPQ= @@ -203,19 +203,21 @@ github.com/gorilla/securecookie v1.1.1/go.mod h1:ra0sb63/xPlUeL+yeDciTfxMRAA+MP+ github.com/gorilla/sessions v1.2.0/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= github.com/gorilla/sessions v1.2.1 h1:DHd3rPN5lE3Ts3D8rKkQ8x/0kqfeNmBAaiSi+o7FsgI= github.com/gorilla/sessions v1.2.1/go.mod h1:dk2InVEVJ0sfLlnXv9EAgkf6ecYs/i80K/zI+bUmuGM= -github.com/gorilla/websocket v1.4.2 h1:+/TMaTYc4QFitKJxsQ7Yye35DkWvkdLcvGKqM+x0Ufc= -github.com/gorilla/websocket v1.4.2/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= +github.com/gorilla/websocket v1.5.3 h1:saDtZ6Pbx/0u+bgYQ3q96pZgCzfhKXGPqt7kZ72aNNg= +github.com/gorilla/websocket v1.5.3/go.mod h1:YR8l580nyteQvAITg2hZ9XVh4b55+EU/adAjf1fMHhE= github.com/grpc-ecosystem/grpc-gateway v1.16.0/go.mod h1:BDjrQk3hbvj6Nolgz8mAMFbcEtjT1g+wF4CSlocrBnw= github.com/hashicorp/errwrap v1.0.0 h1:hLrqtEDnRye3+sgx6z4qVLNuviH3MR5aQ0ykNJa/UYA= github.com/hashicorp/errwrap v1.0.0/go.mod h1:YH+1FKiLXxHSkmPseP+kNlulaMuP3n2brvKWEqk/Jc4= github.com/hashicorp/go-cleanhttp v0.5.0/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= -github.com/hashicorp/go-cleanhttp v0.5.1 h1:dH3aiDG9Jvb5r5+bYHsikaOUIpcM0xvgMXVoDkXMzJM= github.com/hashicorp/go-cleanhttp v0.5.1/go.mod h1:JpRdi6/HCYpAwUzNwuwqhbovhLtngrth3wmdIIUrZ80= +github.com/hashicorp/go-cleanhttp v0.5.2 h1:035FKYIWjmULyFRBKPs8TBQoi0x6d9G4xc9neXJWAZQ= +github.com/hashicorp/go-cleanhttp v0.5.2/go.mod h1:kO/YDlP8L1346E6Sodw+PrpBSV4/SoxCXGY6BqNFT48= github.com/hashicorp/go-hclog v0.0.0-20180709165350-ff2cf002a8dd/go.mod h1:9bjs9uLqI8l75knNv3lV1kA55veR+WUPSiKIWcQHudI= github.com/hashicorp/go-hclog v0.8.0/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= github.com/hashicorp/go-hclog v0.9.1/go.mod h1:5CU+agLiy3J7N7QjHK5d05KxGsuXiQLrjA0H7acj2lQ= -github.com/hashicorp/go-hclog v0.14.1 h1:nQcJDQwIAGnmoUWp8ubocEX40cCml/17YkF6csQLReU= github.com/hashicorp/go-hclog v0.14.1/go.mod h1:whpDNt7SSdeAju8AWKIWsul05p54N/39EeqMAyrmvFQ= +github.com/hashicorp/go-hclog v1.6.3 h1:Qr2kF+eVWjTiYmU7Y31tYlP1h0q/X3Nl3tPGdaB11/k= +github.com/hashicorp/go-hclog v1.6.3/go.mod h1:W4Qnvbt70Wk/zYJryRzDRU/4r0kIg0PVHBcfoyhpF5M= github.com/hashicorp/go-immutable-radix v1.0.0 h1:AKDB1HM5PWEA7i4nhcpwOrO2byshxBjXVn/J/3+z5/0= github.com/hashicorp/go-immutable-radix v1.0.0/go.mod h1:0y9vanUI8NX6FsYoO3zeMjhV/C5i9g4Q3DwcSNZ4P60= github.com/hashicorp/go-msgpack v0.5.5/go.mod h1:ahLV/dePpqEmjfWmKiqvPkv/twdG7iPBM1vqhUKIvfM= @@ -225,8 +227,9 @@ github.com/hashicorp/go-multierror v1.0.0 h1:iVjPR7a6H0tWELX5NxNe7bYopibicUzc7uP github.com/hashicorp/go-multierror v1.0.0/go.mod h1:dHtQlpGsu+cZNNAkkCN/P3hoUDHhCYQXV3UM06sGGrk= github.com/hashicorp/go-plugin v1.0.1/go.mod h1:++UyYGoz3o5w9ZzAdZxtQKrWWP+iqPBn3cQptSMzBuY= github.com/hashicorp/go-retryablehttp v0.5.3/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= -github.com/hashicorp/go-retryablehttp v0.5.4 h1:1BZvpawXoJCWX6pNtow9+rpEj+3itIlutiqnntI6jOE= github.com/hashicorp/go-retryablehttp v0.5.4/go.mod h1:9B5zBasrRhHXnJnui7y6sL7es7NDiJgTc6Er0maI1Xs= +github.com/hashicorp/go-retryablehttp v0.7.7 h1:C8hUCYzor8PIfXHa4UrZkU4VvK8o9ISHxT2Q8+VepXU= +github.com/hashicorp/go-retryablehttp v0.7.7/go.mod h1:pkQpWZeYWskR+D1tR2O5OcBFOxfA7DoAO6xtkuQnHTk= github.com/hashicorp/go-rootcerts v1.0.1 h1:DMo4fmknnz0E0evoNYnV48RjWndOsmd6OW+09R3cEP8= github.com/hashicorp/go-rootcerts v1.0.1/go.mod h1:pqUvnprVnM5bf7AOirdbb01K4ccR319Vf4pU3K5EGc8= github.com/hashicorp/go-sockaddr v1.0.2 h1:ztczhD1jLxIRjVejw8gFomI1BQZOe2WoVOu0SyteCQc= @@ -310,8 +313,8 @@ github.com/mailru/easyjson v0.7.6 h1:8yTIVnZgCoiM1TgqoeTl+LfU5Jg6/xL3QhGQnimLYnA github.com/mailru/easyjson v0.7.6/go.mod h1:xzfreul335JAWq5oZzymOObrkdz5UnU4kGfJJLY9Nlc= github.com/mattn/go-colorable v0.0.9/go.mod h1:9vuHe8Xs5qXnSaW/c/ABM9alt+Vo+STaOChaDxuIBZU= github.com/mattn/go-colorable v0.1.4/go.mod h1:U0ppj6V5qS13XJ6of8GYAs25YV2eR4EVcfRqFIhoBtE= -github.com/mattn/go-colorable v0.1.8 h1:c1ghPdyEDarC70ftn0y+A/Ee++9zz8ljHG1b13eJ0s8= -github.com/mattn/go-colorable v0.1.8/go.mod h1:u6P/XSegPjTcexA+o6vUJrdnUu04hMope9wVRipJSqc= +github.com/mattn/go-colorable v0.1.13 h1:fFA4WZxdEF4tXPZVKMLwD8oUnCTTo08duU7wxecdEvA= +github.com/mattn/go-colorable v0.1.13/go.mod h1:7S9/ev0klgBDR4GtXTXX8a3vIGJpMovkB8vQcUbaXHg= github.com/mattn/go-ieproxy v0.0.0-20190702010315-6dee0af9227d/go.mod h1:31jz6HNzdxOmlERGGEc4v/dMssOfmp2p5bT/okiKFFc= github.com/mattn/go-ieproxy v0.0.1 h1:qiyop7gCflfhwCzGyeT0gro3sF9AIg9HU98JORTkqfI= github.com/mattn/go-ieproxy v0.0.1/go.mod h1:pYabZ6IHcRpFh7vIaLfK7rdcWgFEb3SFJ6/gNWuh88E= @@ -319,8 +322,9 @@ github.com/mattn/go-isatty v0.0.3/go.mod h1:M+lRXTBqGeGNdLjl/ufCoiOlB5xdOkqRJdNx github.com/mattn/go-isatty v0.0.8/go.mod h1:Iq45c/XA43vh69/j3iqttzPXn0bhXyGjM0Hdxcsrc5s= github.com/mattn/go-isatty v0.0.10/go.mod h1:qgIWMr58cqv1PHHyhnkY9lrL7etaEgOFcMEpPG5Rm84= github.com/mattn/go-isatty v0.0.11/go.mod h1:PhnuNfih5lzO57/f3n+odYbM4JtupLOxQOAqxQCu2WE= -github.com/mattn/go-isatty v0.0.12 h1:wuysRhFDzyxgEmMf5xjvJ2M9dZoWAXNNr5LSBS7uHXY= -github.com/mattn/go-isatty v0.0.12/go.mod h1:cbi8OIDigv2wuxKPP5vlRcQ1OAZbq2CE4Kysco4FUpU= +github.com/mattn/go-isatty v0.0.16/go.mod h1:kYGgaQfpe5nmfYZH+SKPsOc2e4SrIfOl2e/yFXSvRLM= +github.com/mattn/go-isatty v0.0.20 h1:xfD0iDuEKnDkl03q4limB+vH+GxLEtL/jb4xVJSWWEY= +github.com/mattn/go-isatty v0.0.20/go.mod h1:W+V8PltTTMOvKvAeJH7IuucS94S2C6jfK/D7dTCTo3Y= github.com/mattn/go-runewidth v0.0.4 h1:2BvfKmzob6Bmd4YsL0zygOqfdFnK7GR4QL06Do4/p7Y= github.com/mattn/go-runewidth v0.0.4/go.mod h1:LwmH8dsx7+W8Uxz3IHJYH5QSwggIsqBzpuz5H//U1FU= github.com/matttproud/golang_protobuf_extensions v1.0.1/go.mod h1:D8He9yQNgCq6Z5Ld7szi9bcBfOoFv/3dc6xSMkL2PC0= @@ -522,8 +526,8 @@ golang.org/x/crypto v0.0.0-20201112155050-0c6587e931a9/go.mod h1:LzIPMQfyMNhhGPh golang.org/x/crypto v0.0.0-20210220033148-5ea612d1eb83/go.mod h1:jdWPYTVW3xRLrWPugEBEK3UY2ZEsg3UU495nc5E+M+I= golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc= golang.org/x/crypto v0.0.0-20220314234659-1baeb1ce4c0b/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4= -golang.org/x/crypto v0.31.0 h1:ihbySMvVjLAeSH1IbfcRTkD/iNscyz8rGzjF/E5hV6U= -golang.org/x/crypto v0.31.0/go.mod h1:kDsLvtWBEx7MV9tJOj9bnXsPbxwJQ6csT/x4KIN4Ssk= +golang.org/x/crypto v0.51.0 h1:IBPXwPfKxY7cWQZ38ZCIRPI50YLeevDLlLnyC5wRGTI= +golang.org/x/crypto v0.51.0/go.mod h1:8AdwkbraGNABw2kOX6YFPs3WM22XqI4EXEd8g+x7Oc8= golang.org/x/exp v0.0.0-20190121172915-509febef88a4/go.mod h1:CJ0aWSM057203Lf6IL+f9T1iT9GByDxfZKAQTCR3kQA= golang.org/x/lint v0.0.0-20181026193005-c67002cb31c3/go.mod h1:UVdnD1Gm6xHRNCYTkRU2/jEulfH38KcIWyp/GAMgvoE= golang.org/x/lint v0.0.0-20190227174305-5b3e6a55c961/go.mod h1:wehouNa3lNwaWXcvxsM5YxQ5yQlVC4a0KAMCusXpPoU= @@ -546,7 +550,6 @@ golang.org/x/net v0.0.0-20191112182307-2180aed22343/go.mod h1:z5CRVTTTmAJ677TzLL golang.org/x/net v0.0.0-20200114155413-6afb5195e5aa/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200202094626-16171245cfb2/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= golang.org/x/net v0.0.0-20200226121028-0de0cce0169b/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s= -golang.org/x/net v0.0.0-20200425230154-ff2c4b7c35a0/go.mod h1:qpuaurCH72eLCgpAm/N6yyVIVM9cpaDIP3A8BGJEC5A= golang.org/x/net v0.0.0-20200707034311-ab3426394381/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200822124328-c89045814202/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= golang.org/x/net v0.0.0-20200904194848-62affa334b73/go.mod h1:/O7V0waA8r7cgGh81Ro3o1hOxt32SMVPicZroKQ2sZA= @@ -555,8 +558,8 @@ golang.org/x/net v0.0.0-20201110031124-69a78807bb2b/go.mod h1:sp8m0HH+o8qH0wwXwY golang.org/x/net v0.0.0-20210226172049-e18ecbb05110/go.mod h1:m0MpNAwzfU5UDzcl9v0D8zg8gWTRqZa9RBIspLL5mdg= golang.org/x/net v0.0.0-20211112202133-69e39bad7dc2/go.mod h1:9nx3DQGgdP8bBQD5qxJ1jj9UTztislL4KSBs9R2vV5Y= golang.org/x/net v0.0.0-20220722155237-a158d28d115b/go.mod h1:XRhObCWvk6IyKnWLug+ECip1KBveYUHfp+8e9klMJ9c= -golang.org/x/net v0.33.0 h1:74SYHlV8BIgHIFC/LrYkOGIwL19eTYXQ5wc6TBuO36I= -golang.org/x/net v0.33.0/go.mod h1:HXLR5J+9DxmrqMwG9qjGCxZ+zKXxBru04zlTvWlWuN4= +golang.org/x/net v0.55.0 h1:bcvxaJn3e1U6InsFWt1JUq1aSjnRxLzT2rtD2KfkDF8= +golang.org/x/net v0.55.0/go.mod h1:L5U2KuzuOe1lY7Z+aWVIKK6qEeJXnXV9yzGA+WCHJww= golang.org/x/oauth2 v0.0.0-20180821212333-d2e6202438be/go.mod h1:N/0e6XlmueqKjAGxoOufVs8QHGRruUQn6yWY3a++T0U= golang.org/x/oauth2 v0.0.0-20200107190931-bf48bf16ab8d/go.mod h1:gOpvHmFTYa4IltrdGE7lF6nIHvwfUNPOp7c8zoXwtLw= golang.org/x/oauth2 v0.21.0 h1:tsimM75w1tF/uws5rbeHzIWxEqElMehnc+iW793zsZs= @@ -570,8 +573,8 @@ golang.org/x/sync v0.0.0-20190911185100-cd5d95a43a6e/go.mod h1:RxMgew5VJxzue5/jJ golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20201207232520-09787c993a3a/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= golang.org/x/sync v0.0.0-20220722155255-886fb9371eb4/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM= -golang.org/x/sync v0.10.0 h1:3NQrjDixjgGwUOCaF8w2+VYHv0Ve/vGYSbdkTa98gmQ= -golang.org/x/sync v0.10.0/go.mod h1:Czt+wKu1gCyEFDUtn0jG5QVvpJ6rzVqr5aXyt9drQfk= +golang.org/x/sync v0.20.0 h1:e0PTpb7pjO8GAtTs2dQ6jYa5BWYlMuX047Dco/pItO4= +golang.org/x/sync v0.20.0/go.mod h1:9xrNwdLfx4jkKbNva9FpL6vEN7evnE43NNNJQ2LF3+0= golang.org/x/sys v0.0.0-20180823144017-11551d06cbcc/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180830151530-49385e6e1522/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= golang.org/x/sys v0.0.0-20180926160741-c2ed4eda69e7/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY= @@ -588,9 +591,7 @@ golang.org/x/sys v0.0.0-20190924154521-2837fb4f24fe/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20191008105621-543471e840be/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191026070338-33540a1f6037/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20191112214154-59a1497f0cea/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200116001909-b77594299b42/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200202164722-d101bd2416d5/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= -golang.org/x/sys v0.0.0-20200223170610-d5e6a3e2c0ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200302150141-5c8b2ff67527/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200323222414-85ca7c5b95cd/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= golang.org/x/sys v0.0.0-20200625212154-ddb9806d33ae/go.mod h1:h1NjWce9XRLGQEsW7wpKNCjG9DtNlClVuFLEZdDNbEs= @@ -603,8 +604,10 @@ golang.org/x/sys v0.0.0-20210423082822-04245dca01da/go.mod h1:h1NjWce9XRLGQEsW7w golang.org/x/sys v0.0.0-20210615035016-665e8c7367d1/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220520151302-bc2c85ada10a/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= golang.org/x/sys v0.0.0-20220722155257-8c9f86f7a55f/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= -golang.org/x/sys v0.28.0 h1:Fksou7UEQUWlKvIdsqzJmUmCX3cZuD2+P3XyyzwMhlA= -golang.org/x/sys v0.28.0/go.mod h1:/VUhepiaJMQUp4+oa/7Zr1D23ma6VTLIYjOOTFZPUcA= +golang.org/x/sys v0.0.0-20220811171246-fbc7d0a398ab/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.6.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg= +golang.org/x/sys v0.45.0 h1:dO4czNzziLiiXplLQgBCEpCvXQ3dnkn0SdaZSYdQ+FY= +golang.org/x/sys v0.45.0/go.mod h1:4GL1E5IUh+htKOUEOaiffhrAeqysfVGipDYzABqnCmw= golang.org/x/term v0.0.0-20201117132131-f5c789dd3221/go.mod h1:Nr5EML6q2oocZ2LXRh80K7BxOlk5/8JxuGnuhpl+muw= golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo= golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8= @@ -615,8 +618,8 @@ golang.org/x/text v0.3.3/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.6/go.mod h1:5Zoc/QRtKVWzQhOtBMvqHzDpF6irO9z98xDceosuGiQ= golang.org/x/text v0.3.7/go.mod h1:u+2+/6zg+i71rQMx5EYifcz6MCKuco9NR6JIITiCfzQ= golang.org/x/text v0.3.8/go.mod h1:E6s5w1FMmriuDzIBO73fBruAKo1PCIq6d2Q6DHfQ8WQ= -golang.org/x/text v0.21.0 h1:zyQAAkrwaneQ066sspRyJaG9VNi/YJ1NfzcGB3hZ/qo= -golang.org/x/text v0.21.0/go.mod h1:4IBbMaMmOPCJ8SecivzSH54+73PCFmPWxNTLm+vZkEQ= +golang.org/x/text v0.37.0 h1:Cqjiwd9eSg8e0QAkyCaQTNHFIIzWtidPahFWR83rTrc= +golang.org/x/text v0.37.0/go.mod h1:a5sjxXGs9hsn/AJVwuElvCAo9v8QYLzvavO5z2PiM38= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4 h1:SvFZT6jyqRaOeXpc5h/JSfZenJ2O330aBsf7JfSUXmQ= golang.org/x/time v0.0.0-20190308202827-9d24e82272b4/go.mod h1:tRJNPiyCQ0inRvYxbN9jk5I+vvW/OXSQhTDSoE431IQ= golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=