Only allow listing on folders and enforce this. Also remove string sorting from Consul backend as it's not a requirement and other backends don't do it.

This commit is contained in:
Jeff Mitchell 2016-01-19 17:05:01 -05:00
parent e412ac8461
commit be1b4c8a46
6 changed files with 36 additions and 30 deletions

View File

@ -61,7 +61,7 @@ func TestList(t *testing.T) {
}
exp := map[string]interface{}{
"keys": []interface{}{"secret/foo", "secret/foo/"},
"keys": []interface{}{"foo", "foo/"},
}
if !reflect.DeepEqual(secret.Data, exp) {

View File

@ -3,7 +3,6 @@ package physical
import (
"fmt"
"io/ioutil"
"sort"
"strconv"
"strings"
"time"
@ -188,6 +187,13 @@ func (c *ConsulBackend) List(prefix string) ([]string, error) {
defer metrics.MeasureSince([]string{"consul", "list"}, time.Now())
scan := c.path + prefix
// The TrimPrefix call below will not work correctly if we have "//" at the
// end. This can happen in cases where you are e.g. listing the root of a
// prefix in a logical backend via "/" instead of ""
if strings.HasSuffix(scan, "//") {
scan = scan[:len(scan)-1]
}
c.permitPool.Acquire()
defer c.permitPool.Release()
@ -195,7 +201,7 @@ func (c *ConsulBackend) List(prefix string) ([]string, error) {
for idx, val := range out {
out[idx] = strings.TrimPrefix(val, scan)
}
sort.Strings(out)
return out, err
}

View File

@ -159,22 +159,24 @@ func (b *CubbyholeBackend) handleList(
return nil, fmt.Errorf("[ERR] cubbyhole list: Client token empty")
}
// Right now we only handle directories, so ensure it ends with /; however,
// some physical backends may not handle the "/" case properly, so only add
// it if we're not listing the root
path := req.Path
if path != "" && !strings.HasSuffix(path, "/") {
path = path + "/"
}
// List the keys at the prefix given by the request
keys, err := req.Storage.List(req.ClientToken + "/" + req.Path)
keys, err := req.Storage.List(req.ClientToken + "/" + path)
if err != nil {
return nil, err
}
// Strip the token; also, add the path for the same reason as in
// passthrough
// Strip the token
strippedKeys := make([]string, len(keys))
for i, key := range keys {
ret := strings.TrimPrefix(key, req.ClientToken+"/")
if ret == "" {
strippedKeys[i] = "."
} else {
strippedKeys[i] = ret
}
strippedKeys[i] = strings.TrimPrefix(key, req.ClientToken+"/")
}
// Generate the response

View File

@ -217,26 +217,22 @@ func (b *PassthroughBackend) handleDelete(
func (b *PassthroughBackend) handleList(
req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
// Right now we only handle directories, so ensure it ends with /; however,
// some physical backends may not handle the "/" case properly, so only add
// it if we're not listing the root
path := req.Path
if path != "" && !strings.HasSuffix(path, "/") {
path = path + "/"
}
// List the keys at the prefix given by the request
keys, err := req.Storage.List(req.Path)
keys, err := req.Storage.List(path)
if err != nil {
return nil, err
}
// A list of an actual key returns "" in the list, which can cause nasty
// things downstream with JSON conversion, including in Go. So, prepend the
// path and let users do what they wish.
retKeys := make([]string, len(keys))
for i, k := range keys {
if k == "" {
retKeys[i] = "."
} else {
retKeys[i] = k
}
}
// Generate the response
return logical.ListResponse(retKeys), nil
return logical.ListResponse(keys), nil
}
func (b *PassthroughBackend) GeneratesLeases() bool {

View File

@ -95,7 +95,8 @@ As expected, the value previously set is returned to us.
<dt>Description</dt>
<dd>
Returns a list of secret entries at the specified location. Folders are
suffixed with `/`.
suffixed with `/`. The input must be a folder; list on a file will not
return a value.
</dd>
<dt>Method</dt>
@ -119,7 +120,7 @@ As expected, the value previously set is returned to us.
{
"auth": null,
"data": {
"keys": ["cubbyhole/foo", "cubbyhole/foo/"]
"keys": ["foo", "foo/"]
},
"lease_duration": 2592000,
"lease_id": "",

View File

@ -108,7 +108,8 @@ seconds (one hour) as specified.
<dt>Description</dt>
<dd>
Returns a list of secret entries at the specified location. Folders are
suffixed with `/`.
suffixed with `/`. The input must be a folder; list on a file will not
return a value.
</dd>
<dt>Method</dt>
@ -132,7 +133,7 @@ seconds (one hour) as specified.
{
"auth": null,
"data": {
"keys": ["secret/foo", "secret/foo/"]
"keys": ["foo", "foo/"]
},
"lease_duration": 2592000,
"lease_id": "",