Пример #1
0
// nonLockedAWSRole returns the properties set on the given role. This method
// does not acquire the read lock before reading the role from the storage. If
// locking is desired, use lockedAWSRole instead.
func (b *backend) nonLockedAWSRole(s logical.Storage, roleName string) (*awsRoleEntry, error) {
	if roleName == "" {
		return nil, fmt.Errorf("missing role name")
	}

	entry, err := s.Get("role/" + strings.ToLower(roleName))
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	// Check if the value held by role ARN field is actually an instance profile ARN
	if result.BoundIamRoleARN != "" && strings.Contains(result.BoundIamRoleARN, ":instance-profile/") {
		// If yes, move it to the correct field
		result.BoundIamInstanceProfileARN = result.BoundIamRoleARN

		// Reset the old field
		result.BoundIamRoleARN = ""

		// Save the update
		if err = b.nonLockedSetAWSRole(s, roleName, &result); err != nil {
			return nil, fmt.Errorf("failed to move instance profile ARN to bound_iam_instance_profile_arn field")
		}
	}

	return &result, nil
}
Пример #2
0
func clientIAM(s logical.Storage) (*iam.IAM, error) {
	entry, err := s.Get("config/root")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, fmt.Errorf(
			"root credentials haven't been configured. Please configure\n" +
				"them at the 'config/root' endpoint")
	}

	var config rootConfig
	if err := entry.DecodeJSON(&config); err != nil {
		return nil, fmt.Errorf("error reading root configuration: %s", err)
	}

	creds := credentials.NewStaticCredentials(config.AccessKey, config.SecretKey, "")
	awsConfig := &aws.Config{
		Credentials: creds,
		Region:      aws.String(config.Region),
		HTTPClient:  cleanhttp.DefaultClient(),
	}

	return iam.New(session.New(awsConfig)), nil
}
Пример #3
0
func getRootConfig(s logical.Storage) (*aws.Config, error) {
	credsConfig := &awsutil.CredentialsConfig{}

	entry, err := s.Get("config/root")
	if err != nil {
		return nil, err
	}
	if entry != nil {
		var config rootConfig
		if err := entry.DecodeJSON(&config); err != nil {
			return nil, fmt.Errorf("error reading root configuration: %s", err)
		}

		credsConfig.AccessKey = config.AccessKey
		credsConfig.SecretKey = config.SecretKey
		credsConfig.Region = config.Region
	}

	if credsConfig.Region == "" {
		credsConfig.Region = "us-east-1"
	}

	credsConfig.HTTPClient = cleanhttp.DefaultClient()

	creds, err := credsConfig.GenerateCredentialChain()
	if err != nil {
		return nil, err
	}

	return &aws.Config{
		Credentials: creds,
		Region:      aws.String(credsConfig.Region),
		HTTPClient:  cleanhttp.DefaultClient(),
	}, nil
}
Пример #4
0
// DB returns the database connection.
func (b *backend) Client(s logical.Storage) (*rabbithole.Client, error) {
	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a client, we got it!
	if b.client != nil {
		return b.client, nil
	}

	// Otherwise, attempt to make connection
	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil,
			fmt.Errorf("configure the client connection with config/connection first")
	}

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

	b.client, err = rabbithole.NewClient(connConfig.URI, connConfig.Username, connConfig.Password)
	if err != nil {
		return nil, err
	}

	return b.client, nil
}
Пример #5
0
// nonLockedAWSPublicCertificateEntry reads the certificate information from
// the storage. This method does not acquire lock before reading the storage.
// If locking is desired, use lockedAWSPublicCertificateEntry instead.
func (b *backend) nonLockedAWSPublicCertificateEntry(s logical.Storage, certName string) (*awsPublicCert, error) {
	entry, err := s.Get("config/certificate/" + certName)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}
	var certEntry awsPublicCert
	if err := entry.DecodeJSON(&certEntry); err != nil {
		return nil, err
	}

	// Handle upgrade for certificate type
	persistNeeded := false
	if certEntry.Type == "" {
		certEntry.Type = "pkcs7"
		persistNeeded = true
	}

	if persistNeeded {
		if err := b.nonLockedSetAWSPublicCertificateEntry(s, certName, &certEntry); err != nil {
			return nil, err
		}
	}

	return &certEntry, nil
}
Пример #6
0
func (b *backend) populateCRLs(storage logical.Storage) error {
	b.crlUpdateMutex.Lock()
	defer b.crlUpdateMutex.Unlock()

	keys, err := storage.List("crls/")
	if err != nil {
		return fmt.Errorf("error listing CRLs: %v", err)
	}
	if keys == nil || len(keys) == 0 {
		return nil
	}

	for _, key := range keys {
		entry, err := storage.Get("crls/" + key)
		if err != nil {
			return fmt.Errorf("error loading CRL %s: %v", key, err)
		}
		if entry == nil {
			continue
		}
		var crlInfo CRLInfo
		err = entry.DecodeJSON(&crlInfo)
		if err != nil {
			return fmt.Errorf("error decoding CRL %s: %v", key, err)
		}
		b.crls[key] = crlInfo
	}

	return nil
}
Пример #7
0
// DB returns the database connection.
func (b *backend) DB(s logical.Storage) (*sql.DB, error) {
	b.logger.Trace("postgres/db: enter")
	defer b.logger.Trace("postgres/db: exit")

	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a DB, we got it!
	if b.db != nil {
		if err := b.db.Ping(); err == nil {
			return b.db, nil
		}
		// If the ping was unsuccessful, close it and ignore errors as we'll be
		// reestablishing anyways
		b.db.Close()
	}

	// Otherwise, attempt to make connection
	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil,
			fmt.Errorf("configure the DB connection with config/connection first")
	}

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

	conn := connConfig.ConnectionURL
	if len(conn) == 0 {
		conn = connConfig.ConnectionString
	}

	// Ensure timezone is set to UTC for all the conenctions
	if strings.HasPrefix(conn, "postgres://") || strings.HasPrefix(conn, "postgresql://") {
		if strings.Contains(conn, "?") {
			conn += "&timezone=utc"
		} else {
			conn += "?timezone=utc"
		}
	} else {
		conn += " timezone=utc"
	}

	b.db, err = sql.Open("postgres", conn)
	if err != nil {
		return nil, err
	}

	// Set some connection pool settings. We don't need much of this,
	// since the request rate shouldn't be high.
	b.db.SetMaxOpenConns(connConfig.MaxOpenConnections)
	b.db.SetMaxIdleConns(connConfig.MaxIdleConnections)

	return b.db, nil
}
Пример #8
0
// DB returns the database connection.
func (b *backend) DB(s logical.Storage) (*sql.DB, error) {
	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a DB, we got it!
	if b.db != nil {
		return b.db, nil
	}

	// Otherwise, attempt to make connection
	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil,
			fmt.Errorf("configure the DB connection with config/connection first")
	}

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

	b.db, err = sql.Open("postgres", conn)
	if err != nil {
		return nil, err
	}

	// Set some connection pool settings. We don't need much of this,
	// since the request rate shouldn't be high.
	b.db.SetMaxOpenConns(2)

	return b.db, nil
}
Пример #9
0
// Takes an IP address and role name and checks if the IP is part
// of CIDR blocks belonging to the role.
func roleContainsIP(s logical.Storage, roleName string, ip string) (bool, error) {
	if roleName == "" {
		return false, fmt.Errorf("missing role name")
	}

	if ip == "" {
		return false, fmt.Errorf("missing ip")
	}

	roleEntry, err := s.Get(fmt.Sprintf("roles/%s", roleName))
	if err != nil {
		return false, fmt.Errorf("error retrieving role '%s'", err)
	}
	if roleEntry == nil {
		return false, fmt.Errorf("role '%s' not found", roleName)
	}

	var role sshRole
	if err := roleEntry.DecodeJSON(&role); err != nil {
		return false, fmt.Errorf("error decoding role '%s'", roleName)
	}

	if matched, err := cidrListContainsIP(ip, role.CIDRList); err != nil {
		return false, err
	} else {
		return matched, nil
	}
}
Пример #10
0
// DB returns the database connection.
func (b *backend) DB(s logical.Storage) (*gocql.Session, error) {
	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a DB, we got it!
	if b.session != nil {
		return b.session, nil
	}

	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil,
			fmt.Errorf("Configure the DB connection with config/connection first")
	}

	config := &sessionConfig{}
	if err := entry.DecodeJSON(config); err != nil {
		return nil, err
	}

	return createSession(config, s)
}
Пример #11
0
// NewSalt creates a new salt based on the configuration
func NewSalt(view logical.Storage, config *Config) (*Salt, error) {
	// Setup the configuration
	if config == nil {
		config = &Config{}
	}
	if config.Location == "" {
		config.Location = DefaultLocation
	}
	if config.HashFunc == nil {
		config.HashFunc = SHA256Hash
	}

	// Create the salt
	s := &Salt{
		config: config,
	}

	// Look for the salt
	raw, err := view.Get(config.Location)
	if err != nil {
		return nil, fmt.Errorf("failed to read salt: %v", err)
	}

	// Restore the salt if it exists
	if raw != nil {
		s.salt = string(raw.Value)
	}

	// Generate a new salt if necessary
	if s.salt == "" {
		s.salt, err = uuid.GenerateUUID()
		if err != nil {
			return nil, fmt.Errorf("failed to generate uuid: %v", err)
		}
		s.generated = true
		if view != nil {
			raw := &logical.StorageEntry{
				Key:   config.Location,
				Value: []byte(s.salt),
			}
			if err := view.Put(raw); err != nil {
				return nil, fmt.Errorf("failed to persist salt: %v", err)
			}
		}
	}

	if config.HMAC != nil {
		if len(config.HMACType) == 0 {
			return nil, fmt.Errorf("HMACType must be defined")
		}
		s.hmacType = config.HMACType
	}

	return s, nil
}
Пример #12
0
// DB returns the default database connection.
func (b *backend) DB(s logical.Storage) (*sql.DB, error) {
	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a DB, we got it!
	if b.db != nil {
		if err := b.db.Ping(); err == nil {
			return b.db, nil
		}
		// If the ping was unsuccessful, close it and ignore errors as we'll be
		// reestablishing anyways
		b.db.Close()
	}

	// Otherwise, attempt to make connection
	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, fmt.Errorf("configure the DB connection with config/connection first")
	}

	var connConfig connectionConfig
	if err := entry.DecodeJSON(&connConfig); err != nil {
		return nil, err
	}
	connString := connConfig.ConnectionString

	db, err := sql.Open("mssql", connString)
	if err != nil {
		return nil, err
	}

	// Set some connection pool settings. We don't need much of this,
	// since the request rate shouldn't be high.
	db.SetMaxOpenConns(connConfig.MaxOpenConnections)

	stmt, err := db.Prepare("SELECT db_name();")
	if err != nil {
		return nil, err
	}
	defer stmt.Close()

	err = stmt.QueryRow().Scan(&b.defaultDb)
	if err != nil {
		return nil, err
	}

	b.db = db
	return b.db, nil
}
Пример #13
0
// DB returns the database connection.
func (b *backend) DB(s logical.Storage) (*sql.DB, error) {
	b.lock.Lock()
	defer b.lock.Unlock()

	// If we already have a DB, we got it!
	if b.db != nil {
		return b.db, nil
	}

	// Otherwise, attempt to make connection
	entry, err := s.Get("config/connection")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil,
			fmt.Errorf("configure the DB connection with config/connection first")
	}

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

	conn := connConfig.ConnectionString
	if len(conn) == 0 {
		conn = connConfig.ConnectionURL
	}

	// Ensure timezone is set to UTC for all the conenctions
	if strings.HasPrefix(conn, "postgres://") || strings.HasPrefix(conn, "postgresql://") {
		var err error
		conn, err = pq.ParseURL(conn)
		if err != nil {
			return nil, err
		}
	}
	conn += " timezone=utc"

	b.db, err = sql.Open("postgres", conn)
	if err != nil {
		return nil, err
	}

	// Set some connection pool settings. We don't need much of this,
	// since the request rate shouldn't be high.
	b.db.SetMaxOpenConns(connConfig.MaxOpenConnections)
	b.db.SetMaxIdleConns(connConfig.MaxIdleConnections)

	return b.db, nil
}
Пример #14
0
// Fetch the client configuration required to access the AWS API.
func (b *backend) nonLockedClientConfigEntry(s logical.Storage) (*clientConfig, error) {
	entry, err := s.Get("config/client")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result clientConfig
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #15
0
func (b *backend) Cert(s logical.Storage, n string) (*CertEntry, error) {
	entry, err := s.Get("cert/" + strings.ToLower(n))
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result CertEntry
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #16
0
// Fetch an item from the whitelist given an instance ID.
func whitelistIdentityEntry(s logical.Storage, instanceID string) (*whitelistIdentity, error) {
	entry, err := s.Get("whitelist/identity/" + instanceID)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result whitelistIdentity
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
// Internal version of the above that does no locking
func (b *backend) nonLockedAWSPublicCertificateEntry(s logical.Storage, certName string) (*awsPublicCert, error) {
	entry, err := s.Get("config/certificate/" + certName)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result awsPublicCert
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #18
0
func (b *backend) nonLockedAWSRole(s logical.Storage, role string) (*awsRoleEntry, error) {
	entry, err := s.Get("role/" + strings.ToLower(role))
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result awsRoleEntry
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #19
0
func (b *backend) getKey(s logical.Storage, n string) (*sshHostKey, error) {
	entry, err := s.Get("keys/" + n)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result sshHostKey
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #20
0
func (b *backend) nonLockedBlacklistRoleTagEntry(s logical.Storage, tag string) (*roleTagBlacklistEntry, error) {
	entry, err := s.Get("blacklist/roletag/" + base64.StdEncoding.EncodeToString([]byte(tag)))
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result roleTagBlacklistEntry
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
func (b *backend) nonLockedConfigTidyIdentities(s logical.Storage) (*tidyWhitelistIdentityConfig, error) {
	entry, err := s.Get(identityWhitelistConfigPath)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result tidyWhitelistIdentityConfig
	if err := entry.DecodeJSON(&result); err != nil {
		return nil, err
	}
	return &result, nil
}
Пример #22
0
// Config returns the configuration for this backend.
func (b *backend) Config(s logical.Storage) (*config, error) {
	entry, err := s.Get("config")
	if err != nil {
		return nil, err
	}

	var result config
	if entry != nil {
		if err := entry.DecodeJSON(&result); err != nil {
			return nil, fmt.Errorf("error reading configuration: %s", err)
		}
	}

	return &result, nil
}
Пример #23
0
// Retrieves the list of roles from the zeroaddress endpoint.
func (b *backend) getZeroAddressRoles(s logical.Storage) (*zeroAddressRoles, error) {
	entry, err := s.Get("config/zeroaddress")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #24
0
func (b *backend) User(s logical.Storage, n string) (*UserEntry, error) {
	entry, err := s.Get("user/" + n)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #25
0
// Lease returns the lease information
func (b *backend) Lease(s logical.Storage) (*configLease, error) {
	entry, err := s.Get("config/lease")
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #26
0
func (b *backend) Group(s logical.Storage, n string) (*GroupEntry, error) {
	entry, err := s.Get("group/" + n)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #27
0
// Get reads the structure.
func (p *PathStruct) Get(s logical.Storage) (map[string]interface{}, error) {
	entry, err := s.Get(fmt.Sprintf("struct/%s", p.Name))
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

	var result map[string]interface{}
	if err := json.Unmarshal(entry.Value, &result); err != nil {
		return nil, err
	}

	return result, nil
}
func (b *backend) nonLockedConfigTidyRoleTags(s logical.Storage) (*tidyBlacklistRoleTagConfig, error) {
	entry, err := s.Get(roletagBlacklistConfigPath)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #29
0
func (b *backend) getOTP(s logical.Storage, n string) (*sshOTP, error) {
	entry, err := s.Get("otp/" + n)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}
Пример #30
0
func (b *backend) Role(s logical.Storage, n string) (*roleEntry, error) {
	entry, err := s.Get("role/" + n)
	if err != nil {
		return nil, err
	}
	if entry == nil {
		return nil, nil
	}

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

	return &result, nil
}