chore(secrets): Abstract secret implementation (#13953)
This commit is contained in:
parent
ac79964226
commit
e2c4e10650
|
|
@ -8,10 +8,9 @@ import (
|
|||
"sort"
|
||||
"strings"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
"github.com/urfave/cli/v2"
|
||||
"golang.org/x/term"
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
)
|
||||
|
||||
func processFilterOnlySecretStoreFlags(ctx *cli.Context) Filters {
|
||||
|
|
@ -119,7 +118,7 @@ To also reveal the actual secret, i.e. the value, you can pass the
|
|||
}
|
||||
}
|
||||
_, _ = fmt.Printf(" %-30s %s\n", k, string(v))
|
||||
config.ReleaseSecret(v)
|
||||
memguard.WipeBytes(v)
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
127
config/secret.go
127
config/secret.go
|
|
@ -6,8 +6,6 @@ import (
|
|||
"strings"
|
||||
"sync/atomic"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
)
|
||||
|
||||
|
|
@ -26,17 +24,67 @@ var secretStorePattern = regexp.MustCompile(`^\w+$`)
|
|||
// in a secret-store.
|
||||
var secretPattern = regexp.MustCompile(`@\{(\w+:\w+)\}`)
|
||||
|
||||
// secretCount is the number of secrets use in Telegraf
|
||||
var secretCount atomic.Int64
|
||||
|
||||
// selectedImpl is the configured implementation for secrets
|
||||
var selectedImpl secretImpl = &protectedSecretImpl{}
|
||||
|
||||
// secretImpl represents an abstraction for different implementations of secrets
|
||||
type secretImpl interface {
|
||||
Container(secret []byte) secretContainer
|
||||
EmptyBuffer() SecretBuffer
|
||||
Wipe(secret []byte)
|
||||
}
|
||||
|
||||
// secretContainer represents an abstraction of the container holding the
|
||||
// actual secret value
|
||||
type secretContainer interface {
|
||||
Destroy()
|
||||
Equals(ref []byte) (bool, error)
|
||||
Buffer() (SecretBuffer, error)
|
||||
AsBuffer(secret []byte) SecretBuffer
|
||||
Replace(secret []byte)
|
||||
}
|
||||
|
||||
// SecretBuffer allows to access the content of the secret
|
||||
type SecretBuffer interface {
|
||||
// Size returns the length of the buffer content
|
||||
Size() int
|
||||
// Grow will grow the capacity of the underlying buffer to the given size
|
||||
Grow(capacity int)
|
||||
// Bytes returns the content of the buffer as bytes.
|
||||
// NOTE: The returned bytes shall NOT be accessed after destroying the
|
||||
// buffer using 'Destroy()' as the underlying the memory area might be
|
||||
// wiped and invalid.
|
||||
Bytes() []byte
|
||||
// TemporaryString returns the content of the buffer as a string.
|
||||
// NOTE: The returned String shall NOT be accessed after destroying the
|
||||
// buffer using 'Destroy()' as the underlying the memory area might be
|
||||
// wiped and invalid.
|
||||
TemporaryString() string
|
||||
// String returns a copy of the underlying buffer's content as string.
|
||||
// It is safe to use the returned value after destroying the buffer.
|
||||
String() string
|
||||
// Destroy will wipe the buffer's content and destroy the underlying
|
||||
// buffer. Do not access the buffer after destroying it.
|
||||
Destroy()
|
||||
}
|
||||
|
||||
// Secret safely stores sensitive data such as a password or token
|
||||
type Secret struct {
|
||||
enclave *memguard.Enclave
|
||||
// container is the implementation for holding the secret. It can be
|
||||
// protected or not depending on the concrete implementation.
|
||||
container secretContainer
|
||||
|
||||
// resolvers are the functions for resolving a given secret-id (key)
|
||||
resolvers map[string]telegraf.ResolveFunc
|
||||
|
||||
// unlinked contains all references in the secret that are not yet
|
||||
// linked to the corresponding secret store.
|
||||
unlinked []string
|
||||
|
||||
// Denotes if the secret is completely empty
|
||||
// notempty denotes if the secret is completely empty
|
||||
notempty bool
|
||||
}
|
||||
|
||||
|
|
@ -71,10 +119,10 @@ func (s *Secret) init(secret []byte) {
|
|||
|
||||
// Find all parts that need to be resolved and return them
|
||||
s.unlinked = secretPattern.FindAllString(string(secret), -1)
|
||||
|
||||
// Setup the enclave
|
||||
s.enclave = memguard.NewEnclave(secret)
|
||||
s.resolvers = nil
|
||||
|
||||
// Setup the container implementation
|
||||
s.container = selectedImpl.Container(secret)
|
||||
}
|
||||
|
||||
// Destroy the secret content
|
||||
|
|
@ -83,17 +131,11 @@ func (s *Secret) Destroy() {
|
|||
s.unlinked = nil
|
||||
s.notempty = false
|
||||
|
||||
if s.enclave == nil {
|
||||
return
|
||||
if s.container != nil {
|
||||
s.container.Destroy()
|
||||
s.container = nil
|
||||
}
|
||||
|
||||
// Wipe the secret from memory
|
||||
lockbuf, err := s.enclave.Open()
|
||||
if err == nil {
|
||||
lockbuf.Destroy()
|
||||
}
|
||||
s.enclave = nil
|
||||
|
||||
// Keep track of the number of secrets...
|
||||
secretCount.Add(-1)
|
||||
}
|
||||
|
|
@ -105,7 +147,7 @@ func (s *Secret) Empty() bool {
|
|||
|
||||
// EqualTo performs a constant-time comparison of the secret to the given reference
|
||||
func (s *Secret) EqualTo(ref []byte) (bool, error) {
|
||||
if s.enclave == nil {
|
||||
if s.container == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
|
|
@ -113,20 +155,13 @@ func (s *Secret) EqualTo(ref []byte) (bool, error) {
|
|||
return false, fmt.Errorf("unlinked parts in secret: %v", strings.Join(s.unlinked, ";"))
|
||||
}
|
||||
|
||||
// Get a locked-buffer of the secret to perform the comparison
|
||||
lockbuf, err := s.enclave.Open()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("opening enclave failed: %w", err)
|
||||
}
|
||||
defer lockbuf.Destroy()
|
||||
|
||||
return lockbuf.EqualTo(ref), nil
|
||||
return s.container.Equals(ref)
|
||||
}
|
||||
|
||||
// Get return the string representation of the secret
|
||||
func (s *Secret) Get() ([]byte, error) {
|
||||
if s.enclave == nil {
|
||||
return nil, nil
|
||||
func (s *Secret) Get() (SecretBuffer, error) {
|
||||
if s.container == nil {
|
||||
return selectedImpl.EmptyBuffer(), nil
|
||||
}
|
||||
|
||||
if len(s.unlinked) > 0 {
|
||||
|
|
@ -134,22 +169,19 @@ func (s *Secret) Get() ([]byte, error) {
|
|||
}
|
||||
|
||||
// Decrypt the secret so we can return it
|
||||
lockbuf, err := s.enclave.Open()
|
||||
buffer, err := s.container.Buffer()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening enclave failed: %w", err)
|
||||
return nil, err
|
||||
}
|
||||
defer lockbuf.Destroy()
|
||||
secret := lockbuf.Bytes()
|
||||
|
||||
// We've got a static secret so simply return the buffer
|
||||
if len(s.resolvers) == 0 {
|
||||
// Make a copy as we cannot access lockbuf after Destroy, i.e.
|
||||
// after this function finishes.
|
||||
newsecret := append([]byte{}, secret...)
|
||||
return newsecret, protect(newsecret)
|
||||
return buffer, nil
|
||||
}
|
||||
defer buffer.Destroy()
|
||||
|
||||
replaceErrs := make([]string, 0)
|
||||
newsecret := secretPattern.ReplaceAllFunc(secret, func(match []byte) []byte {
|
||||
newsecret := secretPattern.ReplaceAllFunc(buffer.Bytes(), func(match []byte) []byte {
|
||||
resolver, found := s.resolvers[string(match)]
|
||||
if !found {
|
||||
replaceErrs = append(replaceErrs, fmt.Sprintf("no resolver for %q", match))
|
||||
|
|
@ -164,11 +196,11 @@ func (s *Secret) Get() ([]byte, error) {
|
|||
return replacement
|
||||
})
|
||||
if len(replaceErrs) > 0 {
|
||||
memguard.WipeBytes(newsecret)
|
||||
selectedImpl.Wipe(newsecret)
|
||||
return nil, fmt.Errorf("replacing secrets failed: %s", strings.Join(replaceErrs, ";"))
|
||||
}
|
||||
|
||||
return newsecret, protect(newsecret)
|
||||
return s.container.AsBuffer(newsecret), nil
|
||||
}
|
||||
|
||||
// Set overwrites the secret's value with a new one. Please note, the secret
|
||||
|
|
@ -182,7 +214,7 @@ func (s *Secret) Set(value []byte) error {
|
|||
}
|
||||
|
||||
// Set the new secret
|
||||
s.enclave = memguard.NewEnclave(secret)
|
||||
s.container.Replace(secret)
|
||||
s.resolvers = res
|
||||
s.notempty = len(value) > 0
|
||||
|
||||
|
|
@ -198,27 +230,26 @@ func (s *Secret) GetUnlinked() []string {
|
|||
// secret-store resolvers.
|
||||
func (s *Secret) Link(resolvers map[string]telegraf.ResolveFunc) error {
|
||||
// Decrypt the secret so we can return it
|
||||
if s.enclave == nil {
|
||||
if s.container == nil {
|
||||
return nil
|
||||
}
|
||||
lockbuf, err := s.enclave.Open()
|
||||
buffer, err := s.container.Buffer()
|
||||
if err != nil {
|
||||
return fmt.Errorf("opening enclave failed: %w", err)
|
||||
return err
|
||||
}
|
||||
defer lockbuf.Destroy()
|
||||
secret := lockbuf.Bytes()
|
||||
defer buffer.Destroy()
|
||||
|
||||
// Iterate through the parts and try to resolve them. For static parts
|
||||
// we directly replace them, while for dynamic ones we store the resolver.
|
||||
newsecret, res, replaceErrs := resolve(secret, resolvers)
|
||||
newsecret, res, replaceErrs := resolve(buffer.Bytes(), resolvers)
|
||||
if len(replaceErrs) > 0 {
|
||||
return fmt.Errorf("linking secrets failed: %s", strings.Join(replaceErrs, ";"))
|
||||
}
|
||||
s.resolvers = res
|
||||
|
||||
// Store the secret if it has changed
|
||||
if string(secret) != string(newsecret) {
|
||||
s.enclave = memguard.NewEnclave(newsecret)
|
||||
if buffer.TemporaryString() != string(newsecret) {
|
||||
s.container.Replace(newsecret)
|
||||
}
|
||||
|
||||
// All linked now
|
||||
|
|
|
|||
|
|
@ -0,0 +1,131 @@
|
|||
package config
|
||||
|
||||
import (
|
||||
"fmt"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
)
|
||||
|
||||
type protectedSecretImpl struct{}
|
||||
|
||||
func (*protectedSecretImpl) Container(secret []byte) secretContainer {
|
||||
return &protectedSecretContainer{
|
||||
enclave: memguard.NewEnclave(secret),
|
||||
}
|
||||
}
|
||||
|
||||
func (*protectedSecretImpl) EmptyBuffer() SecretBuffer {
|
||||
return &lockedBuffer{}
|
||||
}
|
||||
|
||||
func (*protectedSecretImpl) Wipe(secret []byte) {
|
||||
memguard.WipeBytes(secret)
|
||||
}
|
||||
|
||||
type lockedBuffer struct {
|
||||
buf *memguard.LockedBuffer
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) Size() int {
|
||||
if lb.buf == nil {
|
||||
return 0
|
||||
}
|
||||
return lb.buf.Size()
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) Grow(capacity int) {
|
||||
size := lb.Size()
|
||||
if capacity <= size {
|
||||
return
|
||||
}
|
||||
|
||||
buf := memguard.NewBuffer(capacity)
|
||||
if lb.buf != nil {
|
||||
buf.Copy(lb.buf.Bytes())
|
||||
}
|
||||
lb.buf.Destroy()
|
||||
lb.buf = buf
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) Bytes() []byte {
|
||||
if lb.buf == nil {
|
||||
return nil
|
||||
}
|
||||
return lb.buf.Bytes()
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) TemporaryString() string {
|
||||
if lb.buf == nil {
|
||||
return ""
|
||||
}
|
||||
return lb.buf.String()
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) String() string {
|
||||
if lb.buf == nil {
|
||||
return ""
|
||||
}
|
||||
return string(lb.buf.Bytes())
|
||||
}
|
||||
|
||||
func (lb *lockedBuffer) Destroy() {
|
||||
if lb.buf == nil {
|
||||
return
|
||||
}
|
||||
lb.buf.Destroy()
|
||||
lb.buf = nil
|
||||
}
|
||||
|
||||
type protectedSecretContainer struct {
|
||||
enclave *memguard.Enclave
|
||||
}
|
||||
|
||||
func (c *protectedSecretContainer) Destroy() {
|
||||
if c.enclave == nil {
|
||||
return
|
||||
}
|
||||
|
||||
// Wipe the secret from memory
|
||||
lockbuf, err := c.enclave.Open()
|
||||
if err == nil {
|
||||
lockbuf.Destroy()
|
||||
}
|
||||
c.enclave = nil
|
||||
}
|
||||
|
||||
func (c *protectedSecretContainer) Equals(ref []byte) (bool, error) {
|
||||
if c.enclave == nil {
|
||||
return false, nil
|
||||
}
|
||||
|
||||
// Get a locked-buffer of the secret to perform the comparison
|
||||
lockbuf, err := c.enclave.Open()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("opening enclave failed: %w", err)
|
||||
}
|
||||
defer lockbuf.Destroy()
|
||||
|
||||
return lockbuf.EqualTo(ref), nil
|
||||
}
|
||||
|
||||
func (c *protectedSecretContainer) Buffer() (SecretBuffer, error) {
|
||||
if c.enclave == nil {
|
||||
return &lockedBuffer{}, nil
|
||||
}
|
||||
|
||||
// Get a locked-buffer of the secret to perform the comparison
|
||||
lockbuf, err := c.enclave.Open()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("opening enclave failed: %w", err)
|
||||
}
|
||||
|
||||
return &lockedBuffer{lockbuf}, nil
|
||||
}
|
||||
|
||||
func (c *protectedSecretContainer) AsBuffer(secret []byte) SecretBuffer {
|
||||
return &lockedBuffer{memguard.NewBufferFromBytes(secret)}
|
||||
}
|
||||
|
||||
func (c *protectedSecretContainer) Replace(secret []byte) {
|
||||
c.enclave = memguard.NewEnclave(secret)
|
||||
}
|
||||
|
|
@ -19,8 +19,8 @@ func TestSecretConstantManually(t *testing.T) {
|
|||
defer s.Destroy()
|
||||
retrieved, err := s.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(retrieved)
|
||||
require.EqualValues(t, mysecret, retrieved)
|
||||
defer retrieved.Destroy()
|
||||
require.EqualValues(t, mysecret, retrieved.TemporaryString())
|
||||
}
|
||||
|
||||
func TestLinking(t *testing.T) {
|
||||
|
|
@ -35,8 +35,8 @@ func TestLinking(t *testing.T) {
|
|||
require.NoError(t, s.Link(resolvers))
|
||||
retrieved, err := s.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(retrieved)
|
||||
require.EqualValues(t, "a resolved secret", retrieved)
|
||||
defer retrieved.Destroy()
|
||||
require.EqualValues(t, "a resolved secret", retrieved.TemporaryString())
|
||||
}
|
||||
|
||||
func TestLinkingResolverError(t *testing.T) {
|
||||
|
|
@ -96,8 +96,8 @@ func TestUninitializedEnclave(t *testing.T) {
|
|||
require.NoError(t, s.Link(map[string]telegraf.ResolveFunc{}))
|
||||
retrieved, err := s.Get()
|
||||
require.NoError(t, err)
|
||||
require.Empty(t, retrieved)
|
||||
ReleaseSecret(retrieved)
|
||||
defer retrieved.Destroy()
|
||||
require.Empty(t, retrieved.Bytes())
|
||||
}
|
||||
|
||||
func TestEnclaveOpenError(t *testing.T) {
|
||||
|
|
@ -162,9 +162,9 @@ func TestSecretConstant(t *testing.T) {
|
|||
plugin := c.Inputs[0].Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
require.EqualValues(t, tt.expected, string(secret))
|
||||
require.EqualValues(t, tt.expected, secret.TemporaryString())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -313,9 +313,9 @@ func TestSecretUnquote(t *testing.T) {
|
|||
plugin := c.Inputs[0].Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
require.EqualValues(t, plugin.Expected, string(secret))
|
||||
require.EqualValues(t, plugin.Expected, secret.TemporaryString())
|
||||
})
|
||||
}
|
||||
}
|
||||
|
|
@ -343,9 +343,9 @@ func TestSecretEnvironmentVariable(t *testing.T) {
|
|||
plugin := c.Inputs[0].Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
require.EqualValues(t, "an env secret", secret)
|
||||
require.EqualValues(t, "an env secret", secret.TemporaryString())
|
||||
}
|
||||
|
||||
func TestSecretStoreStatic(t *testing.T) {
|
||||
|
|
@ -384,8 +384,8 @@ func TestSecretStoreStatic(t *testing.T) {
|
|||
plugin := input.Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, expected[i], secret)
|
||||
ReleaseSecret(secret)
|
||||
require.EqualValues(t, expected[i], secret.TemporaryString())
|
||||
secret.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -430,8 +430,8 @@ func TestSecretStoreInvalidKeys(t *testing.T) {
|
|||
plugin := input.Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
require.EqualValues(t, expected[i], secret)
|
||||
ReleaseSecret(secret)
|
||||
require.EqualValues(t, expected[i], secret.TemporaryString())
|
||||
secret.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -507,9 +507,9 @@ func TestSecretStoreStaticChanging(t *testing.T) {
|
|||
plugin := c.Inputs[0].Input.(*MockupSecretPlugin)
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
require.EqualValues(t, "Ood Bnar", secret)
|
||||
require.EqualValues(t, "Ood Bnar", secret.TemporaryString())
|
||||
|
||||
for _, v := range sequence {
|
||||
store.Secrets["secret"] = []byte(v)
|
||||
|
|
@ -517,8 +517,8 @@ func TestSecretStoreStaticChanging(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// The secret should not change as the store is marked non-dyamic!
|
||||
require.EqualValues(t, "Ood Bnar", secret)
|
||||
ReleaseSecret(secret)
|
||||
require.EqualValues(t, "Ood Bnar", secret.TemporaryString())
|
||||
secret.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -553,8 +553,8 @@ func TestSecretStoreDynamic(t *testing.T) {
|
|||
require.NoError(t, err)
|
||||
|
||||
// The secret should not change as the store is marked non-dynamic!
|
||||
require.EqualValues(t, v, secret)
|
||||
ReleaseSecret(secret)
|
||||
require.EqualValues(t, v, secret.TemporaryString())
|
||||
secret.Destroy()
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -620,14 +620,14 @@ func TestSecretSet(t *testing.T) {
|
|||
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
require.EqualValues(t, "a secret", string(secret))
|
||||
defer secret.Destroy()
|
||||
require.EqualValues(t, "a secret", secret.TemporaryString())
|
||||
|
||||
require.NoError(t, plugin.Secret.Set([]byte("another secret")))
|
||||
newsecret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(newsecret)
|
||||
require.EqualValues(t, "another secret", string(newsecret))
|
||||
defer newsecret.Destroy()
|
||||
require.EqualValues(t, "another secret", newsecret.TemporaryString())
|
||||
}
|
||||
|
||||
func TestSecretSetResolve(t *testing.T) {
|
||||
|
|
@ -654,14 +654,14 @@ func TestSecretSetResolve(t *testing.T) {
|
|||
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
require.EqualValues(t, "Ood Bnar", string(secret))
|
||||
defer secret.Destroy()
|
||||
require.EqualValues(t, "Ood Bnar", secret.TemporaryString())
|
||||
|
||||
require.NoError(t, plugin.Secret.Set([]byte("@{mock:secret} is cool")))
|
||||
newsecret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(newsecret)
|
||||
require.EqualValues(t, "Ood Bnar is cool", string(newsecret))
|
||||
defer newsecret.Destroy()
|
||||
require.EqualValues(t, "Ood Bnar is cool", newsecret.TemporaryString())
|
||||
}
|
||||
|
||||
func TestSecretSetResolveInvalid(t *testing.T) {
|
||||
|
|
@ -688,8 +688,8 @@ func TestSecretSetResolveInvalid(t *testing.T) {
|
|||
|
||||
secret, err := plugin.Secret.Get()
|
||||
require.NoError(t, err)
|
||||
defer ReleaseSecret(secret)
|
||||
require.EqualValues(t, "Ood Bnar", string(secret))
|
||||
defer secret.Destroy()
|
||||
require.EqualValues(t, "Ood Bnar", secret.TemporaryString())
|
||||
|
||||
err = plugin.Secret.Set([]byte("@{mock:another_secret}"))
|
||||
require.ErrorContains(t, err, `linking new secrets failed: unlinked part "@{mock:another_secret}"`)
|
||||
|
|
|
|||
|
|
@ -1,20 +0,0 @@
|
|||
//go:build linux
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"syscall"
|
||||
|
||||
"github.com/awnumar/memguard"
|
||||
)
|
||||
|
||||
func protect(secret []byte) error {
|
||||
return syscall.Mlock(secret)
|
||||
}
|
||||
|
||||
func ReleaseSecret(secret []byte) {
|
||||
memguard.WipeBytes(secret)
|
||||
if err := syscall.Munlock(secret); err != nil {
|
||||
panic(err)
|
||||
}
|
||||
}
|
||||
|
|
@ -1,15 +0,0 @@
|
|||
//go:build !linux
|
||||
|
||||
package config
|
||||
|
||||
import (
|
||||
"github.com/awnumar/memguard"
|
||||
)
|
||||
|
||||
func protect(_ []byte) error {
|
||||
return nil
|
||||
}
|
||||
|
||||
func ReleaseSecret(secret []byte) {
|
||||
memguard.WipeBytes(secret)
|
||||
}
|
||||
|
|
@ -33,14 +33,14 @@ func (k *SASLAuth) SetSASLConfig(cfg *sarama.Config) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
cfg.Net.SASL.User = string(username)
|
||||
config.ReleaseSecret(username)
|
||||
cfg.Net.SASL.User = username.String()
|
||||
username.Destroy()
|
||||
password, err := k.SASLPassword.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
cfg.Net.SASL.Password = string(password)
|
||||
config.ReleaseSecret(password)
|
||||
cfg.Net.SASL.Password = password.String()
|
||||
password.Destroy()
|
||||
|
||||
if k.SASLMechanism != "" {
|
||||
cfg.Net.SASL.Mechanism = sarama.SASLMechanism(k.SASLMechanism)
|
||||
|
|
@ -58,8 +58,8 @@ func (k *SASLAuth) SetSASLConfig(cfg *sarama.Config) error {
|
|||
case sarama.SASLTypeGSSAPI:
|
||||
cfg.Net.SASL.GSSAPI.ServiceName = k.SASLGSSAPIServiceName
|
||||
cfg.Net.SASL.GSSAPI.AuthType = gssapiAuthType(k.SASLGSSAPIAuthType)
|
||||
cfg.Net.SASL.GSSAPI.Username = string(username)
|
||||
cfg.Net.SASL.GSSAPI.Password = string(password)
|
||||
cfg.Net.SASL.GSSAPI.Username = username.String()
|
||||
cfg.Net.SASL.GSSAPI.Password = password.String()
|
||||
cfg.Net.SASL.GSSAPI.DisablePAFXFAST = k.SASLGSSAPIDisablePAFXFAST
|
||||
cfg.Net.SASL.GSSAPI.KerberosConfigPath = k.SASLGSSAPIKerberosConfigPath
|
||||
cfg.Net.SASL.GSSAPI.KeyTabPath = k.SASLGSSAPIKeyTabPath
|
||||
|
|
@ -71,7 +71,7 @@ func (k *SASLAuth) SetSASLConfig(cfg *sarama.Config) error {
|
|||
}
|
||||
}
|
||||
|
||||
if len(username) > 0 || k.SASLMechanism != "" {
|
||||
if !k.SASLUsername.Empty() || k.SASLMechanism != "" {
|
||||
cfg.Net.SASL.Enable = true
|
||||
|
||||
version, err := SASLVersion(cfg.Version, k.SASLVersion)
|
||||
|
|
@ -89,9 +89,9 @@ func (k *SASLAuth) Token() (*sarama.AccessToken, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(token)
|
||||
defer token.Destroy()
|
||||
return &sarama.AccessToken{
|
||||
Token: string(token),
|
||||
Token: token.String(),
|
||||
Extensions: k.SASLExtentions,
|
||||
}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -6,7 +6,6 @@ import (
|
|||
|
||||
mqttv3 "github.com/eclipse/paho.mqtt.golang" // Library that supports v3.1.1
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
"github.com/influxdata/telegraf/internal"
|
||||
)
|
||||
|
||||
|
|
@ -54,16 +53,16 @@ func NewMQTTv311Client(cfg *MqttConfig) (*mqttv311Client, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
opts.SetUsername(string(user))
|
||||
config.ReleaseSecret(user)
|
||||
opts.SetUsername(user.String())
|
||||
user.Destroy()
|
||||
}
|
||||
if !cfg.Password.Empty() {
|
||||
password, err := cfg.Password.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
opts.SetPassword(string(password))
|
||||
config.ReleaseSecret(password)
|
||||
opts.SetPassword(password.String())
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
servers, err := parseServers(cfg.Servers)
|
||||
|
|
|
|||
|
|
@ -17,6 +17,8 @@ import (
|
|||
type mqttv5Client struct {
|
||||
client *mqttv5auto.ConnectionManager
|
||||
options mqttv5auto.ClientConfig
|
||||
username config.Secret
|
||||
password config.Secret
|
||||
timeout time.Duration
|
||||
qos int
|
||||
retain bool
|
||||
|
|
@ -47,19 +49,6 @@ func NewMQTTv5Client(cfg *MqttConfig) (*mqttv5Client, error) {
|
|||
opts.ClientID = "Telegraf-Output-" + id
|
||||
}
|
||||
|
||||
user, err := cfg.Username.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
pass, err := cfg.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(user)
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
opts.SetUsernamePassword(string(user), pass)
|
||||
config.ReleaseSecret(user)
|
||||
config.ReleaseSecret(pass)
|
||||
|
||||
tlsCfg, err := cfg.ClientConfig.TLSConfig()
|
||||
if err != nil {
|
||||
return nil, err
|
||||
|
|
@ -107,6 +96,8 @@ func NewMQTTv5Client(cfg *MqttConfig) (*mqttv5Client, error) {
|
|||
return &mqttv5Client{
|
||||
options: opts,
|
||||
timeout: time.Duration(cfg.Timeout),
|
||||
username: cfg.Username,
|
||||
password: config.Password,
|
||||
qos: cfg.QoS,
|
||||
retain: cfg.Retain,
|
||||
properties: properties,
|
||||
|
|
@ -114,6 +105,18 @@ func NewMQTTv5Client(cfg *MqttConfig) (*mqttv5Client, error) {
|
|||
}
|
||||
|
||||
func (m *mqttv5Client) Connect() (bool, error) {
|
||||
user, err := m.username.Get()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer user.Destroy()
|
||||
pass, err := m.password.Get()
|
||||
if err != nil {
|
||||
return false, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer pass.Destroy()
|
||||
m.options.SetUsernamePassword(user.TemporaryString(), pass.Bytes())
|
||||
|
||||
client, err := mqttv5auto.NewConnection(context.Background(), m.options)
|
||||
if err != nil {
|
||||
return false, err
|
||||
|
|
|
|||
|
|
@ -301,21 +301,21 @@ func (o *OpcUAClient) generateAuth(a string, cert []byte, user, passwd config.Se
|
|||
|
||||
var username, password []byte
|
||||
if !user.Empty() {
|
||||
var err error
|
||||
username, err = user.Get()
|
||||
usecret, err := user.Get()
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("error reading the username input: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer usecret.Destroy()
|
||||
username = usecret.Bytes()
|
||||
}
|
||||
|
||||
if !passwd.Empty() {
|
||||
var err error
|
||||
password, err = passwd.Get()
|
||||
psecret, err := passwd.Get()
|
||||
if err != nil {
|
||||
return 0, nil, fmt.Errorf("error reading the password input: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer psecret.Destroy()
|
||||
password = psecret.Bytes()
|
||||
}
|
||||
authOption = opcua.AuthUsername(string(username), string(password))
|
||||
case "certificate":
|
||||
|
|
|
|||
|
|
@ -289,17 +289,18 @@ func (c *CtrlXDataLayer) Start(acc telegraf.Accumulator) error {
|
|||
|
||||
password, err := c.Password.Get()
|
||||
if err != nil {
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
|
||||
c.tokenManager = token.TokenManager{
|
||||
Url: c.url,
|
||||
Username: string(username),
|
||||
Password: string(password),
|
||||
Username: username.String(),
|
||||
Password: password.String(),
|
||||
Connection: c.connection,
|
||||
}
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
|
||||
c.acc = acc
|
||||
|
||||
|
|
|
|||
|
|
@ -73,7 +73,7 @@ func (m *Example) Init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
|
||||
// Initialze your internal states
|
||||
m.count = 1
|
||||
|
|
|
|||
|
|
@ -112,10 +112,7 @@ func (h *HTTP) SetParserFunc(fn telegraf.ParserFunc) {
|
|||
// Returns:
|
||||
//
|
||||
// error: Any error that may have occurred
|
||||
func (h *HTTP) gatherURL(
|
||||
acc telegraf.Accumulator,
|
||||
url string,
|
||||
) error {
|
||||
func (h *HTTP) gatherURL(acc telegraf.Accumulator, url string) error {
|
||||
body := makeRequestBodyReader(h.ContentEncoding, h.Body)
|
||||
request, err := http.NewRequest(h.Method, url, body)
|
||||
if err != nil {
|
||||
|
|
@ -127,7 +124,8 @@ func (h *HTTP) gatherURL(
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
bearer := "Bearer " + strings.TrimSpace(string(token))
|
||||
bearer := "Bearer " + strings.TrimSpace(token.String())
|
||||
token.Destroy()
|
||||
request.Header.Set("Authorization", bearer)
|
||||
} else if h.TokenFile != "" {
|
||||
token, err := os.ReadFile(h.BearerToken)
|
||||
|
|
@ -209,15 +207,15 @@ func (h *HTTP) setRequestAuth(request *http.Request) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
|
||||
password, err := h.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
|
||||
request.SetBasicAuth(string(username), string(password))
|
||||
request.SetBasicAuth(username.String(), password.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -407,13 +407,13 @@ func (h *HTTPResponse) setRequestAuth(request *http.Request) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
password, err := h.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
request.SetBasicAuth(string(username), string(password))
|
||||
defer password.Destroy()
|
||||
request.SetBasicAuth(username.String(), password.String())
|
||||
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -370,8 +370,8 @@ func (m *MQTTConsumer) createOpts() (*mqtt.ClientOptions, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
opts.SetUsername(string(user))
|
||||
config.ReleaseSecret(user)
|
||||
opts.SetUsername(user.String())
|
||||
user.Destroy()
|
||||
}
|
||||
|
||||
if !m.Password.Empty() {
|
||||
|
|
@ -379,8 +379,8 @@ func (m *MQTTConsumer) createOpts() (*mqtt.ClientOptions, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
opts.SetPassword(string(password))
|
||||
config.ReleaseSecret(password)
|
||||
opts.SetPassword(password.String())
|
||||
password.Destroy()
|
||||
}
|
||||
if len(m.Servers) == 0 {
|
||||
return opts, fmt.Errorf("could not get host information")
|
||||
|
|
|
|||
|
|
@ -109,8 +109,8 @@ func (m *Mysql) Init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting server %d failed: %w", i, err)
|
||||
}
|
||||
dsn := string(dsnSecret)
|
||||
config.ReleaseSecret(dsnSecret)
|
||||
dsn := dsnSecret.String()
|
||||
dsnSecret.Destroy()
|
||||
conf, err := mysql.ParseDSN(dsn)
|
||||
if err != nil {
|
||||
return fmt.Errorf("parsing %q failed: %w", dsn, err)
|
||||
|
|
@ -419,8 +419,8 @@ func (m *Mysql) gatherServer(server *config.Secret, acc telegraf.Accumulator) er
|
|||
if err != nil {
|
||||
return err
|
||||
}
|
||||
dsn := string(dsnSecret)
|
||||
config.ReleaseSecret(dsnSecret)
|
||||
dsn := dsnSecret.String()
|
||||
dsnSecret.Destroy()
|
||||
servtag := getDSNTag(dsn)
|
||||
|
||||
db, err := sql.Open("mysql", dsn)
|
||||
|
|
|
|||
|
|
@ -109,19 +109,19 @@ func (o *OpensearchQuery) newClient() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer username.Destroy()
|
||||
|
||||
password, err := o.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer password.Destroy()
|
||||
|
||||
clientConfig := opensearch.Config{
|
||||
Addresses: o.URLs,
|
||||
Username: string(username),
|
||||
Password: string(password),
|
||||
Username: username.String(),
|
||||
Password: password.String(),
|
||||
}
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
|
||||
if o.InsecureSkipVerify {
|
||||
clientConfig.Transport = &http.Transport{
|
||||
|
|
|
|||
|
|
@ -1,7 +1,6 @@
|
|||
package postgresql
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"database/sql"
|
||||
"fmt"
|
||||
"net"
|
||||
|
|
@ -106,8 +105,8 @@ func (p *Service) Start(telegraf.Accumulator) (err error) {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting address failed: %w", err)
|
||||
}
|
||||
addr := string(addrSecret)
|
||||
defer config.ReleaseSecret(addrSecret)
|
||||
addr := addrSecret.String()
|
||||
defer addrSecret.Destroy()
|
||||
|
||||
if p.Address.Empty() || addr == "localhost" {
|
||||
addr = "host=localhost sslmode=disable"
|
||||
|
|
@ -161,15 +160,15 @@ func (p *Service) SanitizedAddress() (sanitizedAddress string, err error) {
|
|||
if err != nil {
|
||||
return sanitizedAddress, fmt.Errorf("getting address for sanitization failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(addr)
|
||||
defer addr.Destroy()
|
||||
|
||||
var canonicalizedAddress string
|
||||
if bytes.HasPrefix(addr, []byte("postgres://")) || bytes.HasPrefix(addr, []byte("postgresql://")) {
|
||||
if canonicalizedAddress, err = parseURL(string(addr)); err != nil {
|
||||
if strings.HasPrefix(addr.TemporaryString(), "postgres://") || strings.HasPrefix(addr.TemporaryString(), "postgresql://") {
|
||||
if canonicalizedAddress, err = parseURL(addr.String()); err != nil {
|
||||
return sanitizedAddress, err
|
||||
}
|
||||
} else {
|
||||
canonicalizedAddress = string(addr)
|
||||
canonicalizedAddress = addr.String()
|
||||
}
|
||||
|
||||
return kvMatcher.ReplaceAllString(canonicalizedAddress, ""), nil
|
||||
|
|
|
|||
|
|
@ -75,28 +75,35 @@ func (r *Radius) pollServer(acc telegraf.Accumulator, server string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting secret failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
username, err := r.Username.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
|
||||
password, err := r.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
|
||||
// Create the radius packet with PAP authentication
|
||||
packet := radius.New(radius.CodeAccessRequest, secret)
|
||||
err = rfc2865.UserName_Set(packet, username)
|
||||
if err != nil {
|
||||
packet := radius.New(radius.CodeAccessRequest, secret.Bytes())
|
||||
if err := rfc2865.UserName_Set(packet, username.Bytes()); err != nil {
|
||||
return fmt.Errorf("setting username for radius auth failed: %w", err)
|
||||
}
|
||||
err = rfc2865.UserPassword_Set(packet, password)
|
||||
if err != nil {
|
||||
|
||||
// The radius client requires the password in a buffer with capacity being
|
||||
// a multiple of 16 for internal operations. To not expose the password we
|
||||
// grow the (potentially protected) buffer to the required capacity.
|
||||
capacity := password.Size()
|
||||
if capacity%16 != 0 {
|
||||
password.Grow(capacity + 16 - capacity%16)
|
||||
}
|
||||
|
||||
if err := rfc2865.UserPassword_Set(packet, password.Bytes()[:capacity]); err != nil {
|
||||
return fmt.Errorf("setting password for radius auth failed: %w", err)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -192,22 +192,22 @@ func (s *SnmpTrap) Start(acc telegraf.Accumulator) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting secname failed: %w", err)
|
||||
}
|
||||
secname := string(secnameSecret)
|
||||
config.ReleaseSecret(secnameSecret)
|
||||
secname := secnameSecret.String()
|
||||
secnameSecret.Destroy()
|
||||
|
||||
privPasswdSecret, err := s.PrivPassword.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting secname failed: %w", err)
|
||||
}
|
||||
privPasswd := string(privPasswdSecret)
|
||||
config.ReleaseSecret(privPasswdSecret)
|
||||
privPasswd := privPasswdSecret.String()
|
||||
privPasswdSecret.Destroy()
|
||||
|
||||
authPasswdSecret, err := s.AuthPassword.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting secname failed: %w", err)
|
||||
}
|
||||
authPasswd := string(authPasswdSecret)
|
||||
config.ReleaseSecret(authPasswdSecret)
|
||||
authPasswd := authPasswdSecret.String()
|
||||
authPasswdSecret.Destroy()
|
||||
|
||||
s.listener.Params.SecurityParameters = &gosnmp.UsmSecurityParameters{
|
||||
UserName: secname,
|
||||
|
|
|
|||
|
|
@ -372,8 +372,8 @@ func (s *SQL) setupConnection() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting DSN failed: %w", err)
|
||||
}
|
||||
dsn := string(dsnSecret)
|
||||
config.ReleaseSecret(dsnSecret)
|
||||
dsn := dsnSecret.String()
|
||||
dsnSecret.Destroy()
|
||||
|
||||
s.Log.Debug("Connecting...")
|
||||
s.db, err = dbsql.Open(s.driverName, dsn)
|
||||
|
|
|
|||
|
|
@ -218,8 +218,8 @@ func (s *SQLServer) Gather(acc telegraf.Accumulator) error {
|
|||
acc.AddError(err)
|
||||
continue
|
||||
}
|
||||
dsn := string(dnsSecret)
|
||||
config.ReleaseSecret(dnsSecret)
|
||||
dsn := dnsSecret.String()
|
||||
dnsSecret.Destroy()
|
||||
|
||||
for _, query := range s.queries {
|
||||
wg.Add(1)
|
||||
|
|
@ -272,8 +272,8 @@ func (s *SQLServer) Start(acc telegraf.Accumulator) error {
|
|||
// Use the DSN (connection string) directly. In this case,
|
||||
// empty username/password causes use of Windows
|
||||
// integrated authentication.
|
||||
pool, err = sql.Open("mssql", string(dsn))
|
||||
config.ReleaseSecret(dsn)
|
||||
pool, err = sql.Open("mssql", dsn.String())
|
||||
dsn.Destroy()
|
||||
if err != nil {
|
||||
acc.AddError(err)
|
||||
continue
|
||||
|
|
@ -300,8 +300,8 @@ func (s *SQLServer) Start(acc telegraf.Accumulator) error {
|
|||
acc.AddError(err)
|
||||
continue
|
||||
}
|
||||
connector, err := mssql.NewAccessTokenConnector(string(dsn), tokenProvider)
|
||||
config.ReleaseSecret(dsn)
|
||||
connector, err := mssql.NewAccessTokenConnector(dsn.String(), tokenProvider)
|
||||
dsn.Destroy()
|
||||
if err != nil {
|
||||
acc.AddError(fmt.Errorf("error creating the SQL connector: %w", err))
|
||||
continue
|
||||
|
|
|
|||
|
|
@ -120,21 +120,21 @@ func (t *Tacacs) pollServer(acc telegraf.Accumulator, client *tacplus.Client) er
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting secret failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(secret)
|
||||
defer secret.Destroy()
|
||||
|
||||
client.ConnConfig.Secret = secret
|
||||
client.ConnConfig.Secret = secret.Bytes()
|
||||
|
||||
username, err := t.Username.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
|
||||
password, err := t.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
|
||||
ctx := context.Background()
|
||||
if t.ResponseTimeout > 0 {
|
||||
|
|
@ -162,7 +162,7 @@ func (t *Tacacs) pollServer(acc telegraf.Accumulator, client *tacplus.Client) er
|
|||
return nil
|
||||
}
|
||||
|
||||
reply, err = session.Continue(ctx, string(username))
|
||||
reply, err = session.Continue(ctx, username.String())
|
||||
if err != nil {
|
||||
if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
return fmt.Errorf("error on tacacs authentication continue username request to %s : %w", client.Addr, err)
|
||||
|
|
@ -179,7 +179,7 @@ func (t *Tacacs) pollServer(acc telegraf.Accumulator, client *tacplus.Client) er
|
|||
return nil
|
||||
}
|
||||
|
||||
reply, err = session.Continue(ctx, string(password))
|
||||
reply, err = session.Continue(ctx, password.String())
|
||||
if err != nil {
|
||||
if !errors.Is(err, context.DeadlineExceeded) && !errors.Is(err, os.ErrDeadlineExceeded) {
|
||||
return fmt.Errorf("error on tacacs authentication continue password request to %s : %w", client.Addr, err)
|
||||
|
|
|
|||
|
|
@ -21,7 +21,6 @@ import (
|
|||
"github.com/vmware/govmomi/vim25/types"
|
||||
|
||||
"github.com/influxdata/telegraf"
|
||||
"github.com/influxdata/telegraf/config"
|
||||
)
|
||||
|
||||
// The highest number of metrics we can query for, no matter what settings
|
||||
|
|
@ -106,13 +105,13 @@ func (cf *ClientFactory) testClient(ctx context.Context) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
password, err := cf.parent.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
auth := url.UserPassword(string(username), string(password))
|
||||
defer password.Destroy()
|
||||
auth := url.UserPassword(username.String(), password.String())
|
||||
|
||||
if err := cf.client.Client.SessionManager.Login(ctx2, auth); err != nil {
|
||||
return fmt.Errorf("renewing authentication failed: %w", err)
|
||||
|
|
@ -143,12 +142,12 @@ func NewClient(ctx context.Context, vSphereURL *url.URL, vs *VSphere) (*Client,
|
|||
}
|
||||
password, err := vs.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
vSphereURL.User = url.UserPassword(string(username), string(password))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
vSphereURL.User = url.UserPassword(username.String(), password.String())
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
vs.Log.Debugf("Creating client: %s", vSphereURL.Host)
|
||||
|
|
|
|||
|
|
@ -301,16 +301,16 @@ func (q *AMQP) makeClientConfig() (*ClientConfig, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
password, err := q.Password.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
auth = []amqp.Authentication{
|
||||
&amqp.PlainAuth{
|
||||
Username: string(username),
|
||||
Password: string(password),
|
||||
Username: username.String(),
|
||||
Password: password.String(),
|
||||
},
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -64,12 +64,12 @@ func (c *Clarify) Init() error {
|
|||
}
|
||||
password, err := c.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
creds := clarify.BasicAuthCredentials(string(username), string(password))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
creds := clarify.BasicAuthCredentials(username.String(), password.String())
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
c.client = creds.Client(ctx)
|
||||
return nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -156,8 +156,8 @@ func (d *Dynatrace) send(msg string) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
req.Header.Add("Authorization", "Api-Token "+string(token))
|
||||
config.ReleaseSecret(token)
|
||||
req.Header.Add("Authorization", "Api-Token "+token.String())
|
||||
token.Destroy()
|
||||
}
|
||||
// add user-agent header to identify metric source
|
||||
req.Header.Add("User-Agent", "telegraf")
|
||||
|
|
|
|||
|
|
@ -472,12 +472,12 @@ func (a *Elasticsearch) getAuthOptions() ([]elastic.ClientOptionFunc, error) {
|
|||
}
|
||||
password, err := a.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
fns = append(fns, elastic.SetBasicAuth(string(username), string(password)))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
fns = append(fns, elastic.SetBasicAuth(username.String(), password.String()))
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
if !a.AuthBearerToken.Empty() {
|
||||
|
|
@ -485,9 +485,9 @@ func (a *Elasticsearch) getAuthOptions() ([]elastic.ClientOptionFunc, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
auth := []string{"Bearer " + string(token)}
|
||||
auth := []string{"Bearer " + token.String()}
|
||||
fns = append(fns, elastic.SetHeaders(http.Header{"Authorization": auth}))
|
||||
config.ReleaseSecret(token)
|
||||
token.Destroy()
|
||||
}
|
||||
return fns, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -79,7 +79,7 @@ func (g *Groundwork) Init() error {
|
|||
}
|
||||
password, err := g.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
g.client = clients.GWClient{
|
||||
|
|
@ -87,13 +87,13 @@ func (g *Groundwork) Init() error {
|
|||
AppType: g.DefaultAppType,
|
||||
GWConnection: &clients.GWConnection{
|
||||
HostName: g.Server,
|
||||
UserName: string(username),
|
||||
Password: string(password),
|
||||
UserName: username.String(),
|
||||
Password: password.String(),
|
||||
IsDynamicInventory: true,
|
||||
},
|
||||
}
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
|
||||
logper.SetLogger(
|
||||
func(fields interface{}, format string, a ...interface{}) {
|
||||
|
|
|
|||
|
|
@ -105,11 +105,8 @@ func (h *HTTP) Close() error {
|
|||
}
|
||||
|
||||
func (h *HTTP) Write(metrics []telegraf.Metric) error {
|
||||
var reqBody []byte
|
||||
|
||||
if h.UseBatchFormat {
|
||||
var err error
|
||||
reqBody, err = h.serializer.SerializeBatch(metrics)
|
||||
reqBody, err := h.serializer.SerializeBatch(metrics)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -118,8 +115,7 @@ func (h *HTTP) Write(metrics []telegraf.Metric) error {
|
|||
}
|
||||
|
||||
for _, metric := range metrics {
|
||||
var err error
|
||||
reqBody, err = h.serializer.Serialize(metric)
|
||||
reqBody, err := h.serializer.Serialize(metric)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
|
@ -185,12 +181,12 @@ func (h *HTTP) writeMetric(reqBody []byte) error {
|
|||
}
|
||||
password, err := h.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
req.SetBasicAuth(string(username), string(password))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
req.SetBasicAuth(username.String(), password.String())
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
// google api auth
|
||||
|
|
|
|||
|
|
@ -500,12 +500,12 @@ func (c *httpClient) addHeaders(req *http.Request) error {
|
|||
}
|
||||
password, err := c.config.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
req.SetBasicAuth(string(username), string(password))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
req.SetBasicAuth(username.String(), password.String())
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
for header, value := range c.config.Headers {
|
||||
|
|
|
|||
|
|
@ -100,9 +100,8 @@ func NewHTTPClient(cfg *HTTPConfig) (*httpClient, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
headers["Authorization"] = "Token " + string(token)
|
||||
config.ReleaseSecret(token)
|
||||
|
||||
headers["Authorization"] = "Token " + token.String()
|
||||
token.Destroy()
|
||||
for k, v := range cfg.Headers {
|
||||
headers[k] = v
|
||||
}
|
||||
|
|
|
|||
|
|
@ -177,14 +177,13 @@ func (i *Instrumental) Write(metrics []telegraf.Metric) error {
|
|||
}
|
||||
|
||||
func (i *Instrumental) authenticate(conn net.Conn) error {
|
||||
tokenSecret, err := i.APIToken.Get()
|
||||
token, err := i.APIToken.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
token := string(tokenSecret)
|
||||
config.ReleaseSecret(tokenSecret)
|
||||
defer token.Destroy()
|
||||
|
||||
if _, err := fmt.Fprintf(conn, HandshakeFormat, token); err != nil {
|
||||
if _, err := fmt.Fprintf(conn, HandshakeFormat, token.TemporaryString()); err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -85,17 +85,18 @@ func (s *IoTDB) Connect() error {
|
|||
}
|
||||
password, err := s.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer password.Destroy()
|
||||
sessionConf := &client.Config{
|
||||
Host: s.Host,
|
||||
Port: s.Port,
|
||||
UserName: string(username),
|
||||
Password: string(password),
|
||||
UserName: username.String(),
|
||||
Password: password.String(),
|
||||
}
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
|
||||
var ss = client.NewSession(sessionConf)
|
||||
s.session = &ss
|
||||
|
|
|
|||
|
|
@ -149,12 +149,12 @@ func (l *Librato) writeBatch(start int, sizeBatch int, metricCounter int, tempGa
|
|||
}
|
||||
token, err := l.APIToken.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(user)
|
||||
user.Destroy()
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
req.SetBasicAuth(string(user), string(token))
|
||||
config.ReleaseSecret(user)
|
||||
config.ReleaseSecret(token)
|
||||
req.SetBasicAuth(user.String(), token.String())
|
||||
user.Destroy()
|
||||
token.Destroy()
|
||||
|
||||
resp, err := l.client.Do(req)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -145,9 +145,9 @@ func (l *Logzio) authURL() (string, error) {
|
|||
if err != nil {
|
||||
return "", fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(token)
|
||||
defer token.Destroy()
|
||||
|
||||
return fmt.Sprintf("%s/?token=%s", l.URL, string(token)), nil
|
||||
return fmt.Sprintf("%s/?token=%s", l.URL, token.TemporaryString()), nil
|
||||
}
|
||||
|
||||
func (l *Logzio) parseMetric(metric telegraf.Metric) *Metric {
|
||||
|
|
|
|||
|
|
@ -163,12 +163,12 @@ func (l *Loki) writeMetrics(s Streams) error {
|
|||
}
|
||||
password, err := l.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
req.SetBasicAuth(string(username), string(password))
|
||||
config.ReleaseSecret(password)
|
||||
config.ReleaseSecret(username)
|
||||
req.SetBasicAuth(username.String(), password.String())
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
for k, v := range l.Headers {
|
||||
|
|
|
|||
|
|
@ -107,16 +107,16 @@ func (s *MongoDB) Init() error {
|
|||
}
|
||||
password, err := s.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
credential := options.Credential{
|
||||
AuthMechanism: "SCRAM-SHA-256",
|
||||
Username: string(username),
|
||||
Password: string(password),
|
||||
Username: username.String(),
|
||||
Password: password.String(),
|
||||
}
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
s.clientOptions.SetAuth(credential)
|
||||
case "X509":
|
||||
//format connection string to include tls/x509 options
|
||||
|
|
|
|||
|
|
@ -58,12 +58,12 @@ func (n *NATS) Connect() error {
|
|||
}
|
||||
password, err := n.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
username.Destroy()
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
opts = append(opts, nats.UserInfo(string(username), string(password)))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
opts = append(opts, nats.UserInfo(username.String(), password.String()))
|
||||
username.Destroy()
|
||||
password.Destroy()
|
||||
}
|
||||
|
||||
if n.Credentials != "" {
|
||||
|
|
|
|||
|
|
@ -140,14 +140,14 @@ func (p *PrometheusClient) Init() error {
|
|||
ipRange = append(ipRange, ipNet)
|
||||
}
|
||||
|
||||
password, err := p.BasicPassword.Get()
|
||||
psecret, err := p.BasicPassword.Get()
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
passwordStr := string(password)
|
||||
defer config.ReleaseSecret(password)
|
||||
password := psecret.String()
|
||||
psecret.Destroy()
|
||||
|
||||
authHandler := internal.BasicAuthHandler(p.BasicUsername, passwordStr, "prometheus", onAuthError)
|
||||
authHandler := internal.BasicAuthHandler(p.BasicUsername, password, "prometheus", onAuthError)
|
||||
rangeHandler := internal.IPRangeHandler(ipRange, onError)
|
||||
promHandler := promhttp.HandlerFor(registry, promhttp.HandlerOpts{ErrorHandling: promhttp.ContinueOnError})
|
||||
landingPageHandler := http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||||
|
|
|
|||
|
|
@ -36,18 +36,18 @@ func (r *RedisTimeSeries) Connect() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
|
||||
password, err := r.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
|
||||
r.client = redis.NewClient(&redis.Options{
|
||||
Addr: r.Address,
|
||||
Username: string(username),
|
||||
Password: string(password),
|
||||
Username: username.String(),
|
||||
Password: password.String(),
|
||||
DB: r.Database,
|
||||
})
|
||||
return r.client.Ping().Err()
|
||||
|
|
|
|||
|
|
@ -86,8 +86,8 @@ func (s *SignalFx) Connect() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
client.AuthToken = string(token)
|
||||
config.ReleaseSecret(token)
|
||||
client.AuthToken = token.String()
|
||||
token.Destroy()
|
||||
|
||||
if s.IngestURL != "" {
|
||||
client.DatapointEndpoint = datapointEndpointForIngestURL(s.IngestURL)
|
||||
|
|
|
|||
|
|
@ -101,13 +101,13 @@ func (q *STOMP) getAuthOption() (func(*stomp.Conn) error, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(username)
|
||||
defer username.Destroy()
|
||||
password, err := q.Password.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(password)
|
||||
return stomp.ConnOpt.Login(string(username), string(password)), nil
|
||||
defer password.Destroy()
|
||||
return stomp.ConnOpt.Login(username.String(), password.String()), nil
|
||||
}
|
||||
|
||||
func init() {
|
||||
|
|
|
|||
|
|
@ -131,8 +131,8 @@ func (w *Warp10) Write(metrics []telegraf.Metric) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
req.Header.Set("X-Warp10-Token", string(token))
|
||||
config.ReleaseSecret(token)
|
||||
req.Header.Set("X-Warp10-Token", token.String())
|
||||
token.Destroy()
|
||||
|
||||
resp, err := w.client.Do(req)
|
||||
if err != nil {
|
||||
|
|
|
|||
|
|
@ -320,12 +320,12 @@ func (w *Wavefront) Close() error {
|
|||
|
||||
func (w *Wavefront) makeAuthOptions() ([]wavefront.Option, error) {
|
||||
if !w.Token.Empty() {
|
||||
b, err := w.Token.Get()
|
||||
tsecret, err := w.Token.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse token value: %w", err)
|
||||
}
|
||||
token := string(b)
|
||||
config.ReleaseSecret(b)
|
||||
token := tsecret.String()
|
||||
tsecret.Destroy()
|
||||
|
||||
return []wavefront.Option{
|
||||
wavefront.APIToken(token),
|
||||
|
|
@ -333,31 +333,31 @@ func (w *Wavefront) makeAuthOptions() ([]wavefront.Option, error) {
|
|||
}
|
||||
|
||||
if !w.AuthCSPAPIToken.Empty() {
|
||||
b, err := w.AuthCSPAPIToken.Get()
|
||||
tsecret, err := w.AuthCSPAPIToken.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to CSP API token value: %w", err)
|
||||
}
|
||||
apiToken := string(b)
|
||||
config.ReleaseSecret(b)
|
||||
apiToken := tsecret.String()
|
||||
tsecret.Destroy()
|
||||
return []wavefront.Option{
|
||||
wavefront.CSPAPIToken(apiToken, wavefront.CSPBaseURL(w.CSPBaseURL)),
|
||||
}, nil
|
||||
}
|
||||
|
||||
if w.AuthCSPClientCredentials != nil {
|
||||
appIDBytes, err := w.AuthCSPClientCredentials.AppID.Get()
|
||||
appIDSecret, err := w.AuthCSPClientCredentials.AppID.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Client Credentials App ID value: %w", err)
|
||||
}
|
||||
appID := string(appIDBytes)
|
||||
config.ReleaseSecret(appIDBytes)
|
||||
appID := appIDSecret.String()
|
||||
appIDSecret.Destroy()
|
||||
|
||||
appSecretBytes, err := w.AuthCSPClientCredentials.AppSecret.Get()
|
||||
appSecret, err := w.AuthCSPClientCredentials.AppSecret.Get()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("failed to parse Client Credentials App Secret value: %w", err)
|
||||
}
|
||||
cspAppSecret := string(appSecretBytes)
|
||||
config.ReleaseSecret(appSecretBytes)
|
||||
cspAppSecret := appSecret.String()
|
||||
appSecret.Destroy()
|
||||
|
||||
options := []wavefront.CSPOption{
|
||||
wavefront.CSPBaseURL(w.CSPBaseURL),
|
||||
|
|
|
|||
|
|
@ -96,12 +96,12 @@ func (a *AesEncryptor) Init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting key failed: %w", err)
|
||||
}
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey)))
|
||||
if _, err := hex.Decode(key, encodedKey); err != nil {
|
||||
config.ReleaseSecret(encodedKey)
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey.Bytes())))
|
||||
_, err = hex.Decode(key, encodedKey.Bytes())
|
||||
encodedKey.Destroy()
|
||||
if err != nil {
|
||||
return fmt.Errorf("decoding key failed: %w", err)
|
||||
}
|
||||
config.ReleaseSecret(encodedKey)
|
||||
actuallen := len(key)
|
||||
memguard.WipeBytes(key)
|
||||
|
||||
|
|
@ -118,8 +118,8 @@ func (a *AesEncryptor) Init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting IV failed: %w", err)
|
||||
}
|
||||
ivlen := len(encodedIV)
|
||||
config.ReleaseSecret(encodedIV)
|
||||
ivlen := len(encodedIV.Bytes())
|
||||
encodedIV.Destroy()
|
||||
if ivlen != 2*aes.BlockSize {
|
||||
return errors.New("init vector size must match block size")
|
||||
}
|
||||
|
|
@ -140,12 +140,12 @@ func (a *AesEncryptor) Decrypt(data []byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting key failed: %w", err)
|
||||
}
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey)))
|
||||
if _, err := hex.Decode(key, encodedKey); err != nil {
|
||||
config.ReleaseSecret(encodedKey)
|
||||
key := make([]byte, hex.DecodedLen(len(encodedKey.Bytes())))
|
||||
_, err = hex.Decode(key, encodedKey.Bytes())
|
||||
encodedKey.Destroy()
|
||||
if err != nil {
|
||||
return nil, fmt.Errorf("decoding key failed: %w", err)
|
||||
}
|
||||
config.ReleaseSecret(encodedKey)
|
||||
|
||||
// Setup AES
|
||||
block, err := aes.NewCipher(key)
|
||||
|
|
@ -158,9 +158,9 @@ func (a *AesEncryptor) Decrypt(data []byte) ([]byte, error) {
|
|||
if err != nil {
|
||||
return nil, fmt.Errorf("getting initialization-vector failed: %w", err)
|
||||
}
|
||||
iv := make([]byte, hex.DecodedLen(len(encodedIV)))
|
||||
_, err = hex.Decode(iv, encodedIV)
|
||||
config.ReleaseSecret(encodedIV)
|
||||
iv := make([]byte, hex.DecodedLen(len(encodedIV.Bytes())))
|
||||
_, err = hex.Decode(iv, encodedIV.Bytes())
|
||||
encodedIV.Destroy()
|
||||
if err != nil {
|
||||
memguard.WipeBytes(iv)
|
||||
return nil, fmt.Errorf("decoding init vector failed: %w", err)
|
||||
|
|
|
|||
|
|
@ -201,14 +201,13 @@ func (h *HTTP) setRequestAuth(request *http.Request) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting username failed: %w", err)
|
||||
}
|
||||
defer username.Destroy()
|
||||
password, err := h.Password.Get()
|
||||
if err != nil {
|
||||
config.ReleaseSecret(username)
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
request.SetBasicAuth(string(username), string(password))
|
||||
config.ReleaseSecret(username)
|
||||
config.ReleaseSecret(password)
|
||||
defer password.Destroy()
|
||||
request.SetBasicAuth(username.String(), password.String())
|
||||
}
|
||||
|
||||
if !h.Token.Empty() {
|
||||
|
|
@ -216,8 +215,8 @@ func (h *HTTP) setRequestAuth(request *http.Request) error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting token failed: %w", err)
|
||||
}
|
||||
bearer := "Bearer " + strings.TrimSpace(string(token))
|
||||
config.ReleaseSecret(token)
|
||||
defer token.Destroy()
|
||||
bearer := "Bearer " + strings.TrimSpace(token.String())
|
||||
request.Header.Set("Authorization", bearer)
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -39,15 +39,15 @@ func (k *KDFConfig) generatePBKDF2HMAC(hf hashFunc, keylen int) (config.Secret,
|
|||
if err != nil {
|
||||
return config.Secret{}, config.Secret{}, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(passwd)
|
||||
defer passwd.Destroy()
|
||||
|
||||
salt, err := k.Salt.Get()
|
||||
if err != nil {
|
||||
return config.Secret{}, config.Secret{}, fmt.Errorf("getting salt failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(salt)
|
||||
defer salt.Destroy()
|
||||
|
||||
rawkey := pbkdf2.Key(passwd, salt, k.Iterations, keylen, hf)
|
||||
rawkey := pbkdf2.Key(passwd.Bytes(), salt.Bytes(), k.Iterations, keylen, hf)
|
||||
key := config.NewSecret([]byte(hex.EncodeToString(rawkey)))
|
||||
return key, config.Secret{}, nil
|
||||
}
|
||||
|
|
|
|||
|
|
@ -41,12 +41,14 @@ func TestKDF(t *testing.T) {
|
|||
|
||||
key, err := skey.Get()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.key, string(key))
|
||||
defer key.Destroy()
|
||||
require.Equal(t, tt.key, key.TemporaryString())
|
||||
|
||||
if tt.iv != "" {
|
||||
iv, err := siv.Get()
|
||||
require.NoError(t, err)
|
||||
require.Equal(t, tt.iv, string(iv))
|
||||
defer iv.Destroy()
|
||||
require.Equal(t, tt.iv, iv.TemporaryString())
|
||||
} else {
|
||||
require.True(t, siv.Empty())
|
||||
}
|
||||
|
|
|
|||
|
|
@ -47,15 +47,15 @@ func (j *Jose) Init() error {
|
|||
if err != nil {
|
||||
return fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(passwd)
|
||||
promptFunc = keyring.FixedStringPrompt(string(passwd))
|
||||
defer passwd.Destroy()
|
||||
promptFunc = keyring.FixedStringPrompt(passwd.String())
|
||||
} else if !config.Password.Empty() {
|
||||
passwd, err := config.Password.Get()
|
||||
if err != nil {
|
||||
return fmt.Errorf("getting global password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(passwd)
|
||||
promptFunc = keyring.FixedStringPrompt(string(passwd))
|
||||
defer passwd.Destroy()
|
||||
promptFunc = keyring.FixedStringPrompt(passwd.String())
|
||||
}
|
||||
|
||||
// Setup the actual keyring
|
||||
|
|
|
|||
|
|
@ -120,19 +120,20 @@ func (o *OAuth2) Init() error {
|
|||
|
||||
csecret, err := c.ClientSecret.Get()
|
||||
if err != nil {
|
||||
cid.Destroy()
|
||||
return fmt.Errorf("getting client secret for %q failed: %w", c.Key, err)
|
||||
}
|
||||
|
||||
// Setup the configuration
|
||||
cfg := &clientcredentials.Config{
|
||||
ClientID: string(cid),
|
||||
ClientSecret: string(csecret),
|
||||
ClientID: cid.String(),
|
||||
ClientSecret: csecret.String(),
|
||||
TokenURL: endpoint.TokenURL,
|
||||
Scopes: c.Scopes,
|
||||
AuthStyle: endpoint.AuthStyle,
|
||||
}
|
||||
config.ReleaseSecret(cid)
|
||||
config.ReleaseSecret(csecret)
|
||||
cid.Destroy()
|
||||
csecret.Destroy()
|
||||
|
||||
// Add the parameters if any
|
||||
for k, v := range c.Params {
|
||||
|
|
|
|||
|
|
@ -6,21 +6,18 @@ import (
|
|||
"fmt"
|
||||
|
||||
"github.com/99designs/keyring"
|
||||
|
||||
"github.com/influxdata/telegraf/config"
|
||||
)
|
||||
|
||||
func (o *OS) createKeyringConfig() (keyring.Config, error) {
|
||||
passwd, err := o.Password.Get()
|
||||
if err != nil {
|
||||
return keyring.Config{}, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
defer config.ReleaseSecret(passwd)
|
||||
|
||||
// Create the prompt-function in case we need it
|
||||
promptFunc := keyring.TerminalPrompt
|
||||
if len(passwd) != 0 {
|
||||
promptFunc = keyring.FixedStringPrompt(string(passwd))
|
||||
if !o.Password.Empty() {
|
||||
passwd, err := o.Password.Get()
|
||||
if err != nil {
|
||||
return keyring.Config{}, fmt.Errorf("getting password failed: %w", err)
|
||||
}
|
||||
promptFunc = keyring.FixedStringPrompt(passwd.String())
|
||||
passwd.Destroy()
|
||||
}
|
||||
|
||||
return keyring.Config{
|
||||
|
|
|
|||
Loading…
Reference in New Issue