File: AppendixH.html

package info (click to toggle)
putty 0.83-3
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 13,216 kB
  • sloc: ansic: 148,476; python: 8,466; perl: 1,830; makefile: 128; sh: 117
file content (459 lines) | stat: -rw-r--r-- 26,378 bytes parent folder | download
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
277
278
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
378
379
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
402
403
404
405
406
407
408
409
410
411
412
413
414
415
416
417
418
419
420
421
422
423
424
425
426
427
428
429
430
431
432
433
434
435
436
437
438
439
440
441
442
443
444
445
446
447
448
449
450
451
452
453
454
455
456
457
458
459
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN"
"http://www.w3.org/TR/html4/strict.dtd">
<html>
<head>
<meta http-equiv="content-type" content="text/html; charset=US-ASCII">
<title>PuTTY authentication plugin protocol</title>
<link rel="previous" href="AppendixG.html">
<link rel="ToC" href="index.html">
<link rel="up" href="index.html">
<link rel="index" href="IndexPage.html">
<link rel="next" href="AppendixI.html">
</head>
<body>
<p><a href="AppendixG.html">Previous</a> | <a href="index.html">Contents</a> | <a href="IndexPage.html">Index</a> | <a href="AppendixI.html">Next</a></p>

<ul>
<li><a href="#authplugin">Appendix H: PuTTY authentication plugin protocol</a>
<ul>
<li><a href="#authplugin-req">H.1 Requirements</a></li>
<li><a href="#authplugin-transport">H.2 Transport and configuration</a></li>
<li><a href="#authplugin-formats">H.3 Data formats and marshalling</a></li>
<li><a href="#authplugin-version">H.4 Protocol versioning</a></li>
<li><a href="#authplugin-overview">H.5 Overview and sequence of events</a></li>
<li><a href="#authplugin-messages">H.6 Message formats</a>
<ul>
<li><a href="#PLUGIN_INIT">H.6.1 <code>PLUGIN_INIT</code></a></li>
<li><a href="#PLUGIN_INIT_RESPONSE">H.6.2 <code>PLUGIN_INIT_RESPONSE</code></a></li>
<li><a href="#PLUGIN_INIT_FAILURE">H.6.3 <code>PLUGIN_INIT_FAILURE</code></a></li>
<li><a href="#PLUGIN_PROTOCOL">H.6.4 <code>PLUGIN_PROTOCOL</code></a></li>
<li><a href="#PLUGIN_PROTOCOL_REJECT">H.6.5 <code>PLUGIN_PROTOCOL_REJECT</code></a></li>
<li><a href="#PLUGIN_PROTOCOL_ACCEPT">H.6.6 <code>PLUGIN_PROTOCOL_ACCEPT</code></a></li>
<li><a href="#PLUGIN_KI_SERVER_REQUEST">H.6.7 <code>PLUGIN_KI_SERVER_REQUEST</code></a></li>
<li><a href="#PLUGIN_KI_SERVER_RESPONSE">H.6.8 <code>PLUGIN_KI_SERVER_RESPONSE</code></a></li>
<li><a href="#PLUGIN_KI_USER_REQUEST">H.6.9 <code>PLUGIN_KI_USER_REQUEST</code></a></li>
<li><a href="#PLUGIN_KI_USER_RESPONSE">H.6.10 <code>PLUGIN_KI_USER_RESPONSE</code></a></li>
<li><a href="#PLUGIN_AUTH_SUCCESS">H.6.11 <code>PLUGIN_AUTH_SUCCESS</code></a></li>
<li><a href="#PLUGIN_AUTH_FAILURE">H.6.12 <code>PLUGIN_AUTH_FAILURE</code></a></li>
</ul></li>
<li><a href="#authplugin-refs">H.7 References</a></li>
</ul></li>
</ul>
<h1><a name="authplugin"></a><a name="AH"></a>Appendix H: PuTTY authentication plugin protocol</h1>
<p>
This appendix contains the specification for the protocol spoken over local IPC between PuTTY and an authentication helper plugin.
</p>
<p>
If you already have an authentication plugin and want to configure PuTTY to use it, see <a href="Chapter4.html#config-ssh-authplugin">section 4.22.3</a> for how to do that. This appendix is for people writing new authentication plugins.
</p>
<h2><a name="authplugin-req"></a><a name="SH.1"></a>H.1 Requirements</h2>
<p>
The following requirements informed the specification of this protocol.
</p>
<p>
<strong>Automate keyboard-interactive authentication.</strong> We're motivated in the first place by the observation that the general SSH userauth method &#8216;<code>keyboard-interactive</code>&#8217; (defined in <a href="#p1">[RFC4256]</a>) can be used for many kinds of challenge/response or one-time-password styles of authentication, and in more than one of those, the necessary responses might be obtained from an auxiliary network connection, such as an HTTPS transaction. So it's useful if a user doesn't have to manually copy-type or copy-paste from their web browser into their SSH client, but instead, the process can be automated.
</p>
<p>
<strong>Be able to pass prompts on to the user.</strong> On the other hand, some userauth methods can be only <em>partially</em> automated; some of the server's prompts might still require human input. Also, the plugin automating the authentication might need to ask its own questions that are not provided by the SSH server. (For example, &#8216;please enter the master key that the real response will be generated by hashing&#8217;.) So after the plugin intercepts the server's questions, it needs to be able to ask its own questions of the user, which may or may not be the same questions sent by the server.
</p>
<p>
<strong>Allow automatic generation of the username.</strong> Sometimes, the authentication method comes with a mechanism for discovering the username to be used in the SSH login. So the plugin has to start up early enough that the client hasn't committed to a username yet.
</p>
<p>
<strong>Future expansion route to other SSH userauth flavours.</strong> The initial motivation for this protocol is specific to keyboard-interactive. But other SSH authentication methods exist, and they may also benefit from automation in future. We're making no attempt here to predict what those methods might be or how they might be automated, but we do need to leave a space where they can be slotted in later if necessary.
</p>
<p>
<strong>Minimal information loss.</strong> Keyboard-interactive prompts and replies should be passed to and from the plugin in a form as close as possible to the way they look on the wire in SSH itself. Therefore, the protocol resembles SSH in its data formats and marshalling (instead of, for example, translating from SSH binary packet style to another well-known format such as JSON, which would introduce edge cases in character encoding).
</p>
<p>
<strong>Half-duplex.</strong> Simultaneously trying to read one I/O stream and write another adds a lot of complexity to software. It becomes necessary to have an organised event loop containing <code>select</code> or <code>WaitForMultipleObjects</code> or similar, which can invoke the handler for whichever event happens soonest. There's no need to add that complexity in an application like this, which isn't transferring large amounts of bulk data or multiplexing unrelated activities. So, to keep life simple for plugin authors, we set the ground rule that it must always be 100% clear which side is supposed to be sending a message next. That way, the plugin can be written as sequential code progressing through the protocol, making simple read and write calls to receive or send each message.
</p>
<p>
<strong>Communicate success/failure, to facilitate caching in the plugin.</strong> A plugin might want to cache recently used data for next time, but only in the case where authentication using that data was actually successful. So the client has to tell the plugin what the outcome was, if it's known. (But this is best-effort only. Obviously the plugin cannot <em>depend</em> on hearing the answer, because any IPC protocol at all carries the risk that the other end might crash or be killed by things outside its control.)
</p>
<h2><a name="authplugin-transport"></a><a name="SH.2"></a>H.2 Transport and configuration</h2>
<p>
Plugins are executable programs on the client platform.
</p>
<p>
The SSH client must be manually configured to use a plugin for a particular connection. The configuration takes the form of a command line, including the location of the plugin executable, and optionally command-line arguments that are meaningful to the particular plugin.
</p>
<p>
The client invokes the plugin as a subprocess, passing it a pair of 8-bit-clean pipes as its standard input and output. On those pipes, the client and plugin will communicate via the protocol specified below.
</p>
<h2><a name="authplugin-formats"></a><a name="SH.3"></a>H.3 Data formats and marshalling</h2>
<p>
This protocol borrows the low-level data formatting from SSH itself, in particular the following wire encodings from <a href="#p0">[RFC4251]</a> section 5:
</p>
<dl><dt>
<strong>byte</strong>
</dt>
<dd>
An integer between 0 and 0xFF inclusive, transmitted as a single byte of binary data.
</dd>
<dt>
<strong>boolean</strong>
</dt>
<dd>
The values &#8216;true&#8217; or &#8216;false&#8217;, transmitted as the bytes 1 and 0 respectively.
</dd>
<dt>
<strong>uint32</strong>
</dt>
<dd>
An integer between 0 and 0xFFFFFFFF inclusive, transmitted as 4 bytes of binary data, in big-endian (&#8216;network&#8217;) byte order.
</dd>
<dt>
<strong>string</strong>
</dt>
<dd>
A sequence of bytes, preceded by a <strong>uint32</strong> giving the number of bytes in the sequence. The length field does not include itself. For example, the empty string is represented by four zero bytes (the <strong>uint32</strong> encoding of 0); the string "AB" is represented by the six bytes 0,0,0,2,'A','B'.
</dd>
</dl>
<p>
Unlike SSH itself, the protocol spoken between the client and the plugin is unencrypted, because local inter-process pipes are assumed to be secured by the OS kernel. So the binary packet protocol is much simpler than SSH proper, and is similar to SFTP and the OpenSSH agent protocol.
</p>
<p>
The data sent in each direction of the conversation consists of a sequence of <strong>messages</strong> exchanged between the SSH client and the plugin. Each message is encoded as a <strong>string</strong>. The contents of the string begin with a <strong>byte</strong> giving the message type, which determines the format of the rest of the message.
</p>
<h2><a name="authplugin-version"></a><a name="SH.4"></a>H.4 Protocol versioning</h2>
<p>
This protocol itself is versioned. At connection setup, the client states the highest version number it knows how to speak, and then the plugin responds by choosing the version number that will actually be spoken (which may not be higher than the client's value).
</p>
<p>
Including a version number makes it possible to make breaking changes to the protocol later.
</p>
<p>
Even version numbers represent released versions of this spec. Odd numbers represent drafts or development versions in between releases. A client and plugin negotiating an odd version number are not guaranteed to interoperate; the developer testing the combination is responsible for ensuring the two are compatible.
</p>
<p>
This document describes version 2 of the protocol, the first released version. (The initial drafts had version 1.)
</p>
<h2><a name="authplugin-overview"></a><a name="SH.5"></a>H.5 Overview and sequence of events</h2>
<p>
At the very beginning of the user authentication phase of SSH, the client launches the plugin subprocess, if one is configured. It immediately sends the <code>PLUGIN_INIT</code> message, telling the plugin some initial information about where the SSH connection is to.
</p>
<p>
The plugin responds with <code>PLUGIN_INIT_RESPONSE</code>, which may optionally tell the SSH client what username to use.
</p>
<p>
The client begins trying to authenticate with the SSH server in the usual way, using the username provided by the plugin (if any) or alternatively one obtained via its normal (non-plugin) policy.
</p>
<p>
The client follows its normal policy for selecting authentication methods to attempt. If it chooses a method that this protocol does not cover, then the client will perform that method in its own way without consulting the plugin.
</p>
<p>
However, if the client and server decide to attempt a method that this protocol <em>does</em> cover, then the client sends <code>PLUGIN_PROTOCOL</code> specifying the SSH protocol id for the authentication method being used. The plugin responds with <code>PLUGIN_PROTOCOL_ACCEPT</code> if it's willing to assist with this auth method, or <code>PLUGIN_PROTOCOL_REJECT</code> if it isn't.
</p>
<p>
If the plugin sends <code>PLUGIN_PROTOCOL_REJECT</code>, then the client will proceed as if the plugin were not present. Later, if another auth method is negotiated (either because this one failed, or because it succeeded but the server wants multiple auth methods), the client may send a further <code>PLUGIN_PROTOCOL</code> and try again.
</p>
<p>
If the plugin sends <code>PLUGIN_PROTOCOL_ACCEPT</code>, then a protocol segment begins that is specific to that auth method, terminating in either <code>PLUGIN_AUTH_SUCCESS</code> or <code>PLUGIN_AUTH_FAILURE</code>. After that, again, the client may send a further <code>PLUGIN_PROTOCOL</code>.
</p>
<p>
Currently the only supported method is &#8216;<code>keyboard-interactive</code>&#8217;, defined in <a href="#p1">[RFC4256]</a>. Once the client has announced this to the server, the followup protocol is as follows:
</p>
<p>
Each time the server sends an <code>SSH_MSG_USERAUTH_INFO_REQUEST</code> message requesting authentication responses from the user, the SSH client translates the message into <code>PLUGIN_KI_SERVER_REQUEST</code> and passes it on to the plugin.
</p>
<p>
At this point, the plugin may optionally send back <code>PLUGIN_KI_USER_REQUEST</code> containing prompts to be presented to the actual user. The client will reply with a matching <code>PLUGIN_KI_USER_RESPONSE</code> after asking the user to reply to the question(s) in the request message. The plugin can repeat this cycle multiple times.
</p>
<p>
Once the plugin has all the information it needs to respond to the server's authentication prompts, it sends <code>PLUGIN_KI_SERVER_RESPONSE</code> back to the client, which translates it into <code>SSH_MSG_USERAUTH_INFO_RESPONSE</code> to send on to the server.
</p>
<p>
After that, as described in <a href="#p1">[RFC4256]</a>, the server is free to accept authentication, reject it, or send another <code>SSH_MSG_USERAUTH_INFO_REQUEST</code>. Each <code>SSH_MSG_USERAUTH_INFO_REQUEST</code> is dealt with in the same way as above.
</p>
<p>
If the server terminates keyboard-interactive authentication with <code>SSH_MSG_USERAUTH_SUCCESS</code> or <code>SSH_MSG_USERAUTH_FAILURE</code>, the client informs the plugin by sending either <code>PLUGIN_AUTH_SUCCESS</code> or <code>PLUGIN_AUTH_FAILURE</code>. <code>PLUGIN_AUTH_SUCCESS</code> is sent when <em>that particular authentication method</em> was successful, regardless of whether the SSH server chooses to request further authentication afterwards: in particular, <code>SSH_MSG_USERAUTH_FAILURE</code> with the &#8216;partial success&#8217; flag (see <a href="#p2">[RFC4252]</a> section 5.1) translates into <code>PLUGIN_AUTH_SUCCESS</code>.
</p>
<p>
The plugin's standard input will close when the client no longer requires the plugin's services, for any reason. This could be because authentication is complete (with overall success or overall failure), or because the user has manually aborted the session in mid-authentication, or because the client crashed.
</p>
<h2><a name="authplugin-messages"></a><a name="SH.6"></a>H.6 Message formats</h2>
<p>
This section describes the format of every message in the protocol.
</p>
<p>
As described in <a href="#authplugin-formats">section H.3</a>, every message starts with the same two fields:
</p>
<ul><li>
<strong>uint32</strong>: overall length of the message
</li>
<li>
<strong>byte</strong>: message type.
</li>
</ul>
<p>
The length field does not include itself, but does include the type code.
</p>
<p>
The following subsections each give the format of the remainder of the message, after the type code.
</p>
<p>
The type codes themselves are defined here:
</p>
<pre><code>#define PLUGIN_INIT                   1
#define PLUGIN_INIT_RESPONSE          2
#define PLUGIN_PROTOCOL               3
#define PLUGIN_PROTOCOL_ACCEPT        4
#define PLUGIN_PROTOCOL_REJECT        5
#define PLUGIN_AUTH_SUCCESS           6
#define PLUGIN_AUTH_FAILURE           7
#define PLUGIN_INIT_FAILURE           8

#define PLUGIN_KI_SERVER_REQUEST     20
#define PLUGIN_KI_SERVER_RESPONSE    21
#define PLUGIN_KI_USER_REQUEST       22
#define PLUGIN_KI_USER_RESPONSE      23
</code></pre>
<p>
If this protocol is extended to be able to assist with further auth methods, their message type codes will also begin from 20, overlapping the codes for keyboard-interactive.
</p>
<h3><a name="PLUGIN_INIT"></a><a name="SH.6.1"></a>H.6.1 <code>PLUGIN_INIT</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: the first message sent at connection startup
</p>
<p>
<strong>What happens next</strong>: the plugin will send <code>PLUGIN_INIT_RESPONSE</code> or <code>PLUGIN_INIT_FAILURE</code>
</p>
<p>
<strong>Message contents after the type code</strong>:
</p>
<ul><li>
<strong>uint32</strong>: the highest version number of this protocol that the client knows how to speak.
</li>
<li>
<strong>string</strong>: the hostname of the server. This will be the <em>logical</em> hostname, in cases where it differs from the physical destination of the network connection. Whatever name would be used by the SSH client to cache the server's host key, that's the same name passed in this message.
</li>
<li>
<strong>uint32</strong>: the port number on the server. (Together with the host name, this forms a primary key identifying a particular server. Port numbers may be vital because a single host can run two unrelated SSH servers with completely different authentication requirements, e.g. system sshd on port 22 and Gerrit on port 29418.)
</li>
<li>
<strong>string</strong>: the username that the client will use to log in, if the plugin chooses not to override it. An empty string means that the client has no opinion about this (and might, for example, prompt the user).
</li>
</ul>
<h3><a name="PLUGIN_INIT_RESPONSE"></a><a name="SH.6.2"></a>H.6.2 <code>PLUGIN_INIT_RESPONSE</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: response to <code>PLUGIN_INIT</code>
</p>
<p>
<strong>What happens next</strong>: the client will send <code>PLUGIN_PROTOCOL</code>, or perhaps terminate the session (if no auth method is ever negotiated that the plugin can help with)
</p>
<p>
<strong>Message contents after the type code</strong>:
</p>
<ul><li>
<strong>uint32</strong>: the version number of this protocol that the connection will use. Must be no greater than the max version number sent by the client in <code>PLUGIN_INIT</code>.
</li>
<li>
<strong>string</strong>: the username that the plugin suggests the client use. An empty string means that the plugin has no opinion and the client should stick with the username it already had (or prompt the user, if it had none).
</li>
</ul>
<h3><a name="PLUGIN_INIT_FAILURE"></a><a name="SH.6.3"></a>H.6.3 <code>PLUGIN_INIT_FAILURE</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: response to <code>PLUGIN_INIT</code>
</p>
<p>
<strong>What happens next</strong>: the session is over
</p>
<p>
<strong>Message contents after the type code</strong>:
</p>
<ul><li>
<strong>string</strong>: an error message to present to the user indicating why the plugin was unable to start up.
</li>
</ul>
<h3><a name="PLUGIN_PROTOCOL"></a><a name="SH.6.4"></a>H.6.4 <code>PLUGIN_PROTOCOL</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_INIT_RESPONSE</code>, or after a previous auth phase terminates with <code>PLUGIN_AUTH_SUCCESS</code> or <code>PLUGIN_AUTH_FAILURE</code>
</p>
<p>
<strong>What happens next</strong>: the plugin will send <code>PLUGIN_PROTOCOL_ACCEPT</code> or <code>PLUGIN_PROTOCOL_REJECT</code>
</p>
<p>
<strong>Message contents after the type code</strong>:
</p>
<ul><li>
<strong>string</strong>: the SSH protocol id of the auth method the client intends to attempt. Currently the only method specified for use in this protocol is &#8216;<code>keyboard-interactive</code>&#8217;.
</li>
</ul>
<h3><a name="PLUGIN_PROTOCOL_REJECT"></a><a name="SH.6.5"></a>H.6.5 <code>PLUGIN_PROTOCOL_REJECT</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_PROTOCOL</code>
</p>
<p>
<strong>What happens next</strong>: the client will either send another <code>PLUGIN_PROTOCOL</code> or terminate the session
</p>
<p>
<strong>Message contents after the type code</strong>:
</p>
<ul><li>
<strong>string</strong>: an error message to present to the user, explaining why the plugin cannot help with this authentication protocol.
<p>
An example might be &#8216;unable to open &lt;config file&gt;: &lt;OS error message&gt;&#8217;, if the plugin depends on some configuration that the user has not set up.
</p>
<p>
If the plugin does not support this this particular authentication protocol at all, this string should be left blank, so that no message will be presented to the user at all.
</p>

</li>
</ul>
<h3><a name="PLUGIN_PROTOCOL_ACCEPT"></a><a name="SH.6.6"></a>H.6.6 <code>PLUGIN_PROTOCOL_ACCEPT</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_PROTOCOL</code>
</p>
<p>
<strong>What happens next</strong>: depends on the auth protocol agreed on. For keyboard-interactive, the client will send <code>PLUGIN_KI_SERVER_REQUEST</code> or <code>PLUGIN_AUTH_SUCCESS</code> or <code>PLUGIN_AUTH_FAILURE</code>. No other method is specified.
</p>
<p>
<strong>Message contents after the type code</strong>: none.
</p>
<h3><a name="PLUGIN_KI_SERVER_REQUEST"></a><a name="SH.6.7"></a>H.6.7 <code>PLUGIN_KI_SERVER_REQUEST</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_PROTOCOL</code>, or after a previous <code>PLUGIN_KI_SERVER_RESPONSE</code>, when the SSH server has sent <code>SSH_MSG_USERAUTH_INFO_REQUEST</code>
</p>
<p>
<strong>What happens next</strong>: the plugin will send either <code>PLUGIN_KI_USER_REQUEST</code> or <code>PLUGIN_KI_SERVER_RESPONSE</code>
</p>
<p>
<strong>Message contents after the type code</strong>: the exact contents of the <code>SSH_MSG_USERAUTH_INFO_REQUEST</code> just sent by the server. See <a href="#p1">[RFC4256]</a> section 3.2 for details. The summary:
</p>
<ul><li>
<strong>string</strong>: name of this prompt collection (e.g. to use as a dialog-box title)
</li>
<li>
<strong>string</strong>: instructions to be displayed before this prompt collection
</li>
<li>
<strong>string</strong>: language tag (deprecated)
</li>
<li>
<strong>uint32</strong>: number of prompts in this collection
</li>
<li>
That many copies of:
<ul><li>
<strong>string</strong>: prompt (in UTF-8)
</li>
<li>
<strong>boolean</strong>: whether the response to this prompt is safe to echo to the screen
</li>
</ul>

</li>
</ul>
<h3><a name="PLUGIN_KI_SERVER_RESPONSE"></a><a name="SH.6.8"></a>H.6.8 <code>PLUGIN_KI_SERVER_RESPONSE</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: response to <code>PLUGIN_KI_SERVER_REQUEST</code>, perhaps after one or more intervening pairs of <code>PLUGIN_KI_USER_REQUEST</code> and <code>PLUGIN_KI_USER_RESPONSE</code>
</p>
<p>
<strong>What happens next</strong>: the client will send a further <code>PLUGIN_KI_SERVER_REQUEST</code>, or <code>PLUGIN_AUTH_SUCCESS</code> or <code>PLUGIN_AUTH_FAILURE</code>
</p>
<p>
<strong>Message contents after the type code</strong>: the exact contents of the <code>SSH_MSG_USERAUTH_INFO_RESPONSE</code> that the client should send back to the server. See <a href="#p1">[RFC4256]</a> section 3.4 for details. The summary:
</p>
<ul><li>
<strong>uint32</strong>: number of responses (must match the &#8216;number of prompts&#8217; field from the corresponding server request)
</li>
<li>
That many copies of:
<ul><li>
<strong>string</strong>: response to the <em>n</em>th prompt (in UTF-8)
</li>
</ul>

</li>
</ul>
<h3><a name="PLUGIN_KI_USER_REQUEST"></a><a name="SH.6.9"></a>H.6.9 <code>PLUGIN_KI_USER_REQUEST</code></h3>
<p>
<strong>Direction</strong>: plugin to client
</p>
<p>
<strong>When</strong>: response to <code>PLUGIN_KI_SERVER_REQUEST</code>, if the plugin cannot answer the server's auth prompts without presenting prompts of its own to the user
</p>
<p>
<strong>What happens next</strong>: the client will send <code>PLUGIN_KI_USER_RESPONSE</code>
</p>
<p>
<strong>Message contents after the type code</strong>: exactly the same as in <code>PLUGIN_KI_SERVER_REQUEST</code> (see <a href="#PLUGIN_KI_SERVER_REQUEST">section H.6.7</a>).
</p>
<h3><a name="PLUGIN_KI_USER_RESPONSE"></a><a name="SH.6.10"></a>H.6.10 <code>PLUGIN_KI_USER_RESPONSE</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: response to <code>PLUGIN_KI_USER_REQUEST</code>
</p>
<p>
<strong>What happens next</strong>: the plugin will send <code>PLUGIN_KI_SERVER_RESPONSE</code>, or another <code>PLUGIN_KI_USER_REQUEST</code>
</p>
<p>
<strong>Message contents after the type code</strong>: exactly the same as in <code>PLUGIN_KI_SERVER_RESPONSE</code> (see <a href="#PLUGIN_KI_SERVER_RESPONSE">section H.6.8</a>).
</p>
<h3><a name="PLUGIN_AUTH_SUCCESS"></a><a name="SH.6.11"></a>H.6.11 <code>PLUGIN_AUTH_SUCCESS</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_KI_SERVER_RESPONSE</code>, or (in unusual cases) after <code>PLUGIN_PROTOCOL_ACCEPT</code>
</p>
<p>
<strong>What happens next</strong>: the client will either send another <code>PLUGIN_PROTOCOL</code> or terminate the session
</p>
<p>
<strong>Message contents after the type code</strong>: none
</p>
<h3><a name="PLUGIN_AUTH_FAILURE"></a><a name="SH.6.12"></a>H.6.12 <code>PLUGIN_AUTH_FAILURE</code></h3>
<p>
<strong>Direction</strong>: client to plugin
</p>
<p>
<strong>When</strong>: sent after <code>PLUGIN_KI_SERVER_RESPONSE</code>, or (in unusual cases) after <code>PLUGIN_PROTOCOL_ACCEPT</code>
</p>
<p>
<strong>What happens next</strong>: the client will either send another <code>PLUGIN_PROTOCOL</code> or terminate the session
</p>
<p>
<strong>Message contents after the type code</strong>: none
</p>
<h2><a name="authplugin-refs"></a><a name="SH.7"></a>H.7 References</h2>
<p><a name="p0"></a>
[RFC4251] <a href="https://www.rfc-editor.org/rfc/rfc4251">RFC 4251</a>, &#8216;The Secure Shell (SSH) Protocol Architecture&#8217;.
</p>
<p><a name="p2"></a>
[RFC4252] <a href="https://www.rfc-editor.org/rfc/rfc4252">RFC 4252</a>, &#8216;The Secure Shell (SSH) Authentication Protocol&#8217;.
</p>
<p><a name="p1"></a>
[RFC4256] <a href="https://www.rfc-editor.org/rfc/rfc4256">RFC 4256</a>, &#8216;Generic Message Exchange Authentication for the Secure Shell Protocol (SSH)&#8217; (better known by its wire id &#8216;keyboard-interactive&#8217;).
</p>

<hr><p>If you want to provide feedback on this manual or on the PuTTY tools themselves, see the <a href="https://www.chiark.greenend.org.uk/~sgtatham/putty/feedback.html">Feedback page</a>.</p><address>
[PuTTY release 0.83]</address></body>
</html>