Documentation
¶
Overview ¶
Package sshpool dials an instance's SSH endpoint with its stored credentials and reports how the presented host key relates to the pinned one. Nothing here writes to the database: pinning is the caller's decision, taken on the report this package returns.
Index ¶
Constants ¶
const HardlinkExtension = "hardlink@openssh.com"
HardlinkExtension is the sftp extension a server advertises when it can make hard links.
Variables ¶
var ErrConnect = errors.New("could not connect to the SSH host")
ErrConnect marks a failure to reach the host or complete the handshake, as opposed to a fault in what qui stored: the caller answers the two differently, and only the first earns an unreadable pin its precedence.
var ErrNotRemote = errors.New("instance is not in remote filesystem mode")
ErrNotRemote answers a dial for an instance whose row is not in remote filesystem mode. It is not memoised: the row changes without the host doing anything, and the next dial reads it again.
var ErrPinUnusable = errors.New("host key pin is unusable")
ErrPinUnusable marks the errors Connect raises before it dials, when the stored pin is missing or will not decrypt or parse. The pool dials only rows in remote mode, which carry a pin, so there it means a pin that will not decrypt or parse. That lasts until the pin changes, which is why the pool tells it apart from a host that is merely down.
var ErrPoolClosed = errors.New("ssh pool is closed")
ErrPoolClosed answers a caller that arrives after shutdown began: nothing may dial once Close has run.
Functions ¶
This section is empty.
Types ¶
type Capabilities ¶
type Capabilities struct {
SFTP bool
Statvfs bool
Hardlink bool
Limits bool
Exec bool
GNUUserland bool
}
Capabilities is what the server lets us do, probed read-only.
type Dialer ¶
type Dialer struct {
// contains filtered or unexported fields
}
Dialer opens SSH connections: one-shot ones for Test and Confirm, and the long-lived ones Pool keeps through Connect.
func (*Dialer) Confirm ¶
Confirm dials the instance and succeeds only if the host presents hostKey, so the caller can pin the key the user was shown rather than whatever the host offers at pin time. hostKey is in SSH wire format, the form the pin column holds.
type MismatchError ¶
MismatchError reports that the host presented a key other than the expected one. Error prints fingerprints only, so the message is safe to log; the fields carry the keys for callers that need them.
func (*MismatchError) Error ¶
func (e *MismatchError) Error() string
type Pool ¶ added in v1.31.0
type Pool struct {
// contains filtered or unexported fields
}
Pool keeps one SSH connection with one SFTP session per instance.
ponytail: one connection per instance, no bounded session pool; that arrives with the exec tier, which needs more than one channel at a time.
func (*Pool) Close ¶ added in v1.31.0
func (p *Pool) Close()
Close drops every connection and refuses every later caller. Called once, at shutdown; a caller mid-dial holds its entry until that dial ends, which the dial timeout bounds.
func (*Pool) Invalidate ¶ added in v1.31.0
Invalidate ends the instance's connection and forgets its memo. The credential, pin and instance update routes call it after they write the row, so the next dial reads the new values. A mismatch is re-memoised by the next dial, so a refusal survives a spurious call at the cost of one dial. Safe on a nil pool.
func (*Pool) Remove ¶ added in v1.31.0
Remove is Invalidate for an instance that no longer exists: the entry goes with the connection.
type Report ¶
type Report struct {
Status Status
HostKey ssh.PublicKey
PinnedKey ssh.PublicKey // mismatch only
Capabilities *Capabilities // nil on mismatch and pin_unreadable: no session is opened
}
Report is the outcome of Test. A mismatch is a result, not a failure: the user has to see both keys to decide whether the host was re-keyed or replaced.
type Status ¶
type Status string
Status is how the host key the server presented relates to the stored pin.
const ( StatusUnpinned Status = "unpinned" StatusPinned Status = "pinned" StatusMismatch Status = "mismatch" // StatusPinUnreadable: the stored pin does not decrypt. The presented key // is reported so the user can replace the pin through the same heavy // confirmation a mismatch gets; nothing is trusted and nothing is probed. StatusPinUnreadable Status = "pin_unreadable" )