This repository has been archived by the owner on Jun 11, 2019. It is now read-only.
-
Notifications
You must be signed in to change notification settings - Fork 8
/
commands.go
99 lines (82 loc) · 2.83 KB
/
commands.go
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
package main
import (
"fmt"
"io"
"io/ioutil"
"os"
"path"
"regexp"
"strings"
)
const maxLineLength = 64
var shellIdentifierRegexp = regexp.MustCompile("^[A-Za-z_][A-Za-z0-9_]*$")
// Encrypts data from stdin and writes to stdout
func encryptCommand(input io.Reader, output io.Writer, crypto EncryptionStrategy, wrapLines bool) {
plaintext, err := ioutil.ReadAll(input)
check(err, "Failed to read plaintext data from standard input")
envelope, err := crypto.Encrypt(plaintext)
check(err)
if wrapLines {
for i := 0; i < len(envelope); i += maxLineLength {
output.Write([]byte(envelope[i:min(i+maxLineLength, len(envelope))]))
output.Write([]byte("\n"))
}
} else {
output.Write([]byte(envelope))
}
}
// Decrypts data from stdin and writes to stdout
func decryptStream(input io.Reader, output io.Writer, crypto DecryptionStrategy) {
payload, err := ioutil.ReadAll(input)
check(err, "Failed to read encrypted data from standard input")
result, err := decryptEnvelopes(string(payload), crypto)
check(err, "Failed to decrypt from standard input")
output.Write([]byte(result))
}
// Decrypts environment variables and writes them to stdout
func decryptEnvironment(input []string, output io.Writer, crypto DecryptionStrategy) (bool, error) {
ok := true
var err error
for _, item := range input {
keyval := strings.SplitN(item, "=", 2)
key, value := keyval[0], keyval[1]
result := value
decryptedResult, suberr := decryptEnvelopes(result, crypto)
if suberr != nil {
ok = false
err = suberr
fmt.Fprintf(os.Stderr, "%s: %s\n", key, err)
continue
}
if decryptedResult != result {
if !shellIdentifierRegexp.Match([]byte(key)) {
ok = false
err = fmt.Errorf("the env var '%s' is not a valid shell script identifier. Only alphanumeric characters and underscores are supported, starting with an alphabetic or underscore character", key)
fmt.Fprintf(os.Stderr, "%s: %s\n", key, err)
}
fmt.Fprintf(output, "export %s='%s'\n", key, decryptedResult)
}
}
return ok, err
}
func createExecArgs(args []string, encryptedEnviron []string, crypto DecryptionStrategy) (cmd string, decryptedArgs []string, decryptedEnviron []string, err error) {
cmd = args[0]
decryptedArgs = make([]string, len(args))
decryptedArgs[0] = path.Base(cmd) // By unix convention argv[0] has to be set to basename of command
for i, arg := range args[1:] {
decryptedArg, subErr := decryptEnvelopes(arg, crypto)
if subErr != nil {
err = fmt.Errorf("Error while decrypting argument: %v", subErr)
}
decryptedArgs[i+1] = decryptedArg
}
decryptedEnviron = make([]string, len(encryptedEnviron))
for i, env := range encryptedEnviron {
decryptedEnv, subErr := decryptEnvelopes(env, crypto)
if subErr != nil {
err = fmt.Errorf("Error while decrypting environment variables: %v", subErr)
}
decryptedEnviron[i] = decryptedEnv
}
return
}