Пример #1
0
func (b *PassthroughBackend) handleRead(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	// Read the path
	out, err := req.Storage.Get(req.Path)
	if err != nil {
		return nil, fmt.Errorf("read failed: %v", err)
	}

	// Fast-path the no data case
	if out == nil {
		return nil, nil
	}

	// Decode the data
	var rawData map[string]interface{}

	if err := jsonutil.DecodeJSON(out.Value, &rawData); err != nil {
		return nil, fmt.Errorf("json decoding failed: %v", err)
	}

	var resp *logical.Response
	if b.generateLeases {
		// Generate the response
		resp = b.Secret("generic").Response(rawData, nil)
		resp.Secret.Renewable = false
	} else {
		resp = &logical.Response{
			Secret: &logical.Secret{},
			Data:   rawData,
		}
	}

	// Check if there is a ttl key
	var ttl string
	ttl, _ = rawData["ttl"].(string)
	if len(ttl) == 0 {
		ttl, _ = rawData["lease"].(string)
	}
	ttlDuration := b.System().DefaultLeaseTTL()
	if len(ttl) != 0 {
		dur, err := duration.ParseDurationSecond(ttl)
		if err == nil {
			ttlDuration = dur
		}

		if b.generateLeases {
			resp.Secret.Renewable = true
		}
	}

	resp.Secret.TTL = ttlDuration

	return resp, nil
}
Пример #2
0
// requestWrapTTL adds the WrapTTL value to the logical.Request if it
// exists.
func requestWrapTTL(r *http.Request, req *logical.Request) (*logical.Request, error) {
	// First try for the header value
	wrapTTL := r.Header.Get(WrapTTLHeaderName)
	if wrapTTL == "" {
		return req, nil
	}

	// If it has an allowed suffix parse as a duration string
	dur, err := duration.ParseDurationSecond(wrapTTL)
	if err != nil {
		return req, err
	}
	if int64(dur) < 0 {
		return req, fmt.Errorf("requested wrap ttl cannot be negative")
	}
	req.WrapTTL = dur

	return req, nil
}
Пример #3
0
func (c *TokenRenewCommand) Run(args []string) int {
	var format, increment string
	flags := c.Meta.FlagSet("token-renew", meta.FlagSetDefault)
	flags.StringVar(&format, "format", "table", "")
	flags.StringVar(&increment, "increment", "", "")
	flags.Usage = func() { c.Ui.Error(c.Help()) }
	if err := flags.Parse(args); err != nil {
		return 1
	}

	args = flags.Args()
	if len(args) > 2 {
		flags.Usage()
		c.Ui.Error(fmt.Sprintf(
			"\ntoken-renew expects at most two arguments"))
		return 1
	}

	var token string
	if len(args) > 0 {
		token = args[0]
	}

	var inc int
	// If both are specified prefer the argument
	if len(args) == 2 {
		increment = args[1]
	}
	if increment != "" {
		dur, err := duration.ParseDurationSecond(increment)
		if err != nil {
			c.Ui.Error(fmt.Sprintf("Invalid increment: %s", err))
			return 1
		}

		inc = int(dur / time.Second)
	}

	client, err := c.Client()
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error initializing client: %s", err))
		return 2
	}

	// If the given token is the same as the client's, use renew-self instead
	// as this is far more likely to be allowed via policy
	var secret *api.Secret
	if token == "" {
		secret, err = client.Auth().Token().RenewSelf(inc)
	} else {
		secret, err = client.Auth().Token().Renew(token, inc)
	}
	if err != nil {
		c.Ui.Error(fmt.Sprintf(
			"Error renewing token: %s", err))
		return 1
	}

	return OutputSecret(c.Ui, format, secret)
}
Пример #4
0
// handleTuneWriteCommon is used to set config settings on a path
func (b *SystemBackend) handleTuneWriteCommon(
	path string, data *framework.FieldData) (*logical.Response, error) {
	path = sanitizeMountPath(path)

	// Prevent protected paths from being changed
	for _, p := range untunableMounts {
		if strings.HasPrefix(path, p) {
			err := fmt.Errorf("[ERR] core: cannot tune '%s'", path)
			b.Backend.Logger().Print(err)
			return handleError(err)
		}
	}

	mountEntry := b.Core.router.MatchingMountEntry(path)
	if mountEntry == nil {
		err := fmt.Errorf("[ERR] sys: tune of path '%s' failed: no mount entry found", path)
		b.Backend.Logger().Print(err)
		return handleError(err)
	}

	var lock *sync.RWMutex
	switch {
	case strings.HasPrefix(path, "auth/"):
		lock = &b.Core.authLock
	default:
		lock = &b.Core.mountsLock
	}

	// Timing configuration parameters
	{
		var newDefault, newMax *time.Duration
		defTTL := data.Get("default_lease_ttl").(string)
		switch defTTL {
		case "":
		case "system":
			tmpDef := time.Duration(0)
			newDefault = &tmpDef
		default:
			tmpDef, err := duration.ParseDurationSecond(defTTL)
			if err != nil {
				return handleError(err)
			}
			newDefault = &tmpDef
		}

		maxTTL := data.Get("max_lease_ttl").(string)
		switch maxTTL {
		case "":
		case "system":
			tmpMax := time.Duration(0)
			newMax = &tmpMax
		default:
			tmpMax, err := duration.ParseDurationSecond(maxTTL)
			if err != nil {
				return handleError(err)
			}
			newMax = &tmpMax
		}

		if newDefault != nil || newMax != nil {
			lock.Lock()
			defer lock.Unlock()

			if err := b.tuneMountTTLs(path, &mountEntry.Config, newDefault, newMax); err != nil {
				b.Backend.Logger().Printf("[ERR] sys: tune of path '%s' failed: %v", path, err)
				return handleError(err)
			}
		}
	}

	return nil, nil
}
Пример #5
0
// handleMount is used to mount a new path
func (b *SystemBackend) handleMount(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	// Get all the options
	path := data.Get("path").(string)
	logicalType := data.Get("type").(string)
	description := data.Get("description").(string)

	path = sanitizeMountPath(path)

	var config MountConfig

	var apiConfig struct {
		DefaultLeaseTTL string `json:"default_lease_ttl" structs:"default_lease_ttl" mapstructure:"default_lease_ttl"`
		MaxLeaseTTL     string `json:"max_lease_ttl" structs:"max_lease_ttl" mapstructure:"max_lease_ttl"`
	}
	configMap := data.Get("config").(map[string]interface{})
	if configMap != nil && len(configMap) != 0 {
		err := mapstructure.Decode(configMap, &apiConfig)
		if err != nil {
			return logical.ErrorResponse(
					"unable to convert given mount config information"),
				logical.ErrInvalidRequest
		}
	}

	switch apiConfig.DefaultLeaseTTL {
	case "":
	case "system":
	default:
		tmpDef, err := duration.ParseDurationSecond(apiConfig.DefaultLeaseTTL)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
					"unable to parse default TTL of %s: %s", apiConfig.DefaultLeaseTTL, err)),
				logical.ErrInvalidRequest
		}
		config.DefaultLeaseTTL = tmpDef
	}

	switch apiConfig.MaxLeaseTTL {
	case "":
	case "system":
	default:
		tmpMax, err := duration.ParseDurationSecond(apiConfig.MaxLeaseTTL)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
					"unable to parse max TTL of %s: %s", apiConfig.MaxLeaseTTL, err)),
				logical.ErrInvalidRequest
		}
		config.MaxLeaseTTL = tmpMax
	}

	if config.MaxLeaseTTL != 0 && config.DefaultLeaseTTL > config.MaxLeaseTTL {
		return logical.ErrorResponse(
				"given default lease TTL greater than given max lease TTL"),
			logical.ErrInvalidRequest
	}

	if config.DefaultLeaseTTL > b.Core.maxLeaseTTL {
		return logical.ErrorResponse(fmt.Sprintf(
				"given default lease TTL greater than system max lease TTL of %d", int(b.Core.maxLeaseTTL.Seconds()))),
			logical.ErrInvalidRequest
	}

	if logicalType == "" {
		return logical.ErrorResponse(
				"backend type must be specified as a string"),
			logical.ErrInvalidRequest
	}

	// Create the mount entry
	me := &MountEntry{
		Table:       mountTableType,
		Path:        path,
		Type:        logicalType,
		Description: description,
		Config:      config,
	}

	// Attempt mount
	if err := b.Core.mount(me); err != nil {
		b.Backend.Logger().Printf("[ERR] sys: mount %s failed: %v", me.Path, err)
		return handleError(err)
	}

	return nil, nil
}
Пример #6
0
func (d *FieldData) getPrimitive(
	k string, schema *FieldSchema) (interface{}, bool, error) {
	raw, ok := d.Raw[k]
	if !ok {
		return nil, false, nil
	}

	switch schema.Type {
	case TypeBool:
		var result bool
		if err := mapstructure.WeakDecode(raw, &result); err != nil {
			return nil, true, err
		}
		return result, true, nil

	case TypeInt:
		var result int
		if err := mapstructure.WeakDecode(raw, &result); err != nil {
			return nil, true, err
		}
		return result, true, nil

	case TypeString:
		var result string
		if err := mapstructure.WeakDecode(raw, &result); err != nil {
			return nil, true, err
		}
		return result, true, nil

	case TypeMap:
		var result map[string]interface{}
		if err := mapstructure.WeakDecode(raw, &result); err != nil {
			return nil, true, err
		}
		return result, true, nil

	case TypeDurationSecond:
		var result int
		switch inp := raw.(type) {
		case nil:
			return nil, false, nil
		case int:
			result = inp
		case float32:
			result = int(inp)
		case float64:
			result = int(inp)
		case string:
			dur, err := duration.ParseDurationSecond(inp)
			if err != nil {
				return nil, true, err
			}
			result = int(dur.Seconds())
		case json.Number:
			valInt64, err := inp.Int64()
			if err != nil {
				return nil, true, err
			}
			result = int(valInt64)
		default:
			return nil, false, fmt.Errorf("invalid input '%v'", raw)
		}
		return result, true, nil

	default:
		panic(fmt.Sprintf("Unknown type: %s", schema.Type))
	}
}