diff options
| author | Nicola Murino <nicola.murino@gmail.com> | 2024-08-19 08:11:17 +0000 |
|---|---|---|
| committer | Gopher Robot <gobot@golang.org> | 2024-08-22 07:31:38 +0000 |
| commit | 03924127659c5fb14e9f06f77df82d10a31098b3 (patch) | |
| tree | 1b7e12b7eb195f8c3aa0fea26cbb24139f7e0a98 /design/68723/agent/agent.html | |
| parent | 54d6775ff71ccbc00c276db2a4e4841d67011cf4 (diff) | |
| download | go-x-proposal-03924127659c5fb14e9f06f77df82d10a31098b3.tar.xz | |
design/68723-crypto-ssh-v2.md: new proposal
For golang/go#68723
Updates golang/go#65269
Change-Id: Ied7a96ab990abe257c4b8c295e292f92a745a4a7
GitHub-Last-Rev: 33f25ddbfaf1d9b13300202c735801beef284c07
GitHub-Pull-Request: golang/proposal#51
Reviewed-on: https://go-review.googlesource.com/c/proposal/+/602855
Commit-Queue: Nicola Murino <nicola.murino@gmail.com>
Reviewed-by: Nicola Murino <nicola.murino@gmail.com>
Auto-Submit: Nicola Murino <nicola.murino@gmail.com>
Diffstat (limited to 'design/68723/agent/agent.html')
| -rw-r--r-- | design/68723/agent/agent.html | 846 |
1 files changed, 846 insertions, 0 deletions
diff --git a/design/68723/agent/agent.html b/design/68723/agent/agent.html new file mode 100644 index 0000000..51f95b6 --- /dev/null +++ b/design/68723/agent/agent.html @@ -0,0 +1,846 @@ +<!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>agent</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 agent</h2> +<pre class="chroma"><span class="kn">import</span> <span class="s">"golang.org/x/crypto/ssh/agent"</span></pre> +<p>Package agent implements the ssh-agent protocol, and provides both +a client and a server. The client can talk to a standard ssh-agent +that uses UNIX sockets, and one could implement an alternative +ssh-agent process using the sample server. +<p>References: +<pre>[PROTOCOL.agent]: https://tools.ietf.org/html/draft-miller-ssh-agent-14 +</pre> +<h3 id="pkg-index">Index</h3> +<ul> + <li><a href="#pkg-variables">Variables</a></li><li><a href="#ForwardToAgent">func ForwardToAgent(client *ssh.Client, keyring Agent) error</a></li> + <li><a href="#ForwardToRemote">func ForwardToRemote(client *ssh.Client, addr string) error</a></li> + <li><a href="#RequestAgentForwarding">func RequestAgentForwarding(session *ssh.Session) error</a></li> + <li><a href="#ServeAgent">func ServeAgent(agent Agent, c io.ReadWriter) error</a></li> + <li> + <a href="#AddedKey">type AddedKey</a> + </li> + <li> + <a href="#Agent">type Agent</a> + <ul> + <li><a href="#NewKeyring">func NewKeyring() Agent</a></li> + </ul> + </li> + <li> + <a href="#ConstraintExtension">type ConstraintExtension</a> + </li> + <li> + <a href="#ExtendedAgent">type ExtendedAgent</a> + <ul> + <li><a href="#NewClient">func NewClient(rw io.ReadWriter) ExtendedAgent</a></li> + </ul> + </li> + <li> + <a href="#Key">type Key</a> + <ul> + <li><a href="#Key.Marshal">func (k *Key) Marshal() []byte</a></li> + <li><a href="#Key.String">func (k *Key) String() string</a></li> + <li><a href="#Key.Type">func (k *Key) Type() string</a></li> + <li><a href="#Key.Verify">func (k *Key) Verify(data []byte, sig *ssh.Signature) error</a></li> + </ul> + </li> + <li> + <a href="#SignatureFlags">type SignatureFlags</a> + </li> + </ul><h4 id="pkg-examples">Examples</h4> +<ul> + <li><a href="#example-NewClient">NewClient</a></li> + </ul><h3 id="pkg-variables">Variables</h3> + <pre class="chroma"><span class="kd">var</span> <span id="ErrExtensionUnsupported"><span class="nx">ErrExtensionUnsupported</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">"agent: extension unsupported"</span><span class="p">)</span></pre> + <p>ErrExtensionUnsupported indicates that an extension defined in +[PROTOCOL.agent] section 3.8 is unsupported by the agent. Specifically this +error indicates that the agent returned a standard SSH_AGENT_FAILURE message +as the result of a SSH_AGENTC_EXTENSION request. Note that the protocol +specification (and therefore this error) does not distinguish between a +specific extension being unsupported and extensions being unsupported entirely. +<h3 id="pkg-functions">Functions</h3> + <h3 id="ForwardToAgent">func ForwardToAgent</h3> + <pre class="chroma"><span class="kd">func</span> <span class="nf">ForwardToAgent</span><span class="p">(</span><span class="nx">client</span> <span class="o">*</span><a href=".."><span class="nx">ssh</span></a><span class="p">.</span><a href="..#Client"><span class="nx">Client</span></a><span class="p">,</span> <span class="nx">keyring</span> <a href="#Agent"><span class="nx">Agent</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre> + <p>ForwardToAgent routes authentication requests to the given keyring. +<h3 id="ForwardToRemote">func ForwardToRemote</h3> + <pre class="chroma"><span class="kd">func</span> <span class="nf">ForwardToRemote</span><span class="p">(</span><span class="nx">client</span> <span class="o">*</span><a href=".."><span class="nx">ssh</span></a><span class="p">.</span><a href="..#Client"><span class="nx">Client</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> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre> + <p>ForwardToRemote routes authentication requests to the ssh-agent +process serving on the given unix socket. +<h3 id="RequestAgentForwarding">func RequestAgentForwarding</h3> + <pre class="chroma"><span class="kd">func</span> <span class="nf">RequestAgentForwarding</span><span class="p">(</span><span class="nx">session</span> <span class="o">*</span><a href=".."><span class="nx">ssh</span></a><span class="p">.</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></pre> + <p>RequestAgentForwarding sets up agent forwarding for the session. +ForwardToAgent or ForwardToRemote should be called to route +the authentication requests. +<h3 id="ServeAgent">func ServeAgent</h3> + <pre class="chroma"><span class="kd">func</span> <span class="nf">ServeAgent</span><span class="p">(</span><span class="nx">agent</span> <a href="#Agent"><span class="nx">Agent</span></a><span class="p">,</span> <span class="nx">c</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><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a></pre> + <p>ServeAgent serves the agent protocol on the given connection. It +returns when an I/O error occurs. +<h3 id="pkg-types">Types</h3> + <h3 id="AddedKey">type AddedKey</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">AddedKey</span> <span class="kd">struct</span> <span class="p">{</span> + <span class="c1">// PrivateKey must be a *rsa.PrivateKey, *dsa.PrivateKey, +</span><span class="c1"></span> <span class="c1">// ed25519.PrivateKey or *ecdsa.PrivateKey, which will be inserted into the +</span><span class="c1"></span> <span class="c1">// agent. +</span><span class="c1"></span> <span id="AddedKey.PrivateKey"><span class="nx">PrivateKey</span></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="c1">// Certificate, if not nil, is communicated to the agent and will be +</span><span class="c1"></span> <span class="c1">// stored with the key. +</span><span class="c1"></span> <span id="AddedKey.Certificate"><span class="nx">Certificate</span></span> <span class="o">*</span><a href=".."><span class="nx">ssh</span></a><span class="p">.</span><a href="..#Certificate"><span class="nx">Certificate</span></a> + <span class="c1">// Comment is an optional, free-form string. +</span><span class="c1"></span> <span id="AddedKey.Comment"><span class="nx">Comment</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a> + <span class="c1">// LifetimeSecs, if not zero, is the number of seconds that the +</span><span class="c1"></span> <span class="c1">// agent will store the key for. +</span><span class="c1"></span> <span id="AddedKey.LifetimeSecs"><span class="nx">LifetimeSecs</span></span> <a href="https://pkg.go.dev/builtin#uint32"><span class="kt">uint32</span></a> + <span class="c1">// ConfirmBeforeUse, if true, requests that the agent confirm with the +</span><span class="c1"></span> <span class="c1">// user before each use of this key. +</span><span class="c1"></span> <span id="AddedKey.ConfirmBeforeUse"><span class="nx">ConfirmBeforeUse</span></span> <a href="https://pkg.go.dev/builtin#bool"><span class="kt">bool</span></a> + <span class="c1">// ConstraintExtensions are the experimental or private-use constraints +</span><span class="c1"></span> <span class="c1">// defined by users. +</span><span class="c1"></span> <span id="AddedKey.ConstraintExtensions"><span class="nx">ConstraintExtensions</span></span> <span class="p">[]</span><a href="#ConstraintExtension"><span class="nx">ConstraintExtension</span></a> +<span class="p">}</span></pre> + <p>AddedKey describes an SSH key to be added to an Agent. +<h3 id="Agent">type Agent</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">Agent</span> <span class="kd">interface</span> <span class="p">{</span> + <span class="c1">// List returns the identities known to the agent. +</span><span class="c1"></span> <span id="Agent.List"><span class="nf">List</span></span><span class="p">()</span> <span class="p">([]</span><span class="o">*</span><a href="#Key"><span class="nx">Key</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">// Sign has the agent sign the data using a protocol 2 key as defined in +</span><span class="c1"></span> <span class="c1">// [PROTOCOL.agent] section 3.6. This method is also implemented in +</span><span class="c1"></span> <span class="c1">// [ssh.Signer] interface. +</span><span class="c1"></span> <span id="Agent.Sign"><span class="nf">Sign</span></span><span class="p">(</span><span class="nx">key</span> <a href=".."><span class="nx">ssh</span></a><span class="p">.</span><a href="..#PublicKey"><span class="nx">PublicKey</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=".."><span class="nx">ssh</span></a><span class="p">.</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">// SignWithFlags signs like Sign, but allows for additional flags to be +</span><span class="c1"></span> <span class="c1">// sent/received. See [PROTOCOL.agent] section 3.6.1. +</span><span class="c1"></span> <span id="Agent.SignWithFlags"><span class="nf">SignWithFlags</span></span><span class="p">(</span><span class="nx">key</span> <a href=".."><span class="nx">ssh</span></a><span class="p">.</span><a href="..#PublicKey"><span class="nx">PublicKey</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">flags</span> <a href="#SignatureFlags"><span class="nx">SignatureFlags</span></a><span class="p">)</span> <span class="p">(</span><span class="o">*</span><a href=".."><span class="nx">ssh</span></a><span class="p">.</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">// Add adds a private key to the agent. +</span><span class="c1"></span> <span id="Agent.Add"><span class="nf">Add</span></span><span class="p">(</span><span class="nx">key</span> <a href="#AddedKey"><span class="nx">AddedKey</span></a><span class="p">)</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a> + + <span class="c1">// Remove removes all identities with the given public key. +</span><span class="c1"></span> <span id="Agent.Remove"><span class="nf">Remove</span></span><span class="p">(</span><span class="nx">key</span> <a href=".."><span class="nx">ssh</span></a><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="c1">// RemoveAll removes all identities. +</span><span class="c1"></span> <span id="Agent.RemoveAll"><span class="nf">RemoveAll</span></span><span class="p">()</span> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a> + + <span class="c1">// Lock locks the agent. Sign and Remove will fail, and List will empty an empty list. +</span><span class="c1"></span> <span id="Agent.Lock"><span class="nf">Lock</span></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> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a> + + <span class="c1">// Unlock undoes the effect of Lock +</span><span class="c1"></span> <span id="Agent.Unlock"><span class="nf">Unlock</span></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> <a href="https://pkg.go.dev/builtin#error"><span class="kt">error</span></a> + + <span class="c1">// Signers returns signers for all the known keys. +</span><span class="c1"></span> <span id="Agent.Signers"><span class="nf">Signers</span></span><span class="p">()</span> <span class="p">([]</span><a href=".."><span class="nx">ssh</span></a><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> +<span class="p">}</span></pre> + <p>Agent represents the capabilities of an ssh-agent. +<h4 id="NewKeyring">func NewKeyring</h4> + <pre class="chroma"><span class="kd">func</span> <span class="nf">NewKeyring</span><span class="p">()</span> <a href="#Agent"><span class="nx">Agent</span></a></pre> + <p>NewKeyring returns an Agent that holds keys in memory. It is safe +for concurrent use by multiple goroutines. +<h3 id="ConstraintExtension">type ConstraintExtension</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">ConstraintExtension</span> <span class="kd">struct</span> <span class="p">{</span> + <span class="c1">// ExtensionName consist of a UTF-8 string suffixed by the +</span><span class="c1"></span> <span class="c1">// implementation domain following the naming scheme defined +</span><span class="c1"></span> <span class="c1">// in Section 4.2 of RFC 4251, e.g. "foo@example.com". +</span><span class="c1"></span> <span id="ConstraintExtension.ExtensionName"><span class="nx">ExtensionName</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a> + <span class="c1">// ExtensionDetails contains the actual content of the extended +</span><span class="c1"></span> <span class="c1">// constraint. +</span><span class="c1"></span> <span id="ConstraintExtension.ExtensionDetails"><span class="nx">ExtensionDetails</span></span> <span class="p">[]</span><a href="https://pkg.go.dev/builtin#byte"><span class="kt">byte</span></a> +<span class="p">}</span></pre> + <p>ConstraintExtension describes an optional constraint defined by users. +<h3 id="ExtendedAgent">type ExtendedAgent</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">ExtendedAgent</span> <span class="kd">interface</span> <span class="p">{</span> + <a href="#Agent"><span class="nx">Agent</span></a> + + <span class="c1">// Extension processes a custom extension request. Standard-compliant agents are not +</span><span class="c1"></span> <span class="c1">// required to support any extensions, but this method allows agents to implement +</span><span class="c1"></span> <span class="c1">// vendor-specific methods or add experimental features. See [PROTOCOL.agent] section 3.8. +</span><span class="c1"></span> <span class="c1">// If agent extensions are unsupported entirely this method MUST return an +</span><span class="c1"></span> <span class="c1">// ErrExtensionUnsupported error. Similarly, if just the specific extensionType in +</span><span class="c1"></span> <span class="c1">// the request is unsupported by the agent then ErrExtensionUnsupported MUST be +</span><span class="c1"></span> <span class="c1">// returned. +</span><span class="c1"></span> <span class="c1">// +</span><span class="c1"></span> <span class="c1">// In the case of success, since [PROTOCOL.agent] section 3.8 specifies that the contents +</span><span class="c1"></span> <span class="c1">// of the response are unspecified (including the type of the message), the complete +</span><span class="c1"></span> <span class="c1">// response will be returned as a []byte slice, including the "type" byte of the message. +</span><span class="c1"></span> <span id="ExtendedAgent.Extension"><span class="nf">Extension</span></span><span class="p">(</span><span class="nx">extensionType</span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a><span class="p">,</span> <span class="nx">contents</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="p">}</span></pre> + <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">rw</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><span class="p">)</span> <a href="#ExtendedAgent"><span class="nx">ExtendedAgent</span></a></pre> + <p>NewClient returns an Agent that talks to an ssh-agent process over +the given connection. +<details id="example-NewClient" 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">"context"</span> + <span class="s">"log"</span> + <span class="s">"net"</span> + <span class="s">"os"</span> + + <span class="s">"golang.org/x/crypto/ssh"</span> + <span class="s">"golang.org/x/crypto/ssh/agent"</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">// ssh-agent(1) provides a UNIX socket at $SSH_AUTH_SOCK. +</span><span class="c1"></span> <span class="nx">socket</span> <span class="o">:=</span> <span class="nx">os</span><span class="p">.</span><span class="nf">Getenv</span><span class="p">(</span><span class="s">"SSH_AUTH_SOCK"</span><span class="p">)</span> + <span class="nx">conn</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">"unix"</span><span class="p">,</span> <span class="nx">socket</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">"Failed to open SSH_AUTH_SOCK: %v"</span><span class="p">,</span> <span class="nx">err</span><span class="p">)</span> + <span class="p">}</span> + + <span class="nx">agentClient</span> <span class="o">:=</span> <span class="nx">agent</span><span class="p">.</span><span class="nf">NewClient</span><span class="p">(</span><span class="nx">conn</span><span class="p">)</span> + <span class="nx">config</span> <span class="o">:=</span> <span class="o">&</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">"gopher"</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 a callback rather than PublicKeys so we only consult the +</span><span class="c1"></span> <span class="c1">// agent once the remote server wants it. +</span><span class="c1"></span> <span class="nx">ssh</span><span class="p">.</span><span class="nf">PublicKeysCallback</span><span class="p">(</span><span class="nx">agentClient</span><span class="p">.</span><span class="nx">Signers</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">InsecureIgnoreHostKey</span><span class="p">(),</span> + <span class="p">}</span> + + <span class="nx">sshc</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">"tcp"</span><span class="p">,</span> <span class="s">"localhost:22"</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="c1">// Use sshc... +</span><span class="c1"></span> <span class="nx">sshc</span><span class="p">.</span><span class="nf">Close</span><span class="p">()</span> +<span class="p">}</span></pre> + </details> + <h3 id="Key">type Key</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">Key</span> <span class="kd">struct</span> <span class="p">{</span> + <span id="Key.Format"><span class="nx">Format</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a> + <span id="Key.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="Key.Comment"><span class="nx">Comment</span></span> <a href="https://pkg.go.dev/builtin#string"><span class="kt">string</span></a> +<span class="p">}</span></pre> + <p>Key represents a protocol 2 public key as defined in +[PROTOCOL.agent], section 3.3. +<h4 id="Key.Marshal">func (*Key) Marshal</h4> + <pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">k</span> <span class="o">*</span><a href="#Key"><span class="nx">Key</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 returns key blob to satisfy the ssh.PublicKey interface. +<h4 id="Key.String">func (*Key) String</h4> + <pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">k</span> <span class="o">*</span><a href="#Key"><span class="nx">Key</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 returns the storage form of an agent key with the format, base64 +encoded serialized key, and the comment if it is not empty. +<h4 id="Key.Type">func (*Key) Type</h4> + <pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">k</span> <span class="o">*</span><a href="#Key"><span class="nx">Key</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 public key type. +<h4 id="Key.Verify">func (*Key) Verify</h4> + <pre class="chroma"><span class="kd">func</span> <span class="p">(</span><span class="nx">k</span> <span class="o">*</span><a href="#Key"><span class="nx">Key</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=".."><span class="nx">ssh</span></a><span class="p">.</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 satisfies the ssh.PublicKey interface. +<h3 id="SignatureFlags">type SignatureFlags</h3> + <pre class="chroma"><span class="kd">type</span> <span class="nx">SignatureFlags</span> <a href="https://pkg.go.dev/builtin#uint32"><span class="kt">uint32</span></a></pre> + <p>SignatureFlags represent additional flags that can be passed to the signature +requests an defined in [PROTOCOL.agent] section 3.6.1. +<pre class="chroma"><span class="kd">const</span> <span class="p">(</span> + <span id="SignatureFlagReserved"><span class="nx">SignatureFlagReserved</span></span> <a href="#SignatureFlags"><span class="nx">SignatureFlags</span></a> <span class="p">=</span> <span class="mi">1</span> <span class="o"><<</span> <a href="https://pkg.go.dev/builtin#iota"><span class="kc">iota</span></a> + <span id="SignatureFlagRsaSha256"><span class="nx">SignatureFlagRsaSha256</span></span> + <span id="SignatureFlagRsaSha512"><span class="nx">SignatureFlagRsaSha512</span></span> +<span class="p">)</span></pre> + <p>SignatureFlag values as defined in [PROTOCOL.agent] section 5.3. +</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 + '">¶</a>' + }) + + document.querySelectorAll("details.example > summary").forEach((el) => { + let id = el.parentElement.id; + if (!id) { + return + } + el.innerHTML += ' <a class="permalink" href="#' + id + '">¶</a>' + }) + + openDetailsAnchor() + }) + </script> + </body> +</html> |
