upspin

package
v0.0.0-...-3f1964b Latest Latest
Warning

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

Go to latest
Published: Apr 1, 2024 License: Apache-2.0 Imports: 9 Imported by: 89

Documentation

Overview

Package upspin contains global interfaces and other definitions for the components of the system.

Upspin provides a global hierarchical name space for accessing arbitrary user-defined data. The interfaces for accessing and protecting data are general: Any service that implements the interfaces defined here, whether provided by the Upspin project itself or by an external agent that implements these interfaces as an alternate access method, contributes to the global name space.

The name space itself is a single rooted tree. The root of the tree contains a subdirectory for each user, called the user root, that contains all directories and storage for that user. The user root is identified by the user's name, which has an email-like format. Thus the fully qualified name (called a path name) of an item looks analogous to

user@name.com/file/name

There is no leading slash in a path name.

There are three fundamental services defined in Upspin.

* The StoreServer is the ultimate location for user-provided data. Every piece of user data stored in the system is identified by a Location, which identifies where it is stored and how to address it.

* The DirServer implements the name space, binding hierarchical, Unix-like names to Locations of data stored in StoreServers. Directories also attach metadata to file names, which may include encryption/decryption keys or other access-control information.

* The KeyServer stores, for each registered user, the Location of the user root and any public encryption keys exported by that user.

Each of these three services is itself distributed, so for instance a user root may be hosted on or split across multiple DirServer instances, which coordinate to provide a consistent view of the user's data.

Finally, the Client interface provides a coherent high-level file-like API that, internally, calls upon the other services to access and manage the data. Most applications using Upspin will talk to the Client interface alone.

Most users of Upspin will use the public KeyServer at key.upspin.io to hold their public keys, but run private DirServers and StoreServers. The shared key server combined with uniform interfaces provide a consistent public view of the system.

Many of the methods of the types in this package accept or return slices or pointers to data structures. It is a requirement that all implementations of these methods do not share data with the caller, that is, that data passed can be modified safely by the method or the caller without affecting the memory of the caller or the method, respectively.

For more information about the overall system see

upspin.io/doc/overview.md

and other documents in that directory.

Index

Constants

View Source
const (
	// WatchStart returns all known events.
	WatchStart = -iota
	// WatchCurrent first sends a sequence of events describing the entire
	// tree rooted at name. The Events are sent in sequence such that a
	// directory is sent before its contents. After the full tree has been
	// sent, the operation proceeds as normal.
	WatchCurrent
	// WatchNew returns only new events.
	WatchNew
)

Special Sequence values for Watch that can be used in place of the Sequence argument in the Watch function.

View Source
const (
	// AttrNone is the default attribute, identifying a plain data object.
	AttrNone = Attribute(0)
	// AttrDirectory identifies a directory. It must be the only attribute.
	AttrDirectory = Attribute(1 << 0)
	// AttrLink identifies a link. It must be the only attribute.
	// A link is a path name whose DirEntry identifies another
	// "target" item in the tree, similar to a Unix symbolic link.
	// The target of a link may be another link.
	// The target path is stored in the Link field of the DirEntry.
	// A link DirEntry holds zero DirBlocks.
	AttrLink = Attribute(1 << 1)
	// AttrIncomplete identifies a DirEntry whose Blocks and Packdata
	// fields are elided for access control purposes, or the reply to
	// a successful Put containing only the updated sequence number.
	AttrIncomplete = Attribute(1 << 2)
)

Supported Attributes.

View Source
const (
	SeqNotExist = -1 // Put will fail if item exists.
	SeqIgnore   = 0  // Put will not check sequence number, but will update it.
	SeqBase     = 1  // Base at which valid sequence numbers start.
)

Sequence numbers. Sequence numbers are controlled by the DirServer. For a given user root they start at SeqBase and grow monotonically (typically but not necessarily by one) with each Put or Delete operation in that user's tree. After an item is Put to or Deleted from the DirServer, the Sequence of that item (or its directory, for a Delete) and all of the directories on its path will be set to the next Sequence number for the user tree. Thus, as a corollary, any directory but in particular the user root always has the Sequence number of the most recently modified item at that level or deeper in the tree.

When a file or directory is being created, the sequence number in the DirEntry provided to Put must be either SeqNotExist or SeqIgnore.

View Source
const BlockSize = 1024 * 1024

BlockSize is an arbitrarily chosen size that packers use when breaking data into blocks for storage. Clients are free to use any size, but this value is used in various helper libraries. This is also the default value for flags.BlockSize, but must be kept in sync manually because the flags package cannot import this package.

View Source
const MaxBlockSize = 1024 * 1024 * 1024

MaxBlockSize is the maximum size permitted for a block. The limit guarantees that 32-bit machines can process the data without problems.

View Source
const MaxLinkHops = 20

MaxLinkHops is the maximum number of links that will be followed when evaluating a single path name.

Variables

View Source
var (
	// ErrFollowLink indicates that all or part of a path name has
	// evaluated to a DirEntry that is a link. In that case, the returned
	// DirEntry will be that of the link, and its Name field is guaranteed
	// to be an element-wise prefix of the argument path name. The caller
	// should retry the operation, substituting that prefix (which may be
	// the entire name) with the contents of the Link field of the returned
	// DirEntry.
	ErrFollowLink = errors.New("action incomplete: must follow link")

	// ErrNotSupported indicates that the server does not support the
	// requested operation.
	ErrNotSupported = errors.New("not supported")
)
View Source
var AllUsersKey = PublicKey("read: all")

AllUsersKey is a sentinel PublicKey value used to indicate that a Packer.Share operation should make the data readable to anyone.

View Source
var ErrTooLarge = errors.New("data item too large")

ErrTooLarge reports that an item is too large to be marshaled for transport to a potentially smaller machine. The limit is becase len(x) is of type int, which can be as small as 32 bits.

View Source
var ErrTooShort = errors.New("Unmarshal buffer too short")

ErrTooShort is returned by Unmarshal methods if the data is incomplete.

Functions

func AllFilesGlob

func AllFilesGlob(dir PathName) string

AllFilesGlob returns the Glob pattern that will match all the files in the argument directory, which is treated as a literal string (that is, it is passed through QuoteGlob). For example, given ann@machine.com/foo, it will return ann@machine.com/foo/*.

Types

type Attribute

type Attribute byte

Attribute defines the attributes for a DirEntry.

type BlockPacker

type BlockPacker interface {
	// Pack takes cleartext data and returns the packed ciphertext,
	// appending a DirBlock to the DirEntry.
	//
	// The ciphertext slice remains valid until the next call to Pack.
	Pack(cleartext []byte) (ciphertext []byte, err error)

	// SetLocation updates the Location field of the last-Packed DirBlock.
	SetLocation(Location)

	// Close updates the Signature for the DirEntry and releases any
	// resources associated with the packing operation.
	Close() error
}

BlockPacker operates on a DirEntry, packing and signing DirBlocks.

type BlockUnpacker

type BlockUnpacker interface {
	// NextBlock returns the next DirBlock in the sequence and true,
	// or a zero DirBlock and false if there are no more blocks to unpack.
	NextBlock() (DirBlock, bool)

	// SeekBlock returns the nth DirBlock and true,
	// or a zero DirBlock and false if the nth block does not exist.
	SeekBlock(n int) (DirBlock, bool)

	// Unpack takes ciphertext returns the cleartext. If appropriate, the
	// result is verified as correct according to the block's Packdata.
	//
	// The cleartext slice remains valid until the next call to Unpack.
	Unpack(ciphertext []byte) (cleartext []byte, err error)

	// Close releases any resources associated with the unpacking
	// operation.
	Close() error
}

BlockUnpacker operates on a DirEntry, unpacking and verifying its DirBlocks.

type Client

type Client interface {
	// Get returns the clear, decrypted data stored under the given name.
	// It is intended only for special purposes, since it will allocate memory
	// for the entire "blob" to return. The file-like API below can be less
	//  memory-intensive.
	Get(name PathName) ([]byte, error)

	// Lookup returns the directory entry for the named file. The
	// boolean determines whether, if the final path element is a link,
	// to return the DirEntry for the link (false) or for the target of
	// the link (true).
	Lookup(name PathName, followFinal bool) (*DirEntry, error)

	// Put stores the data at the given name. If something is already
	// stored with that name, it will no longer be available using the
	// name, although it may still exist in the storage server. (See
	// the documentation for Delete.) Like Get, it is not the usual
	// access method. The file-like API is preferred.
	//
	// A successful Put returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	Put(name PathName, data []byte) (*DirEntry, error)

	// PutSequenced stores the data at the given name only if
	// there is no preexisting data stored with that name or if the
	// sequence number of the preexisting data matches that given.
	// PutSequenced with SeqIgnore is the same as Put.
	// On success any preexisting data will no longer be available using
	// the name, although it may still exist in the storage server. (See
	// the documentation for Delete.) Like Get, it is not the usual
	// access method. The file-like API is preferred.
	//
	// A successful PutSequenced returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	PutSequenced(name PathName, seq int64, data []byte) (*DirEntry, error)

	// PutLink creates a link from the new name to the old name. The
	// new name must not look like the path to an Access or Group file.
	// If something is already stored with the new name, it is first
	// deleted from the directory but its storage is not deleted from
	// the Store. (See the documentation for Delete.) The old name is
	// not evaluated, that is, the resulting link will hold the
	// argument to PutLink even if it refers to a path that itself
	// contains links. The name is canonicalized, however (see
	// path.Clean).
	//
	// A successful PutLink returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	PutLink(oldName, newName PathName) (*DirEntry, error)

	// PutDuplicate creates a new name for the references referred to
	// by the old name. Subsequent Puts to either name do not effect
	// the contents referred to by the other. There must be no existing
	// item with the new name. If the final element of the path name
	// is a link, PutDuplicate will duplicate the link and not the
	// link target.
	//
	// A successful PutDuplicate returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	PutDuplicate(oldName, newName PathName) (*DirEntry, error)

	// MakeDirectory creates a directory with the given name, which
	// must not already exist. All but the last element of the path
	// name must already exist and be directories.
	//
	// A successful MakeDirectory returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	MakeDirectory(dirName PathName) (*DirEntry, error)

	// Rename renames oldName to newName. The old name is no longer valid.
	// If the final element of the path name is a link, Rename will
	// Rename the link itself, not the link target.
	//
	// A successful Rename returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	Rename(oldName, newName PathName) (*DirEntry, error)

	// SetTime sets the time in name's DirEntry. If the final element
	// of the path name is a link, SetTime will affect the link itself,
	// not the link target.
	SetTime(name PathName, t Time) error

	// Delete deletes the DirEntry associated with the name. The
	// storage referenced by the DirEntry is not deleted,
	// although the storage server may garbage collect unreferenced
	// data independently. If the final element of the path name is a
	// link, Delete will delete the link itself, not the link target.
	Delete(name PathName) error

	// Glob matches the pattern against the file names of the full
	// rooted tree. That is, the pattern must look like a full path
	// name, but elements of the path may contain metacharacters.
	// Matching is done using Go's path.Match elementwise. The user
	// name must be present in the pattern and is treated as a literal
	// even if it contains metacharacters. Note that if links are
	// evaluated while executing Glob, the Name fields of the returned
	// DirEntries might not match the original argument pattern.
	Glob(pattern string) ([]*DirEntry, error)

	// Open and Create are file-like methods similar to Go's os.File API.
	// The name, however, is a fully-qualified upspin PathName.
	Create(name PathName) (File, error)
	Open(name PathName) (File, error)

	// DirServer returns an error or a reachable bound DirServer for the user.
	DirServer(name PathName) (DirServer, error)
}

The Client interface provides a higher-level API suitable for applications that wish to access Upspin's name space. Most Upspin programs should use the Client interface to talk to Upspin services.

When Client evaluates a path name and encounters a link, it evaluates the link, iteratively if necessary, until it reaches an item that is not a link. (The DirServer interface does not evaluate links.)

In methods where a name is evaluated and a DirEntry returned, if links were evaluated in processing the operation, the Name field of the DirEntry will be different from the argument path name and will hold the link-free path to item.

type Config

type Config interface {
	// The name of the user requesting access.
	UserName() UserName

	// Factotum holds the user's cryptographic keys and encapsulates crypto operations.
	Factotum() Factotum

	// Packing is the Packing to use when creating new data items, although
	// it may be overridden by the implementation, such as to use a cleartext
	// packing for a globally readable ("read:all")  file.
	Packing() Packing

	// KeyEndpoint is the endpoint of the KeyServer to contact to retrieve keys.
	KeyEndpoint() Endpoint

	// DirEndpoint is the endpoint of the DirServer in which to place new data items. It is
	// usually the location of the user's root.
	DirEndpoint() Endpoint

	// StoreEndpoint is the endpoint of the StoreServer in which to place new data items.
	StoreEndpoint() Endpoint

	// CacheEndpoint is the endpoint of the cache server between the client and the StoreServer and DirServers.
	CacheEndpoint() Endpoint

	// Value returns the value for the given configuration key.
	Value(key string) string
}

Config contains client information such as the user's keys and preferred KeyServer, DirServer, and StoreServer endpoints.

type DEHash

type DEHash []byte

DEHash is a hash of the Name, Link, Attribute, Packing, and Time fields of a DirEntry. When using EE or EEIntegrity the hash also includes the block checksums; when using EE it includes the block encryption key.

type Dialer

type Dialer interface {
	// Dial connects to the service and performs any needed authentication.
	Dial(Config, Endpoint) (Service, error)
}

Dialer defines how to connect and authenticate to a server. Each service type (KeyServer, DirServer, StoreServer) implements the methods of the Dialer interface. These methods are not used directly by clients. Instead, clients should use the methods of the Upspin "bind" package to connect to services.

type DirBlock

type DirBlock struct {
	Location Location // Location of data in store.
	Offset   int64    // Byte offset of start of block's data in file.
	Size     int64    // Length of block data in bytes.
	Packdata []byte   // Information maintained by the packing algorithm.
}

DirBlock describes a block of data representing a contiguous section of a file. The block may be of any non-negative size, but in large files is usually BlockSize long.

func (*DirBlock) Copy

func (d *DirBlock) Copy() *DirBlock

Copy makes a deep copy of the block and returns a pointer to the copy.

func (*DirBlock) Marshal

func (d *DirBlock) Marshal() ([]byte, error)

Marshal packs the DirBlock into a byte slice for transport.

func (*DirBlock) MarshalAppend

func (d *DirBlock) MarshalAppend(b []byte) ([]byte, error)

MarshalAppend packs the DirBlock and appends it onto the given byte slice for transport. It will create a new slice if buf is nil and grow the slice if necessary. However, if buf's capacity is large enough, MarshalAppend will do no allocation. If it does allocate, the returned slice will point to different storage than does the input argument, as with the built-in append function.

func (*DirBlock) Unmarshal

func (d *DirBlock) Unmarshal(b []byte) ([]byte, error)

Unmarshal unpacks the byte slice to recover the encoded DirBlock.

type DirEntry

type DirEntry struct {
	// Fields contributing to the signature.
	SignedName PathName   // The full path name of the file used for signing.
	Link       PathName   // The link target, iff the DirEntry has Attr=AttrLink.
	Attr       Attribute  // Attributes for the DirEntry.
	Packing    Packing    // Packing used for every block in file.
	Time       Time       // Time associated with file; might be when it was last written.
	Blocks     []DirBlock // Descriptors for each block. A nil or empty slice represents an empty file.
	Packdata   []byte     // Information maintained by the packing algorithm.

	// Field determining the key used for the signature, hence also tamper-resistant.
	Writer UserName // Writer of the file, often the same as owner.

	// Fields not included in the signature.
	Name     PathName // The full path name of the file. Only the last element can be a link.
	Sequence int64    // The sequence (version) number of the item.
}

DirEntry represents the directory information for a file. The blocks of a file represent contiguous data. There are no holes and no overlaps and the first block always has offset 0. Name and SignedName must not be empty. See comments in DirServer.Put.

func SortDirEntries

func SortDirEntries(slice []*DirEntry, unique bool) []*DirEntry

SortDirEntries does an in-place sort of the slice of DirEntries, sorting them in increasing lexical order by Name. The boolean flag specifies whether to elide identical entries, that is, whether the result should contain entries with unique names only. (Other fields of the DirEntries are ignored.) The return value is the resulting slice, which shares storage with the original but may be shorter if unique is true.

func (*DirEntry) Copy

func (d *DirEntry) Copy() *DirEntry

Copy makes a deep copy of the entry and returns a pointer to the copy.

func (*DirEntry) IsDir

func (d *DirEntry) IsDir() bool

IsDir reports whether the entry is a directory.

func (*DirEntry) IsIncomplete

func (d *DirEntry) IsIncomplete() bool

IsIncomplete reports whether the entry is incomplete, and therefore does not have valid Blocks or Packdata.

func (d *DirEntry) IsLink() bool

IsLink reports whether the entry is a link.

func (*DirEntry) IsRegular

func (d *DirEntry) IsRegular() bool

IsRegular reports whether the entry is neither a directory nor link.

func (*DirEntry) MarkIncomplete

func (d *DirEntry) MarkIncomplete()

MarkIncomplete marks this entry as incomplete and zeroes the Blocks and Packdata fields.

func (*DirEntry) Marshal

func (d *DirEntry) Marshal() ([]byte, error)

Marshal packs the DirEntry into a new byte slice for transport.

func (*DirEntry) MarshalAppend

func (d *DirEntry) MarshalAppend(b []byte) ([]byte, error)

MarshalAppend packs the DirEntry and appends it onto the given byte slice for transport. It will create a new slice if b is nil and grow the slice if necessary. However, if b's capacity is large enough, MarshalAppend will do no allocation. If it does allocate, the returned slice will point to different storage than does the input argument, as with the built-in append function.

func (*DirEntry) Size

func (d *DirEntry) Size() (size int64, err error)

Size returns the total length of the data underlying the DirEntry and validates the block offsets and sizes. If the blocks are not contiguous, it returns an error, but does return the sum of the sizes of the underlying blocks. If a block has a negative size, it returns zero and an error.

func (*DirEntry) Unmarshal

func (d *DirEntry) Unmarshal(b []byte) ([]byte, error)

Unmarshal unpacks a marshaled DirEntry and stores it in the receiver. If successful, every field of d will be overwritten and the remaining data will be returned.

type DirServer

type DirServer interface {
	Dialer
	Service

	// Lookup returns the directory entry for the named file.
	//
	// If the returned error is ErrFollowLink, the caller should
	// retry the operation as outlined in the description for
	// ErrFollowLink. Otherwise in the case of error the
	// returned DirEntry will be nil.
	Lookup(name PathName) (*DirEntry, error)

	// Put stores the DirEntry in the directory server. The entry
	// may be a plain file, a link, or a directory. (Only one of
	// these attributes may be set.)
	// In practice the data for the file should be stored in
	// a StoreServer as specified by the blocks in the entry,
	// all of which should be stored with the same packing.
	//
	// Within the DirEntry, several fields have special properties.
	// Time represents a timestamp for the item. It is advisory only
	// but is included in the packing signature and so should usually
	// be set to a non-zero value.
	//
	// Sequence represents a sequence number that is incremented
	// after each Put. If it is neither 0 nor -1, the DirServer will
	// reject the Put operation if the file does not exist or, for an
	// existing item, if the Sequence is not the same as that
	// stored in the metadata. If it is -1, Put will fail if there
	// is already an item with that name.
	//
	// The Name field of the DirEntry identifies where in the directory
	// tree the entry belongs. The SignedName field, which usually has the
	// same value, is the name used to sign the DirEntry to guarantee its
	// security. They may differ if an entry appears in multiple locations,
	// such as in its original location plus within a second tree holding
	// a snapshot of the original tree but starting from a different root.
	//
	// Most software will concern itself only with the Name field unless
	// generating or validating the entry's signature.
	//
	// All but the last element of the path name must already exist
	// and be directories or links. The final element, if it exists,
	// must not be a directory. If something is already stored under
	// the path, the new location and packdata replace the old.
	//
	// If the returned error is ErrFollowLink, the caller should
	// retry the operation as outlined in the description for
	// ErrFollowLink (with the added step of updating the
	// Name field of the argument DirEntry). For any other error,
	// the return DirEntry will be nil.
	//
	// A successful Put returns an incomplete DirEntry (see the
	// description of AttrIncomplete) containing only the
	// new sequence number.
	Put(entry *DirEntry) (*DirEntry, error)

	// Glob matches the pattern against the file names of the full
	// rooted tree. That is, the pattern must look like a full path
	// name, but elements of the path may contain metacharacters.
	// Matching is done using Go's path.Match elementwise. The user
	// name must be present in the pattern and is treated as a literal
	// even if it contains metacharacters.
	// If the caller has no read permission for the items named in the
	// DirEntries, the returned Location and Packdata fields are cleared.
	//
	// If the returned error is ErrFollowLink, one or more of the
	// returned DirEntries is a link (the others are completely
	// evaluated). The caller should retry the operation for those
	// DirEntries as outlined in the description for ErrFollowLink,
	// updating the pattern as appropriate. Note that any returned
	// links may only partially match the original argument pattern.
	//
	// If the pattern evaluates to one or more name that identifies
	// a link, the DirEntry for the link is returned, not the target.
	// This is analogous to passing false as the second argument
	// to Client.Lookup.
	Glob(pattern string) ([]*DirEntry, error)

	// Delete deletes the DirEntry for a name from the directory service.
	// It does not delete the data it references; use StoreServer.Delete
	// for that. If the name identifies a link, Delete will delete the
	// link itself, not its target.
	//
	// If the returned error is ErrFollowLink, the caller should
	// retry the operation as outlined in the description for
	// ErrFollowLink. (And in that case, the DirEntry will never
	// represent the full path name of the argument.) Otherwise, the
	// returned DirEntry will be nil whether the operation succeeded
	// or not.
	Delete(name PathName) (*DirEntry, error)

	// WhichAccess returns the DirEntry of the Access file that is
	// responsible for the access rights defined for the named item.
	// WhichAccess requires that the calling user have at least one access
	// right granted for the argument name. If not, WhichAccess will return
	// a "does not exist" error, even if the item and/or the Access file
	// exist.
	//
	// If the returned error is ErrFollowLink, the caller should
	// retry the operation as outlined in the description for
	// ErrFollowLink. Otherwise, in the case of error the returned
	// DirEntry will be nil.
	WhichAccess(name PathName) (*DirEntry, error)

	// Watch returns a channel of Events that describe operations that
	// affect the specified path and any of its descendants, beginning
	// at the specified sequence number for the corresponding user root.
	//
	// If sequence is 0, all events known to the DirServer are sent.
	//
	// If sequence is WatchCurrent, the server first sends a sequence
	// of events describing the entire tree rooted at name. The Events are
	// sent in sequence such that a directory is sent before its contents.
	// After the full tree has been sent, the operation proceeds as normal.
	//
	// If sequence is WatchNew, the server sends only new events.
	//
	// If the sequence is otherwise invalid, this is reported by the
	// server sending a single event with a non-nil Error field with
	// Kind=errors.Invalid. The events channel is then closed.
	//
	// When the provided done channel is closed the event channel
	// is closed by the server.
	//
	// To receive an event for a given path under name, the caller must have
	// one or more of the Upspin access rights to that path. Events for
	// which the caller does not have enough rights to watch will not be
	// sent. If the caller has rights but not Read, the entry will be
	// present but incomplete (see the description of AttrIncomplete). If
	// the name does not exist, Watch will succeed and report events if and
	// when it is created.
	//
	// If the caller does not consume events in a timely fashion
	// the server will close the event channel.
	//
	// If this server does not support this method it returns
	// ErrNotSupported.
	//
	// The only errors returned by the Watch method itself are
	// to report that the name is invalid or refers to a non-existent
	// root, or that the operation is not supported.
	Watch(name PathName, sequence int64, done <-chan struct{}) (<-chan Event, error)
}

DirServer manages the name space for one or more users.

type Endpoint

type Endpoint struct {
	// Transport specifies how the network address is to be interpreted,
	// for instance that it is the URL of an HTTP service.
	Transport Transport

	// NetAddr returns the (typically) network address of the data.
	NetAddr NetAddr
}

An Endpoint identifies an instance of a service, encompassing an address such as a domain name and information (the Transport) about how to interpret that address.

func ParseEndpoint

func ParseEndpoint(v string) (*Endpoint, error)

ParseEndpoint parses the string representation of an endpoint.

func (*Endpoint) MarshalJSON

func (ep *Endpoint) MarshalJSON() ([]byte, error)

MarshalJSON implements json.Marshaler.

func (Endpoint) MarshalYAML

func (ep Endpoint) MarshalYAML() (interface{}, error)

MarshalYAML implements yaml.Marshaler. See https://godoc.org/gopkg.in/yaml.v2#Marshaler.

func (Endpoint) String

func (ep Endpoint) String() string

String converts an endpoint to a string.

func (*Endpoint) Unassigned

func (ep *Endpoint) Unassigned() bool

Unassigned (sic) reports whether the endpoint is nil or has value Unassigned.

func (*Endpoint) UnmarshalJSON

func (ep *Endpoint) UnmarshalJSON(data []byte) error

UnmarshalJSON implements json.Unmarshaler.

func (*Endpoint) UnmarshalYAML

func (ep *Endpoint) UnmarshalYAML(unmarshal func(interface{}) error) error

UnmarshalYAML implements yaml.Unmarshaler. See https://godoc.org/gopkg.in/yaml.v2#Unmarshaler.

type Event

type Event struct {
	// Entry is the DirEntry to which the event pertains. Its Sequence
	// field captures the ordering of events for this user.
	Entry *DirEntry

	// Delete is true only if the entry is being deleted;
	// otherwise it is being created or modified.
	Delete bool

	// Error is non-nil if an error occurred while waiting for events.
	// In that case, all other fields are zero.
	Error error
}

Event represents the creation, modification, or deletion of a DirEntry within a DirServer.

type Factotum

type Factotum interface {
	// DirEntryHash is a summary used in signing and verifying directory entries.
	DirEntryHash(n, l PathName, a Attribute, p Packing, t Time, dkey, hash []byte) DEHash

	// FileSign ECDSA-signs DirEntry fields and, in some packings, file contents.
	FileSign(hash DEHash) (Signature, error)

	// ScalarMult is the bare private key operator, used in unwrapping packed data.
	// Each call needs security review to ensure it cannot be abused as a signing
	// oracle. Read https://en.wikipedia.org/wiki/Confused_deputy_problem.
	ScalarMult(keyHash []byte, c elliptic.Curve, x, y *big.Int) (sx, sy *big.Int, err error)

	// Sign signs a slice of bytes with the factotum's private key.
	// The argument hash should be a cryptographic hash of the message you want to sign,
	// no longer than your key's curve order. Don't use without a security consult.
	Sign(hash []byte) (Signature, error)

	// HKDF cryptographically mixes salt, info, and the Factotum secret and
	// writes the result to out, which may be of any length but is typically
	// 8 or 16 bytes. The result is unguessable without the secret, and does
	// not leak the secret. For more information, see package
	// golang.org/x/crypto/hkdf.
	HKDF(salt, info, out []byte) error

	// Pop derives a Factotum that defaults to the previous key.
	Pop() Factotum

	// PublicKey returns the user's public key in canonical string format.
	PublicKey() PublicKey

	// PublicKeyFromHash returns the matching public key or an error.
	PublicKeyFromHash(keyHash []byte) (PublicKey, error)
}

Factotum implements an agent, potentially remote, to handle private key operations.

type File

type File interface {
	// Close releases the resources. For a writable file, it also
	// writes the accumulated data in a StoreServer. After a
	// Close, successful or not, all methods of File except Name
	// will fail.
	Close() error

	// Name returns the full path name of the File.
	Name() PathName

	// Read, ReadAt, Write, WriteAt and Seek implement
	// the standard Go interfaces io.Reader, etc.
	// Because of the nature of Upspin storage, the entire
	// item might need to be read into memory by the
	// implementation before Read can return any data.
	// Similarly, Write might accumulate all data and only
	// flush to storage once Close is called.
	Read(b []byte) (n int, err error)
	ReadAt(b []byte, off int64) (n int, err error)
	Write(b []byte) (n int, err error)
	WriteAt(b []byte, off int64) (n int, err error)
	Seek(offset int64, whence int) (ret int64, err error)
}

The File interface has semantics and an API that parallels a subset of Go's os.File. The main semantic difference, besides the limited method set, is that a Read will only return once the entire contents have been decrypted and verified.

type KeyServer

type KeyServer interface {
	Dialer
	Service

	// Lookup returns all public information about a user.
	Lookup(userName UserName) (*User, error)

	// Put sets or updates information about a user. The user's name must
	// match the authenticated user. The call can update any field except
	// the user name.
	// To add new users, see the signup subcommand of cmd/upspin.
	Put(user *User) error
}

The KeyServer interface provides access to public information about users.

type ListRefsItem

type ListRefsItem struct {
	// Ref holds the reference name.
	Ref Reference
	// Size the length of the reference data.
	Size int64
}

ListRefsItem describes a reference in a StoreServer, returned as part of a ListRefsResponse.

type ListRefsResponse

type ListRefsResponse struct {
	// Refs holds the reference information.
	Refs []ListRefsItem
	// Next holds the token to fetch the next page,
	// or the empty string if this is the last page.
	Next string
}

ListRefsResponse describes a response from a StoreServer.Get call for ListRefsMetadata.

type Location

type Location struct {
	// Endpoint identifies the machine or service where the data resides.
	Endpoint Endpoint

	// Reference is the key that will retrieve the data from the endpoint.
	Reference Reference
}

A Location identifies where a piece of data is stored and how to retrieve it.

type NetAddr

type NetAddr string

A NetAddr is the network address of service. It is interpreted by Dialer's Dial method to connect to the service.

type Packer

type Packer interface {
	// Packing returns the integer identifier of this Packing algorithm.
	Packing() Packing

	// String returns the name of this packer.
	String() string

	// Pack returns a BlockPacker that packs blocks
	// into the given DirEntry.
	Pack(Config, *DirEntry) (BlockPacker, error)

	// Unpack returns a BlockUnpacker that unpacks blocks
	// from the given DirEntry.
	Unpack(Config, *DirEntry) (BlockUnpacker, error)

	// PackLen returns an upper bound on the number of bytes required
	// to store the cleartext after packing.
	// PackLen might update the entry's Packdata field.
	// PackLen returns -1 if there is an error.
	PackLen(config Config, cleartext []byte, entry *DirEntry) int

	// UnpackLen returns an upper bound on the number of bytes
	// required to store the unpacked cleartext.
	// UnpackLen might update the entry's Packdata field.
	// UnpackLen returns -1 if there is an error.
	UnpackLen(config Config, ciphertext []byte, entry *DirEntry) int

	// ReaderHashes returns SHA-256 hashes of the public keys able to decrypt the
	// associated ciphertext.
	ReaderHashes(packdata []byte) ([][]byte, error)

	// Share updates each packdata element to enable all the readers,
	// and only those readers, to be able to decrypt the associated ciphertext,
	// which is held separate from this call. It is used to repair incorrect
	// key wrapping after access rights are changed.
	// In case of error, Share skips processing for that reader or packdata.
	// If packdata[i] is nil on return, it was skipped.
	// Share trusts the caller to check the arguments are not malicious.
	// To enable all Upspin users to decrypt the ciphertext, include
	// AllReadersKey among the provided reader keys.
	//
	// TODO: It would be nice if DirServer provided a method to report
	// which items need updates, so this could be automated.
	Share(config Config, readers []PublicKey, packdata []*[]byte)

	// Name updates the DirEntry to refer to a new path. If the new
	// path is in a different directory, the wrapped keys are reduced to
	// only that of the Upspin user invoking the method. The Packdata
	// in entry must contain a wrapped key for that user.
	Name(config Config, entry *DirEntry, path PathName) error

	// SetTime changes the Time field in a DirEntry and recomputes
	// its signature.
	SetTime(config Config, entry *DirEntry, time Time) error

	// Countersign updates the signatures in the DirEntry when a writer
	// is in the process of switching to a new key. It checks that
	// the first existing signature verifies under the old key, copies
	// that one over the second existing signature, and creates a new
	// first signature using the key from factotum.
	Countersign(oldKey PublicKey, f Factotum, d *DirEntry) error

	// UnpackableByAll reports whether the packed data may be unpacked by
	// all Upspin users. Access and Group files must have this property, as
	// should any files for which access.AllUsers have the read permission.
	UnpackableByAll(d *DirEntry) (bool, error)
}

Packer provides the implementation of a Packing. The pack package binds Packing values to the concrete implementations of this interface.

type Packing

type Packing uint8

A Packing identifies the technique for turning the data pointed to by a key into the user's data. This may involve checksum verification, decrypting, signature checking, or nothing at all. Secondary data such as encryption keys may be required to implement the packing. That data appears in the API as arguments and struct fields called packdata.

const (
	// UnassignedPack is not a packer, but a special value indicating no
	// packer was chosen. It is an error to use this value in a DirEntry
	// except when creating a directory, in which case the DirServer will
	// assign the proper packing.
	UnassignedPack Packing = 0

	// PlainPack is a no-encryption, no-integrity packing. Bytes are copied
	// untouched. DirEntry fields SignedName and so on are signed.
	PlainPack Packing = 1

	// EEPack provides elliptic-curve end-to-end confidentiality and
	// integrity protection. It stores AES-encrypted data, with metadata
	// including an ECDSA signature and ECDH-wrapped keys.
	// (NIST SP 800-57 Pt.1 Rev.4 section 5.6.1)
	// A signature and a per-file symmetric encryption key, wrapped
	// for each reader, are encoded in Packdata.
	// User keys specify a curve:
	// "p256": AES-256, SHA-256, and curve P256; strength 128.
	// "p384": AES-256, SHA-512, and curve P384; strength 192.
	// "p521": AES-256, SHA-512, and curve P521; strength 256.
	// TODO(ehg) add "25519":  x/crypto/curve25519, github.com/agl/ed25519
	EEPack Packing = 20

	// EEIntegrityPack provides elliptic-curve end-to-end integrity protection,
	// like EEPack, but provides no confidentiality.
	// It is typically used when read access is "all".
	EEIntegrityPack Packing = 22
)

func (Packing) String

func (p Packing) String() string

type PathName

type PathName string

A PathName is just a string representing a full path name. It is given a unique type so the API is clear. Example: gopher@google.com/burrow/hoard

func QuoteGlob

func QuoteGlob(p PathName) PathName

QuoteGlob returns a string that quotes all Glob metacharacters inside the argument path name; the returned string is a regular expression matching the literal text. For example, QuoteGlob`[foo]`) returns `\[foo\]`. In effect, the resulting string matches the literal text of the argument with no metacharacter processing.

type PublicKey

type PublicKey string

A PublicKey can be seen by anyone and is used for authenticating a user.

type Refdata

type Refdata struct {
	Reference Reference     // The reference itself.
	Volatile  bool          // If true, the data might change on every Get and cannot be cached.
	Duration  time.Duration // For non-volatile data, the predicted cacheable lifetime; 0 means forever.
}

Refdata attaches information about cacheability to a Reference. A Refdata is returned by a StoreServer to describe the lifetime of the data associated with a Reference.

type Reference

type Reference string

A Reference is the string identifying an item in a StoreServer. It must be a valid UTF-8-encoded Unicode string and not contain U+FFFD.

var (
	// HealthMetadata is used to check that a StoreServer is up. Servers
	// need not return any special response when asked for this reference.
	HealthMetadata Reference = "metadata:Health"

	// HTTPBaseMetadata is used to obtain a base URL from which references
	// may be requested by HTTP(S). The server may return a URL to which
	// a reference may be appended to obtain that reference's data.
	HTTPBaseMetadata Reference = "metadata:HTTP-Base"

	// FlushWritebacksMetadata is used as a signal to flush the cache.
	// A Get will return only after all writebacks have completed.
	FlushWritebacksMetadata Reference = "metadata:FlushWritebacks"

	// ListRefsMetadata is used by administrators to enumerate the
	// references held by a StoreServer. Callers pass this value verbatim
	// for the initial request and append a pagination token for subsequent
	// requests. The response from such a request is a JSON-encoded
	// ListRefsResponse.
	ListRefsMetadata Reference = "metadata:ListRefs:"
)

These special references are used to obtain out-of-band information from StoreServer implementations. StoreServers are not required to support them, in which case they may return errors.NotExist.

type Service

type Service interface {
	// Endpoint returns the network endpoint of the server.
	Endpoint() Endpoint

	// Close closes the connection to the service and releases all resources used.
	// A Service may not be re-used after close.
	Close()
}

Service is the general interface returned by a dialer. It includes methods to configure the service and report its setup.

type Signature

type Signature struct {
	R, S *big.Int
}

Signature is an ECDSA signature.

type StoreServer

type StoreServer interface {
	Dialer
	Service

	// Get attempts to retrieve the data identified by the reference.
	// Three things might happen:
	// 1. The data is in this StoreServer. It is returned. The Location slice
	// and error are nil. Refdata contains information about the data.
	// 2. The data is not in this StoreServer, but may be in one or more
	// other locations known to the store. The slice of Locations
	// is returned. The data, Refdata, Locations, and error are nil.
	// 3. An error occurs. The data, Locations and Refdata are nil
	// and the error describes the problem.
	Get(ref Reference) ([]byte, *Refdata, []Location, error)

	// Put puts the data into the store and returns the reference
	// to be used to retrieve it.
	Put(data []byte) (*Refdata, error)

	// Delete permanently removes all storage space associated
	// with the reference. After a successful Delete, calls to Get with the
	// same reference will fail. If the reference is not found, an error is
	// returned. Implementations may disable this method except for
	// privileged users.
	Delete(ref Reference) error
}

The StoreServer saves and retrieves data without interpretation.

type Time

type Time int64

Time represents a timestamp in units of seconds since the Unix epoch, Jan 1 1970 0:00 UTC.

func Now

func Now() Time

Now returns the current Upspin Time.

func TimeFromGo

func TimeFromGo(t time.Time) Time

TimeFromGo returns the Upspin Time value representation of a Go time.

func (Time) Go

func (t Time) Go() time.Time

Go returns the Go Time value representation of an Upspin time. The time zone always UTC.

func (Time) String

func (t Time) String() string

String returns a default string representation of the time, in the format similar to RFC 3339: "2006-01-02T15:04:05 UTC" The time zone is always UTC.

type Transport

type Transport uint8

Transport identifies the type of access required to reach the data, that is, the realm in which the network address within a Location is to be interpreted.

const (
	// Unassigned denotes a connection to a service that returns an error
	// from every method call. It is useful when a component wants to
	// guarantee it does not access another service.
	// It is also the zero value for Transport.
	Unassigned Transport = iota

	// InProcess denotes that contents are located in the current process,
	// typically in memory.
	InProcess

	// Remote denotes a connection to a remote server through RPC.
	// (Although called remote, the service may be running on the same machine.)
	// The Endpoint's NetAddr contains the HTTP address of the server.
	Remote
)

func (Transport) String

func (t Transport) String() string

type User

type User struct {
	// Name represents the user's name as an e-mail address, such as ann@example.com.
	Name UserName

	// Dirs is a slice of DirServer endpoints where the user's root directory may be located,
	// which should be contacted in order when trying to access the user's tree. Multiple
	// entries represent mirrors, which are as yet unimplemented. TODO.
	Dirs []Endpoint

	// Stores is a slice of StoreServer endpoints where the user's data is primarily written to,
	// which should be contacted in order when trying to access the user's data. Multiple
	// entries represent mirrors, which are as yet unimplemented. TODO.
	Stores []Endpoint

	// PublicKey is the user's current public key.
	PublicKey PublicKey
}

User represents all the public information about an Upspin user as returned by KeyServer.

type UserName

type UserName string

A UserName is just an e-mail address representing a user. It is given a unique type so the API is clear. The user part may contain an optional suffix after a plus sign. Examples: gopher@google.com, me+you@forever.com

Directories

Path Synopsis
Package proto contains the protocol buffer definitions shared between RPC servers and clients, mirroring the interfaces and types in the upspin package itself.
Package proto contains the protocol buffer definitions shared between RPC servers and clients, mirroring the interfaces and types in the upspin package itself.

Jump to

Keyboard shortcuts

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