mirror of
https://github.com/ceph/ceph-csi.git
synced 2025-06-13 10:33:35 +00:00
Use --keyfile option to pass keys to all Ceph CLIs
Every Ceph CLI that is invoked at present passes the key via the --key option, and hence is exposed to key being displayed on the host using a ps command or such means. This commit addresses this issue by stashing the key in a tmp file, which is again created on a tmpfs (or empty dir backed by memory). Further using such tmp files as arguments to the --keyfile option for every CLI that is invoked. This prevents the key from being visible as part of the argument list of the invoked program on the system. Fixes: #318 Signed-off-by: ShyamsundarR <srangana@redhat.com>
This commit is contained in:
committed by
mergify[bot]
parent
c2835183e5
commit
bd204d7d45
@ -63,7 +63,7 @@ func getPools(monitors string, cr *Credentials) ([]cephStoragePoolSummary, error
|
||||
"ceph",
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key="+cr.Key,
|
||||
"--keyfile="+cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-f", "json",
|
||||
"osd", "lspools")
|
||||
@ -122,7 +122,7 @@ func SetOMapKeyValue(monitors string, cr *Credentials, poolName, namespace, oMap
|
||||
args := []string{
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key=" + cr.Key,
|
||||
"--keyfile=" + cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-p", poolName,
|
||||
"setomapval", oMapName, oMapKey, keyValue,
|
||||
@ -157,7 +157,7 @@ func GetOMapValue(monitors string, cr *Credentials, poolName, namespace, oMapNam
|
||||
args := []string{
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key=" + cr.Key,
|
||||
"--keyfile=" + cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-p", poolName,
|
||||
"getomapval", oMapName, oMapKey, tmpFile.Name(),
|
||||
@ -199,7 +199,7 @@ func RemoveOMapKey(monitors string, cr *Credentials, poolName, namespace, oMapNa
|
||||
args := []string{
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key=" + cr.Key,
|
||||
"--keyfile=" + cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-p", poolName,
|
||||
"rmomapkey", oMapName, oMapKey,
|
||||
@ -227,7 +227,7 @@ func CreateObject(monitors string, cr *Credentials, poolName, namespace, objectN
|
||||
args := []string{
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key=" + cr.Key,
|
||||
"--keyfile=" + cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-p", poolName,
|
||||
"create", objectName,
|
||||
@ -257,7 +257,7 @@ func RemoveObject(monitors string, cr *Credentials, poolName, namespace, oMapNam
|
||||
args := []string{
|
||||
"-m", monitors,
|
||||
"--id", cr.ID,
|
||||
"--key=" + cr.Key,
|
||||
"--keyfile=" + cr.KeyFile,
|
||||
"-c", CephConfigPath,
|
||||
"-p", poolName,
|
||||
"rm", oMapName,
|
||||
|
@ -18,22 +18,54 @@ package util
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
"io/ioutil"
|
||||
"os"
|
||||
)
|
||||
|
||||
const (
|
||||
credUserID = "userID"
|
||||
credUserKey = "userKey"
|
||||
credAdminID = "adminID"
|
||||
credAdminKey = "adminKey"
|
||||
credMonitors = "monitors"
|
||||
credUserID = "userID"
|
||||
credUserKey = "userKey"
|
||||
credAdminID = "adminID"
|
||||
credAdminKey = "adminKey"
|
||||
credMonitors = "monitors"
|
||||
tmpKeyFileLocation = "/tmp/csi/keys"
|
||||
tmpKeyFileNamePrefix = "keyfile-"
|
||||
)
|
||||
|
||||
type Credentials struct {
|
||||
ID string
|
||||
Key string
|
||||
ID string
|
||||
KeyFile string
|
||||
}
|
||||
|
||||
func getCredentials(idField, keyField string, secrets map[string]string) (*Credentials, error) {
|
||||
func storeKey(key string) (string, error) {
|
||||
tmpfile, err := ioutil.TempFile(tmpKeyFileLocation, tmpKeyFileNamePrefix)
|
||||
if err != nil {
|
||||
return "", fmt.Errorf("error creating a temporary keyfile (%s)", err)
|
||||
}
|
||||
defer func() {
|
||||
if err != nil {
|
||||
os.Remove(tmpfile.Name())
|
||||
}
|
||||
}()
|
||||
|
||||
if _, err = tmpfile.Write([]byte(key)); err != nil {
|
||||
return "", fmt.Errorf("error writing key to temporary keyfile (%s)", err)
|
||||
}
|
||||
|
||||
keyFile := tmpfile.Name()
|
||||
if keyFile == "" {
|
||||
err = fmt.Errorf("error reading temporary filename for key (%s)", err)
|
||||
return "", err
|
||||
}
|
||||
|
||||
if err = tmpfile.Close(); err != nil {
|
||||
return "", fmt.Errorf("error closing temporary filename (%s)", err)
|
||||
}
|
||||
|
||||
return keyFile, nil
|
||||
}
|
||||
|
||||
func newCredentialsFromSecret(idField, keyField string, secrets map[string]string) (*Credentials, error) {
|
||||
var (
|
||||
c = &Credentials{}
|
||||
ok bool
|
||||
@ -43,19 +75,41 @@ func getCredentials(idField, keyField string, secrets map[string]string) (*Crede
|
||||
return nil, fmt.Errorf("missing ID field '%s' in secrets", idField)
|
||||
}
|
||||
|
||||
if c.Key, ok = secrets[keyField]; !ok {
|
||||
key := secrets[keyField]
|
||||
if key == "" {
|
||||
return nil, fmt.Errorf("missing key field '%s' in secrets", keyField)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
keyFile, err := storeKey(key)
|
||||
if err == nil {
|
||||
c.KeyFile = keyFile
|
||||
}
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
func GetUserCredentials(secrets map[string]string) (*Credentials, error) {
|
||||
return getCredentials(credUserID, credUserKey, secrets)
|
||||
func (cr *Credentials) DeleteCredentials() {
|
||||
os.Remove(cr.KeyFile)
|
||||
}
|
||||
|
||||
func GetAdminCredentials(secrets map[string]string) (*Credentials, error) {
|
||||
return getCredentials(credAdminID, credAdminKey, secrets)
|
||||
func NewUserCredentials(secrets map[string]string) (*Credentials, error) {
|
||||
return newCredentialsFromSecret(credUserID, credUserKey, secrets)
|
||||
}
|
||||
|
||||
func NewAdminCredentials(secrets map[string]string) (*Credentials, error) {
|
||||
return newCredentialsFromSecret(credAdminID, credAdminKey, secrets)
|
||||
}
|
||||
|
||||
func NewCredentials(id, key string) (*Credentials, error) {
|
||||
var c = &Credentials{}
|
||||
|
||||
c.ID = id
|
||||
keyFile, err := storeKey(key)
|
||||
if err == nil {
|
||||
c.KeyFile = keyFile
|
||||
}
|
||||
|
||||
return c, err
|
||||
}
|
||||
|
||||
func GetMonValFromSecret(secrets map[string]string) (string, error) {
|
||||
|
@ -22,15 +22,17 @@ import (
|
||||
|
||||
const (
|
||||
keyArg = "--key="
|
||||
keyFileArg = "--keyfile="
|
||||
secretArg = "secret="
|
||||
optionsArgSeparator = ','
|
||||
strippedKey = "--key=***stripped***"
|
||||
strippedKeyFile = "--keyfile=***stripped***"
|
||||
strippedSecret = "secret=***stripped***"
|
||||
)
|
||||
|
||||
// StripSecretInArgs strips values of either "--key" or "secret=".
|
||||
// StripSecretInArgs strips values of either "--key"/"--keyfile" or "secret=".
|
||||
// `args` is left unchanged.
|
||||
// Expects only one occurrence of either "--key" or "secret=".
|
||||
// Expects only one occurrence of either "--key"/"--keyfile" or "secret=".
|
||||
func StripSecretInArgs(args []string) []string {
|
||||
out := make([]string, len(args))
|
||||
copy(out, args)
|
||||
@ -48,6 +50,11 @@ func stripKey(out []string) bool {
|
||||
out[i] = strippedKey
|
||||
return true
|
||||
}
|
||||
|
||||
if strings.HasPrefix(out[i], keyFileArg) {
|
||||
out[i] = strippedKeyFile
|
||||
return true
|
||||
}
|
||||
}
|
||||
|
||||
return false
|
||||
|
Reference in New Issue
Block a user