cord-776 create build / runtime containers for autmation uservices

Change-Id: I246973192adef56a250ffe93a5f65fff488840c1
diff --git a/switchq/vendor/github.com/juju/utils/password.go b/switchq/vendor/github.com/juju/utils/password.go
new file mode 100644
index 0000000..914e8e4
--- /dev/null
+++ b/switchq/vendor/github.com/juju/utils/password.go
@@ -0,0 +1,92 @@
+// Copyright 2012, 2013 Canonical Ltd.
+// Licensed under the LGPLv3, see LICENCE file for details.
+
+package utils
+
+import (
+	"crypto/rand"
+	"crypto/sha512"
+	"encoding/base64"
+	"fmt"
+	"io"
+
+	"golang.org/x/crypto/pbkdf2"
+)
+
+// CompatSalt is because Juju 1.16 and older used a hard-coded salt to compute
+// the password hash for all users and agents
+var CompatSalt = string([]byte{0x75, 0x82, 0x81, 0xca})
+
+const randomPasswordBytes = 18
+
+// MinAgentPasswordLength describes how long agent passwords should be. We
+// require this length because we assume enough entropy in the Agent password
+// that it is safe to not do extra rounds of iterated hashing.
+var MinAgentPasswordLength = base64.StdEncoding.EncodedLen(randomPasswordBytes)
+
+// RandomBytes returns n random bytes.
+func RandomBytes(n int) ([]byte, error) {
+	buf := make([]byte, n)
+	_, err := io.ReadFull(rand.Reader, buf)
+	if err != nil {
+		return nil, fmt.Errorf("cannot read random bytes: %v", err)
+	}
+	return buf, nil
+}
+
+// RandomPassword generates a random base64-encoded password.
+func RandomPassword() (string, error) {
+	b, err := RandomBytes(randomPasswordBytes)
+	if err != nil {
+		return "", err
+	}
+	return base64.StdEncoding.EncodeToString(b), nil
+}
+
+// RandomSalt generates a random base64 data suitable for using as a password
+// salt The pbkdf2 guideline is to use 8 bytes of salt, so we do 12 raw bytes
+// into 16 base64 bytes. (The alternative is 6 raw into 8 base64).
+func RandomSalt() (string, error) {
+	b, err := RandomBytes(12)
+	if err != nil {
+		return "", err
+	}
+	return base64.StdEncoding.EncodeToString(b), nil
+}
+
+// FastInsecureHash specifies whether a fast, insecure version of the hash
+// algorithm will be used.  Changing this will cause PasswordHash to
+// produce incompatible passwords.  It should only be changed for
+// testing purposes - to make tests run faster.
+var FastInsecureHash = false
+
+// UserPasswordHash returns base64-encoded one-way hash password that is
+// computationally hard to crack by iterating through possible passwords.
+func UserPasswordHash(password string, salt string) string {
+	if salt == "" {
+		panic("salt is not allowed to be empty")
+	}
+	iter := 8192
+	if FastInsecureHash {
+		iter = 1
+	}
+	// Generate 18 byte passwords because we know that MongoDB
+	// uses the MD5 sum of the password anyway, so there's
+	// no point in using more bytes. (18 so we don't get base 64
+	// padding characters).
+	h := pbkdf2.Key([]byte(password), []byte(salt), iter, 18, sha512.New)
+	return base64.StdEncoding.EncodeToString(h)
+}
+
+// AgentPasswordHash returns base64-encoded one-way hash of password. This is
+// not suitable for User passwords because those will have limited entropy (see
+// UserPasswordHash). However, since we generate long random passwords for
+// agents, we can trust that there is sufficient entropy to prevent brute force
+// search. And using a faster hash allows us to restart the state machines and
+// have 1000s of agents log in in a reasonable amount of time.
+func AgentPasswordHash(password string) string {
+	sum := sha512.New()
+	sum.Write([]byte(password))
+	h := sum.Sum(nil)
+	return base64.StdEncoding.EncodeToString(h[:18])
+}