blob: cd79db2ae57fd005712eb925b51718f6a3b692e9 [file] [log] [blame]
otto@openbsd.org0323d9b2019-06-06 05:13:13 +00001/* $OpenBSD: ssh-pkcs11-helper.c,v 1.19 2019/06/06 05:13:13 otto Exp $ */
Damien Miller7ea845e2010-02-12 09:21:02 +11002/*
3 * Copyright (c) 2010 Markus Friedl. All rights reserved.
4 *
5 * Permission to use, copy, modify, and distribute this software for any
6 * purpose with or without fee is hereby granted, provided that the above
7 * copyright notice and this permission notice appear in all copies.
8 *
9 * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
10 * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
11 * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
12 * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
13 * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
14 * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
15 * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
16 */
17
Damien Miller8ad0fbd2010-02-12 09:49:06 +110018#include "includes.h"
19
Damien Miller7ea845e2010-02-12 09:21:02 +110020#include <sys/types.h>
Damien Miller8ad0fbd2010-02-12 09:49:06 +110021#ifdef HAVE_SYS_TIME_H
22# include <sys/time.h>
23#endif
24
25#include "openbsd-compat/sys-queue.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110026
djm@openbsd.org2c223872019-01-23 02:01:10 +000027#include <errno.h>
28#include <poll.h>
Damien Miller7ea845e2010-02-12 09:21:02 +110029#include <stdarg.h>
30#include <string.h>
31#include <unistd.h>
Damien Miller7ea845e2010-02-12 09:21:02 +110032
33#include "xmalloc.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000034#include "sshbuf.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110035#include "log.h"
36#include "misc.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000037#include "sshkey.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110038#include "authfd.h"
39#include "ssh-pkcs11.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000040#include "ssherr.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110041
Damien Miller47f9a412010-03-14 08:37:49 +110042#ifdef ENABLE_PKCS11
43
Damien Miller7ea845e2010-02-12 09:21:02 +110044/* borrows code from sftp-server and ssh-agent */
45
46struct pkcs11_keyinfo {
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000047 struct sshkey *key;
Damien Miller7ea845e2010-02-12 09:21:02 +110048 char *providername;
49 TAILQ_ENTRY(pkcs11_keyinfo) next;
50};
51
52TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
53
54#define MAX_MSG_LENGTH 10240 /*XXX*/
55
Damien Miller7ea845e2010-02-12 09:21:02 +110056/* input and output queue */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000057struct sshbuf *iqueue;
58struct sshbuf *oqueue;
Damien Miller7ea845e2010-02-12 09:21:02 +110059
60static void
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000061add_key(struct sshkey *k, char *name)
Damien Miller7ea845e2010-02-12 09:21:02 +110062{
63 struct pkcs11_keyinfo *ki;
64
65 ki = xcalloc(1, sizeof(*ki));
66 ki->providername = xstrdup(name);
67 ki->key = k;
68 TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
69}
70
71static void
72del_keys_by_name(char *name)
73{
74 struct pkcs11_keyinfo *ki, *nxt;
75
76 for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) {
77 nxt = TAILQ_NEXT(ki, next);
78 if (!strcmp(ki->providername, name)) {
79 TAILQ_REMOVE(&pkcs11_keylist, ki, next);
Darren Tuckera627d422013-06-02 07:31:17 +100080 free(ki->providername);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000081 sshkey_free(ki->key);
Damien Miller7ea845e2010-02-12 09:21:02 +110082 free(ki);
83 }
84 }
85}
86
87/* lookup matching 'private' key */
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000088static struct sshkey *
89lookup_key(struct sshkey *k)
Damien Miller7ea845e2010-02-12 09:21:02 +110090{
91 struct pkcs11_keyinfo *ki;
92
93 TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
94 debug("check %p %s", ki, ki->providername);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000095 if (sshkey_equal(k, ki->key))
Damien Miller7ea845e2010-02-12 09:21:02 +110096 return (ki->key);
97 }
98 return (NULL);
99}
100
101static void
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000102send_msg(struct sshbuf *m)
Damien Miller7ea845e2010-02-12 09:21:02 +1100103{
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000104 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100105
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000106 if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
107 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100108}
109
110static void
111process_add(void)
112{
113 char *name, *pin;
djm@openbsd.org93f02102019-01-20 22:51:37 +0000114 struct sshkey **keys = NULL;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000115 int r, i, nkeys;
Damien Miller7ea845e2010-02-12 09:21:02 +1100116 u_char *blob;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000117 size_t blen;
118 struct sshbuf *msg;
Damien Miller7ea845e2010-02-12 09:21:02 +1100119
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000120 if ((msg = sshbuf_new()) == NULL)
121 fatal("%s: sshbuf_new failed", __func__);
122 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
123 (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
124 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100125 if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000126 if ((r = sshbuf_put_u8(msg,
127 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
128 (r = sshbuf_put_u32(msg, nkeys)) != 0)
129 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100130 for (i = 0; i < nkeys; i++) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000131 if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) {
132 debug("%s: sshkey_to_blob: %s",
133 __func__, ssh_err(r));
Damien Millerf1e44ea2013-12-05 10:23:21 +1100134 continue;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000135 }
136 if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
137 (r = sshbuf_put_cstring(msg, name)) != 0)
138 fatal("%s: buffer error: %s",
139 __func__, ssh_err(r));
Darren Tuckera627d422013-06-02 07:31:17 +1000140 free(blob);
Damien Miller7ea845e2010-02-12 09:21:02 +1100141 add_key(keys[i], name);
142 }
Damien Miller7ea845e2010-02-12 09:21:02 +1100143 } else {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000144 if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
145 fatal("%s: buffer error: %s", __func__, ssh_err(r));
djm@openbsd.org93f02102019-01-20 22:51:37 +0000146 if ((r = sshbuf_put_u32(msg, -nkeys)) != 0)
147 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100148 }
djm@openbsd.org93f02102019-01-20 22:51:37 +0000149 free(keys);
Darren Tuckera627d422013-06-02 07:31:17 +1000150 free(pin);
151 free(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000152 send_msg(msg);
153 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100154}
155
156static void
157process_del(void)
158{
159 char *name, *pin;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000160 struct sshbuf *msg;
161 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100162
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000163 if ((msg = sshbuf_new()) == NULL)
164 fatal("%s: sshbuf_new failed", __func__);
165 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
166 (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
167 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100168 del_keys_by_name(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000169 if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ?
170 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
171 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Darren Tuckera627d422013-06-02 07:31:17 +1000172 free(pin);
173 free(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000174 send_msg(msg);
175 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100176}
177
178static void
179process_sign(void)
180{
181 u_char *blob, *data, *signature = NULL;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000182 size_t blen, dlen, slen = 0;
183 int r, ok = -1;
markus@openbsd.org54d90ac2017-05-30 08:52:19 +0000184 struct sshkey *key, *found;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000185 struct sshbuf *msg;
Damien Miller7ea845e2010-02-12 09:21:02 +1100186
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000187 /* XXX support SHA2 signature flags */
188 if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
189 (r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 ||
190 (r = sshbuf_get_u32(iqueue, NULL)) != 0)
191 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100192
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000193 if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
194 error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
195 else {
Damien Miller7ea845e2010-02-12 09:21:02 +1100196 if ((found = lookup_key(key)) != NULL) {
Damien Miller86687062014-07-02 15:28:02 +1000197#ifdef WITH_OPENSSL
198 int ret;
199
djm@openbsd.org93f02102019-01-20 22:51:37 +0000200 if (key->type == KEY_RSA) {
201 slen = RSA_size(key->rsa);
202 signature = xmalloc(slen);
203 ret = RSA_private_encrypt(dlen, data, signature,
204 found->rsa, RSA_PKCS1_PADDING);
205 if (ret != -1) {
206 slen = ret;
207 ok = 0;
208 }
Darren Tucker97370f62019-05-17 10:54:51 +1000209#ifdef OPENSSL_HAS_ECC
djm@openbsd.org93f02102019-01-20 22:51:37 +0000210 } else if (key->type == KEY_ECDSA) {
dtucker@openbsd.org5c8d14c2019-05-16 08:47:27 +0000211 u_int xslen = ECDSA_size(key->ecdsa);
212
djm@openbsd.org93f02102019-01-20 22:51:37 +0000213 signature = xmalloc(xslen);
214 /* "The parameter type is ignored." */
215 ret = ECDSA_sign(-1, data, dlen, signature,
216 &xslen, found->ecdsa);
217 if (ret != 0)
218 ok = 0;
219 else
220 error("%s: ECDSA_sign"
221 " returns %d", __func__, ret);
222 slen = xslen;
Darren Tucker97370f62019-05-17 10:54:51 +1000223#endif /* OPENSSL_HAS_ECC */
djm@openbsd.org93f02102019-01-20 22:51:37 +0000224 } else
225 error("%s: don't know how to sign with key "
226 "type %d", __func__, (int)key->type);
Damien Miller86687062014-07-02 15:28:02 +1000227#endif /* WITH_OPENSSL */
Damien Miller7ea845e2010-02-12 09:21:02 +1100228 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000229 sshkey_free(key);
Damien Miller7ea845e2010-02-12 09:21:02 +1100230 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000231 if ((msg = sshbuf_new()) == NULL)
232 fatal("%s: sshbuf_new failed", __func__);
Damien Miller7ea845e2010-02-12 09:21:02 +1100233 if (ok == 0) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000234 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
235 (r = sshbuf_put_string(msg, signature, slen)) != 0)
236 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100237 } else {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000238 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0)
239 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100240 }
Darren Tuckera627d422013-06-02 07:31:17 +1000241 free(data);
242 free(blob);
243 free(signature);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000244 send_msg(msg);
245 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100246}
247
248static void
249process(void)
250{
251 u_int msg_len;
252 u_int buf_len;
253 u_int consumed;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000254 u_char type;
255 const u_char *cp;
256 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100257
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000258 buf_len = sshbuf_len(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100259 if (buf_len < 5)
260 return; /* Incomplete message. */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000261 cp = sshbuf_ptr(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100262 msg_len = get_u32(cp);
263 if (msg_len > MAX_MSG_LENGTH) {
264 error("bad message len %d", msg_len);
265 cleanup_exit(11);
266 }
267 if (buf_len < msg_len + 4)
268 return;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000269 if ((r = sshbuf_consume(iqueue, 4)) != 0 ||
270 (r = sshbuf_get_u8(iqueue, &type)) != 0)
271 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100272 buf_len -= 4;
Damien Miller7ea845e2010-02-12 09:21:02 +1100273 switch (type) {
274 case SSH_AGENTC_ADD_SMARTCARD_KEY:
275 debug("process_add");
276 process_add();
277 break;
278 case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
279 debug("process_del");
280 process_del();
281 break;
282 case SSH2_AGENTC_SIGN_REQUEST:
283 debug("process_sign");
284 process_sign();
285 break;
286 default:
287 error("Unknown message %d", type);
288 break;
289 }
290 /* discard the remaining bytes from the current packet */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000291 if (buf_len < sshbuf_len(iqueue)) {
Damien Miller7ea845e2010-02-12 09:21:02 +1100292 error("iqueue grew unexpectedly");
293 cleanup_exit(255);
294 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000295 consumed = buf_len - sshbuf_len(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100296 if (msg_len < consumed) {
297 error("msg_len %d < consumed %d", msg_len, consumed);
298 cleanup_exit(255);
299 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000300 if (msg_len > consumed) {
301 if ((r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
302 fatal("%s: buffer error: %s", __func__, ssh_err(r));
303 }
Damien Miller7ea845e2010-02-12 09:21:02 +1100304}
305
306void
307cleanup_exit(int i)
308{
309 /* XXX */
310 _exit(i);
311}
312
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000313
Damien Miller7ea845e2010-02-12 09:21:02 +1100314int
315main(int argc, char **argv)
316{
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000317 int r, ch, in, out, max, log_stderr = 0;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000318 ssize_t len;
Damien Miller7ea845e2010-02-12 09:21:02 +1100319 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
320 LogLevel log_level = SYSLOG_LEVEL_ERROR;
321 char buf[4*4096];
Damien Miller7ea845e2010-02-12 09:21:02 +1100322 extern char *__progname;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000323 struct pollfd pfd[2];
Damien Miller7ea845e2010-02-12 09:21:02 +1100324
Damien Millerdfa41562010-02-12 10:06:28 +1100325 __progname = ssh_get_progname(argv[0]);
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000326 seed_rng();
327 TAILQ_INIT(&pkcs11_keylist);
Damien Millerdfa41562010-02-12 10:06:28 +1100328
Damien Miller7ea845e2010-02-12 09:21:02 +1100329 log_init(__progname, log_level, log_facility, log_stderr);
330
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000331 while ((ch = getopt(argc, argv, "v")) != -1) {
332 switch (ch) {
333 case 'v':
334 log_stderr = 1;
335 if (log_level == SYSLOG_LEVEL_ERROR)
336 log_level = SYSLOG_LEVEL_DEBUG1;
337 else if (log_level < SYSLOG_LEVEL_DEBUG3)
338 log_level++;
339 break;
340 default:
341 fprintf(stderr, "usage: %s [-v]\n", __progname);
342 exit(1);
343 }
344 }
345
346 log_init(__progname, log_level, log_facility, log_stderr);
347
348 pkcs11_init(0);
349
Damien Miller7ea845e2010-02-12 09:21:02 +1100350 in = STDIN_FILENO;
351 out = STDOUT_FILENO;
352
353 max = 0;
354 if (in > max)
355 max = in;
356 if (out > max)
357 max = out;
358
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000359 if ((iqueue = sshbuf_new()) == NULL)
360 fatal("%s: sshbuf_new failed", __func__);
361 if ((oqueue = sshbuf_new()) == NULL)
362 fatal("%s: sshbuf_new failed", __func__);
Damien Miller7ea845e2010-02-12 09:21:02 +1100363
djm@openbsd.org2c223872019-01-23 02:01:10 +0000364 while (1) {
365 memset(pfd, 0, sizeof(pfd));
366 pfd[0].fd = in;
367 pfd[1].fd = out;
Damien Miller7ea845e2010-02-12 09:21:02 +1100368
369 /*
370 * Ensure that we can read a full buffer and handle
371 * the worst-case length packet it can generate,
372 * otherwise apply backpressure by stopping reads.
373 */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000374 if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
375 (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
djm@openbsd.org2c223872019-01-23 02:01:10 +0000376 pfd[0].events = POLLIN;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000377 else if (r != SSH_ERR_NO_BUFFER_SPACE)
378 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100379
djm@openbsd.org2c223872019-01-23 02:01:10 +0000380 if (sshbuf_len(oqueue) > 0)
381 pfd[1].events = POLLOUT;
Damien Miller7ea845e2010-02-12 09:21:02 +1100382
djm@openbsd.org2c223872019-01-23 02:01:10 +0000383 if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) {
384 if (r == 0 || errno == EINTR)
Damien Miller7ea845e2010-02-12 09:21:02 +1100385 continue;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000386 fatal("poll: %s", strerror(errno));
Damien Miller7ea845e2010-02-12 09:21:02 +1100387 }
388
389 /* copy stdin to iqueue */
djm@openbsd.org2c223872019-01-23 02:01:10 +0000390 if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) {
Damien Miller7ea845e2010-02-12 09:21:02 +1100391 len = read(in, buf, sizeof buf);
392 if (len == 0) {
393 debug("read eof");
394 cleanup_exit(0);
395 } else if (len < 0) {
396 error("read: %s", strerror(errno));
397 cleanup_exit(1);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000398 } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
399 fatal("%s: buffer error: %s",
400 __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100401 }
402 }
403 /* send oqueue to stdout */
djm@openbsd.org2c223872019-01-23 02:01:10 +0000404 if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) {
405 len = write(out, sshbuf_ptr(oqueue),
406 sshbuf_len(oqueue));
Damien Miller7ea845e2010-02-12 09:21:02 +1100407 if (len < 0) {
408 error("write: %s", strerror(errno));
409 cleanup_exit(1);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000410 } else if ((r = sshbuf_consume(oqueue, len)) != 0) {
411 fatal("%s: buffer error: %s",
412 __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100413 }
414 }
415
416 /*
417 * Process requests from client if we can fit the results
418 * into the output buffer, otherwise stop processing input
419 * and let the output queue drain.
420 */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000421 if ((r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
Damien Miller7ea845e2010-02-12 09:21:02 +1100422 process();
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000423 else if (r != SSH_ERR_NO_BUFFER_SPACE)
424 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100425 }
426}
Damien Millerdfa41562010-02-12 10:06:28 +1100427#else /* ENABLE_PKCS11 */
428int
429main(int argc, char **argv)
430{
431 extern char *__progname;
432
433 __progname = ssh_get_progname(argv[0]);
434 log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0);
435 fatal("PKCS#11 support disabled at compile time");
436}
437#endif /* ENABLE_PKCS11 */