Documentation
¶
Overview ¶
Package database provides a pure-Go SQLite-backed credential store.
Index ¶
- Constants
- Variables
- func CanJoin(dbPath string, m UnlockMaterial, folderID string) (rejoin bool, err error)
- func CheckFolderRename(from, to string) error
- func CheckMasterPassword(pw []byte, m UnlockMaterial) error
- func CheckTagRename(from, to string) error
- func CopyTo(dbPath, dest string) (err error)
- func Decrypt(key, ciphertext []byte) ([]byte, error)
- func DecryptEntry(masterKey, encryptedData, salt, aad []byte) ([]byte, error)
- func DefaultDBLocation() (string, error)
- func DefaultDBPath() (string, error)
- func DeriveKey(password, salt []byte, params Argon2idParams) []byte
- func Encrypt(key, plaintext []byte) ([]byte, error)
- func EncryptEntry(masterKey, plaintext, aad []byte) (encryptedData, salt []byte, err error)
- func GenerateSalt(length int) ([]byte, error)
- func IsDamaged(err error) bool
- func JoinVault(dbPath string, m UnlockMaterial, folderID string, links []syncfolder.KeyLink) (rejoin bool, err error)
- func KeySealer(key []byte) syncfolder.Sealer
- func LinkProofHolds(old syncfolder.Sealer, l *syncfolder.KeyLink) bool
- func NewKeyLink(oldKey, newKey []byte, from, to string) (*syncfolder.KeyLink, error)
- func OpenKeyLink(sealer syncfolder.Sealer, l *syncfolder.KeyLink) ([]byte, error)
- func RemoveRecovery(dbPath string) (err error)
- func ReplaceVault(dbPath, backupPath string, now time.Time) (aside string, err error)
- func RestoreInPlace(dbPath, backupPath string) error
- func UnionLinks(a, b []syncfolder.KeyLink) []syncfolder.KeyLink
- func UnlockID(verify []byte) string
- func ValidateUnlockMaterial(salt, verify []byte, params Argon2idParams) error
- func VaultID(dbPath string) (_ string, err error)
- func VaultKeyChange(dbPath string) (id string, err error)
- func VaultKeyLinks(dbPath string) (_ []syncfolder.KeyLink, err error)
- func VaultSyncFolder(dbPath string) (id string, err error)
- func VerifiedLinks(key []byte, id string, links []syncfolder.KeyLink) []syncfolder.KeyLink
- func WriteRecovery(dbPath string, r *RecoveryRecord) (err error)
- type Argon2idParams
- type AuditEntry
- type BackupSummary
- type CryptoOracle
- type EntryEdit
- type EntryProblem
- type FolderCount
- type ImportedHistory
- type KeySource
- type MasterPasswordSource
- type OlderKeys
- type Option
- type PasswordPromptFunc
- type ProblemKind
- type RecoveryOutcome
- type RecoveryRecord
- type RekeyOptions
- type RekeyResult
- type RekeySync
- type Restored
- type SeenRecovery
- type Store
- func (s *Store) AddTag(keys []vault.Key, tag string) (int, error)
- func (s *Store) AuditCountEstimate() (int64, error)
- func (s *Store) AuditEvents(limit int) (_ []AuditEntry, err error)
- func (s *Store) AuditSummary() (count int64, oldest time.Time, err error)
- func (s *Store) CheckKey() error
- func (s *Store) CheckUnlocked() error
- func (s *Store) ClearAudit() (int64, error)
- func (s *Store) Close() error
- func (s *Store) CodeKey(k vault.Key) ([]byte, error)
- func (s *Store) Compact() error
- func (s *Store) DataVersion() (int64, error)
- func (s *Store) Delete(k vault.Key) error
- func (s *Store) DeleteMany(keys []vault.Key) error
- func (s *Store) Details(k vault.Key, reading string) (vault.Details, error)
- func (s *Store) EachSecret(reading string, kinds []vault.Kind, ...) (n int, err error)
- func (s *Store) Edit(k vault.Key, given *EntryEdit) (string, error)
- func (s *Store) EmptyTrash() (int, error)
- func (s *Store) Exists(k vault.Key) error
- func (s *Store) ExpireTrash(cutoff time.Time) (int, error)
- func (s *Store) Fingerprint() ([sha256.Size]byte, error)
- func (s *Store) Folders() ([]FolderCount, error)
- func (s *Store) ForgetVersionOf(k vault.Key, v Version) error
- func (s *Store) ForgetVersions(k vault.Key, ns ...int) error
- func (s *Store) Get(k vault.Key) ([]byte, error)
- func (s *Store) GetFor(k vault.Key, reading string) ([]byte, error)
- func (s *Store) HasEntries() (bool, error)
- func (s *Store) History(k vault.Key) (_ []Version, err error)
- func (s *Store) HistoryKeep() int
- func (s *Store) KeepAlive() error
- func (s *Store) LastAuditEvent(eventType string) (*AuditEntry, error)
- func (s *Store) LastReads(ignoring ...string) (map[string]int64, error)
- func (s *Store) List(f *vault.Filter) (_ []vault.Entry, err error)
- func (s *Store) LogDoctor(detail string)
- func (s *Store) LogImport(detail string)
- func (s *Store) LogSync(detail string)
- func (s *Store) Lookup(k vault.Key) (vault.Entry, error)
- func (s *Store) MoveToFolder(keys []vault.Key, folder string) (int, error)
- func (s *Store) Path() string
- func (s *Store) PruneAudit(before time.Time) (int64, error)
- func (s *Store) PruneHistory(keep int) (int, error)
- func (s *Store) PurgeMany(keys []vault.Key) error
- func (s *Store) Put(k vault.Key, secret []byte) error
- func (s *Store) ReadVersion(k vault.Key, n int, reading string) ([]byte, error)
- func (s *Store) ReadVersionOf(k vault.Key, v Version, reading string) ([]byte, error)
- func (s *Store) Reader() (*Store, error)
- func (s *Store) Recovery() (*RecoveryRecord, error)
- func (s *Store) Rekey(newKey []byte, rec UnlockMaterial, ...) (RekeyResult, error)
- func (s *Store) RemoveFromTrash(ids ...int64) ([]vault.Key, error)
- func (s *Store) RemoveTag(keys []vault.Key, tag string) (int, error)
- func (s *Store) RenameFolder(from, to string) (n int, merged bool, err error)
- func (s *Store) RenameTag(from, to string) (n int, merged bool, err error)
- func (s *Store) RestoreFromTrash(id int64, as vault.Key) (Restored, error)
- func (s *Store) RestoreVersion(k vault.Key, n int) (kept bool, err error)
- func (s *Store) RestoreVersionOf(k vault.Key, v Version) (kept bool, err error)
- func (s *Store) Save(e *vault.Entry, secret []byte) error
- func (s *Store) SaveImported(e *vault.Entry, secret []byte, d *vault.Details, earlier []vault.Earlier) (ImportedHistory, error)
- func (s *Store) SaveWithDetails(e *vault.Entry, secret []byte, d *vault.Details) error
- func (s *Store) SetDetails(k vault.Key, d *vault.Details) error
- func (s *Store) SetHistoryKeep(n int)
- func (s *Store) SetSettings(k vault.Key, settings *vault.Settings) error
- func (s *Store) SetTrashDays(days int)
- func (s *Store) Size() (int64, error)
- func (s *Store) SyncAddTyped(uid string, t *syncfolder.Typed) error
- func (s *Store) SyncAgree(uid string, rev int64, rec *syncfolder.Record, hash syncfolder.Hash) error
- func (s *Store) SyncApply(uid string, rev int64, rec *syncfolder.Record, hash syncfolder.Hash) (int64, error)
- func (s *Store) SyncBase(uid string) (*syncfolder.Record, error)
- func (s *Store) SyncCheck(rec *syncfolder.Record) error
- func (s *Store) SyncComputerID() (string, error)
- func (s *Store) SyncDropEntry(uid string) error
- func (s *Store) SyncFolderID() (string, error)
- func (s *Store) SyncItems() (_ []SyncItem, err error)
- func (s *Store) SyncKeyChange() (string, error)
- func (s *Store) SyncKeyChangeSent() error
- func (s *Store) SyncKeyID() (string, error)
- func (s *Store) SyncKeyLinks() ([]syncfolder.KeyLink, error)
- func (s *Store) SyncLeftDone(uid string) error
- func (s *Store) SyncMendBase(uid string, rec *syncfolder.Record) error
- func (s *Store) SyncNextChange(seen uint64) (uint64, error)
- func (s *Store) SyncOlderKeys() (*OlderKeys, error)
- func (s *Store) SyncRecord(uid, computer string) (_ *syncfolder.Record, rev int64, err error)
- func (s *Store) SyncRecovery() (SeenRecovery, error)
- func (s *Store) SyncRecoverySent(r *syncfolder.Recovery) error
- func (s *Store) SyncSealer() syncfolder.Sealer
- func (s *Store) SyncSetForgotten(uid string, marks []syncfolder.Forgotten) error
- func (s *Store) SyncStartFolder(folderID string) error
- func (s *Store) SyncTakeRecovery(r *SeenRecovery, rec *RecoveryRecord, had []byte) error
- func (s *Store) SyncTyped(uid string) ([]*syncfolder.Typed, error)
- func (s *Store) SyncTypedChecks() error
- func (s *Store) SyncTypedKept(uid, computer string) error
- func (s *Store) SyncWarnFresh(line string, within time.Duration, now time.Time) (bool, error)
- func (s *Store) Tags() (tags []TagCount, untagged int, err error)
- func (s *Store) Trash() (_ []TrashedEntry, err error)
- func (s *Store) TrashDays() int
- func (s *Store) Verify() (VerifyReport, error)
- type SyncAgreed
- type SyncItem
- type SyncPlace
- type TagCount
- type TrashedEntry
- type UnlockMaterial
- type VerifyReport
- type Version
Constants ¶
const MaxSecretSize = 1 << 20 // 1 MiB
MaxSecretSize is the largest secret the store accepts. It applies however the store encrypts, so a secret that saves directly also saves through the agent, whose wire frames must carry it.
const VerifyPlaintext = "sesh-verify"
VerifyPlaintext is the known string sealed into the key record's verify blob. A successful open under the derived key proves the password.
Variables ¶
var ErrDecrypt = errors.New("doesn't decrypt")
ErrDecrypt means a ciphertext doesn't decrypt with the key it was given: it's damaged, or was made with another key. Other errors (no key, a lost agent connection) are something else.
var ErrEntryChanged = errors.New("the entry was changed by another sesh command meanwhile; run this again")
ErrEntryChanged is an entry changed by another sesh command while an edit was re-sealing its secret.
var ErrNameTaken = errors.New("another entry has that name")
ErrNameTaken is an edit's new name being another entry's.
var ErrNoRecovery = errors.New("this vault has no recovery key")
ErrNoRecovery means the vault has no recovery key.
var ErrNoVault = errors.New("no vault yet")
ErrNoVault means there is no vault at the path yet, or one whose master password was never set: the next open creates it.
var ErrNoVersion = errors.New("no such version")
ErrNoVersion is a version number an entry's history doesn't have.
var ErrNotInTrash = errors.New("no entry in the trash has that id")
ErrNotInTrash is a trash id with no entry.
var ErrNothingToChange = errors.New("nothing to change")
ErrNothingToChange is an edit that would leave the entry as it is.
var ErrRecoveryChanged = errors.New("the vault's recovery key changed meanwhile")
ErrRecoveryChanged means the vault's recovery key record changed (another sesh command made or removed one) while a sync was taking the folder's: nothing was taken, and the next sync looks again.
var ErrRejoinOtherKey = errors.New("this vault synced with this folder before, but its master password, or the folder's, has changed since")
ErrRejoinOtherKey is a vault joining again the sync folder it synced with, but under another master password than the folder's now: one of them changed it since.
var ErrSecretTooLarge = errors.New("secret too large")
ErrSecretTooLarge is returned when a secret exceeds MaxSecretSize.
var ErrTryAnotherPassword = errors.New("choose a stronger master password")
ErrTryAnotherPassword is what a new-password check returns to have a different master password asked for.
var ErrVaultBusy = errors.New("another sesh command was using the vault")
ErrVaultBusy means another connection, such as another sesh command, was reading the vault for longer than Compact waits.
var ErrVaultKeyChanged = errors.New("the vault's master password was changed by another sesh command while this one ran; run this again")
ErrVaultKeyChanged means the vault's master password was changed after this command unlocked it: its key no longer opens the vault.
var ErrVaultNotEmpty = errors.New("this vault already has entries of its own, never synced with this folder")
ErrVaultNotEmpty is a vault that can't join a sync folder: it has entries, sealed with its own key (its own salt, even with the same master password).
var ErrVersionGone = errors.New("that earlier secret isn't in the history any more")
ErrVersionGone is a version, named by its row, that's no longer in the entry's history: another command forgot it, or dropped it to history.keep.
var ErrWrongPassword = errors.New("wrong master password")
ErrWrongPassword means every master password attempt failed.
Functions ¶
func CanJoin ¶
func CanJoin(dbPath string, m UnlockMaterial, folderID string) (rejoin bool, err error)
CanJoin says whether the vault at dbPath may join the sync folder folderID, whose vaults' key record is m: none there yet, an empty one, or one joining again the folder it synced with before, under its key (rejoin); ErrRejoinOtherKey for one that synced with it under another; ErrVaultNotEmpty for any other with entries, in the trash or in history. It changes nothing, so a command can check before asking for the master password.
func CheckFolderRename ¶
CheckFolderRename refuses renaming folder from to to without looking at the vault: a name either can't have, the same name, or a folder under from, which would move from into itself.
func CheckMasterPassword ¶
func CheckMasterPassword(pw []byte, m UnlockMaterial) error
CheckMasterPassword says whether pw is the master password of the key record m, without a vault: an error when it isn't.
func CheckTagRename ¶
CheckTagRename refuses renaming tag from to to without looking at the vault: a name either can't have, or the same name.
func CopyTo ¶
CopyTo writes a consistent copy of the vault at dbPath to dest, which must not exist: SQLite's VACUUM INTO, safe while other sesh commands use the vault. The copy holds what the vault does, secrets still encrypted, so making it needs no key. A vault SQLite's integrity check finds damaged is refused, so a damaged vault never replaces good backups. (The quick check doesn't compare indexes with their tables, and a personal vault is small enough for the full one.)
func Decrypt ¶
Decrypt decrypts ciphertext produced by Encrypt using AES-256-GCM. The key must be exactly 32 bytes.
func DecryptEntry ¶
DecryptEntry decrypts data produced by EncryptEntry with the same aad.
func DefaultDBLocation ¶
DefaultDBLocation is DefaultDBPath without creating the directory, for showing the path without touching the filesystem.
func DefaultDBPath ¶
DefaultDBPath returns the platform-appropriate path for the sesh database.
- macOS: ~/Library/Application Support/sesh/passwords.db
- Linux: $XDG_DATA_HOME/sesh/passwords.db (falls back to ~/.local/share/sesh/passwords.db; a relative $XDG_DATA_HOME is ignored per the XDG Base Directory spec)
- Windows: %APPDATA%/sesh/passwords.db (falls back to ~/AppData/Roaming/sesh/passwords.db)
func DeriveKey ¶
func DeriveKey(password, salt []byte, params Argon2idParams) []byte
DeriveKey uses Argon2id to derive an encryption key from a password and salt.
func Encrypt ¶
Encrypt encrypts plaintext using AES-256-GCM with the provided key. The returned ciphertext is nonce || encrypted_data || tag. The key must be exactly 32 bytes; shorter keys are rejected rather than accepted as AES-128 or AES-192.
func EncryptEntry ¶
EncryptEntry encrypts plaintext for storage, generating a per-entry salt and deriving a per-entry key from the master key material + salt. aad is authenticated but not encrypted: decrypting needs the same aad, which binds the ciphertext to what aad names (an entry's key). Returns (encryptedData, salt, error).
func GenerateSalt ¶
GenerateSalt produces a cryptographically random salt of the given length.
func IsDamaged ¶
IsDamaged reports whether err shows the vault file is damaged: SQLite finding it corrupt or not a database, or a key record that fails its checks.
func JoinVault ¶
func JoinVault(dbPath string, m UnlockMaterial, folderID string, links []syncfolder.KeyLink) (rejoin bool, err error)
JoinVault readies the vault at dbPath to join the sync folder folderID, whose vaults' key record is m, the master password already checked against it (CheckMasterPassword). A vault joining again the folder it synced with, under its key, is left as it is (rejoin): what it agreed with the folder before it left is kept, so what changed on both sides since merges as any change does. Any other with entries is refused (ErrVaultNotEmpty): with nothing agreed, it would bring back, as edits, entries deleted elsewhere. A new or empty vault gets m as its key record, so the same master password gives the same key; one that had another loses its recovery record, made for that key. Whatever it kept of an earlier sync (what it agreed, its sync ID, restored and forgotten marks) goes: it starts afresh.
links are the folder's key links, which a new or emptied vault takes.
func LinkProofHolds ¶
func LinkProofHolds(old syncfolder.Sealer, l *syncfolder.KeyLink) bool
LinkProofHolds says whether l's proof opens with old, the sealer of the key l comes from: whether the change was made by a computer that had it.
func NewKeyLink ¶
func NewKeyLink(oldKey, newKey []byte, from, to string) (*syncfolder.KeyLink, error)
NewKeyLink is the master password change from oldKey, whose key record's ID is from, to newKey, whose is to.
func OpenKeyLink ¶
func OpenKeyLink(sealer syncfolder.Sealer, l *syncfolder.KeyLink) ([]byte, error)
OpenKeyLink is the old key l holds, opened with sealer, the new key's. The caller zeroes it.
func RemoveRecovery ¶
RemoveRecovery removes the recovery key record of the vault at dbPath, if it has one.
func ReplaceVault ¶
ReplaceVault replaces the vault at dbPath, missing or damaged, with a copy of the backup at backupPath, which InspectBackup has passed. A vault there is moved aside, never deleted: to <vault>.before-restore-<time>, with its -wal and -shm, so what can still be read of it isn't lost, and its returned path says where. The -wal and -shm go with it rather than staying, where SQLite would apply them to the copy. A symlinked vault is replaced where it really is. No sesh command should be using the vault meanwhile. Once the copy is in place the restore stands: recording it only warns.
func RestoreInPlace ¶
RestoreInPlace replaces the sound vault at dbPath with the backup at backupPath, which InspectBackup has passed, in one transaction: every table but the audit log comes from the backup, and a "restore" event is added. A sesh command with the vault open never sees a half-restored vault, and one that unlocked it before is refused its next write if the key changed (ErrVaultKeyChanged). Once the transaction commits, the restore stands: tidying up after it only warns.
func UnionLinks ¶
func UnionLinks(a, b []syncfolder.KeyLink) []syncfolder.KeyLink
UnionLinks are the links of a and b, each once (by the two key records it joins), a's first and kept over b's: callers give a vault's own, whose proofs were checked, before a folder's, where anyone can add one alongside the real one.
func UnlockID ¶
UnlockID names a vault's key record by its verify blob: the hex SHA-256 of it. The blob is stored in the vault, so the id is not a secret. A password change gives the vault a new one.
func ValidateUnlockMaterial ¶
func ValidateUnlockMaterial(salt, verify []byte, params Argon2idParams) error
ValidateUnlockMaterial checks the fields an unlock derives from. The master-password source and the agent both call it, so they accept exactly the same material.
func VaultID ¶
VaultID returns the vault's id: random, made with it, and never changed. It reads the vault without writing to it.
func VaultKeyChange ¶
VaultKeyChange is the vault at dbPath's SyncKeyChange, read without unlocking it: "" when there's no change to send, or no vault.
func VaultKeyLinks ¶
func VaultKeyLinks(dbPath string) (_ []syncfolder.KeyLink, err error)
VaultKeyLinks are the master password changes of the vault at dbPath, read without unlocking it; none when there's no vault.
func VaultSyncFolder ¶
VaultSyncFolder is the ID of the sync folder the vault at dbPath syncs with, or did before it left; "" when none, or there's no vault. It changes nothing.
func VerifiedLinks ¶
func VerifiedLinks(key []byte, id string, links []syncfolder.KeyLink) []syncfolder.KeyLink
VerifiedLinks are those of links reached back from the key record id, whose key is key, each opening and its proof holding (NewCheckedOlderKeys).
func WriteRecovery ¶
func WriteRecovery(dbPath string, r *RecoveryRecord) (err error)
WriteRecovery makes r the recovery key record of the vault at dbPath, replacing any earlier one. It refuses with ErrVaultKeyChanged when r was made for a key record the vault no longer has.
Types ¶
type Argon2idParams ¶
Argon2idParams are the Argon2id settings a vault's key record holds.
func DefaultArgon2idParams ¶
func DefaultArgon2idParams() Argon2idParams
DefaultArgon2idParams returns the settings a new key record uses unless configured otherwise.
func UnmarshalArgon2idParams ¶
func UnmarshalArgon2idParams(data string) (Argon2idParams, error)
UnmarshalArgon2idParams deserialises Argon2id parameters from JSON.
type AuditEntry ¶
type AuditEntry struct {
CreatedAt time.Time
EventType string
EntryID string // nullable — empty for auth events
Detail string
ID int64
}
AuditEntry represents a row in the audit_log table.
type BackupSummary ¶
type BackupSummary struct {
VaultID string
// Entries is how many entries the backup holds; Trashed, how many of
// its entries are in the trash.
Entries, Trashed int
}
BackupSummary is what InspectBackup found in a backup: whose it is, and how many entries it holds.
func InspectBackup ¶
func InspectBackup(path string) (BackupSummary, error)
InspectBackup checks that the file at path is a sound sesh vault this build can restore: its schema is this build's, SQLite's integrity check passes, and it has a key record and an id. It never writes to the file.
func VaultSummary ¶
func VaultSummary(dbPath string) (BackupSummary, error)
VaultSummary is InspectBackup for the vault itself, read only: its id and entries, or why it can't be read. A vault that's missing, or new (no key record and no entries), is ErrNoVault; a damaged one, IsDamaged.
type CryptoOracle ¶
type CryptoOracle interface {
// EncryptEntry seals plaintext under the master key and returns the
// ciphertext plus the per-entry salt.
EncryptEntry(plaintext, aad []byte) (encryptedData, salt []byte, err error)
// DecryptEntry opens a blob produced by EncryptEntry.
DecryptEntry(encryptedData, salt, aad []byte) ([]byte, error)
}
CryptoOracle encrypts and decrypts entry secrets without exposing the raw master key to the caller. Store depends only on this. The agent's key source implements it directly; a KeySource becomes one through NewKeySourceOracle.
func NewKeySourceOracle ¶
func NewKeySourceOracle(ks KeySource) CryptoOracle
NewKeySourceOracle returns a CryptoOracle backed by ks. Closing the oracle closes ks when ks has a Close method.
type EntryEdit ¶
type EntryEdit struct {
To *vault.Key
Details *vault.DetailsChange
Folder *string
Tags *[]string
TOTP *totp.Params
// FileName is a file entry's new file name, with its new content.
FileName *string
// AWSMFADevice is an AWS profile's entry's new MFA device (its ARN),
// "" for none.
AWSMFADevice *string
Secret []byte
}
EntryEdit is a change to an entry: To, its new key (nil keeps it); Secret, its new secret (nil keeps it; the caller zeroes it); Details, a change to its details (nil keeps them); Folder, the folder it's in after (nil keeps it, "" is none); Tags, all its tags after (nil keeps them); and TOTP, its code's settings after (nil keeps them).
type EntryProblem ¶
type EntryProblem struct {
Err error
Key vault.Key
Kind ProblemKind
// TrashID is the entry's id in the trash, 0 for one that isn't.
TrashID int64
// Version is, for an earlier secret of a live entry's, its version
// number (2 and up, as sesh history numbers them); 0 otherwise.
Version int
}
EntryProblem is an entry Verify couldn't read: its secret or details don't decrypt, or its settings, times, or details don't parse.
type FolderCount ¶
FolderCount is a folder and how many entries it holds: Entries in it alone, Total with its subfolders'. Name "" counts the entries in no folder.
type ImportedHistory ¶
type ImportedHistory struct {
Kept, NoRoom, TooLarge int
}
ImportedHistory is what SaveImported did with an entry's earlier secrets, leaving out those the entry already had: how many it kept, and how many it didn't, for lack of room under history.keep or for being over MaxSecretSize.
type KeySource ¶
type KeySource interface {
// GetEncryptionKey returns the master encryption key.
// The caller must zero the returned slice after use.
GetEncryptionKey() ([]byte, error)
}
KeySource provides the master encryption key: MasterPasswordSource derives it from the master password.
type MasterPasswordSource ¶
type MasterPasswordSource struct {
// contains filtered or unexported fields
}
MasterPasswordSource derives the encryption key from a user-supplied passphrase via Argon2id, with the salt and settings in the vault's key record (vault_key.go).
func NewMasterPasswordSource ¶
func NewMasterPasswordSource(dbPath string, prompt PasswordPromptFunc, opts ...Option) *MasterPasswordSource
NewMasterPasswordSource creates a MasterPasswordSource for the vault at dbPath, which must be absolute.
func (*MasterPasswordSource) Close ¶
func (s *MasterPasswordSource) Close()
Close zeroes and releases the cached key. Safe to call multiple times and safe to call concurrently with GetEncryptionKey. Bumping cacheEpoch fences any in-flight derivation from re-populating the cache after Close returns.
func (*MasterPasswordSource) GetEncryptionKey ¶
func (s *MasterPasswordSource) GetEncryptionKey() ([]byte, error)
GetEncryptionKey prompts for the master password and derives the encryption key. For a new vault it prompts twice for confirmation and creates the vault with its key record. Otherwise it checks the password against the key record's verify blob. The derived key is cached for the lifetime of this source so repeated Get/Set operations within one invocation do not re-prompt.
Per the KeySource contract the caller is free to zero the returned slice — the cache holds a private copy. Call Close() to clear the cached key when done.
func (*MasterPasswordSource) NewKey ¶
func (s *MasterPasswordSource) NewKey() ([]byte, UnlockMaterial, error)
NewKey asks for a new master password, and returns the key it gives with a new salt and the key record for it, for a password change. Nothing is written. The caller zeroes the key.
func (*MasterPasswordSource) UnlockID ¶
func (s *MasterPasswordSource) UnlockID() (string, error)
UnlockID is the id of the key record this source's key was checked against, unlocking first if it hasn't yet.
type OlderKeys ¶
type OlderKeys struct {
// contains filtered or unexported fields
}
OlderKeys are the keys a vault had before master password changes, reached through key links from a key whose sealer it has: every link whose new key is reached opens to its old one, whatever order or branch the changes came in. Opened when first asked for, and zeroed by Close.
func NewCheckedOlderKeys ¶
func NewCheckedOlderKeys(sealer syncfolder.Sealer, id string, links []syncfolder.KeyLink) *OlderKeys
NewCheckedOlderKeys are NewOlderKeys taking only links whose proof holds with the key they open to: for links read from a sync folder, so each key reached is one a change was made from.
func NewOlderKeys ¶
func NewOlderKeys(sealer syncfolder.Sealer, id string, links []syncfolder.KeyLink) *OlderKeys
NewOlderKeys are the keys reached back through links from the key record whose ID is id, which sealer opens with.
func (*OlderKeys) Key ¶
Key is the older key whose key record's ID is id, nil when it isn't reached. It's zeroed by Close.
func (*OlderKeys) Sealer ¶
func (o *OlderKeys) Sealer(id string) syncfolder.Sealer
Sealer is a sealer for the older key whose key record's ID is id, nil when it isn't reached.
func (*OlderKeys) Used ¶
func (o *OlderKeys) Used() []syncfolder.KeyLink
Used are the links the walk opened (with NewCheckedOlderKeys, those whose proofs held), in the order given.
type Option ¶
type Option func(*MasterPasswordSource)
Option configures a MasterPasswordSource. Use with NewMasterPasswordSource.
func WithKDFParams ¶
func WithKDFParams(p Argon2idParams) Option
WithKDFParams sets the Argon2id settings a new key record gets (when the vault is created, or its master password changed); the default is kdf.Default(). Unlocking uses the settings the key record holds.
func WithMaxAttempts ¶
WithMaxAttempts sets the maximum number of password prompts the unlock loop will issue before giving up. Values < 1 are clamped to 1. Only wrong-password failures are retried; key record and I/O errors fail immediately.
The prompt callback must produce fresh user input on each invocation — a callback that returns a constant value (e.g., one backed by an env var) will derive the same wrong key N times and waste ~N × Argon2id cycles before failing. The CLI gates this via resolvePasswordPrompt in main.go, which only marks a prompt interactive when it actually reads fresh bytes; direct callers must apply the same discipline.
Only affects unlock(); first-run create+confirm always runs once.
func WithNewPasswordCheck ¶
WithNewPasswordCheck vets each new master password (at first run, or when a rotation or recovery sets a new one) before it's confirmed. Returning ErrTryAnotherPassword asks for another, up to newPasswordTries times; any other error stops creation. Unlocking never runs it.
type PasswordPromptFunc ¶
PasswordPromptFunc is called to obtain the master password from the user. Implementations should not echo the input.
type ProblemKind ¶
type ProblemKind int
ProblemKind is what Verify couldn't read in an entry.
const ( // ProblemSecret: the secret doesn't decrypt with the vault's key. ProblemSecret ProblemKind = iota + 1 // ProblemSettings: the settings don't parse. ProblemSettings // ProblemTimes: the creation or update time doesn't read, or, in the // trash, when it was deleted. ProblemTimes // ProblemDetails: the notes and custom fields don't decrypt or read. ProblemDetails // ProblemTags: an entry in the trash's tags don't read. ProblemTags )
The kinds of entry problem.
type RecoveryOutcome ¶
type RecoveryOutcome int
RecoveryOutcome is what a password change did with the vault's recovery key record.
const ( // RecoveryNone: the vault had no recovery key record. RecoveryNone RecoveryOutcome = iota // RecoveryKept: the record was re-wrapped to the new key. RecoveryKept // RecoveryRemoved: the record was removed, as a recovery asks. RecoveryRemoved // RecoveryStale: the record was for another vault, so it was removed. RecoveryStale )
The outcomes.
type RecoveryRecord ¶
type RecoveryRecord struct {
CreatedAt time.Time
// UnlockID is the id of the key record the wrap is bound to.
UnlockID string
PublicKey []byte
EphemeralPub []byte
Ciphertext []byte
}
RecoveryRecord is what lets a recovery key open the vault: the recovery key's public key, and the vault key wrapped to it (internal/recovery). Nothing in it opens the vault without the written-down recovery key. A vault has at most one.
func ReadRecovery ¶
func ReadRecovery(dbPath string) (_ *RecoveryRecord, err error)
ReadRecovery reads the recovery key record of the vault at dbPath: ErrNoRecovery when it has none, ErrNoVault when there's no vault there.
type RekeyOptions ¶
type RekeyOptions struct {
// Link is the change as a key link (NewKeyLink), kept with the vault's
// others; nil when there's none to keep.
Link *syncfolder.KeyLink
// Links, with Sync RekeyAdopt, are the sync folder's links, which the
// vault takes in place of its own.
Links []syncfolder.KeyLink
Sync RekeySync
}
RekeyOptions are what a password change does beyond re-encrypting.
type RekeyResult ¶
type RekeyResult struct {
// NewID is the id of the vault's new key record.
NewID string
// Entries is how many entries were re-encrypted; Trashed, how many in
// the trash.
Entries, Trashed int
Recovery RecoveryOutcome
// OldVaultInFile means another sesh command had the vault open, so the
// change couldn't be folded into the vault file yet: until that command
// ends, the file on its own still holds the vault under the old key.
OldVaultInFile bool
}
RekeyResult reports a password change.
type RekeySync ¶
type RekeySync int
RekeySync is what a password change means for syncing.
const ( // RekeyLocal: nothing to sync (the vault doesn't sync now). RekeyLocal RekeySync = iota // RekeySend: a change made here, for the sync folder to take: the key // record the vault had, the folder's, is kept until it's sent. RekeySend // RekeyAdopt: the vault takes the sync folder's key record, changed on // another computer; any change of its own not sent is dropped. RekeyAdopt )
The meanings.
type Restored ¶
Restored is an entry put back from the trash: its name, and whether its tags were damaged, so it came back without them.
type SeenRecovery ¶
type SeenRecovery struct {
// RestoredKey: see Restored.
RestoredKey []byte
syncfolder.Recovery
// Mine says this vault sent it. Earlier says the folder's record goes
// before it: it was seen under a key the vault had before a master
// password change it took from another computer (someone who knew the
// old password could have made it). Restored says the vault's own
// record was put back by a restore since, with the key RestoredKey
// (nil for none): while it's that one, it isn't a change to send, and
// the folder's (or this one) is taken in its place.
Mine, Earlier, Restored bool
}
SeenRecovery is the sync folder's recovery key record as the vault last saw it, taken or sent: a Count of 0 when it saw none.
func VaultSyncRecovery ¶
func VaultSyncRecovery(dbPath string) (_ SeenRecovery, err error)
VaultSyncRecovery is the vault at dbPath's SyncRecovery, read without unlocking it.
type Store ¶
type Store struct {
// contains filtered or unexported fields
}
Store is the vault: entries in a SQLite file, each encrypted, through the vault.Store methods (entries.go).
func Open ¶
func Open(dbPath string, oracle CryptoOracle) (*Store, error)
Open creates or opens the SQLite database at dbPath, runs any pending migrations, and returns a ready-to-use Store.
func (*Store) AuditCountEstimate ¶
AuditCountEstimate returns roughly how many events the audit log holds, without counting rows: the newest event's id minus the oldest's, plus one, each a single lookup at the end of the primary key (one query with both MIN and MAX would scan the table). It's exact while pruning removes the oldest events first, as it does unless the clock moved backward, and an overestimate otherwise.
func (*Store) AuditEvents ¶
func (s *Store) AuditEvents(limit int) (_ []AuditEntry, err error)
AuditEvents returns the newest limit audit events, newest first; limit 0 returns them all.
func (*Store) AuditSummary ¶
AuditSummary returns how many events the audit log holds and when the oldest was written (zero when it's empty).
func (*Store) CheckKey ¶
CheckKey confirms that the store's oracle holds this vault's key: that the key record it was checked against is the one in the file the store has open. The vault's key can change between unlocking and opening, when another sesh command changes the master password; entries written then would be unreadable with the new key. Callers run it right after Open, before any read or write.
func (*Store) CheckUnlocked ¶
CheckUnlocked says whether the store can still read the vault: an error when its key source can no longer serve it (an agent that locked, or stopped), or ErrVaultKeyChanged when the vault's master password changed since it was unlocked. Neither counts as a use of the key.
func (*Store) ClearAudit ¶
ClearAudit deletes every audit event, whatever its timestamp, and returns how many it deleted.
func (*Store) Close ¶
Close releases the database connection and clears any cached key material held by the key source.
func (*Store) CodeKey ¶
CodeKey is the TOTP entry k's key, for drawing its codes on screen, which the audit log doesn't record, as it does reading a secret: a code shown isn't one copied or revealed. Only a TOTP entry's key is read so.
func (*Store) Compact ¶
Compact rewrites the vault without the free space that deleted rows leave behind (SQLite keeps it for reuse rather than shrinking the file), then folds the write-ahead log back into the file. That last step needs every other reader to have finished; it waits up to compactWait for them, then returns ErrVaultBusy.
func (*Store) DataVersion ¶
DataVersion is a number that changes when another connection to the vault file, such as another sesh command, commits a change (SQLite's data_version, read on the store's one connection): two that differ say the vault may have changed between them.
func (*Store) DeleteMany ¶
DeleteMany implements vault.Store: the entries go, in one transaction, into the trash, or for good when it keeps none (see SetTrashDays).
func (*Store) EachSecret ¶
func (s *Store) EachSecret(reading string, kinds []vault.Kind, each func(e *vault.Entry, secret []byte, err error) error) (n int, err error)
EachSecret calls each with every entry of kinds and its secret, decrypted, which it zeroes after each call, and records the reads as one audit event: "<reading>: read N secrets". Other kinds' secrets aren't read. An entry whose secret doesn't decrypt (ErrDecrypt) is handed to each with that error and no secret; one deleted meanwhile is passed over. Any other error, or one from each, stops it.
func (*Store) Edit ¶
Edit changes the entry at k as e says, in one transaction. Its secret and details are sealed to its key (entryAAD, detailsAAD), so a new key re-seals them: decrypted, encrypted for the new key, and written with it. The details after the change must pass Details.Check for the new kind, so an entry keeping notes can't become a secure note. The row stays, so its folder, tags, settings, and creation time come along; its update time moves only with a new secret. A new key another entry has is ErrNameTaken; the entry changed meanwhile is ErrEntryChanged. It returns the change, in words, as the audit event records it.
func (*Store) EmptyTrash ¶
EmptyTrash deletes every entry in the trash for good, and returns how many there were.
func (*Store) ExpireTrash ¶
ExpireTrash deletes for good the entries deleted before cutoff, and returns how many.
func (*Store) Fingerprint ¶
Fingerprint is a hash of what the entries are: every entry's names, filing, details and sealed values, their tags, and the key record. It changes when any of those does, and not for what else is written, such as the audit log, so a change it shows is one to what's stored.
func (*Store) Folders ¶
func (s *Store) Folders() ([]FolderCount, error)
Folders returns every folder, with the folders above them that hold no entries of their own, ordered part by part so subfolders follow their folder. The entries in no folder come first, when there are any.
func (*Store) ForgetVersionOf ¶
ForgetVersionOf deletes k's version v, as History listed it, for good, wherever it's numbered now: ErrVersionGone when it's no longer in the history, even if another command forgets it meanwhile.
func (*Store) ForgetVersions ¶
ForgetVersions deletes k's versions ns (2 and up) for good, all or none: each is resolved before any is deleted, so the numbers mean what they meant when they were listed.
func (*Store) GetFor ¶
GetFor is Get, recording in the audit log what the secret was read for: reading, such as "secret, to run".
func (*Store) HasEntries ¶
HasEntries reports whether the vault holds any entry, in the trash or not, reading none.
func (*Store) History ¶
History is the entry k's earlier secrets, the newest first: version 2 is the first, as version 1 is the current secret.
func (*Store) HistoryKeep ¶
HistoryKeep is how many earlier secrets each entry keeps.
func (*Store) KeepAlive ¶
KeepAlive tells the key source the vault is still in use, so an agent's idle timer starts again; a key source that doesn't time out has nothing to do.
func (*Store) LastAuditEvent ¶
func (s *Store) LastAuditEvent(eventType string) (*AuditEntry, error)
LastAuditEvent is the newest audit event of eventType, or nil when the log has none.
func (*Store) LastReads ¶
LastReads is, for each entry the audit log has a read of, the id of its latest read: a higher id is a later read. Reads whose detail holds any of ignoring are left out.
func (*Store) LogDoctor ¶
LogDoctor records a sesh doctor check of the vault in the audit log, with its result as detail.
func (*Store) LogImport ¶
LogImport records an import in the audit log, with what it brought in as detail.
func (*Store) LogSync ¶
LogSync records a sync with the sync folder in the audit log: detail says what it did.
func (*Store) MoveToFolder ¶
MoveToFolder files the entries keys name in folder ("" for none), returning how many moved; those already there don't count.
func (*Store) PruneAudit ¶
PruneAudit deletes the audit events written before before and returns how many it deleted.
func (*Store) PruneHistory ¶
PruneHistory drops, from every entry's history, live or in the trash, what's past the newest keep (all, for 0), and returns how many.
func (*Store) PurgeMany ¶
PurgeMany deletes the entries for good, not into the trash, in one transaction.
func (*Store) ReadVersion ¶
ReadVersion is the secret of k's version n (2 and up), for reading, which the audit log records.
func (*Store) ReadVersionOf ¶
ReadVersionOf is the secret of k's version v, as History listed it, for reading, which the audit log records: ErrVersionGone when it's no longer in the history.
func (*Store) Reader ¶
Reader is the vault opened again, on its own connection, for a long read (sesh doctor's checks) that would otherwise hold the one connection this store has, and with it every other read and write, until it's done. It shares this store's key, as it is (so it still notices a master password changed or an agent locked), which its Close leaves open. A vault file gone from its place isn't made again.
func (*Store) Recovery ¶
func (s *Store) Recovery() (*RecoveryRecord, error)
Recovery is the vault's recovery key record: ErrNoRecovery when it has none.
func (*Store) Rekey ¶
func (s *Store) Rekey(newKey []byte, rec UnlockMaterial, rewrap func(r *RecoveryRecord, newID string) (*RecoveryRecord, error), opts RekeyOptions) (RekeyResult, error)
Rekey re-encrypts the vault in place under newKey, whose key record is rec, in one transaction: every entry's secret and details, the key record, and the recovery key record, which rewrap re-wraps to the new key. The recovery key record is removed instead when rewrap is nil (a recovery, whose key has been used) or when it was made for another vault. Nothing changes unless all of it does, and the audit log is kept, with one event for the change.
The slow part, re-encrypting each entry, happens before the transaction, so other sesh commands wait for it only briefly; an entry saved in the meantime is re-encrypted inside it.
It refuses with ErrVaultKeyChanged when the vault's key isn't the one the store's key was checked against. Afterwards the store's key no longer opens the vault, so the caller closes it.
opts says what it means for syncing, and the key links kept.
func (*Store) RemoveFromTrash ¶
RemoveFromTrash deletes the trash's entries ids for good, all or none: an id not in the trash deletes nothing. An id named twice counts once. It returns their names.
func (*Store) RenameFolder ¶
RenameFolder renames folder from, and the folders under it, to to, returning how many entries moved. When to already held other entries, the two merge, and merged says so. It's refused when a subfolder's new name would be too long.
func (*Store) RenameTag ¶
RenameTag renames tag from to to on every entry, returning how many entries had it. When to was already in use, the two merge, and merged says so; an entry with both keeps one.
func (*Store) RestoreFromTrash ¶
RestoreFromTrash puts the trash's entry id back, under as when it isn't the zero Key (its secret and details sealed again for that name), and returns the name it has. A name another entry has is refused with ErrNameTaken; as must keep the entry's kind. Sealing again happens before the write, as Edit's does, and the write checks the entry in the trash is as it was read (ErrEntryChanged, if a new master password sealed it again meanwhile).
func (*Store) RestoreVersion ¶
RestoreVersion makes k's version n (2 and up) its secret again; the secret it replaces goes into the history, as any replaced secret does. It reports whether that one was kept: not when none are, or when it's the same secret.
func (*Store) RestoreVersionOf ¶
RestoreVersionOf is RestoreVersion of the version v, as History listed it, wherever it's numbered now: ErrVersionGone when it's no longer in the history.
func (*Store) SaveImported ¶
func (s *Store) SaveImported(e *vault.Entry, secret []byte, d *vault.Details, earlier []vault.Earlier) (ImportedHistory, error)
SaveImported is SaveWithDetails, or Save when d is nil, for an import that also brings the entry's earlier secrets, the newest first. They go into its history below what it has, and below the secret this replaces; one the entry already has, as its secret or an earlier one, isn't kept again, so importing twice adds nothing twice. Only as many as history.keep has room for are kept, the newest, and none over MaxSecretSize; the result says how many.
func (*Store) SaveWithDetails ¶
SaveWithDetails implements vault.Store.
func (*Store) SetDetails ¶
SetDetails implements vault.Store. The update time stays: it follows the secret.
func (*Store) SetHistoryKeep ¶
SetHistoryKeep sets how many earlier secrets each entry keeps; 0 keeps none. A new Store keeps none.
func (*Store) SetSettings ¶
SetSettings implements vault.Store.
func (*Store) SetTrashDays ¶
SetTrashDays sets how many days a deleted entry stays in the trash; 0 means none do, and deleting is for good. A new Store keeps none.
func (*Store) Size ¶
Size is the vault's size on disk in bytes: the database file and its write-ahead log.
func (*Store) SyncAddTyped ¶
func (s *Store) SyncAddTyped(uid string, t *syncfolder.Typed) error
SyncAddTyped keeps t, typed in the entry uid and sent with the count t.N, folded in with what it kept before (syncfolder.Fold).
func (*Store) SyncAgree ¶
func (s *Store) SyncAgree(uid string, rev int64, rec *syncfolder.Record, hash syncfolder.Hash) error
SyncAgree records that the entry uid, at rev here, and the folder's file of hash agree on rec: once this computer has written its version there, or found it the same. If uid's rev isn't rev any more (another command changed it meanwhile), nothing is recorded: ErrEntryChanged, for the next sync.
func (*Store) SyncApply ¶
func (s *Store) SyncApply(uid string, rev int64, rec *syncfolder.Record, hash syncfolder.Hash) (int64, error)
SyncApply makes the entry uid here as rec has it, in one transaction, if its rev is still rev (ErrEntryChanged, for the next sync, if another command changed it meanwhile), and records it agreed with the folder's file of hash. A name another entry has is ErrNameTaken. It returns the entry's rev after; 0 for one deleted for good. The writes are quiet: the rev is set, not raised by them.
func (*Store) SyncBase ¶
func (s *Store) SyncBase(uid string) (*syncfolder.Record, error)
SyncBase is the version uid was last agreed at, nil when it never was. The caller wipes it.
func (*Store) SyncCheck ¶
func (s *Store) SyncCheck(rec *syncfolder.Record) error
SyncCheck says what's wrong with rec as an entry sesh would keep, if anything: a merged one may not fit (too many fields, notes too long).
func (*Store) SyncComputerID ¶
SyncComputerID is this computer's sync ID, made the first time it's asked for: random, kept in the vault, and not taken from a backup, so each computer's changes are counted as its own (syncfolder.Versions).
func (*Store) SyncDropEntry ¶
SyncDropEntry forgets the entry uid, deleted for good here, as synced: nothing is sent for it.
func (*Store) SyncFolderID ¶
SyncFolderID is the ID of the sync folder the vault syncs with, or did before it left; "" when none.
func (*Store) SyncItems ¶
SyncItems is every entry, live, in the trash, or gone since it was synced, by uid.
func (*Store) SyncKeyChange ¶
SyncKeyChange is the ID of the key record the vault had before a master password change made here that the sync folder hasn't taken yet (the folder's), or "" when there's none to send.
func (*Store) SyncKeyChangeSent ¶
SyncKeyChangeSent records that the sync folder has the vault's key record: there's no change to send.
func (*Store) SyncKeyID ¶
SyncKeyID is the ID of the vault's key record (UnlockID), which every sync file sealed with its key names.
func (*Store) SyncKeyLinks ¶
func (s *Store) SyncKeyLinks() ([]syncfolder.KeyLink, error)
SyncKeyLinks are the vault's master password changes, oldest first.
func (*Store) SyncLeftDone ¶
SyncLeftDone records that the entry uid, agreed under a key left behind (SyncItem.Left), was made again from the folder's version under the new key, with what was typed here: that's no longer kept.
func (*Store) SyncMendBase ¶
func (s *Store) SyncMendBase(uid string, rec *syncfolder.Record) error
SyncMendBase keeps rec again as the version the entry uid was last agreed at, in place of one that doesn't open (damaged).
func (*Store) SyncNextChange ¶
SyncNextChange is the count of this computer's next change written to the sync folder: one more than any it gave before, and than seen (any of its counts in what it's writing over), counted in the vault before the change is written, so no two changes it writes, even one written and then lost to a crash, share a count.
func (*Store) SyncOlderKeys ¶
SyncOlderKeys are this vault's older keys, through its own links, from its key now.
func (*Store) SyncRecord ¶
SyncRecord is the entry uid as it is here, as a record made on computer: everything it holds, its secrets opened, with its rev as read. For one gone, it's a record of its deletion for good, now. The caller wipes it.
func (*Store) SyncRecovery ¶
func (s *Store) SyncRecovery() (SeenRecovery, error)
SyncRecovery is the sync folder's recovery key record as the vault last saw it.
func (*Store) SyncRecoverySent ¶
func (s *Store) SyncRecoverySent(r *syncfolder.Recovery) error
SyncRecoverySent records r as the sync folder's recovery key record, the vault's own, written there.
func (*Store) SyncSealer ¶
func (s *Store) SyncSealer() syncfolder.Sealer
SyncSealer seals and opens sync files with the vault's key.
func (*Store) SyncSetForgotten ¶
func (s *Store) SyncSetForgotten(uid string, marks []syncfolder.Forgotten) error
SyncSetForgotten makes the earlier secrets forgotten on purpose in the entry uid exactly marks, in place of what it had.
func (*Store) SyncStartFolder ¶
SyncStartFolder makes folderID the sync folder the vault syncs with. A vault that synced with another forgets what it agreed with that one, so every entry goes to the new folder as a change (entries restored from a backup stay marked so), and so does its recovery key record; one syncing with folderID already keeps it.
func (*Store) SyncTakeRecovery ¶
func (s *Store) SyncTakeRecovery(r *SeenRecovery, rec *RecoveryRecord, had []byte) error
SyncTakeRecovery makes rec, nil for none, the vault's recovery key record, and r the folder's as the vault saw it, in one transaction; rec is for the vault's key record as it is. had is the public key of the vault's record the sync looked at (nil for none): when it isn't that any more, nothing changes (ErrRecoveryChanged).
func (*Store) SyncTyped ¶
func (s *Store) SyncTyped(uid string) ([]*syncfolder.Typed, error)
SyncTyped is what was typed in the entry uid and kept (SyncAddTyped), in the order it was sent. One that doesn't open is left out.
func (*Store) SyncTypedChecks ¶
SyncTypedChecks checks, for each entry whose secret, notes, fields or earlier secrets changed or went since (sync_typed_check), that what's kept of what was typed in it the vault still has (SyncTypedKept): so nothing forgotten, trimmed or deleted for good stays there, synced or not.
func (*Store) SyncTypedKept ¶
SyncTypedKept drops, of what was typed in the entry uid and kept, any secret, notes or field the entry no longer has (syncfolder.Typed.Kept), computer naming this computer.
func (*Store) SyncWarnFresh ¶
SyncWarnFresh says whether an automatic sync should say the warning line at now: it wasn't said in the last within. When it should, it's recorded as said now.
func (*Store) Trash ¶
func (s *Store) Trash() (_ []TrashedEntry, err error)
Trash lists the trash, the most recently deleted first. A row whose times or tags don't read is still listed, without them, so it can be removed; sesh doctor names what's wrong with it.
func (*Store) Verify ¶
func (s *Store) Verify() (VerifyReport, error)
Verify checks the vault without writing to it, from one read-only view of it: SQLite's integrity check of the file, then every entry's secret decrypted with the store's key and its settings and times read. It reports every problem rather than stopping at the first.
Only a secret that doesn't decrypt with the vault's key (ErrDecrypt) counts as a damaged entry. Any other failure, such as an agent that locked or went away, or a master password changed by another command (ErrVaultKeyChanged), means the check couldn't finish, and is returned as an error with a partial report.
type SyncAgreed ¶
type SyncAgreed struct {
Hash syncfolder.Hash
Rev int64
// Intact says the version agreed is kept as it was sealed (its hash),
// for this entry, with the vault's key now: it opens without being
// opened to find out.
Intact bool
}
SyncAgreed is what this computer and the folder last agreed on for an entry: its rev here then, and the hash of the folder's file (SyncBase is the version itself).
type SyncItem ¶
type SyncItem struct {
// Agreed is nil for an entry never synced.
Agreed *SyncAgreed
UID string
// Key is its name; the zero Key when gone.
Key vault.Key
Place SyncPlace
// Rev is 0 when gone.
Rev int64
// Restored says it was restored from a backup and hasn't synced since;
// RestoredRev is its rev then (another now: changed since);
// RestoredChanged, that the backup had it changed and not synced.
RestoredRev int64
Restored bool
RestoredChanged bool
// Left says it was agreed under a key this computer left behind,
// taking a master password change made elsewhere: until it's made
// again from the folder's version under the new key (SyncLeftDone),
// nothing is sent for it.
Left bool
}
SyncItem is an entry as sync sees it.
type TrashedEntry ¶
type TrashedEntry struct {
DeletedAt time.Time
vault.Entry
ID int64 // its trash id, which sesh trash names it by
}
TrashedEntry is an entry in the trash.
type UnlockMaterial ¶
type UnlockMaterial struct {
Salt []byte
Verify []byte
Params Argon2idParams
}
UnlockMaterial is the vault's key record: what an unlock derives the key from and checks it against. Nothing here is the key.
func ReadUnlockMaterial ¶
func ReadUnlockMaterial(dbPath string) (_ UnlockMaterial, err error)
ReadUnlockMaterial reads the key record of the vault at dbPath, without any key. It returns ErrNoVault when there is no vault there yet, and never creates one.
type VerifyReport ¶
type VerifyReport struct {
// Recovery is the recovery key record, nil when there's none or
// RecoveryErr says it can't be read.
Recovery *RecoveryRecord
RecoveryErr error
// KeyID is the id of the vault's key record (UnlockID).
KeyID string
// Structure is what SQLite's integrity check found wrong with the
// file, empty when it's sound. When the check itself couldn't run,
// its error is the one line.
Structure []string
// Problems are the entries that can't be read, ordered by key.
Problems []EntryProblem
// TrashProblems are those of the entries in the trash.
TrashProblems []EntryProblem
// HistoryProblems are the entries' earlier secrets that can't be read:
// of a live entry (with its Version) or one in the trash (TrashID).
HistoryProblems []EntryProblem
// Entries is how many entries the vault holds; Trashed, how many are
// in the trash; History, how many earlier secrets they keep.
Entries, Trashed, History int
}
VerifyReport is what Verify found, all from one consistent view of the vault.