agent

package
v0.0.0-...-7480f4d Latest Latest
Warning

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

Go to latest
Published: Oct 18, 2022 License: GPL-3.0, BSD-3-Clause Imports: 21 Imported by: 0

Documentation

Overview

Package agent implements the ssh-agent protocol, and provides both a client and a server. The client can talk to a standard ssh-agent that uses UNIX sockets, and one could implement an alternative ssh-agent process using the sample server.

References:

[PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-00

Index

Examples

Constants

This section is empty.

Variables

View Source
var ErrExtensionUnsupported = errors.New("agent: extension unsupported")

ErrExtensionUnsupported indicates that an extension defined in [PROTOCOL.agent] section 4.7 is unsupported by the agent. Specifically this error indicates that the agent returned a standard SSH_AGENT_FAILURE message as the result of a SSH_AGENTC_EXTENSION request. Note that the protocol specification (and therefore this error) does not distinguish between a specific extension being unsupported and extensions being unsupported entirely.

Functions

func ForwardToAgent

func ForwardToAgent(client *ssh.Client, keyring Agent) error

ForwardToAgent routes authentication requests to the given keyring.

func ForwardToRemote

func ForwardToRemote(client *ssh.Client, addr string) error

ForwardToRemote routes authentication requests to the ssh-agent process serving on the given unix socket.

func RequestAgentForwarding

func RequestAgentForwarding(session *ssh.Session) error

RequestAgentForwarding sets up agent forwarding for the session. ForwardToAgent or ForwardToRemote should be called to route the authentication requests.

func ServeAgent

func ServeAgent(agent Agent, c io.ReadWriter) error

ServeAgent serves the agent protocol on the given connection. It returns when an I/O error occurs.

Types

type AddedKey

type AddedKey struct {
	// PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey,
	// ed25519.PrivateKey or *ecdsa.PrivateKey, which will be inserted into the
	// agent.
	PrivateKey interface{}
	// Certificate, if not nil, is communicated to the agent and will be
	// stored with the key.
	Certificate *ssh.Certificate
	// Comment is an optional, free-form string.
	Comment string
	// LifetimeSecs, if not zero, is the number of seconds that the
	// agent will store the key for.
	LifetimeSecs uint32
	// ConfirmBeforeUse, if true, requests that the agent confirm with the
	// user before each use of this key.
	ConfirmBeforeUse bool
	// ConstraintExtensions are the experimental or private-use constraints
	// defined by users.
	ConstraintExtensions []ConstraintExtension
}

AddedKey describes an SSH key to be added to an Agent.

type Agent

type Agent interface {
	// List returns the identities known to the agent.
	List() ([]*Key, error)

	// Sign has the agent sign the data using a protocol 2 key as defined
	// in [PROTOCOL.agent] section 2.6.2.
	Sign(key ssh.PublicKey, data []byte) (*ssh.Signature, error)

	// Add adds a private key to the agent.
	Add(key AddedKey) error

	// Remove removes all identities with the given public key.
	Remove(key ssh.PublicKey) error

	// RemoveAll removes all identities.
	RemoveAll() error

	// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list.
	Lock(passphrase []byte) error

	// Unlock undoes the effect of Lock
	Unlock(passphrase []byte) error

	// Signers returns signers for all the known keys.
	Signers() ([]ssh.Signer, error)
}

Agent represents the capabilities of an ssh-agent.

func NewKeyring

func NewKeyring() Agent

NewKeyring returns an Agent that holds keys in memory. It is safe for concurrent use by multiple goroutines.

type ConstraintExtension

type ConstraintExtension struct {
	// ExtensionName consist of a UTF-8 string suffixed by the
	// implementation domain following the naming scheme defined
	// in Section 4.2 of [RFC4251], e.g.  "foo@example.com".
	ExtensionName string
	// ExtensionDetails contains the actual content of the extended
	// constraint.
	ExtensionDetails []byte
}

ConstraintExtension describes an optional constraint defined by users.

type ExtendedAgent

type ExtendedAgent interface {
	Agent

	// SignWithFlags signs like Sign, but allows for additional flags to be sent/received
	SignWithFlags(key ssh.PublicKey, data []byte, flags SignatureFlags) (*ssh.Signature, error)

	// Extension processes a custom extension request. Standard-compliant agents are not
	// required to support any extensions, but this method allows agents to implement
	// vendor-specific methods or add experimental features. See [PROTOCOL.agent] section 4.7.
	// If agent extensions are unsupported entirely this method MUST return an
	// ErrExtensionUnsupported error. Similarly, if just the specific extensionType in
	// the request is unsupported by the agent then ErrExtensionUnsupported MUST be
	// returned.
	//
	// In the case of success, since [PROTOCOL.agent] section 4.7 specifies that the contents
	// of the response are unspecified (including the type of the message), the complete
	// response will be returned as a []byte slice, including the "type" byte of the message.
	Extension(extensionType string, contents []byte) ([]byte, error)
}

func NewClient

func NewClient(rw io.ReadWriter) ExtendedAgent

NewClient returns an Agent that talks to an ssh-agent process over the given connection.

Example
package main

import (
	"log"
	"net"
	"os"

	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/ssh"
	"github.com/Psiphon-Labs/psiphon-tunnel-core/psiphon/common/crypto/ssh/agent"
)

func main() {
	// ssh-agent(1) provides a UNIX socket at $SSH_AUTH_SOCK.
	socket := os.Getenv("SSH_AUTH_SOCK")
	conn, err := net.Dial("unix", socket)
	if err != nil {
		log.Fatalf("Failed to open SSH_AUTH_SOCK: %v", err)
	}

	agentClient := agent.NewClient(conn)
	config := &ssh.ClientConfig{
		User: "gopher",
		Auth: []ssh.AuthMethod{
			// Use a callback rather than PublicKeys so we only consult the
			// agent once the remote server wants it.
			ssh.PublicKeysCallback(agentClient.Signers),
		},
		HostKeyCallback: ssh.InsecureIgnoreHostKey(),
	}

	sshc, err := ssh.Dial("tcp", "localhost:22", config)
	if err != nil {
		log.Fatal(err)
	}
	// Use sshc...
	sshc.Close()
}
Output:

type Key

type Key struct {
	Format  string
	Blob    []byte
	Comment string
}

Key represents a protocol 2 public key as defined in [PROTOCOL.agent], section 2.5.2.

func (*Key) Marshal

func (k *Key) Marshal() []byte

Marshal returns key blob to satisfy the ssh.PublicKey interface.

func (*Key) String

func (k *Key) String() string

String returns the storage form of an agent key with the format, base64 encoded serialized key, and the comment if it is not empty.

func (*Key) Type

func (k *Key) Type() string

Type returns the public key type.

func (*Key) Verify

func (k *Key) Verify(data []byte, sig *ssh.Signature) error

Verify satisfies the ssh.PublicKey interface.

type SignatureFlags

type SignatureFlags uint32

SignatureFlags represent additional flags that can be passed to the signature requests an defined in [PROTOCOL.agent] section 4.5.1.

const (
	SignatureFlagReserved SignatureFlags = 1 << iota
	SignatureFlagRsaSha256
	SignatureFlagRsaSha512
)

SignatureFlag values as defined in [PROTOCOL.agent] section 5.3.

Jump to

Keyboard shortcuts

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