1
0
mirror of https://github.com/minio/mc.git synced 2025-11-28 08:03:56 +03:00

Secret key prompt (#3083)

This commit is contained in:
Jeffrey Clark
2020-03-14 07:03:44 +00:00
committed by GitHub
parent 5b5d65a142
commit bcbbfa7352
5 changed files with 173 additions and 22 deletions

View File

@@ -17,7 +17,9 @@
package cmd package cmd
import ( import (
"bufio"
"fmt" "fmt"
"os"
"strings" "strings"
"github.com/fatih/color" "github.com/fatih/color"
@@ -25,6 +27,7 @@ import (
json "github.com/minio/mc/pkg/colorjson" json "github.com/minio/mc/pkg/colorjson"
"github.com/minio/mc/pkg/probe" "github.com/minio/mc/pkg/probe"
"github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/console"
"golang.org/x/crypto/ssh/terminal"
) )
var adminUserAddCmd = cli.Command{ var adminUserAddCmd = cli.Command{
@@ -53,13 +56,23 @@ EXAMPLES:
{{.DisableHistory}} {{.DisableHistory}}
{{.Prompt}} {{.HelpName}} myminio foobar foo12345 {{.Prompt}} {{.HelpName}} myminio foobar foo12345
{{.EnableHistory}} {{.EnableHistory}}
2. Add a new user 'foobar' to MinIO server, prompting for keys.
{{.Prompt}} {{.HelpName}} myminio
Enter Access Key: foobar
Enter Secret Key: foobar12345
3. Add a new user 'foobar' to MinIO server using piped keys.
{{.DisableHistory}}
{{.Prompt}} echo -e "foobar\nfoobar12345" | {{.HelpName}} myminio
{{.EnableHistory}}
`, `,
} }
// checkAdminUserAddSyntax - validate all the passed arguments // checkAdminUserAddSyntax - validate all the passed arguments
func checkAdminUserAddSyntax(ctx *cli.Context) { func checkAdminUserAddSyntax(ctx *cli.Context) {
if len(ctx.Args()) != 3 { argsNr := len(ctx.Args())
cli.ShowCommandHelpAndExit(ctx, "add", 1) // last argument is exit code if argsNr > 3 || argsNr < 1 {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Incorrect number of arguments for user add command.")
} }
} }
@@ -115,6 +128,43 @@ func (u userMessage) JSON() string {
return string(jsonMessageBytes) return string(jsonMessageBytes)
} }
// fetchUserKeys - returns the access and secret key
func fetchUserKeys(args cli.Args) (string, string) {
accessKey := ""
secretKey := ""
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
reader := bufio.NewReader(os.Stdin)
argCount := len(args)
if argCount == 1 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
}
value, _, _ := reader.ReadLine()
accessKey = string(value)
} else {
accessKey = args.Get(1)
}
if argCount == 1 || argCount == 2 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
secretKey = string(bytePassword)
} else {
value, _, _ := reader.ReadLine()
secretKey = string(value)
}
} else {
secretKey = args.Get(2)
}
return accessKey, secretKey
}
// mainAdminUserAdd is the handle for "mc admin user add" command. // mainAdminUserAdd is the handle for "mc admin user add" command.
func mainAdminUserAdd(ctx *cli.Context) error { func mainAdminUserAdd(ctx *cli.Context) error {
checkAdminUserAddSyntax(ctx) checkAdminUserAddSyntax(ctx)
@@ -124,17 +174,18 @@ func mainAdminUserAdd(ctx *cli.Context) error {
// Get the alias parameter from cli // Get the alias parameter from cli
args := ctx.Args() args := ctx.Args()
aliasedURL := args.Get(0) aliasedURL := args.Get(0)
accessKey, secretKey := fetchUserKeys(args)
// Create a new MinIO Admin Client // Create a new MinIO Admin Client
client, err := newAdminClient(aliasedURL) client, err := newAdminClient(aliasedURL)
fatalIf(err, "Unable to initialize admin connection.") fatalIf(err, "Unable to initialize admin connection.")
fatalIf(probe.NewError(client.AddUser(args.Get(1), args.Get(2))).Trace(args...), "Cannot add new user") fatalIf(probe.NewError(client.AddUser(accessKey, secretKey)).Trace(args...), "Cannot add new user")
printMsg(userMessage{ printMsg(userMessage{
op: "add", op: "add",
AccessKey: args.Get(1), AccessKey: accessKey,
SecretKey: args.Get(2), SecretKey: secretKey,
UserStatus: "enabled", UserStatus: "enabled",
}) })

View File

@@ -17,15 +17,21 @@
package cmd package cmd
import ( import (
"bufio"
"fmt"
"math/rand" "math/rand"
"os"
"time" "time"
"github.com/fatih/color" "github.com/fatih/color"
"github.com/minio/cli" "github.com/minio/cli"
"github.com/minio/mc/pkg/probe" "github.com/minio/mc/pkg/probe"
"github.com/minio/minio/pkg/console" "github.com/minio/minio/pkg/console"
"golang.org/x/crypto/ssh/terminal"
) )
const cred = "YellowItalics"
var hostAddFlags = []cli.Flag{ var hostAddFlags = []cli.Flag{
cli.StringFlag{ cli.StringFlag{
Name: "lookup", Name: "lookup",
@@ -71,24 +77,34 @@ EXAMPLES:
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com \ {{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com \
BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
{{.EnableHistory}} {{.EnableHistory}}
4. Add Amazon S3 storage service under "mys3" alias, prompting for keys.
{{.Prompt}} {{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
5. Add Amazon S3 storage service under "mys3" alias using piped keys.
{{.DisableHistory}}
{{.Prompt}} echo -e "BKIKJAA5BMMU2RHO6IBB\nV8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
{{.HelpName}} mys3 https://s3.amazonaws.com --api "s3v4" --lookup "dns"
{{.EnableHistory}}
`, `,
} }
// checkConfigHostAddSyntax - verifies input arguments to 'config host add'. // checkConfigHostAddSyntax - verifies input arguments to 'config host add'.
func checkConfigHostAddSyntax(ctx *cli.Context) { func checkConfigHostAddSyntax(ctx *cli.Context, accessKey string, secretKey string) {
args := ctx.Args() args := ctx.Args()
argsNr := len(args) argsNr := len(args)
if argsNr < 4 || argsNr > 5 { if argsNr > 4 || argsNr < 2 {
fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...), fatalIf(errInvalidArgument().Trace(ctx.Args().Tail()...),
"Incorrect number of arguments for host add command.") "Incorrect number of arguments for host add command.")
} }
alias := args.Get(0) alias := args.Get(0)
url := args.Get(1) url := args.Get(1)
accessKey := args.Get(2)
secretKey := args.Get(3)
api := ctx.String("api") api := ctx.String("api")
bucketLookup := ctx.String("lookup") bucketLookup := ctx.String("lookup")
if !isValidAlias(alias) { if !isValidAlias(alias) {
fatalIf(errInvalidAlias(alias), "Invalid alias.") fatalIf(errInvalidAlias(alias), "Invalid alias.")
} }
@@ -213,18 +229,54 @@ func buildS3Config(url, accessKey, secretKey, api, lookup string) (*Config, *pro
return s3Config, nil return s3Config, nil
} }
// fetchHostKeys - returns the user accessKey and secretKey
func fetchHostKeys(args cli.Args) (string, string) {
accessKey := ""
secretKey := ""
console.SetColor(cred, color.New(color.FgYellow, color.Italic))
isTerminal := terminal.IsTerminal(int(os.Stdin.Fd()))
reader := bufio.NewReader(os.Stdin)
argsNr := len(args)
if argsNr == 2 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Access Key: "))
}
value, _, _ := reader.ReadLine()
accessKey = string(value)
} else {
accessKey = args.Get(2)
}
if argsNr == 2 || argsNr == 3 {
if isTerminal {
fmt.Printf("%s", console.Colorize(cred, "Enter Secret Key: "))
bytePassword, _ := terminal.ReadPassword(int(os.Stdin.Fd()))
fmt.Printf("\n")
secretKey = string(bytePassword)
} else {
value, _, _ := reader.ReadLine()
secretKey = string(value)
}
} else {
secretKey = args.Get(3)
}
return accessKey, secretKey
}
func mainConfigHostAdd(ctx *cli.Context) error { func mainConfigHostAdd(ctx *cli.Context) error {
checkConfigHostAddSyntax(ctx)
console.SetColor("HostMessage", color.New(color.FgGreen)) console.SetColor("HostMessage", color.New(color.FgGreen))
var ( var (
args = ctx.Args() args = ctx.Args()
url = trimTrailingSeparator(args.Get(1)) url = trimTrailingSeparator(args.Get(1))
accessKey = args.Get(2) api = ctx.String("api")
secretKey = args.Get(3) lookup = ctx.String("lookup")
api = ctx.String("api")
lookup = ctx.String("lookup")
) )
accessKey, secretKey := fetchHostKeys(args)
checkConfigHostAddSyntax(ctx, accessKey, secretKey)
s3Config, err := buildS3Config(url, accessKey, secretKey, api, lookup) s3Config, err := buildS3Config(url, accessKey, secretKey, api, lookup)
fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials.") fatalIf(err.Trace(ctx.Args()...), "Unable to initialize new config from the provided credentials.")

View File

@@ -99,14 +99,35 @@ MinIO server displays URL, access and secret keys.
#### Usage #### Usage
``` ```
mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> mc config host add <ALIAS> <YOUR-MINIO-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY]
``` ```
Keys must be supplied by argument or standard input.
Alias is simply a short name to your MinIO service. MinIO end-point, access and secret keys are supplied by your MinIO service. Admin API uses "S3v4" signature and cannot be changed. Alias is simply a short name to your MinIO service. MinIO end-point, access and secret keys are supplied by your MinIO service. Admin API uses "S3v4" signature and cannot be changed.
``` ### Examples
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
``` 1. Keys by argument
```
mc config host add minio http://192.168.1.51:9000 BKIKJAA5BMMU2RHO6IBB V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```
2. Keys by prompt
```
mc config host add minio http://192.168.1.51:9000
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```
2. Keys by pipe
```
echo -e "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
mc config host add minio http://192.168.1.51:9000
```
## 4. Test Your Setup ## 4. Test Your Setup
@@ -439,6 +460,14 @@ COMMANDS:
mc admin user add myminio/ newuser newuser123 mc admin user add myminio/ newuser newuser123
``` ```
*Example: Add a new user 'newuser' on MinIO, using standard input.*
```
mc admin user add myminio/
Enter Access Key: newuser
Enter Secret Key: newuser123
```
*Example: Disable a user 'newuser' on MinIO.* *Example: Disable a user 'newuser' on MinIO.*
``` ```

View File

@@ -119,9 +119,11 @@ To add one or more Amazon S3 compatible hosts, please follow the instructions be
#### Usage #### Usage
``` ```
mc config host add <ALIAS> <YOUR-S3-ENDPOINT> <YOUR-ACCESS-KEY> <YOUR-SECRET-KEY> <API-SIGNATURE> mc config host add <ALIAS> <YOUR-S3-ENDPOINT> [YOUR-ACCESS-KEY] [YOUR-SECRET-KEY] [--api API-SIGNATURE]
``` ```
Keys must be supplied by argument or standard input.
Alias is simply a short name to your cloud storage service. S3 end-point, access and secret keys are supplied by your cloud storage provider. API signature is an optional argument. By default, it is set to "S3v4". Alias is simply a short name to your cloud storage service. S3 end-point, access and secret keys are supplied by your cloud storage provider. API signature is an optional argument. By default, it is set to "S3v4".
### Example - MinIO Cloud Storage ### Example - MinIO Cloud Storage
@@ -146,6 +148,23 @@ Get your AccessKeyID and SecretAccessKey by following [Google Credentials Guide]
mc config host add gcs https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12 mc config host add gcs https://storage.googleapis.com BKIKJAA5BMMU2RHO6IBB V8f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
``` ```
### Example - Specify keys using standard input
1. Prompt
```
mc config host add minio http://192.168.1.51 --api S3v4
Enter Access Key: BKIKJAA5BMMU2RHO6IBB
Enter Secret Key: V7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12
```
2. Pipe
```
echo -e "BKIKJAA5BMMU2RHO6IBB\nV7f1CwQqAcwo80UEIJEjc5gVQUSSx5ohQ9GSrr12" | \
mc config host add minio http://192.168.1.51 --api S3v4
```
### Specify host configuration through environment variable ### Specify host configuration through environment variable
``` ```
export MC_HOST_<alias>=https://<Access Key>:<Secret Key>@<YOUR-S3-ENDPOINT> export MC_HOST_<alias>=https://<Access Key>:<Secret Key>@<YOUR-S3-ENDPOINT>

2
go.mod
View File

@@ -24,7 +24,7 @@ require (
github.com/rjeczalik/notify v0.9.2 github.com/rjeczalik/notify v0.9.2
github.com/ugorji/go v1.1.7 // indirect github.com/ugorji/go v1.1.7 // indirect
go.uber.org/zap v1.11.0 // indirect go.uber.org/zap v1.11.0 // indirect
golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6 // indirect golang.org/x/crypto v0.0.0-20200214034016-1d94cc7ab1c6
golang.org/x/net v0.0.0-20200202094626-16171245cfb2 golang.org/x/net v0.0.0-20200202094626-16171245cfb2
golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect golang.org/x/sys v0.0.0-20200212091648-12a6c2dcc1e4 // indirect
golang.org/x/text v0.3.2 golang.org/x/text v0.3.2