Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
18 changes: 11 additions & 7 deletions lib/utils/envutils/environment.go
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ package envutils
import (
"bufio"
"fmt"
"io"
"os"
"strings"

Expand All @@ -39,18 +40,22 @@ func ReadEnvironmentFile(filename string) ([]string, error) {
}
defer file.Close()

return readEnvironment(file)
}

func readEnvironment(r io.Reader) ([]string, error) {
var lineno int
env := &SafeEnv{}

scanner := bufio.NewScanner(file)
scanner := bufio.NewScanner(r)
for scanner.Scan() {
line := strings.TrimSpace(scanner.Text())

// follow the lead of OpenSSH and don't allow more than 1,000 environment variables
// https://github.com/openssh/openssh-portable/blob/master/session.c#L873-L874
lineno = lineno + 1
if lineno > teleport.MaxEnvironmentFileLines {
log.Warnf("Too many lines in environment file %v, returning first %v lines", filename, teleport.MaxEnvironmentFileLines)
log.Warnf("Too many lines in environment file, returning first %v lines", teleport.MaxEnvironmentFileLines)
return *env, nil
}

Expand All @@ -62,25 +67,24 @@ func ReadEnvironmentFile(filename string) ([]string, error) {
// split on first =, if not found, log it and continue
idx := strings.Index(line, "=")
if idx == -1 {
log.Debugf("Bad line %v while reading %v: no = separator found", lineno, filename)
log.Debugf("Bad line %v while reading environment file: no = separator found", lineno)
continue
}

// split key and value and make sure that key has a name
key := line[:idx]
value := line[idx+1:]
if strings.TrimSpace(key) == "" {
log.Debugf("Bad line %v while reading %v: key without name", lineno, filename)
log.Debugf("Bad line %v while reading environment file: key without name", lineno)
continue
}

// key is added trusted within this context, but should be "AddFullUnique" when combined with any other values
env.AddTrusted(key, value)
}

err = scanner.Err()
if err != nil {
log.Warnf("Unable to read environment file %v: %v, skipping", filename, err)
if err := scanner.Err(); err != nil {
log.Warnf("Unable to read environment file: %v", err)
return []string{}, nil
}

Expand Down
19 changes: 4 additions & 15 deletions lib/utils/envutils/environment_test.go
Original file line number Diff line number Diff line change
Expand Up @@ -16,14 +16,13 @@ limitations under the License.
package envutils

import (
"os"
"bytes"
"testing"

"github.com/google/go-cmp/cmp"
"github.com/stretchr/testify/require"
)

func TestReadEnvironmentFile(t *testing.T) {
func TestReadEnvironment(t *testing.T) {
t.Parallel()

// contents of environment file
Expand All @@ -40,21 +39,11 @@ bar=foo
LD_PRELOAD=attack
`)

// create a temp file with an environment in it
f, err := os.CreateTemp(t.TempDir(), "teleport-environment-")
require.NoError(t, err)
defer os.Remove(f.Name())
_, err = f.Write(rawenv)
require.NoError(t, err)
err = f.Close()
require.NoError(t, err)

// read in the temp file
env, err := ReadEnvironmentFile(f.Name())
env, err := readEnvironment(bytes.NewReader(rawenv))
require.NoError(t, err)

// check we parsed it correctly
require.Empty(t, cmp.Diff(env, []string{"foo=bar", "foo=bar=baz", "foo=", "bar=foo"}))
require.Equal(t, []string{"foo=bar", "foo=bar=baz", "foo=", "bar=foo"}, env)
}

func TestSafeEnvAdd(t *testing.T) {
Expand Down