Beispiel #1
0
// Verify that we are able to update from non-salted (<0.2) to
// using a Salt for the paths
func TestBackend_upgradeToSalted(t *testing.T) {
	inm := new(logical.InmemStorage)

	// Create some fake keys
	se, _ := logical.StorageEntryJSON("struct/map/app-id/foo",
		map[string]string{"value": "test"})
	inm.Put(se)
	se, _ = logical.StorageEntryJSON("struct/map/user-id/bar",
		map[string]string{"value": "foo"})
	inm.Put(se)

	// Initialize the backend, this should do the automatic upgrade
	conf := &logical.BackendConfig{
		StorageView: inm,
	}
	backend, err := Factory(conf)
	if err != nil {
		t.Fatalf("err: %v", err)
	}

	// Check the keys have been upgraded
	out, err := inm.Get("struct/map/app-id/foo")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if out != nil {
		t.Fatalf("unexpected key")
	}
	out, err = inm.Get("struct/map/user-id/bar")
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if out != nil {
		t.Fatalf("unexpected key")
	}

	// Backend should still be able to resolve
	req := logical.TestRequest(t, logical.ReadOperation, "map/app-id/foo")
	req.Storage = inm
	resp, err := backend.HandleRequest(req)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if resp.Data["value"] != "test" {
		t.Fatalf("bad: %#v", resp)
	}

	req = logical.TestRequest(t, logical.ReadOperation, "map/user-id/bar")
	req.Storage = inm
	resp, err = backend.HandleRequest(req)
	if err != nil {
		t.Fatalf("err: %v", err)
	}
	if resp.Data["value"] != "foo" {
		t.Fatalf("bad: %#v", resp)
	}
}
Beispiel #2
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
}
Beispiel #3
0
// SetPolicy is used to create or update the given policy
func (ps *PolicyStore) SetPolicy(p *Policy) error {
	defer metrics.MeasureSince([]string{"policy", "set_policy"}, time.Now())
	if p.Name == "root" {
		return fmt.Errorf("cannot update root policy")
	}
	if p.Name == "" {
		return fmt.Errorf("policy name missing")
	}

	// Create the entry
	entry, err := logical.StorageEntryJSON(p.Name, &PolicyEntry{
		Version: 2,
		Raw:     p.Raw,
	})
	if err != nil {
		return fmt.Errorf("failed to create entry: %v", err)
	}
	if err := ps.view.Put(entry); err != nil {
		return fmt.Errorf("failed to persist policy: %v", err)
	}

	// Update the LRU cache
	ps.lru.Add(p.Name, p)
	return nil
}
Beispiel #4
0
func (b *backend) pathConfigLeaseWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	ttlRaw := d.Get("ttl").(string)
	ttlMaxRaw := d.Get("max_ttl").(string)
	if len(ttlMaxRaw) == 0 {
		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 max_ttl: %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
}
Beispiel #5
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
}
Beispiel #6
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
}
Beispiel #7
0
// createSecretIDAccessorEntry creates an identifier for the SecretID. A storage index,
// mapping the accessor to the SecretID is also created. This method should
// be called when the lock for the corresponding SecretID is held.
func (b *backend) createSecretIDAccessorEntry(s logical.Storage, entry *secretIDStorageEntry, secretIDHMAC string) error {
	// Create a random accessor
	accessorUUID, err := uuid.GenerateUUID()
	if err != nil {
		return err
	}
	entry.SecretIDAccessor = accessorUUID

	// Create index entry, mapping the accessor to the token ID
	entryIndex := "accessor/" + b.salt.SaltID(entry.SecretIDAccessor)

	accessorLock := b.secretIDAccessorLock(accessorUUID)
	accessorLock.Lock()
	defer accessorLock.Unlock()

	if entry, err := logical.StorageEntryJSON(entryIndex, &secretIDAccessorStorageEntry{
		SecretIDHMAC: secretIDHMAC,
	}); err != nil {
		return err
	} else if err = s.Put(entry); err != nil {
		return fmt.Errorf("failed to persist accessor index entry: %s", err)
	}

	return nil
}
// Generates an UUID OTP and creates an entry for the same in storage backend with its salted string.
func (b *backend) GenerateOTPCredential(req *logical.Request, username, ip string) (string, error) {
	otp, otpSalted := b.GenerateSaltedOTP()

	// Check if there is an entry already created for the newly generated OTP.
	entry, err := b.getOTP(req.Storage, otpSalted)

	// If entry already exists for the OTP, make sure that new OTP is not
	// replacing an existing one by recreating new ones until an unused
	// OTP is generated. It is very unlikely that this is the case and this
	// code is just for safety.
	for err == nil && entry != nil {
		otp, otpSalted = b.GenerateSaltedOTP()
		entry, err = b.getOTP(req.Storage, otpSalted)
		if err != nil {
			return "", err
		}
	}

	// Store an entry for the salt of OTP.
	newEntry, err := logical.StorageEntryJSON("otp/"+otpSalted, sshOTP{
		Username: username,
		IP:       ip,
	})
	if err != nil {
		return "", err
	}
	if err := req.Storage.Put(newEntry); err != nil {
		return "", err
	}
	return otp, nil
}
Beispiel #9
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
}
Beispiel #10
0
// Registers a new role with the backend
func (b *backend) pathRoleUpdate(req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)
	if name == "" {
		return logical.ErrorResponse("missing name"), nil
	}

	tags := d.Get("tags").(string)
	rawVHosts := d.Get("vhosts").(string)

	if tags == "" && rawVHosts == "" {
		return logical.ErrorResponse("both tags and vhosts not specified"), nil
	}

	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
}
Beispiel #11
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
}
Beispiel #12
0
func (b *backend) pathRoleCreate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	name := data.Get("name").(string)

	creationCQL := data.Get("creation_cql").(string)

	rollbackCQL := data.Get("rollback_cql").(string)

	leaseRaw := data.Get("lease").(string)
	lease, err := time.ParseDuration(leaseRaw)
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Error parsing lease value of %s: %s", leaseRaw, err)), nil
	}

	entry := &roleEntry{
		Lease:       lease,
		CreationCQL: creationCQL,
		RollbackCQL: rollbackCQL,
	}

	// Store it
	entryJSON, err := logical.StorageEntryJSON("role/"+name, entry)
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entryJSON); err != nil {
		return nil, err
	}

	return nil, nil
}
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
}
func (b *backend) pathConfigTidyRoletagBlacklistCreateUpdate(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	b.configMutex.Lock()
	defer b.configMutex.Unlock()

	configEntry, err := b.nonLockedConfigTidyRoleTags(req.Storage)
	if err != nil {
		return nil, err
	}
	if configEntry == nil {
		configEntry = &tidyBlacklistRoleTagConfig{}
	}
	safetyBufferInt, ok := data.GetOk("safety_buffer")
	if ok {
		configEntry.SafetyBuffer = safetyBufferInt.(int)
	} else if req.Operation == logical.CreateOperation {
		configEntry.SafetyBuffer = data.Get("safety_buffer").(int)
	}
	disablePeriodicTidyBool, ok := data.GetOk("disable_periodic_tidy")
	if ok {
		configEntry.DisablePeriodicTidy = disablePeriodicTidyBool.(bool)
	} else if req.Operation == logical.CreateOperation {
		configEntry.DisablePeriodicTidy = data.Get("disable_periodic_tidy").(bool)
	}

	entry, err := logical.StorageEntryJSON(roletagBlacklistConfigPath, configEntry)
	if err != nil {
		return nil, err
	}

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

	return nil, nil
}
Beispiel #15
0
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{
		PasswordHash: hash,
		Policies:     policies,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, 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
}
Beispiel #17
0
func pathRolesWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := d.Get("name").(string)
	policyRaw, err := base64.StdEncoding.DecodeString(d.Get("policy").(string))
	if err != nil {
		return logical.ErrorResponse(fmt.Sprintf(
			"Error decoding policy base64: %s", err)), nil
	}
	lease, err := time.ParseDuration(d.Get("lease").(string))
	if err != nil || lease == time.Duration(0) {
		lease = DefaultLeaseDuration
	}

	entry, err := logical.StorageEntryJSON("policy/"+name, roleConfig{
		Policy: string(policyRaw),
		Lease:  lease,
	})
	if err != nil {
		return nil, err
	}

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

	return nil, nil
}
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
}
func (b *backend) pathGenerateIntermediate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	var err error

	exported, format, role, errorResp := b.getGenerationParams(data)
	if errorResp != nil {
		return errorResp, nil
	}

	var resp *logical.Response
	parsedBundle, err := generateIntermediateCSR(b, role, nil, req, data)
	if err != nil {
		switch err.(type) {
		case certutil.UserError:
			return logical.ErrorResponse(err.Error()), nil
		case certutil.InternalError:
			return nil, err
		}
	}

	csrb, err := parsedBundle.ToCSRBundle()
	if err != nil {
		return nil, fmt.Errorf("Error converting raw CSR bundle to CSR bundle: %s", err)
	}

	resp = &logical.Response{
		Data: map[string]interface{}{},
	}

	switch format {
	case "pem":
		resp.Data["csr"] = csrb.CSR
		if exported {
			resp.Data["private_key"] = csrb.PrivateKey
			resp.Data["private_key_type"] = csrb.PrivateKeyType
		}
	case "der":
		resp.Data["csr"] = base64.StdEncoding.EncodeToString(parsedBundle.CSRBytes)
		if exported {
			resp.Data["private_key"] = base64.StdEncoding.EncodeToString(parsedBundle.PrivateKeyBytes)
			resp.Data["private_key_type"] = csrb.PrivateKeyType
		}
	}

	cb := &certutil.CertBundle{}
	cb.PrivateKey = csrb.PrivateKey
	cb.PrivateKeyType = csrb.PrivateKeyType

	entry, err := logical.StorageEntryJSON("config/ca_bundle", cb)
	if err != nil {
		return nil, err
	}
	err = req.Storage.Put(entry)
	if err != nil {
		return nil, err
	}

	return resp, nil
}
Beispiel #20
0
func (b *backend) setUser(s logical.Storage, username string, userEntry *UserEntry) error {
	entry, err := logical.StorageEntryJSON("user/"+username, userEntry)
	if err != nil {
		return err
	}

	return s.Put(entry)
}
Beispiel #21
0
func (b *backend) pathRoleCreate(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {

	name := data.Get("name").(string)
	if name == "" {
		return logical.ErrorResponse("Missing name"), nil
	}

	roleDB := data.Get("db").(string)
	if roleDB == "" {
		return logical.ErrorResponse("db parameter is required"), nil
	}

	// Example roles JSON:
	//
	// [ "readWrite", { "role": "readWrite", "db": "test" } ]
	//
	// For storage, we convert such an array into a homogeneous array of role documents like:
	//
	// [ { "role": "readWrite" }, { "role": "readWrite", "db": "test" } ]
	//
	var roles []mongodbRole
	rolesJson := []byte(data.Get("roles").(string))
	if len(rolesJson) > 0 {
		var rolesArray []interface{}
		err := json.Unmarshal(rolesJson, &rolesArray)
		if err != nil {
			return nil, err
		}
		for _, rawRole := range rolesArray {
			switch role := rawRole.(type) {
			case string:
				roles = append(roles, mongodbRole{Role: role})
			case map[string]interface{}:
				if db, ok := role["db"].(string); ok {
					if roleName, ok := role["role"].(string); ok {
						roles = append(roles, mongodbRole{Role: roleName, DB: db})
					}
				}
			}
		}
	}

	// Store it
	entry, err := logical.StorageEntryJSON("role/"+name, &roleStorageEntry{
		DB:           roleDB,
		MongoDBRoles: roles,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
Beispiel #22
0
func (b *backend) pathConfigWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {

	cfg := &ConfigEntry{}
	url := d.Get("url").(string)
	if url != "" {
		cfg.Url = strings.ToLower(url)
	}
	userattr := d.Get("userattr").(string)
	if userattr != "" {
		cfg.UserAttr = strings.ToLower(userattr)
	}
	userdn := d.Get("userdn").(string)
	if userdn != "" {
		cfg.UserDN = userdn
	}
	groupdn := d.Get("groupdn").(string)
	if groupdn != "" {
		cfg.GroupDN = groupdn
	}
	upndomain := d.Get("upndomain").(string)
	if groupdn != "" {
		cfg.UPNDomain = upndomain
	}
	certificate := d.Get("certificate").(string)
	if certificate != "" {
		cfg.Certificate = certificate
	}
	insecureTLS := d.Get("insecure_tls").(bool)
	if insecureTLS {
		cfg.InsecureTLS = insecureTLS
	}
	startTLS := d.Get("starttls").(bool)
	if startTLS {
		cfg.StartTLS = startTLS
	}

	// Try to connect to the LDAP server, to validate the URL configuration
	// We can also check the URL at this stage, as anything else would probably
	// require authentication.
	conn, cerr := cfg.DialLDAP()
	if cerr != nil {
		return logical.ErrorResponse(cerr.Error()), nil
	}
	conn.Close()

	entry, err := logical.StorageEntryJSON("config", cfg)
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	return nil, nil
}
func (b *backend) pathConnectionUpdate(req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	uri := data.Get("connection_uri").(string)
	username := data.Get("username").(string)
	password := data.Get("password").(string)

	if uri == "" {
		return logical.ErrorResponse(fmt.Sprintf(
			"'connection_uri' is a required parameter.")), nil
	}

	if username == "" {
		return logical.ErrorResponse(fmt.Sprintf(
			"'username' is a required parameter.")), nil
	}

	if password == "" {
		return logical.ErrorResponse(fmt.Sprintf(
			"'password' is a required parameter.")), nil
	}

	// Don't check the connection_url if verification is disabled
	verifyConnection := data.Get("verify_connection").(bool)
	if verifyConnection {
		// Create RabbitMQ management client
		client, err := rabbithole.NewClient(uri, username, password)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"Error  info: %s", err)), nil
		}

		// Verify provided user is able to list users
		_, err = client.ListUsers()
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"Error validating connection info by listing users: %s", err)), nil
		}
	}

	// Store it
	entry, err := logical.StorageEntryJSON("config/connection", connectionConfig{
		URI:      uri,
		Username: username,
		Password: password,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	// Reset the client connection
	b.ResetClient()

	return nil, nil
}
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("the connection_url parameter must be supplied"), nil
		} else {
			connURL = connValue
		}
	}

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

	// 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("mysql", 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{
		ConnectionURL:      connURL,
		MaxOpenConnections: maxOpenConns,
		VerifyConnection:   verifyConnection,
	})
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}

	// Reset the DB connection
	b.ResetDB()

	resp := &logical.Response{}
	resp.AddWarning("Read access to this endpoint should be controlled via ACLs as it will return the connection URL as it is, including passwords, if any.")

	return resp, nil
}
// Stores an instance ID and the information required to validate further login/renewal attempts from
// the same instance ID.
func setWhitelistIdentityEntry(s logical.Storage, instanceID string, identity *whitelistIdentity) error {
	entry, err := logical.StorageEntryJSON("whitelist/identity/"+instanceID, identity)
	if err != nil {
		return err
	}

	if err := s.Put(entry); err != nil {
		return err
	}
	return nil
}
Beispiel #26
0
func (b *backend) pathCAWrite(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	pemBundle := data.Get("pem_bundle").(string)

	parsedBundle, err := certutil.ParsePEMBundle(pemBundle)
	if err != nil {
		switch err.(type) {
		case errutil.InternalError:
			return nil, err
		default:
			return logical.ErrorResponse(err.Error()), nil
		}
	}

	if parsedBundle.PrivateKey == nil ||
		parsedBundle.PrivateKeyType == certutil.UnknownPrivateKey {
		return logical.ErrorResponse("private key not found in the PEM bundle"), nil
	}

	if parsedBundle.Certificate == nil {
		return logical.ErrorResponse("no certificate found in the PEM bundle"), nil
	}

	if !parsedBundle.Certificate.IsCA {
		return logical.ErrorResponse("the given certificate is not marked for CA use and cannot be used with this backend"), nil
	}

	cb, err := parsedBundle.ToCertBundle()
	if err != nil {
		return nil, fmt.Errorf("error converting raw values into cert bundle: %s", err)
	}

	entry, err := logical.StorageEntryJSON("config/ca_bundle", cb)
	if err != nil {
		return nil, err
	}
	err = req.Storage.Put(entry)
	if err != nil {
		return nil, err
	}

	// For ease of later use, also store just the certificate at a known
	// location, plus a fresh CRL
	entry.Key = "ca"
	entry.Value = parsedBundle.CertificateBytes
	err = req.Storage.Put(entry)
	if err != nil {
		return nil, err
	}

	err = buildCRL(b, req)

	return nil, err
}
Beispiel #27
0
func (b *backend) pathCertWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	name := strings.ToLower(d.Get("name").(string))
	certificate := d.Get("certificate").(string)
	displayName := d.Get("display_name").(string)
	policies := strings.Split(d.Get("policies").(string), ",")
	for i, p := range policies {
		policies[i] = strings.TrimSpace(p)
	}

	// Default the display name to the certificate name if not given
	if displayName == "" {
		displayName = name
	}

	if len(policies) == 0 {
		return logical.ErrorResponse("policies required"), nil
	}
	parsed := parsePEM([]byte(certificate))
	if len(parsed) == 0 {
		return logical.ErrorResponse("failed to parse certificate"), nil
	}

	certEntry := &CertEntry{
		Name:        name,
		Certificate: certificate,
		DisplayName: displayName,
		Policies:    policies,
	}

	// Parse the lease duration or default to backend/system default
	var err error
	maxTTL := b.System().MaxLeaseTTL()
	ttl := time.Duration(d.Get("ttl").(int)) * time.Second
	if ttl == time.Duration(0) {
		ttl = time.Second * time.Duration(d.Get("lease").(int))
	}
	if ttl > maxTTL {
		return logical.ErrorResponse(fmt.Sprintf("Given TTL of %d seconds greater than current mount/system default of %d seconds", ttl/time.Second, maxTTL/time.Second)), nil
	}
	if ttl > time.Duration(0) {
		certEntry.TTL = ttl
	}

	// Store it
	entry, err := logical.StorageEntryJSON("cert/"+name, certEntry)
	if err != nil {
		return nil, err
	}
	if err := req.Storage.Put(entry); err != nil {
		return nil, err
	}
	return nil, nil
}
// Stores the given list of roles at zeroaddress endpoint
func (b *backend) putZeroAddressRoles(s logical.Storage, roles []string) error {
	entry, err := logical.StorageEntryJSON("config/zeroaddress", &zeroAddressRoles{
		Roles: roles,
	})
	if err != nil {
		return err
	}
	if err := s.Put(entry); err != nil {
		return err
	}
	return nil
}
Beispiel #29
0
func pathRolesWrite(
	req *logical.Request, d *framework.FieldData) (*logical.Response, error) {
	tokenType := d.Get("token_type").(string)

	switch tokenType {
	case "client":
	case "management":
	default:
		return logical.ErrorResponse(
			"token_type must be \"client\" or \"management\""), nil
	}

	name := d.Get("name").(string)
	policy := d.Get("policy").(string)
	var policyRaw []byte
	var err error
	if tokenType != "management" {
		if policy == "" {
			return logical.ErrorResponse(
				"policy cannot be empty when not using management tokens"), nil
		}
		policyRaw, err = base64.StdEncoding.DecodeString(d.Get("policy").(string))
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"Error decoding policy base64: %s", err)), nil
		}
	}

	var lease time.Duration
	leaseParam := d.Get("lease").(string)
	if leaseParam != "" {
		lease, err = time.ParseDuration(leaseParam)
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf(
				"error parsing given lease of %s: %s", leaseParam, err)), nil
		}
	}

	entry, err := logical.StorageEntryJSON("policy/"+name, roleConfig{
		Policy:    string(policyRaw),
		Lease:     lease,
		TokenType: tokenType,
	})
	if err != nil {
		return nil, err
	}

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

	return nil, nil
}
Beispiel #30
0
func (b *backend) pathConfigWrite(
	req *logical.Request, data *framework.FieldData) (*logical.Response, error) {
	organization := 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
		}
	}

	var ttl time.Duration
	var err error
	ttlRaw, ok := data.GetOk("ttl")
	if !ok || len(ttlRaw.(string)) == 0 {
		ttl = 0
	} else {
		ttl, err = time.ParseDuration(ttlRaw.(string))
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf("Invalid 'ttl':%s", err)), nil
		}
	}

	var maxTTL time.Duration
	maxTTLRaw, ok := data.GetOk("max_ttl")
	if !ok || len(maxTTLRaw.(string)) == 0 {
		maxTTL = 0
	} else {
		maxTTL, err = time.ParseDuration(maxTTLRaw.(string))
		if err != nil {
			return logical.ErrorResponse(fmt.Sprintf("Invalid 'max_ttl':%s", err)), nil
		}
	}

	entry, err := logical.StorageEntryJSON("config", config{
		Org:     organization,
		BaseURL: baseURL,
		TTL:     ttl,
		MaxTTL:  maxTTL,
	})

	if err != nil {
		return nil, err
	}

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

	return nil, nil
}