actions

package
v0.2.4 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Aug 23, 2018 License: Apache-2.0 Imports: 14 Imported by: 0

Documentation

Overview

Package actions is the high-level interface to the fscrypt packages. The functions here roughly correspond with commands for the tool in cmd/fscrypt. All of the actions include a significant amount of logging, so that good output can be provided for cmd/fscrypt's verbose mode. The top-level actions currently include:

  • Creating a new config file
  • Creating a context on which to perform actions
  • Creating, unlocking, and modifying Protectors
  • Creating, unlocking, and modifying Policies

Index

Constants

View Source
const LegacyConfig = "legacy"

LegacyConfig indicates that keys should be inserted into the keyring with the legacy service prefixes. Needed for kernels before v4.8.

Variables

View Source
var (
	ErrNoConfigFile     = errors.New("global config file does not exist")
	ErrBadConfigFile    = errors.New("global config file has invalid data")
	ErrConfigFileExists = errors.New("global config file already exists")
	ErrBadConfig        = errors.New("invalid Config structure provided")
	ErrLocked           = errors.New("key needs to be unlocked first")
)

Errors relating to Config files or Config structures.

View Source
var (
	ErrMissingPolicyMetadata  = util.SystemError("missing policy metadata for encrypted directory")
	ErrPolicyMetadataMismatch = util.SystemError("inconsistent metadata between filesystem and directory")
	ErrDifferentFilesystem    = errors.New("policies may only protect files on the same filesystem")
	ErrOnlyProtector          = errors.New("cannot remove the only protector for a policy")
	ErrAlreadyProtected       = errors.New("policy already protected by protector")
	ErrNotProtected           = errors.New("policy not protected by protector")
)

Errors relating to Policies

View Source
var (
	ErrProtectorName        = errors.New("login protectors do not need a name")
	ErrMissingProtectorName = errors.New("custom protectors must have a name")
	ErrDuplicateName        = errors.New("protector with this name already exists")
	ErrDuplicateUID         = errors.New("login protector for this user already exists")
)

Errors relating to Protectors

View Source
var ConfigFileLocation = "/etc/fscrypt.conf"

ConfigFileLocation is the location of fscrypt's global settings. This can be overridden by the user of this package.

Functions

func CreateConfigFile

func CreateConfigFile(target time.Duration, useLegacy bool) error

CreateConfigFile creates a new config file at the appropriate location with the appropriate hashing costs and encryption parameters. This creation is configurable in two ways. First, a time target must be specified. This target will determine the hashing costs, by picking parameters that make the hashing take as long as the specified target. Second, the config can include the legacy option, which is needed for systems with kernels older than v4.8.

func PurgeAllPolicies

func PurgeAllPolicies(ctx *Context) error

PurgeAllPolicies removes all policy keys on the filesystem from the kernel keyring. In order for this removal to have an effect, the filesystem should also be unmounted.

Types

type Context

type Context struct {
	// Config is the struct loaded from the global config file. It can be
	// modified after being loaded to customise parameters.
	Config *metadata.Config
	// Mount is the filesystem relitive to which all Protectors and Policies
	// are added, edited, removed, and applied.
	Mount *filesystem.Mount
	// TargetUser is the user for which protectors are created and to whose
	// keyring policies are provisioned.
	TargetUser *user.User
}

Context contains the necessary global state to perform most of fscrypt's actions.

func NewContextFromMountpoint

func NewContextFromMountpoint(mountpoint string, target *user.User) (*Context, error)

NewContextFromMountpoint makes a context for the filesystem at the specified mountpoint and whose Config is loaded from the global config file. On success, the Context contains a valid Config and Mount. The target defaults the the current effective user if none is specified.

func NewContextFromPath

func NewContextFromPath(path string, target *user.User) (*Context, error)

NewContextFromPath makes a context for the filesystem containing the specified path and whose Config is loaded from the global config file. On success, the Context contains a valid Config and Mount. The target defaults the the current effective user if none is specified.

func (*Context) ProtectorOptions

func (ctx *Context) ProtectorOptions() ([]*ProtectorOption, error)

ProtectorOptions creates a slice of all the options for all of the Protectors on the Context's mountpoint.

type KeyFunc

type KeyFunc func(info ProtectorInfo, retry bool) (*crypto.Key, error)

KeyFunc is passed to a function that will require some type of key. The info parameter is provided so the callback knows which key to provide. The retry parameter indicates that a previous key provided by this callback was incorrect (this allows for user feedback like "incorrect passphrase").

For passphrase sources, the returned key should be a passphrase. For raw sources, the returned key should be a 256-bit cryptographic key. Consumers of the callback will wipe the returned key. An error returned by the callback will be propagated back to the caller.

type OptionFunc

type OptionFunc func(policyDescriptor string, options []*ProtectorOption) (int, error)

OptionFunc is passed to a function that needs to unlock a Policy. The callback is used to specify which protector should be used to unlock a Policy. The descriptor indicates which Policy we are using, while the options correspond to the valid Protectors protecting the Policy.

The OptionFunc should either return a valid index into options, which corresponds to the desired protector, or an error (which will be propagated back to the caller).

type Policy

type Policy struct {
	Context *Context
	// contains filtered or unexported fields
}

Policy represents an unlocked policy, so it contains the PolicyData as well as the actual protector key. These unlocked Polices can then be applied to a directory, or have their key material inserted into the keyring (which will allow encrypted files to be accessed). As with the key struct, a Policy should be wiped after use.

func CreatePolicy

func CreatePolicy(ctx *Context, protector *Protector) (*Policy, error)

CreatePolicy creates a Policy protected by given Protector and stores the appropriate data on the filesystem. On error, no data is changed on the filesystem.

func GetPolicy

func GetPolicy(ctx *Context, descriptor string) (*Policy, error)

GetPolicy retrieves a locked policy with a specific descriptor. The Policy is still locked in this case, so it must be unlocked before using certain methods.

func GetPolicyFromPath

func GetPolicyFromPath(ctx *Context, path string) (*Policy, error)

GetPolicyFromPath returns the locked policy descriptor for a file on the filesystem. The Policy is still locked in this case, so it must be unlocked before using certain methods. An error is returned if the metadata is inconsistent or the path is not encrypted.

func (*Policy) AddProtector

func (policy *Policy) AddProtector(protector *Protector) error

AddProtector updates the data that is wrapping the Policy Key so that the provided Protector is now protecting the specified Policy. If an error is returned, no data has been changed. If the policy and protector are on different filesystems, a link will be created between them. The policy and protector must both be unlocked.

func (*Policy) Apply

func (policy *Policy) Apply(path string) error

Apply sets the Policy on a specified directory. Currently we impose the additional constraint that policies and the directories they are applied to must reside on the same filesystem.

func (*Policy) Deprovision

func (policy *Policy) Deprovision() error

Deprovision removes the Policy key from the kernel keyring. This prevents reading and writing to the directory once the caches are cleared.

func (*Policy) Description added in v0.2.0

func (policy *Policy) Description() string

Description returns the description that will be used when the key for this Policy is inserted into the keyring

func (*Policy) Descriptor

func (policy *Policy) Descriptor() string

Descriptor returns the key descriptor for this policy.

func (*Policy) Destroy

func (policy *Policy) Destroy() error

Destroy removes a policy from the filesystem. The internal key should still be wiped with Lock().

func (*Policy) IsProvisioned

func (policy *Policy) IsProvisioned() bool

IsProvisioned returns a boolean indicating if the policy has its key in the keyring, meaning files and directories using this policy are accessible.

func (*Policy) Lock

func (policy *Policy) Lock() error

Lock wipes a Policy's internal Key. It should always be called after using a Policy. This is often done with a defer statement. There is no effect if called multiple times.

func (*Policy) ProtectorDescriptors

func (policy *Policy) ProtectorDescriptors() []string

ProtectorDescriptors creates a slice of the Protector descriptors for the protectors protecting this policy.

func (*Policy) ProtectorOptions

func (policy *Policy) ProtectorOptions() []*ProtectorOption

ProtectorOptions creates a slice of ProtectorOptions for the protectors protecting this policy.

func (*Policy) Provision

func (policy *Policy) Provision() error

Provision inserts the Policy key into the kernel keyring. This allows reading and writing of files encrypted with this directory. Requires unlocked Policy.

func (*Policy) RemoveProtector

func (policy *Policy) RemoveProtector(protector *Protector) error

RemoveProtector updates the data that is wrapping the Policy Key so that the provided Protector is no longer protecting the specified Policy. If an error is returned, no data has been changed. Note that no protector links are removed (in the case where the protector and policy are on different filesystems). The policy and protector can be locked or unlocked.

func (*Policy) Revert

func (policy *Policy) Revert() error

Revert destroys a policy if it was created, but does nothing if it was just queried from the filesystem.

func (*Policy) String

func (policy *Policy) String() string

func (*Policy) Unlock

func (policy *Policy) Unlock(optionFn OptionFunc, keyFn KeyFunc) error

Unlock unwraps the Policy's internal key. As a Protector is needed to unlock the Policy, callbacks to select the Policy and get the key are needed. This method will retry the keyFn as necessary to get the correct key for the selected protector. Does nothing if policy is already unlocked.

func (*Policy) UnlockWithProtector added in v0.2.0

func (policy *Policy) UnlockWithProtector(protector *Protector) error

UnlockWithProtector uses an unlocked Protector to unlock a policy. An error is returned if the Protector is not yet unlocked or does not protect the policy. Does nothing if policy is already unlocked.

func (*Policy) UsesProtector added in v0.2.0

func (policy *Policy) UsesProtector(protector *Protector) bool

UsesProtector returns if the policy is protected with the protector

type Protector

type Protector struct {
	Context *Context
	// contains filtered or unexported fields
}

Protector represents an unlocked protector, so it contains the ProtectorData as well as the actual protector key. These unlocked Protectors are necessary to unlock policies and create new polices. As with the key struct, a Protector should be wiped after use.

func CreateProtector

func CreateProtector(ctx *Context, name string, keyFn KeyFunc) (*Protector, error)

CreateProtector creates an unlocked protector with a given name (name only needed for custom and raw protector types). The keyFn provided to create the Protector key will only be called once. If an error is returned, no data has been changed on the filesystem.

func GetProtector

func GetProtector(ctx *Context, descriptor string) (*Protector, error)

GetProtector retrieves a Protector with a specific descriptor. The Protector is still locked in this case, so it must be unlocked before using certain methods.

func GetProtectorFromOption

func GetProtectorFromOption(ctx *Context, option *ProtectorOption) (*Protector, error)

GetProtectorFromOption retrieves a protector based on a protector option. If the option had a load error, this function returns that error. The Protector is still locked in this case, so it must be unlocked before using certain methods.

func (*Protector) Descriptor

func (protector *Protector) Descriptor() string

Descriptor returns the protector descriptor.

func (*Protector) Destroy

func (protector *Protector) Destroy() error

Destroy removes a protector from the filesystem. The internal key should still be wiped with Lock().

func (*Protector) Lock

func (protector *Protector) Lock() error

Lock wipes a Protector's internal Key. It should always be called after using an unlocked Protector. This is often done with a defer statement. There is no effect if called multiple times.

func (*Protector) Revert

func (protector *Protector) Revert() error

Revert destroys a protector if it was created, but does nothing if it was just queried from the filesystem.

func (*Protector) Rewrap

func (protector *Protector) Rewrap(keyFn KeyFunc) error

Rewrap updates the data that is wrapping the Protector Key. This is useful if a user's password has changed, for example. The keyFn provided to rewrap the Protector key will only be called once. Requires unlocked Protector.

func (*Protector) String

func (protector *Protector) String() string

func (*Protector) Unlock

func (protector *Protector) Unlock(keyFn KeyFunc) (err error)

Unlock unwraps the Protector's internal key. The keyFn provided to unwrap the Protector key will be retried as necessary to get the correct key. Lock() should be called after use. Does nothing if protector is already unlocked.

type ProtectorInfo

type ProtectorInfo struct {
	// contains filtered or unexported fields
}

ProtectorInfo is the information a caller will receive about a Protector before they have to return the corresponding key. This is currently a read-only view of metadata.ProtectorData.

func (*ProtectorInfo) Descriptor

func (pi *ProtectorInfo) Descriptor() string

Descriptor is the Protector's descriptor used to uniquely identify it.

func (*ProtectorInfo) Name

func (pi *ProtectorInfo) Name() string

Name is used to describe custom passphrase and raw key descriptors.

func (*ProtectorInfo) Source

func (pi *ProtectorInfo) Source() metadata.SourceType

Source indicates the type of the descriptor (how it should be unlocked).

func (*ProtectorInfo) UID

func (pi *ProtectorInfo) UID() int64

UID is used to identify the user for login passphrases.

type ProtectorOption

type ProtectorOption struct {
	ProtectorInfo
	// LinkedMount is the mountpoint for a linked protector. It is nil if
	// the protector is not a linked protector (or there is a LoadError).
	LinkedMount *filesystem.Mount
	// LoadError is non-nil if there was an error in getting the data for
	// the protector.
	LoadError error
}

ProtectorOption is information about a protector relative to a Policy.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL