2015-03-04 07:34:32 +00:00
|
|
|
package command
|
|
|
|
|
|
|
|
import (
|
2015-05-21 02:43:47 +00:00
|
|
|
"bufio"
|
2016-04-20 18:38:20 +00:00
|
|
|
"encoding/json"
|
2015-03-30 17:55:41 +00:00
|
|
|
"fmt"
|
2015-05-21 02:43:47 +00:00
|
|
|
"io"
|
2015-03-30 17:55:41 +00:00
|
|
|
"os"
|
2015-04-02 00:01:10 +00:00
|
|
|
"sort"
|
2016-06-15 16:35:30 +00:00
|
|
|
"strconv"
|
2015-03-04 07:34:32 +00:00
|
|
|
"strings"
|
2015-03-30 17:55:41 +00:00
|
|
|
|
2015-04-06 16:53:43 +00:00
|
|
|
"github.com/hashicorp/vault/api"
|
2015-04-08 06:29:49 +00:00
|
|
|
"github.com/hashicorp/vault/helper/kv-builder"
|
2015-03-30 17:55:41 +00:00
|
|
|
"github.com/hashicorp/vault/helper/password"
|
2016-04-01 17:16:05 +00:00
|
|
|
"github.com/hashicorp/vault/meta"
|
2015-04-08 06:29:49 +00:00
|
|
|
"github.com/mitchellh/mapstructure"
|
2017-08-24 22:23:40 +00:00
|
|
|
"github.com/posener/complete"
|
2015-04-02 00:01:10 +00:00
|
|
|
"github.com/ryanuber/columnize"
|
2015-03-04 07:34:32 +00:00
|
|
|
)
|
|
|
|
|
2015-04-06 03:50:18 +00:00
|
|
|
// AuthHandler is the interface that any auth handlers must implement
|
|
|
|
// to enable auth via the CLI.
|
|
|
|
type AuthHandler interface {
|
2017-08-31 20:57:00 +00:00
|
|
|
Auth(*api.Client, map[string]string) (*api.Secret, error)
|
2015-04-06 03:50:18 +00:00
|
|
|
Help() string
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:34:32 +00:00
|
|
|
// AuthCommand is a Command that handles authentication.
|
|
|
|
type AuthCommand struct {
|
2016-04-01 17:16:05 +00:00
|
|
|
meta.Meta
|
2015-04-06 03:50:18 +00:00
|
|
|
|
|
|
|
Handlers map[string]AuthHandler
|
2015-05-23 18:22:35 +00:00
|
|
|
|
|
|
|
// The fields below can be overwritten for tests
|
|
|
|
testStdin io.Reader
|
2015-03-04 07:34:32 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (c *AuthCommand) Run(args []string) int {
|
2016-06-15 20:45:07 +00:00
|
|
|
var method, authPath string
|
2017-07-12 19:04:34 +00:00
|
|
|
var methods, methodHelp, noVerify, noStore, tokenOnly bool
|
2016-04-01 17:16:05 +00:00
|
|
|
flags := c.Meta.FlagSet("auth", meta.FlagSetDefault)
|
2015-04-02 00:01:10 +00:00
|
|
|
flags.BoolVar(&methods, "methods", false, "")
|
2015-04-06 16:38:16 +00:00
|
|
|
flags.BoolVar(&methodHelp, "method-help", false, "")
|
2015-08-19 02:18:23 +00:00
|
|
|
flags.BoolVar(&noVerify, "no-verify", false, "")
|
2017-06-05 20:36:28 +00:00
|
|
|
flags.BoolVar(&noStore, "no-store", false, "")
|
2017-07-12 19:04:34 +00:00
|
|
|
flags.BoolVar(&tokenOnly, "token-only", false, "")
|
2015-03-04 07:34:32 +00:00
|
|
|
flags.StringVar(&method, "method", "", "method")
|
2016-06-15 20:45:07 +00:00
|
|
|
flags.StringVar(&authPath, "path", "", "")
|
2015-03-04 07:34:32 +00:00
|
|
|
flags.Usage = func() { c.Ui.Error(c.Help()) }
|
|
|
|
if err := flags.Parse(args); err != nil {
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2015-04-02 00:01:10 +00:00
|
|
|
if methods {
|
|
|
|
return c.listMethods()
|
|
|
|
}
|
|
|
|
|
2015-03-29 23:42:45 +00:00
|
|
|
args = flags.Args()
|
|
|
|
|
2016-04-01 20:02:18 +00:00
|
|
|
tokenHelper, err := c.TokenHelper()
|
2015-03-30 17:55:41 +00:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error initializing token helper: %s\n\n"+
|
|
|
|
"Please verify that the token helper is available and properly\n"+
|
|
|
|
"configured for your system. Please refer to the documentation\n"+
|
|
|
|
"on token helpers for more information.",
|
|
|
|
err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// token is where the final token will go
|
2015-04-06 03:50:18 +00:00
|
|
|
handler := c.Handlers[method]
|
2015-05-21 02:43:47 +00:00
|
|
|
|
2015-05-23 18:22:35 +00:00
|
|
|
// Read token from stdin if first arg is exactly "-"
|
|
|
|
var stdin io.Reader = os.Stdin
|
|
|
|
if c.testStdin != nil {
|
|
|
|
stdin = c.testStdin
|
|
|
|
}
|
|
|
|
|
2015-05-21 02:43:47 +00:00
|
|
|
if len(args) > 0 && args[0] == "-" {
|
2015-05-23 18:22:35 +00:00
|
|
|
stdinR := bufio.NewReader(stdin)
|
|
|
|
args[0], err = stdinR.ReadString('\n')
|
2015-05-21 02:43:47 +00:00
|
|
|
if err != nil && err != io.EOF {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Error reading from stdin: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
args[0] = strings.TrimSpace(args[0])
|
|
|
|
}
|
|
|
|
|
2015-03-30 17:55:41 +00:00
|
|
|
if method == "" {
|
2015-04-06 03:50:18 +00:00
|
|
|
token := ""
|
2015-03-30 17:55:41 +00:00
|
|
|
if len(args) > 0 {
|
|
|
|
token = args[0]
|
|
|
|
}
|
|
|
|
|
2015-04-06 03:50:18 +00:00
|
|
|
handler = &tokenAuthHandler{Token: token}
|
2015-04-08 06:29:49 +00:00
|
|
|
args = nil
|
2016-09-08 15:14:47 +00:00
|
|
|
|
|
|
|
switch authPath {
|
|
|
|
case "", "auth/token":
|
|
|
|
default:
|
|
|
|
c.Ui.Error("Token authentication does not support custom paths")
|
|
|
|
return 1
|
|
|
|
}
|
2015-04-06 03:50:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
if handler == nil {
|
|
|
|
methods := make([]string, 0, len(c.Handlers))
|
2015-09-18 18:01:28 +00:00
|
|
|
for k := range c.Handlers {
|
2015-04-06 03:50:18 +00:00
|
|
|
methods = append(methods, k)
|
2015-03-30 17:55:41 +00:00
|
|
|
}
|
2015-04-06 03:50:18 +00:00
|
|
|
sort.Strings(methods)
|
|
|
|
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Unknown authentication method: %s\n\n"+
|
|
|
|
"Please use a supported authentication method. The list of supported\n"+
|
|
|
|
"authentication methods is shown below. Note that this list may not\n"+
|
|
|
|
"be exhaustive: Vault may support other auth methods. For auth methods\n"+
|
|
|
|
"unsupported by the CLI, please use the HTTP API.\n\n"+
|
|
|
|
"%s",
|
|
|
|
method,
|
|
|
|
strings.Join(methods, ", ")))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2015-04-06 16:38:16 +00:00
|
|
|
if methodHelp {
|
|
|
|
c.Ui.Output(handler.Help())
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2015-06-18 20:48:04 +00:00
|
|
|
// Warn if the VAULT_TOKEN environment variable is set, as that will take
|
2017-07-12 19:04:34 +00:00
|
|
|
// precedence. Don't output on token-only since we're likely piping output.
|
|
|
|
if os.Getenv("VAULT_TOKEN") != "" && !tokenOnly {
|
2015-06-18 20:48:04 +00:00
|
|
|
c.Ui.Output("==> WARNING: VAULT_TOKEN environment variable set!\n")
|
|
|
|
c.Ui.Output(" The environment variable takes precedence over the value")
|
|
|
|
c.Ui.Output(" set by the auth command. Either update the value of the")
|
|
|
|
c.Ui.Output(" environment variable or unset it to use the new token.\n")
|
|
|
|
}
|
|
|
|
|
2015-04-08 06:29:49 +00:00
|
|
|
var vars map[string]string
|
|
|
|
if len(args) > 0 {
|
|
|
|
builder := kvbuilder.Builder{Stdin: os.Stdin}
|
|
|
|
if err := builder.Add(args...); err != nil {
|
|
|
|
c.Ui.Error(err.Error())
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
if err := mapstructure.Decode(builder.Map(), &vars); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Error parsing options: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
2016-09-08 15:14:47 +00:00
|
|
|
} else {
|
|
|
|
vars = make(map[string]string)
|
2015-04-08 06:29:49 +00:00
|
|
|
}
|
|
|
|
|
2015-04-06 16:53:43 +00:00
|
|
|
// Build the client so we can auth
|
|
|
|
client, err := c.Client()
|
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error initializing client to auth: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2016-06-15 20:45:07 +00:00
|
|
|
if authPath != "" {
|
|
|
|
vars["mount"] = authPath
|
|
|
|
}
|
|
|
|
|
2015-04-06 16:53:43 +00:00
|
|
|
// Authenticate
|
2017-08-31 20:57:00 +00:00
|
|
|
secret, err := handler.Auth(client, vars)
|
2015-04-06 03:50:18 +00:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(err.Error())
|
|
|
|
return 1
|
2015-03-30 17:55:41 +00:00
|
|
|
}
|
2017-08-31 20:57:00 +00:00
|
|
|
if secret == nil {
|
|
|
|
c.Ui.Error("Empty response from auth helper")
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
// If we had requested a wrapped token, we want to unset that request
|
|
|
|
// before performing further functions
|
|
|
|
client.SetWrappingLookupFunc(func(string, string) string {
|
|
|
|
return ""
|
|
|
|
})
|
|
|
|
|
|
|
|
CHECK_TOKEN:
|
|
|
|
var token string
|
|
|
|
switch {
|
|
|
|
case secret == nil:
|
|
|
|
c.Ui.Error("Empty response from auth helper")
|
|
|
|
return 1
|
|
|
|
|
|
|
|
case secret.Auth != nil:
|
|
|
|
token = secret.Auth.ClientToken
|
|
|
|
|
|
|
|
case secret.WrapInfo != nil:
|
|
|
|
if secret.WrapInfo.WrappedAccessor == "" {
|
|
|
|
c.Ui.Error("Got a wrapped response from Vault but wrapped reply does not seem to contain a token")
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
if tokenOnly {
|
|
|
|
c.Ui.Output(secret.WrapInfo.Token)
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
if noStore {
|
|
|
|
return OutputSecret(c.Ui, "table", secret)
|
|
|
|
}
|
|
|
|
client.SetToken(secret.WrapInfo.Token)
|
|
|
|
secret, err = client.Logical().Unwrap("")
|
|
|
|
goto CHECK_TOKEN
|
|
|
|
|
|
|
|
default:
|
|
|
|
c.Ui.Error("No auth or wrapping info in auth helper response")
|
|
|
|
return 1
|
|
|
|
}
|
2015-03-30 17:55:41 +00:00
|
|
|
|
2016-03-18 18:41:22 +00:00
|
|
|
// Cache the previous token so that it can be restored if authentication fails
|
|
|
|
var previousToken string
|
|
|
|
if previousToken, err = tokenHelper.Get(); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf("Error caching the previous token: %s\n\n", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
2017-07-12 19:04:34 +00:00
|
|
|
if tokenOnly {
|
|
|
|
c.Ui.Output(token)
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2015-03-30 17:55:41 +00:00
|
|
|
// Store the token!
|
2017-06-05 20:36:28 +00:00
|
|
|
if !noStore {
|
|
|
|
if err := tokenHelper.Store(token); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error storing token: %s\n\n"+
|
|
|
|
"Authentication was not successful and did not persist.\n"+
|
|
|
|
"Please reauthenticate, or fix the issue above if possible.",
|
|
|
|
err))
|
|
|
|
return 1
|
|
|
|
}
|
2015-03-30 17:55:41 +00:00
|
|
|
}
|
|
|
|
|
2015-08-19 02:18:23 +00:00
|
|
|
if noVerify {
|
|
|
|
c.Ui.Output(fmt.Sprintf(
|
|
|
|
"Authenticated - no token verification has been performed.",
|
|
|
|
))
|
|
|
|
|
2017-06-05 20:36:28 +00:00
|
|
|
if noStore {
|
|
|
|
if err := tokenHelper.Erase(); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error removing prior token: %s\n\n"+
|
|
|
|
"Authentication was successful, but unable to remove the\n"+
|
|
|
|
"previous token.",
|
|
|
|
err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
2015-08-19 02:18:23 +00:00
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2016-03-18 18:41:22 +00:00
|
|
|
// Build the client again so it can read the token we just wrote
|
|
|
|
client, err = c.Client()
|
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error initializing client to verify the token: %s", err))
|
2017-06-05 20:36:28 +00:00
|
|
|
if !noStore {
|
|
|
|
if err := tokenHelper.Store(previousToken); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error restoring the previous token: %s\n\n"+
|
|
|
|
"Please reauthenticate with a valid token.",
|
|
|
|
err))
|
|
|
|
}
|
2016-03-18 18:41:22 +00:00
|
|
|
}
|
|
|
|
return 1
|
|
|
|
}
|
2017-08-31 20:57:00 +00:00
|
|
|
client.SetWrappingLookupFunc(func(string, string) string {
|
|
|
|
return ""
|
|
|
|
})
|
2016-03-18 18:41:22 +00:00
|
|
|
|
2017-06-05 20:36:28 +00:00
|
|
|
// If in no-store mode it won't have read the token from a token-helper (or
|
|
|
|
// will read an old one) so set it explicitly
|
|
|
|
if noStore {
|
|
|
|
client.SetToken(token)
|
|
|
|
}
|
|
|
|
|
2015-03-31 22:15:08 +00:00
|
|
|
// Verify the token
|
2017-08-31 20:57:00 +00:00
|
|
|
secret, err = client.Auth().Token().LookupSelf()
|
2015-03-31 22:15:08 +00:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error validating token: %s", err))
|
2016-03-18 18:41:22 +00:00
|
|
|
if err := tokenHelper.Store(previousToken); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error restoring the previous token: %s\n\n"+
|
|
|
|
"Please reauthenticate with a valid token.",
|
|
|
|
err))
|
|
|
|
}
|
2015-03-31 22:15:08 +00:00
|
|
|
return 1
|
|
|
|
}
|
2017-06-05 20:36:28 +00:00
|
|
|
if secret == nil && !noStore {
|
2015-04-29 02:23:26 +00:00
|
|
|
c.Ui.Error(fmt.Sprintf("Error: Invalid token"))
|
2016-03-18 18:41:22 +00:00
|
|
|
if err := tokenHelper.Store(previousToken); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error restoring the previous token: %s\n\n"+
|
|
|
|
"Please reauthenticate with a valid token.",
|
|
|
|
err))
|
|
|
|
}
|
2015-04-29 02:23:26 +00:00
|
|
|
return 1
|
|
|
|
}
|
2015-03-31 22:15:08 +00:00
|
|
|
|
2017-06-05 20:36:28 +00:00
|
|
|
if noStore {
|
|
|
|
if err := tokenHelper.Erase(); err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error removing prior token: %s\n\n"+
|
|
|
|
"Authentication was successful, but unable to remove the\n"+
|
|
|
|
"previous token.",
|
|
|
|
err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
2015-03-31 22:15:08 +00:00
|
|
|
// Get the policies we have
|
|
|
|
policiesRaw, ok := secret.Data["policies"]
|
2017-08-31 20:57:00 +00:00
|
|
|
if !ok || policiesRaw == nil {
|
|
|
|
policiesRaw = []interface{}{"unknown"}
|
2015-03-31 22:15:08 +00:00
|
|
|
}
|
|
|
|
var policies []string
|
|
|
|
for _, v := range policiesRaw.([]interface{}) {
|
|
|
|
policies = append(policies, v.(string))
|
|
|
|
}
|
|
|
|
|
2016-04-13 18:45:48 +00:00
|
|
|
output := "Successfully authenticated! You are now logged in."
|
2017-06-05 20:36:28 +00:00
|
|
|
if noStore {
|
|
|
|
output += "\nThe token has not been stored to the configured token helper."
|
|
|
|
}
|
2016-04-13 18:45:48 +00:00
|
|
|
if method != "" {
|
|
|
|
output += "\nThe token below is already saved in the session. You do not"
|
|
|
|
output += "\nneed to \"vault auth\" again with the token."
|
|
|
|
}
|
2015-10-02 17:33:19 +00:00
|
|
|
output += fmt.Sprintf("\ntoken: %s", secret.Data["id"])
|
2016-04-20 18:38:20 +00:00
|
|
|
output += fmt.Sprintf("\ntoken_duration: %s", secret.Data["ttl"].(json.Number).String())
|
2015-09-18 18:01:28 +00:00
|
|
|
if len(policies) > 0 {
|
2016-09-01 20:32:27 +00:00
|
|
|
output += fmt.Sprintf("\ntoken_policies: %v", policies)
|
2015-09-18 18:01:28 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c.Ui.Output(output)
|
2015-03-31 06:10:59 +00:00
|
|
|
|
2015-03-04 07:34:32 +00:00
|
|
|
return 0
|
2016-03-18 18:41:22 +00:00
|
|
|
|
2015-03-04 07:34:32 +00:00
|
|
|
}
|
|
|
|
|
2017-08-24 22:23:40 +00:00
|
|
|
func (c *AuthCommand) getMethods() (map[string]*api.AuthMount, error) {
|
2015-04-02 00:01:10 +00:00
|
|
|
client, err := c.Client()
|
|
|
|
if err != nil {
|
2017-08-24 22:23:40 +00:00
|
|
|
return nil, err
|
2015-04-02 00:01:10 +00:00
|
|
|
}
|
2017-08-31 20:57:00 +00:00
|
|
|
client.SetWrappingLookupFunc(func(string, string) string {
|
|
|
|
return ""
|
|
|
|
})
|
2015-04-02 00:01:10 +00:00
|
|
|
|
|
|
|
auth, err := client.Sys().ListAuth()
|
2017-08-24 22:23:40 +00:00
|
|
|
if err != nil {
|
|
|
|
return nil, err
|
|
|
|
}
|
|
|
|
|
|
|
|
return auth, nil
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *AuthCommand) listMethods() int {
|
|
|
|
auth, err := c.getMethods()
|
2015-04-02 00:01:10 +00:00
|
|
|
if err != nil {
|
|
|
|
c.Ui.Error(fmt.Sprintf(
|
|
|
|
"Error reading auth table: %s", err))
|
|
|
|
return 1
|
|
|
|
}
|
|
|
|
|
|
|
|
paths := make([]string, 0, len(auth))
|
2015-09-18 18:01:28 +00:00
|
|
|
for path := range auth {
|
2015-04-02 00:01:10 +00:00
|
|
|
paths = append(paths, path)
|
|
|
|
}
|
|
|
|
sort.Strings(paths)
|
|
|
|
|
2017-06-26 17:14:36 +00:00
|
|
|
columns := []string{"Path | Type | Accessor | Default TTL | Max TTL | Replication Behavior | Description"}
|
2016-06-15 16:35:30 +00:00
|
|
|
for _, path := range paths {
|
|
|
|
auth := auth[path]
|
|
|
|
defTTL := "system"
|
|
|
|
if auth.Config.DefaultLeaseTTL != 0 {
|
|
|
|
defTTL = strconv.Itoa(auth.Config.DefaultLeaseTTL)
|
|
|
|
}
|
|
|
|
maxTTL := "system"
|
|
|
|
if auth.Config.MaxLeaseTTL != 0 {
|
|
|
|
maxTTL = strconv.Itoa(auth.Config.MaxLeaseTTL)
|
|
|
|
}
|
2017-02-16 16:37:27 +00:00
|
|
|
replicatedBehavior := "replicated"
|
|
|
|
if auth.Local {
|
|
|
|
replicatedBehavior = "local"
|
|
|
|
}
|
2015-04-02 00:01:10 +00:00
|
|
|
columns = append(columns, fmt.Sprintf(
|
2017-06-26 17:14:36 +00:00
|
|
|
"%s | %s | %s | %s | %s | %s | %s", path, auth.Type, auth.Accessor, defTTL, maxTTL, replicatedBehavior, auth.Description))
|
2015-04-02 00:01:10 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
c.Ui.Output(columnize.SimpleFormat(columns))
|
|
|
|
return 0
|
|
|
|
}
|
|
|
|
|
2015-03-04 07:34:32 +00:00
|
|
|
func (c *AuthCommand) Synopsis() string {
|
|
|
|
return "Prints information about how to authenticate with Vault"
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *AuthCommand) Help() string {
|
|
|
|
helpText := `
|
2016-09-01 23:56:30 +00:00
|
|
|
Usage: vault auth [options] [auth-information]
|
2015-03-29 23:42:45 +00:00
|
|
|
|
2017-03-25 17:51:12 +00:00
|
|
|
Authenticate with Vault using the given token or via any supported
|
2015-03-29 23:42:45 +00:00
|
|
|
authentication backend.
|
2015-03-04 07:34:32 +00:00
|
|
|
|
2016-09-01 23:56:30 +00:00
|
|
|
By default, the -method is assumed to be token. If not supplied via the
|
|
|
|
command-line, a prompt for input will be shown. If the authentication
|
|
|
|
information is "-", it will be read from stdin.
|
|
|
|
|
|
|
|
The -method option allows alternative authentication methods to be used,
|
|
|
|
such as userpass, GitHub, or TLS certificates. For these, additional
|
|
|
|
values as "key=value" pairs may be required. For example, to authenticate
|
|
|
|
to the userpass auth backend:
|
|
|
|
|
|
|
|
$ vault auth -method=userpass username=my-username
|
|
|
|
|
|
|
|
Use "-method-help" to get help for a specific method.
|
|
|
|
|
|
|
|
If an auth backend is enabled at a different path, the "-method" flag
|
|
|
|
should still point to the canonical name, and the "-path" flag should be
|
|
|
|
used. If a GitHub auth backend was mounted as "github-private", one would
|
|
|
|
authenticate to this backend via:
|
|
|
|
|
|
|
|
$ vault auth -method=github -path=github-private
|
|
|
|
|
|
|
|
The value of the "-path" flag is supplied to auth providers as the "mount"
|
|
|
|
option in the payload to specify the mount point.
|
2015-03-04 07:34:32 +00:00
|
|
|
|
2017-08-31 20:57:00 +00:00
|
|
|
If response wrapping is used (via -wrap-ttl), the returned token will be
|
|
|
|
automatically unwrapped unless:
|
|
|
|
* -token-only is used, in which case the wrapping token will be output
|
|
|
|
* -no-store is used, in which case the details of the wrapping token
|
|
|
|
will be printed
|
|
|
|
|
2015-03-04 07:52:54 +00:00
|
|
|
General Options:
|
|
|
|
|
2016-04-01 17:16:05 +00:00
|
|
|
` + meta.GeneralOptionsUsage() + `
|
2015-03-04 07:52:54 +00:00
|
|
|
|
|
|
|
Auth Options:
|
2015-03-04 07:34:32 +00:00
|
|
|
|
2017-08-31 20:57:00 +00:00
|
|
|
-method=name Use the method given here, which is a type of backend, not
|
|
|
|
the path. If this authentication method is not available,
|
|
|
|
exit with code 1.
|
2015-04-02 00:01:10 +00:00
|
|
|
|
2015-04-06 16:38:16 +00:00
|
|
|
-method-help If set, the help for the selected method will be shown.
|
|
|
|
|
2015-04-06 03:50:18 +00:00
|
|
|
-methods List the available auth methods.
|
|
|
|
|
2015-08-19 02:18:23 +00:00
|
|
|
-no-verify Do not verify the token after creation; avoids a use count
|
|
|
|
decrement.
|
|
|
|
|
2017-06-05 20:36:28 +00:00
|
|
|
-no-store Do not store the token after creation; it will only be
|
|
|
|
displayed in the command output.
|
|
|
|
|
2017-07-12 19:04:34 +00:00
|
|
|
-token-only Output only the token to stdout. This implies -no-verify
|
|
|
|
and -no-store.
|
|
|
|
|
2016-06-20 20:24:49 +00:00
|
|
|
-path The path at which the auth backend is enabled. If an auth
|
|
|
|
backend is mounted at multiple paths, this option can be
|
|
|
|
used to authenticate against specific paths.
|
2015-03-04 07:34:32 +00:00
|
|
|
`
|
|
|
|
return strings.TrimSpace(helpText)
|
|
|
|
}
|
2015-04-06 03:50:18 +00:00
|
|
|
|
|
|
|
// tokenAuthHandler handles retrieving the token from the command-line.
|
|
|
|
type tokenAuthHandler struct {
|
|
|
|
Token string
|
|
|
|
}
|
|
|
|
|
2017-08-31 20:57:00 +00:00
|
|
|
func (h *tokenAuthHandler) Auth(*api.Client, map[string]string) (*api.Secret, error) {
|
2015-04-06 03:50:18 +00:00
|
|
|
token := h.Token
|
|
|
|
if token == "" {
|
|
|
|
var err error
|
|
|
|
|
|
|
|
// No arguments given, read the token from user input
|
|
|
|
fmt.Printf("Token (will be hidden): ")
|
|
|
|
token, err = password.Read(os.Stdin)
|
|
|
|
fmt.Printf("\n")
|
|
|
|
if err != nil {
|
2017-08-31 20:57:00 +00:00
|
|
|
return nil, fmt.Errorf(
|
2015-04-06 03:50:18 +00:00
|
|
|
"Error attempting to ask for token. The raw error message\n"+
|
|
|
|
"is shown below, but the most common reason for this error is\n"+
|
|
|
|
"that you attempted to pipe a value into auth. If you want to\n"+
|
|
|
|
"pipe the token, please pass '-' as the token argument.\n\n"+
|
|
|
|
"Raw error: %s", err)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
if token == "" {
|
2017-08-31 20:57:00 +00:00
|
|
|
return nil, fmt.Errorf(
|
2015-04-06 03:50:18 +00:00
|
|
|
"A token must be passed to auth. Please view the help\n" +
|
|
|
|
"for more information.")
|
|
|
|
}
|
|
|
|
|
2017-08-31 20:57:00 +00:00
|
|
|
return &api.Secret{
|
|
|
|
Auth: &api.SecretAuth{
|
|
|
|
ClientToken: token,
|
|
|
|
},
|
|
|
|
}, nil
|
2015-04-06 03:50:18 +00:00
|
|
|
}
|
|
|
|
|
|
|
|
func (h *tokenAuthHandler) Help() string {
|
2015-04-06 16:38:16 +00:00
|
|
|
help := `
|
|
|
|
No method selected with the "-method" flag, so the "auth" command assumes
|
|
|
|
you'll be using raw token authentication. For this, specify the token to
|
2017-03-25 17:51:12 +00:00
|
|
|
authenticate as the parameter to "vault auth". Example:
|
2015-04-06 16:38:16 +00:00
|
|
|
|
|
|
|
vault auth 123456
|
|
|
|
|
|
|
|
The token used to authenticate must come from some other source. A root
|
|
|
|
token is created when Vault is first initialized. After that, subsequent
|
|
|
|
tokens are created via the API or command line interface (with the
|
|
|
|
"token"-prefixed commands).
|
|
|
|
`
|
|
|
|
|
|
|
|
return strings.TrimSpace(help)
|
2015-04-06 03:50:18 +00:00
|
|
|
}
|
2017-08-24 22:23:40 +00:00
|
|
|
|
|
|
|
func (c *AuthCommand) AutocompleteArgs() complete.Predictor {
|
|
|
|
return complete.PredictNothing
|
|
|
|
}
|
|
|
|
|
|
|
|
func (c *AuthCommand) AutocompleteFlags() complete.Flags {
|
|
|
|
var predictFunc complete.PredictFunc = func(a complete.Args) []string {
|
|
|
|
auths, err := c.getMethods()
|
|
|
|
if err != nil {
|
|
|
|
return []string{}
|
|
|
|
}
|
|
|
|
|
|
|
|
methods := make([]string, 0, len(auths))
|
|
|
|
for _, auth := range auths {
|
|
|
|
if strings.HasPrefix(auth.Type, a.Last) {
|
|
|
|
methods = append(methods, auth.Type)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
|
|
|
|
return methods
|
|
|
|
}
|
|
|
|
|
|
|
|
return complete.Flags{
|
|
|
|
"-method": predictFunc,
|
|
|
|
"-methods": complete.PredictNothing,
|
|
|
|
"-method-help": complete.PredictNothing,
|
|
|
|
"-no-verify": complete.PredictNothing,
|
|
|
|
"-no-store": complete.PredictNothing,
|
|
|
|
"-token-only": complete.PredictNothing,
|
|
|
|
"-path": complete.PredictNothing,
|
|
|
|
}
|
|
|
|
}
|