go.mondoo.com/cnquery@v0.0.0-20231005093811-59568235f6ea/providers-sdk/v1/vault/credential.go (about)

     1  // Copyright (c) Mondoo, Inc.
     2  // SPDX-License-Identifier: BUSL-1.1
     3  
     4  package vault
     5  
     6  import (
     7  	"encoding/json"
     8  	"errors"
     9  	"os"
    10  	"strings"
    11  )
    12  
    13  // PreProcess converts a more user-friendly configuration into a standard secrets form:
    14  // eg. { user: "chris", password: "pwd"} will be converted to { type: "password", user: "chris", secret: "<byte pwd>"}
    15  func (cred *Credential) PreProcess() {
    16  	// load private key pem into secret
    17  	if cred.PrivateKey != "" {
    18  		cred.Secret = []byte(cred.PrivateKey)
    19  		cred.PrivateKey = ""
    20  		if cred.Type == CredentialType_undefined {
    21  			cred.Type = CredentialType_private_key
    22  		}
    23  	}
    24  
    25  	// NOTE: it is possible that private keys hold an additional password, therefore we only
    26  	// copy the password into the secret when the credential type is password
    27  	if (cred.Type == CredentialType_undefined || cred.Type == CredentialType_password) && cred.Password != "" {
    28  		cred.Secret = []byte(cred.Password)
    29  		cred.Password = ""
    30  		cred.Type = CredentialType_password
    31  	}
    32  }
    33  
    34  // UnmarshalJSON parses either an int or a string representation of
    35  // CredentialType into the struct
    36  func (s *CredentialType) UnmarshalJSON(data []byte) error {
    37  	// check if we have a number
    38  	var code int32
    39  	err := json.Unmarshal(data, &code)
    40  	if err == nil {
    41  		*s = CredentialType(code)
    42  	}
    43  	if err != nil {
    44  		var name string
    45  		err = json.Unmarshal(data, &name)
    46  		code, ok := CredentialType_value[strings.TrimSpace(name)]
    47  		if !ok {
    48  			return errors.New("unknown type value: " + string(data))
    49  		}
    50  		*s = CredentialType(code)
    51  	}
    52  	return nil
    53  }
    54  
    55  // MarshalJSON returns the JSON representation of CredentialType
    56  // NOTE: we do not use pointers here to ensure its converted properly
    57  // even if the struct is used directly
    58  func (s CredentialType) MarshalJSON() ([]byte, error) {
    59  	v, ok := CredentialType_name[int32(s)]
    60  	if !ok {
    61  		return nil, errors.New("could not marshal CredentialType")
    62  	}
    63  	return json.Marshal(v)
    64  }
    65  
    66  func NewPrivateKeyCredential(user string, pemBytes []byte, password string) *Credential {
    67  	return &Credential{
    68  		Type:     CredentialType_private_key,
    69  		User:     user,
    70  		Secret:   pemBytes,
    71  		Password: password,
    72  	}
    73  }
    74  
    75  func NewPrivateKeyCredentialFromPath(user string, path string, password string) (*Credential, error) {
    76  	if _, err := os.Stat(path); os.IsNotExist(err) {
    77  		return nil, errors.New("private key does not exist " + path)
    78  	}
    79  
    80  	pemBytes, err := os.ReadFile(path)
    81  	if err != nil {
    82  		return nil, err
    83  	}
    84  
    85  	return NewPrivateKeyCredential(user, pemBytes, password), nil
    86  }
    87  
    88  func NewPasswordCredential(user string, password string) *Credential {
    89  	return &Credential{
    90  		Type:   CredentialType_password,
    91  		User:   user,
    92  		Secret: []byte(password),
    93  	}
    94  }
    95  
    96  // GetPassword returns the first password in the list
    97  func GetPassword(list []*Credential) (*Credential, error) {
    98  	for i := range list {
    99  		credential := list[i]
   100  		if credential.Type == CredentialType_password {
   101  			return credential, nil
   102  		}
   103  	}
   104  	return nil, errors.New("no password found")
   105  }
   106  
   107  // UnmarshalJSON parses either an int or a string representation of
   108  // SecretEncoding into the struct
   109  func (s *SecretEncoding) UnmarshalJSON(data []byte) error {
   110  	// check if we have a number
   111  	var code int32
   112  	err := json.Unmarshal(data, &code)
   113  	if err == nil {
   114  		*s = SecretEncoding(code)
   115  	}
   116  	if err != nil {
   117  		var name string
   118  		err = json.Unmarshal(data, &name)
   119  		code, ok := SecretEncoding_value["encoding_"+strings.ToLower(strings.TrimSpace(name))]
   120  		if !ok {
   121  			return errors.New("unknown type value: " + string(data))
   122  		}
   123  		*s = SecretEncoding(code)
   124  	}
   125  	return nil
   126  }
   127  
   128  // MarshalJSON returns the JSON representation of SecretEncoding
   129  // NOTE: we do not use pointers here to ensure its converted properly
   130  // even if the struct is used directly
   131  func (s SecretEncoding) MarshalJSON() ([]byte, error) {
   132  	v, ok := SecretEncoding_name[int32(s)]
   133  	if !ok {
   134  		return nil, errors.New("could not marshal CredentialType")
   135  	}
   136  	return json.Marshal(v)
   137  }