Exemple #1
0
// Validate check if all necessary fields from CreateBasicAuthSecretOptions are present.
func (o CreateBasicAuthSecretOptions) Validate() error {
	if len(o.SecretName) == 0 {
		return errors.New("basic authentication secret name must be present")
	}

	if o.PromptForPassword {
		if len(o.Password) != 0 {
			return errors.New("must provide either --prompt or --password flag")
		}
		if cmdutil.IsTerminal(o.Reader) {
			o.Password = cmdutil.PromptForPasswordString(o.Reader, o.Out, "Password: "******"password must be provided")
			}
		} else {
			return errors.New("provided reader is not a terminal")
		}
	} else {
		if len(o.Username) == 0 && len(o.Password) == 0 && len(o.CertificatePath) == 0 {
			return errors.New("must provide basic authentication credentials")
		}
	}

	return nil
}
Exemple #2
0
// Complete fills CreateBasicAuthSecretOptions fields with data and checks for mutual exclusivity
// between flags from different option groups.
func (o *CreateBasicAuthSecretOptions) Complete(f *kcmdutil.Factory, args []string) error {
	if len(args) != 1 {
		return errors.New("must have exactly one argument: secret name")
	}
	o.SecretName = args[0]

	if o.PromptForPassword {
		if len(o.Password) != 0 {
			return errors.New("must provide either --prompt or --password flag")
		}
		if !term.IsTerminal(o.Reader) {
			return errors.New("provided reader is not a terminal")
		}

		o.Password = cmdutil.PromptForPasswordString(o.Reader, o.Out, "Password: "******"password must be provided")
		}
	}

	if f != nil {
		client, err := f.Client()
		if err != nil {
			return err
		}
		namespace, _, err := f.DefaultNamespace()
		if err != nil {
			return err
		}
		o.SecretsInterface = client.Secrets(namespace)
	}

	return nil
}
Exemple #3
0
func (c *BasicChallengeHandler) HandleChallenge(requestURL string, headers http.Header) (http.Header, bool, error) {
	if c.prompted {
		glog.V(2).Info("already prompted for challenge, won't prompt again")
		return nil, false, nil
	}
	if c.handled {
		glog.V(2).Info("already handled basic challenge")
		return nil, false, nil
	}

	username := c.Username
	password := c.Password

	missingUsername := len(username) == 0
	missingPassword := len(password) == 0

	if (missingUsername || missingPassword) && c.Reader != nil {
		w := c.Writer
		if w == nil {
			w = os.Stdout
		}

		if _, realm := basicRealm(headers); len(realm) > 0 {
			fmt.Fprintf(w, "Authentication required for %s (%s)\n", c.Host, realm)
		} else {
			fmt.Fprintf(w, "Authentication required for %s\n", c.Host)
		}
		if missingUsername {
			username = util.PromptForString(c.Reader, w, "Username: "******"Username: %s\n", username)
		}
		if missingPassword {
			password = util.PromptForPasswordString(c.Reader, w, "Password: "******":") {
			return nil, false, fmt.Errorf("username %s is invalid for basic auth", username)
		}
		responseHeaders := http.Header{}
		responseHeaders.Set("Authorization", getBasicHeader(username, password))
		// remember so we don't re-handle non-interactively
		c.handled = true
		return responseHeaders, true, nil
	}

	glog.V(2).Info("no username or password available")
	return nil, false, nil
}
Exemple #4
0
func (c *BasicChallengeHandler) HandleChallenge(headers http.Header) (http.Header, bool, error) {
	if c.prompted {
		glog.V(2).Info("already prompted for challenge, won't prompt again")
		return nil, false, nil
	}
	if c.Reader == nil && c.handled {
		glog.V(2).Info("already handled basic challenge, no reader to alter inputs")
		return nil, false, nil
	}

	username := c.Username
	password := c.Password

	missingUsername := len(username) == 0
	missingPassword := len(password) == 0

	if (missingUsername || missingPassword) && c.Reader != nil {
		w := c.Writer
		if w == nil {
			w = os.Stdout
		}

		if _, realm := basicRealm(headers); len(realm) > 0 {
			fmt.Fprintf(w, "Authentication required for %s (%s)\n", c.Host, realm)
		} else {
			fmt.Fprintf(w, "Authentication required for %s\n", c.Host)
		}
		if missingUsername {
			username = util.PromptForString(c.Reader, w, "Username: "******"Username: %s\n", username)
		}
		if missingPassword {
			password = util.PromptForPasswordString(c.Reader, w, "Password: "******"Authorization", getBasicHeader(username, password))
		// remember so we don't re-handle non-interactively
		c.handled = true
		return responseHeaders, true, nil
	}

	glog.V(2).Info("no username or password available")
	return nil, false, nil
}
// Do watches for unauthorized challenges.  If we know to respond, we respond to the challenge
func (client *challengingClient) Do(req *http.Request) (*http.Response, error) {
	// Set custom header required by server to avoid CSRF attacks on browsers using basic auth
	if req.Header == nil {
		req.Header = http.Header{}
	}
	req.Header.Set(CSRFTokenHeader, "1")

	resp, err := client.delegate.Do(req)
	if err != nil {
		return nil, err
	}

	if resp.StatusCode == http.StatusUnauthorized {
		if wantsBasicAuth, realm := isBasicAuthChallenge(resp); wantsBasicAuth {
			username := client.defaultUsername
			password := client.defaultPassword

			missingUsername := len(username) == 0
			missingPassword := len(password) == 0

			url := *req.URL
			url.Path, url.RawQuery, url.Fragment = "", "", ""

			if (missingUsername || missingPassword) && client.reader != nil {
				fmt.Printf("Authentication required for %s (%s)\n", &url, realm)
				if missingUsername {
					username = util.PromptForString(client.reader, "Username: "******"Password: ")
				}
			}

			if len(username) > 0 || len(password) > 0 {
				client.delegate.Transport = kclient.NewBasicAuthRoundTripper(username, password, client.delegate.Transport)
				return client.delegate.Do(resp.Request)
			}
		}
	}
	return resp, err
}