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 }
// 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 }
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) }
// 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 }
// 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 }
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)) } }