blob: 81bf8823b476f04f9919377b0e78eaea45b3a55e [file] [log] [blame]
<!DOCTYPE html>
<html>
<head>
<meta charset="utf-8">
<meta name="viewport" content="width=device-width, initial-scale=1.0">
<meta name="generator" content="doc2go">
<title>ssh</title>
<style>
body {
margin: 1em 2em;
font-family: Helvetica, sans-serif;
background-color: #f8f8f8;
font-size: 1em;
}
h1,
h2,
h3,
h4,
h5,
h6 {
margin-top: 0.3em;
margin-bottom: 0.3em;
}
h1,
h2,
h3,
h4 {
font-weight: 500;
}
h2 {
font-size: 1.75em
}
h3 {
font-size: 1.5em
}
h4 {
font-size: 1.33em
}
h5 {
font-size: 1em
}
a {
text-decoration: none;
color: #0366a5;
}
a:hover {
text-decoration: underline;
}
a.permalink {
display: none;
}
a.permalink:hover {
text-decoration: none;
}
*:hover>a.permalink {
display: inline;
}
nav {
padding: 1em;
background-color: #eee;
border-radius: 0.5em;
display: flex;
flex-wrap: wrap;
}
nav .navbar-right {
margin-left: auto;
}
/* Remove first level of nesting for a package's index section. */
#pkg-index+ul,
#pkg-examples+ul {
list-style-type: none;
padding: 0;
}
code,
kbd,
pre {
font-family: Consolas, monospace;
}
pre {
color: #222;
overflow-x: auto;
border: 1px solid #ccc;
border-radius: 0.5em;
background-color: #eee;
padding: 0.75em;
font-size: 0.9em;
}
details.example>summary {
color: #0366a5;
cursor: pointer;
}
details.deprecated>summary {
list-style: none;
}
span.deprecated-tag {
color: #eee;
background-color: #999;
padding: 0.125rem 0.3rem;
border-radius: 0.3rem;
font-size: 0.7rem;
vertical-align: middle;
cursor: pointer;
}
#search {
margin: 0.3em 0;
}
#generated-by-footer {
font-size: x-small;
}
/* Background */
.bg {
background-color: #ffffff;
}
/* PreWrapper */
.chroma {
background-color: #ffffff;
}
/* Error */
.chroma .err {
color: #a61717;
background-color: #e3d2d2
}
/* LineLink */
.chroma .lnlinks {
outline: none;
text-decoration: none;
color: inherit
}
/* LineTableTD */
.chroma .lntd {
vertical-align: top;
padding: 0;
margin: 0;
border: 0;
}
/* LineTable */
.chroma .lntable {
border-spacing: 0;
padding: 0;
margin: 0;
border: 0;
}
/* LineHighlight */
.chroma .hl {
background-color: #e5e5e5
}
/* LineNumbersTable */
.chroma .lnt {
white-space: pre;
-webkit-user-select: none;
user-select: none;
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* LineNumbers */
.chroma .ln {
white-space: pre;
-webkit-user-select: none;
user-select: none;
margin-right: 0.4em;
padding: 0 0.4em 0 0.4em;
color: #7f7f7f
}
/* Line */
.chroma .line {
display: flex;
}
/* Keyword */
.chroma .k {
color: #000000;
font-weight: bold
}
/* KeywordConstant */
.chroma .kc {
color: #000000;
font-weight: bold
}
/* KeywordDeclaration */
.chroma .kd {
color: #000000;
font-weight: bold
}
/* KeywordNamespace */
.chroma .kn {
color: #000000;
font-weight: bold
}
/* KeywordPseudo */
.chroma .kp {
color: #000000;
font-weight: bold
}
/* KeywordReserved */
.chroma .kr {
color: #000000;
font-weight: bold
}
/* KeywordType */
.chroma .kt {
color: #445588;
font-weight: bold
}
/* NameAttribute */
.chroma .na {
color: #008080
}
/* NameBuiltin */
.chroma .nb {
color: #0086b3
}
/* NameBuiltinPseudo */
.chroma .bp {
color: #999999
}
/* NameClass */
.chroma .nc {
color: #445588;
font-weight: bold
}
/* NameConstant */
.chroma .no {
color: #008080
}
/* NameDecorator */
.chroma .nd {
color: #3c5d5d;
font-weight: bold
}
/* NameEntity */
.chroma .ni {
color: #800080
}
/* NameException */
.chroma .ne {
color: #990000;
font-weight: bold
}
/* NameFunction */
.chroma .nf {
color: #990000;
font-weight: bold
}
/* NameLabel */
.chroma .nl {
color: #990000;
font-weight: bold
}
/* NameNamespace */
.chroma .nn {
color: #555555
}
/* NameTag */
.chroma .nt {
color: #000080
}
/* NameVariable */
.chroma .nv {
color: #008080
}
/* NameVariableClass */
.chroma .vc {
color: #008080
}
/* NameVariableGlobal */
.chroma .vg {
color: #008080
}
/* NameVariableInstance */
.chroma .vi {
color: #008080
}
/* LiteralString */
.chroma .s {
color: #dd1144
}
/* LiteralStringAffix */
.chroma .sa {
color: #dd1144
}
/* LiteralStringBacktick */
.chroma .sb {
color: #dd1144
}
/* LiteralStringChar */
.chroma .sc {
color: #dd1144
}
/* LiteralStringDelimiter */
.chroma .dl {
color: #dd1144
}
/* LiteralStringDoc */
.chroma .sd {
color: #dd1144
}
/* LiteralStringDouble */
.chroma .s2 {
color: #dd1144
}
/* LiteralStringEscape */
.chroma .se {
color: #dd1144
}
/* LiteralStringHeredoc */
.chroma .sh {
color: #dd1144
}
/* LiteralStringInterpol */
.chroma .si {
color: #dd1144
}
/* LiteralStringOther */
.chroma .sx {
color: #dd1144
}
/* LiteralStringRegex */
.chroma .sr {
color: #009926
}
/* LiteralStringSingle */
.chroma .s1 {
color: #dd1144
}
/* LiteralStringSymbol */
.chroma .ss {
color: #990073
}
/* LiteralNumber */
.chroma .m {
color: #009999
}
/* LiteralNumberBin */
.chroma .mb {
color: #009999
}
/* LiteralNumberFloat */
.chroma .mf {
color: #009999
}
/* LiteralNumberHex */
.chroma .mh {
color: #009999
}
/* LiteralNumberInteger */
.chroma .mi {
color: #009999
}
/* LiteralNumberIntegerLong */
.chroma .il {
color: #009999
}
/* LiteralNumberOct */
.chroma .mo {
color: #009999
}
/* Operator */
.chroma .o {
color: #000000;
font-weight: bold
}
/* OperatorWord */
.chroma .ow {
color: #000000;
font-weight: bold
}
/* Comment */
.chroma .c {
color: #999988;
font-style: italic
}
/* CommentHashbang */
.chroma .ch {
color: #999988;
font-style: italic
}
/* CommentMultiline */
.chroma .cm {
color: #999988;
font-style: italic
}
/* CommentSingle */
.chroma .c1 {
color: #999988;
font-style: italic
}
/* CommentSpecial */
.chroma .cs {
color: #999999;
font-weight: bold;
font-style: italic
}
/* CommentPreproc */
.chroma .cp {
color: #999999;
font-weight: bold;
font-style: italic
}
/* CommentPreprocFile */
.chroma .cpf {
color: #999999;
font-weight: bold;
font-style: italic
}
/* GenericDeleted */
.chroma .gd {
color: #000000;
background-color: #ffdddd
}
/* GenericEmph */
.chroma .ge {
color: #000000;
font-style: italic
}
/* GenericError */
.chroma .gr {
color: #aa0000
}
/* GenericHeading */
.chroma .gh {
color: #999999
}
/* GenericInserted */
.chroma .gi {
color: #000000;
background-color: #ddffdd
}
/* GenericOutput */
.chroma .go {
color: #888888
}
/* GenericPrompt */
.chroma .gp {
color: #555555
}
/* GenericStrong */
.chroma .gs {
font-weight: bold
}
/* GenericSubheading */
.chroma .gu {
color: #aaaaaa
}
/* GenericTraceback */
.chroma .gt {
color: #aa0000
}
/* GenericUnderline */
.chroma .gl {
text-decoration: underline
}
/* TextWhitespace */
.chroma .w {
color: #bbbbbb
}
</style>
</head>
<body>
<main><h2 id="pkg-overview">package ssh</h2>
<pre class="chroma"><span class="kn">import</span> <span class="s">&#34;golang.org/x/crypto/ssh&#34;</span></pre>
<p>Package ssh implements an SSH client and server.
<p>SSH is a transport security protocol, an authentication protocol and a
family of application protocols. The most typical application level
protocol is a remote shell and this is specifically implemented. However,
the multiplexed nature of SSH is exposed to users that wish to support
others.
<p>References:
<pre>[PROTOCOL]: https://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL?rev=HEAD
[PROTOCOL.certkeys]: http://cvsweb.openbsd.org/cgi-bin/cvsweb/src/usr.bin/ssh/PROTOCOL.certkeys?rev=HEAD
[SSH-PARAMETERS]: http://www.iana.org/assignments/ssh-parameters/ssh-parameters.xml#ssh-parameters-1
</pre>
<p>This package does not fall under the stability promise of the Go language itself,
so its API may be changed when pressing needs arise.
<h3 id="pkg-index">Index</h3>
<ul>
<li><a href="#pkg-constants">Constants</a></li><li><a href="#pkg-variables">Variables</a></li><li><a href="#FingerprintLegacyMD5">func FingerprintLegacyMD5(pubKey PublicKey) string</a></li>
<li><a href="#FingerprintSHA256">func FingerprintSHA256(pubKey PublicKey) string</a></li>
<li><a href="#Marshal">func Marshal(msg interface{}) []byte</a></li>
<li><a href="#MarshalAuthorizedKey">func MarshalAuthorizedKey(key PublicKey) []byte</a></li>
<li><a href="#MarshalPrivateKey">func MarshalPrivateKey(key crypto.PrivateKey, options MarshalPrivateKeyOptions) (*pem.Block, error)</a></li>
<li><a href="#Unmarshal">func Unmarshal(data []byte, out interface{}) error</a></li>
<li>
<a href="#Algorithms">type Algorithms</a>
<ul>
<li><a href="#InsecureAlgorithms">func InsecureAlgorithms() Algorithms</a></li>
<li><a href="#SupportedAlgorithms">func SupportedAlgorithms() Algorithms</a></li>
</ul>
</li>
<li>
<a href="#AuthMethod">type AuthMethod</a>
<ul>
<li><a href="#GSSAPIWithMICAuthMethod">func GSSAPIWithMICAuthMethod(gssAPIClient GSSAPIClient, target string) AuthMethod</a></li>
<li><a href="#KeyboardInteractive">func KeyboardInteractive(challenge KeyboardInteractiveChallenge) AuthMethod</a></li>
<li><a href="#Password">func Password(secret string) AuthMethod</a></li>
<li><a href="#PasswordCallback">func PasswordCallback(prompt func() (secret string, err error)) AuthMethod</a></li>
<li><a href="#PublicKeys">func PublicKeys(signers ...Signer) AuthMethod</a></li>
<li><a href="#PublicKeysCallback">func PublicKeysCallback(getSigners func() (signers []Signer, err error)) AuthMethod</a></li>
<li><a href="#RetryableAuthMethod">func RetryableAuthMethod(auth AuthMethod, maxTries int) AuthMethod</a></li>
</ul>
</li>
<li>
<a href="#BannerCallback">type BannerCallback</a>
<ul>
<li><a href="#BannerDisplayStderr">func BannerDisplayStderr() BannerCallback</a></li>
</ul>
</li>
<li>
<a href="#BannerError">type BannerError</a>
<ul>
<li><a href="#BannerError.Error">func (b *BannerError) Error() string</a></li>
<li><a href="#BannerError.Unwrap">func (b *BannerError) Unwrap() error</a></li>
</ul>
</li>
<li>
<a href="#CertChecker">type CertChecker</a>
<ul>
<li><a href="#CertChecker.Authenticate">func (c *CertChecker) Authenticate(conn ConnMetadata, pubKey PublicKey) (*Permissions, error)</a></li>
<li><a href="#CertChecker.CheckCert">func (c *CertChecker) CheckCert(principal string, cert *Certificate) error</a></li>
<li><a href="#CertChecker.CheckHostKey">func (c *CertChecker) CheckHostKey(addr string, remote net.Addr, key PublicKey) error</a></li>
</ul>
</li>
<li>
<a href="#Certificate">type Certificate</a>
<ul>
<li><a href="#Certificate.Marshal">func (c *Certificate) Marshal() []byte</a></li>
<li><a href="#Certificate.SignCert">func (c *Certificate) SignCert(rand io.Reader, authority Signer) error</a></li>
<li><a href="#Certificate.Type">func (c *Certificate) Type() string</a></li>
<li><a href="#Certificate.Verify">func (c *Certificate) Verify(data []byte, sig *Signature) error</a></li>
</ul>
</li>
<li>
<a href="#Channel">type Channel</a>
<ul>
<li><a href="#Channel.Close">func (c *Channel) Close() error</a></li>
<li><a href="#Channel.CloseWrite">func (c *Channel) CloseWrite() error</a></li>
<li><a href="#Channel.Handle">func (c *Channel) Handle(handler RequestHandler) error</a></li>
<li><a href="#Channel.Read">func (c *Channel) Read(data []byte) (int, error)</a></li>
<li><a href="#Channel.SendRequest">func (c *Channel) SendRequest(name string, wantReply bool, payload []byte) (bool, error)</a></li>
<li><a href="#Channel.SetDeadline">func (c *Channel) SetDeadline(deadline time.Time) error</a></li>
<li><a href="#Channel.SetReadDeadline">func (c *Channel) SetReadDeadline(deadline time.Time) error</a></li>
<li><a href="#Channel.SetWriteDeadline">func (c *Channel) SetWriteDeadline(deadline time.Time) error</a></li>
<li><a href="#Channel.Stderr">func (c *Channel) Stderr() io.ReadWriter</a></li>
<li><a href="#Channel.Write">func (c *Channel) Write(data []byte) (int, error)</a></li>
</ul>
</li>
<li>
<a href="#ChannelHandler">type ChannelHandler</a>
</li>
<li>
<a href="#ChannelHandlerFunc">type ChannelHandlerFunc</a>
<ul>
<li><a href="#ChannelHandlerFunc.NewChannel">func (f ChannelHandlerFunc) NewChannel(ch *NewChannel)</a></li>
</ul>
</li>
<li>
<a href="#Client">type Client</a>
<ul>
<li><a href="#Dial">func Dial(ctx context.Context, network, addr string, config *ClientConfig) (*Client, error)</a></li>
<li><a href="#NewClient">func NewClient(c *ClientConn) *Client</a></li>
<li><a href="#Client.Close">func (c Client) Close() error</a></li>
<li><a href="#Client.Dial">func (c *Client) Dial(ctx context.Context, n, addr string) (net.Conn, error)</a></li>
<li><a href="#Client.DialTCP">func (c *Client) DialTCP(ctx context.Context, n string, laddr, raddr *net.TCPAddr) (net.Conn, error)</a></li>
<li><a href="#Client.HandleChannelOpen">func (c *Client) HandleChannelOpen(channelType string, handler ChannelHandler) error</a></li>
<li><a href="#Client.Listen">func (c *Client) Listen(n, addr string) (net.Listener, error)</a></li>
<li><a href="#Client.ListenUnix">func (c *Client) ListenUnix(socketPath string) (net.Listener, error)</a></li>
<li><a href="#Client.NewSession">func (c *Client) NewSession() (*Session, error)</a></li>
</ul>
</li>
<li>
<a href="#ClientConfig">type ClientConfig</a>
</li>
<li>
<a href="#ClientConn">type ClientConn</a>
<ul>
<li><a href="#NewClientConn">func NewClientConn(c net.Conn, addr string, config *ClientConfig) (*ClientConn, error)</a></li>
<li><a href="#ClientConn.Close">func (c ClientConn) Close() error</a></li>
<li><a href="#ClientConn.Handle">func (c *ClientConn) Handle(channelHandler ChannelHandler, requestHandler RequestHandler) error</a></li>
</ul>
</li>
<li>
<a href="#ClientHandler">type ClientHandler</a>
</li>
<li>
<a href="#ClientHandlerFunc">type ClientHandlerFunc</a>
<ul>
<li><a href="#ClientHandlerFunc.HandleClient">func (f ClientHandlerFunc) HandleClient(conn *ServerConn)</a></li>
</ul>
</li>
<li>
<a href="#Config">type Config</a>
<ul>
<li><a href="#Config.SetDefaults">func (c *Config) SetDefaults()</a></li>
</ul>
</li>
<li>
<a href="#ConnMetadata">type ConnMetadata</a>
<ul>
<li><a href="#ConnMetadata.ClientVersion">func (c ConnMetadata) ClientVersion() []byte</a></li>
<li><a href="#ConnMetadata.LocalAddr">func (c ConnMetadata) LocalAddr() net.Addr</a></li>
<li><a href="#ConnMetadata.RemoteAddr">func (c ConnMetadata) RemoteAddr() net.Addr</a></li>
<li><a href="#ConnMetadata.ServerVersion">func (c ConnMetadata) ServerVersion() []byte</a></li>
<li><a href="#ConnMetadata.SessionID">func (c ConnMetadata) SessionID() []byte</a></li>
<li><a href="#ConnMetadata.User">func (c ConnMetadata) User() string</a></li>
</ul>
</li>
<li>
<a href="#CryptoPublicKey">type CryptoPublicKey</a>
</li>
<li>
<a href="#ExitError">type ExitError</a>
<ul>
<li><a href="#ExitError.Error">func (e *ExitError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#ExitMissingError">type ExitMissingError</a>
<ul>
<li><a href="#ExitMissingError.Error">func (e *ExitMissingError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#GSSAPIClient">type GSSAPIClient</a>
</li>
<li>
<a href="#GSSAPIServer">type GSSAPIServer</a>
</li>
<li>
<a href="#GSSAPIWithMICConfig">type GSSAPIWithMICConfig</a>
</li>
<li>
<a href="#HostKeyCallback">type HostKeyCallback</a>
<ul>
<li><a href="#FixedHostKey">func FixedHostKey(key PublicKey) HostKeyCallback</a></li>
<li><a href="#InsecureIgnoreHostKey">func InsecureIgnoreHostKey() HostKeyCallback</a></li>
</ul>
</li>
<li>
<a href="#KeyboardInteractiveChallenge">type KeyboardInteractiveChallenge</a>
</li>
<li>
<a href="#MarshalPrivateKeyOptions">type MarshalPrivateKeyOptions</a>
</li>
<li>
<a href="#NewChannel">type NewChannel</a>
<ul>
<li><a href="#NewChannel.Accept">func (c *NewChannel) Accept() (*Channel, error)</a></li>
<li><a href="#NewChannel.ChannelType">func (c *NewChannel) ChannelType() string</a></li>
<li><a href="#NewChannel.ExtraData">func (c *NewChannel) ExtraData() []byte</a></li>
<li><a href="#NewChannel.Reject">func (c *NewChannel) Reject(reason RejectionReason, message string) error</a></li>
</ul>
</li>
<li>
<a href="#OpenChannelError">type OpenChannelError</a>
<ul>
<li><a href="#OpenChannelError.Error">func (e *OpenChannelError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#PartialSuccessError">type PartialSuccessError</a>
<ul>
<li><a href="#PartialSuccessError.Error">func (p *PartialSuccessError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#PassphraseMissingError">type PassphraseMissingError</a>
<ul>
<li><a href="#PassphraseMissingError.Error">func (*PassphraseMissingError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#Permissions">type Permissions</a>
</li>
<li>
<a href="#PrivateKeySigner">type PrivateKeySigner</a>
<ul>
<li><a href="#ParsePrivateKey">func ParsePrivateKey(pemBytes []byte) (*PrivateKeySigner, error)</a></li>
<li><a href="#ParsePrivateKeyWithPassphrase">func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (*PrivateKeySigner, error)</a></li>
<li><a href="#PrivateKeySigner.CryptoSigner">func (k *PrivateKeySigner) CryptoSigner() crypto.Signer</a></li>
</ul>
</li>
<li>
<a href="#PublicKey">type PublicKey</a>
<ul>
<li><a href="#NewPublicKey">func NewPublicKey(key crypto.PublicKey) (PublicKey, error)</a></li>
<li><a href="#ParseAuthorizedKey">func ParseAuthorizedKey(in []byte) (out PublicKey, comment string, options []string, rest []byte, err error)</a></li>
<li><a href="#ParseKnownHosts">func ParseKnownHosts(in []byte) (marker string, hosts []string, pubKey PublicKey, comment string, rest []byte, ...)</a></li>
<li><a href="#ParsePublicKey">func ParsePublicKey(in []byte) (out PublicKey, err error)</a></li>
</ul>
</li>
<li>
<a href="#RejectionReason">type RejectionReason</a>
<ul>
<li><a href="#RejectionReason.String">func (r RejectionReason) String() string</a></li>
</ul>
</li>
<li>
<a href="#Request">type Request</a>
<ul>
<li><a href="#Request.Reply">func (r *Request) Reply(ok bool, payload []byte) error</a></li>
</ul>
</li>
<li>
<a href="#RequestHandler">type RequestHandler</a>
</li>
<li>
<a href="#RequestHandlerFunc">type RequestHandlerFunc</a>
<ul>
<li><a href="#RequestHandlerFunc.NewRequest">func (f RequestHandlerFunc) NewRequest(req *Request)</a></li>
</ul>
</li>
<li>
<a href="#Server">type Server</a>
<ul>
<li><a href="#Server.AddHostKey">func (s *Server) AddHostKey(key Signer)</a></li>
<li><a href="#Server.Close">func (s *Server) Close() error</a></li>
<li><a href="#Server.ListenAndServe">func (s *Server) ListenAndServe(addr string) error</a></li>
<li><a href="#Server.Serve">func (s *Server) Serve(l net.Listener) error</a></li>
</ul>
</li>
<li>
<a href="#ServerAuthCallbacks">type ServerAuthCallbacks</a>
</li>
<li>
<a href="#ServerAuthError">type ServerAuthError</a>
<ul>
<li><a href="#ServerAuthError.Error">func (l ServerAuthError) Error() string</a></li>
</ul>
</li>
<li>
<a href="#ServerConn">type ServerConn</a>
<ul>
<li><a href="#NewServerConn">func NewServerConn(ctx context.Context, c net.Conn, config *Server) (*ServerConn, error)</a></li>
<li><a href="#ServerConn.Close">func (c *ServerConn) Close() error</a></li>
<li><a href="#ServerConn.Handle">func (c *ServerConn) Handle(channelHandler ChannelHandler, requestHandler RequestHandler) error</a></li>
</ul>
</li>
<li>
<a href="#Session">type Session</a>
<ul>
<li><a href="#Session.Close">func (s *Session) Close() error</a></li>
<li><a href="#Session.CombinedOutput">func (s *Session) CombinedOutput(cmd string) ([]byte, error)</a></li>
<li><a href="#Session.Output">func (s *Session) Output(cmd string) ([]byte, error)</a></li>
<li><a href="#Session.RequestPty">func (s *Session) RequestPty(term string, h, w int, termmodes TerminalModes) error</a></li>
<li><a href="#Session.RequestSubsystem">func (s *Session) RequestSubsystem(subsystem string) error</a></li>
<li><a href="#Session.Run">func (s *Session) Run(cmd string) error</a></li>
<li><a href="#Session.SendRequest">func (s *Session) SendRequest(name string, wantReply bool, payload []byte) (bool, error)</a></li>
<li><a href="#Session.Setenv">func (s *Session) Setenv(name, value string) error</a></li>
<li><a href="#Session.Shell">func (s *Session) Shell() error</a></li>
<li><a href="#Session.Signal">func (s *Session) Signal(sig Signal) error</a></li>
<li><a href="#Session.Start">func (s *Session) Start(cmd string) error</a></li>
<li><a href="#Session.StderrPipe">func (s *Session) StderrPipe() (io.Reader, error)</a></li>
<li><a href="#Session.StdinPipe">func (s *Session) StdinPipe() (io.WriteCloser, error)</a></li>
<li><a href="#Session.StdoutPipe">func (s *Session) StdoutPipe() (io.Reader, error)</a></li>
<li><a href="#Session.Wait">func (s *Session) Wait() error</a></li>
<li><a href="#Session.WindowChange">func (s *Session) WindowChange(h, w int) error</a></li>
</ul>
</li>
<li>
<a href="#Signal">type Signal</a>
</li>
<li>
<a href="#Signature">type Signature</a>
</li>
<li>
<a href="#Signer">type Signer</a>
<ul>
<li><a href="#NewCertSigner">func NewCertSigner(cert *Certificate, signer Signer) (Signer, error)</a></li>
<li><a href="#NewSigner">func NewSigner(signer crypto.Signer) (Signer, error)</a></li>
<li><a href="#NewSignerWithAlgorithms">func NewSignerWithAlgorithms(signer Signer, algorithms []string) (Signer, error)</a></li>
</ul>
</li>
<li>
<a href="#TerminalModes">type TerminalModes</a>
</li>
<li>
<a href="#Waitmsg">type Waitmsg</a>
<ul>
<li><a href="#Waitmsg.ExitStatus">func (w Waitmsg) ExitStatus() int</a></li>
<li><a href="#Waitmsg.Lang">func (w Waitmsg) Lang() string</a></li>
<li><a href="#Waitmsg.Msg">func (w Waitmsg) Msg() string</a></li>
<li><a href="#Waitmsg.Signal">func (w Waitmsg) Signal() string</a></li>
<li><a href="#Waitmsg.String">func (w Waitmsg) String() string</a></li>
</ul>
</li>
</ul><h4 id="pkg-examples">Examples</h4>
<ul>
<li><a href="#example-Certificate.SignCert">Certificate.SignCert</a></li>
<li><a href="#example-Client.Listen">Client.Listen</a></li>
<li><a href="#example-Dial">Dial</a></li>
<li><a href="#example-NewServerConn">NewServerConn</a></li>
<li><a href="#example-PublicKeys">PublicKeys</a></li>
<li><a href="#example-RetryableAuthMethod">RetryableAuthMethod</a></li>
<li><a href="#example-Server.AddHostKey">Server.AddHostKey</a></li>
<li><a href="#example-Server.ListenAndServe">Server.ListenAndServe</a></li>
<li><a href="#example-Session.RequestPty">Session.RequestPty</a></li>
</ul><h3 id="pkg-constants">Constants</h3>
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="CertAlgoRSAv01"><span class="nx">CertAlgoRSAv01</span></span> <span class="p">=</span> <span class="s">&#34;ssh-rsa-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoECDSA256v01"><span class="nx">CertAlgoECDSA256v01</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp256-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoECDSA384v01"><span class="nx">CertAlgoECDSA384v01</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp384-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoECDSA521v01"><span class="nx">CertAlgoECDSA521v01</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp521-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoSKECDSA256v01"><span class="nx">CertAlgoSKECDSA256v01</span></span> <span class="p">=</span> <span class="s">&#34;sk-ecdsa-sha2-nistp256-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoED25519v01"><span class="nx">CertAlgoED25519v01</span></span> <span class="p">=</span> <span class="s">&#34;ssh-ed25519-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoSKED25519v01"><span class="nx">CertAlgoSKED25519v01</span></span> <span class="p">=</span> <span class="s">&#34;sk-ssh-ed25519-cert-v01@openssh.com&#34;</span>
<span class="c1">// CertAlgoRSASHA256v01 and CertAlgoRSASHA512v01 can&#39;t appear as a
</span><span class="c1"></span> <span class="c1">// Certificate.Type (or PublicKey.Type), but only in
</span><span class="c1"></span> <span class="c1">// ClientConfig.HostKeyAlgorithms.
</span><span class="c1"></span> <span id="CertAlgoRSASHA256v01"><span class="nx">CertAlgoRSASHA256v01</span></span> <span class="p">=</span> <span class="s">&#34;rsa-sha2-256-cert-v01@openssh.com&#34;</span>
<span id="CertAlgoRSASHA512v01"><span class="nx">CertAlgoRSASHA512v01</span></span> <span class="p">=</span> <span class="s">&#34;rsa-sha2-512-cert-v01@openssh.com&#34;</span>
<span class="p">)</span></pre>
<p>Certificate algorithm names from [PROTOCOL.certkeys]. These values can appear
in Certificate.Type, PublicKey.Type, and ClientConfig.HostKeyAlgorithms.
Unlike key algorithm names, these are not passed to AlgorithmSigner nor
returned by MultiAlgorithmSigner and don&apos;t appear in the Signature.Format
field.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="UserCert"><span class="nx">UserCert</span></span> <span class="p">=</span> <span class="mi">1</span>
<span id="HostCert"><span class="nx">HostCert</span></span> <span class="p">=</span> <span class="mi">2</span>
<span class="p">)</span></pre>
<p>Certificate types distinguish between host and user
certificates. The values can be set in the CertType field of
Certificate.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="CipherAES128GCM"><span class="nx">CipherAES128GCM</span></span> <span class="p">=</span> <span class="s">&#34;aes128-gcm@openssh.com&#34;</span>
<span id="CipherAES256GCM"><span class="nx">CipherAES256GCM</span></span> <span class="p">=</span> <span class="s">&#34;aes256-gcm@openssh.com&#34;</span>
<span id="CipherChacha20Poly1305"><span class="nx">CipherChacha20Poly1305</span></span> <span class="p">=</span> <span class="s">&#34;chacha20-poly1305@openssh.com&#34;</span>
<span id="CipherAES128CTR"><span class="nx">CipherAES128CTR</span></span> <span class="p">=</span> <span class="s">&#34;aes128-ctr&#34;</span>
<span id="CipherAES192CTR"><span class="nx">CipherAES192CTR</span></span> <span class="p">=</span> <span class="s">&#34;aes192-ctr&#34;</span>
<span id="CipherAES256CTR"><span class="nx">CipherAES256CTR</span></span> <span class="p">=</span> <span class="s">&#34;aes256-ctr&#34;</span>
<span id="InsecureCipherAES128CBC"><span class="nx">InsecureCipherAES128CBC</span></span> <span class="p">=</span> <span class="s">&#34;aes128-cbc&#34;</span>
<span id="InsecureCipherTripleDESCBC"><span class="nx">InsecureCipherTripleDESCBC</span></span> <span class="p">=</span> <span class="s">&#34;3des-cbc&#34;</span>
<span id="InsecureCipherRC4"><span class="nx">InsecureCipherRC4</span></span> <span class="p">=</span> <span class="s">&#34;arcfour&#34;</span>
<span id="InsecureCipherRC4128"><span class="nx">InsecureCipherRC4128</span></span> <span class="p">=</span> <span class="s">&#34;arcfour128&#34;</span>
<span id="InsecureCipherRC4256"><span class="nx">InsecureCipherRC4256</span></span> <span class="p">=</span> <span class="s">&#34;arcfour256&#34;</span>
<span class="p">)</span></pre>
<p>Implemented ciphers algorithms.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="InsecureKeyExchangeDH1SHA1"><span class="nx">InsecureKeyExchangeDH1SHA1</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group1-sha1&#34;</span>
<span id="InsecureKeyExchangeDH14SHA1"><span class="nx">InsecureKeyExchangeDH14SHA1</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group14-sha1&#34;</span>
<span id="KeyExchangeDH14SHA256"><span class="nx">KeyExchangeDH14SHA256</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group14-sha256&#34;</span>
<span id="KeyExchangeDH16SHA512"><span class="nx">KeyExchangeDH16SHA512</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group16-sha512&#34;</span>
<span id="KeyExchangeECDHP256"><span class="nx">KeyExchangeECDHP256</span></span> <span class="p">=</span> <span class="s">&#34;ecdh-sha2-nistp256&#34;</span>
<span id="KeyExchangeECDHP384"><span class="nx">KeyExchangeECDHP384</span></span> <span class="p">=</span> <span class="s">&#34;ecdh-sha2-nistp384&#34;</span>
<span id="KeyExchangeECDHP521"><span class="nx">KeyExchangeECDHP521</span></span> <span class="p">=</span> <span class="s">&#34;ecdh-sha2-nistp521&#34;</span>
<span id="KeyExchangeCurve25519SHA256"><span class="nx">KeyExchangeCurve25519SHA256</span></span> <span class="p">=</span> <span class="s">&#34;curve25519-sha256&#34;</span>
<span id="InsecureKeyExchangeDHGEXSHA1"><span class="nx">InsecureKeyExchangeDHGEXSHA1</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group-exchange-sha1&#34;</span>
<span id="KeyExchangeDHGEXSHA256"><span class="nx">KeyExchangeDHGEXSHA256</span></span> <span class="p">=</span> <span class="s">&#34;diffie-hellman-group-exchange-sha256&#34;</span>
<span class="p">)</span></pre>
<p>Implemented key exchanges algorithms.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="HMACSHA256ETM"><span class="nx">HMACSHA256ETM</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha2-256-etm@openssh.com&#34;</span>
<span id="HMACSHA512ETM"><span class="nx">HMACSHA512ETM</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha2-512-etm@openssh.com&#34;</span>
<span id="HMACSHA256"><span class="nx">HMACSHA256</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha2-256&#34;</span>
<span id="HMACSHA512"><span class="nx">HMACSHA512</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha2-512&#34;</span>
<span id="InsecureHMACSHA1"><span class="nx">InsecureHMACSHA1</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha1&#34;</span>
<span id="InsecureHMACSHA196"><span class="nx">InsecureHMACSHA196</span></span> <span class="p">=</span> <span class="s">&#34;hmac-sha1-96&#34;</span>
<span class="p">)</span></pre>
<p>Implemented message authentication code (MAC) algorithms.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="KeyTypeRSA"><span class="nx">KeyTypeRSA</span></span> <span class="p">=</span> <span class="s">&#34;ssh-rsa&#34;</span>
<span id="KeyTypeECDSA256"><span class="nx">KeyTypeECDSA256</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp256&#34;</span>
<span id="KeyTypeECDSA384"><span class="nx">KeyTypeECDSA384</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp384&#34;</span>
<span id="KeyTypeECDSA521"><span class="nx">KeyTypeECDSA521</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp521&#34;</span>
<span id="KeyTypeSKECDSA256"><span class="nx">KeyTypeSKECDSA256</span></span> <span class="p">=</span> <span class="s">&#34;sk-ecdsa-sha2-nistp256@openssh.com&#34;</span>
<span id="KeyTypeED25519"><span class="nx">KeyTypeED25519</span></span> <span class="p">=</span> <span class="s">&#34;ssh-ed25519&#34;</span>
<span id="KeyTypeSKED25519"><span class="nx">KeyTypeSKED25519</span></span> <span class="p">=</span> <span class="s">&#34;sk-ssh-ed25519@openssh.com&#34;</span>
<span class="p">)</span></pre>
<p>Implemented public key types.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="KeyAlgoRSA"><span class="nx">KeyAlgoRSA</span></span> <span class="p">=</span> <span class="s">&#34;ssh-rsa&#34;</span>
<span id="KeyAlgoECDSA256"><span class="nx">KeyAlgoECDSA256</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp256&#34;</span>
<span id="KeyAlgoSKECDSA256"><span class="nx">KeyAlgoSKECDSA256</span></span> <span class="p">=</span> <span class="s">&#34;sk-ecdsa-sha2-nistp256@openssh.com&#34;</span>
<span id="KeyAlgoECDSA384"><span class="nx">KeyAlgoECDSA384</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp384&#34;</span>
<span id="KeyAlgoECDSA521"><span class="nx">KeyAlgoECDSA521</span></span> <span class="p">=</span> <span class="s">&#34;ecdsa-sha2-nistp521&#34;</span>
<span id="KeyAlgoED25519"><span class="nx">KeyAlgoED25519</span></span> <span class="p">=</span> <span class="s">&#34;ssh-ed25519&#34;</span>
<span id="KeyAlgoSKED25519"><span class="nx">KeyAlgoSKED25519</span></span> <span class="p">=</span> <span class="s">&#34;sk-ssh-ed25519@openssh.com&#34;</span>
<span class="c1">// KeyAlgoRSASHA256 and KeyAlgoRSASHA512 are only public key algorithms, not
</span><span class="c1"></span> <span class="c1">// public key formats, so they can&#39;t appear as a PublicKey.Type. The
</span><span class="c1"></span> <span class="c1">// corresponding PublicKey.Type is KeyAlgoRSA. See RFC 8332, Section 2.
</span><span class="c1"></span> <span id="KeyAlgoRSASHA256"><span class="nx">KeyAlgoRSASHA256</span></span> <span class="p">=</span> <span class="s">&#34;rsa-sha2-256&#34;</span>
<span id="KeyAlgoRSASHA512"><span class="nx">KeyAlgoRSASHA512</span></span> <span class="p">=</span> <span class="s">&#34;rsa-sha2-512&#34;</span>
<span class="p">)</span></pre>
<p>Public key algorithms names. These values can appear in PublicKey.Type,
ClientConfig.HostKeyAlgorithms, Signature.Format, or as AlgorithmSigner
arguments.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="VINTR"><span class="nx">VINTR</span></span> <span class="p">=</span> <span class="mi">1</span>
<span id="VQUIT"><span class="nx">VQUIT</span></span> <span class="p">=</span> <span class="mi">2</span>
<span id="VERASE"><span class="nx">VERASE</span></span> <span class="p">=</span> <span class="mi">3</span>
<span id="VKILL"><span class="nx">VKILL</span></span> <span class="p">=</span> <span class="mi">4</span>
<span id="VEOF"><span class="nx">VEOF</span></span> <span class="p">=</span> <span class="mi">5</span>
<span id="VEOL"><span class="nx">VEOL</span></span> <span class="p">=</span> <span class="mi">6</span>
<span id="VEOL2"><span class="nx">VEOL2</span></span> <span class="p">=</span> <span class="mi">7</span>
<span id="VSTART"><span class="nx">VSTART</span></span> <span class="p">=</span> <span class="mi">8</span>
<span id="VSTOP"><span class="nx">VSTOP</span></span> <span class="p">=</span> <span class="mi">9</span>
<span id="VSUSP"><span class="nx">VSUSP</span></span> <span class="p">=</span> <span class="mi">10</span>
<span id="VDSUSP"><span class="nx">VDSUSP</span></span> <span class="p">=</span> <span class="mi">11</span>
<span id="VREPRINT"><span class="nx">VREPRINT</span></span> <span class="p">=</span> <span class="mi">12</span>
<span id="VWERASE"><span class="nx">VWERASE</span></span> <span class="p">=</span> <span class="mi">13</span>
<span id="VLNEXT"><span class="nx">VLNEXT</span></span> <span class="p">=</span> <span class="mi">14</span>
<span id="VFLUSH"><span class="nx">VFLUSH</span></span> <span class="p">=</span> <span class="mi">15</span>
<span id="VSWTCH"><span class="nx">VSWTCH</span></span> <span class="p">=</span> <span class="mi">16</span>
<span id="VSTATUS"><span class="nx">VSTATUS</span></span> <span class="p">=</span> <span class="mi">17</span>
<span id="VDISCARD"><span class="nx">VDISCARD</span></span> <span class="p">=</span> <span class="mi">18</span>
<span id="IGNPAR"><span class="nx">IGNPAR</span></span> <span class="p">=</span> <span class="mi">30</span>
<span id="PARMRK"><span class="nx">PARMRK</span></span> <span class="p">=</span> <span class="mi">31</span>
<span id="INPCK"><span class="nx">INPCK</span></span> <span class="p">=</span> <span class="mi">32</span>
<span id="ISTRIP"><span class="nx">ISTRIP</span></span> <span class="p">=</span> <span class="mi">33</span>
<span id="INLCR"><span class="nx">INLCR</span></span> <span class="p">=</span> <span class="mi">34</span>
<span id="IGNCR"><span class="nx">IGNCR</span></span> <span class="p">=</span> <span class="mi">35</span>
<span id="ICRNL"><span class="nx">ICRNL</span></span> <span class="p">=</span> <span class="mi">36</span>
<span id="IUCLC"><span class="nx">IUCLC</span></span> <span class="p">=</span> <span class="mi">37</span>
<span id="IXON"><span class="nx">IXON</span></span> <span class="p">=</span> <span class="mi">38</span>
<span id="IXANY"><span class="nx">IXANY</span></span> <span class="p">=</span> <span class="mi">39</span>
<span id="IXOFF"><span class="nx">IXOFF</span></span> <span class="p">=</span> <span class="mi">40</span>
<span id="IMAXBEL"><span class="nx">IMAXBEL</span></span> <span class="p">=</span> <span class="mi">41</span>
<span id="IUTF8"><span class="nx">IUTF8</span></span> <span class="p">=</span> <span class="mi">42</span> <span class="c1">// RFC 8160
</span><span class="c1"></span> <span id="ISIG"><span class="nx">ISIG</span></span> <span class="p">=</span> <span class="mi">50</span>
<span id="ICANON"><span class="nx">ICANON</span></span> <span class="p">=</span> <span class="mi">51</span>
<span id="XCASE"><span class="nx">XCASE</span></span> <span class="p">=</span> <span class="mi">52</span>
<span id="ECHO"><span class="nx">ECHO</span></span> <span class="p">=</span> <span class="mi">53</span>
<span id="ECHOE"><span class="nx">ECHOE</span></span> <span class="p">=</span> <span class="mi">54</span>
<span id="ECHOK"><span class="nx">ECHOK</span></span> <span class="p">=</span> <span class="mi">55</span>
<span id="ECHONL"><span class="nx">ECHONL</span></span> <span class="p">=</span> <span class="mi">56</span>
<span id="NOFLSH"><span class="nx">NOFLSH</span></span> <span class="p">=</span> <span class="mi">57</span>
<span id="TOSTOP"><span class="nx">TOSTOP</span></span> <span class="p">=</span> <span class="mi">58</span>
<span id="IEXTEN"><span class="nx">IEXTEN</span></span> <span class="p">=</span> <span class="mi">59</span>
<span id="ECHOCTL"><span class="nx">ECHOCTL</span></span> <span class="p">=</span> <span class="mi">60</span>
<span id="ECHOKE"><span class="nx">ECHOKE</span></span> <span class="p">=</span> <span class="mi">61</span>
<span id="PENDIN"><span class="nx">PENDIN</span></span> <span class="p">=</span> <span class="mi">62</span>
<span id="OPOST"><span class="nx">OPOST</span></span> <span class="p">=</span> <span class="mi">70</span>
<span id="OLCUC"><span class="nx">OLCUC</span></span> <span class="p">=</span> <span class="mi">71</span>
<span id="ONLCR"><span class="nx">ONLCR</span></span> <span class="p">=</span> <span class="mi">72</span>
<span id="OCRNL"><span class="nx">OCRNL</span></span> <span class="p">=</span> <span class="mi">73</span>
<span id="ONOCR"><span class="nx">ONOCR</span></span> <span class="p">=</span> <span class="mi">74</span>
<span id="ONLRET"><span class="nx">ONLRET</span></span> <span class="p">=</span> <span class="mi">75</span>
<span id="CS7"><span class="nx">CS7</span></span> <span class="p">=</span> <span class="mi">90</span>
<span id="CS8"><span class="nx">CS8</span></span> <span class="p">=</span> <span class="mi">91</span>
<span id="PARENB"><span class="nx">PARENB</span></span> <span class="p">=</span> <span class="mi">92</span>
<span id="PARODD"><span class="nx">PARODD</span></span> <span class="p">=</span> <span class="mi">93</span>
<span id="TTY_OP_ISPEED"><span class="nx">TTY_OP_ISPEED</span></span> <span class="p">=</span> <span class="mi">128</span>
<span id="TTY_OP_OSPEED"><span class="nx">TTY_OP_OSPEED</span></span> <span class="p">=</span> <span class="mi">129</span>
<span class="p">)</span></pre>
<p>POSIX terminal mode flags as listed in RFC 4254 Section 8.
<pre class="chroma"><span class="kd">const</span> <span id="CertTimeInfinity"><span class="nx">CertTimeInfinity</span></span> <span class="p">=</span> <span class="mi">1</span><span class="o">&lt;&lt;</span><span class="mi">64</span> <span class="o">-</span> <span class="mi">1</span></pre>
<p>CertTimeInfinity can be used for OpenSSHCertV01.ValidBefore to indicate that
a certificate does not expire.
<h3 id="pkg-variables">Variables</h3>
<pre class="chroma"><span class="kd">var</span> <span id="ErrNoAuth"><span class="nx">ErrNoAuth</span></span> <span class="p">=</span> <a href="https://pkg.go.dev/errors"><span class="nx">errors</span></a><span class="p">.</span><a href="https://pkg.go.dev/errors#New"><span class="nf">New</span></a><span class="p">(</span><span class="s">&#34;ssh: no auth passed yet&#34;</span><span class="p">)</span></pre>
<p>ErrNoAuth is the error value returned if no
authentication method has been passed yet. This happens as a normal
part of the authentication loop, since the client first tries
&apos;none&apos; authentication to discover available methods.
It is returned in ServerAuthError.Errors from NewServerConn.
<h3 id="pkg-functions">Functions</h3>
<h3 id="FingerprintLegacyMD5">func FingerprintLegacyMD5</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">FingerprintLegacyMD5</span><span class="p">(</span><span class="nx">pubKey</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>FingerprintLegacyMD5 returns the user presentation of the key&apos;s
fingerprint as described by RFC 4716 section 4.
<h3 id="FingerprintSHA256">func FingerprintSHA256</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">FingerprintSHA256</span><span class="p">(</span><span class="nx">pubKey</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>FingerprintSHA256 returns the user presentation of the key&apos;s
fingerprint as unpadded base64 encoded sha256 hash.
This format was introduced from OpenSSH 6.8.
<a href="https://www.openssh.com/txt/release-6.8">https://www.openssh.com/txt/release-6.8</a>
<a href="https://tools.ietf.org/html/rfc4648#section-3.2">https://tools.ietf.org/html/rfc4648#section-3.2</a> (unpadded base64 encoding)
<h3 id="Marshal">func Marshal</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">Marshal</span><span class="p">(</span><span class="nx">msg</span> <span class="kd">interface</span><span class="p">{})</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>Marshal serializes the message in msg to SSH wire format. The msg
argument should be a struct or pointer to struct. If the first
member has the &quot;sshtype&quot; tag set to a number in decimal, that
number is prepended to the result. If the last of member has the
&quot;ssh&quot; tag set to &quot;rest&quot;, its contents are appended to the output.
<h3 id="MarshalAuthorizedKey">func MarshalAuthorizedKey</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">MarshalAuthorizedKey</span><span class="p">(</span><span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>MarshalAuthorizedKey serializes key for inclusion in an OpenSSH
authorized_keys file. The return value ends with newline.
<h3 id="MarshalPrivateKey">func MarshalPrivateKey</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">MarshalPrivateKey</span><span class="p">(</span><span class="nx">key</span> <a href="https://pkg.go.dev/crypto"><span class="nx">crypto</span></a><span class="p">.</span><a href="https://pkg.go.dev/crypto#PrivateKey"><span class="nx">PrivateKey</span></a><span class="p">,</span> <span class="nx">options</span> <a href="#MarshalPrivateKeyOptions"><span class="nx">MarshalPrivateKeyOptions</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="https://pkg.go.dev/encoding/pem"><span class="nx">pem</span></a><span class="p">.</span><a href="https://pkg.go.dev/encoding/pem#Block"><span class="nx">Block</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>MarshalPrivateKey returns a PEM block with the private key serialized in the
OpenSSH format.
<h3 id="Unmarshal">func Unmarshal</h3>
<pre class="chroma"><span class="kd">func</span> <span class="nf">Unmarshal</span><span class="p">(</span><span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">out</span> <span class="kd">interface</span><span class="p">{})</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Unmarshal parses data in SSH wire format into a structure. The out
argument should be a pointer to struct. If the first member of the
struct has the &quot;sshtype&quot; tag set to a &apos;|&apos;-separated set of numbers
in decimal, the packet must start with one of those numbers. In
case of error, Unmarshal returns a ParseError or
UnexpectedMessageError.
<h3 id="pkg-types">Types</h3>
<h3 id="Algorithms">type Algorithms</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Algorithms</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="Algorithms.KeyExchanges"><span class="nx">KeyExchanges</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Algorithms.Ciphers"><span class="nx">Ciphers</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Algorithms.MACs"><span class="nx">MACs</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Algorithms.HostKeys"><span class="nx">HostKeys</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Algorithms.PublicKeyAuths"><span class="nx">PublicKeyAuths</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>Algorithms defines a set of algorithms that can be configured in the client
or server config for negotiation during a handshake.
<h4 id="InsecureAlgorithms">func InsecureAlgorithms</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">InsecureAlgorithms</span><span class="p">()</span> <a href="#Algorithms"><span class="nx">Algorithms</span></a></pre>
<p>InsecureAlgorithms returns algorithms currently implemented by this package
and which have security issues.
<h4 id="SupportedAlgorithms">func SupportedAlgorithms</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">SupportedAlgorithms</span><span class="p">()</span> <a href="#Algorithms"><span class="nx">Algorithms</span></a></pre>
<p>SupportedAlgorithms returns algorithms currently implemented by this package,
excluding those with security issues, which are returned by
InsecureAlgorithms. The algorithms listed here are in preference order.
<h3 id="AuthMethod">type AuthMethod</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">AuthMethod</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported methods
</span><span class="c1"></span><span class="p">}</span></pre>
<p>An AuthMethod represents an instance of an RFC 4252 authentication method.
<h4 id="GSSAPIWithMICAuthMethod">func GSSAPIWithMICAuthMethod</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">GSSAPIWithMICAuthMethod</span><span class="p">(</span><span class="nx">gssAPIClient</span> <a href="#GSSAPIClient"><span class="nx">GSSAPIClient</span></a><span class="p">,</span> <span class="nx">target</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>GSSAPIWithMICAuthMethod is an AuthMethod with &quot;gssapi-with-mic&quot; authentication.
See RFC 4462 section 3
gssAPIClient is implementation of the GSSAPIClient interface, see the definition of the interface for details.
target is the server host you want to log in to.
<h4 id="KeyboardInteractive">func KeyboardInteractive</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">KeyboardInteractive</span><span class="p">(</span><span class="nx">challenge</span> <a href="#KeyboardInteractiveChallenge"><span class="nx">KeyboardInteractiveChallenge</span></a><span class="p">)</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>KeyboardInteractive returns an AuthMethod using a prompt/response
sequence controlled by the server.
<h4 id="Password">func Password</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">Password</span><span class="p">(</span><span class="nx">secret</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>Password returns an AuthMethod using the given password.
<h4 id="PasswordCallback">func PasswordCallback</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">PasswordCallback</span><span class="p">(</span><span class="nx">prompt</span> <span class="kd">func</span><span class="p">()</span> <span class="p">(</span><span class="nx">secret</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">))</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>PasswordCallback returns an AuthMethod that uses a callback for
fetching a password.
<h4 id="PublicKeys">func PublicKeys</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">PublicKeys</span><span class="p">(</span><span class="nx">signers</span> <span class="o">...</span><a href="#Signer"><span class="nx">Signer</span></a><span class="p">)</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>PublicKeys returns an AuthMethod that uses the given key
pairs.
<details id="example-PublicKeys" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;context&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;os&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">hostKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span>
<span class="c1">// A public key may be used to authenticate against the remote
</span><span class="c1"></span> <span class="c1">// server by using an unencrypted PEM-encoded private key file.
</span><span class="c1"></span> <span class="c1">//
</span><span class="c1"></span> <span class="c1">// If you have an encrypted private key, the crypto/x509 package
</span><span class="c1"></span> <span class="c1">// can be used to decrypt it.
</span><span class="c1"></span> <span class="nx">key</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;/home/user/.ssh/id_rsa&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;unable to read private key: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Create the Signer for this private key.
</span><span class="c1"></span> <span class="nx">signer</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParsePrivateKey</span><span class="p">(</span><span class="nx">key</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;unable to parse private key: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">ClientConfig</span><span class="p">{</span>
<span class="nx">User</span><span class="p">:</span> <span class="s">&#34;user&#34;</span><span class="p">,</span>
<span class="nx">Auth</span><span class="p">:</span> <span class="p">[]</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">AuthMethod</span><span class="p">{</span>
<span class="c1">// Use the PublicKeys method for remote authentication.
</span><span class="c1"></span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">PublicKeys</span><span class="p">(</span><span class="nx">signer</span><span class="p">),</span>
<span class="p">},</span>
<span class="nx">HostKey</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FixedHostKey</span><span class="p">(</span><span class="nx">hostKey</span><span class="p">),</span>
<span class="p">}</span>
<span class="c1">// Connect to the remote server and perform the SSH handshake.
</span><span class="c1"></span> <span class="nx">client</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">Dial</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;host.com:22&#34;</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;unable to connect: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">client</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="p">}</span></pre>
</details>
<h4 id="PublicKeysCallback">func PublicKeysCallback</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">PublicKeysCallback</span><span class="p">(</span><span class="nx">getSigners</span> <span class="kd">func</span><span class="p">()</span> <span class="p">(</span><span class="nx">signers</span> <span class="p">[]</span><a href="#Signer"><span class="nx">Signer</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">))</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>PublicKeysCallback returns an AuthMethod that runs the given
function to obtain a list of key pairs.
<h4 id="RetryableAuthMethod">func RetryableAuthMethod</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">RetryableAuthMethod</span><span class="p">(</span><span class="nx">auth</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a><span class="p">,</span> <span class="nx">maxTries</span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a><span class="p">)</span> <a href="#AuthMethod"><span class="nx">AuthMethod</span></a></pre>
<p>RetryableAuthMethod is a decorator for other auth methods enabling them to
be retried up to maxTries before considering that AuthMethod itself failed.
If maxTries is &lt;= 0, will retry indefinitely
<p>This is useful for interactive clients using challenge/response type
authentication (e.g. Keyboard-Interactive, Password, etc) where the user
could mistype their response resulting in the server issuing a
SSH_MSG_USERAUTH_FAILURE (rfc4252 #8 [password] and rfc4256 #3.4
[keyboard-interactive]); Without this decorator, the non-retryable
AuthMethod would be removed from future consideration, and never tried again
(and so the user would never be able to retry their entry).
<details id="example-RetryableAuthMethod" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="nx">user</span> <span class="o">:=</span> <span class="s">&#34;testuser&#34;</span>
<span class="nx">NumberOfPrompts</span> <span class="o">:=</span> <span class="mi">3</span>
<span class="c1">// Normally this would be a callback that prompts the user to answer the
</span><span class="c1">// provided questions
</span><span class="c1"></span><span class="nx">Cb</span> <span class="o">:=</span> <span class="kd">func</span><span class="p">(</span><span class="nx">user</span><span class="p">,</span> <span class="nx">instruction</span> <span class="kt">string</span><span class="p">,</span> <span class="nx">questions</span> <span class="p">[]</span><span class="kt">string</span><span class="p">,</span> <span class="nx">echos</span> <span class="p">[]</span><span class="kt">bool</span><span class="p">)</span> <span class="p">(</span><span class="nx">answers</span> <span class="p">[]</span><span class="kt">string</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">return</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="s">&#34;answer1&#34;</span><span class="p">,</span> <span class="s">&#34;answer2&#34;</span><span class="p">},</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ClientConfig</span><span class="p">{</span>
<span class="nx">HostKey</span><span class="p">:</span> <span class="nf">InsecureIgnoreHostKey</span><span class="p">(),</span>
<span class="nx">User</span><span class="p">:</span> <span class="nx">user</span><span class="p">,</span>
<span class="nx">Auth</span><span class="p">:</span> <span class="p">[]</span><span class="nx">AuthMethod</span><span class="p">{</span>
<span class="nf">RetryableAuthMethod</span><span class="p">(</span><span class="nf">KeyboardInteractiveChallenge</span><span class="p">(</span><span class="nx">Cb</span><span class="p">),</span> <span class="nx">NumberOfPrompts</span><span class="p">),</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="nx">host</span> <span class="o">:=</span> <span class="s">&#34;mysshserver&#34;</span>
<span class="nx">netConn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nf">Dial</span><span class="p">(</span><span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="nx">host</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">sshConn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nf">NewClientConn</span><span class="p">(</span><span class="nx">netConn</span><span class="p">,</span> <span class="nx">host</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">_</span> <span class="p">=</span> <span class="nx">sshConn</span></pre>
</details>
<h3 id="BannerCallback">type BannerCallback</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">BannerCallback</span> <span class="kd">func</span><span class="p">(</span><span class="nx">message</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>BannerCallback is the function type used for treat the banner sent by
the server. A BannerCallback receives the message sent by the remote server.
<h4 id="BannerDisplayStderr">func BannerDisplayStderr</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">BannerDisplayStderr</span><span class="p">()</span> <a href="#BannerCallback"><span class="nx">BannerCallback</span></a></pre>
<p>BannerDisplayStderr returns a function that can be used for
ClientConfig.BannerCallback to display banners on os.Stderr.
<h3 id="BannerError">type BannerError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">BannerError</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="BannerError.Err"><span class="nx">Err</span></span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span id="BannerError.Message"><span class="nx">Message</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>BannerError is an error that can be returned by authentication handlers in
Server to send a banner message to the client.
<h4 id="BannerError.Error">func (*BannerError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><a href="#BannerError"><span class="nx">BannerError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h4 id="BannerError.Unwrap">func (*BannerError) Unwrap</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">b</span> <span class="o">*</span><a href="#BannerError"><span class="nx">BannerError</span></a><span class="p">)</span> <span class="nf">Unwrap</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<h3 id="CertChecker">type CertChecker</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">CertChecker</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// SupportedCriticalOptions lists the CriticalOptions that the
</span><span class="c1"></span> <span class="c1">// server application layer understands. These are only used
</span><span class="c1"></span> <span class="c1">// for user certificates.
</span><span class="c1"></span> <span id="CertChecker.SupportedCriticalOptions"><span class="nx">SupportedCriticalOptions</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// IsUserAuthority should return true if the key is recognized as an
</span><span class="c1"></span> <span class="c1">// authority for the given user certificate. This allows for
</span><span class="c1"></span> <span class="c1">// certificates to be signed by other certificates. This must be set
</span><span class="c1"></span> <span class="c1">// if this CertChecker will be checking user certificates.
</span><span class="c1"></span> <span id="CertChecker.IsUserAuthority"><span class="nx">IsUserAuthority</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">auth</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a>
<span class="c1">// IsHostAuthority should report whether the key is recognized as
</span><span class="c1"></span> <span class="c1">// an authority for this host. This allows for certificates to be
</span><span class="c1"></span> <span class="c1">// signed by other keys, and for those other keys to only be valid
</span><span class="c1"></span> <span class="c1">// signers for particular hostnames. This must be set if this
</span><span class="c1"></span> <span class="c1">// CertChecker will be checking host certificates.
</span><span class="c1"></span> <span id="CertChecker.IsHostAuthority"><span class="nx">IsHostAuthority</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">auth</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">,</span> <span class="nx">address</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a>
<span class="c1">// Clock is used for verifying time stamps. If nil, time.Now
</span><span class="c1"></span> <span class="c1">// is used.
</span><span class="c1"></span> <span id="CertChecker.Clock"><span class="nx">Clock</span></span> <span class="kd">func</span><span class="p">()</span> <a href="https://pkg.go.dev/time"><span class="nx">time</span></a><span class="p">.</span><a href="https://pkg.go.dev/time#Time"><span class="nx">Time</span></a>
<span class="c1">// UserKeyFallback is called when CertChecker.Authenticate encounters a
</span><span class="c1"></span> <span class="c1">// public key that is not a certificate. It must implement validation
</span><span class="c1"></span> <span class="c1">// of user keys or else, if nil, all such keys are rejected.
</span><span class="c1"></span> <span id="CertChecker.UserKeyFallback"><span class="nx">UserKeyFallback</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// HostKeyFallback is called when CertChecker.CheckHostKey encounters a
</span><span class="c1"></span> <span class="c1">// public key that is not a certificate. It must implement host key
</span><span class="c1"></span> <span class="c1">// validation or else, if nil, all such keys are rejected.
</span><span class="c1"></span> <span id="CertChecker.HostKeyFallback"><span class="nx">HostKeyFallback</span></span> <a href="#HostKeyCallback"><span class="nx">HostKeyCallback</span></a>
<span class="c1">// IsRevoked is called for each certificate so that revocation checking
</span><span class="c1"></span> <span class="c1">// can be implemented. It should return true if the given certificate
</span><span class="c1"></span> <span class="c1">// is revoked and false otherwise. If nil, no certificates are
</span><span class="c1"></span> <span class="c1">// considered to have been revoked.
</span><span class="c1"></span> <span id="CertChecker.IsRevoked"><span class="nx">IsRevoked</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">cert</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a>
<span class="p">}</span></pre>
<p>CertChecker does the work of verifying a certificate. Its methods
can be plugged into ClientConfig.HostKeyCallback and
Server.PublicKeyCallback. For the CertChecker to work,
minimally, the IsAuthority callback should be set.
<h4 id="CertChecker.Authenticate">func (*CertChecker) Authenticate</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#CertChecker"><span class="nx">CertChecker</span></a><span class="p">)</span> <span class="nf">Authenticate</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">pubKey</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Authenticate checks a user certificate. Authenticate can be used as
a value for Server.PublicKeyCallback.
<h4 id="CertChecker.CheckCert">func (*CertChecker) CheckCert</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#CertChecker"><span class="nx">CertChecker</span></a><span class="p">)</span> <span class="nf">CheckCert</span><span class="p">(</span><span class="nx">principal</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">cert</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>CheckCert checks CriticalOptions, ValidPrincipals, revocation, timestamp and
the signature of the certificate.
<h4 id="CertChecker.CheckHostKey">func (*CertChecker) CheckHostKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#CertChecker"><span class="nx">CertChecker</span></a><span class="p">)</span> <span class="nf">CheckHostKey</span><span class="p">(</span><span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">remote</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Addr"><span class="nx">Addr</span></a><span class="p">,</span> <span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>CheckHostKey checks a host key certificate. This method can be
plugged into ClientConfig.HostKeyCallback.
<h3 id="Certificate">type Certificate</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Certificate</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="Certificate.Nonce"><span class="nx">Nonce</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a>
<span id="Certificate.Key"><span class="nx">Key</span></span> <a href="#PublicKey"><span class="nx">PublicKey</span></a>
<span id="Certificate.Serial"><span class="nx">Serial</span></span> <a href="https://pkg.go.dev/builtin#uint64"><span class="kt">uint64</span></a>
<span id="Certificate.CertType"><span class="nx">CertType</span></span> <a href="https://pkg.go.dev/builtin#uint32"><span class="kt">uint32</span></a>
<span id="Certificate.KeyId"><span class="nx">KeyId</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Certificate.ValidPrincipals"><span class="nx">ValidPrincipals</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Certificate.ValidAfter"><span class="nx">ValidAfter</span></span> <a href="https://pkg.go.dev/builtin#uint64"><span class="kt">uint64</span></a>
<span id="Certificate.ValidBefore"><span class="nx">ValidBefore</span></span> <a href="https://pkg.go.dev/builtin#uint64"><span class="kt">uint64</span></a>
<a href="#Permissions"><span class="nx">Permissions</span></a>
<span id="Certificate.Reserved"><span class="nx">Reserved</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a>
<span id="Certificate.SignatureKey"><span class="nx">SignatureKey</span></span> <a href="#PublicKey"><span class="nx">PublicKey</span></a>
<span id="Certificate.Signature"><span class="nx">Signature</span></span> <span class="o">*</span><a href="#Signature"><span class="nx">Signature</span></a>
<span class="p">}</span></pre>
<p>An Certificate represents an OpenSSH certificate as defined in
[PROTOCOL.certkeys]?rev=1.8. The Certificate type implements the
PublicKey interface, so it can be unmarshaled using
ParsePublicKey.
<h4 id="Certificate.Marshal">func (*Certificate) Marshal</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <span class="nf">Marshal</span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>Marshal serializes c into OpenSSH&apos;s wire format. It is part of the
PublicKey interface.
<h4 id="Certificate.SignCert">func (*Certificate) SignCert</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <span class="nf">SignCert</span><span class="p">(</span><span class="nx">rand</span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a><span class="p">,</span> <span class="nx">authority</span> <a href="#Signer"><span class="nx">Signer</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>SignCert signs the certificate with an authority, setting the Nonce,
SignatureKey, and Signature fields. If the authority implements the
MultiAlgorithmSigner interface the first algorithm in the list is used. This
is useful if you want to sign with a specific algorithm.
<details id="example-Certificate.SignCert" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;crypto/rand&#34;</span>
<span class="s">&#34;crypto/rsa&#34;</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Sign a certificate with a specific algorithm.
</span><span class="c1"></span> <span class="nx">privateKey</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">rsa</span><span class="p">.</span><span class="nf">GenerateKey</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nx">Reader</span><span class="p">,</span> <span class="mi">3072</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to generate RSA key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">publicKey</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">NewPublicKey</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">privateKey</span><span class="p">.</span><span class="nx">PublicKey</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to get RSA public key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">caKey</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">rsa</span><span class="p">.</span><span class="nf">GenerateKey</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nx">Reader</span><span class="p">,</span> <span class="mi">3072</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to generate CA key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">signer</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">NewSigner</span><span class="p">(</span><span class="nx">caKey</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to generate signer from key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">mas</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">NewSignerWithAlgorithms</span><span class="p">(</span><span class="nx">signer</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">KeyAlgoRSASHA256</span><span class="p">})</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to create signer with algorithms: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">certificate</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">Certificate</span><span class="p">{</span>
<span class="nx">Key</span><span class="p">:</span> <span class="nx">publicKey</span><span class="p">,</span>
<span class="nx">CertType</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">UserCert</span><span class="p">,</span>
<span class="p">}</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">certificate</span><span class="p">.</span><span class="nf">SignCert</span><span class="p">(</span><span class="nx">rand</span><span class="p">.</span><span class="nx">Reader</span><span class="p">,</span> <span class="nx">mas</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to sign certificate: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Save the public key to a file and check that rsa-sha-256 is used for
</span><span class="c1"></span> <span class="c1">// signing:
</span><span class="c1"></span> <span class="c1">// ssh-keygen -L -f &lt;path to the file&gt;
</span><span class="c1"></span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nb">string</span><span class="p">(</span><span class="nx">ssh</span><span class="p">.</span><span class="nf">MarshalAuthorizedKey</span><span class="p">(</span><span class="o">&amp;</span><span class="nx">certificate</span><span class="p">)))</span>
<span class="p">}</span></pre>
</details>
<h4 id="Certificate.Type">func (*Certificate) Type</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <span class="nf">Type</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>Type returns the certificate algorithm name. It is part of the PublicKey interface.
<h4 id="Certificate.Verify">func (*Certificate) Verify</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">)</span> <span class="nf">Verify</span><span class="p">(</span><span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">sig</span> <span class="o">*</span><a href="#Signature"><span class="nx">Signature</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Verify verifies a signature against the certificate&apos;s public
key. It is part of the PublicKey interface.
<h3 id="Channel">type Channel</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Channel</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>A Channel is an ordered, reliable, flow-controlled, duplex stream
that is multiplexed over an SSH connection.
<h4 id="Channel.Close">func (*Channel) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Close signals end of channel use. No data may be sent after this call.
<h4 id="Channel.CloseWrite">func (*Channel) CloseWrite</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">CloseWrite</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>CloseWrite signals the end of sending in-band data. Requests may still be
sent, and the other side may still send data.
<h4 id="Channel.Handle">func (*Channel) Handle</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">Handle</span><span class="p">(</span><span class="nx">handler</span> <a href="#RequestHandler"><span class="nx">RequestHandler</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Handle must be called to handle channel&apos;s requests. Handle blocks. If
requestHandler is nil, requests will be discarded.
<h4 id="Channel.Read">func (*Channel) Read</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">Read</span><span class="p">(</span><span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Read reads up to len(data) bytes from the channel.
<h4 id="Channel.SendRequest">func (*Channel) SendRequest</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">SendRequest</span><span class="p">(</span><span class="nx">name</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">wantReply</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <span class="nx">payload</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>SendRequest sends a channel request. If wantReply is true, it will wait for a
reply and return the result as a boolean, otherwise the return value will be
false. Channel requests are out-of-band messages so they may be sent even if
the data stream is closed or blocked by flow control. If the channel is
closed before a reply is returned, io.EOF is returned.
<h4 id="Channel.SetDeadline">func (*Channel) SetDeadline</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">SetDeadline</span><span class="p">(</span><span class="nx">deadline</span> <a href="https://pkg.go.dev/time"><span class="nx">time</span></a><span class="p">.</span><a href="https://pkg.go.dev/time#Time"><span class="nx">Time</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>SetDeadline sets the read and write deadlines associated with the
channel. It is equivalent to calling both SetReadDeadline and
SetWriteDeadline. Deadlines errors are not fatal, the Channel can be used
again after resetting the deadlines.
<h4 id="Channel.SetReadDeadline">func (*Channel) SetReadDeadline</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">SetReadDeadline</span><span class="p">(</span><span class="nx">deadline</span> <a href="https://pkg.go.dev/time"><span class="nx">time</span></a><span class="p">.</span><a href="https://pkg.go.dev/time#Time"><span class="nx">Time</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>SetReadDeadline sets the deadline for future Read calls and unblock Read
calls waiting for data. A zero value for t means Read will not time out.
<h4 id="Channel.SetWriteDeadline">func (*Channel) SetWriteDeadline</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">SetWriteDeadline</span><span class="p">(</span><span class="nx">deadline</span> <a href="https://pkg.go.dev/time"><span class="nx">time</span></a><span class="p">.</span><a href="https://pkg.go.dev/time#Time"><span class="nx">Time</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>SetWriteDeadline sets the deadline for future Write calls and unblock
Write calls waiting for window capacity. A zero value for t means Write
will not time out.
<h4 id="Channel.Stderr">func (*Channel) Stderr</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">Stderr</span><span class="p">()</span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#ReadWriter"><span class="nx">ReadWriter</span></a></pre>
<p>Stderr returns an io.ReadWriter that writes to this channel with the extended
data type set to stderr. Stderr may safely be read and written from a
different goroutine than Read and Write respectively.
<h4 id="Channel.Write">func (*Channel) Write</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">)</span> <span class="nf">Write</span><span class="p">(</span><span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Write writes len(data) bytes to the channel.
<h3 id="ChannelHandler">type ChannelHandler</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ChannelHandler</span> <span class="kd">interface</span> <span class="p">{</span>
<span id="ChannelHandler.NewChannel"><span class="nf">NewChannel</span></span><span class="p">(</span><span class="nx">ch</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span>
<span class="p">}</span></pre>
<p>ChannelHandler defines the interface to handle new channel requests.
<h3 id="ChannelHandlerFunc">type ChannelHandlerFunc</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ChannelHandlerFunc</span> <span class="kd">func</span><span class="p">(</span><span class="nx">ch</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span></pre>
<p>ChannelHandlerFunc is an adapter to allow the use of ordinary function as
<a href="#ChannelHandler">ChannelHandler</a>. If f is a function with the appropriate signature,
ChannelHandlerFunc(f) is a <a href="#ChannelHandler">ChannelHandler</a> that calls f.
<h4 id="ChannelHandlerFunc.NewChannel">func (ChannelHandlerFunc) NewChannel</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">f</span> <a href="#ChannelHandlerFunc"><span class="nx">ChannelHandlerFunc</span></a><span class="p">)</span> <span class="nf">NewChannel</span><span class="p">(</span><span class="nx">ch</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span></pre>
<p>NewChannel calls f(ch).
<h3 id="Client">type Client</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Client</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>Client implements a traditional SSH client that supports shells,
subprocesses, TCP port/streamlocal forwarding and tunneled dialing.
<h4 id="Dial">func Dial</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">Dial</span><span class="p">(</span><span class="nx">ctx</span> <a href="https://pkg.go.dev/context"><span class="nx">context</span></a><span class="p">.</span><a href="https://pkg.go.dev/context#Context"><span class="nx">Context</span></a><span class="p">,</span> <span class="nx">network</span><span class="p">,</span> <span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">config</span> <span class="o">*</span><a href="#ClientConfig"><span class="nx">ClientConfig</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Dial starts a client connection to the given SSH server. It is a
convenience function that connects to the given network address,
initiates the SSH handshake, and then sets up a Client. For access
to incoming channels and requests, use net.Dial with NewClientConn
instead.
<details id="example-Dial" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;bytes&#34;</span>
<span class="s">&#34;context&#34;</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;time&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">hostKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span>
<span class="c1">// An SSH client is represented with a ClientConn.
</span><span class="c1"></span> <span class="c1">//
</span><span class="c1"></span> <span class="c1">// To authenticate with the remote server you must pass at least one
</span><span class="c1"></span> <span class="c1">// implementation of AuthMethod via the Auth field in ClientConfig,
</span><span class="c1"></span> <span class="c1">// and provide a HostKeyCallback.
</span><span class="c1"></span> <span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">ClientConfig</span><span class="p">{</span>
<span class="nx">User</span><span class="p">:</span> <span class="s">&#34;username&#34;</span><span class="p">,</span>
<span class="nx">Auth</span><span class="p">:</span> <span class="p">[]</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">AuthMethod</span><span class="p">{</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">Password</span><span class="p">(</span><span class="s">&#34;yourpassword&#34;</span><span class="p">),</span>
<span class="p">},</span>
<span class="nx">HostKey</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FixedHostKey</span><span class="p">(</span><span class="nx">hostKey</span><span class="p">),</span>
<span class="p">}</span>
<span class="c1">// Allow at most 10 seconds to complete the handshake and create the Client.
</span><span class="c1"></span> <span class="nx">ctx</span><span class="p">,</span> <span class="nx">cancel</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">WithTimeout</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="mi">10</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
<span class="k">defer</span> <span class="nf">cancel</span><span class="p">()</span>
<span class="nx">client</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">Dial</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;yourserver.com:22&#34;</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to dial: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">client</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Each ClientConn can support multiple interactive sessions,
</span><span class="c1"></span> <span class="c1">// represented by a Session.
</span><span class="c1"></span> <span class="nx">session</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">client</span><span class="p">.</span><span class="nf">NewSession</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to create session: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">session</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Once a Session is created, you can execute a single command on
</span><span class="c1"></span> <span class="c1">// the remote side using the Run method.
</span><span class="c1"></span> <span class="kd">var</span> <span class="nx">b</span> <span class="nx">bytes</span><span class="p">.</span><span class="nx">Buffer</span>
<span class="nx">session</span><span class="p">.</span><span class="nx">Stdout</span> <span class="p">=</span> <span class="o">&amp;</span><span class="nx">b</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">session</span><span class="p">.</span><span class="nf">Run</span><span class="p">(</span><span class="s">&#34;/usr/bin/whoami&#34;</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to run: &#34;</span> <span class="o">+</span> <span class="nx">err</span><span class="p">.</span><span class="nf">Error</span><span class="p">())</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">b</span><span class="p">.</span><span class="nf">String</span><span class="p">())</span>
<span class="p">}</span></pre>
</details>
<h4 id="NewClient">func NewClient</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewClient</span><span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#ClientConn"><span class="nx">ClientConn</span></a><span class="p">)</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a></pre>
<p>NewClient creates a Client on top of the given connection.
<h4 id="Client.Close">func (Client) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">Client</span><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<h4 id="Client.Dial">func (*Client) Dial</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">Dial</span><span class="p">(</span><span class="nx">ctx</span> <a href="https://pkg.go.dev/context"><span class="nx">context</span></a><span class="p">.</span><a href="https://pkg.go.dev/context#Context"><span class="nx">Context</span></a><span class="p">,</span> <span class="nx">n</span><span class="p">,</span> <span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Dial initiates a connection to the addr from the remote host.
The resulting connection has a zero LocalAddr() and RemoteAddr().
<h4 id="Client.DialTCP">func (*Client) DialTCP</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">DialTCP</span><span class="p">(</span><span class="nx">ctx</span> <a href="https://pkg.go.dev/context"><span class="nx">context</span></a><span class="p">.</span><a href="https://pkg.go.dev/context#Context"><span class="nx">Context</span></a><span class="p">,</span> <span class="nx">n</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">laddr</span><span class="p">,</span> <span class="nx">raddr</span> <span class="o">*</span><a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#TCPAddr"><span class="nx">TCPAddr</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>DialTCP connects to the remote address raddr on the network net,
which must be &quot;tcp&quot;, &quot;tcp4&quot;, or &quot;tcp6&quot;. If laddr is not nil, it is used
as the local address for the connection.
<h4 id="Client.HandleChannelOpen">func (*Client) HandleChannelOpen</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">HandleChannelOpen</span><span class="p">(</span><span class="nx">channelType</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">handler</span> <a href="#ChannelHandler"><span class="nx">ChannelHandler</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>HandleChannelOpen allows to define a <a href="#ChannelHandler">ChannelHandler</a> for the specified
channel type. An error is returned if an handler for the specified type is
already registered.
<h4 id="Client.Listen">func (*Client) Listen</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">Listen</span><span class="p">(</span><span class="nx">n</span><span class="p">,</span> <span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Listener"><span class="nx">Listener</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Listen requests the remote peer open a listening socket on
addr. Incoming connections will be available by calling Accept on
the returned net.Listener. The listener must be serviced, or the
SSH connection may hang.
N must be &quot;tcp&quot;, &quot;tcp4&quot;, &quot;tcp6&quot;, or &quot;unix&quot;.
<details id="example-Client.Listen" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;context&#34;</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;net/http&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">hostKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span>
<span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">ClientConfig</span><span class="p">{</span>
<span class="nx">User</span><span class="p">:</span> <span class="s">&#34;username&#34;</span><span class="p">,</span>
<span class="nx">Auth</span><span class="p">:</span> <span class="p">[]</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">AuthMethod</span><span class="p">{</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">Password</span><span class="p">(</span><span class="s">&#34;password&#34;</span><span class="p">),</span>
<span class="p">},</span>
<span class="nx">HostKey</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FixedHostKey</span><span class="p">(</span><span class="nx">hostKey</span><span class="p">),</span>
<span class="p">}</span>
<span class="c1">// Dial your ssh server.
</span><span class="c1"></span> <span class="nx">conn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">Dial</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;localhost:22&#34;</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to connect: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">conn</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Request the remote side to open port 8080 on all interfaces.
</span><span class="c1"></span> <span class="nx">l</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">conn</span><span class="p">.</span><span class="nf">Listen</span><span class="p">(</span><span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;0.0.0.0:8080&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to register tcp forward: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">l</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Serve HTTP with your SSH server acting as a reverse proxy.
</span><span class="c1"></span> <span class="nx">http</span><span class="p">.</span><span class="nf">Serve</span><span class="p">(</span><span class="nx">l</span><span class="p">,</span> <span class="nx">http</span><span class="p">.</span><span class="nf">HandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">resp</span> <span class="nx">http</span><span class="p">.</span><span class="nx">ResponseWriter</span><span class="p">,</span> <span class="nx">req</span> <span class="o">*</span><span class="nx">http</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">Fprintf</span><span class="p">(</span><span class="nx">resp</span><span class="p">,</span> <span class="s">&#34;Hello world!\n&#34;</span><span class="p">)</span>
<span class="p">}))</span>
<span class="p">}</span></pre>
</details>
<h4 id="Client.ListenUnix">func (*Client) ListenUnix</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">ListenUnix</span><span class="p">(</span><span class="nx">socketPath</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Listener"><span class="nx">Listener</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ListenUnix is similar to ListenTCP but uses a Unix domain socket.
<h4 id="Client.NewSession">func (*Client) NewSession</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Client"><span class="nx">Client</span></a><span class="p">)</span> <span class="nf">NewSession</span><span class="p">()</span> <span class="p">(</span><span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewSession opens a new Session for this client. (A session is a remote
execution of a program.)
<h3 id="ClientConfig">type ClientConfig</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ClientConfig</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Config contains configuration that is shared between clients and
</span><span class="c1"></span> <span class="c1">// servers.
</span><span class="c1"></span> <a href="#Config"><span class="nx">Config</span></a>
<span class="c1">// User contains the username to authenticate as.
</span><span class="c1"></span> <span id="ClientConfig.User"><span class="nx">User</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// Auth contains possible authentication methods to use with the
</span><span class="c1"></span> <span class="c1">// server. Only the first instance of a particular RFC 4252 method will
</span><span class="c1"></span> <span class="c1">// be used during authentication.
</span><span class="c1"></span> <span id="ClientConfig.Auth"><span class="nx">Auth</span></span> <span class="p">[]</span><a href="#AuthMethod"><span class="nx">AuthMethod</span></a>
<span class="c1">// HostKey is called during the cryptographic
</span><span class="c1"></span> <span class="c1">// handshake to validate the server&#39;s host key. The client
</span><span class="c1"></span> <span class="c1">// configuration must supply this callback for the connection
</span><span class="c1"></span> <span class="c1">// to succeed. The functions InsecureIgnoreHostKey or
</span><span class="c1"></span> <span class="c1">// FixedHostKey can be used for simplistic host key checks.
</span><span class="c1"></span> <span id="ClientConfig.HostKey"><span class="nx">HostKey</span></span> <a href="#HostKeyCallback"><span class="nx">HostKeyCallback</span></a>
<span class="c1">// Banner is called during the SSH dance to display a custom
</span><span class="c1"></span> <span class="c1">// server&#39;s message. The client configuration can supply this callback to
</span><span class="c1"></span> <span class="c1">// handle it as wished. The function BannerDisplayStderr can be used for
</span><span class="c1"></span> <span class="c1">// simplistic display on Stderr.
</span><span class="c1"></span> <span id="ClientConfig.Banner"><span class="nx">Banner</span></span> <a href="#BannerCallback"><span class="nx">BannerCallback</span></a>
<span class="c1">// ClientVersion contains the version identification string that will
</span><span class="c1"></span> <span class="c1">// be used for the connection. If empty, a reasonable default is used.
</span><span class="c1"></span> <span id="ClientConfig.ClientVersion"><span class="nx">ClientVersion</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// HostKeyAlgorithms lists the public key algorithms that the client will
</span><span class="c1"></span> <span class="c1">// accept from the server for host key authentication, in order of
</span><span class="c1"></span> <span class="c1">// preference. If empty, a reasonable default is used. Any
</span><span class="c1"></span> <span class="c1">// string returned from a PublicKey.Type method may be used, or
</span><span class="c1"></span> <span class="c1">// any of the CertAlgo and KeyAlgo constants.
</span><span class="c1"></span> <span id="ClientConfig.HostKeyAlgorithms"><span class="nx">HostKeyAlgorithms</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>A ClientConfig structure is used to configure a Client. It must not be
modified after having been passed to an SSH function.
<h3 id="ClientConn">type ClientConn</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ClientConn</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>ClientConn is an authenticated SSH connection, as seen from the
client
<h4 id="NewClientConn">func NewClientConn</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewClientConn</span><span class="p">(</span><span class="nx">c</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">,</span> <span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">config</span> <span class="o">*</span><a href="#ClientConfig"><span class="nx">ClientConfig</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#ClientConn"><span class="nx">ClientConn</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewClientConn establishes an authenticated SSH connection using c as the
underlying transport. You can use <a href="#NewClient">NewClient</a> to build an SSH client or
handle this client connection yourself by using <a href="#ClientConn.Handle">ClientConn.Handle</a>.
<h4 id="ClientConn.Close">func (ClientConn) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ClientConn</span><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<h4 id="ClientConn.Handle">func (*ClientConn) Handle</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#ClientConn"><span class="nx">ClientConn</span></a><span class="p">)</span> <span class="nf">Handle</span><span class="p">(</span><span class="nx">channelHandler</span> <a href="#ChannelHandler"><span class="nx">ChannelHandler</span></a><span class="p">,</span> <span class="nx">requestHandler</span> <a href="#RequestHandler"><span class="nx">RequestHandler</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Handle must be called to handle requests and channels if you want to handle a
<a href="#ClientConn">ClientConn</a> yourself without building a <a href="#Client">Client</a> using <a href="#NewClient">NewClient</a>. Handle
blocks. If channelHandler is nil channels will be rejected. If requestHandler
is nil, requests will be discarded.
<h3 id="ClientHandler">type ClientHandler</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ClientHandler</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// HandleClient is called after the handshake completes and a client
</span><span class="c1"></span> <span class="c1">// authenticates with the server.
</span><span class="c1"></span> <span id="ClientHandler.HandleClient"><span class="nf">HandleClient</span></span><span class="p">(</span><span class="nx">conn</span> <span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">)</span>
<span class="p">}</span></pre>
<p>ClientHandler defines the interface to handle authenticated server
connections.
<h3 id="ClientHandlerFunc">type ClientHandlerFunc</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ClientHandlerFunc</span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">)</span></pre>
<p>ClientHandlerFunc is an adapter to allow the use of ordinary function as
<a href="#ClientHandler">ClientHandler</a>. If f is a function with the appropriate signature,
ClientHandlerFunc(f) is a <a href="#ClientHandler">ClientHandler</a> that calls f.
<h4 id="ClientHandlerFunc.HandleClient">func (ClientHandlerFunc) HandleClient</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">f</span> <a href="#ClientHandlerFunc"><span class="nx">ClientHandlerFunc</span></a><span class="p">)</span> <span class="nf">HandleClient</span><span class="p">(</span><span class="nx">conn</span> <span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">)</span></pre>
<p>HandleClient calls f(conn).
<h3 id="Config">type Config</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Config</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Rand provides the source of entropy for cryptographic
</span><span class="c1"></span> <span class="c1">// primitives. If Rand is nil, the cryptographic random reader
</span><span class="c1"></span> <span class="c1">// in package crypto/rand will be used.
</span><span class="c1"></span> <span id="Config.Rand"><span class="nx">Rand</span></span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a>
<span class="c1">// The maximum number of bytes sent or received after which a
</span><span class="c1"></span> <span class="c1">// new key is negotiated. It must be at least 256. If
</span><span class="c1"></span> <span class="c1">// unspecified, a size suitable for the chosen cipher is used.
</span><span class="c1"></span> <span id="Config.RekeyThreshold"><span class="nx">RekeyThreshold</span></span> <a href="https://pkg.go.dev/builtin#uint64"><span class="kt">uint64</span></a>
<span class="c1">// The allowed key exchanges algorithms. If unspecified then a default set
</span><span class="c1"></span> <span class="c1">// of algorithms is used. Unsupported values are silently ignored.
</span><span class="c1"></span> <span id="Config.KeyExchanges"><span class="nx">KeyExchanges</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// The allowed cipher algorithms. If unspecified then a sensible default is
</span><span class="c1"></span> <span class="c1">// used. Unsupported values are silently ignored.
</span><span class="c1"></span> <span id="Config.Ciphers"><span class="nx">Ciphers</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// The allowed MAC algorithms. If unspecified then a sensible default is
</span><span class="c1"></span> <span class="c1">// used. Unsupported values are silently ignored.
</span><span class="c1"></span> <span id="Config.MACs"><span class="nx">MACs</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>Config contains configuration data common to both Server and
ClientConfig.
<h4 id="Config.SetDefaults">func (*Config) SetDefaults</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#Config"><span class="nx">Config</span></a><span class="p">)</span> <span class="nf">SetDefaults</span><span class="p">()</span></pre>
<p>SetDefaults sets sensible values for unset fields in config. This is
exported for testing: Configs passed to SSH functions are copied and have
default values set automatically.
<h3 id="ConnMetadata">type ConnMetadata</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ConnMetadata</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>ConnMetadata holds metadata for the connection.
<h4 id="ConnMetadata.ClientVersion">func (ConnMetadata) ClientVersion</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">ClientVersion</span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>ClientVersion returns the client&apos;s version string as hashed into the session
ID.
<h4 id="ConnMetadata.LocalAddr">func (ConnMetadata) LocalAddr</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">LocalAddr</span><span class="p">()</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Addr"><span class="nx">Addr</span></a></pre>
<p>LocalAddr returns the local address for this connection.
<h4 id="ConnMetadata.RemoteAddr">func (ConnMetadata) RemoteAddr</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">RemoteAddr</span><span class="p">()</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Addr"><span class="nx">Addr</span></a></pre>
<p>RemoteAddr returns the remote address for this connection.
<h4 id="ConnMetadata.ServerVersion">func (ConnMetadata) ServerVersion</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">ServerVersion</span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>ServerVersion returns the server&apos;s version string as hashed into the session
ID.
<h4 id="ConnMetadata.SessionID">func (ConnMetadata) SessionID</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">SessionID</span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>SessionID returns the session hash, also denoted by H.
<h4 id="ConnMetadata.User">func (ConnMetadata) User</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="nx">ConnMetadata</span><span class="p">)</span> <span class="nf">User</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>User returns the user ID for this connection.
<h3 id="CryptoPublicKey">type CryptoPublicKey</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">CryptoPublicKey</span> <span class="kd">interface</span> <span class="p">{</span>
<span id="CryptoPublicKey.CryptoPublicKey"><span class="nf">CryptoPublicKey</span></span><span class="p">()</span> <a href="https://pkg.go.dev/crypto"><span class="nx">crypto</span></a><span class="p">.</span><a href="https://pkg.go.dev/crypto#PublicKey"><span class="nx">PublicKey</span></a>
<span class="p">}</span></pre>
<p>CryptoPublicKey, if implemented by a PublicKey,
returns the underlying crypto.PublicKey form of the key.
<h3 id="ExitError">type ExitError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ExitError</span> <span class="kd">struct</span> <span class="p">{</span>
<a href="#Waitmsg"><span class="nx">Waitmsg</span></a>
<span class="p">}</span></pre>
<p>An ExitError reports unsuccessful completion of a remote command.
<h4 id="ExitError.Error">func (*ExitError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><a href="#ExitError"><span class="nx">ExitError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="ExitMissingError">type ExitMissingError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ExitMissingError</span> <span class="kd">struct</span><span class="p">{}</span></pre>
<p>ExitMissingError is returned if a session is torn down cleanly, but
the server sends no confirmation of the exit status.
<h4 id="ExitMissingError.Error">func (*ExitMissingError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><a href="#ExitMissingError"><span class="nx">ExitMissingError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="GSSAPIClient">type GSSAPIClient</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">GSSAPIClient</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// InitSecContext initiates the establishment of a security context for GSS-API between the
</span><span class="c1"></span> <span class="c1">// ssh client and ssh server. Initially the token parameter should be specified as nil.
</span><span class="c1"></span> <span class="c1">// The routine may return a outputToken which should be transferred to
</span><span class="c1"></span> <span class="c1">// the ssh server, where the ssh server will present it to
</span><span class="c1"></span> <span class="c1">// AcceptSecContext. If no token need be sent, InitSecContext will indicate this by setting
</span><span class="c1"></span> <span class="c1">// needContinue to false. To complete the context
</span><span class="c1"></span> <span class="c1">// establishment, one or more reply tokens may be required from the ssh
</span><span class="c1"></span> <span class="c1">// server;if so, InitSecContext will return a needContinue which is true.
</span><span class="c1"></span> <span class="c1">// In this case, InitSecContext should be called again when the
</span><span class="c1"></span> <span class="c1">// reply token is received from the ssh server, passing the reply
</span><span class="c1"></span> <span class="c1">// token to InitSecContext via the token parameters.
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.2.1 and RFC 4462 section 3.4.
</span><span class="c1"></span> <span id="GSSAPIClient.InitSecContext"><span class="nf">InitSecContext</span></span><span class="p">(</span><span class="nx">target</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">token</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">isGSSDelegCreds</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">outputToken</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">needContinue</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// GetMIC generates a cryptographic MIC for the SSH2 message, and places
</span><span class="c1"></span> <span class="c1">// the MIC in a token for transfer to the ssh server.
</span><span class="c1"></span> <span class="c1">// The contents of the MIC field are obtained by calling GSS_GetMIC()
</span><span class="c1"></span> <span class="c1">// over the following, using the GSS-API context that was just
</span><span class="c1"></span> <span class="c1">// established:
</span><span class="c1"></span> <span class="c1">// string session identifier
</span><span class="c1"></span> <span class="c1">// byte SSH_MSG_USERAUTH_REQUEST
</span><span class="c1"></span> <span class="c1">// string user name
</span><span class="c1"></span> <span class="c1">// string service
</span><span class="c1"></span> <span class="c1">// string &#34;gssapi-with-mic&#34;
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.3.1 and RFC 4462 3.5.
</span><span class="c1"></span> <span id="GSSAPIClient.GetMIC"><span class="nf">GetMIC</span></span><span class="p">(</span><span class="nx">micFiled</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">([]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// Whenever possible, it should be possible for
</span><span class="c1"></span> <span class="c1">// DeleteSecContext() calls to be successfully processed even
</span><span class="c1"></span> <span class="c1">// if other calls cannot succeed, thereby enabling context-related
</span><span class="c1"></span> <span class="c1">// resources to be released.
</span><span class="c1"></span> <span class="c1">// In addition to deleting established security contexts,
</span><span class="c1"></span> <span class="c1">// gss_delete_sec_context must also be able to delete &#34;half-built&#34;
</span><span class="c1"></span> <span class="c1">// security contexts resulting from an incomplete sequence of
</span><span class="c1"></span> <span class="c1">// InitSecContext()/AcceptSecContext() calls.
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.2.3.
</span><span class="c1"></span> <span id="GSSAPIClient.DeleteSecContext"><span class="nf">DeleteSecContext</span></span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="p">}</span></pre>
<p>GSSAPIClient provides the API to plug-in GSSAPI authentication for client logins.
<h3 id="GSSAPIServer">type GSSAPIServer</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">GSSAPIServer</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// AcceptSecContext allows a remotely initiated security context between the application
</span><span class="c1"></span> <span class="c1">// and a remote peer to be established by the ssh client. The routine may return a
</span><span class="c1"></span> <span class="c1">// outputToken which should be transferred to the ssh client,
</span><span class="c1"></span> <span class="c1">// where the ssh client will present it to InitSecContext.
</span><span class="c1"></span> <span class="c1">// If no token need be sent, AcceptSecContext will indicate this
</span><span class="c1"></span> <span class="c1">// by setting the needContinue to false. To
</span><span class="c1"></span> <span class="c1">// complete the context establishment, one or more reply tokens may be
</span><span class="c1"></span> <span class="c1">// required from the ssh client. if so, AcceptSecContext
</span><span class="c1"></span> <span class="c1">// will return a needContinue which is true, in which case it
</span><span class="c1"></span> <span class="c1">// should be called again when the reply token is received from the ssh
</span><span class="c1"></span> <span class="c1">// client, passing the token to AcceptSecContext via the
</span><span class="c1"></span> <span class="c1">// token parameters.
</span><span class="c1"></span> <span class="c1">// The srcName return value is the authenticated username.
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.2.2 and RFC 4462 section 3.4.
</span><span class="c1"></span> <span id="GSSAPIServer.AcceptSecContext"><span class="nf">AcceptSecContext</span></span><span class="p">(</span><span class="nx">token</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">outputToken</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">srcName</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">needContinue</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// VerifyMIC verifies that a cryptographic MIC, contained in the token parameter,
</span><span class="c1"></span> <span class="c1">// fits the supplied message is received from the ssh client.
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.3.2.
</span><span class="c1"></span> <span id="GSSAPIServer.VerifyMIC"><span class="nf">VerifyMIC</span></span><span class="p">(</span><span class="nx">micField</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">micToken</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="c1">// Whenever possible, it should be possible for
</span><span class="c1"></span> <span class="c1">// DeleteSecContext() calls to be successfully processed even
</span><span class="c1"></span> <span class="c1">// if other calls cannot succeed, thereby enabling context-related
</span><span class="c1"></span> <span class="c1">// resources to be released.
</span><span class="c1"></span> <span class="c1">// In addition to deleting established security contexts,
</span><span class="c1"></span> <span class="c1">// gss_delete_sec_context must also be able to delete &#34;half-built&#34;
</span><span class="c1"></span> <span class="c1">// security contexts resulting from an incomplete sequence of
</span><span class="c1"></span> <span class="c1">// InitSecContext()/AcceptSecContext() calls.
</span><span class="c1"></span> <span class="c1">// See RFC 2743 section 2.2.3.
</span><span class="c1"></span> <span id="GSSAPIServer.DeleteSecContext"><span class="nf">DeleteSecContext</span></span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="p">}</span></pre>
<p>GSSAPIServer provides the API to plug in GSSAPI authentication for server logins.
<h3 id="GSSAPIWithMICConfig">type GSSAPIWithMICConfig</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">GSSAPIWithMICConfig</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// AllowLogin, must be set, is called when gssapi-with-mic
</span><span class="c1"></span> <span class="c1">// authentication is selected (RFC 4462 section 3). The srcName is from the
</span><span class="c1"></span> <span class="c1">// results of the GSS-API authentication. The format is username@DOMAIN.
</span><span class="c1"></span> <span class="c1">// GSSAPI just guarantees to the server who the user is, but not if they can log in, and with what permissions.
</span><span class="c1"></span> <span class="c1">// This callback is called after the user identity is established with GSSAPI to decide if the user can login with
</span><span class="c1"></span> <span class="c1">// which permissions. If the user is allowed to login, it should return a nil error.
</span><span class="c1"></span> <span id="GSSAPIWithMICConfig.AllowLogin"><span class="nx">AllowLogin</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">srcName</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// Server must be set. It&#39;s the implementation
</span><span class="c1"></span> <span class="c1">// of the GSSAPIServer interface. See GSSAPIServer interface for details.
</span><span class="c1"></span> <span id="GSSAPIWithMICConfig.Server"><span class="nx">Server</span></span> <a href="#GSSAPIServer"><span class="nx">GSSAPIServer</span></a>
<span class="p">}</span></pre>
<h3 id="HostKeyCallback">type HostKeyCallback</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">HostKeyCallback</span> <span class="kd">func</span><span class="p">(</span><span class="nx">hostname</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">remote</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Addr"><span class="nx">Addr</span></a><span class="p">,</span> <span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>HostKeyCallback is the function type used for verifying server
keys. A HostKeyCallback must return nil if the host key is OK, or
an error to reject it. It receives the hostname as passed to Dial
or NewClientConn. The remote address is the RemoteAddr of the
net.Conn underlying the SSH connection.
<h4 id="FixedHostKey">func FixedHostKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">FixedHostKey</span><span class="p">(</span><span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <a href="#HostKeyCallback"><span class="nx">HostKeyCallback</span></a></pre>
<p>FixedHostKey returns a function for use in
ClientConfig.HostKeyCallback to accept only a specific host key.
<h4 id="InsecureIgnoreHostKey">func InsecureIgnoreHostKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">InsecureIgnoreHostKey</span><span class="p">()</span> <a href="#HostKeyCallback"><span class="nx">HostKeyCallback</span></a></pre>
<p>InsecureIgnoreHostKey returns a function that can be used for
ClientConfig.HostKeyCallback to accept any host key. It should
not be used for production code.
<h3 id="KeyboardInteractiveChallenge">type KeyboardInteractiveChallenge</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">KeyboardInteractiveChallenge</span> <span class="kd">func</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">instruction</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">questions</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">echos</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">answers</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>KeyboardInteractiveChallenge should print questions, optionally
disabling echoing (e.g. for passwords), and return all the answers.
Challenge may be called multiple times in a single session. After
successful authentication, the server may send a challenge with no
questions, for which the name and instruction messages should be
printed. RFC 4256 section 3.3 details how the UI should behave for
both CLI and GUI environments.
<h3 id="MarshalPrivateKeyOptions">type MarshalPrivateKeyOptions</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">MarshalPrivateKeyOptions</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="MarshalPrivateKeyOptions.Comment"><span class="nx">Comment</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="MarshalPrivateKeyOptions.Passphrase"><span class="nx">Passphrase</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="MarshalPrivateKeyOptions.SaltRounds"><span class="nx">SaltRounds</span></span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a>
<span class="p">}</span></pre>
<p>MarshalPrivateKeyOptions defines the available options to Marshal a private
key in OpenSSH format.
<h3 id="NewChannel">type NewChannel</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">NewChannel</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>NewChannel represents an incoming request to a channel. It must either be
accepted for use by calling Accept, or rejected by calling Reject.
<h4 id="NewChannel.Accept">func (*NewChannel) Accept</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span> <span class="nf">Accept</span><span class="p">()</span> <span class="p">(</span><span class="o">*</span><a href="#Channel"><span class="nx">Channel</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Accept accepts the channel creation request. The returned channel must be
serviced using <a href="#Channel.Handle">Channel.Handle</a>.
<h4 id="NewChannel.ChannelType">func (*NewChannel) ChannelType</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span> <span class="nf">ChannelType</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>ChannelType returns the type of the channel, as supplied by the
client.
<h4 id="NewChannel.ExtraData">func (*NewChannel) ExtraData</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span> <span class="nf">ExtraData</span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a></pre>
<p>ExtraData returns the arbitrary payload for this channel, as supplied
by the client. This data is specific to the channel type.
<h4 id="NewChannel.Reject">func (*NewChannel) Reject</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#NewChannel"><span class="nx">NewChannel</span></a><span class="p">)</span> <span class="nf">Reject</span><span class="p">(</span><span class="nx">reason</span> <a href="#RejectionReason"><span class="nx">RejectionReason</span></a><span class="p">,</span> <span class="nx">message</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Reject rejects the channel creation request. After calling
this, no other methods on the Channel may be called.
<h3 id="OpenChannelError">type OpenChannelError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">OpenChannelError</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="OpenChannelError.Reason"><span class="nx">Reason</span></span> <a href="#RejectionReason"><span class="nx">RejectionReason</span></a>
<span id="OpenChannelError.Message"><span class="nx">Message</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>OpenChannelError is returned if the other side rejects an
OpenChannel request.
<h4 id="OpenChannelError.Error">func (*OpenChannelError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">e</span> <span class="o">*</span><a href="#OpenChannelError"><span class="nx">OpenChannelError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="PartialSuccessError">type PartialSuccessError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">PartialSuccessError</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Next defines the authentication callbacks to apply to further steps. The
</span><span class="c1"></span> <span class="c1">// available methods communicated to the client are based on the non-nil
</span><span class="c1"></span> <span class="c1">// ServerAuthCallbacks fields.
</span><span class="c1"></span> <span id="PartialSuccessError.Next"><span class="nx">Next</span></span> <a href="#ServerAuthCallbacks"><span class="nx">ServerAuthCallbacks</span></a>
<span class="p">}</span></pre>
<p>PartialSuccessError can be returned by any of the <a href="#Server">Server</a>
authentication callbacks to indicate to the client that authentication has
partially succeeded, but further steps are required.
<h4 id="PartialSuccessError.Error">func (*PartialSuccessError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">p</span> <span class="o">*</span><a href="#PartialSuccessError"><span class="nx">PartialSuccessError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="PassphraseMissingError">type PassphraseMissingError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">PassphraseMissingError</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// PublicKey will be set if the private key format includes an unencrypted
</span><span class="c1"></span> <span class="c1">// public key along with the encrypted private key.
</span><span class="c1"></span> <span id="PassphraseMissingError.PublicKey"><span class="nx">PublicKey</span></span> <a href="#PublicKey"><span class="nx">PublicKey</span></a>
<span class="p">}</span></pre>
<p>A PassphraseMissingError indicates that parsing this private key requires a
passphrase. Use ParsePrivateKeyWithPassphrase.
<h4 id="PassphraseMissingError.Error">func (*PassphraseMissingError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="o">*</span><a href="#PassphraseMissingError"><span class="nx">PassphraseMissingError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="Permissions">type Permissions</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Permissions</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// CriticalOptions indicate restrictions to the default
</span><span class="c1"></span> <span class="c1">// permissions, and are typically used in conjunction with
</span><span class="c1"></span> <span class="c1">// user certificates. The standard for SSH certificates
</span><span class="c1"></span> <span class="c1">// defines &#34;force-command&#34; (only allow the given command to
</span><span class="c1"></span> <span class="c1">// execute) and &#34;source-address&#34; (only allow connections from
</span><span class="c1"></span> <span class="c1">// the given address). The SSH package currently only enforces
</span><span class="c1"></span> <span class="c1">// the &#34;source-address&#34; critical option. It is up to server
</span><span class="c1"></span> <span class="c1">// implementations to enforce other critical options, such as
</span><span class="c1"></span> <span class="c1">// &#34;force-command&#34;, by checking them after the SSH handshake
</span><span class="c1"></span> <span class="c1">// is successful. In general, SSH servers should reject
</span><span class="c1"></span> <span class="c1">// connections that specify critical options that are unknown
</span><span class="c1"></span> <span class="c1">// or not supported.
</span><span class="c1"></span> <span id="Permissions.CriticalOptions"><span class="nx">CriticalOptions</span></span> <span class="kd">map</span><span class="p">[</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// Extensions are extra functionality that the server may
</span><span class="c1"></span> <span class="c1">// offer on authenticated connections. Lack of support for an
</span><span class="c1"></span> <span class="c1">// extension does not preclude authenticating a user. Common
</span><span class="c1"></span> <span class="c1">// extensions are &#34;permit-agent-forwarding&#34;,
</span><span class="c1"></span> <span class="c1">// &#34;permit-X11-forwarding&#34;. The Go SSH library currently does
</span><span class="c1"></span> <span class="c1">// not act on any extension, and it is up to server
</span><span class="c1"></span> <span class="c1">// implementations to honor them. Extensions can be used to
</span><span class="c1"></span> <span class="c1">// pass data from the authentication callbacks to the server
</span><span class="c1"></span> <span class="c1">// application layer.
</span><span class="c1"></span> <span id="Permissions.Extensions"><span class="nx">Extensions</span></span> <span class="kd">map</span><span class="p">[</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>The Permissions type holds fine-grained permissions that are
specific to a user or a specific authentication method for a user.
The Permissions value for a successful authentication attempt is
available in ServerConn, so it can be used to pass information from
the user-authentication phase to the application layer.
<h3 id="PrivateKeySigner">type PrivateKeySigner</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">PrivateKeySigner</span> <span class="kd">struct</span> <span class="p">{</span>
<a href="#Signer"><span class="nx">Signer</span></a>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>PrivateKeySigner is a <a href="#Signer">ssh.Signer</a> that can also return the associated
<a href="https://pkg.go.dev/crypto#Signer">crypto.Signer</a>.
<h4 id="ParsePrivateKey">func ParsePrivateKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">ParsePrivateKey</span><span class="p">(</span><span class="nx">pemBytes</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#PrivateKeySigner"><span class="nx">PrivateKeySigner</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ParsePrivateKey returns a <a href="#PrivateKeySigner">ssh.PrivateKeySigner</a> from a PEM encoded private
key. It supports RSA, ECDSA, and Ed25519 private keys in PKCS#1, PKCS#8,
OpenSSL, and OpenSSH formats. If the private key is encrypted, it will return
a PassphraseMissingError.
<h4 id="ParsePrivateKeyWithPassphrase">func ParsePrivateKeyWithPassphrase</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">ParsePrivateKeyWithPassphrase</span><span class="p">(</span><span class="nx">pemBytes</span><span class="p">,</span> <span class="nx">passphrase</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#PrivateKeySigner"><span class="nx">PrivateKeySigner</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ParsePrivateKeyWithPassphrase returns a <a href="#PrivateKeySigner">ssh.PrivateKeySigner</a> from a PEM
encoded private key and passphrase. It supports the same keys as
<a href="#ParsePrivateKey">ssh.ParsePrivateKey</a>.
<h4 id="PrivateKeySigner.CryptoSigner">func (*PrivateKeySigner) CryptoSigner</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">k</span> <span class="o">*</span><a href="#PrivateKeySigner"><span class="nx">PrivateKeySigner</span></a><span class="p">)</span> <span class="nf">CryptoSigner</span><span class="p">()</span> <a href="https://pkg.go.dev/crypto"><span class="nx">crypto</span></a><span class="p">.</span><a href="https://pkg.go.dev/crypto#Signer"><span class="nx">Signer</span></a></pre>
<p>CryptoSigner returns the private key associated with the Signer. It returns a
*rsa.PrivateKey, an *ecdsa.PrivateKey or an ed25519.PrivateKey (not a pointer).
Note: in v1 ed25519.PrivateKey was returned as a pointer.
<h3 id="PublicKey">type PublicKey</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">PublicKey</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// Type returns the key format name, e.g. &#34;ssh-rsa&#34;.
</span><span class="c1"></span> <span id="PublicKey.Type"><span class="nf">Type</span></span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// Marshal returns the serialized key data in SSH wire format, with the name
</span><span class="c1"></span> <span class="c1">// prefix. To unmarshal the returned data, use the ParsePublicKey function.
</span><span class="c1"></span> <span id="PublicKey.Marshal"><span class="nf">Marshal</span></span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a>
<span class="c1">// Verify that sig is a signature on the given data using this key. This
</span><span class="c1"></span> <span class="c1">// method will hash the data appropriately first. sig.Format is allowed to
</span><span class="c1"></span> <span class="c1">// be any signature algorithm compatible with the key type, the caller
</span><span class="c1"></span> <span class="c1">// should check if it has more stringent requirements.
</span><span class="c1"></span> <span id="PublicKey.Verify"><span class="nf">Verify</span></span><span class="p">(</span><span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">sig</span> <span class="o">*</span><a href="#Signature"><span class="nx">Signature</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="p">}</span></pre>
<p>PublicKey represents a public key using an unspecified algorithm.
<p>Some PublicKeys provided by this package also implement CryptoPublicKey.
<h4 id="NewPublicKey">func NewPublicKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewPublicKey</span><span class="p">(</span><span class="nx">key</span> <a href="https://pkg.go.dev/crypto"><span class="nx">crypto</span></a><span class="p">.</span><a href="https://pkg.go.dev/crypto#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">(</span><a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewPublicKey takes an *rsa.PublicKey, *ecdsa.PublicKey, or ed25519.PublicKey
returns a corresponding PublicKey instance. ECDSA keys must use P-256, P-384
or P-521.
<h4 id="ParseAuthorizedKey">func ParseAuthorizedKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">ParseAuthorizedKey</span><span class="p">(</span><span class="nx">in</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">out</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">,</span> <span class="nx">comment</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">options</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">rest</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ParseAuthorizedKey parses a public key from an authorized_keys
file used in OpenSSH according to the sshd(8) manual page.
<h4 id="ParseKnownHosts">func ParseKnownHosts</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">ParseKnownHosts</span><span class="p">(</span><span class="nx">in</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">marker</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">hosts</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">pubKey</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">,</span> <span class="nx">comment</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">rest</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ParseKnownHosts parses an entry in the format of the known_hosts file.
<p>The known_hosts format is documented in the sshd(8) manual page. This
function will parse a single entry from in. On successful return, marker
will contain the optional marker value (i.e. &quot;cert-authority&quot; or &quot;revoked&quot;)
or else be empty, hosts will contain the hosts that this entry matches,
pubKey will contain the public key and comment will contain any trailing
comment at the end of the line. See the sshd(8) manual page for the various
forms that a host string can take.
<p>The unparsed remainder of the input will be returned in rest. This function
can be called repeatedly to parse multiple entries.
<p>If no entries were found in the input then err will be io.EOF. Otherwise a
non-nil err value indicates a parse error.
<h4 id="ParsePublicKey">func ParsePublicKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">ParsePublicKey</span><span class="p">(</span><span class="nx">in</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="nx">out</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>ParsePublicKey parses an SSH public key formatted for use in
the SSH wire protocol according to RFC 4253, section 6.6.
<h3 id="RejectionReason">type RejectionReason</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">RejectionReason</span> <a href="https://pkg.go.dev/builtin#uint32"><span class="kt">uint32</span></a></pre>
<p>RejectionReason is an enumeration used when rejecting channel creation
requests. See RFC 4254, section 5.1.
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="Prohibited"><span class="nx">Prohibited</span></span> <a href="#RejectionReason"><span class="nx">RejectionReason</span></a> <span class="p">=</span> <a href="https://pkg.go.dev/builtin#iota"><span class="kc">iota</span></a> <span class="o">+</span> <span class="mi">1</span>
<span id="ConnectionFailed"><span class="nx">ConnectionFailed</span></span>
<span id="UnknownChannelType"><span class="nx">UnknownChannelType</span></span>
<span id="ResourceShortage"><span class="nx">ResourceShortage</span></span>
<span class="p">)</span></pre>
<h4 id="RejectionReason.String">func (RejectionReason) String</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">r</span> <a href="#RejectionReason"><span class="nx">RejectionReason</span></a><span class="p">)</span> <span class="nf">String</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>String converts the rejection reason to human readable form.
<h3 id="Request">type Request</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Request</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="Request.Type"><span class="nx">Type</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Request.WantReply"><span class="nx">WantReply</span></span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a>
<span id="Request.Payload"><span class="nx">Payload</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>Request is a request sent outside of the normal stream of
data. Requests can either be specific to an SSH channel, or they
can be global.
<h4 id="Request.Reply">func (*Request) Reply</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">r</span> <span class="o">*</span><a href="#Request"><span class="nx">Request</span></a><span class="p">)</span> <span class="nf">Reply</span><span class="p">(</span><span class="nx">ok</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <span class="nx">payload</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Reply sends a response to a request. It must be called for all requests
where WantReply is true and is a no-op otherwise. The payload argument is
ignored for replies to channel-specific requests.
<h3 id="RequestHandler">type RequestHandler</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">RequestHandler</span> <span class="kd">interface</span> <span class="p">{</span>
<span id="RequestHandler.NewRequest"><span class="nf">NewRequest</span></span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><a href="#Request"><span class="nx">Request</span></a><span class="p">)</span>
<span class="p">}</span></pre>
<p>RequestHandler defines the interface to handle new <a href="#Request">Request</a>.ListenTCP
<h3 id="RequestHandlerFunc">type RequestHandlerFunc</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">RequestHandlerFunc</span> <span class="kd">func</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><a href="#Request"><span class="nx">Request</span></a><span class="p">)</span></pre>
<p>RequestHandlerFunc is an adapter to allow the use of ordinary function as
<a href="#RequestHandler">RequestHandler</a>. If f is a function with the appropriate signature,
RequestHandlerFunc(f) is a <a href="#RequestHandler">RequestHandler</a> that calls f.
<h4 id="RequestHandlerFunc.NewRequest">func (RequestHandlerFunc) NewRequest</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">f</span> <a href="#RequestHandlerFunc"><span class="nx">RequestHandlerFunc</span></a><span class="p">)</span> <span class="nf">NewRequest</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><a href="#Request"><span class="nx">Request</span></a><span class="p">)</span></pre>
<p>NewRequest calls f(req).
<h3 id="Server">type Server</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Server</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Config contains configuration shared between client and server.
</span><span class="c1"></span> <a href="#Config"><span class="nx">Config</span></a>
<span class="c1">// PublicKeyAuthAlgorithms specifies the supported client public key
</span><span class="c1"></span> <span class="c1">// authentication algorithms. Note that this should not include certificate
</span><span class="c1"></span> <span class="c1">// types since those use the underlying algorithm. This list is sent to the
</span><span class="c1"></span> <span class="c1">// client if it supports the server-sig-algs extension. Order is irrelevant.
</span><span class="c1"></span> <span class="c1">// If unspecified then a default set of algorithms is used.
</span><span class="c1"></span> <span id="Server.PublicKeyAuthAlgorithms"><span class="nx">PublicKeyAuthAlgorithms</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// NoClientAuth, if non-nil, is called when a user
</span><span class="c1"></span> <span class="c1">// attempts to authenticate with auth method &#34;none&#34;.
</span><span class="c1"></span> <span id="Server.NoClientAuth"><span class="nx">NoClientAuth</span></span> <span class="kd">func</span><span class="p">(</span><a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// MaxAuthTries specifies the maximum number of authentication attempts
</span><span class="c1"></span> <span class="c1">// permitted per connection. If set to a negative number, the number of
</span><span class="c1"></span> <span class="c1">// attempts are unlimited. If set to zero, the number of attempts are limited
</span><span class="c1"></span> <span class="c1">// to 6.
</span><span class="c1"></span> <span id="Server.MaxAuthTries"><span class="nx">MaxAuthTries</span></span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a>
<span class="c1">// Password, if non-nil, is called when a user
</span><span class="c1"></span> <span class="c1">// attempts to authenticate using a password.
</span><span class="c1"></span> <span id="Server.Password"><span class="nx">Password</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">password</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// PublicKey, if non-nil, is called when a client
</span><span class="c1"></span> <span class="c1">// offers a public key for authentication. It must return a nil error
</span><span class="c1"></span> <span class="c1">// if the given public key can be used to authenticate the
</span><span class="c1"></span> <span class="c1">// given user. For example, see CertChecker.Authenticate. A
</span><span class="c1"></span> <span class="c1">// call to this function does not guarantee that the key
</span><span class="c1"></span> <span class="c1">// offered is in fact used to authenticate. To record any data
</span><span class="c1"></span> <span class="c1">// depending on the public key, store it inside a
</span><span class="c1"></span> <span class="c1">// Permissions.Extensions entry.
</span><span class="c1"></span> <span id="Server.PublicKey"><span class="nx">PublicKey</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// KeyboardInteractive, if non-nil, is called when
</span><span class="c1"></span> <span class="c1">// keyboard-interactive authentication is selected (RFC
</span><span class="c1"></span> <span class="c1">// 4256). The client object&#39;s Challenge function should be
</span><span class="c1"></span> <span class="c1">// used to query the user. The callback may offer multiple
</span><span class="c1"></span> <span class="c1">// Challenge rounds. To avoid information leaks, the client
</span><span class="c1"></span> <span class="c1">// should be presented a challenge even if the user is
</span><span class="c1"></span> <span class="c1">// unknown.
</span><span class="c1"></span> <span id="Server.KeyboardInteractive"><span class="nx">KeyboardInteractive</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">client</span> <a href="#KeyboardInteractiveChallenge"><span class="nx">KeyboardInteractiveChallenge</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// AuthLog, if non-nil, is called to log all authentication
</span><span class="c1"></span> <span class="c1">// attempts.
</span><span class="c1"></span> <span id="Server.AuthLog"><span class="nx">AuthLog</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">method</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// ServerVersion is the version identification string to announce in
</span><span class="c1"></span> <span class="c1">// the public handshake.
</span><span class="c1"></span> <span class="c1">// If empty, a reasonable default is used.
</span><span class="c1"></span> <span class="c1">// Note that RFC 4253 section 4.2 requires that this string start with
</span><span class="c1"></span> <span class="c1">// &#34;SSH-2.0-&#34;.
</span><span class="c1"></span> <span id="Server.ServerVersion"><span class="nx">ServerVersion</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// BannerCallback, if present, is called and the return string is sent to
</span><span class="c1"></span> <span class="c1">// the client after key exchange completed but before authentication.
</span><span class="c1"></span> <span id="Server.Banner"><span class="nx">Banner</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="c1">// GSSAPIWithMICConfig includes gssapi server and callback, which if both non-nil, is used
</span><span class="c1"></span> <span class="c1">// when gssapi-with-mic authentication is selected (RFC 4462 section 3).
</span><span class="c1"></span> <span id="Server.GSSAPIWithMICConfig"><span class="nx">GSSAPIWithMICConfig</span></span> <span class="o">*</span><a href="#GSSAPIWithMICConfig"><span class="nx">GSSAPIWithMICConfig</span></a>
<span class="c1">// HandshakeTimeout defines the timeout for the initial handshake, as milliseconds.
</span><span class="c1"></span> <span id="Server.HandshakeTimeout"><span class="nx">HandshakeTimeout</span></span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a>
<span class="c1">// ConnectionFailed, if non-nil, is called to report handshake errors.
</span><span class="c1"></span> <span id="Server.ConnectionFailed"><span class="nx">ConnectionFailed</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">,</span> <span class="nx">err</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// ConnectionAddedCallback, if non-nil, is called when a client connects, by
</span><span class="c1"></span> <span class="c1">// returning an error the connection will be refused.
</span><span class="c1"></span> <span id="Server.ConnectionAdded"><span class="nx">ConnectionAdded</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="c1">// ClientHandler defines the handler for authenticated clients. It is called
</span><span class="c1"></span> <span class="c1">// if the handshake is successfull. The handler must serve requests and
</span><span class="c1"></span> <span class="c1">// channels using [ServerConn.Handle].
</span><span class="c1"></span> <span id="Server.ClientHandler"><span class="nx">ClientHandler</span></span> <a href="#ClientHandler"><span class="nx">ClientHandler</span></a>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>Server holds server specific configuration data.
<h4 id="Server.AddHostKey">func (*Server) AddHostKey</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Server"><span class="nx">Server</span></a><span class="p">)</span> <span class="nf">AddHostKey</span><span class="p">(</span><span class="nx">key</span> <a href="#Signer"><span class="nx">Signer</span></a><span class="p">)</span></pre>
<p>AddHostKey adds a private key as a host key. If an existing host
key exists with the same public key format, it is replaced. Each server
config must have at least one host key.
<details id="example-Server.AddHostKey" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;os&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Minimal Server supporting only password authentication.
</span><span class="c1"></span> <span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Server</span><span class="p">{</span>
<span class="nx">Password</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">ConnMetadata</span><span class="p">,</span> <span class="nx">pass</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Should use constant-time compare (or better, salt+hash) in
</span><span class="c1"></span> <span class="c1">// a production setting.
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">()</span> <span class="o">==</span> <span class="s">&#34;testuser&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">string</span><span class="p">(</span><span class="nx">pass</span><span class="p">)</span> <span class="o">==</span> <span class="s">&#34;tiger&#34;</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;password rejected for %q&#34;</span><span class="p">,</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">())</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="nx">privateBytes</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;id_rsa&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to load private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">private</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParsePrivateKey</span><span class="p">(</span><span class="nx">privateBytes</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to parse private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Restrict host key algorithms to disable ssh-rsa.
</span><span class="c1"></span> <span class="nx">signer</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">NewSignerWithAlgorithms</span><span class="p">(</span><span class="nx">private</span><span class="p">,</span> <span class="p">[]</span><span class="kt">string</span><span class="p">{</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">KeyAlgoRSASHA256</span><span class="p">,</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">KeyAlgoRSASHA512</span><span class="p">})</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to create private key with restricted algorithms: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">config</span><span class="p">.</span><span class="nf">AddHostKey</span><span class="p">(</span><span class="nx">signer</span><span class="p">)</span>
<span class="p">}</span></pre>
</details>
<h4 id="Server.Close">func (*Server) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Server"><span class="nx">Server</span></a><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Close immediately closes all active net.Listeners.
<h4 id="Server.ListenAndServe">func (*Server) ListenAndServe</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Server"><span class="nx">Server</span></a><span class="p">)</span> <span class="nf">ListenAndServe</span><span class="p">(</span><span class="nx">addr</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<details id="example-Server.ListenAndServe" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;net&#34;</span>
<span class="s">&#34;os&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="s">&#34;golang.org/x/term&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Public key authentication is done by comparing
</span><span class="c1"></span> <span class="c1">// the public key of a received connection
</span><span class="c1"></span> <span class="c1">// with the entries in the authorized_keys file.
</span><span class="c1"></span> <span class="nx">authorizedKeysBytes</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;authorized_keys&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Failed to load authorized_keys, err: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">authorizedKeysMap</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">bool</span><span class="p">{}</span>
<span class="k">for</span> <span class="nb">len</span><span class="p">(</span><span class="nx">authorizedKeysBytes</span><span class="p">)</span> <span class="p">&gt;</span> <span class="mi">0</span> <span class="p">{</span>
<span class="nx">pubKey</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">rest</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParseAuthorizedKey</span><span class="p">(</span><span class="nx">authorizedKeysBytes</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">authorizedKeysMap</span><span class="p">[</span><span class="nb">string</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">.</span><span class="nf">Marshal</span><span class="p">())]</span> <span class="p">=</span> <span class="kc">true</span>
<span class="nx">authorizedKeysBytes</span> <span class="p">=</span> <span class="nx">rest</span>
<span class="p">}</span>
<span class="c1">// An SSH server is represented by a Server, which holds
</span><span class="c1"></span> <span class="c1">// certificate details and handles authentication of ServerConns.
</span><span class="c1"></span> <span class="nx">server</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Server</span><span class="p">{</span>
<span class="c1">// Remove to disable password auth.
</span><span class="c1"></span> <span class="nx">Password</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">ConnMetadata</span><span class="p">,</span> <span class="nx">pass</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Should use constant-time compare (or better, salt+hash) in
</span><span class="c1"></span> <span class="c1">// a production setting.
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">()</span> <span class="o">==</span> <span class="s">&#34;testuser&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">string</span><span class="p">(</span><span class="nx">pass</span><span class="p">)</span> <span class="o">==</span> <span class="s">&#34;tiger&#34;</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;password rejected for %q&#34;</span><span class="p">,</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">())</span>
<span class="p">},</span>
<span class="c1">// Remove to disable public key auth.
</span><span class="c1"></span> <span class="nx">PublicKey</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">ConnMetadata</span><span class="p">,</span> <span class="nx">pubKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">authorizedKeysMap</span><span class="p">[</span><span class="nb">string</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">.</span><span class="nf">Marshal</span><span class="p">())]</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">{</span>
<span class="c1">// Record the public key used for authentication.
</span><span class="c1"></span> <span class="nx">Extensions</span><span class="p">:</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
<span class="s">&#34;pubkey-fp&#34;</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FingerprintSHA256</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">),</span>
<span class="p">},</span>
<span class="p">},</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;unknown public key for %q&#34;</span><span class="p">,</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">())</span>
<span class="p">},</span>
<span class="nx">ConnectionFailed</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">net</span><span class="p">.</span><span class="nx">Conn</span><span class="p">,</span> <span class="nx">err</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Here we can get the error if an handshake fails
</span><span class="c1"></span> <span class="p">},</span>
<span class="nx">ClientHandler</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ClientHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">ServerConn</span><span class="p">)</span> <span class="p">{</span>
<span class="nx">conn</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">ChannelHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">newChannel</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">NewChannel</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// In this handler we have to accept and use the new channel or reject it.
</span><span class="c1"></span>
<span class="c1">// Channels have a type, depending on the application level
</span><span class="c1"></span> <span class="c1">// protocol intended. In the case of a shell, the type is
</span><span class="c1"></span> <span class="c1">// &#34;session&#34; and ServerShell may be used to present a simple
</span><span class="c1"></span> <span class="c1">// terminal interface.
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">newChannel</span><span class="p">.</span><span class="nf">ChannelType</span><span class="p">()</span> <span class="o">!=</span> <span class="s">&#34;session&#34;</span> <span class="p">{</span>
<span class="nx">newChannel</span><span class="p">.</span><span class="nf">Reject</span><span class="p">(</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">UnknownChannelType</span><span class="p">,</span> <span class="s">&#34;unknown channel type&#34;</span><span class="p">)</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="nx">channel</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">newChannel</span><span class="p">.</span><span class="nf">Accept</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Could not accept channel: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">err</span> <span class="p">=</span> <span class="nx">channel</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span><span class="nx">ssh</span><span class="p">.</span><span class="nf">RequestHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Sessions have out-of-band requests such as &#34;shell&#34;,
</span><span class="c1"></span> <span class="c1">// &#34;pty-req&#34; and &#34;env&#34;. Here we handle only the
</span><span class="c1"></span> <span class="c1">// &#34;shell&#34; request.
</span><span class="c1"></span> <span class="nx">req</span><span class="p">.</span><span class="nf">Reply</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">Type</span> <span class="o">==</span> <span class="s">&#34;shell&#34;</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="p">}))</span>
<span class="nx">terminal</span> <span class="o">:=</span> <span class="nx">term</span><span class="p">.</span><span class="nf">NewTerminal</span><span class="p">(</span><span class="nx">channel</span><span class="p">,</span> <span class="s">&#34;&gt; &#34;</span><span class="p">)</span>
<span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">channel</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="p">}()</span>
<span class="k">for</span> <span class="p">{</span>
<span class="nx">line</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">terminal</span><span class="p">.</span><span class="nf">ReadLine</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="k">break</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">line</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}()</span>
<span class="p">}),</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">RequestHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">req</span><span class="p">.</span><span class="nx">WantReply</span> <span class="p">{</span>
<span class="nx">req</span><span class="p">.</span><span class="nf">Reply</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}),</span>
<span class="p">)</span>
<span class="p">}),</span>
<span class="p">}</span>
<span class="nx">privateBytes</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;id_rsa&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to load private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">private</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParsePrivateKey</span><span class="p">(</span><span class="nx">privateBytes</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to parse private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">server</span><span class="p">.</span><span class="nf">AddHostKey</span><span class="p">(</span><span class="nx">private</span><span class="p">)</span>
<span class="nx">server</span><span class="p">.</span><span class="nf">ListenAndServe</span><span class="p">(</span><span class="s">&#34;0.0.0.0:2022&#34;</span><span class="p">)</span>
<span class="p">}</span></pre>
</details>
<h4 id="Server.Serve">func (*Server) Serve</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Server"><span class="nx">Server</span></a><span class="p">)</span> <span class="nf">Serve</span><span class="p">(</span><span class="nx">l</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Listener"><span class="nx">Listener</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Serve accepts incoming connections on the Listener l, creating a new service
goroutine for each and execute the provided <a href="#ClientHandler">ClientHandler</a> implementation.
<h3 id="ServerAuthCallbacks">type ServerAuthCallbacks</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ServerAuthCallbacks</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Password behaves like [Server.PasswordCallback].
</span><span class="c1"></span> <span id="ServerAuthCallbacks.Password"><span class="nx">Password</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">password</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// PublicKey behaves like [Server.PublicKeyCallback].
</span><span class="c1"></span> <span id="ServerAuthCallbacks.PublicKey"><span class="nx">PublicKey</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">key</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// KeyboardInteractive behaves like [Server.KeyboardInteractiveCallback].
</span><span class="c1"></span> <span id="ServerAuthCallbacks.KeyboardInteractive"><span class="nx">KeyboardInteractive</span></span> <span class="kd">func</span><span class="p">(</span><span class="nx">conn</span> <a href="#ConnMetadata"><span class="nx">ConnMetadata</span></a><span class="p">,</span> <span class="nx">client</span> <a href="#KeyboardInteractiveChallenge"><span class="nx">KeyboardInteractiveChallenge</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// GSSAPIWithMICConfig behaves like [Server.GSSAPIWithMICConfig].
</span><span class="c1"></span> <span id="ServerAuthCallbacks.GSSAPIWithMICConfig"><span class="nx">GSSAPIWithMICConfig</span></span> <span class="o">*</span><a href="#GSSAPIWithMICConfig"><span class="nx">GSSAPIWithMICConfig</span></a>
<span class="p">}</span></pre>
<p>ServerAuthCallbacks defines server-side authentication callbacks.
<h3 id="ServerAuthError">type ServerAuthError</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ServerAuthError</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Errors contains authentication errors returned by the authentication
</span><span class="c1"></span> <span class="c1">// callback methods. The first entry is typically ErrNoAuth.
</span><span class="c1"></span> <span id="ServerAuthError.Errors"><span class="nx">Errors</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a>
<span class="p">}</span></pre>
<p>ServerAuthError represents server authentication errors and is
sometimes returned by NewServerConn. It appends any authentication
errors that may occur, and is returned if all of the authentication
methods provided by the user failed to authenticate.
<h4 id="ServerAuthError.Error">func (ServerAuthError) Error</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">l</span> <a href="#ServerAuthError"><span class="nx">ServerAuthError</span></a><span class="p">)</span> <span class="nf">Error</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="ServerConn">type ServerConn</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">ServerConn</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// If the succeeding authentication callback returned a
</span><span class="c1"></span> <span class="c1">// non-nil Permissions pointer, it is stored here.
</span><span class="c1"></span> <span id="ServerConn.Permissions"><span class="nx">Permissions</span></span> <span class="o">*</span><a href="#Permissions"><span class="nx">Permissions</span></a>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>ServerConn is an authenticated SSH connection, as seen from the
server
<h4 id="NewServerConn">func NewServerConn</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewServerConn</span><span class="p">(</span><span class="nx">ctx</span> <a href="https://pkg.go.dev/context"><span class="nx">context</span></a><span class="p">.</span><a href="https://pkg.go.dev/context#Context"><span class="nx">Context</span></a><span class="p">,</span> <span class="nx">c</span> <a href="https://pkg.go.dev/net"><span class="nx">net</span></a><span class="p">.</span><a href="https://pkg.go.dev/net#Conn"><span class="nx">Conn</span></a><span class="p">,</span> <span class="nx">config</span> <span class="o">*</span><a href="#Server"><span class="nx">Server</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewServerConn starts a new SSH server with c as the underlying
transport. It starts with a handshake and, if the handshake is
unsuccessful, it closes the connection and returns an error. The
Request and NewChannel channels must be serviced, or the connection
will hang.
<p>The returned error may be of type *ServerAuthError for
authentication errors.
<p>This is a low level API useful for advanced use cases, you must use
<a href="#ServerConn.Handle">ServerConn.Handle</a> to handle Requests and Channels.
<details id="example-NewServerConn" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;context&#34;</span>
<span class="s">&#34;fmt&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;net&#34;</span>
<span class="s">&#34;os&#34;</span>
<span class="s">&#34;sync&#34;</span>
<span class="s">&#34;time&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="s">&#34;golang.org/x/term&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="c1">// Public key authentication is done by comparing
</span><span class="c1"></span> <span class="c1">// the public key of a received connection
</span><span class="c1"></span> <span class="c1">// with the entries in the authorized_keys file.
</span><span class="c1"></span> <span class="nx">authorizedKeysBytes</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;authorized_keys&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Failed to load authorized_keys, err: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">authorizedKeysMap</span> <span class="o">:=</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">bool</span><span class="p">{}</span>
<span class="k">for</span> <span class="nb">len</span><span class="p">(</span><span class="nx">authorizedKeysBytes</span><span class="p">)</span> <span class="p">&gt;</span> <span class="mi">0</span> <span class="p">{</span>
<span class="nx">pubKey</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">_</span><span class="p">,</span> <span class="nx">rest</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParseAuthorizedKey</span><span class="p">(</span><span class="nx">authorizedKeysBytes</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">authorizedKeysMap</span><span class="p">[</span><span class="nb">string</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">.</span><span class="nf">Marshal</span><span class="p">())]</span> <span class="p">=</span> <span class="kc">true</span>
<span class="nx">authorizedKeysBytes</span> <span class="p">=</span> <span class="nx">rest</span>
<span class="p">}</span>
<span class="c1">// An SSH server is represented by a Server, which holds
</span><span class="c1"></span> <span class="c1">// certificate details and handles authentication of ServerConns.
</span><span class="c1"></span> <span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Server</span><span class="p">{</span>
<span class="c1">// Remove to disable password auth.
</span><span class="c1"></span> <span class="nx">Password</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">ConnMetadata</span><span class="p">,</span> <span class="nx">pass</span> <span class="p">[]</span><span class="kt">byte</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Should use constant-time compare (or better, salt+hash) in
</span><span class="c1"></span> <span class="c1">// a production setting.
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">()</span> <span class="o">==</span> <span class="s">&#34;testuser&#34;</span> <span class="o">&amp;&amp;</span> <span class="nb">string</span><span class="p">(</span><span class="nx">pass</span><span class="p">)</span> <span class="o">==</span> <span class="s">&#34;tiger&#34;</span> <span class="p">{</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;password rejected for %q&#34;</span><span class="p">,</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">())</span>
<span class="p">},</span>
<span class="c1">// Remove to disable public key auth.
</span><span class="c1"></span> <span class="nx">PublicKey</span><span class="p">:</span> <span class="kd">func</span><span class="p">(</span><span class="nx">c</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">ConnMetadata</span><span class="p">,</span> <span class="nx">pubKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span><span class="p">)</span> <span class="p">(</span><span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">,</span> <span class="kt">error</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">authorizedKeysMap</span><span class="p">[</span><span class="nb">string</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">.</span><span class="nf">Marshal</span><span class="p">())]</span> <span class="p">{</span>
<span class="k">return</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">{</span>
<span class="c1">// Record the public key used for authentication.
</span><span class="c1"></span> <span class="nx">Extensions</span><span class="p">:</span> <span class="kd">map</span><span class="p">[</span><span class="kt">string</span><span class="p">]</span><span class="kt">string</span><span class="p">{</span>
<span class="s">&#34;pubkey-fp&#34;</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FingerprintSHA256</span><span class="p">(</span><span class="nx">pubKey</span><span class="p">),</span>
<span class="p">},</span>
<span class="p">},</span> <span class="kc">nil</span>
<span class="p">}</span>
<span class="k">return</span> <span class="kc">nil</span><span class="p">,</span> <span class="nx">fmt</span><span class="p">.</span><span class="nf">Errorf</span><span class="p">(</span><span class="s">&#34;unknown public key for %q&#34;</span><span class="p">,</span> <span class="nx">c</span><span class="p">.</span><span class="nf">User</span><span class="p">())</span>
<span class="p">},</span>
<span class="p">}</span>
<span class="nx">privateBytes</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">ReadFile</span><span class="p">(</span><span class="s">&#34;id_rsa&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to load private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">private</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">ParsePrivateKey</span><span class="p">(</span><span class="nx">privateBytes</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;Failed to parse private key: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">config</span><span class="p">.</span><span class="nf">AddHostKey</span><span class="p">(</span><span class="nx">private</span><span class="p">)</span>
<span class="c1">// Once a Server has been configured, connections can be
</span><span class="c1"></span> <span class="c1">// accepted.
</span><span class="c1"></span> <span class="nx">listener</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">net</span><span class="p">.</span><span class="nf">Listen</span><span class="p">(</span><span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;0.0.0.0:2022&#34;</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;failed to listen for connection: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">nConn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">listener</span><span class="p">.</span><span class="nf">Accept</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;failed to accept incoming connection: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Allow at most 10 seconds to complete the handshake and create the
</span><span class="c1"></span> <span class="c1">// server connection.
</span><span class="c1"></span> <span class="nx">ctx</span><span class="p">,</span> <span class="nx">cancel</span> <span class="o">:=</span> <span class="nx">context</span><span class="p">.</span><span class="nf">WithTimeout</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="mi">10</span><span class="o">*</span><span class="nx">time</span><span class="p">.</span><span class="nx">Second</span><span class="p">)</span>
<span class="k">defer</span> <span class="nf">cancel</span><span class="p">()</span>
<span class="c1">// Before use, a handshake must be performed on the incoming
</span><span class="c1"></span> <span class="c1">// net.Conn.
</span><span class="c1"></span> <span class="nx">conn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">NewServerConn</span><span class="p">(</span><span class="nx">ctx</span><span class="p">,</span> <span class="nx">nConn</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;failed to handshake: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Printf</span><span class="p">(</span><span class="s">&#34;logged in with key %s&#34;</span><span class="p">,</span> <span class="nx">conn</span><span class="p">.</span><span class="nx">Permissions</span><span class="p">.</span><span class="nx">Extensions</span><span class="p">[</span><span class="s">&#34;pubkey-fp&#34;</span><span class="p">])</span>
<span class="kd">var</span> <span class="nx">wg</span> <span class="nx">sync</span><span class="p">.</span><span class="nx">WaitGroup</span>
<span class="k">defer</span> <span class="nx">wg</span><span class="p">.</span><span class="nf">Wait</span><span class="p">()</span>
<span class="nx">conn</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">ChannelHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">newChannel</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">NewChannel</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Channels have a type, depending on the application level
</span><span class="c1"></span> <span class="c1">// protocol intended. In the case of a shell, the type is
</span><span class="c1"></span> <span class="c1">// &#34;session&#34; and ServerShell may be used to present a simple
</span><span class="c1"></span> <span class="c1">// terminal interface.
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">newChannel</span><span class="p">.</span><span class="nf">ChannelType</span><span class="p">()</span> <span class="o">!=</span> <span class="s">&#34;session&#34;</span> <span class="p">{</span>
<span class="nx">newChannel</span><span class="p">.</span><span class="nf">Reject</span><span class="p">(</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">UnknownChannelType</span><span class="p">,</span> <span class="s">&#34;unknown channel type&#34;</span><span class="p">)</span>
<span class="k">return</span>
<span class="p">}</span>
<span class="nx">channel</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">newChannel</span><span class="p">.</span><span class="nf">Accept</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Could not accept channel: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">err</span> <span class="p">=</span> <span class="nx">channel</span><span class="p">.</span><span class="nf">Handle</span><span class="p">(</span><span class="nx">ssh</span><span class="p">.</span><span class="nf">RequestHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
<span class="c1">// Sessions have out-of-band requests such as &#34;shell&#34;,
</span><span class="c1"></span> <span class="c1">// &#34;pty-req&#34; and &#34;env&#34;. Here we handle only the
</span><span class="c1"></span> <span class="c1">// &#34;shell&#34; request.
</span><span class="c1"></span> <span class="nx">req</span><span class="p">.</span><span class="nf">Reply</span><span class="p">(</span><span class="nx">req</span><span class="p">.</span><span class="nx">Type</span> <span class="o">==</span> <span class="s">&#34;shell&#34;</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="p">}))</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatalf</span><span class="p">(</span><span class="s">&#34;Could not handle channel: %v&#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="nx">terminal</span> <span class="o">:=</span> <span class="nx">term</span><span class="p">.</span><span class="nf">NewTerminal</span><span class="p">(</span><span class="nx">channel</span><span class="p">,</span> <span class="s">&#34;&gt; &#34;</span><span class="p">)</span>
<span class="nx">wg</span><span class="p">.</span><span class="nf">Add</span><span class="p">(</span><span class="mi">1</span><span class="p">)</span>
<span class="k">go</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="k">defer</span> <span class="kd">func</span><span class="p">()</span> <span class="p">{</span>
<span class="nx">channel</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="nx">wg</span><span class="p">.</span><span class="nf">Done</span><span class="p">()</span>
<span class="p">}()</span>
<span class="k">for</span> <span class="p">{</span>
<span class="nx">line</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">terminal</span><span class="p">.</span><span class="nf">ReadLine</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="k">break</span>
<span class="p">}</span>
<span class="nx">fmt</span><span class="p">.</span><span class="nf">Println</span><span class="p">(</span><span class="nx">line</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}()</span>
<span class="p">}),</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">RequestHandlerFunc</span><span class="p">(</span><span class="kd">func</span><span class="p">(</span><span class="nx">req</span> <span class="o">*</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">Request</span><span class="p">)</span> <span class="p">{</span>
<span class="k">if</span> <span class="nx">req</span><span class="p">.</span><span class="nx">WantReply</span> <span class="p">{</span>
<span class="nx">req</span><span class="p">.</span><span class="nf">Reply</span><span class="p">(</span><span class="kc">false</span><span class="p">,</span> <span class="kc">nil</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}))</span>
<span class="p">}</span></pre>
</details>
<h4 id="ServerConn.Close">func (*ServerConn) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Close closes the underlying network connection.
<h4 id="ServerConn.Handle">func (*ServerConn) Handle</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">c</span> <span class="o">*</span><a href="#ServerConn"><span class="nx">ServerConn</span></a><span class="p">)</span> <span class="nf">Handle</span><span class="p">(</span><span class="nx">channelHandler</span> <a href="#ChannelHandler"><span class="nx">ChannelHandler</span></a><span class="p">,</span> <span class="nx">requestHandler</span> <a href="#RequestHandler"><span class="nx">RequestHandler</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Handle must be called to handle requests and channels. Handle blocks. If
channelHandler is nil channels will be rejected. If requestHandler is nil,
requests will be discarded.
<h3 id="Session">type Session</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Session</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// Stdin specifies the remote process&#39;s standard input.
</span><span class="c1"></span> <span class="c1">// If Stdin is nil, the remote process reads from an empty
</span><span class="c1"></span> <span class="c1">// bytes.Buffer.
</span><span class="c1"></span> <span id="Session.Stdin"><span class="nx">Stdin</span></span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a>
<span class="c1">// Stdout and Stderr specify the remote process&#39;s standard
</span><span class="c1"></span> <span class="c1">// output and error.
</span><span class="c1"></span> <span class="c1">//
</span><span class="c1"></span> <span class="c1">// If either is nil, Run connects the corresponding file
</span><span class="c1"></span> <span class="c1">// descriptor to an instance of io.Discard. There is a
</span><span class="c1"></span> <span class="c1">// fixed amount of buffering that is shared for the two streams.
</span><span class="c1"></span> <span class="c1">// If either blocks it may eventually cause the remote
</span><span class="c1"></span> <span class="c1">// command to block.
</span><span class="c1"></span> <span id="Session.Stdout"><span class="nx">Stdout</span></span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Writer"><span class="nx">Writer</span></a>
<span id="Session.Stderr"><span class="nx">Stderr</span></span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Writer"><span class="nx">Writer</span></a>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>A Session represents a connection to a remote command or shell.
<h4 id="Session.Close">func (*Session) Close</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Close</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<h4 id="Session.CombinedOutput">func (*Session) CombinedOutput</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">CombinedOutput</span><span class="p">(</span><span class="nx">cmd</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">([]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>CombinedOutput runs cmd on the remote host and returns its combined
standard output and standard error.
<h4 id="Session.Output">func (*Session) Output</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Output</span><span class="p">(</span><span class="nx">cmd</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">([]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>Output runs cmd on the remote host and returns its standard output.
<h4 id="Session.RequestPty">func (*Session) RequestPty</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">RequestPty</span><span class="p">(</span><span class="nx">term</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">h</span><span class="p">,</span> <span class="nx">w</span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a><span class="p">,</span> <span class="nx">termmodes</span> <a href="#TerminalModes"><span class="nx">TerminalModes</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>RequestPty requests the association of a pty with the session on the remote host.
<details id="example-Session.RequestPty" class="example">
<summary>Example</summary>
<pre class="chroma"><span class="kn">package</span> <span class="nx">main</span>
<span class="kn">import</span> <span class="p">(</span>
<span class="s">&#34;context&#34;</span>
<span class="s">&#34;log&#34;</span>
<span class="s">&#34;golang.org/x/crypto/ssh&#34;</span>
<span class="p">)</span>
<span class="kd">func</span> <span class="nf">main</span><span class="p">()</span> <span class="p">{</span>
<span class="kd">var</span> <span class="nx">hostKey</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">PublicKey</span>
<span class="c1">// Create client config
</span><span class="c1"></span> <span class="nx">config</span> <span class="o">:=</span> <span class="o">&amp;</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">ClientConfig</span><span class="p">{</span>
<span class="nx">User</span><span class="p">:</span> <span class="s">&#34;username&#34;</span><span class="p">,</span>
<span class="nx">Auth</span><span class="p">:</span> <span class="p">[]</span><span class="nx">ssh</span><span class="p">.</span><span class="nx">AuthMethod</span><span class="p">{</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nf">Password</span><span class="p">(</span><span class="s">&#34;password&#34;</span><span class="p">),</span>
<span class="p">},</span>
<span class="nx">HostKey</span><span class="p">:</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">FixedHostKey</span><span class="p">(</span><span class="nx">hostKey</span><span class="p">),</span>
<span class="p">}</span>
<span class="c1">// Connect to ssh server
</span><span class="c1"></span> <span class="nx">conn</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">Dial</span><span class="p">(</span><span class="nx">context</span><span class="p">.</span><span class="nf">Background</span><span class="p">(),</span> <span class="s">&#34;tcp&#34;</span><span class="p">,</span> <span class="s">&#34;localhost:22&#34;</span><span class="p">,</span> <span class="nx">config</span><span class="p">)</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to connect: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">conn</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Create a session
</span><span class="c1"></span> <span class="nx">session</span><span class="p">,</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">conn</span><span class="p">.</span><span class="nf">NewSession</span><span class="p">()</span>
<span class="k">if</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;unable to create session: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="k">defer</span> <span class="nx">session</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span>
<span class="c1">// Set up terminal modes
</span><span class="c1"></span> <span class="nx">modes</span> <span class="o">:=</span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">TerminalModes</span><span class="p">{</span>
<span class="nx">ssh</span><span class="p">.</span><span class="nx">ECHO</span><span class="p">:</span> <span class="mi">0</span><span class="p">,</span> <span class="c1">// disable echoing
</span><span class="c1"></span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">TTY_OP_ISPEED</span><span class="p">:</span> <span class="mi">14400</span><span class="p">,</span> <span class="c1">// input speed = 14.4kbaud
</span><span class="c1"></span> <span class="nx">ssh</span><span class="p">.</span><span class="nx">TTY_OP_OSPEED</span><span class="p">:</span> <span class="mi">14400</span><span class="p">,</span> <span class="c1">// output speed = 14.4kbaud
</span><span class="c1"></span> <span class="p">}</span>
<span class="c1">// Request pseudo terminal
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">session</span><span class="p">.</span><span class="nf">RequestPty</span><span class="p">(</span><span class="s">&#34;xterm&#34;</span><span class="p">,</span> <span class="mi">40</span><span class="p">,</span> <span class="mi">80</span><span class="p">,</span> <span class="nx">modes</span><span class="p">);</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;request for pseudo terminal failed: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="c1">// Start remote shell
</span><span class="c1"></span> <span class="k">if</span> <span class="nx">err</span> <span class="o">:=</span> <span class="nx">session</span><span class="p">.</span><span class="nf">Shell</span><span class="p">();</span> <span class="nx">err</span> <span class="o">!=</span> <span class="kc">nil</span> <span class="p">{</span>
<span class="nx">log</span><span class="p">.</span><span class="nf">Fatal</span><span class="p">(</span><span class="s">&#34;failed to start shell: &#34;</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span>
<span class="p">}</span>
<span class="p">}</span></pre>
</details>
<h4 id="Session.RequestSubsystem">func (*Session) RequestSubsystem</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">RequestSubsystem</span><span class="p">(</span><span class="nx">subsystem</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>RequestSubsystem requests the association of a subsystem with the session on the remote host.
A subsystem is a predefined command that runs in the background when the ssh session is initiated
<h4 id="Session.Run">func (*Session) Run</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Run</span><span class="p">(</span><span class="nx">cmd</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Run runs cmd on the remote host. Typically, the remote
server passes cmd to the shell for interpretation.
A Session only accepts one call to Run, Start, Shell, Output,
or CombinedOutput.
<p>The returned error is nil if the command runs, has no problems
copying stdin, stdout, and stderr, and exits with a zero exit
status.
<p>If the remote server does not send an exit status, an error of type
*ExitMissingError is returned. If the command completes
unsuccessfully or is interrupted by a signal, the error is of type
*ExitError. Other error types may be returned for I/O problems.
<h4 id="Session.SendRequest">func (*Session) SendRequest</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">SendRequest</span><span class="p">(</span><span class="nx">name</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">wantReply</span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <span class="nx">payload</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>SendRequest sends an out-of-band channel request on the SSH channel
underlying the session.
<h4 id="Session.Setenv">func (*Session) Setenv</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Setenv</span><span class="p">(</span><span class="nx">name</span><span class="p">,</span> <span class="nx">value</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Setenv sets an environment variable that will be applied to any
command executed by Shell or Run.
<h4 id="Session.Shell">func (*Session) Shell</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Shell</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Shell starts a login shell on the remote host. A Session only
accepts one call to Run, Start, Shell, Output, or CombinedOutput.
<h4 id="Session.Signal">func (*Session) Signal</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Signal</span><span class="p">(</span><span class="nx">sig</span> <a href="#Signal"><span class="nx">Signal</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Signal sends the given signal to the remote process.
sig is one of the SIG* constants.
<h4 id="Session.Start">func (*Session) Start</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Start</span><span class="p">(</span><span class="nx">cmd</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Start runs cmd on the remote host. Typically, the remote
server passes cmd to the shell for interpretation.
A Session only accepts one call to Run, Start or Shell.
<h4 id="Session.StderrPipe">func (*Session) StderrPipe</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">StderrPipe</span><span class="p">()</span> <span class="p">(</span><a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>StderrPipe returns a pipe that will be connected to the
remote command&apos;s standard error when the command starts.
There is a fixed amount of buffering that is shared between
stdout and stderr streams. If the StderrPipe reader is
not serviced fast enough it may eventually cause the
remote command to block.
<h4 id="Session.StdinPipe">func (*Session) StdinPipe</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">StdinPipe</span><span class="p">()</span> <span class="p">(</span><a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#WriteCloser"><span class="nx">WriteCloser</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>StdinPipe returns a pipe that will be connected to the
remote command&apos;s standard input when the command starts.
<h4 id="Session.StdoutPipe">func (*Session) StdoutPipe</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">StdoutPipe</span><span class="p">()</span> <span class="p">(</span><a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>StdoutPipe returns a pipe that will be connected to the
remote command&apos;s standard output when the command starts.
There is a fixed amount of buffering that is shared between
stdout and stderr streams. If the StdoutPipe reader is
not serviced fast enough it may eventually cause the
remote command to block.
<h4 id="Session.Wait">func (*Session) Wait</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">Wait</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>Wait waits for the remote command to exit.
<p>The returned error is nil if the command runs, has no problems
copying stdin, stdout, and stderr, and exits with a zero exit
status.
<p>If the remote server does not send an exit status, an error of type
*ExitMissingError is returned. If the command completes
unsuccessfully or is interrupted by a signal, the error is of type
*ExitError. Other error types may be returned for I/O problems.
<h4 id="Session.WindowChange">func (*Session) WindowChange</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">s</span> <span class="o">*</span><a href="#Session"><span class="nx">Session</span></a><span class="p">)</span> <span class="nf">WindowChange</span><span class="p">(</span><span class="nx">h</span><span class="p">,</span> <span class="nx">w</span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre>
<p>WindowChange informs the remote host about a terminal window dimension change to h rows and w columns.
<h3 id="Signal">type Signal</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Signal</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<pre class="chroma"><span class="kd">const</span> <span class="p">(</span>
<span id="SIGABRT"><span class="nx">SIGABRT</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;ABRT&#34;</span>
<span id="SIGALRM"><span class="nx">SIGALRM</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;ALRM&#34;</span>
<span id="SIGFPE"><span class="nx">SIGFPE</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;FPE&#34;</span>
<span id="SIGHUP"><span class="nx">SIGHUP</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;HUP&#34;</span>
<span id="SIGILL"><span class="nx">SIGILL</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;ILL&#34;</span>
<span id="SIGINT"><span class="nx">SIGINT</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;INT&#34;</span>
<span id="SIGKILL"><span class="nx">SIGKILL</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;KILL&#34;</span>
<span id="SIGPIPE"><span class="nx">SIGPIPE</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;PIPE&#34;</span>
<span id="SIGQUIT"><span class="nx">SIGQUIT</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;QUIT&#34;</span>
<span id="SIGSEGV"><span class="nx">SIGSEGV</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;SEGV&#34;</span>
<span id="SIGTERM"><span class="nx">SIGTERM</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;TERM&#34;</span>
<span id="SIGUSR1"><span class="nx">SIGUSR1</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;USR1&#34;</span>
<span id="SIGUSR2"><span class="nx">SIGUSR2</span></span> <a href="#Signal"><span class="nx">Signal</span></a> <span class="p">=</span> <span class="s">&#34;USR2&#34;</span>
<span class="p">)</span></pre>
<p>POSIX signals as listed in RFC 4254 Section 6.10.
<h3 id="Signature">type Signature</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Signature</span> <span class="kd">struct</span> <span class="p">{</span>
<span id="Signature.Format"><span class="nx">Format</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span id="Signature.Blob"><span class="nx">Blob</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a>
<span id="Signature.Rest"><span class="nx">Rest</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a> <span class="s">`ssh:&#34;rest&#34;`</span>
<span class="p">}</span></pre>
<p>Signature represents a cryptographic signature.
<h3 id="Signer">type Signer</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Signer</span> <span class="kd">interface</span> <span class="p">{</span>
<span class="c1">// PublicKey returns the associated PublicKey.
</span><span class="c1"></span> <span id="Signer.PublicKey"><span class="nf">PublicKey</span></span><span class="p">()</span> <a href="#PublicKey"><span class="nx">PublicKey</span></a>
<span class="c1">// Sign returns a signature for the given data. This method will hash the
</span><span class="c1"></span> <span class="c1">// data appropriately first. The signature algorithm is expected to match
</span><span class="c1"></span> <span class="c1">// the key format returned by the PublicKey.Type method (and not to be any
</span><span class="c1"></span> <span class="c1">// alternative algorithm supported by the key format).
</span><span class="c1"></span> <span id="Signer.Sign"><span class="nf">Sign</span></span><span class="p">(</span><span class="nx">rand</span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a><span class="p">,</span> <span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Signature"><span class="nx">Signature</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// SignWithAlgorithm is like Signer.Sign, but allows specifying a desired
</span><span class="c1"></span> <span class="c1">// signing algorithm. Callers may pass an empty string for the algorithm in
</span><span class="c1"></span> <span class="c1">// which case the AlgorithmSigner will use a default algorithm. This default
</span><span class="c1"></span> <span class="c1">// doesn&#39;t currently control any behavior in this package.
</span><span class="c1"></span> <span id="Signer.SignWithAlgorithm"><span class="nf">SignWithAlgorithm</span></span><span class="p">(</span><span class="nx">rand</span> <a href="https://pkg.go.dev/io"><span class="nx">io</span></a><span class="p">.</span><a href="https://pkg.go.dev/io#Reader"><span class="nx">Reader</span></a><span class="p">,</span> <span class="nx">data</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a><span class="p">,</span> <span class="nx">algorithm</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href="#Signature"><span class="nx">Signature</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span>
<span class="c1">// Algorithms returns the available algorithms in preference order. The list
</span><span class="c1"></span> <span class="c1">// must not be empty, and it must not include certificate types.
</span><span class="c1"></span> <span id="Signer.Algorithms"><span class="nf">Algorithms</span></span><span class="p">()</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a>
<span class="p">}</span></pre>
<p>A Signer can create signatures that verify against a public key.
<p>Some Signers provided by this package also implement MultiAlgorithmSigner.
<h4 id="NewCertSigner">func NewCertSigner</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewCertSigner</span><span class="p">(</span><span class="nx">cert</span> <span class="o">*</span><a href="#Certificate"><span class="nx">Certificate</span></a><span class="p">,</span> <span class="nx">signer</span> <a href="#Signer"><span class="nx">Signer</span></a><span class="p">)</span> <span class="p">(</span><a href="#Signer"><span class="nx">Signer</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewCertSigner returns a Signer that signs with the given Certificate, whose
private key is held by signer. It returns an error if the public key in cert
doesn&apos;t match the key used by signer.
<h4 id="NewSigner">func NewSigner</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewSigner</span><span class="p">(</span><span class="nx">signer</span> <a href="https://pkg.go.dev/crypto"><span class="nx">crypto</span></a><span class="p">.</span><a href="https://pkg.go.dev/crypto#Signer"><span class="nx">Signer</span></a><span class="p">)</span> <span class="p">(</span><a href="#Signer"><span class="nx">Signer</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewSigner takes any crypto.Signer implementation and returns a corresponding
Signer interface. This can be used, for example, with keys kept in hardware
modules.
<h4 id="NewSignerWithAlgorithms">func NewSignerWithAlgorithms</h4>
<pre class="chroma"><span class="kd">func</span> <span class="nf">NewSignerWithAlgorithms</span><span class="p">(</span><span class="nx">signer</span> <a href="#Signer"><span class="nx">Signer</span></a><span class="p">,</span> <span class="nx">algorithms</span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">)</span> <span class="p">(</span><a href="#Signer"><span class="nx">Signer</span></a><span class="p">,</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
<p>NewSignerWithAlgorithms returns a signer restricted to the specified
algorithms. The algorithms must be set in preference order. The list must not
be empty, and it must not include certificate types. An error is returned if
the specified algorithms are incompatible with the public key type.
<h3 id="TerminalModes">type TerminalModes</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">TerminalModes</span> <span class="kd">map</span><span class="p">[</span><a href="https://pkg.go.dev/builtin#uint8"><span class="kt">uint8</span></a><span class="p">]</span><a href="https://pkg.go.dev/builtin#uint32"><span class="kt">uint32</span></a></pre>
<h3 id="Waitmsg">type Waitmsg</h3>
<pre class="chroma"><span class="kd">type</span> <span class="nx">Waitmsg</span> <span class="kd">struct</span> <span class="p">{</span>
<span class="c1">// contains filtered or unexported fields
</span><span class="c1"></span><span class="p">}</span></pre>
<p>Waitmsg stores the information about an exited remote command
as reported by Wait.
<h4 id="Waitmsg.ExitStatus">func (Waitmsg) ExitStatus</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">w</span> <a href="#Waitmsg"><span class="nx">Waitmsg</span></a><span class="p">)</span> <span class="nf">ExitStatus</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#int"><span class="kt">int</span></a></pre>
<p>ExitStatus returns the exit status of the remote command.
<h4 id="Waitmsg.Lang">func (Waitmsg) Lang</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">w</span> <a href="#Waitmsg"><span class="nx">Waitmsg</span></a><span class="p">)</span> <span class="nf">Lang</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>Lang returns the language tag. See RFC 3066
<h4 id="Waitmsg.Msg">func (Waitmsg) Msg</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">w</span> <a href="#Waitmsg"><span class="nx">Waitmsg</span></a><span class="p">)</span> <span class="nf">Msg</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>Msg returns the exit message given by the remote command
<h4 id="Waitmsg.Signal">func (Waitmsg) Signal</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">w</span> <a href="#Waitmsg"><span class="nx">Waitmsg</span></a><span class="p">)</span> <span class="nf">Signal</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<p>Signal returns the exit signal of the remote command if
it was terminated violently.
<h4 id="Waitmsg.String">func (Waitmsg) String</h4>
<pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">w</span> <a href="#Waitmsg"><span class="nx">Waitmsg</span></a><span class="p">)</span> <span class="nf">String</span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a></pre>
<h3 id="pkg-directories">Directories</h3>
<table>
<tbody>
<tr>
<td><a href="agent/agent.html">agent</a></td>
<td>Package agent implements the ssh-agent protocol, and provides both a client and a server.</td>
</tr>
<tr>
<td><a href="knownhosts/knownhosts.html">knownhosts</a></td>
<td>Package knownhosts implements a parser for the OpenSSH known_hosts host key database, and provides utility functions for writing OpenSSH compliant known_hosts files.</td>
</tr>
</tbody>
</table>
</main>
<hr>
<footer>
<small id="generated-by-footer">
Generated with <a href="https://abhinav.github.io/doc2go/">doc2go</a>
</small>
</footer>
<script type="text/javascript">
// If the page was opened with an anchor (e.g. #foo),
// and the destination is a <details> element, open it.
function openDetailsAnchor() {
let hash = window.location.hash
if (!hash) {
return
}
let el = document.getElementById(hash.slice(1)) // remove leading '#'
if (!el) {
return
}
let details = el.closest("details")
while (details) {
details.open = true
details = details.parentElement.closest("details")
}
// New elements may have appeared.
// Set hash again to scroll to the right place.
window.location.hash = hash;
return false;
}
window.addEventListener('hashchange', openDetailsAnchor)
window.addEventListener('load', () => {
document.querySelectorAll("h2, h3, h4, h5, h6").forEach((el) => {
if (!el.id) {
return
}
el.innerHTML += ' <a class="permalink" href="#' + el.id + '">&para;</a>'
})
document.querySelectorAll("details.example > summary").forEach((el) => {
let id = el.parentElement.id;
if (!id) {
return
}
el.innerHTML += ' <a class="permalink" href="#' + id + '">&para;</a>'
})
openDetailsAnchor()
})
</script>
</body>
</html>