aboutsummaryrefslogtreecommitdiff
path: root/design/68723/ssh.html
diff options
context:
space:
mode:
Diffstat (limited to 'design/68723/ssh.html')
-rw-r--r--design/68723/ssh.html2817
1 files changed, 2817 insertions, 0 deletions
diff --git a/design/68723/ssh.html b/design/68723/ssh.html
new file mode 100644
index 0000000..c079e1a
--- /dev/null
+++ b/design/68723/ssh.html
@@ -0,0 +1,2817 @@
+<!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, comment string) (*pem.Block, error)</a></li>
+ <li><a href="#MarshalPrivateKeyWithPassphrase">func MarshalPrivateKeyWithPassphrase(key crypto.PrivateKey, comment string, passphrase []byte) (*pem.Block, error)</a></li>
+ <li><a href="#ParseRawPrivateKey">func ParseRawPrivateKey(pemBytes []byte) (crypto.Signer, error)</a></li>
+ <li><a href="#ParseRawPrivateKeyWithPassphrase">func ParseRawPrivateKeyWithPassphrase(pemBytes, passphrase []byte) (crypto.Signer, 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="#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="#PublicKey">type PublicKey</a>
+ <ul>
+ <li><a href="#NewPublicKey">func NewPublicKey(key interface{}) (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>
+ <li><a href="#ParsePrivateKey">func ParsePrivateKey(pemBytes []byte) (Signer, error)</a></li>
+ <li><a href="#ParsePrivateKeyWithPassphrase">func ParsePrivateKeyWithPassphrase(pemBytes, passphrase []byte) (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">comment</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="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="MarshalPrivateKeyWithPassphrase">func MarshalPrivateKeyWithPassphrase</h3>
+ <pre class="chroma"><span class="kd">func</span> <span class="nf">MarshalPrivateKeyWithPassphrase</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">comment</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><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="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>MarshalPrivateKeyWithPassphrase returns a PEM block holding the encrypted
+private key serialized in the OpenSSH format.
+<h3 id="ParseRawPrivateKey">func ParseRawPrivateKey</h3>
+ <pre class="chroma"><span class="kd">func</span> <span class="nf">ParseRawPrivateKey</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><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> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
+ <p>ParseRawPrivateKey returns a private key 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.
+<h3 id="ParseRawPrivateKeyWithPassphrase">func ParseRawPrivateKeyWithPassphrase</h3>
+ <pre class="chroma"><span class="kd">func</span> <span class="nf">ParseRawPrivateKeyWithPassphrase</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><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> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a><span class="p">)</span></pre>
+ <p>ParseRawPrivateKeyWithPassphrase returns a private key decrypted with
+passphrase from a PEM encoded private key. If the passphrase is wrong, it
+will return x509.IncorrectPasswordError.
+<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="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="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> <span class="kd">interface</span><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, *dsa.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.
+<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><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>ParsePrivateKey returns a Signer from a PEM encoded private key. It supports
+the same keys as ParseRawPrivateKey. 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><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>ParsePrivateKeyWithPassphrase returns a Signer from a PEM encoded private
+key and passphrase. It supports the same keys as
+ParseRawPrivateKeyWithPassphrase.
+<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>