Merge branch 'master' of https://github.com/hashicorp/vault into vishalvault
This commit is contained in:
commit
27e66e175f
|
@ -1,4 +1,4 @@
|
|||
## 0.2.0 (unreleased)
|
||||
## 0.2.0 (July 13, 2015)
|
||||
|
||||
FEATURES:
|
||||
|
||||
|
@ -28,9 +28,12 @@ IMPROVEMENTS:
|
|||
All policy files must be updated for future writes. Adding the explicit glob
|
||||
character `*` to the path specification is all that is required.
|
||||
* core: policy merging to give deny highest precedence [GH-400]
|
||||
* credential/app-id: Protect against timing attack on app-id
|
||||
* credential/cert: Record the common name in the metadata [GH-342]
|
||||
* credential/ldap: Allow TLS verification to be disabled [GH-372]
|
||||
* credential/ldap: More flexible names allowed [GH-245] [GH-379] [GH-367]
|
||||
* credential/userpass: Protect against timing attack on password
|
||||
* credential/userpass: Use bcrypt for password matching
|
||||
* http: response codes improved to reflect error [GH-366]
|
||||
* http: the `sys/health` endpoint supports `?standbyok` to return 200 on standby [GH-389]
|
||||
* secret/app-id: Support deleting AppID and UserIDs [GH-200]
|
||||
|
@ -38,6 +41,7 @@ IMPROVEMENTS:
|
|||
* secret/transit: Decouple raw key from key management endpoint [GH-355]
|
||||
* secret/transit: Upsert named key when encrypt is used [GH-355]
|
||||
* storage/zk: Support for HA configuration [GH-252]
|
||||
* storage/zk: Changing node representation. **Backwards incompatible**. [GH-416]
|
||||
|
||||
BUG FIXES:
|
||||
|
||||
|
|
11
Godeps/Godeps.json
generated
11
Godeps/Godeps.json
generated
|
@ -1,6 +1,9 @@
|
|||
{
|
||||
"ImportPath": "github.com/hashicorp/vault",
|
||||
"GoVersion": "go1.4.2",
|
||||
"Packages": [
|
||||
"."
|
||||
],
|
||||
"Deps": [
|
||||
{
|
||||
"ImportPath": "github.com/armon/go-metrics",
|
||||
|
@ -185,6 +188,14 @@
|
|||
"ImportPath": "github.com/vaughan0/go-ini",
|
||||
"Rev": "a98ad7ee00ec53921f08832bc06ecf7fd600e6a1"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/bcrypt",
|
||||
"Rev": "cc04154d65fb9296747569b107cfd05380b1ea3e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/blowfish",
|
||||
"Rev": "cc04154d65fb9296747569b107cfd05380b1ea3e"
|
||||
},
|
||||
{
|
||||
"ImportPath": "golang.org/x/crypto/ssh/terminal",
|
||||
"Rev": "cc04154d65fb9296747569b107cfd05380b1ea3e"
|
||||
|
|
35
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go
generated
vendored
Normal file
35
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/base64.go
generated
vendored
Normal file
|
@ -0,0 +1,35 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bcrypt
|
||||
|
||||
import "encoding/base64"
|
||||
|
||||
const alphabet = "./ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789"
|
||||
|
||||
var bcEncoding = base64.NewEncoding(alphabet)
|
||||
|
||||
func base64Encode(src []byte) []byte {
|
||||
n := bcEncoding.EncodedLen(len(src))
|
||||
dst := make([]byte, n)
|
||||
bcEncoding.Encode(dst, src)
|
||||
for dst[n-1] == '=' {
|
||||
n--
|
||||
}
|
||||
return dst[:n]
|
||||
}
|
||||
|
||||
func base64Decode(src []byte) ([]byte, error) {
|
||||
numOfEquals := 4 - (len(src) % 4)
|
||||
for i := 0; i < numOfEquals; i++ {
|
||||
src = append(src, '=')
|
||||
}
|
||||
|
||||
dst := make([]byte, bcEncoding.DecodedLen(len(src)))
|
||||
n, err := bcEncoding.Decode(dst, src)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return dst[:n], nil
|
||||
}
|
294
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
294
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt.go
generated
vendored
Normal file
|
@ -0,0 +1,294 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package bcrypt implements Provos and Mazières's bcrypt adaptive hashing
|
||||
// algorithm. See http://www.usenix.org/event/usenix99/provos/provos.pdf
|
||||
package bcrypt // import "golang.org/x/crypto/bcrypt"
|
||||
|
||||
// The code is a port of Provos and Mazières's C implementation.
|
||||
import (
|
||||
"crypto/rand"
|
||||
"crypto/subtle"
|
||||
"errors"
|
||||
"fmt"
|
||||
"golang.org/x/crypto/blowfish"
|
||||
"io"
|
||||
"strconv"
|
||||
)
|
||||
|
||||
const (
|
||||
MinCost int = 4 // the minimum allowable cost as passed in to GenerateFromPassword
|
||||
MaxCost int = 31 // the maximum allowable cost as passed in to GenerateFromPassword
|
||||
DefaultCost int = 10 // the cost that will actually be set if a cost below MinCost is passed into GenerateFromPassword
|
||||
)
|
||||
|
||||
// The error returned from CompareHashAndPassword when a password and hash do
|
||||
// not match.
|
||||
var ErrMismatchedHashAndPassword = errors.New("crypto/bcrypt: hashedPassword is not the hash of the given password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash is too short to
|
||||
// be a bcrypt hash.
|
||||
var ErrHashTooShort = errors.New("crypto/bcrypt: hashedSecret too short to be a bcrypted password")
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash was created with
|
||||
// a bcrypt algorithm newer than this implementation.
|
||||
type HashVersionTooNewError byte
|
||||
|
||||
func (hv HashVersionTooNewError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt algorithm version '%c' requested is newer than current version '%c'", byte(hv), majorVersion)
|
||||
}
|
||||
|
||||
// The error returned from CompareHashAndPassword when a hash starts with something other than '$'
|
||||
type InvalidHashPrefixError byte
|
||||
|
||||
func (ih InvalidHashPrefixError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: bcrypt hashes must start with '$', but hashedSecret started with '%c'", byte(ih))
|
||||
}
|
||||
|
||||
type InvalidCostError int
|
||||
|
||||
func (ic InvalidCostError) Error() string {
|
||||
return fmt.Sprintf("crypto/bcrypt: cost %d is outside allowed range (%d,%d)", int(ic), int(MinCost), int(MaxCost))
|
||||
}
|
||||
|
||||
const (
|
||||
majorVersion = '2'
|
||||
minorVersion = 'a'
|
||||
maxSaltSize = 16
|
||||
maxCryptedHashSize = 23
|
||||
encodedSaltSize = 22
|
||||
encodedHashSize = 31
|
||||
minHashSize = 59
|
||||
)
|
||||
|
||||
// magicCipherData is an IV for the 64 Blowfish encryption calls in
|
||||
// bcrypt(). It's the string "OrpheanBeholderScryDoubt" in big-endian bytes.
|
||||
var magicCipherData = []byte{
|
||||
0x4f, 0x72, 0x70, 0x68,
|
||||
0x65, 0x61, 0x6e, 0x42,
|
||||
0x65, 0x68, 0x6f, 0x6c,
|
||||
0x64, 0x65, 0x72, 0x53,
|
||||
0x63, 0x72, 0x79, 0x44,
|
||||
0x6f, 0x75, 0x62, 0x74,
|
||||
}
|
||||
|
||||
type hashed struct {
|
||||
hash []byte
|
||||
salt []byte
|
||||
cost int // allowed range is MinCost to MaxCost
|
||||
major byte
|
||||
minor byte
|
||||
}
|
||||
|
||||
// GenerateFromPassword returns the bcrypt hash of the password at the given
|
||||
// cost. If the cost given is less than MinCost, the cost will be set to
|
||||
// DefaultCost, instead. Use CompareHashAndPassword, as defined in this package,
|
||||
// to compare the returned hashed password with its cleartext version.
|
||||
func GenerateFromPassword(password []byte, cost int) ([]byte, error) {
|
||||
p, err := newFromPassword(password, cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
return p.Hash(), nil
|
||||
}
|
||||
|
||||
// CompareHashAndPassword compares a bcrypt hashed password with its possible
|
||||
// plaintext equivalent. Returns nil on success, or an error on failure.
|
||||
func CompareHashAndPassword(hashedPassword, password []byte) error {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherHash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
otherP := &hashed{otherHash, p.salt, p.cost, p.major, p.minor}
|
||||
if subtle.ConstantTimeCompare(p.Hash(), otherP.Hash()) == 1 {
|
||||
return nil
|
||||
}
|
||||
|
||||
return ErrMismatchedHashAndPassword
|
||||
}
|
||||
|
||||
// Cost returns the hashing cost used to create the given hashed
|
||||
// password. When, in the future, the hashing cost of a password system needs
|
||||
// to be increased in order to adjust for greater computational power, this
|
||||
// function allows one to establish which passwords need to be updated.
|
||||
func Cost(hashedPassword []byte) (int, error) {
|
||||
p, err := newFromHash(hashedPassword)
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
return p.cost, nil
|
||||
}
|
||||
|
||||
func newFromPassword(password []byte, cost int) (*hashed, error) {
|
||||
if cost < MinCost {
|
||||
cost = DefaultCost
|
||||
}
|
||||
p := new(hashed)
|
||||
p.major = majorVersion
|
||||
p.minor = minorVersion
|
||||
|
||||
err := checkCost(cost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.cost = cost
|
||||
|
||||
unencodedSalt := make([]byte, maxSaltSize)
|
||||
_, err = io.ReadFull(rand.Reader, unencodedSalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
p.salt = base64Encode(unencodedSalt)
|
||||
hash, err := bcrypt(password, p.cost, p.salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
p.hash = hash
|
||||
return p, err
|
||||
}
|
||||
|
||||
func newFromHash(hashedSecret []byte) (*hashed, error) {
|
||||
if len(hashedSecret) < minHashSize {
|
||||
return nil, ErrHashTooShort
|
||||
}
|
||||
p := new(hashed)
|
||||
n, err := p.decodeVersion(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
n, err = p.decodeCost(hashedSecret)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
hashedSecret = hashedSecret[n:]
|
||||
|
||||
// The "+2" is here because we'll have to append at most 2 '=' to the salt
|
||||
// when base64 decoding it in expensiveBlowfishSetup().
|
||||
p.salt = make([]byte, encodedSaltSize, encodedSaltSize+2)
|
||||
copy(p.salt, hashedSecret[:encodedSaltSize])
|
||||
|
||||
hashedSecret = hashedSecret[encodedSaltSize:]
|
||||
p.hash = make([]byte, len(hashedSecret))
|
||||
copy(p.hash, hashedSecret)
|
||||
|
||||
return p, nil
|
||||
}
|
||||
|
||||
func bcrypt(password []byte, cost int, salt []byte) ([]byte, error) {
|
||||
cipherData := make([]byte, len(magicCipherData))
|
||||
copy(cipherData, magicCipherData)
|
||||
|
||||
c, err := expensiveBlowfishSetup(password, uint32(cost), salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
for i := 0; i < 24; i += 8 {
|
||||
for j := 0; j < 64; j++ {
|
||||
c.Encrypt(cipherData[i:i+8], cipherData[i:i+8])
|
||||
}
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. We only encode 23 of
|
||||
// the 24 bytes encrypted.
|
||||
hsh := base64Encode(cipherData[:maxCryptedHashSize])
|
||||
return hsh, nil
|
||||
}
|
||||
|
||||
func expensiveBlowfishSetup(key []byte, cost uint32, salt []byte) (*blowfish.Cipher, error) {
|
||||
|
||||
csalt, err := base64Decode(salt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Bug compatibility with C bcrypt implementations. They use the trailing
|
||||
// NULL in the key string during expansion.
|
||||
ckey := append(key, 0)
|
||||
|
||||
c, err := blowfish.NewSaltedCipher(ckey, csalt)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
var i, rounds uint64
|
||||
rounds = 1 << cost
|
||||
for i = 0; i < rounds; i++ {
|
||||
blowfish.ExpandKey(ckey, c)
|
||||
blowfish.ExpandKey(csalt, c)
|
||||
}
|
||||
|
||||
return c, nil
|
||||
}
|
||||
|
||||
func (p *hashed) Hash() []byte {
|
||||
arr := make([]byte, 60)
|
||||
arr[0] = '$'
|
||||
arr[1] = p.major
|
||||
n := 2
|
||||
if p.minor != 0 {
|
||||
arr[2] = p.minor
|
||||
n = 3
|
||||
}
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], []byte(fmt.Sprintf("%02d", p.cost)))
|
||||
n += 2
|
||||
arr[n] = '$'
|
||||
n += 1
|
||||
copy(arr[n:], p.salt)
|
||||
n += encodedSaltSize
|
||||
copy(arr[n:], p.hash)
|
||||
n += encodedHashSize
|
||||
return arr[:n]
|
||||
}
|
||||
|
||||
func (p *hashed) decodeVersion(sbytes []byte) (int, error) {
|
||||
if sbytes[0] != '$' {
|
||||
return -1, InvalidHashPrefixError(sbytes[0])
|
||||
}
|
||||
if sbytes[1] > majorVersion {
|
||||
return -1, HashVersionTooNewError(sbytes[1])
|
||||
}
|
||||
p.major = sbytes[1]
|
||||
n := 3
|
||||
if sbytes[2] != '$' {
|
||||
p.minor = sbytes[2]
|
||||
n++
|
||||
}
|
||||
return n, nil
|
||||
}
|
||||
|
||||
// sbytes should begin where decodeVersion left off.
|
||||
func (p *hashed) decodeCost(sbytes []byte) (int, error) {
|
||||
cost, err := strconv.Atoi(string(sbytes[0:2]))
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
err = checkCost(cost)
|
||||
if err != nil {
|
||||
return -1, err
|
||||
}
|
||||
p.cost = cost
|
||||
return 3, nil
|
||||
}
|
||||
|
||||
func (p *hashed) String() string {
|
||||
return fmt.Sprintf("&{hash: %#v, salt: %#v, cost: %d, major: %c, minor: %c}", string(p.hash), p.salt, p.cost, p.major, p.minor)
|
||||
}
|
||||
|
||||
func checkCost(cost int) error {
|
||||
if cost < MinCost || cost > MaxCost {
|
||||
return InvalidCostError(cost)
|
||||
}
|
||||
return nil
|
||||
}
|
226
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt_test.go
generated
vendored
Normal file
226
Godeps/_workspace/src/golang.org/x/crypto/bcrypt/bcrypt_test.go
generated
vendored
Normal file
|
@ -0,0 +1,226 @@
|
|||
// Copyright 2011 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package bcrypt
|
||||
|
||||
import (
|
||||
"bytes"
|
||||
"fmt"
|
||||
"testing"
|
||||
)
|
||||
|
||||
func TestBcryptingIsEasy(t *testing.T) {
|
||||
pass := []byte("mypassword")
|
||||
hp, err := GenerateFromPassword(pass, 0)
|
||||
if err != nil {
|
||||
t.Fatalf("GenerateFromPassword error: %s", err)
|
||||
}
|
||||
|
||||
if CompareHashAndPassword(hp, pass) != nil {
|
||||
t.Errorf("%v should hash %s correctly", hp, pass)
|
||||
}
|
||||
|
||||
notPass := "notthepass"
|
||||
err = CompareHashAndPassword(hp, []byte(notPass))
|
||||
if err != ErrMismatchedHashAndPassword {
|
||||
t.Errorf("%v and %s should be mismatched", hp, notPass)
|
||||
}
|
||||
}
|
||||
|
||||
func TestBcryptingIsCorrect(t *testing.T) {
|
||||
pass := []byte("allmine")
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
expectedHash := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
|
||||
|
||||
hash, err := bcrypt(pass, 10, salt)
|
||||
if err != nil {
|
||||
t.Fatalf("bcrypt blew up: %v", err)
|
||||
}
|
||||
if !bytes.HasSuffix(expectedHash, hash) {
|
||||
t.Errorf("%v should be the suffix of %v", hash, expectedHash)
|
||||
}
|
||||
|
||||
h, err := newFromHash(expectedHash)
|
||||
if err != nil {
|
||||
t.Errorf("Unable to parse %s: %v", string(expectedHash), err)
|
||||
}
|
||||
|
||||
// This is not the safe way to compare these hashes. We do this only for
|
||||
// testing clarity. Use bcrypt.CompareHashAndPassword()
|
||||
if err == nil && !bytes.Equal(expectedHash, h.Hash()) {
|
||||
t.Errorf("Parsed hash %v should equal %v", h.Hash(), expectedHash)
|
||||
}
|
||||
}
|
||||
|
||||
func TestVeryShortPasswords(t *testing.T) {
|
||||
key := []byte("k")
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
_, err := bcrypt(key, 10, salt)
|
||||
if err != nil {
|
||||
t.Errorf("One byte key resulted in error: %s", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestTooLongPasswordsWork(t *testing.T) {
|
||||
salt := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
// One byte over the usual 56 byte limit that blowfish has
|
||||
tooLongPass := []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
tooLongExpected := []byte("$2a$10$XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C")
|
||||
hash, err := bcrypt(tooLongPass, 10, salt)
|
||||
if err != nil {
|
||||
t.Fatalf("bcrypt blew up on long password: %v", err)
|
||||
}
|
||||
if !bytes.HasSuffix(tooLongExpected, hash) {
|
||||
t.Errorf("%v should be the suffix of %v", hash, tooLongExpected)
|
||||
}
|
||||
}
|
||||
|
||||
type InvalidHashTest struct {
|
||||
err error
|
||||
hash []byte
|
||||
}
|
||||
|
||||
var invalidTests = []InvalidHashTest{
|
||||
{ErrHashTooShort, []byte("$2a$10$fooo")},
|
||||
{ErrHashTooShort, []byte("$2a")},
|
||||
{HashVersionTooNewError('3'), []byte("$3a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
{InvalidHashPrefixError('%'), []byte("%2a$10$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
{InvalidCostError(32), []byte("$2a$32$sssssssssssssssssssssshhhhhhhhhhhhhhhhhhhhhhhhhhhhhhh")},
|
||||
}
|
||||
|
||||
func TestInvalidHashErrors(t *testing.T) {
|
||||
check := func(name string, expected, err error) {
|
||||
if err == nil {
|
||||
t.Errorf("%s: Should have returned an error", name)
|
||||
}
|
||||
if err != nil && err != expected {
|
||||
t.Errorf("%s gave err %v but should have given %v", name, err, expected)
|
||||
}
|
||||
}
|
||||
for _, iht := range invalidTests {
|
||||
_, err := newFromHash(iht.hash)
|
||||
check("newFromHash", iht.err, err)
|
||||
err = CompareHashAndPassword(iht.hash, []byte("anything"))
|
||||
check("CompareHashAndPassword", iht.err, err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestUnpaddedBase64Encoding(t *testing.T) {
|
||||
original := []byte{101, 201, 101, 75, 19, 227, 199, 20, 239, 236, 133, 32, 30, 109, 243, 30}
|
||||
encodedOriginal := []byte("XajjQvNhvvRt5GSeFk1xFe")
|
||||
|
||||
encoded := base64Encode(original)
|
||||
|
||||
if !bytes.Equal(encodedOriginal, encoded) {
|
||||
t.Errorf("Encoded %v should have equaled %v", encoded, encodedOriginal)
|
||||
}
|
||||
|
||||
decoded, err := base64Decode(encodedOriginal)
|
||||
if err != nil {
|
||||
t.Fatalf("base64Decode blew up: %s", err)
|
||||
}
|
||||
|
||||
if !bytes.Equal(decoded, original) {
|
||||
t.Errorf("Decoded %v should have equaled %v", decoded, original)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCost(t *testing.T) {
|
||||
suffix := "XajjQvNhvvRt5GSeFk1xFe5l47dONXg781AmZtd869sO8zfsHuw7C"
|
||||
for _, vers := range []string{"2a", "2"} {
|
||||
for _, cost := range []int{4, 10} {
|
||||
s := fmt.Sprintf("$%s$%02d$%s", vers, cost, suffix)
|
||||
h := []byte(s)
|
||||
actual, err := Cost(h)
|
||||
if err != nil {
|
||||
t.Errorf("Cost, error: %s", err)
|
||||
continue
|
||||
}
|
||||
if actual != cost {
|
||||
t.Errorf("Cost, expected: %d, actual: %d", cost, actual)
|
||||
}
|
||||
}
|
||||
}
|
||||
_, err := Cost([]byte("$a$a$" + suffix))
|
||||
if err == nil {
|
||||
t.Errorf("Cost, malformed but no error returned")
|
||||
}
|
||||
}
|
||||
|
||||
func TestCostValidationInHash(t *testing.T) {
|
||||
if testing.Short() {
|
||||
return
|
||||
}
|
||||
|
||||
pass := []byte("mypassword")
|
||||
|
||||
for c := 0; c < MinCost; c++ {
|
||||
p, _ := newFromPassword(pass, c)
|
||||
if p.cost != DefaultCost {
|
||||
t.Errorf("newFromPassword should default costs below %d to %d, but was %d", MinCost, DefaultCost, p.cost)
|
||||
}
|
||||
}
|
||||
|
||||
p, _ := newFromPassword(pass, 14)
|
||||
if p.cost != 14 {
|
||||
t.Errorf("newFromPassword should default cost to 14, but was %d", p.cost)
|
||||
}
|
||||
|
||||
hp, _ := newFromHash(p.Hash())
|
||||
if p.cost != hp.cost {
|
||||
t.Errorf("newFromHash should maintain the cost at %d, but was %d", p.cost, hp.cost)
|
||||
}
|
||||
|
||||
_, err := newFromPassword(pass, 32)
|
||||
if err == nil {
|
||||
t.Fatalf("newFromPassword: should return a cost error")
|
||||
}
|
||||
if err != InvalidCostError(32) {
|
||||
t.Errorf("newFromPassword: should return cost error, got %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
func TestCostReturnsWithLeadingZeroes(t *testing.T) {
|
||||
hp, _ := newFromPassword([]byte("abcdefgh"), 7)
|
||||
cost := hp.Hash()[4:7]
|
||||
expected := []byte("07$")
|
||||
|
||||
if !bytes.Equal(expected, cost) {
|
||||
t.Errorf("single digit costs in hash should have leading zeros: was %v instead of %v", cost, expected)
|
||||
}
|
||||
}
|
||||
|
||||
func TestMinorNotRequired(t *testing.T) {
|
||||
noMinorHash := []byte("$2$10$XajjQvNhvvRt5GSeFk1xFeyqRrsxkhBkUiQeg0dt.wU1qD4aFDcga")
|
||||
h, err := newFromHash(noMinorHash)
|
||||
if err != nil {
|
||||
t.Fatalf("No minor hash blew up: %s", err)
|
||||
}
|
||||
if h.minor != 0 {
|
||||
t.Errorf("Should leave minor version at 0, but was %d", h.minor)
|
||||
}
|
||||
|
||||
if !bytes.Equal(noMinorHash, h.Hash()) {
|
||||
t.Errorf("Should generate hash %v, but created %v", noMinorHash, h.Hash())
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkEqual(b *testing.B) {
|
||||
b.StopTimer()
|
||||
passwd := []byte("somepasswordyoulike")
|
||||
hash, _ := GenerateFromPassword(passwd, 10)
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
CompareHashAndPassword(hash, passwd)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkGeneration(b *testing.B) {
|
||||
b.StopTimer()
|
||||
passwd := []byte("mylongpassword1234")
|
||||
b.StartTimer()
|
||||
for i := 0; i < b.N; i++ {
|
||||
GenerateFromPassword(passwd, 10)
|
||||
}
|
||||
}
|
159
Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go
generated
vendored
Normal file
159
Godeps/_workspace/src/golang.org/x/crypto/blowfish/block.go
generated
vendored
Normal file
|
@ -0,0 +1,159 @@
|
|||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package blowfish
|
||||
|
||||
// getNextWord returns the next big-endian uint32 value from the byte slice
|
||||
// at the given position in a circular manner, updating the position.
|
||||
func getNextWord(b []byte, pos *int) uint32 {
|
||||
var w uint32
|
||||
j := *pos
|
||||
for i := 0; i < 4; i++ {
|
||||
w = w<<8 | uint32(b[j])
|
||||
j++
|
||||
if j >= len(b) {
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
*pos = j
|
||||
return w
|
||||
}
|
||||
|
||||
// ExpandKey performs a key expansion on the given *Cipher. Specifically, it
|
||||
// performs the Blowfish algorithm's key schedule which sets up the *Cipher's
|
||||
// pi and substitution tables for calls to Encrypt. This is used, primarily,
|
||||
// by the bcrypt package to reuse the Blowfish key schedule during its
|
||||
// set up. It's unlikely that you need to use this directly.
|
||||
func ExpandKey(key []byte, c *Cipher) {
|
||||
j := 0
|
||||
for i := 0; i < 18; i++ {
|
||||
// Using inlined getNextWord for performance.
|
||||
var d uint32
|
||||
for k := 0; k < 4; k++ {
|
||||
d = d<<8 | uint32(key[j])
|
||||
j++
|
||||
if j >= len(key) {
|
||||
j = 0
|
||||
}
|
||||
}
|
||||
c.p[i] ^= d
|
||||
}
|
||||
|
||||
var l, r uint32
|
||||
for i := 0; i < 18; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.p[i], c.p[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s0[i], c.s0[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s1[i], c.s1[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s2[i], c.s2[i+1] = l, r
|
||||
}
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s3[i], c.s3[i+1] = l, r
|
||||
}
|
||||
}
|
||||
|
||||
// This is similar to ExpandKey, but folds the salt during the key
|
||||
// schedule. While ExpandKey is essentially expandKeyWithSalt with an all-zero
|
||||
// salt passed in, reusing ExpandKey turns out to be a place of inefficiency
|
||||
// and specializing it here is useful.
|
||||
func expandKeyWithSalt(key []byte, salt []byte, c *Cipher) {
|
||||
j := 0
|
||||
for i := 0; i < 18; i++ {
|
||||
c.p[i] ^= getNextWord(key, &j)
|
||||
}
|
||||
|
||||
j = 0
|
||||
var l, r uint32
|
||||
for i := 0; i < 18; i += 2 {
|
||||
l ^= getNextWord(salt, &j)
|
||||
r ^= getNextWord(salt, &j)
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.p[i], c.p[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l ^= getNextWord(salt, &j)
|
||||
r ^= getNextWord(salt, &j)
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s0[i], c.s0[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l ^= getNextWord(salt, &j)
|
||||
r ^= getNextWord(salt, &j)
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s1[i], c.s1[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l ^= getNextWord(salt, &j)
|
||||
r ^= getNextWord(salt, &j)
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s2[i], c.s2[i+1] = l, r
|
||||
}
|
||||
|
||||
for i := 0; i < 256; i += 2 {
|
||||
l ^= getNextWord(salt, &j)
|
||||
r ^= getNextWord(salt, &j)
|
||||
l, r = encryptBlock(l, r, c)
|
||||
c.s3[i], c.s3[i+1] = l, r
|
||||
}
|
||||
}
|
||||
|
||||
func encryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||
xl, xr := l, r
|
||||
xl ^= c.p[0]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[1]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[2]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[3]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[4]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[5]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[6]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[7]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[8]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[9]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[10]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[11]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[12]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[13]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[14]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[15]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[16]
|
||||
xr ^= c.p[17]
|
||||
return xr, xl
|
||||
}
|
||||
|
||||
func decryptBlock(l, r uint32, c *Cipher) (uint32, uint32) {
|
||||
xl, xr := l, r
|
||||
xl ^= c.p[17]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[16]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[15]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[14]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[13]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[12]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[11]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[10]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[9]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[8]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[7]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[6]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[5]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[4]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[3]
|
||||
xr ^= ((c.s0[byte(xl>>24)] + c.s1[byte(xl>>16)]) ^ c.s2[byte(xl>>8)]) + c.s3[byte(xl)] ^ c.p[2]
|
||||
xl ^= ((c.s0[byte(xr>>24)] + c.s1[byte(xr>>16)]) ^ c.s2[byte(xr>>8)]) + c.s3[byte(xr)] ^ c.p[1]
|
||||
xr ^= c.p[0]
|
||||
return xr, xl
|
||||
}
|
274
Godeps/_workspace/src/golang.org/x/crypto/blowfish/blowfish_test.go
generated
vendored
Normal file
274
Godeps/_workspace/src/golang.org/x/crypto/blowfish/blowfish_test.go
generated
vendored
Normal file
|
@ -0,0 +1,274 @@
|
|||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
package blowfish
|
||||
|
||||
import "testing"
|
||||
|
||||
type CryptTest struct {
|
||||
key []byte
|
||||
in []byte
|
||||
out []byte
|
||||
}
|
||||
|
||||
// Test vector values are from http://www.schneier.com/code/vectors.txt.
|
||||
var encryptTests = []CryptTest{
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}},
|
||||
{
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x51, 0x86, 0x6F, 0xD5, 0xB8, 0x5E, 0xCB, 0x8A}},
|
||||
{
|
||||
[]byte{0x30, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x10, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x01},
|
||||
[]byte{0x7D, 0x85, 0x6F, 0x9A, 0x61, 0x30, 0x63, 0xF2}},
|
||||
{
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x24, 0x66, 0xDD, 0x87, 0x8B, 0x96, 0x3C, 0x9D}},
|
||||
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x61, 0xF9, 0xC3, 0x80, 0x22, 0x81, 0xB0, 0x96}},
|
||||
{
|
||||
[]byte{0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11, 0x11},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x7D, 0x0C, 0xC6, 0x30, 0xAF, 0xDA, 0x1E, 0xC7}},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x4E, 0xF9, 0x97, 0x45, 0x61, 0x98, 0xDD, 0x78}},
|
||||
{
|
||||
[]byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x0A, 0xCE, 0xAB, 0x0F, 0xC6, 0xA0, 0xA2, 0x8D}},
|
||||
{
|
||||
[]byte{0x7C, 0xA1, 0x10, 0x45, 0x4A, 0x1A, 0x6E, 0x57},
|
||||
[]byte{0x01, 0xA1, 0xD6, 0xD0, 0x39, 0x77, 0x67, 0x42},
|
||||
[]byte{0x59, 0xC6, 0x82, 0x45, 0xEB, 0x05, 0x28, 0x2B}},
|
||||
{
|
||||
[]byte{0x01, 0x31, 0xD9, 0x61, 0x9D, 0xC1, 0x37, 0x6E},
|
||||
[]byte{0x5C, 0xD5, 0x4C, 0xA8, 0x3D, 0xEF, 0x57, 0xDA},
|
||||
[]byte{0xB1, 0xB8, 0xCC, 0x0B, 0x25, 0x0F, 0x09, 0xA0}},
|
||||
{
|
||||
[]byte{0x07, 0xA1, 0x13, 0x3E, 0x4A, 0x0B, 0x26, 0x86},
|
||||
[]byte{0x02, 0x48, 0xD4, 0x38, 0x06, 0xF6, 0x71, 0x72},
|
||||
[]byte{0x17, 0x30, 0xE5, 0x77, 0x8B, 0xEA, 0x1D, 0xA4}},
|
||||
{
|
||||
[]byte{0x38, 0x49, 0x67, 0x4C, 0x26, 0x02, 0x31, 0x9E},
|
||||
[]byte{0x51, 0x45, 0x4B, 0x58, 0x2D, 0xDF, 0x44, 0x0A},
|
||||
[]byte{0xA2, 0x5E, 0x78, 0x56, 0xCF, 0x26, 0x51, 0xEB}},
|
||||
{
|
||||
[]byte{0x04, 0xB9, 0x15, 0xBA, 0x43, 0xFE, 0xB5, 0xB6},
|
||||
[]byte{0x42, 0xFD, 0x44, 0x30, 0x59, 0x57, 0x7F, 0xA2},
|
||||
[]byte{0x35, 0x38, 0x82, 0xB1, 0x09, 0xCE, 0x8F, 0x1A}},
|
||||
{
|
||||
[]byte{0x01, 0x13, 0xB9, 0x70, 0xFD, 0x34, 0xF2, 0xCE},
|
||||
[]byte{0x05, 0x9B, 0x5E, 0x08, 0x51, 0xCF, 0x14, 0x3A},
|
||||
[]byte{0x48, 0xF4, 0xD0, 0x88, 0x4C, 0x37, 0x99, 0x18}},
|
||||
{
|
||||
[]byte{0x01, 0x70, 0xF1, 0x75, 0x46, 0x8F, 0xB5, 0xE6},
|
||||
[]byte{0x07, 0x56, 0xD8, 0xE0, 0x77, 0x47, 0x61, 0xD2},
|
||||
[]byte{0x43, 0x21, 0x93, 0xB7, 0x89, 0x51, 0xFC, 0x98}},
|
||||
{
|
||||
[]byte{0x43, 0x29, 0x7F, 0xAD, 0x38, 0xE3, 0x73, 0xFE},
|
||||
[]byte{0x76, 0x25, 0x14, 0xB8, 0x29, 0xBF, 0x48, 0x6A},
|
||||
[]byte{0x13, 0xF0, 0x41, 0x54, 0xD6, 0x9D, 0x1A, 0xE5}},
|
||||
{
|
||||
[]byte{0x07, 0xA7, 0x13, 0x70, 0x45, 0xDA, 0x2A, 0x16},
|
||||
[]byte{0x3B, 0xDD, 0x11, 0x90, 0x49, 0x37, 0x28, 0x02},
|
||||
[]byte{0x2E, 0xED, 0xDA, 0x93, 0xFF, 0xD3, 0x9C, 0x79}},
|
||||
{
|
||||
[]byte{0x04, 0x68, 0x91, 0x04, 0xC2, 0xFD, 0x3B, 0x2F},
|
||||
[]byte{0x26, 0x95, 0x5F, 0x68, 0x35, 0xAF, 0x60, 0x9A},
|
||||
[]byte{0xD8, 0x87, 0xE0, 0x39, 0x3C, 0x2D, 0xA6, 0xE3}},
|
||||
{
|
||||
[]byte{0x37, 0xD0, 0x6B, 0xB5, 0x16, 0xCB, 0x75, 0x46},
|
||||
[]byte{0x16, 0x4D, 0x5E, 0x40, 0x4F, 0x27, 0x52, 0x32},
|
||||
[]byte{0x5F, 0x99, 0xD0, 0x4F, 0x5B, 0x16, 0x39, 0x69}},
|
||||
{
|
||||
[]byte{0x1F, 0x08, 0x26, 0x0D, 0x1A, 0xC2, 0x46, 0x5E},
|
||||
[]byte{0x6B, 0x05, 0x6E, 0x18, 0x75, 0x9F, 0x5C, 0xCA},
|
||||
[]byte{0x4A, 0x05, 0x7A, 0x3B, 0x24, 0xD3, 0x97, 0x7B}},
|
||||
{
|
||||
[]byte{0x58, 0x40, 0x23, 0x64, 0x1A, 0xBA, 0x61, 0x76},
|
||||
[]byte{0x00, 0x4B, 0xD6, 0xEF, 0x09, 0x17, 0x60, 0x62},
|
||||
[]byte{0x45, 0x20, 0x31, 0xC1, 0xE4, 0xFA, 0xDA, 0x8E}},
|
||||
{
|
||||
[]byte{0x02, 0x58, 0x16, 0x16, 0x46, 0x29, 0xB0, 0x07},
|
||||
[]byte{0x48, 0x0D, 0x39, 0x00, 0x6E, 0xE7, 0x62, 0xF2},
|
||||
[]byte{0x75, 0x55, 0xAE, 0x39, 0xF5, 0x9B, 0x87, 0xBD}},
|
||||
{
|
||||
[]byte{0x49, 0x79, 0x3E, 0xBC, 0x79, 0xB3, 0x25, 0x8F},
|
||||
[]byte{0x43, 0x75, 0x40, 0xC8, 0x69, 0x8F, 0x3C, 0xFA},
|
||||
[]byte{0x53, 0xC5, 0x5F, 0x9C, 0xB4, 0x9F, 0xC0, 0x19}},
|
||||
{
|
||||
[]byte{0x4F, 0xB0, 0x5E, 0x15, 0x15, 0xAB, 0x73, 0xA7},
|
||||
[]byte{0x07, 0x2D, 0x43, 0xA0, 0x77, 0x07, 0x52, 0x92},
|
||||
[]byte{0x7A, 0x8E, 0x7B, 0xFA, 0x93, 0x7E, 0x89, 0xA3}},
|
||||
{
|
||||
[]byte{0x49, 0xE9, 0x5D, 0x6D, 0x4C, 0xA2, 0x29, 0xBF},
|
||||
[]byte{0x02, 0xFE, 0x55, 0x77, 0x81, 0x17, 0xF1, 0x2A},
|
||||
[]byte{0xCF, 0x9C, 0x5D, 0x7A, 0x49, 0x86, 0xAD, 0xB5}},
|
||||
{
|
||||
[]byte{0x01, 0x83, 0x10, 0xDC, 0x40, 0x9B, 0x26, 0xD6},
|
||||
[]byte{0x1D, 0x9D, 0x5C, 0x50, 0x18, 0xF7, 0x28, 0xC2},
|
||||
[]byte{0xD1, 0xAB, 0xB2, 0x90, 0x65, 0x8B, 0xC7, 0x78}},
|
||||
{
|
||||
[]byte{0x1C, 0x58, 0x7F, 0x1C, 0x13, 0x92, 0x4F, 0xEF},
|
||||
[]byte{0x30, 0x55, 0x32, 0x28, 0x6D, 0x6F, 0x29, 0x5A},
|
||||
[]byte{0x55, 0xCB, 0x37, 0x74, 0xD1, 0x3E, 0xF2, 0x01}},
|
||||
{
|
||||
[]byte{0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xFA, 0x34, 0xEC, 0x48, 0x47, 0xB2, 0x68, 0xB2}},
|
||||
{
|
||||
[]byte{0x1F, 0x1F, 0x1F, 0x1F, 0x0E, 0x0E, 0x0E, 0x0E},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xA7, 0x90, 0x79, 0x51, 0x08, 0xEA, 0x3C, 0xAE}},
|
||||
{
|
||||
[]byte{0xE0, 0xFE, 0xE0, 0xFE, 0xF1, 0xFE, 0xF1, 0xFE},
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0xC3, 0x9E, 0x07, 0x2D, 0x9F, 0xAC, 0x63, 0x1D}},
|
||||
{
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x01, 0x49, 0x33, 0xE0, 0xCD, 0xAF, 0xF6, 0xE4}},
|
||||
{
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0xF2, 0x1E, 0x9A, 0x77, 0xB7, 0x1C, 0x49, 0xBC}},
|
||||
{
|
||||
[]byte{0x01, 0x23, 0x45, 0x67, 0x89, 0xAB, 0xCD, 0xEF},
|
||||
[]byte{0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00},
|
||||
[]byte{0x24, 0x59, 0x46, 0x88, 0x57, 0x54, 0x36, 0x9A}},
|
||||
{
|
||||
[]byte{0xFE, 0xDC, 0xBA, 0x98, 0x76, 0x54, 0x32, 0x10},
|
||||
[]byte{0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF, 0xFF},
|
||||
[]byte{0x6B, 0x5C, 0x5A, 0x9C, 0x5D, 0x9E, 0x0A, 0x5A}},
|
||||
}
|
||||
|
||||
func TestCipherEncrypt(t *testing.T) {
|
||||
for i, tt := range encryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
ct := make([]byte, len(tt.out))
|
||||
c.Encrypt(ct, tt.in)
|
||||
for j, v := range ct {
|
||||
if v != tt.out[j] {
|
||||
t.Errorf("Cipher.Encrypt, test vector #%d: cipher-text[%d] = %#x, expected %#x", i, j, v, tt.out[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestCipherDecrypt(t *testing.T) {
|
||||
for i, tt := range encryptTests {
|
||||
c, err := NewCipher(tt.key)
|
||||
if err != nil {
|
||||
t.Errorf("NewCipher(%d bytes) = %s", len(tt.key), err)
|
||||
continue
|
||||
}
|
||||
pt := make([]byte, len(tt.in))
|
||||
c.Decrypt(pt, tt.out)
|
||||
for j, v := range pt {
|
||||
if v != tt.in[j] {
|
||||
t.Errorf("Cipher.Decrypt, test vector #%d: plain-text[%d] = %#x, expected %#x", i, j, v, tt.in[j])
|
||||
break
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func TestSaltedCipherKeyLength(t *testing.T) {
|
||||
if _, err := NewSaltedCipher(nil, []byte{'a'}); err != KeySizeError(0) {
|
||||
t.Errorf("NewSaltedCipher with short key, gave error %#v, expected %#v", err, KeySizeError(0))
|
||||
}
|
||||
|
||||
// A 57-byte key. One over the typical blowfish restriction.
|
||||
key := []byte("012345678901234567890123456789012345678901234567890123456")
|
||||
if _, err := NewSaltedCipher(key, []byte{'a'}); err != nil {
|
||||
t.Errorf("NewSaltedCipher with long key, gave error %#v", err)
|
||||
}
|
||||
}
|
||||
|
||||
// Test vectors generated with Blowfish from OpenSSH.
|
||||
var saltedVectors = [][8]byte{
|
||||
{0x0c, 0x82, 0x3b, 0x7b, 0x8d, 0x01, 0x4b, 0x7e},
|
||||
{0xd1, 0xe1, 0x93, 0xf0, 0x70, 0xa6, 0xdb, 0x12},
|
||||
{0xfc, 0x5e, 0xba, 0xde, 0xcb, 0xf8, 0x59, 0xad},
|
||||
{0x8a, 0x0c, 0x76, 0xe7, 0xdd, 0x2c, 0xd3, 0xa8},
|
||||
{0x2c, 0xcb, 0x7b, 0xee, 0xac, 0x7b, 0x7f, 0xf8},
|
||||
{0xbb, 0xf6, 0x30, 0x6f, 0xe1, 0x5d, 0x62, 0xbf},
|
||||
{0x97, 0x1e, 0xc1, 0x3d, 0x3d, 0xe0, 0x11, 0xe9},
|
||||
{0x06, 0xd7, 0x4d, 0xb1, 0x80, 0xa3, 0xb1, 0x38},
|
||||
{0x67, 0xa1, 0xa9, 0x75, 0x0e, 0x5b, 0xc6, 0xb4},
|
||||
{0x51, 0x0f, 0x33, 0x0e, 0x4f, 0x67, 0xd2, 0x0c},
|
||||
{0xf1, 0x73, 0x7e, 0xd8, 0x44, 0xea, 0xdb, 0xe5},
|
||||
{0x14, 0x0e, 0x16, 0xce, 0x7f, 0x4a, 0x9c, 0x7b},
|
||||
{0x4b, 0xfe, 0x43, 0xfd, 0xbf, 0x36, 0x04, 0x47},
|
||||
{0xb1, 0xeb, 0x3e, 0x15, 0x36, 0xa7, 0xbb, 0xe2},
|
||||
{0x6d, 0x0b, 0x41, 0xdd, 0x00, 0x98, 0x0b, 0x19},
|
||||
{0xd3, 0xce, 0x45, 0xce, 0x1d, 0x56, 0xb7, 0xfc},
|
||||
{0xd9, 0xf0, 0xfd, 0xda, 0xc0, 0x23, 0xb7, 0x93},
|
||||
{0x4c, 0x6f, 0xa1, 0xe4, 0x0c, 0xa8, 0xca, 0x57},
|
||||
{0xe6, 0x2f, 0x28, 0xa7, 0x0c, 0x94, 0x0d, 0x08},
|
||||
{0x8f, 0xe3, 0xf0, 0xb6, 0x29, 0xe3, 0x44, 0x03},
|
||||
{0xff, 0x98, 0xdd, 0x04, 0x45, 0xb4, 0x6d, 0x1f},
|
||||
{0x9e, 0x45, 0x4d, 0x18, 0x40, 0x53, 0xdb, 0xef},
|
||||
{0xb7, 0x3b, 0xef, 0x29, 0xbe, 0xa8, 0x13, 0x71},
|
||||
{0x02, 0x54, 0x55, 0x41, 0x8e, 0x04, 0xfc, 0xad},
|
||||
{0x6a, 0x0a, 0xee, 0x7c, 0x10, 0xd9, 0x19, 0xfe},
|
||||
{0x0a, 0x22, 0xd9, 0x41, 0xcc, 0x23, 0x87, 0x13},
|
||||
{0x6e, 0xff, 0x1f, 0xff, 0x36, 0x17, 0x9c, 0xbe},
|
||||
{0x79, 0xad, 0xb7, 0x40, 0xf4, 0x9f, 0x51, 0xa6},
|
||||
{0x97, 0x81, 0x99, 0xa4, 0xde, 0x9e, 0x9f, 0xb6},
|
||||
{0x12, 0x19, 0x7a, 0x28, 0xd0, 0xdc, 0xcc, 0x92},
|
||||
{0x81, 0xda, 0x60, 0x1e, 0x0e, 0xdd, 0x65, 0x56},
|
||||
{0x7d, 0x76, 0x20, 0xb2, 0x73, 0xc9, 0x9e, 0xee},
|
||||
}
|
||||
|
||||
func TestSaltedCipher(t *testing.T) {
|
||||
var key, salt [32]byte
|
||||
for i := range key {
|
||||
key[i] = byte(i)
|
||||
salt[i] = byte(i + 32)
|
||||
}
|
||||
for i, v := range saltedVectors {
|
||||
c, err := NewSaltedCipher(key[:], salt[:i])
|
||||
if err != nil {
|
||||
t.Fatal(err)
|
||||
}
|
||||
var buf [8]byte
|
||||
c.Encrypt(buf[:], buf[:])
|
||||
if v != buf {
|
||||
t.Errorf("%d: expected %x, got %x", i, v, buf)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkExpandKeyWithSalt(b *testing.B) {
|
||||
key := make([]byte, 32)
|
||||
salt := make([]byte, 16)
|
||||
c, _ := NewCipher(key)
|
||||
for i := 0; i < b.N; i++ {
|
||||
expandKeyWithSalt(key, salt, c)
|
||||
}
|
||||
}
|
||||
|
||||
func BenchmarkExpandKey(b *testing.B) {
|
||||
key := make([]byte, 32)
|
||||
c, _ := NewCipher(key)
|
||||
for i := 0; i < b.N; i++ {
|
||||
ExpandKey(key, c)
|
||||
}
|
||||
}
|
91
Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
Normal file
91
Godeps/_workspace/src/golang.org/x/crypto/blowfish/cipher.go
generated
vendored
Normal file
|
@ -0,0 +1,91 @@
|
|||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// Package blowfish implements Bruce Schneier's Blowfish encryption algorithm.
|
||||
package blowfish // import "golang.org/x/crypto/blowfish"
|
||||
|
||||
// The code is a port of Bruce Schneier's C implementation.
|
||||
// See http://www.schneier.com/blowfish.html.
|
||||
|
||||
import "strconv"
|
||||
|
||||
// The Blowfish block size in bytes.
|
||||
const BlockSize = 8
|
||||
|
||||
// A Cipher is an instance of Blowfish encryption using a particular key.
|
||||
type Cipher struct {
|
||||
p [18]uint32
|
||||
s0, s1, s2, s3 [256]uint32
|
||||
}
|
||||
|
||||
type KeySizeError int
|
||||
|
||||
func (k KeySizeError) Error() string {
|
||||
return "crypto/blowfish: invalid key size " + strconv.Itoa(int(k))
|
||||
}
|
||||
|
||||
// NewCipher creates and returns a Cipher.
|
||||
// The key argument should be the Blowfish key, from 1 to 56 bytes.
|
||||
func NewCipher(key []byte) (*Cipher, error) {
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 || k > 56 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(&result)
|
||||
ExpandKey(key, &result)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// NewSaltedCipher creates a returns a Cipher that folds a salt into its key
|
||||
// schedule. For most purposes, NewCipher, instead of NewSaltedCipher, is
|
||||
// sufficient and desirable. For bcrypt compatiblity, the key can be over 56
|
||||
// bytes.
|
||||
func NewSaltedCipher(key, salt []byte) (*Cipher, error) {
|
||||
if len(salt) == 0 {
|
||||
return NewCipher(key)
|
||||
}
|
||||
var result Cipher
|
||||
if k := len(key); k < 1 {
|
||||
return nil, KeySizeError(k)
|
||||
}
|
||||
initCipher(&result)
|
||||
expandKeyWithSalt(key, salt, &result)
|
||||
return &result, nil
|
||||
}
|
||||
|
||||
// BlockSize returns the Blowfish block size, 8 bytes.
|
||||
// It is necessary to satisfy the Block interface in the
|
||||
// package "crypto/cipher".
|
||||
func (c *Cipher) BlockSize() int { return BlockSize }
|
||||
|
||||
// Encrypt encrypts the 8-byte buffer src using the key k
|
||||
// and stores the result in dst.
|
||||
// Note that for amounts of data larger than a block,
|
||||
// it is not safe to just call Encrypt on successive blocks;
|
||||
// instead, use an encryption mode like CBC (see crypto/cipher/cbc.go).
|
||||
func (c *Cipher) Encrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
l, r = encryptBlock(l, r, c)
|
||||
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||
}
|
||||
|
||||
// Decrypt decrypts the 8-byte buffer src using the key k
|
||||
// and stores the result in dst.
|
||||
func (c *Cipher) Decrypt(dst, src []byte) {
|
||||
l := uint32(src[0])<<24 | uint32(src[1])<<16 | uint32(src[2])<<8 | uint32(src[3])
|
||||
r := uint32(src[4])<<24 | uint32(src[5])<<16 | uint32(src[6])<<8 | uint32(src[7])
|
||||
l, r = decryptBlock(l, r, c)
|
||||
dst[0], dst[1], dst[2], dst[3] = byte(l>>24), byte(l>>16), byte(l>>8), byte(l)
|
||||
dst[4], dst[5], dst[6], dst[7] = byte(r>>24), byte(r>>16), byte(r>>8), byte(r)
|
||||
}
|
||||
|
||||
func initCipher(c *Cipher) {
|
||||
copy(c.p[0:], p[0:])
|
||||
copy(c.s0[0:], s0[0:])
|
||||
copy(c.s1[0:], s1[0:])
|
||||
copy(c.s2[0:], s2[0:])
|
||||
copy(c.s3[0:], s3[0:])
|
||||
}
|
199
Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go
generated
vendored
Normal file
199
Godeps/_workspace/src/golang.org/x/crypto/blowfish/const.go
generated
vendored
Normal file
|
@ -0,0 +1,199 @@
|
|||
// Copyright 2010 The Go Authors. All rights reserved.
|
||||
// Use of this source code is governed by a BSD-style
|
||||
// license that can be found in the LICENSE file.
|
||||
|
||||
// The startup permutation array and substitution boxes.
|
||||
// They are the hexadecimal digits of PI; see:
|
||||
// http://www.schneier.com/code/constants.txt.
|
||||
|
||||
package blowfish
|
||||
|
||||
var s0 = [256]uint32{
|
||||
0xd1310ba6, 0x98dfb5ac, 0x2ffd72db, 0xd01adfb7, 0xb8e1afed, 0x6a267e96,
|
||||
0xba7c9045, 0xf12c7f99, 0x24a19947, 0xb3916cf7, 0x0801f2e2, 0x858efc16,
|
||||
0x636920d8, 0x71574e69, 0xa458fea3, 0xf4933d7e, 0x0d95748f, 0x728eb658,
|
||||
0x718bcd58, 0x82154aee, 0x7b54a41d, 0xc25a59b5, 0x9c30d539, 0x2af26013,
|
||||
0xc5d1b023, 0x286085f0, 0xca417918, 0xb8db38ef, 0x8e79dcb0, 0x603a180e,
|
||||
0x6c9e0e8b, 0xb01e8a3e, 0xd71577c1, 0xbd314b27, 0x78af2fda, 0x55605c60,
|
||||
0xe65525f3, 0xaa55ab94, 0x57489862, 0x63e81440, 0x55ca396a, 0x2aab10b6,
|
||||
0xb4cc5c34, 0x1141e8ce, 0xa15486af, 0x7c72e993, 0xb3ee1411, 0x636fbc2a,
|
||||
0x2ba9c55d, 0x741831f6, 0xce5c3e16, 0x9b87931e, 0xafd6ba33, 0x6c24cf5c,
|
||||
0x7a325381, 0x28958677, 0x3b8f4898, 0x6b4bb9af, 0xc4bfe81b, 0x66282193,
|
||||
0x61d809cc, 0xfb21a991, 0x487cac60, 0x5dec8032, 0xef845d5d, 0xe98575b1,
|
||||
0xdc262302, 0xeb651b88, 0x23893e81, 0xd396acc5, 0x0f6d6ff3, 0x83f44239,
|
||||
0x2e0b4482, 0xa4842004, 0x69c8f04a, 0x9e1f9b5e, 0x21c66842, 0xf6e96c9a,
|
||||
0x670c9c61, 0xabd388f0, 0x6a51a0d2, 0xd8542f68, 0x960fa728, 0xab5133a3,
|
||||
0x6eef0b6c, 0x137a3be4, 0xba3bf050, 0x7efb2a98, 0xa1f1651d, 0x39af0176,
|
||||
0x66ca593e, 0x82430e88, 0x8cee8619, 0x456f9fb4, 0x7d84a5c3, 0x3b8b5ebe,
|
||||
0xe06f75d8, 0x85c12073, 0x401a449f, 0x56c16aa6, 0x4ed3aa62, 0x363f7706,
|
||||
0x1bfedf72, 0x429b023d, 0x37d0d724, 0xd00a1248, 0xdb0fead3, 0x49f1c09b,
|
||||
0x075372c9, 0x80991b7b, 0x25d479d8, 0xf6e8def7, 0xe3fe501a, 0xb6794c3b,
|
||||
0x976ce0bd, 0x04c006ba, 0xc1a94fb6, 0x409f60c4, 0x5e5c9ec2, 0x196a2463,
|
||||
0x68fb6faf, 0x3e6c53b5, 0x1339b2eb, 0x3b52ec6f, 0x6dfc511f, 0x9b30952c,
|
||||
0xcc814544, 0xaf5ebd09, 0xbee3d004, 0xde334afd, 0x660f2807, 0x192e4bb3,
|
||||
0xc0cba857, 0x45c8740f, 0xd20b5f39, 0xb9d3fbdb, 0x5579c0bd, 0x1a60320a,
|
||||
0xd6a100c6, 0x402c7279, 0x679f25fe, 0xfb1fa3cc, 0x8ea5e9f8, 0xdb3222f8,
|
||||
0x3c7516df, 0xfd616b15, 0x2f501ec8, 0xad0552ab, 0x323db5fa, 0xfd238760,
|
||||
0x53317b48, 0x3e00df82, 0x9e5c57bb, 0xca6f8ca0, 0x1a87562e, 0xdf1769db,
|
||||
0xd542a8f6, 0x287effc3, 0xac6732c6, 0x8c4f5573, 0x695b27b0, 0xbbca58c8,
|
||||
0xe1ffa35d, 0xb8f011a0, 0x10fa3d98, 0xfd2183b8, 0x4afcb56c, 0x2dd1d35b,
|
||||
0x9a53e479, 0xb6f84565, 0xd28e49bc, 0x4bfb9790, 0xe1ddf2da, 0xa4cb7e33,
|
||||
0x62fb1341, 0xcee4c6e8, 0xef20cada, 0x36774c01, 0xd07e9efe, 0x2bf11fb4,
|
||||
0x95dbda4d, 0xae909198, 0xeaad8e71, 0x6b93d5a0, 0xd08ed1d0, 0xafc725e0,
|
||||
0x8e3c5b2f, 0x8e7594b7, 0x8ff6e2fb, 0xf2122b64, 0x8888b812, 0x900df01c,
|
||||
0x4fad5ea0, 0x688fc31c, 0xd1cff191, 0xb3a8c1ad, 0x2f2f2218, 0xbe0e1777,
|
||||
0xea752dfe, 0x8b021fa1, 0xe5a0cc0f, 0xb56f74e8, 0x18acf3d6, 0xce89e299,
|
||||
0xb4a84fe0, 0xfd13e0b7, 0x7cc43b81, 0xd2ada8d9, 0x165fa266, 0x80957705,
|
||||
0x93cc7314, 0x211a1477, 0xe6ad2065, 0x77b5fa86, 0xc75442f5, 0xfb9d35cf,
|
||||
0xebcdaf0c, 0x7b3e89a0, 0xd6411bd3, 0xae1e7e49, 0x00250e2d, 0x2071b35e,
|
||||
0x226800bb, 0x57b8e0af, 0x2464369b, 0xf009b91e, 0x5563911d, 0x59dfa6aa,
|
||||
0x78c14389, 0xd95a537f, 0x207d5ba2, 0x02e5b9c5, 0x83260376, 0x6295cfa9,
|
||||
0x11c81968, 0x4e734a41, 0xb3472dca, 0x7b14a94a, 0x1b510052, 0x9a532915,
|
||||
0xd60f573f, 0xbc9bc6e4, 0x2b60a476, 0x81e67400, 0x08ba6fb5, 0x571be91f,
|
||||
0xf296ec6b, 0x2a0dd915, 0xb6636521, 0xe7b9f9b6, 0xff34052e, 0xc5855664,
|
||||
0x53b02d5d, 0xa99f8fa1, 0x08ba4799, 0x6e85076a,
|
||||
}
|
||||
|
||||
var s1 = [256]uint32{
|
||||
0x4b7a70e9, 0xb5b32944, 0xdb75092e, 0xc4192623, 0xad6ea6b0, 0x49a7df7d,
|
||||
0x9cee60b8, 0x8fedb266, 0xecaa8c71, 0x699a17ff, 0x5664526c, 0xc2b19ee1,
|
||||
0x193602a5, 0x75094c29, 0xa0591340, 0xe4183a3e, 0x3f54989a, 0x5b429d65,
|
||||
0x6b8fe4d6, 0x99f73fd6, 0xa1d29c07, 0xefe830f5, 0x4d2d38e6, 0xf0255dc1,
|
||||
0x4cdd2086, 0x8470eb26, 0x6382e9c6, 0x021ecc5e, 0x09686b3f, 0x3ebaefc9,
|
||||
0x3c971814, 0x6b6a70a1, 0x687f3584, 0x52a0e286, 0xb79c5305, 0xaa500737,
|
||||
0x3e07841c, 0x7fdeae5c, 0x8e7d44ec, 0x5716f2b8, 0xb03ada37, 0xf0500c0d,
|
||||
0xf01c1f04, 0x0200b3ff, 0xae0cf51a, 0x3cb574b2, 0x25837a58, 0xdc0921bd,
|
||||
0xd19113f9, 0x7ca92ff6, 0x94324773, 0x22f54701, 0x3ae5e581, 0x37c2dadc,
|
||||
0xc8b57634, 0x9af3dda7, 0xa9446146, 0x0fd0030e, 0xecc8c73e, 0xa4751e41,
|
||||
0xe238cd99, 0x3bea0e2f, 0x3280bba1, 0x183eb331, 0x4e548b38, 0x4f6db908,
|
||||
0x6f420d03, 0xf60a04bf, 0x2cb81290, 0x24977c79, 0x5679b072, 0xbcaf89af,
|
||||
0xde9a771f, 0xd9930810, 0xb38bae12, 0xdccf3f2e, 0x5512721f, 0x2e6b7124,
|
||||
0x501adde6, 0x9f84cd87, 0x7a584718, 0x7408da17, 0xbc9f9abc, 0xe94b7d8c,
|
||||
0xec7aec3a, 0xdb851dfa, 0x63094366, 0xc464c3d2, 0xef1c1847, 0x3215d908,
|
||||
0xdd433b37, 0x24c2ba16, 0x12a14d43, 0x2a65c451, 0x50940002, 0x133ae4dd,
|
||||
0x71dff89e, 0x10314e55, 0x81ac77d6, 0x5f11199b, 0x043556f1, 0xd7a3c76b,
|
||||
0x3c11183b, 0x5924a509, 0xf28fe6ed, 0x97f1fbfa, 0x9ebabf2c, 0x1e153c6e,
|
||||
0x86e34570, 0xeae96fb1, 0x860e5e0a, 0x5a3e2ab3, 0x771fe71c, 0x4e3d06fa,
|
||||
0x2965dcb9, 0x99e71d0f, 0x803e89d6, 0x5266c825, 0x2e4cc978, 0x9c10b36a,
|
||||
0xc6150eba, 0x94e2ea78, 0xa5fc3c53, 0x1e0a2df4, 0xf2f74ea7, 0x361d2b3d,
|
||||
0x1939260f, 0x19c27960, 0x5223a708, 0xf71312b6, 0xebadfe6e, 0xeac31f66,
|
||||
0xe3bc4595, 0xa67bc883, 0xb17f37d1, 0x018cff28, 0xc332ddef, 0xbe6c5aa5,
|
||||
0x65582185, 0x68ab9802, 0xeecea50f, 0xdb2f953b, 0x2aef7dad, 0x5b6e2f84,
|
||||
0x1521b628, 0x29076170, 0xecdd4775, 0x619f1510, 0x13cca830, 0xeb61bd96,
|
||||
0x0334fe1e, 0xaa0363cf, 0xb5735c90, 0x4c70a239, 0xd59e9e0b, 0xcbaade14,
|
||||
0xeecc86bc, 0x60622ca7, 0x9cab5cab, 0xb2f3846e, 0x648b1eaf, 0x19bdf0ca,
|
||||
0xa02369b9, 0x655abb50, 0x40685a32, 0x3c2ab4b3, 0x319ee9d5, 0xc021b8f7,
|
||||
0x9b540b19, 0x875fa099, 0x95f7997e, 0x623d7da8, 0xf837889a, 0x97e32d77,
|
||||
0x11ed935f, 0x16681281, 0x0e358829, 0xc7e61fd6, 0x96dedfa1, 0x7858ba99,
|
||||
0x57f584a5, 0x1b227263, 0x9b83c3ff, 0x1ac24696, 0xcdb30aeb, 0x532e3054,
|
||||
0x8fd948e4, 0x6dbc3128, 0x58ebf2ef, 0x34c6ffea, 0xfe28ed61, 0xee7c3c73,
|
||||
0x5d4a14d9, 0xe864b7e3, 0x42105d14, 0x203e13e0, 0x45eee2b6, 0xa3aaabea,
|
||||
0xdb6c4f15, 0xfacb4fd0, 0xc742f442, 0xef6abbb5, 0x654f3b1d, 0x41cd2105,
|
||||
0xd81e799e, 0x86854dc7, 0xe44b476a, 0x3d816250, 0xcf62a1f2, 0x5b8d2646,
|
||||
0xfc8883a0, 0xc1c7b6a3, 0x7f1524c3, 0x69cb7492, 0x47848a0b, 0x5692b285,
|
||||
0x095bbf00, 0xad19489d, 0x1462b174, 0x23820e00, 0x58428d2a, 0x0c55f5ea,
|
||||
0x1dadf43e, 0x233f7061, 0x3372f092, 0x8d937e41, 0xd65fecf1, 0x6c223bdb,
|
||||
0x7cde3759, 0xcbee7460, 0x4085f2a7, 0xce77326e, 0xa6078084, 0x19f8509e,
|
||||
0xe8efd855, 0x61d99735, 0xa969a7aa, 0xc50c06c2, 0x5a04abfc, 0x800bcadc,
|
||||
0x9e447a2e, 0xc3453484, 0xfdd56705, 0x0e1e9ec9, 0xdb73dbd3, 0x105588cd,
|
||||
0x675fda79, 0xe3674340, 0xc5c43465, 0x713e38d8, 0x3d28f89e, 0xf16dff20,
|
||||
0x153e21e7, 0x8fb03d4a, 0xe6e39f2b, 0xdb83adf7,
|
||||
}
|
||||
|
||||
var s2 = [256]uint32{
|
||||
0xe93d5a68, 0x948140f7, 0xf64c261c, 0x94692934, 0x411520f7, 0x7602d4f7,
|
||||
0xbcf46b2e, 0xd4a20068, 0xd4082471, 0x3320f46a, 0x43b7d4b7, 0x500061af,
|
||||
0x1e39f62e, 0x97244546, 0x14214f74, 0xbf8b8840, 0x4d95fc1d, 0x96b591af,
|
||||
0x70f4ddd3, 0x66a02f45, 0xbfbc09ec, 0x03bd9785, 0x7fac6dd0, 0x31cb8504,
|
||||
0x96eb27b3, 0x55fd3941, 0xda2547e6, 0xabca0a9a, 0x28507825, 0x530429f4,
|
||||
0x0a2c86da, 0xe9b66dfb, 0x68dc1462, 0xd7486900, 0x680ec0a4, 0x27a18dee,
|
||||
0x4f3ffea2, 0xe887ad8c, 0xb58ce006, 0x7af4d6b6, 0xaace1e7c, 0xd3375fec,
|
||||
0xce78a399, 0x406b2a42, 0x20fe9e35, 0xd9f385b9, 0xee39d7ab, 0x3b124e8b,
|
||||
0x1dc9faf7, 0x4b6d1856, 0x26a36631, 0xeae397b2, 0x3a6efa74, 0xdd5b4332,
|
||||
0x6841e7f7, 0xca7820fb, 0xfb0af54e, 0xd8feb397, 0x454056ac, 0xba489527,
|
||||
0x55533a3a, 0x20838d87, 0xfe6ba9b7, 0xd096954b, 0x55a867bc, 0xa1159a58,
|
||||
0xcca92963, 0x99e1db33, 0xa62a4a56, 0x3f3125f9, 0x5ef47e1c, 0x9029317c,
|
||||
0xfdf8e802, 0x04272f70, 0x80bb155c, 0x05282ce3, 0x95c11548, 0xe4c66d22,
|
||||
0x48c1133f, 0xc70f86dc, 0x07f9c9ee, 0x41041f0f, 0x404779a4, 0x5d886e17,
|
||||
0x325f51eb, 0xd59bc0d1, 0xf2bcc18f, 0x41113564, 0x257b7834, 0x602a9c60,
|
||||
0xdff8e8a3, 0x1f636c1b, 0x0e12b4c2, 0x02e1329e, 0xaf664fd1, 0xcad18115,
|
||||
0x6b2395e0, 0x333e92e1, 0x3b240b62, 0xeebeb922, 0x85b2a20e, 0xe6ba0d99,
|
||||
0xde720c8c, 0x2da2f728, 0xd0127845, 0x95b794fd, 0x647d0862, 0xe7ccf5f0,
|
||||
0x5449a36f, 0x877d48fa, 0xc39dfd27, 0xf33e8d1e, 0x0a476341, 0x992eff74,
|
||||
0x3a6f6eab, 0xf4f8fd37, 0xa812dc60, 0xa1ebddf8, 0x991be14c, 0xdb6e6b0d,
|
||||
0xc67b5510, 0x6d672c37, 0x2765d43b, 0xdcd0e804, 0xf1290dc7, 0xcc00ffa3,
|
||||
0xb5390f92, 0x690fed0b, 0x667b9ffb, 0xcedb7d9c, 0xa091cf0b, 0xd9155ea3,
|
||||
0xbb132f88, 0x515bad24, 0x7b9479bf, 0x763bd6eb, 0x37392eb3, 0xcc115979,
|
||||
0x8026e297, 0xf42e312d, 0x6842ada7, 0xc66a2b3b, 0x12754ccc, 0x782ef11c,
|
||||
0x6a124237, 0xb79251e7, 0x06a1bbe6, 0x4bfb6350, 0x1a6b1018, 0x11caedfa,
|
||||
0x3d25bdd8, 0xe2e1c3c9, 0x44421659, 0x0a121386, 0xd90cec6e, 0xd5abea2a,
|
||||
0x64af674e, 0xda86a85f, 0xbebfe988, 0x64e4c3fe, 0x9dbc8057, 0xf0f7c086,
|
||||
0x60787bf8, 0x6003604d, 0xd1fd8346, 0xf6381fb0, 0x7745ae04, 0xd736fccc,
|
||||
0x83426b33, 0xf01eab71, 0xb0804187, 0x3c005e5f, 0x77a057be, 0xbde8ae24,
|
||||
0x55464299, 0xbf582e61, 0x4e58f48f, 0xf2ddfda2, 0xf474ef38, 0x8789bdc2,
|
||||
0x5366f9c3, 0xc8b38e74, 0xb475f255, 0x46fcd9b9, 0x7aeb2661, 0x8b1ddf84,
|
||||
0x846a0e79, 0x915f95e2, 0x466e598e, 0x20b45770, 0x8cd55591, 0xc902de4c,
|
||||
0xb90bace1, 0xbb8205d0, 0x11a86248, 0x7574a99e, 0xb77f19b6, 0xe0a9dc09,
|
||||
0x662d09a1, 0xc4324633, 0xe85a1f02, 0x09f0be8c, 0x4a99a025, 0x1d6efe10,
|
||||
0x1ab93d1d, 0x0ba5a4df, 0xa186f20f, 0x2868f169, 0xdcb7da83, 0x573906fe,
|
||||
0xa1e2ce9b, 0x4fcd7f52, 0x50115e01, 0xa70683fa, 0xa002b5c4, 0x0de6d027,
|
||||
0x9af88c27, 0x773f8641, 0xc3604c06, 0x61a806b5, 0xf0177a28, 0xc0f586e0,
|
||||
0x006058aa, 0x30dc7d62, 0x11e69ed7, 0x2338ea63, 0x53c2dd94, 0xc2c21634,
|
||||
0xbbcbee56, 0x90bcb6de, 0xebfc7da1, 0xce591d76, 0x6f05e409, 0x4b7c0188,
|
||||
0x39720a3d, 0x7c927c24, 0x86e3725f, 0x724d9db9, 0x1ac15bb4, 0xd39eb8fc,
|
||||
0xed545578, 0x08fca5b5, 0xd83d7cd3, 0x4dad0fc4, 0x1e50ef5e, 0xb161e6f8,
|
||||
0xa28514d9, 0x6c51133c, 0x6fd5c7e7, 0x56e14ec4, 0x362abfce, 0xddc6c837,
|
||||
0xd79a3234, 0x92638212, 0x670efa8e, 0x406000e0,
|
||||
}
|
||||
|
||||
var s3 = [256]uint32{
|
||||
0x3a39ce37, 0xd3faf5cf, 0xabc27737, 0x5ac52d1b, 0x5cb0679e, 0x4fa33742,
|
||||
0xd3822740, 0x99bc9bbe, 0xd5118e9d, 0xbf0f7315, 0xd62d1c7e, 0xc700c47b,
|
||||
0xb78c1b6b, 0x21a19045, 0xb26eb1be, 0x6a366eb4, 0x5748ab2f, 0xbc946e79,
|
||||
0xc6a376d2, 0x6549c2c8, 0x530ff8ee, 0x468dde7d, 0xd5730a1d, 0x4cd04dc6,
|
||||
0x2939bbdb, 0xa9ba4650, 0xac9526e8, 0xbe5ee304, 0xa1fad5f0, 0x6a2d519a,
|
||||
0x63ef8ce2, 0x9a86ee22, 0xc089c2b8, 0x43242ef6, 0xa51e03aa, 0x9cf2d0a4,
|
||||
0x83c061ba, 0x9be96a4d, 0x8fe51550, 0xba645bd6, 0x2826a2f9, 0xa73a3ae1,
|
||||
0x4ba99586, 0xef5562e9, 0xc72fefd3, 0xf752f7da, 0x3f046f69, 0x77fa0a59,
|
||||
0x80e4a915, 0x87b08601, 0x9b09e6ad, 0x3b3ee593, 0xe990fd5a, 0x9e34d797,
|
||||
0x2cf0b7d9, 0x022b8b51, 0x96d5ac3a, 0x017da67d, 0xd1cf3ed6, 0x7c7d2d28,
|
||||
0x1f9f25cf, 0xadf2b89b, 0x5ad6b472, 0x5a88f54c, 0xe029ac71, 0xe019a5e6,
|
||||
0x47b0acfd, 0xed93fa9b, 0xe8d3c48d, 0x283b57cc, 0xf8d56629, 0x79132e28,
|
||||
0x785f0191, 0xed756055, 0xf7960e44, 0xe3d35e8c, 0x15056dd4, 0x88f46dba,
|
||||
0x03a16125, 0x0564f0bd, 0xc3eb9e15, 0x3c9057a2, 0x97271aec, 0xa93a072a,
|
||||
0x1b3f6d9b, 0x1e6321f5, 0xf59c66fb, 0x26dcf319, 0x7533d928, 0xb155fdf5,
|
||||
0x03563482, 0x8aba3cbb, 0x28517711, 0xc20ad9f8, 0xabcc5167, 0xccad925f,
|
||||
0x4de81751, 0x3830dc8e, 0x379d5862, 0x9320f991, 0xea7a90c2, 0xfb3e7bce,
|
||||
0x5121ce64, 0x774fbe32, 0xa8b6e37e, 0xc3293d46, 0x48de5369, 0x6413e680,
|
||||
0xa2ae0810, 0xdd6db224, 0x69852dfd, 0x09072166, 0xb39a460a, 0x6445c0dd,
|
||||
0x586cdecf, 0x1c20c8ae, 0x5bbef7dd, 0x1b588d40, 0xccd2017f, 0x6bb4e3bb,
|
||||
0xdda26a7e, 0x3a59ff45, 0x3e350a44, 0xbcb4cdd5, 0x72eacea8, 0xfa6484bb,
|
||||
0x8d6612ae, 0xbf3c6f47, 0xd29be463, 0x542f5d9e, 0xaec2771b, 0xf64e6370,
|
||||
0x740e0d8d, 0xe75b1357, 0xf8721671, 0xaf537d5d, 0x4040cb08, 0x4eb4e2cc,
|
||||
0x34d2466a, 0x0115af84, 0xe1b00428, 0x95983a1d, 0x06b89fb4, 0xce6ea048,
|
||||
0x6f3f3b82, 0x3520ab82, 0x011a1d4b, 0x277227f8, 0x611560b1, 0xe7933fdc,
|
||||
0xbb3a792b, 0x344525bd, 0xa08839e1, 0x51ce794b, 0x2f32c9b7, 0xa01fbac9,
|
||||
0xe01cc87e, 0xbcc7d1f6, 0xcf0111c3, 0xa1e8aac7, 0x1a908749, 0xd44fbd9a,
|
||||
0xd0dadecb, 0xd50ada38, 0x0339c32a, 0xc6913667, 0x8df9317c, 0xe0b12b4f,
|
||||
0xf79e59b7, 0x43f5bb3a, 0xf2d519ff, 0x27d9459c, 0xbf97222c, 0x15e6fc2a,
|
||||
0x0f91fc71, 0x9b941525, 0xfae59361, 0xceb69ceb, 0xc2a86459, 0x12baa8d1,
|
||||
0xb6c1075e, 0xe3056a0c, 0x10d25065, 0xcb03a442, 0xe0ec6e0e, 0x1698db3b,
|
||||
0x4c98a0be, 0x3278e964, 0x9f1f9532, 0xe0d392df, 0xd3a0342b, 0x8971f21e,
|
||||
0x1b0a7441, 0x4ba3348c, 0xc5be7120, 0xc37632d8, 0xdf359f8d, 0x9b992f2e,
|
||||
0xe60b6f47, 0x0fe3f11d, 0xe54cda54, 0x1edad891, 0xce6279cf, 0xcd3e7e6f,
|
||||
0x1618b166, 0xfd2c1d05, 0x848fd2c5, 0xf6fb2299, 0xf523f357, 0xa6327623,
|
||||
0x93a83531, 0x56cccd02, 0xacf08162, 0x5a75ebb5, 0x6e163697, 0x88d273cc,
|
||||
0xde966292, 0x81b949d0, 0x4c50901b, 0x71c65614, 0xe6c6c7bd, 0x327a140a,
|
||||
0x45e1d006, 0xc3f27b9a, 0xc9aa53fd, 0x62a80f00, 0xbb25bfe2, 0x35bdd2f6,
|
||||
0x71126905, 0xb2040222, 0xb6cbcf7c, 0xcd769c2b, 0x53113ec0, 0x1640e3d3,
|
||||
0x38abbd60, 0x2547adf0, 0xba38209c, 0xf746ce76, 0x77afa1c5, 0x20756060,
|
||||
0x85cbfe4e, 0x8ae88dd8, 0x7aaaf9b0, 0x4cf9aa7e, 0x1948c25c, 0x02fb8a8c,
|
||||
0x01c36ae4, 0xd6ebe1f9, 0x90d4f869, 0xa65cdea0, 0x3f09252d, 0xc208e69f,
|
||||
0xb74e6132, 0xce77e25b, 0x578fdfe3, 0x3ac372e6,
|
||||
}
|
||||
|
||||
var p = [18]uint32{
|
||||
0x243f6a88, 0x85a308d3, 0x13198a2e, 0x03707344, 0xa4093822, 0x299f31d0,
|
||||
0x082efa98, 0xec4e6c89, 0x452821e6, 0x38d01377, 0xbe5466cf, 0x34e90c6c,
|
||||
0xc0ac29b7, 0xc97c50dd, 0x3f84d5b5, 0xb5470917, 0x9216d5d9, 0x8979fb1b,
|
||||
}
|
|
@ -20,13 +20,15 @@ func (c *Sys) ListPolicies() ([]string, error) {
|
|||
func (c *Sys) GetPolicy(name string) (string, error) {
|
||||
r := c.c.NewRequest("GET", fmt.Sprintf("/v1/sys/policy/%s", name))
|
||||
resp, err := c.c.RawRequest(r)
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
if resp != nil {
|
||||
defer resp.Body.Close()
|
||||
if resp.StatusCode == 404 {
|
||||
return "", nil
|
||||
}
|
||||
}
|
||||
if err != nil {
|
||||
return "", err
|
||||
}
|
||||
|
||||
var result getPoliciesResp
|
||||
err = resp.DecodeJSON(&result)
|
||||
|
|
|
@ -2,6 +2,7 @@ package appId
|
|||
|
||||
import (
|
||||
"crypto/sha1"
|
||||
"crypto/subtle"
|
||||
"encoding/hex"
|
||||
"fmt"
|
||||
"net"
|
||||
|
@ -82,8 +83,11 @@ func (b *backend) pathLogin(
|
|||
|
||||
// Verify that the app is in the list
|
||||
found := false
|
||||
appIdBytes := []byte(appId)
|
||||
for _, app := range strings.Split(apps, ",") {
|
||||
if strings.TrimSpace(app) == appId {
|
||||
match := []byte(strings.TrimSpace(app))
|
||||
// Protect against a timing attack with the app_id comparison
|
||||
if subtle.ConstantTimeCompare(match, appIdBytes) == 1 {
|
||||
found = true
|
||||
}
|
||||
}
|
||||
|
|
|
@ -1,11 +1,13 @@
|
|||
package userpass
|
||||
|
||||
import (
|
||||
"crypto/subtle"
|
||||
"strings"
|
||||
"time"
|
||||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func pathLogin(b *backend) *framework.Path {
|
||||
|
@ -35,16 +37,30 @@ func pathLogin(b *backend) *framework.Path {
|
|||
func (b *backend) pathLogin(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
username := strings.ToLower(d.Get("name").(string))
|
||||
password := d.Get("password").(string)
|
||||
|
||||
// Get the user and validate auth
|
||||
user, err := b.User(req.Storage, username)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
if user == nil || user.Password != d.Get("password").(string) {
|
||||
if user == nil {
|
||||
return logical.ErrorResponse("unknown username or password"), nil
|
||||
}
|
||||
|
||||
// Check for a password match. Check for a hash collision for Vault 0.2+,
|
||||
// but handle the older legacy passwords with a constant time comparison.
|
||||
passwordBytes := []byte(password)
|
||||
if user.PasswordHash != nil {
|
||||
if err := bcrypt.CompareHashAndPassword(user.PasswordHash, passwordBytes); err != nil {
|
||||
return logical.ErrorResponse("unknown username or password"), nil
|
||||
}
|
||||
} else {
|
||||
if subtle.ConstantTimeCompare([]byte(user.Password), passwordBytes) != 1 {
|
||||
return logical.ErrorResponse("unknown username or password"), nil
|
||||
}
|
||||
}
|
||||
|
||||
return &logical.Response{
|
||||
Auth: &logical.Auth{
|
||||
Policies: user.Policies,
|
||||
|
|
|
@ -5,6 +5,7 @@ import (
|
|||
|
||||
"github.com/hashicorp/vault/logical"
|
||||
"github.com/hashicorp/vault/logical/framework"
|
||||
"golang.org/x/crypto/bcrypt"
|
||||
)
|
||||
|
||||
func pathUsers(b *backend) *framework.Path {
|
||||
|
@ -85,14 +86,21 @@ func (b *backend) pathUserRead(
|
|||
func (b *backend) pathUserWrite(
|
||||
req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
|
||||
name := strings.ToLower(d.Get("name").(string))
|
||||
password := d.Get("password").(string)
|
||||
policies := strings.Split(d.Get("policies").(string), ",")
|
||||
for i, p := range policies {
|
||||
policies[i] = strings.TrimSpace(p)
|
||||
}
|
||||
|
||||
// Generate a hash of the password
|
||||
hash, err := bcrypt.GenerateFromPassword([]byte(password), bcrypt.DefaultCost)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
|
||||
// Store it
|
||||
entry, err := logical.StorageEntryJSON("user/"+name, &UserEntry{
|
||||
Password: d.Get("password").(string),
|
||||
PasswordHash: hash,
|
||||
Policies: policies,
|
||||
})
|
||||
if err != nil {
|
||||
|
@ -106,7 +114,14 @@ func (b *backend) pathUserWrite(
|
|||
}
|
||||
|
||||
type UserEntry struct {
|
||||
// Password is deprecated in Vault 0.2 in favor of
|
||||
// PasswordHash, but is retained for backwards compatibilty.
|
||||
Password string
|
||||
|
||||
// PasswordHash is a bcrypt hash of the password. This is
|
||||
// used instead of the actual password in Vault 0.2+.
|
||||
PasswordHash []byte
|
||||
|
||||
Policies []string
|
||||
}
|
||||
|
||||
|
|
|
@ -5,9 +5,9 @@ var GitCommit string
|
|||
var GitDescribe string
|
||||
|
||||
// The main version number that is being run at the moment.
|
||||
const Version = "0.2.0"
|
||||
const Version = "0.2.1"
|
||||
|
||||
// A pre-release marker for the version. If this is "" (empty string)
|
||||
// then it means that it is a final release. Otherwise, this is a pre-release
|
||||
// such as "dev" (in development), "beta", "rc1", etc.
|
||||
const VersionPrerelease = "rc"
|
||||
const VersionPrerelease = "dev"
|
||||
|
|
|
@ -125,6 +125,14 @@ func testBackend(t *testing.T, b Backend) {
|
|||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
|
||||
// Get should return the child
|
||||
out, err = b.Get("foo/bar")
|
||||
if err != nil {
|
||||
t.Fatalf("err: %v", err)
|
||||
}
|
||||
if out == nil {
|
||||
t.Fatalf("missing child")
|
||||
}
|
||||
}
|
||||
|
||||
func testBackend_ListPrefix(t *testing.T, b Backend) {
|
||||
|
|
|
@ -2,6 +2,7 @@ package physical
|
|||
|
||||
import (
|
||||
"fmt"
|
||||
"path/filepath"
|
||||
"sort"
|
||||
"strings"
|
||||
"sync"
|
||||
|
@ -11,6 +12,14 @@ import (
|
|||
"github.com/samuel/go-zookeeper/zk"
|
||||
)
|
||||
|
||||
const (
|
||||
// ZKNodeFilePrefix is prefixed to any "files" in ZooKeeper,
|
||||
// so that they do not collide with directory entries. Otherwise,
|
||||
// we cannot delete a file if the path is a full-prefix of another
|
||||
// key.
|
||||
ZKNodeFilePrefix = "_"
|
||||
)
|
||||
|
||||
// ZookeeperBackend is a physical backend that stores data at specific
|
||||
// prefix within Zookeeper. It is used in production situations as
|
||||
// it allows Vault to run on multiple machines in a highly-available manner.
|
||||
|
@ -89,24 +98,9 @@ func (c *ZookeeperBackend) ensurePath(path string, value []byte) error {
|
|||
return nil
|
||||
}
|
||||
|
||||
// deletePath is a helper that will recursively delete
|
||||
// a given path
|
||||
func (c *ZookeeperBackend) deletePath(path string) error {
|
||||
children, _, _ := c.client.Children(path)
|
||||
|
||||
for _, childPath := range children {
|
||||
err := c.deletePath(path + "/" + childPath)
|
||||
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
}
|
||||
err := c.client.Delete(path, -1)
|
||||
if err != nil {
|
||||
return err
|
||||
}
|
||||
|
||||
return nil
|
||||
// nodePath returns an etcd filepath based on the given key.
|
||||
func (c *ZookeeperBackend) nodePath(key string) string {
|
||||
return filepath.Join(c.path, filepath.Dir(key), ZKNodeFilePrefix+filepath.Base(key))
|
||||
}
|
||||
|
||||
// Put is used to insert or update an entry
|
||||
|
@ -114,7 +108,7 @@ func (c *ZookeeperBackend) Put(entry *Entry) error {
|
|||
defer metrics.MeasureSince([]string{"zookeeper", "put"}, time.Now())
|
||||
|
||||
// Attempt to set the full path
|
||||
fullPath := c.path + entry.Key
|
||||
fullPath := c.nodePath(entry.Key)
|
||||
_, err := c.client.Set(fullPath, entry.Value, -1)
|
||||
|
||||
// If we get ErrNoNode, we need to construct the path hierarchy
|
||||
|
@ -129,7 +123,7 @@ func (c *ZookeeperBackend) Get(key string) (*Entry, error) {
|
|||
defer metrics.MeasureSince([]string{"zookeeper", "get"}, time.Now())
|
||||
|
||||
// Attempt to read the full path
|
||||
fullPath := c.path + key
|
||||
fullPath := c.nodePath(key)
|
||||
value, _, err := c.client.Get(fullPath)
|
||||
|
||||
// Ignore if the node does not exist
|
||||
|
@ -156,8 +150,8 @@ func (c *ZookeeperBackend) Delete(key string) error {
|
|||
defer metrics.MeasureSince([]string{"zookeeper", "delete"}, time.Now())
|
||||
|
||||
// Delete the full path
|
||||
fullPath := c.path + key
|
||||
err := c.deletePath(fullPath)
|
||||
fullPath := c.nodePath(key)
|
||||
err := c.client.Delete(fullPath, -1)
|
||||
|
||||
// Mask if the node does not exist
|
||||
if err == zk.ErrNoNode {
|
||||
|
@ -182,14 +176,14 @@ func (c *ZookeeperBackend) List(prefix string) ([]string, error) {
|
|||
|
||||
children := []string{}
|
||||
for _, key := range result {
|
||||
children = append(children, key)
|
||||
|
||||
// Check if this entry has any child entries,
|
||||
// and append the slash which is what Vault depends on
|
||||
// for iteration
|
||||
nodeChildren, _, _ := c.client.Children(fullPath + "/" + key)
|
||||
if nodeChildren != nil && len(nodeChildren) > 0 {
|
||||
children = append(children, key+"/")
|
||||
} else {
|
||||
children = append(children, key[1:])
|
||||
}
|
||||
}
|
||||
sort.Strings(children)
|
||||
|
@ -229,7 +223,7 @@ func (i *ZookeeperHALock) Lock(stopCh <-chan struct{}) (<-chan struct{}, error)
|
|||
didLock := make(chan struct{})
|
||||
failLock := make(chan error, 1)
|
||||
releaseCh := make(chan bool, 1)
|
||||
lockpath := i.in.path + i.key
|
||||
lockpath := i.in.nodePath(i.key)
|
||||
go i.attemptLock(lockpath, didLock, failLock, releaseCh)
|
||||
|
||||
// Wait for lock acquisition, failure, or shutdown
|
||||
|
@ -327,7 +321,7 @@ func (i *ZookeeperHALock) Unlock() error {
|
|||
}
|
||||
|
||||
func (i *ZookeeperHALock) Value() (bool, string, error) {
|
||||
lockpath := i.in.path + i.key
|
||||
lockpath := i.in.nodePath(i.key)
|
||||
value, _, err := i.in.client.Get(lockpath)
|
||||
return (value != nil), string(value), err
|
||||
}
|
||||
|
|
|
@ -88,10 +88,4 @@ func TestZookeeperHABackend(t *testing.T) {
|
|||
t.Fatalf("zookeeper does not implement HABackend")
|
||||
}
|
||||
testHABackend(t, ha, ha)
|
||||
|
||||
err = client.Delete(randPath + "/foo", -1)
|
||||
if err != nil {
|
||||
t.Fatalf("err: failed to cleanup! %s", err)
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -236,6 +236,12 @@ func (b *AESGCMBarrier) ReloadKeyring() error {
|
|||
return fmt.Errorf("failed to check for keyring: %v", err)
|
||||
}
|
||||
|
||||
// Ensure that the keyring exists. This should never happen,
|
||||
// and indicates something really bad has happened.
|
||||
if out == nil {
|
||||
return fmt.Errorf("keyring unexpectedly missing")
|
||||
}
|
||||
|
||||
// Decrypt the barrier init key
|
||||
plain, err := b.decrypt(gcm, out.Value)
|
||||
if err != nil {
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
GIT
|
||||
remote: git://github.com/hashicorp/middleman-hashicorp.git
|
||||
revision: 7796ba44d303ac8e1b566e855e2766e6d0f695fc
|
||||
revision: 76f0f284ad44cea0457484ea83467192f02daf87
|
||||
specs:
|
||||
middleman-hashicorp (0.1.0)
|
||||
bootstrap-sass (~> 3.3)
|
||||
|
@ -11,6 +11,7 @@ GIT
|
|||
middleman-minify-html (~> 3.4)
|
||||
middleman-syntax (~> 2.0)
|
||||
rack-contrib (~> 1.2)
|
||||
rack-protection (~> 1.5)
|
||||
rack-rewrite (~> 1.5)
|
||||
rack-ssl-enforcer (~> 0.2)
|
||||
redcarpet (~> 3.2)
|
||||
|
@ -20,18 +21,18 @@ GIT
|
|||
GEM
|
||||
remote: https://rubygems.org/
|
||||
specs:
|
||||
activesupport (4.1.10)
|
||||
activesupport (4.1.12)
|
||||
i18n (~> 0.6, >= 0.6.9)
|
||||
json (~> 1.7, >= 1.7.7)
|
||||
minitest (~> 5.1)
|
||||
thread_safe (~> 0.1)
|
||||
tzinfo (~> 1.1)
|
||||
autoprefixer-rails (5.2.0)
|
||||
autoprefixer-rails (5.2.1)
|
||||
execjs
|
||||
json
|
||||
bootstrap-sass (3.3.4.1)
|
||||
bootstrap-sass (3.3.5.1)
|
||||
autoprefixer-rails (>= 5.0.0.1)
|
||||
sass (>= 3.2.19)
|
||||
sass (>= 3.3.0)
|
||||
builder (3.2.2)
|
||||
celluloid (0.16.0)
|
||||
timers (~> 4.0.0)
|
||||
|
@ -53,14 +54,15 @@ GEM
|
|||
sass (>= 3.3.0, < 3.5)
|
||||
compass-import-once (1.0.5)
|
||||
sass (>= 3.2, < 3.5)
|
||||
daemons (1.2.2)
|
||||
daemons (1.2.3)
|
||||
em-websocket (0.5.1)
|
||||
eventmachine (>= 0.12.9)
|
||||
http_parser.rb (~> 0.6.0)
|
||||
erubis (2.7.0)
|
||||
eventmachine (1.0.7)
|
||||
execjs (2.5.2)
|
||||
ffi (1.9.8)
|
||||
ffi (1.9.10)
|
||||
git-version-bump (0.15.1)
|
||||
haml (4.0.6)
|
||||
tilt
|
||||
hike (1.2.3)
|
||||
|
@ -71,11 +73,11 @@ GEM
|
|||
http_parser.rb (0.6.0)
|
||||
i18n (0.7.0)
|
||||
json (1.8.3)
|
||||
kramdown (1.7.0)
|
||||
kramdown (1.8.0)
|
||||
less (2.6.0)
|
||||
commonjs (~> 0.2.7)
|
||||
libv8 (3.16.14.7)
|
||||
listen (2.10.0)
|
||||
libv8 (3.16.14.11)
|
||||
listen (2.10.1)
|
||||
celluloid (~> 0.16.0)
|
||||
rb-fsevent (>= 0.9.3)
|
||||
rb-inotify (>= 0.9)
|
||||
|
@ -118,17 +120,20 @@ GEM
|
|||
middleman-core (~> 3.2)
|
||||
rouge (~> 1.0)
|
||||
minitest (5.7.0)
|
||||
multi_json (1.11.1)
|
||||
multi_json (1.11.2)
|
||||
padrino-helpers (0.12.5)
|
||||
i18n (~> 0.6, >= 0.6.7)
|
||||
padrino-support (= 0.12.5)
|
||||
tilt (~> 1.4.1)
|
||||
padrino-support (0.12.5)
|
||||
activesupport (>= 3.1)
|
||||
rack (1.6.1)
|
||||
rack-contrib (1.2.0)
|
||||
rack (>= 0.9.1)
|
||||
rack-livereload (0.3.15)
|
||||
rack (1.6.4)
|
||||
rack-contrib (1.3.0)
|
||||
git-version-bump (~> 0.15)
|
||||
rack (~> 1.4)
|
||||
rack-livereload (0.3.16)
|
||||
rack
|
||||
rack-protection (1.5.3)
|
||||
rack
|
||||
rack-rewrite (1.5.1)
|
||||
rack-ssl-enforcer (0.2.8)
|
||||
|
@ -137,11 +142,11 @@ GEM
|
|||
rb-fsevent (0.9.5)
|
||||
rb-inotify (0.9.5)
|
||||
ffi (>= 0.5.0)
|
||||
redcarpet (3.3.1)
|
||||
ref (1.0.5)
|
||||
rouge (1.9.0)
|
||||
sass (3.4.14)
|
||||
sprockets (2.12.3)
|
||||
redcarpet (3.3.2)
|
||||
ref (2.0.0)
|
||||
rouge (1.9.1)
|
||||
sass (3.4.16)
|
||||
sprockets (2.12.4)
|
||||
hike (~> 1.2)
|
||||
multi_json (~> 1.0)
|
||||
rack (~> 1.0)
|
||||
|
@ -177,4 +182,4 @@ DEPENDENCIES
|
|||
middleman-hashicorp!
|
||||
|
||||
BUNDLED WITH
|
||||
1.10.3
|
||||
1.10.5
|
||||
|
|
|
@ -3,6 +3,17 @@ require "rack/contrib/not_found"
|
|||
require "rack/contrib/response_headers"
|
||||
require "rack/contrib/static_cache"
|
||||
require "rack/contrib/try_static"
|
||||
require "rack/protection"
|
||||
|
||||
# Protect against various bad things
|
||||
use Rack::Protection::JsonCsrf
|
||||
use Rack::Protection::RemoteReferrer
|
||||
use Rack::Protection::HttpOrigin
|
||||
use Rack::Protection::EscapedParams
|
||||
use Rack::Protection::XSSHeader
|
||||
use Rack::Protection::FrameOptions
|
||||
use Rack::Protection::PathTraversal
|
||||
use Rack::Protection::IPSpoofing
|
||||
|
||||
# Properly compress the output if the client can handle it.
|
||||
use Rack::Deflater
|
||||
|
|
|
@ -85,7 +85,7 @@ Demo.DemoStepController = Ember.ObjectController.extend({
|
|||
this.set('fullscreen', true);
|
||||
break;
|
||||
case "help":
|
||||
this.get('controllers.demo').appendLog('You can use `vault help <command>` ' +
|
||||
this.get('controllers.demo').appendLog('You can use `vault path-help <command>` ' +
|
||||
'to learn more about specific Vault commands, or `next` ' +
|
||||
'and `previous` to navigate. Or, `fu` to go fullscreen.', false);
|
||||
break;
|
||||
|
|
|
@ -89,7 +89,7 @@ token/ token token based credentials
|
|||
|
||||
To use the App ID auth backend, an operator must configure it with
|
||||
the set of App IDs, user IDs, and the mapping between them. An
|
||||
example is shown below, use `vault help` for more details.
|
||||
example is shown below, use `vault path-help` for more details.
|
||||
|
||||
```
|
||||
$ vault write auth/app-id/map/app-id/foo value=root display_name=foo
|
||||
|
|
|
@ -54,7 +54,7 @@ token/ token token based credentials
|
|||
|
||||
To use the "cert" auth backend, an operator must configure it with
|
||||
trusted certificates that are allowed to authenticate. An example is shown below.
|
||||
Use `vault help` for more details.
|
||||
Use `vault path-help` for more details.
|
||||
|
||||
```
|
||||
$ vault write auth/cert/certs/web display_name=web policies=web,prod certificate=@web-cert.pem lease=3600
|
||||
|
|
|
@ -83,7 +83,7 @@ token/ token token based credentials
|
|||
|
||||
To use the "ldap" auth backend, an operator must configure it with
|
||||
the address of the LDAP server that is to be used. An example is shown below.
|
||||
Use `vault help` for more details.
|
||||
Use `vault path-help` for more details.
|
||||
|
||||
```
|
||||
$ vault write auth/ldap/config url="ldap://ldap.forumsys.com" \
|
||||
|
|
|
@ -73,7 +73,7 @@ of the cookie should be "token" and the value should be the token.
|
|||
If not specified, defaults to all the policies of the calling token.
|
||||
</li>
|
||||
<li>
|
||||
<span class="param">metadata</span>
|
||||
<span class="param">meta</span>
|
||||
<span class="param-flags">optional</span>
|
||||
A map of string to string valued metadata. This is passed through
|
||||
to the audit backends.
|
||||
|
@ -88,7 +88,8 @@ of the cookie should be "token" and the value should be the token.
|
|||
<span class="param">lease</span>
|
||||
<span class="param-flags">optional</span>
|
||||
The lease period of the token, provided as "1h", where hour is
|
||||
the largest suffix. If not provided, the token is valid indefinitely.
|
||||
the largest suffix. If not provided, the token is valid for the default
|
||||
lease duration (30 days), or indefinitely if the root policy is used.
|
||||
</li>
|
||||
<li>
|
||||
<span class="param">display_name</span>
|
||||
|
|
|
@ -80,7 +80,7 @@ userpass/ userpass
|
|||
|
||||
To use the "userpass" auth backend, an operator must configure it with
|
||||
users that are allowed to authenticate. An example is shown below.
|
||||
Use `vault help` for more details.
|
||||
Use `vault path-help` for more details.
|
||||
|
||||
```
|
||||
$ vault write auth/userpass/users/mitchellh password=foo policies=root
|
||||
|
|
|
@ -1,7 +1,7 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Help"
|
||||
sidebar_current: "docs-commands-help"
|
||||
page_title: "Path Help"
|
||||
sidebar_current: "docs-commands-path-help"
|
||||
description: |-
|
||||
The Vault CLI has a built-in help system that can be used to get help for not only the CLI itself, but also any paths that the CLI can be used with within Vault.
|
||||
---
|
||||
|
@ -9,7 +9,7 @@ description: |-
|
|||
# Help
|
||||
|
||||
In addition to standard CLI help using the `-h` or `-help` flag for
|
||||
commands, Vault has a built-in `help` command that can be used to get
|
||||
commands, Vault has a built-in `path-help` command that can be used to get
|
||||
help for specific paths within Vault. These paths are used with the
|
||||
API or `read, write, delete` commands in order to interact with Vault.
|
||||
|
||||
|
@ -24,25 +24,25 @@ properly to execute this command to look up paths.
|
|||
|
||||
## Discovering Paths
|
||||
|
||||
Before using `help`, it is important to understand "paths" within Vault.
|
||||
Before using `path-help`, it is important to understand "paths" within Vault.
|
||||
Paths are the parameters used for `vault read`, `vault write`, etc. An
|
||||
example path is `secret/foo`, or `aws/config/root`. The paths available
|
||||
depend on the mounted secret backends. Because of this, the interactive
|
||||
help is an indispensable tool to finding what paths are supported.
|
||||
|
||||
To discover what paths are supported, use `vault help <mount point>`.
|
||||
To discover what paths are supported, use `vault path-help <mount point>`.
|
||||
For example, if you mounted the AWS secret backend, you can use
|
||||
`vault help aws` to find the paths supported by that backend. The paths
|
||||
`vault path-help aws` to find the paths supported by that backend. The paths
|
||||
will be shown with regular expressions, which can make them hard to
|
||||
parse, but they're also extremely exact.
|
||||
|
||||
You can try it right away with any Vault with `vault help secret`, since
|
||||
You can try it right away with any Vault with `vault path-help secret`, since
|
||||
`secret` is always mounted initially. The output from this command is shown
|
||||
below and contains both a description of what that backend is for, along with
|
||||
the paths it supports.
|
||||
|
||||
```
|
||||
$ vault help secret
|
||||
$ vault path-help secret
|
||||
## DESCRIPTION
|
||||
|
||||
The generic backend reads and writes arbitrary secrets to the backend.
|
||||
|
@ -69,11 +69,11 @@ you may or may not be able to access certain paths.
|
|||
## Single Path
|
||||
|
||||
Once you've found a path you like, you can learn more about it by
|
||||
using `vault help <path>` where "path" is a path that matches one of the
|
||||
using `vault path-help <path>` where "path" is a path that matches one of the
|
||||
regular expressions from the backend help.
|
||||
|
||||
Or, if you saw an example online with `vault write` or some similar
|
||||
command, you can plug that directly into `vault help` to learn about it
|
||||
command, you can plug that directly into `vault path-help` to learn about it
|
||||
(assuming you have the proper backends mounted!).
|
||||
|
||||
For example, below we get the help for a single secret in the `secret/`
|
||||
|
@ -81,7 +81,7 @@ mount point. The help shows the operations that that path supports, the
|
|||
parameters it takes (for write), and a description of that specific path.
|
||||
|
||||
```
|
||||
$ vault help secret/password
|
||||
$ vault path-help secret/password
|
||||
Request: password
|
||||
Matching Route: ^.*$
|
||||
|
||||
|
|
|
@ -21,8 +21,8 @@ organization. For example, you can authenticate using GitHub, certs, etc.
|
|||
|
||||
There are many authentication backends available for Vault. They
|
||||
are enabled using `vault auth-enable`. After they're enabled, you can
|
||||
learn more about them using `vault help auth/<name>`. For example,
|
||||
if you enable GitHub, you can use `vault help auth/github` to learn more
|
||||
learn more about them using `vault path-help auth/<name>`. For example,
|
||||
if you enable GitHub, you can use `vault path-help auth/github` to learn more
|
||||
about how to configure it and login.
|
||||
|
||||
Multiple authentication backends can be enabled, but only one is required
|
||||
|
@ -76,11 +76,11 @@ must be used.
|
|||
#### Via the API
|
||||
|
||||
API authentication is generally used for machine authentication. Each
|
||||
auth backend implements is own login endpoint. Use the `vault help`
|
||||
auth backend implements is own login endpoint. Use the `vault path-help`
|
||||
mechanism to find the proper endpoint.
|
||||
|
||||
For example, the GitHub login endpoint is located at `auth/github/login`.
|
||||
And to determine the arguments needed, `vault help auth/github/login` can
|
||||
And to determine the arguments needed, `vault path-help auth/github/login` can
|
||||
be used.
|
||||
|
||||
## Auth Leases
|
||||
|
|
|
@ -67,11 +67,11 @@ durability, etc.
|
|||
backend supports HA. It is the most recommended backend for Vault
|
||||
and has been shown to work at high scale under heavy load.
|
||||
|
||||
* `zookeeper` - Store data within [Zookeeper](https://zookeeper.apache.org/).
|
||||
This backend does not support HA.
|
||||
|
||||
* `etcd` - Store data within [etcd](https://coreos.com/etcd/).
|
||||
This backend does not support HA.
|
||||
This backend supports HA.
|
||||
|
||||
* `zookeeper` - Store data within [Zookeeper](https://zookeeper.apache.org/).
|
||||
This backend supports HA.
|
||||
|
||||
* `s3` - Store data within an S3 bucket [S3](http://aws.amazon.com/s3/).
|
||||
This backend does not support HA.
|
||||
|
|
|
@ -1,127 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Creating Modules"
|
||||
sidebar_current: "docs-modules-create"
|
||||
description: |-
|
||||
Creating modules in Vault is easy. You may want to do this to better organize your code, to make a reusable component, or just to learn more about Vault. For any reason, if you already know the basics of Vault, creating a module is a piece of cake.
|
||||
---
|
||||
|
||||
# Creating Modules
|
||||
|
||||
Creating modules in Vault is easy. You may want to do this to better
|
||||
organize your code, to make a reusable component, or just to learn more about
|
||||
Vault. For any reason, if you already know the basics of Vault,
|
||||
creating a module is a piece of cake.
|
||||
|
||||
Modules in Vault are just folders with Vault files. In fact,
|
||||
when you run `vault apply`, the current working directory holding
|
||||
the Vault files you're applying comprise what is called the
|
||||
_root module_. It itself is a valid module.
|
||||
|
||||
Therefore, you can enter the source of any module, run `vault apply`,
|
||||
and expect it to work (assuming you satisfy the required variables, if any).
|
||||
|
||||
## An Example
|
||||
|
||||
Within a folder containing Vault configurations, create a subfolder
|
||||
"child". In this subfolder, make one empty "main.tf" file. Then, back in
|
||||
the root folder containing the "child" folder, add this to one of the
|
||||
Vault files:
|
||||
|
||||
```javascript
|
||||
module "child" {
|
||||
source = "./child"
|
||||
}
|
||||
```
|
||||
|
||||
This will work. You've created your first module! You can add resources
|
||||
to the child module to see how that interaction works.
|
||||
|
||||
Note: Prior to running the above, you'll have to run
|
||||
[the get command](/docs/commands/get.html) for Vault to sync
|
||||
your modules. This should be instant since the module is just a local path.
|
||||
|
||||
## Inputs/Outputs
|
||||
|
||||
To make modules more useful than simple isolated containers of Vault
|
||||
configurations, modules can be configured and also have outputs that can be
|
||||
consumed by the configuration using the module.
|
||||
|
||||
Inputs of a module are [variables](/docs/configuration/variables.html)
|
||||
and outputs are [outputs](/docs/configuration/outputs.html). There is no
|
||||
special syntax to define these, they're defined just like any other
|
||||
variables or outputs.
|
||||
|
||||
In the "child" module we created above, add the following:
|
||||
|
||||
```javascript
|
||||
variable "memory" {}
|
||||
|
||||
output "received" {
|
||||
value = "${var.memory}"
|
||||
}
|
||||
```
|
||||
|
||||
This will create a required variable "memory" and then an output "received"
|
||||
that will simply be the value of the memory variable.
|
||||
|
||||
You can then configure the module and use the output like so:
|
||||
|
||||
```javascript
|
||||
module "child" {
|
||||
source = "./child"
|
||||
|
||||
memory = "1G"
|
||||
}
|
||||
|
||||
output "child_memory" {
|
||||
value = "${module.child.received}"
|
||||
}
|
||||
```
|
||||
|
||||
If you run `apply`, you'll again see that this works.
|
||||
|
||||
And that is all there is to it. Variables and outputs are used to configure
|
||||
modules and provide results. Resources within a module are isolated,
|
||||
and the whole thing is managed as a single unit.
|
||||
|
||||
## Paths and Embedded Files
|
||||
|
||||
It is sometimes useful to embed files within the module that aren't
|
||||
Vault configuration files, such as a script to provision a resource
|
||||
or a file to upload.
|
||||
|
||||
In these cases, you can't use a relative path, since paths in Vault
|
||||
are generally relative to the working directory that Vault was executed
|
||||
from. Instead, you want to use a module-relative path. To do this, use
|
||||
the [path interpolated variables](/docs/configuration/interpolation.html).
|
||||
|
||||
An example is shown below:
|
||||
|
||||
```javascript
|
||||
resource "aws_instance" "server" {
|
||||
...
|
||||
|
||||
provisioner "remote-exec" {
|
||||
script = "${path.module}/script.sh"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
In the above, we use `${path.module}` to get a module-relative path. This
|
||||
is usually what you'll want in any case.
|
||||
|
||||
## Nested Modules
|
||||
|
||||
You can use a module within a module just like you would anywhere else.
|
||||
This module will be hidden from the root user, so you'll have re-expose any
|
||||
variables if you need to, as well as outputs.
|
||||
|
||||
The [get command](/docs/commands/get.html) will automatically get all
|
||||
nested modules as well.
|
||||
|
||||
You don't have to worry about conflicting versions of modules, since
|
||||
Vault builds isolated subtrees of all dependencies. For example,
|
||||
one module might use version 1.0 of module "foo" and another module
|
||||
might use version 2.0 of module "foo", and this would all work fine
|
||||
within Vault since the modules are created separately.
|
|
@ -1,17 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Modules"
|
||||
sidebar_current: "docs-modules"
|
||||
description: |-
|
||||
Modules in Vault are self-contained packages of Vault configurations that are managed as a group. Modules are used to create reusable components in Vault as well as for basic code organization.
|
||||
---
|
||||
|
||||
# Modules
|
||||
|
||||
Modules in Vault are self-contained packages of Vault configurations
|
||||
that are managed as a group. Modules are used to create reusable components
|
||||
in Vault as well as for basic code organization.
|
||||
|
||||
Modules are very easy to both use and create. Depending on what you're
|
||||
looking to do first, use the navigation on the left to dive into how
|
||||
modules work.
|
|
@ -1,205 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Module Sources"
|
||||
sidebar_current: "docs-modules-sources"
|
||||
description: |-
|
||||
As documented in usage, the only required parameter when using a module is the `source` parameter which tells Vault where the module can be found and what constraints to put on the module if any (such as branches for Git, versions, etc.).
|
||||
---
|
||||
|
||||
# Module Sources
|
||||
|
||||
As documented in [usage](/docs/modules/usage.html), the only required
|
||||
parameter when using a module is the `source` parameter which tells Vault
|
||||
where the module can be found and what constraints to put on the module
|
||||
if any (such as branches for Git, versions, etc.).
|
||||
|
||||
Vault manages modules for you: it downloads them, organizes them
|
||||
on disk, checks for updates, etc. Vault uses this source parameter for
|
||||
the download/update of modules.
|
||||
|
||||
Vault supports the following sources:
|
||||
|
||||
* Local file paths
|
||||
|
||||
* GitHub
|
||||
|
||||
* BitBucket
|
||||
|
||||
* Generic Git, Mercurial repositories
|
||||
|
||||
* HTTP URLs
|
||||
|
||||
Each is documented further below.
|
||||
|
||||
## Local File Paths
|
||||
|
||||
The easiest source is the local file path. For maximum portability, this
|
||||
should be a relative file path into a subdirectory. This allows you to
|
||||
organize your Vault configuration into modules within one repository,
|
||||
for example.
|
||||
|
||||
An example is shown below:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "./consul"
|
||||
}
|
||||
```
|
||||
|
||||
Updates for file paths are automatic: when "downloading" the module
|
||||
using the [get command](/docs/commands/get.html), Vault will create
|
||||
a symbolic link to the original directory. Therefore, any changes are
|
||||
automatically instantly available.
|
||||
|
||||
## GitHub
|
||||
|
||||
Vault will automatically recognize GitHub URLs and turn them into
|
||||
the proper Git repository. The syntax is simple:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "github.com/hashicorp/example"
|
||||
}
|
||||
```
|
||||
|
||||
Subdirectories within the repository can also be referenced:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "github.com/hashicorp/example//subdir"
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The double-slash is important. It is what tells Vault that
|
||||
that is the separator for a subdirectory, and not part of the repository
|
||||
itself.
|
||||
|
||||
GitHub source URLs will require that Git is installed on your system
|
||||
and that you have the proper access to the repository.
|
||||
|
||||
You can use the same parameters to GitHub repositories as you can generic
|
||||
Git repositories (such as tags or branches). See the documentation for generic
|
||||
Git repositories for more information.
|
||||
|
||||
## BitBucket
|
||||
|
||||
Vault will automatically recognize BitBucket URLs and turn them into
|
||||
the proper Git or Mercurial repository. An example:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "bitbucket.org/hashicorp/example"
|
||||
}
|
||||
```
|
||||
|
||||
Subdirectories within the repository can also be referenced:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "bitbucket.org/hashicorp/example//subdir"
|
||||
}
|
||||
```
|
||||
|
||||
**Note:** The double-slash is important. It is what tells Vault that
|
||||
that is the separator for a subdirectory, and not part of the repository
|
||||
itself.
|
||||
|
||||
BitBucket URLs will require that Git or Mercurial is installed on your
|
||||
system, depending on the source URL.
|
||||
|
||||
## Generic Git Repository
|
||||
|
||||
Generic Git repositories are also supported. The value of `source` in this
|
||||
case should be a complete Git-compatible URL. Using Git requires that
|
||||
Git is installed on your system. Example:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "git://hashicorp.com/module.git"
|
||||
}
|
||||
```
|
||||
|
||||
You can also use protocols such as HTTP or SSH, but you'll have to hint
|
||||
to Vault (using the forced source type syntax documented below) to use
|
||||
Git:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "git::https://hashicorp.com/module.git"
|
||||
}
|
||||
```
|
||||
|
||||
URLs for Git repositories (of any protocol) support the following query
|
||||
parameters:
|
||||
|
||||
* `ref` - The ref to checkout. This can be a branch, tag, commit, etc.
|
||||
|
||||
An example of using these parameters is shown below:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "git::https://hashicorp.com/module.git?ref=master"
|
||||
}
|
||||
```
|
||||
|
||||
## Generic Mercurial Repository
|
||||
|
||||
Generic Mercurial repositories are supported. The value of `source` in this
|
||||
case should be a complete Mercurial-compatible URL. Using Mercurial requires that
|
||||
Mercurial is installed on your system. Example:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "hg::http://hashicorp.com/module.hg"
|
||||
}
|
||||
```
|
||||
|
||||
In the case of above, we used the forced source type syntax documented below.
|
||||
Mercurial repositories require this.
|
||||
|
||||
URLs for Mercurial repositories (of any protocol) support the following query
|
||||
parameters:
|
||||
|
||||
* `rev` - The rev to checkout. This can be a branch, tag, commit, etc.
|
||||
|
||||
## HTTP URLs
|
||||
|
||||
Any HTTP endpoint can serve up Vault modules. For HTTP URLs (SSL is
|
||||
supported, as well), Vault will make a GET request to the given URL.
|
||||
An additional GET parameter `vault-get=1` will be appended, allowing
|
||||
you to optionally render the page differently when Vault is requesting it.
|
||||
|
||||
Vault then looks for the resulting module URL in the following order.
|
||||
|
||||
First, if a header `X-Vault-Get` is present, then it should contain
|
||||
the source URL of the actual module. This will be used.
|
||||
|
||||
If the header isn't present, Vault will look for a `<meta>` tag
|
||||
with the name of "vault-get". The value will be used as the source
|
||||
URL.
|
||||
|
||||
## Forced Source Type
|
||||
|
||||
In a couple places above, we've referenced "forced source type." Forced
|
||||
source type is a syntax added to URLs that allow you to force a specific
|
||||
method for download/updating the module. It is used to disambiguate URLs.
|
||||
|
||||
For example, the source "http://hashicorp.com/foo.git" could just as
|
||||
easily be a plain HTTP URL as it might be a Git repository speaking the
|
||||
HTTP protocol. The forced source type syntax is used to force Vault
|
||||
one way or the other.
|
||||
|
||||
Example:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "git::http://hashicorp.com/foo.git"
|
||||
}
|
||||
```
|
||||
|
||||
The above will force Vault to get the module using Git, despite it
|
||||
being an HTTP URL.
|
||||
|
||||
If a forced source type isn't specified, Vault will match the exact
|
||||
protocol if it supports it. It will not try multiple methods. In the case
|
||||
above, it would've used the HTTP method.
|
|
@ -1,106 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Using Modules"
|
||||
sidebar_current: "docs-modules-usage"
|
||||
description: Using modules in Vault is very similar to defining resources.
|
||||
---
|
||||
|
||||
# Module Usage
|
||||
|
||||
Using modules in Vault is very similar to defining resources:
|
||||
|
||||
```javascript
|
||||
module "consul" {
|
||||
source = "github.com/hashicorp/consul/vault/aws"
|
||||
servers = 3
|
||||
}
|
||||
```
|
||||
|
||||
You can view the full documentation for the syntax of configuring
|
||||
modules [here](/docs/configuration/modules.html).
|
||||
|
||||
As you can see, it is very similar to defining resources, with the exception
|
||||
that we don't specify a type, and just a name. This name can be used elsewhere
|
||||
in the configuration to reference the module and its variables.
|
||||
|
||||
The existence of the above configuration will tell Vault to create
|
||||
the resources in the "consul" module which can be found on GitHub with the
|
||||
given URL. Just like a resource, the module configuration can be deleted
|
||||
to remove the module.
|
||||
|
||||
## Source
|
||||
|
||||
The only required configuration key is the `source` parameter. The value of
|
||||
this tells Vault where the module can be downloaded, updated, etc.
|
||||
Vault comes with support for a variety of module sources. These
|
||||
are documented on a [separate page](/docs/modules/sources.html).
|
||||
|
||||
Prior to running any command such as `plan` with a configuration that
|
||||
uses modules, you'll have to [get](/docs/commands/get.html) the modules.
|
||||
This is done using the [get command](/docs/commands/get.html).
|
||||
|
||||
```
|
||||
$ vault get
|
||||
...
|
||||
```
|
||||
|
||||
This command will download the modules if they haven't been already.
|
||||
By default, the command will not check for updates, so it is safe (and fast)
|
||||
to run multiple times. You can use the `-u` flag to check and download
|
||||
updates.
|
||||
|
||||
## Configuration
|
||||
|
||||
The parameters used to configure modules, such as the `servers` parameter
|
||||
above, map directly to [variables](/docs/configuration/variables.html) within
|
||||
the module itself. Therefore, you can quickly discover all the configuration
|
||||
for a module by inspecting the source of it very easily.
|
||||
|
||||
Additionally, because these map directly to variables, they're always simple
|
||||
key/value pairs. Modules can't have complex variable inputs.
|
||||
|
||||
## Outputs
|
||||
|
||||
Modules can also specify their own [outputs](/docs/configuration/outputs.html).
|
||||
These outputs can be referenced in other places in your configuration.
|
||||
For example:
|
||||
|
||||
```javascript
|
||||
resource "aws_instance" "client" {
|
||||
ami = "ami-123456"
|
||||
instance_type = "m1.small"
|
||||
availability_zone = "${module.consul.server_availability_zone}"
|
||||
}
|
||||
```
|
||||
|
||||
This purposely is very similar to accessing resource attributes. But instead
|
||||
of mapping to a resource, the variable in this case maps to an output of
|
||||
a module.
|
||||
|
||||
Just like resources, this will create a dependency from the `aws_instance.client`
|
||||
resource to the module, so the module will be built first.
|
||||
|
||||
## Plans and Graphs
|
||||
|
||||
With modules, commands such as the [plan command](/docs/commands/plan.html)
|
||||
and
|
||||
[graph command](/docs/commands/graph.html) will show the module as a single
|
||||
unit by default. You can use the `-module-depth` parameter to expand this
|
||||
graph further.
|
||||
|
||||
For example, with a configuration similar to what we've built above, here
|
||||
is what the graph output looks like by default:
|
||||
|
||||
<div class="center">
|
||||
![Vault Module Graph](docs/module_graph.png)
|
||||
</div>
|
||||
|
||||
But if we set `-module-depth=-1`, the graph will look like this:
|
||||
|
||||
<div class="center">
|
||||
![Vault Expanded Module Graph](docs/module_graph_expand.png)
|
||||
</div>
|
||||
|
||||
Other commands work similarly with modules. Note that the `-module-depth`
|
||||
flag is purely a formatting flag; it doesn't affect what modules are created
|
||||
or not.
|
|
@ -1,54 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Provisioner Connections"
|
||||
sidebar_current: "docs-provisioners-connection"
|
||||
description: |-
|
||||
Many provisioners require access to the remote resource. For example, a provisioner may need to use ssh to connect to the resource.
|
||||
---
|
||||
|
||||
# Provisioner Connections
|
||||
|
||||
Many provisioners require access to the remote resource. For example,
|
||||
a provisioner may need to use ssh to connect to the resource.
|
||||
|
||||
Vault uses a number of defaults when connecting to a resource, but these
|
||||
can be overridden using `connection` block in either a `resource` or `provisioner`.
|
||||
Any `connection` information provided in a `resource` will apply to all the
|
||||
provisioners, but it can be scoped to a single provisioner as well. One use case
|
||||
is to have an initial provisioner connect as root to setup user accounts, and have
|
||||
subsequent provisioners connect as a user with more limited permissions.
|
||||
|
||||
## Example usage
|
||||
|
||||
```javascript
|
||||
# Copies the file as the root user using a password
|
||||
provisioner "file" {
|
||||
source = "conf/myapp.conf"
|
||||
destination = "/etc/myapp.conf"
|
||||
connection {
|
||||
user = "root"
|
||||
password = "${var.root_password}"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `type` - The connection type that should be used. This defaults to "ssh". The type
|
||||
of connection supported depends on the provisioner.
|
||||
|
||||
* `user` - The user that we should use for the connection. This defaults to "root".
|
||||
|
||||
* `password` - The password we should use for the connection.
|
||||
|
||||
* `key_file` - The SSH key to use for the connection. This takes preference over the
|
||||
password if provided.
|
||||
|
||||
* `host` - The address of the resource to connect to. This is provided by the provider.
|
||||
|
||||
* `port` - The port to connect to. This defaults to 22.
|
||||
|
||||
* `timeout` - The timeout to wait for the connection to become available. This defaults
|
||||
to 5 minutes. Should be provided as a string like "30s" or "5m".
|
|
@ -1,65 +0,0 @@
|
|||
---
|
||||
layout: "docs"
|
||||
page_title: "Provisioner: file"
|
||||
sidebar_current: "docs-provisioners-file"
|
||||
description: |-
|
||||
The `file` provisioner is used to copy files or directories from the machine executing Vault to the newly created resource. The `file` provisioner only supports `ssh` type connections.
|
||||
---
|
||||
|
||||
# File Provisioner
|
||||
|
||||
The `file` provisioner is used to copy files or directories from the machine
|
||||
executing Vault to the newly created resource. The `file` provisioner only
|
||||
supports `ssh` type [connections](/docs/provisioners/connection.html).
|
||||
|
||||
## Example usage
|
||||
|
||||
```javascript
|
||||
resource "aws_instance" "web" {
|
||||
...
|
||||
|
||||
# Copies the myapp.conf file to /etc/myapp.conf
|
||||
provisioner "file" {
|
||||
source = "conf/myapp.conf"
|
||||
destination = "/etc/myapp.conf"
|
||||
}
|
||||
|
||||
# Copies the configs.d folder to /etc/configs.d
|
||||
provisioner "file" {
|
||||
source = "conf/configs.d"
|
||||
destination = "/etc"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Argument Reference
|
||||
|
||||
The following arguments are supported:
|
||||
|
||||
* `source` - (Required) This is the source file or folder. It can be specified as relative
|
||||
to the current working directory or as an absolute path.
|
||||
|
||||
* `destination` - (Required) This is the destination path. It must be specified as an
|
||||
absolute path.
|
||||
|
||||
## Directory Uploads
|
||||
|
||||
The file provisioner is also able to upload a complete directory to the remote machine.
|
||||
When uploading a directory, there are a few important things you should know.
|
||||
|
||||
First, the destination directory must already exist. If you need to create it,
|
||||
use a remote-exec provisioner just prior to the file provisioner in order to create the directory.
|
||||
|
||||
Next, the existence of a trailing slash on the source path will determine whether the
|
||||
directory name will be embedded within the destination, or whether the destination will
|
||||
be created. An example explains this best:
|
||||
|
||||
If the source is `/foo` (no trailing slash), and the destination is `/tmp`, then the contents
|
||||
of `/foo` on the local machine will be uploaded to `/tmp/foo` on the remote machine. The
|
||||
`foo` directory on the remote machine will be created by Vault.
|
||||
|
||||
If the source, however, is `/foo/` (a trailing slash is present), and the destination is
|
||||
`/tmp`, then the contents of `/foo` will be uploaded directly into `/tmp` directly.
|
||||
|
||||
This behavior was adopted from the standard behavior of rsync. Note that under the covers,
|
||||
rsync may or may not be used.
|
|
@ -16,7 +16,7 @@ be generated on the fly, and are automatically revoked when the Vault
|
|||
lease is expired.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation
|
||||
on every path, use `vault help` after mounting the backend.
|
||||
on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
@ -143,7 +143,7 @@ The root credentials need permission to perform various IAM actions. These are t
|
|||
|
||||
Note that this policy example is unrelated to the policy you wrote to `aws/roles/deploy`. This policy example should be applied to the IAM user (or role) associated with the root credentials that you wrote to `aws/config/root`. You have to apply it yourself in IAM. The policy you wrote to `aws/roles/deploy` is the policy you want the AWS secret backend to apply to the temporary credentials it returns from `aws/creds/deploy`.
|
||||
|
||||
If you get stuck at any time, simply run `vault help aws` or with a subpath for
|
||||
If you get stuck at any time, simply run `vault path-help aws` or with a subpath for
|
||||
interactive help output.
|
||||
|
||||
## API
|
||||
|
|
|
@ -87,7 +87,7 @@ that trusted operators can manage the role definitions, and both
|
|||
users and applications are restricted in the credentials they are
|
||||
allowed to read.
|
||||
|
||||
If you get stuck at any time, simply run `vault help cassandra` or with a
|
||||
If you get stuck at any time, simply run `vault path-help cassandra` or with a
|
||||
subpath for interactive help output.
|
||||
|
||||
## API
|
||||
|
|
|
@ -15,7 +15,7 @@ The Consul secret backend for Vault generates
|
|||
API tokens dynamically based on Consul ACL policies.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation
|
||||
on every path, use `vault help` after mounting the backend.
|
||||
on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
|
@ -56,7 +56,7 @@ with regards to mounting:
|
|||
were created at. The data stored for the backend won't be deleted.
|
||||
|
||||
Once a secret backend is mounted, you can interact with it directly
|
||||
at its mount point according to its own API. You can use the `vault help`
|
||||
at its mount point according to its own API. You can use the `vault path-help`
|
||||
system to determine the paths it responds to.
|
||||
|
||||
## Barrier View
|
||||
|
|
|
@ -24,7 +24,7 @@ Vault makes use of its own internal revocation system to ensure that users
|
|||
become invalid within a reasonable time of the lease expiring.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation
|
||||
on every path, use `vault help` after mounting the backend.
|
||||
on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
|
@ -16,7 +16,7 @@ By keeping leases relatively short, revocations are less likely to be needed, ke
|
|||
|
||||
In addition, by allowing revocation to mostly be forgone, this backend allows for ephemeral certificates; certificates can be fetched and stored in memory upon application startup and discarded upon shutdown, without ever being written to disk.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation on every path, use `vault help` after mounting the backend.
|
||||
This page will show a quick start for this backend. For detailed documentation on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Considerations
|
||||
|
||||
|
@ -127,7 +127,7 @@ Vault has now generated a new set of credentials using the `example-dot-com` rol
|
|||
|
||||
Using ACLs, it is possible to restrict using the pki backend such that trusted operators can manage the role definitions, and both users and applications are restricted in the credentials they are allowed to read.
|
||||
|
||||
If you get stuck at any time, simply run `vault help pki` or with a subpath for interactive help output.
|
||||
If you get stuck at any time, simply run `vault path-help pki` or with a subpath for interactive help output.
|
||||
|
||||
## API
|
||||
|
||||
|
|
|
@ -25,7 +25,7 @@ Vault makes use both of its own internal revocation system as well as the
|
|||
become invalid within a reasonable time of the lease expiring.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation
|
||||
on every path, use `vault help` after mounting the backend.
|
||||
on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
@ -104,7 +104,7 @@ that trusted operators can manage the role definitions, and both
|
|||
users and applications are restricted in the credentials they are
|
||||
allowed to read.
|
||||
|
||||
If you get stuck at any time, simply run `vault help postgresql` or with a
|
||||
If you get stuck at any time, simply run `vault path-help postgresql` or with a
|
||||
subpath for interactive help output.
|
||||
|
||||
## API
|
||||
|
|
|
@ -30,7 +30,7 @@ Additionally, since encrypt/decrypt operations must enter the audit log,
|
|||
any decryption event is recorded.
|
||||
|
||||
This page will show a quick start for this backend. For detailed documentation
|
||||
on every path, use `vault help` after mounting the backend.
|
||||
on every path, use `vault path-help` after mounting the backend.
|
||||
|
||||
## Quick Start
|
||||
|
||||
|
|
|
@ -107,7 +107,7 @@ Vault is the single policy authority, unlike auth where you can mount
|
|||
multiple backends. Any mounted auth backend must map identities to these
|
||||
core policies.
|
||||
|
||||
Use the `vault help` system with your auth backend to determine how the
|
||||
Use the `vault path-help` system with your auth backend to determine how the
|
||||
mapping is done, since it is specific to each backend. For example,
|
||||
with GitHub, it is done by team using the `map/teams/<team>` path:
|
||||
|
||||
|
|
|
@ -96,7 +96,7 @@ Successfully enabled 'github' at 'github'!
|
|||
|
||||
Auth backends are mounted, just like secret backends, except auth
|
||||
backends are always prefixed with `auth/`. So the GitHub backend we just
|
||||
mounted can be accessed at `auth/github`. You can use `vault help` to
|
||||
mounted can be accessed at `auth/github`. You can use `vault path-help` to
|
||||
learn more about it.
|
||||
|
||||
With the backend enabled, we first have to configure it. For GitHub,
|
||||
|
|
|
@ -28,10 +28,10 @@ For this, we'll assume you have the AWS backend mounted. If not, mount
|
|||
it with `vault mount aws`. Even if you don't have an AWS account, you
|
||||
can still mount the AWS backend.
|
||||
|
||||
With the backend mounted, let's learn about it with `vault help`:
|
||||
With the backend mounted, let's learn about it with `vault path-help`:
|
||||
|
||||
```
|
||||
$ vault help aws
|
||||
$ vault path-help aws
|
||||
## DESCRIPTION
|
||||
|
||||
The AWS backend dynamically generates AWS access keys for a set of
|
||||
|
@ -62,7 +62,7 @@ you may or may not be able to access certain paths.
|
|||
Read and write IAM policies that access keys can be made for.
|
||||
```
|
||||
|
||||
The `vault help` command takes a path. By specifying the root path for
|
||||
The `vault path-help` command takes a path. By specifying the root path for
|
||||
a mount, it will give us the overview of that mount. Notice how the help
|
||||
not only contains a description, but also the exact regular expressions
|
||||
used to match routes for this backend along with a brief description
|
||||
|
@ -71,14 +71,14 @@ of what the route is for.
|
|||
## Path Help
|
||||
|
||||
After seeing the overview, we can continue to dive deeper by getting
|
||||
help for an individual path. For this, just use `vault help` with a path
|
||||
help for an individual path. For this, just use `vault path-help` with a path
|
||||
that would match the regular expression for that path. Note that the path
|
||||
doesn't need to actually _work_. For example, we'll get the help below
|
||||
for accessing `aws/creds/operator`, even though we never created the `operator`
|
||||
role:
|
||||
|
||||
```
|
||||
$ vault help aws/creds/operator
|
||||
$ vault path-help aws/creds/operator
|
||||
Request: creds/operator
|
||||
Matching Route: ^creds/(?P<name>\w+)$
|
||||
|
||||
|
|
|
@ -42,7 +42,7 @@ usage: vault [-version] [-help] <command> [args]
|
|||
|
||||
Common commands:
|
||||
delete Delete operation on secrets in Vault
|
||||
help Look up the help for a path
|
||||
path-help Look up the help for a path
|
||||
read Read data or secrets from Vault
|
||||
renew Renew the lease of a secret
|
||||
revoke Revoke a secret.
|
||||
|
@ -58,12 +58,15 @@ All other commands:
|
|||
auth-disable Disable an auth provider
|
||||
auth-enable Enable a new auth provider
|
||||
init Initialize a new Vault server
|
||||
key-status Provides information about the active encryption key
|
||||
mount Mount a logical backend
|
||||
mounts Lists mounted backends in Vault
|
||||
policies List the policies on the server
|
||||
policy-delete Delete a policy from the server
|
||||
policy-write Write a policy to the server
|
||||
rekey Rekeys Vault to generate new unseal keys
|
||||
remount Remount a secret backend to a new path
|
||||
rotate Rotates the backend encryption key used to persist data
|
||||
seal Seals the vault server
|
||||
token-create Create a new auth token
|
||||
token-renew Renew an auth token
|
||||
|
|
|
@ -79,8 +79,8 @@
|
|||
<li<%= sidebar_current("docs-commands") %>>
|
||||
<a href="/docs/commands/index.html">Commands (CLI)</a>
|
||||
<ul class="nav">
|
||||
<li<%= sidebar_current("docs-commands-help") %>>
|
||||
<a href="/docs/commands/help.html">Help</a>
|
||||
<li<%= sidebar_current("docs-commands-path-help") %>>
|
||||
<a href="/docs/commands/help.html">Path Help</a>
|
||||
</li>
|
||||
|
||||
<li<%= sidebar_current("docs-commands-readwrite") %>>
|
||||
|
|
Loading…
Reference in a new issue