Advertisement
Guest User

Untitled

a guest
Sep 19th, 2017
73
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
text 8.45 KB | None | 0 0
  1. diff --git a/agent/request.go b/agent/request.go
  2. index c539ca2..89648d2 100644
  3. --- a/agent/request.go
  4. +++ b/agent/request.go
  5. @@ -23,6 +23,9 @@ type Request struct {
  6. StorePlugin string `json:"store_plugin"`
  7. StoreEndpoint string `json:"store_endpoint"`
  8. RestoreKey string `json:"restore_key"`
  9. + EncryptionMode string `json:"encryption_mode"`
  10. + EncryptionKey string `json:"encryption_key"`
  11. + EncryptionIV string `json:"encryption_iv"`
  12. }
  13.  
  14. func ParseRequestValue(value []byte) (*Request, error) {
  15. @@ -97,6 +100,12 @@ func (req *Request) Run(output chan string) error {
  16.  
  17. log.Debugf("ENV: %s", strings.Join(cmd.Env, ","))
  18.  
  19. + // set potentially sensitive things
  20. + // FIXME this is not secure and needs to be ripped out before we merge
  21. + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_MODE=%s", req.EncryptionMode)
  22. + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_KEY=%x", req.EncryptionKey)
  23. + cmd.Env = append(cmd.Env, "SHIELD_ENCRYPTION_IV=%x", req.EncryptionIV)
  24. +
  25. stdout, err := cmd.StdoutPipe()
  26. if err != nil {
  27. return err
  28. diff --git a/crypter/crypter.go b/crypter/crypter.go
  29. new file mode 100644
  30. index 0000000..1b1ca5c
  31. --- /dev/null
  32. +++ b/crypter/crypter.go
  33. @@ -0,0 +1,66 @@
  34. +package crypter
  35. +
  36. +import (
  37. + "crypto/aes"
  38. + "crypto/cipher"
  39. + "crypto/rand"
  40. + "fmt"
  41. + "io"
  42. + "strings"
  43. +
  44. + "golang.org/x/crypto/blowfish"
  45. + "golang.org/x/crypto/twofish"
  46. +)
  47. +
  48. +func Stream(enctype string, key, iv []byte) (cipher.Stream, cipher.Stream, error) {
  49. + // cipher-mode combinations included so far are:
  50. + // aes-cfb, blowfish-cfb, twofish-cfb
  51. + if enctype == "" {
  52. + return nil, nil, fmt.Errorf("No encryption type specified")
  53. + }
  54. + if !strings.Contains(enctype, "-") {
  55. + return nil, nil, fmt.Errorf("Invalid encryption type '%s' specified", enctype)
  56. + }
  57. + cipherName := strings.Split(enctype, "-")[0]
  58. + mode := strings.Split(enctype, "-")[1]
  59. +
  60. + var err error
  61. + var block cipher.Block
  62. +
  63. + switch cipherName {
  64. + // Was originally going to specify aes128 or aes256, but the keysize determines
  65. + // which is used.
  66. + case "aes128", "aes256": // should we pull 128-bit? FIXME
  67. + block, err = aes.NewCipher(key)
  68. + case "blowfish": // not recommended by its author; pull it? FIXME
  69. + block, err = blowfish.NewCipher(key)
  70. + case "twofish":
  71. + block, err = twofish.NewCipher(key)
  72. + default:
  73. + return nil, nil, fmt.Errorf("Invalid cipher '%s' specified", cipherName)
  74. + }
  75. +
  76. + if err != nil {
  77. + return nil, nil, err
  78. + }
  79. +
  80. + switch mode {
  81. + case "cfb":
  82. + return cipher.NewCFBEncrypter(block, iv), cipher.NewCFBDecrypter(block, iv), nil
  83. + case "ofb":
  84. + return cipher.NewOFB(block, iv), cipher.NewOFB(block, iv), nil
  85. + case "ctr":
  86. + return cipher.NewCTR(block, iv), cipher.NewCTR(block, iv), nil
  87. + default:
  88. + return nil, nil, fmt.Errorf("Invalid encryption mode '%s' specified", cipherName)
  89. + }
  90. +}
  91. +
  92. +func Initialize() (string, string, error) {
  93. + //Generate the random IV
  94. + iv := make([]byte, twofish.BlockSize)
  95. + if _, err := io.ReadFull(rand.Reader, iv); err != nil {
  96. + return "", "", err
  97. + }
  98. + return "", "", nil
  99. +}
  100. diff --git a/crypter/vault.go b/crypter/vault.go
  101. new file mode 100644
  102. index 0000000..b7942c2
  103. --- /dev/null
  104. +++ b/crypter/vault.go
  105. @@ -0,0 +1,3 @@
  106. +package crypter
  107. +
  108. +
  109. diff --git a/db/schema.go b/db/schema.go
  110. index 95f12f6..fb6aa6a 100644
  111. --- a/db/schema.go
  112. +++ b/db/schema.go
  113. @@ -12,6 +12,7 @@ var Schemas = map[int]Schema{
  114. 1: v1Schema{},
  115. 2: v2Schema{},
  116. 3: v3Schema{},
  117. + 4: v4Schema{},
  118. }
  119.  
  120. type Schema interface {
  121. diff --git a/db/schema_v4.go b/db/schema_v4.go
  122. new file mode 100644
  123. index 0000000..893f34d
  124. --- /dev/null
  125. +++ b/db/schema_v4.go
  126. @@ -0,0 +1,14 @@
  127. +package db
  128. +
  129. +type v4Schema struct{}
  130. +
  131. +func (s v4Schema) Deploy(db *DB) error {
  132. + var err error
  133. +
  134. + err = db.Exec(`ALTER TABLE archives ADD COLUMN encryption_mode VARCHAR(50)`)
  135. + if err != nil {
  136. + return err
  137. + }
  138. +
  139. + return nil
  140. +}
  141. diff --git a/plugin/exec.go b/plugin/exec.go
  142. index 0107e3f..afa53a8 100644
  143. --- a/plugin/exec.go
  144. +++ b/plugin/exec.go
  145. @@ -1,11 +1,16 @@
  146. package plugin
  147.  
  148. import (
  149. + "encoding/hex"
  150. "fmt"
  151. - "github.com/mattn/go-shellwords"
  152. + "io"
  153. "os"
  154. "os/exec"
  155. "syscall"
  156. +
  157. + "crypto/cipher"
  158. + "github.com/mattn/go-shellwords"
  159. + "github.com/starkandwayne/shield/crypter"
  160. )
  161.  
  162. const NOPIPE = 0
  163. @@ -13,8 +18,8 @@ const STDIN = 1
  164. const STDOUT = 2
  165.  
  166. type ExecOptions struct {
  167. - Stdout *os.File
  168. - Stdin *os.File
  169. + Stdout io.Writer
  170. + Stdin io.Reader
  171. Stderr *os.File
  172. Cmd string
  173. ExpectRC []int
  174. @@ -27,15 +32,39 @@ func ExecWithOptions(opts ExecOptions) error {
  175. }
  176. DEBUG("Executing '%s' with arguments %v", cmdArgs[0], cmdArgs[1:])
  177.  
  178. + // some liberties will be taken here. hang on!
  179. + keyRaw, err := hex.DecodeString(os.Getenv("SHIELD_ENCRYPTION_KEY"))
  180. + if err != nil {
  181. + return err
  182. + }
  183. + ivRaw, err := hex.DecodeString(os.Getenv("SHIELD_ENCRYPTION_IV"))
  184. + if err != nil {
  185. + return err
  186. + }
  187. + // keyRaw := "\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD"
  188. + // ivRaw := "\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA"
  189. + // ivRaw = keyRaw
  190. +
  191. + encStream, decStream, err := crypter.Stream(os.Getenv("SHIELD_ENCRYPTION_TYPE"), keyRaw, ivRaw)
  192. + if err != nil {
  193. + return err
  194. + }
  195. cmd := exec.Command(cmdArgs[0], cmdArgs[1:]...)
  196. if opts.Stdout != nil {
  197. - cmd.Stdout = opts.Stdout
  198. + cmd.Stdout = cipher.StreamWriter{
  199. + S: encStream,
  200. + W: opts.Stdout,
  201. + }
  202. }
  203. if opts.Stderr != nil {
  204. cmd.Stderr = opts.Stderr
  205. }
  206. if opts.Stdin != nil {
  207. cmd.Stdin = opts.Stdin
  208. + cmd.Stdin = cipher.StreamReader{
  209. + S: decStream,
  210. + R: opts.Stdin,
  211. + }
  212. }
  213.  
  214. if len(opts.ExpectRC) == 0 {
  215. @@ -78,6 +107,5 @@ func Exec(cmdString string, flags int) error {
  216. if flags&STDIN == STDIN {
  217. opts.Stdin = os.Stdin
  218. }
  219. -
  220. return ExecWithOptions(opts)
  221. }
  222. diff --git a/plugin/exec_test.go b/plugin/exec_test.go
  223. index b9a3342..a46e4b3 100644
  224. --- a/plugin/exec_test.go
  225. +++ b/plugin/exec_test.go
  226. @@ -12,6 +12,11 @@ import (
  227. )
  228.  
  229. var _ = Describe("Plugin Commands", func() {
  230. + BeforeEach(func() {
  231. + os.Setenv("SHIELD_ENCRYPTION_KEY", "DEADBEEFDECAFBADDEADBEEFDECAFBAD")
  232. + os.Setenv("SHIELD_ENCRYPTION_IV", "DEADBEEFDECAFBADDEADBEEFDECAFBAD")
  233. + os.Setenv("SHIELD_ENCRYPTION_TYPE", "aes256-ctr")
  234. + })
  235.  
  236. drain := func(file *os.File, output chan string) {
  237. data, err := ioutil.ReadAll(file)
  238. diff --git a/run b/run
  239. new file mode 100755
  240. index 0000000..0d02a93
  241. --- /dev/null
  242. +++ b/run
  243. @@ -0,0 +1,54 @@
  244. +#!/bin/bash
  245. +set -u
  246. +
  247. +export LC_ALL=C
  248. +
  249. +export DEBUG=1
  250. +ENDPOINT='{"data":"i am secret information"}'
  251. +PLUGIN=dummy
  252. +
  253. +KEY=DEADBEEFDECAFBADDEADBEEFDECAFBAD
  254. +IV=${KEY}
  255. +
  256. +export SHIELD_ENCRYPTION_TYPE="aes256-ctr"
  257. +export SHIELD_ENCRYPTION_KEY="$KEY"
  258. +export SHIELD_ENCRYPTION_IV="$IV"
  259. +
  260. +#./$PLUGIN validate -e "${ENDPOINT}"
  261. +./$PLUGIN backup -e "${ENDPOINT}" > out.enc
  262. +
  263. +echo
  264. +echo "----------------------"
  265. +echo
  266. +
  267. +(echo "i am secret information" | \
  268. + openssl enc -aes-256-ctr -nosalt \
  269. + -nopad -K $KEY -iv $IV) > out.ssl
  270. +
  271. +echo "from out.ssl (via openssl):"
  272. +echo "----------------------"
  273. +openssl enc -aes-256-ctr -d -nosalt \
  274. + -nopad -K $KEY -iv $IV < out.ssl
  275. +echo "----------------------"
  276. +
  277. +echo
  278. +echo "from out.enc (via openssl):"
  279. +echo "----------------------"
  280. +openssl enc -aes-256-ctr -d -nosalt \
  281. + -nopad -K $KEY -iv $IV < out.enc | od -a
  282. +echo "----------------------"
  283. +
  284. +echo "SHA sum of out.*:"
  285. +echo "----------------------"
  286. +shasum out.*
  287. +echo "----------------------"
  288. +
  289. +echo
  290. +echo "restore op:"
  291. +echo "----------------------"
  292. +cat out.enc | ./$PLUGIN restore -e '{"file":"restored.out"}'
  293. +cat restored.out
  294. +echo "----------------------"
  295. +
  296. +echo "ALL DONE!"
  297. +exit 0
  298. diff --git a/supervisor/worker.go b/supervisor/worker.go
  299. index 76fc113..66af5a0 100644
  300. --- a/supervisor/worker.go
  301. +++ b/supervisor/worker.go
  302. @@ -40,6 +40,9 @@ type WorkerRequest struct {
  303. StorePlugin string `json:"store_plugin"`
  304. StoreEndpoint string `json:"store_endpoint"`
  305. RestoreKey string `json:"restore_key"`
  306. + EncryptionMode string `json:"encryption_mode"`
  307. + EncryptionKey string `json:"encryption_key"`
  308. + EncryptionIV string `json:"encryption_iv"`
  309. }
  310.  
  311. func worker(id uint, privateKeyFile string, work chan *db.Task, updates chan WorkerUpdate) {
  312. @@ -103,6 +106,9 @@ func worker(id uint, privateKeyFile string, work chan *db.Task, updates chan Wor
  313. StorePlugin: t.StorePlugin,
  314. StoreEndpoint: t.StoreEndpoint,
  315. RestoreKey: t.RestoreKey,
  316. + EncryptionMode: "aes256-ctr",
  317. + EncryptionKey: "\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD\xDE\xAD\xBE\xEF\xDE\xCA\xFB\xAD",
  318. + EncryptionIV: "\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA\xCA\xFE\xBA\xBE\xAB\xAD\x1D\xEA",
  319. })
  320. if err != nil {
  321. updates <- WorkerUpdate{Task: t.UUID, Op: OUTPUT,
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement