func (b *backend) pathConnectionWrite(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	connValue := data.Get("value").(string)
	connURL := data.Get("connection_url").(string)
	if connURL == "" {
		if connValue == "" {
			return logical.ErrorResponse("connection_url parameter must be supplied"), nil
		} else {
			connURL = connValue
		}
	}

	maxOpenConns := data.Get("max_open_connections").(int)
	if maxOpenConns == 0 {
		maxOpenConns = 2
	}

	maxIdleConns := data.Get("max_idle_connections").(int)
	if maxIdleConns == 0 {
		maxIdleConns = maxOpenConns
	}
	if maxIdleConns > maxOpenConns {
		maxIdleConns = maxOpenConns
	}

	// Don't check the connection_url if verification is disabled
	verifyConnection := data.Get("verify_connection").(bool)
	if verifyConnection {
		// Verify the string
		db, err := sql.Open("postgres", connURL)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"Error validating connection info: %s", err)), nil
		}
		defer db.Close()
		if err := db.Ping(); err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"Error validating connection info: %s", err)), nil
		}
	}

	// Store it
	entry, err := logical.StorageEntryJSON("config/connection", connectionConfig{
		ConnectionString:   connValue,
		ConnectionURL:      connURL,
		MaxOpenConnections: maxOpenConns,
		MaxIdleConnections: maxIdleConns,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	// Reset the DB connection
	b.ResetDB()

	return nil, nil
}
Пример #2
0
func pathRolesRead(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)

	entry, err := req.Storage.Get("policy/" + name)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result roleConfig
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}

	if result.TokenType == "" {
		result.TokenType = "client"
	}

	// Generate the response
	resp := &logical.Response{
		Data: map[string]interface{}{
			"lease":      result.Lease.String(),
			"token_type": result.TokenType,
		},
	}
	if result.Policy != "" {
		resp.Data["policy"] = base64.StdEncoding.EncodeToString([]byte(result.Policy))
	}
	return resp, nil
}
Пример #3
0
// handleLookup handles the auth/token/lookup/id path for querying information about
// a particular token. This can be used to see which policies are applicable.
func (ts *TokenStore) handleLookup(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	id := data.Get("token").(string)
	if id == "" {
		id = req.ClientToken
	}
	if id == "" {
		return logical.ErrorResponse("missing token ID"), logical.ErrInvalidRequest
	}

	// Lookup the token
	out, err := ts.Lookup(id)
	if err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}

	// Fast-path the not found case
	if out == nil {
		return nil, nil
	}

	// Generate a response. We purposely omit the parent reference otherwise
	// you could escalade your privileges.
	resp := &logical.Response{
		Data: map[string]interface{}{
			"id":           out.ID,
			"policies":     out.Policies,
			"path":         out.Path,
			"meta":         out.Meta,
			"display_name": out.DisplayName,
			"num_uses":     out.NumUses,
		},
	}
	return resp, nil
}
Пример #4
0
// handleMountConfig is used to get config settings on a backend
func (b *SystemBackend) handleMountConfig(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	path := data.Get("path").(string)
	if path == "" {
		return logical.ErrorResponse(
				"path must be specified as a string"),
			logical.ErrInvalidRequest
	}

	if !strings.HasSuffix(path, "/") {
		path += "/"
	}

	sysView := b.Core.router.MatchingSystemView(path)
	if sysView == nil {
		err := fmt.Errorf("[ERR] sys: cannot fetch sysview for path %s", path)
		b.Backend.Logger().Print(err)
		return handleError(err)
	}

	resp := &logical.Response{
		Data: map[string]interface{}{
			"default_lease_ttl": int(sysView.DefaultLeaseTTL().Seconds()),
			"max_lease_ttl":     int(sysView.MaxLeaseTTL().Seconds()),
		},
	}

	return resp, nil
}
Пример #5
0
// handleRawRead is used to read directly from the barrier
func (b *SystemBackend) handleRawRead(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	path := data.Get("path").(string)

	// Prevent access of protected paths
	for _, p := range protectedPaths {
		if strings.HasPrefix(path, p) {
			err := fmt.Sprintf("cannot read '%s'", path)
			return logical.ErrorResponse(err), logical.ErrInvalidRequest
		}
	}

	entry, err := b.Core.barrier.Get(path)
	if err != nil {
		return handleError(err)
	}
	if entry == nil {
		return nil, nil
	}
	resp := &logical.Response{
		Data: map[string]interface{}{
			"value": string(entry.Value),
		},
	}
	return resp, nil
}
Пример #6
0
func (b *backend) pathLeaseWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	leaseRaw := d.Get("lease").(string)
	leaseMaxRaw := d.Get("lease_max").(string)

	lease, err := time.ParseDuration(leaseRaw)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Invalid lease: %s", err)), nil
	}
	leaseMax, err := time.ParseDuration(leaseMaxRaw)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Invalid lease: %s", err)), nil
	}

	// Store it
	entry, err := logical.StorageEntryJSON("config/lease", &configLease{
		Lease:    lease,
		LeaseMax: leaseMax,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #7
0
func (b *backend) pathSTSRead(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	policyName := d.Get("name").(string)
	ttl := int64(d.Get("ttl").(int))

	// Read the policy
	policy, err := req.Storage.Get("policy/" + policyName)
	if err != nil {
		return nil, fmt.Errorf("error retrieving role: %s", err)
	}
	if policy == nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Role '%s' not found", policyName)), nil
	}
	policyValue := string(policy.Value)
	if strings.HasPrefix(policyValue, "arn:") {
		return logical.ErrorResponse(
				"Can't generate STS credentials for a managed policy; use an inline policy instead"),
			logical.ErrInvalidRequest
	}
	// Use the helper to create the secret
	return b.secretTokenCreate(
		req.Storage,
		req.DisplayName, policyName, policyValue,
		&ttl,
	)
}
Пример #8
0
func (b *backend) pathCRLDelete(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := strings.ToLower(d.Get("name").(string))
	if name == "" {
		return logical.ErrorResponse(`"name" parameter cannot be empty`), nil
	}

	b.crlUpdateMutex.Lock()
	defer b.crlUpdateMutex.Unlock()

	_, ok := b.crls[name]
	if !ok {
		return logical.ErrorResponse(fmt.Sprintf(
			"no such CRL %s", name,
		)), nil
	}

	err := req.Storage.Delete("crls/" + name)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"error deleting crl %s: %v", name, err),
		), nil
	}

	delete(b.crls, name)

	return nil, nil
}
Пример #9
0
func (b *backend) pathCRLRead(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := strings.ToLower(d.Get("name").(string))
	if name == "" {
		return logical.ErrorResponse(`"name" parameter must be set`), nil
	}

	b.crlUpdateMutex.RLock()
	defer b.crlUpdateMutex.RUnlock()

	var retData map[string]interface{}

	crl, ok := b.crls[name]
	if !ok {
		return logical.ErrorResponse(fmt.Sprintf(
			"no such CRL %s", name,
		)), nil
	}

	retData = structs.New(&crl).Map()

	return &logical.Response{
		Data: retData,
	}, nil
}
Пример #10
0
func (b *backend) pathRoleUpdate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	name, err := validateName(data)
	if err != nil {
		return nil, err
	}
	tags := data.Get("tags").(string)
	rawVHosts := data.Get("vhosts").(string)

	var vhosts map[string]vhostPermission
	if len(rawVHosts) > 0 {
		err := json.Unmarshal([]byte(rawVHosts), &vhosts)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf("failed to unmarshal vhosts: %s", err)), nil
		}
	}

	// Store it
	entry, err := logical.StorageEntryJSON("role/"+name, &roleEntry{
		Tags:   tags,
		VHosts: vhosts,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #11
0
func pathConfigWrite(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	conf := config{
		Org: data.Get("organization").(string),
	}
	baseURL := data.Get("base_url").(string)
	if len(baseURL) != 0 {
		_, err := url.Parse(baseURL)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf("Error parsing given base_url: %s", err)), nil
		}
		conf.BaseURL = baseURL
	}

	entry, err := logical.StorageEntryJSON("config", conf)
	if err != nil {
		return nil, err
	}

	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #12
0
func pathPolicyDelete(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)

	p, err := getPolicy(req, name)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf("error looking up policy %s, error is %s", name, err)), err
	}
	if p == nil {
		return logical.ErrorResponse(fmt.Sprintf("no such key %s", name)), logical.ErrInvalidRequest
	}

	if !p.DeletionAllowed {
		return logical.ErrorResponse(fmt.Sprintf("'allow_deletion' config value is not set")), logical.ErrInvalidRequest
	}

	err = req.Storage.Delete("policy/" + name)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf("error deleting policy %s: %s", name, err)), err
	}

	err = req.Storage.Delete("archive/" + name)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf("error deleting archive %s: %s", name, err)), err
	}

	return nil, nil
}
Пример #13
0
func (b *backend) pathRoleCreate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	name := data.Get("name").(string)
	sql := data.Get("sql").(string)

	// Get our connection
	db, err := b.DB(req.Storage)
	if err != nil {
		return nil, err
	}

	// Test the query by trying to prepare it, HANA don't support grant if user not exist
	query := SplitSQL(sql)[0]
	stmt, err := db.Prepare(Query(query, map[string]string{
		"name":     "VAULT_TEST_ACCOUNT",
		"password": "******",
	}))
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Error testing query: %s", err)), nil
	}
	stmt.Close()

	// Store it
	entry, err := logical.StorageEntryJSON("role/"+name, &roleEntry{
		SQL: sql,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}
	return nil, nil
}
Пример #14
0
func (b *backend) pathConfigLeaseWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	ttlRaw := d.Get("ttl").(string)
	ttlMaxRaw := d.Get("ttl_max").(string)

	ttl, err := time.ParseDuration(ttlRaw)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Invalid ttl: %s", err)), nil
	}
	ttlMax, err := time.ParseDuration(ttlMaxRaw)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Invalid ttl_max: %s", err)), nil
	}

	// Store it
	entry, err := logical.StorageEntryJSON("config/lease", &configLease{
		TTL:    ttl,
		TTLMax: ttlMax,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #15
0
// pathRoleRead is used to view the information registered for a given AMI ID.
func (b *backend) pathRoleRead(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	roleEntry, err := b.lockedAWSRole(req.Storage, strings.ToLower(data.Get("role").(string)))
	if err != nil {
		return nil, err
	}
	if roleEntry == nil {
		return nil, nil
	}

	// Prepare the map of all the entries in the roleEntry.
	respData := structs.New(roleEntry).Map()

	// HMAC key belonging to the role should NOT be exported.
	delete(respData, "hmac_key")

	// Display the ttl in seconds.
	respData["ttl"] = roleEntry.TTL / time.Second
	// Display the max_ttl in seconds.
	respData["max_ttl"] = roleEntry.MaxTTL / time.Second

	return &logical.Response{
		Data: respData,
	}, nil
}
Пример #16
0
func (b *backend) pathConnectionWrite(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	connString := data.Get("value").(string)

	// Verify the string
	db, err := sql.Open("postgres", connString)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Error validating connection info: %s", err)), nil
	}
	defer db.Close()
	if err := db.Ping(); err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Error validating connection info: %s", err)), nil
	}

	// Store it
	entry, err := logical.StorageEntryJSON("config/connection", connString)
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	// Reset the DB connection
	b.ResetDB()

	return nil, nil
}
Пример #17
0
func pathPolicyRead(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)

	p, err := getPolicy(req, name)
	if err != nil {
		return nil, err
	}
	if p == nil {
		return nil, nil
	}

	// Return the response
	resp := &logical.Response{
		Data: map[string]interface{}{
			"name":                   p.Name,
			"cipher_mode":            p.CipherMode,
			"derived":                p.Derived,
			"deletion_allowed":       p.DeletionAllowed,
			"min_decryption_version": p.MinDecryptionVersion,
		},
	}
	if p.Derived {
		resp.Data["kdf_mode"] = p.KDFMode
	}

	retKeys := map[string]int64{}
	for k, v := range p.Keys {
		retKeys[strconv.Itoa(k)] = v.CreationTime
	}
	resp.Data["keys"] = retKeys

	return resp, nil
}
Пример #18
0
func (b *backend) pathKeysWrite(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	keyName := d.Get("key_name").(string)
	if keyName == "" {
		return logical.ErrorResponse("Missing key_name"), nil
	}

	keyString := d.Get("key").(string)

	// Check if the key provided is infact a private key
	signer, err := ssh.ParsePrivateKey([]byte(keyString))
	if err != nil || signer == nil {
		return logical.ErrorResponse("Invalid key"), nil
	}

	if keyString == "" {
		return logical.ErrorResponse("Missing key"), nil
	}

	keyPath := fmt.Sprintf("keys/%s", keyName)

	// Store the key
	entry, err := logical.StorageEntryJSON(keyPath, map[string]interface{}{
		"key": keyString,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}
	return nil, nil
}
Пример #19
0
// handleRevokeOrphan handles the auth/token/revoke-orphan/id path for revocation of tokens
// in a way that leaves child tokens orphaned. Normally, using sys/revoke/leaseID will revoke
// the token and all children.
func (ts *TokenStore) handleRevokeOrphan(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	// Parse the id
	id := data.Get("token").(string)
	if id == "" {
		return logical.ErrorResponse("missing token ID"), logical.ErrInvalidRequest
	}

	parent, err := ts.Lookup(req.ClientToken)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf("parent token lookup failed: %s", err.Error())), logical.ErrInvalidRequest
	}
	if parent == nil {
		return logical.ErrorResponse("parent token lookup failed"), logical.ErrInvalidRequest
	}

	// Check if the client token has sudo/root privileges for the requested path
	isSudo := ts.System().SudoPrivilege(req.MountPoint+req.Path, req.ClientToken)

	if !isSudo {
		return logical.ErrorResponse("root or sudo privileges required to revoke and orphan"),
			logical.ErrInvalidRequest
	}

	// Revoke and orphan
	if err := ts.Revoke(id); err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}
	return nil, nil
}
Пример #20
0
func (b *backend) pathConfigZeroAddressWrite(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	roleNames := d.Get("roles").(string)
	if roleNames == "" {
		return logical.ErrorResponse("Missing roles"), nil
	}

	// Check if the roles listed actually exist in the backend
	roles := strings.Split(roleNames, ",")
	for _, item := range roles {
		role, err := b.getRole(req.Storage, item)
		if err != nil {
			return nil, err
		}
		if role == nil {
			return logical.ErrorResponse(fmt.Sprintf("Role [%s] does not exist", item)), nil
		}
	}

	err := b.putZeroAddressRoles(req.Storage, roles)
	if err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #21
0
func (b *backend) pathLogin(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	username := d.Get("username").(string)
	password := d.Get("password").(string)

	policies, resp, err := b.Login(req, username, password)
	if len(policies) == 0 {
		return resp, err
	}

	sort.Strings(policies)

	return &logical.Response{
		Auth: &logical.Auth{
			Policies: policies,
			Metadata: map[string]string{
				"username": username,
				"policies": strings.Join(policies, ","),
			},
			InternalData: map[string]interface{}{
				"password": password,
			},
			DisplayName: username,
		},
	}, nil
}
// pathConfigCertificateCreateUpdate is used to register an AWS Public Key that is
// used to verify the PKCS#7 signature of the instance identity document.
func (b *backend) pathConfigCertificateCreateUpdate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	certName := data.Get("cert_name").(string)
	if certName == "" {
		return logical.ErrorResponse("missing cert_name"), nil
	}

	b.configMutex.Lock()
	defer b.configMutex.Unlock()

	// Check if there is already a certificate entry registered.
	certEntry, err := b.nonLockedAWSPublicCertificateEntry(req.Storage, certName)
	if err != nil {
		return nil, err
	}
	if certEntry == nil {
		certEntry = &awsPublicCert{}
	}

	// Check if the value is provided by the client.
	certStrData, ok := data.GetOk("aws_public_cert")
	if ok {
		if certBytes, err := base64.StdEncoding.DecodeString(certStrData.(string)); err == nil {
			certEntry.AWSPublicCert = string(certBytes)
		} else {
			certEntry.AWSPublicCert = certStrData.(string)
		}
	} else {
		// aws_public_cert should be supplied for both create and update operations.
		// If it is not provided, throw an error.
		return logical.ErrorResponse("missing aws_public_cert"), nil
	}

	// If explicitly set to empty string, error out.
	if certEntry.AWSPublicCert == "" {
		return logical.ErrorResponse("invalid aws_public_cert"), nil
	}

	// Verify the certificate by decoding it and parsing it.
	publicCert, err := decodePEMAndParseCertificate(certEntry.AWSPublicCert)
	if err != nil {
		return nil, err
	}
	if publicCert == nil {
		return logical.ErrorResponse("invalid certificate; failed to decode and parse certificate"), nil
	}

	// Ensure that we have not
	// If none of the checks fail, save the provided certificate.
	entry, err := logical.StorageEntryJSON("config/certificate/"+certName, certEntry)
	if err != nil {
		return nil, err
	}

	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Пример #23
0
// handleRevokeOrphan handles the auth/token/revoke-orphan/id path for revocation of tokens
// in a way that leaves child tokens orphaned. Normally, using sys/revoke/leaseID will revoke
// the token and all children.
func (ts *TokenStore) handleRevokeOrphan(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	// Parse the id
	id := data.Get("token").(string)
	if id == "" {
		return logical.ErrorResponse("missing token ID"), logical.ErrInvalidRequest
	}

	parent, err := ts.Lookup(req.ClientToken)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf("parent token lookup failed: %s", err.Error())), logical.ErrInvalidRequest
	}
	if parent == nil {
		return logical.ErrorResponse("parent token lookup failed"), logical.ErrInvalidRequest
	}

	// Check if the parent policy is root
	isRoot := strListContains(parent.Policies, "root")

	if !isRoot {
		return logical.ErrorResponse("root required to revoke and orphan"),
			logical.ErrInvalidRequest
	}

	// Revoke and orphan
	if err := ts.Revoke(id); err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}
	return nil, nil
}
Пример #24
0
func (b *backend) pathCredsCreateRead(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	name := data.Get("name").(string)

	// Get the role
	role, err := getRole(req.Storage, name)
	if err != nil {
		return nil, err
	}
	if role == nil {
		return logical.ErrorResponse(fmt.Sprintf("Unknown role: %s", name)), nil
	}

	displayName := req.DisplayName
	userUUID, err := uuid.GenerateUUID()
	if err != nil {
		return nil, err
	}
	username := fmt.Sprintf("vault_%s_%s_%s_%d", name, displayName, userUUID, time.Now().Unix())
	username = strings.Replace(username, "-", "_", -1)
	password, err := uuid.GenerateUUID()
	if err != nil {
		return nil, err
	}

	// Get our connection
	session, err := b.DB(req.Storage)
	if err != nil {
		return nil, err
	}

	// Execute each query
	for _, query := range splitSQL(role.CreationCQL) {
		err = session.Query(substQuery(query, map[string]string{
			"username": username,
			"password": password,
		})).Exec()
		if err != nil {
			for _, query := range splitSQL(role.RollbackCQL) {
				session.Query(substQuery(query, map[string]string{
					"username": username,
					"password": password,
				})).Exec()
			}
			return nil, err
		}
	}

	// Return the secret
	resp := b.Secret(SecretCredsType).Response(map[string]interface{}{
		"username": username,
		"password": password,
	}, map[string]interface{}{
		"username": username,
		"role":     name,
	})
	resp.Secret.TTL = role.Lease

	return resp, nil
}
Пример #25
0
func pathRawRead(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)
	p, err := getPolicy(req, name)
	if err != nil {
		return nil, err
	}
	if p == nil {
		return nil, nil
	}

	// Return the response
	resp := &logical.Response{
		Data: map[string]interface{}{
			"name":        p.Name,
			"key":         p.Key,
			"cipher_mode": p.CipherMode,
			"derived":     p.Derived,
		},
	}
	if p.Derived {
		resp.Data["kdf_mode"] = p.KDFMode
	}
	return resp, nil
}
Пример #26
0
// DuoHandler interacts with the Duo Auth API to authenticate a user
// login request. If successful, the original response from the login
// backend is returned.
func DuoHandler(req *logical.Request, d *framework.FieldData, resp *logical.Response) (
	*logical.Response, error) {
	duoConfig, err := GetDuoConfig(req)
	if err != nil || duoConfig == nil {
		return logical.ErrorResponse("Could not load Duo configuration"), nil
	}

	duoAuthClient, err := GetDuoAuthClient(req, duoConfig)
	if err != nil {
		return logical.ErrorResponse(err.Error()), nil
	}

	username, ok := resp.Auth.Metadata["username"]
	if !ok {
		return logical.ErrorResponse("Could not read username for MFA"), nil
	}

	var request *duoAuthRequest = &duoAuthRequest{}
	request.successResp = resp
	request.username = username
	request.method = d.Get("method").(string)
	request.passcode = d.Get("passcode").(string)
	request.ipAddr = req.Connection.RemoteAddr

	return duoHandler(duoConfig, duoAuthClient, request)
}
Пример #27
0
func (b *backend) pathRoleRead(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	role, err := b.getRole(req.Storage, data.Get("name").(string))
	if err != nil {
		return nil, err
	}
	if role == nil {
		return nil, nil
	}

	hasMax := true
	if len(role.MaxTTL) == 0 {
		role.MaxTTL = "(system default)"
		hasMax = false
	}
	if len(role.TTL) == 0 {
		if hasMax {
			role.TTL = "(system default, capped to role max)"
		} else {
			role.TTL = "(system default)"
		}
	}

	resp := &logical.Response{
		Data: structs.New(role).Map(),
	}

	return resp, nil
}
Пример #28
0
// Establishes dichotomy of request operation between CreateOperation and UpdateOperation.
// Returning 'true' forces an UpdateOperation, CreateOperation otherwise.
func (b *backend) pathRoleExistenceCheck(req *logical.Request, data *framework.FieldData) (bool, error) {
	entry, err := b.lockedAWSRole(req.Storage, strings.ToLower(data.Get("role").(string)))
	if err != nil {
		return false, err
	}
	return entry != nil, nil
}
Пример #29
0
// handleRenew handles the auth/token/renew/id path for renewal of tokens.
// This is used to prevent token expiration and revocation.
func (ts *TokenStore) handleRenew(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	id := data.Get("token").(string)
	if id == "" {
		return logical.ErrorResponse("missing token ID"), logical.ErrInvalidRequest
	}
	incrementRaw := data.Get("increment").(int)

	// Convert the increment
	increment := time.Duration(incrementRaw) * time.Second

	// Lookup the token
	out, err := ts.Lookup(id)
	if err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}

	// Verify the token exists
	if out == nil {
		return logical.ErrorResponse("token not found"), logical.ErrInvalidRequest
	}

	// Revoke the token and its children
	auth, err := ts.expiration.RenewToken(out.Path, out.ID, increment)
	if err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}

	// Generate the response
	resp := &logical.Response{
		Auth: auth,
	}
	return resp, nil
}
Пример #30
0
// handleLookup handles the auth/token/lookup/id path for querying information about
// a particular token. This can be used to see which policies are applicable.
func (ts *TokenStore) handleLookup(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	id := data.Get("token").(string)
	if id == "" {
		id = req.ClientToken
	}
	if id == "" {
		return logical.ErrorResponse("missing token ID"), logical.ErrInvalidRequest
	}

	// Lookup the token
	out, err := ts.Lookup(id)

	if err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}

	if out == nil {
		return logical.ErrorResponse("bad token"), logical.ErrPermissionDenied
	}

	// Generate a response. We purposely omit the parent reference otherwise
	// you could escalate your privileges.
	resp := &logical.Response{
		Data: map[string]interface{}{
			"id":            out.ID,
			"accessor":      out.Accessor,
			"policies":      out.Policies,
			"path":          out.Path,
			"meta":          out.Meta,
			"display_name":  out.DisplayName,
			"num_uses":      out.NumUses,
			"orphan":        false,
			"creation_time": int64(out.CreationTime),
			"creation_ttl":  int64(out.TTL.Seconds()),
			"ttl":           int64(0),
			"role":          out.Role,
		},
	}

	if out.Parent == "" {
		resp.Data["orphan"] = true
	}

	// Fetch the last renewal time
	leaseTimes, err := ts.expiration.FetchLeaseTimesByToken(out.Path, out.ID)
	if err != nil {
		return logical.ErrorResponse(err.Error()), logical.ErrInvalidRequest
	}
	if leaseTimes != nil {
		if !leaseTimes.LastRenewalTime.IsZero() {
			resp.Data["last_renewal_time"] = leaseTimes.LastRenewalTime.Unix()
		}
		if !leaseTimes.ExpireTime.IsZero() {
			resp.Data["ttl"] = int64(leaseTimes.ExpireTime.Sub(time.Now().Round(time.Second)).Seconds())
		}
	}

	return resp, nil
}