blob: db96d128d2a55ac36ce663dd6616da48a64dfadf [file] [log] [blame]
// Copyright 2016 The Vanadium Authors. All rights reserved.
// Use of this source code is governed by a BSD-style
// license that can be found in the LICENSE file.
package impl
import (
"fmt"
"os"
"path/filepath"
"v.io/v23/security"
"v.io/x/ref/lib/exec"
vsecurity "v.io/x/ref/lib/security"
"v.io/x/ref/services/agent"
)
// principalManager manages security principals.
type principalManager interface {
// Create creates a new principal for the instance directory.
Create(instanceDir string) error
// Delete deletes the principal for the instance directory.
Delete(instanceDir string) error
// Load returns the principal for the instance directory. Assumes the
// principal is Create-d and Serve-ing.
Load(instanceDir string) (agent.Principal, error)
// Serve makes the principal available for Load-in or for use by a child
// app. The config object, if not nil, is mutated to make the principal
// available for a child process.
Serve(instanceDir string, config exec.Config) error
// StopServing undoes Serve.
StopServing(instanceDir string) error
// Debug returns a debugging information about the principal.
Debug(instanceDir string) string
}
func newPrincipalManager() principalManager {
return &diskCredsPM{}
}
// diskCredsPM is a principalManager implementation that uses on-disk
// credentials. The credentials are not shared via the security agent, and are
// not locked against concurrent access.
type diskCredsPM struct{}
type noOpClosePrincipal struct {
security.Principal
}
func (p noOpClosePrincipal) Close() error {
return nil
}
func (pm *diskCredsPM) Create(instanceDir string) error {
credentialsDir := filepath.Join(instanceDir, "credentials")
// TODO(caprita): The app's system user id needs access to this dir.
// Use the suidhelper to chown it.
_, err := vsecurity.CreatePersistentPrincipal(credentialsDir, nil)
return err
}
func (pm *diskCredsPM) Delete(instanceDir string) error {
credentialsDir := filepath.Join(instanceDir, "credentials")
return os.RemoveAll(credentialsDir)
}
func (pm *diskCredsPM) Load(instanceDir string) (agent.Principal, error) {
credentialsDir := filepath.Join(instanceDir, "credentials")
// TODO(caprita): The app's system user id needs access to this dir.
// Use the suidhelper to chown it.
p, err := vsecurity.LoadPersistentPrincipal(credentialsDir, nil)
if err != nil {
return nil, err
}
return noOpClosePrincipal{p}, nil
}
func (pm *diskCredsPM) Serve(instanceDir string, cfg exec.Config) error {
if cfg != nil {
cfg.Set("v23.credentials", filepath.Join(instanceDir, "credentials"))
}
return nil
}
func (pm *diskCredsPM) StopServing(instanceDir string) error {
return nil
}
func (pm *diskCredsPM) Debug(instanceDir string) string {
credentialsDir := filepath.Join(instanceDir, "credentials")
return fmt.Sprintf("Credentials dir-based (%v)", credentialsDir)
}