blob: 219ce9b5dd88294fe3b00de7e0133e067aa0378c [file] [log] [blame]
djm@openbsd.org670104b2019-09-06 05:23:55 +00001/* $OpenBSD: ssh-pkcs11-helper.c,v 1.21 2019/09/06 05:23:55 djm 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.orgbe02d7c2019-09-06 04:53:27 +000027#include <stdlib.h>
djm@openbsd.org2c223872019-01-23 02:01:10 +000028#include <errno.h>
Darren Tucker6fc7e1c2019-10-28 15:53:25 +110029#ifdef HAVE_POLL_H
djm@openbsd.org2c223872019-01-23 02:01:10 +000030#include <poll.h>
Darren Tucker6fc7e1c2019-10-28 15:53:25 +110031#endif
Damien Miller7ea845e2010-02-12 09:21:02 +110032#include <stdarg.h>
33#include <string.h>
34#include <unistd.h>
Damien Miller7ea845e2010-02-12 09:21:02 +110035
36#include "xmalloc.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000037#include "sshbuf.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110038#include "log.h"
39#include "misc.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000040#include "sshkey.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110041#include "authfd.h"
42#include "ssh-pkcs11.h"
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000043#include "ssherr.h"
Damien Miller7ea845e2010-02-12 09:21:02 +110044
Damien Miller47f9a412010-03-14 08:37:49 +110045#ifdef ENABLE_PKCS11
46
djm@openbsd.org670104b2019-09-06 05:23:55 +000047#ifdef WITH_OPENSSL
48
Damien Miller7ea845e2010-02-12 09:21:02 +110049/* borrows code from sftp-server and ssh-agent */
50
51struct pkcs11_keyinfo {
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000052 struct sshkey *key;
Damien Miller7ea845e2010-02-12 09:21:02 +110053 char *providername;
54 TAILQ_ENTRY(pkcs11_keyinfo) next;
55};
56
57TAILQ_HEAD(, pkcs11_keyinfo) pkcs11_keylist;
58
59#define MAX_MSG_LENGTH 10240 /*XXX*/
60
Damien Miller7ea845e2010-02-12 09:21:02 +110061/* input and output queue */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000062struct sshbuf *iqueue;
63struct sshbuf *oqueue;
Damien Miller7ea845e2010-02-12 09:21:02 +110064
65static void
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000066add_key(struct sshkey *k, char *name)
Damien Miller7ea845e2010-02-12 09:21:02 +110067{
68 struct pkcs11_keyinfo *ki;
69
70 ki = xcalloc(1, sizeof(*ki));
71 ki->providername = xstrdup(name);
72 ki->key = k;
73 TAILQ_INSERT_TAIL(&pkcs11_keylist, ki, next);
74}
75
76static void
77del_keys_by_name(char *name)
78{
79 struct pkcs11_keyinfo *ki, *nxt;
80
81 for (ki = TAILQ_FIRST(&pkcs11_keylist); ki; ki = nxt) {
82 nxt = TAILQ_NEXT(ki, next);
83 if (!strcmp(ki->providername, name)) {
84 TAILQ_REMOVE(&pkcs11_keylist, ki, next);
Darren Tuckera627d422013-06-02 07:31:17 +100085 free(ki->providername);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +000086 sshkey_free(ki->key);
Damien Miller7ea845e2010-02-12 09:21:02 +110087 free(ki);
88 }
89 }
90}
91
92/* lookup matching 'private' key */
markus@openbsd.org54d90ac2017-05-30 08:52:19 +000093static struct sshkey *
94lookup_key(struct sshkey *k)
Damien Miller7ea845e2010-02-12 09:21:02 +110095{
96 struct pkcs11_keyinfo *ki;
97
98 TAILQ_FOREACH(ki, &pkcs11_keylist, next) {
99 debug("check %p %s", ki, ki->providername);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000100 if (sshkey_equal(k, ki->key))
Damien Miller7ea845e2010-02-12 09:21:02 +1100101 return (ki->key);
102 }
103 return (NULL);
104}
105
106static void
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000107send_msg(struct sshbuf *m)
Damien Miller7ea845e2010-02-12 09:21:02 +1100108{
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000109 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100110
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000111 if ((r = sshbuf_put_stringb(oqueue, m)) != 0)
112 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100113}
114
115static void
116process_add(void)
117{
118 char *name, *pin;
djm@openbsd.org93f02102019-01-20 22:51:37 +0000119 struct sshkey **keys = NULL;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000120 int r, i, nkeys;
Damien Miller7ea845e2010-02-12 09:21:02 +1100121 u_char *blob;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000122 size_t blen;
123 struct sshbuf *msg;
Damien Miller7ea845e2010-02-12 09:21:02 +1100124
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000125 if ((msg = sshbuf_new()) == NULL)
126 fatal("%s: sshbuf_new failed", __func__);
127 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
128 (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
129 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100130 if ((nkeys = pkcs11_add_provider(name, pin, &keys)) > 0) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000131 if ((r = sshbuf_put_u8(msg,
132 SSH2_AGENT_IDENTITIES_ANSWER)) != 0 ||
133 (r = sshbuf_put_u32(msg, nkeys)) != 0)
134 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100135 for (i = 0; i < nkeys; i++) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000136 if ((r = sshkey_to_blob(keys[i], &blob, &blen)) != 0) {
137 debug("%s: sshkey_to_blob: %s",
138 __func__, ssh_err(r));
Damien Millerf1e44ea2013-12-05 10:23:21 +1100139 continue;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000140 }
141 if ((r = sshbuf_put_string(msg, blob, blen)) != 0 ||
142 (r = sshbuf_put_cstring(msg, name)) != 0)
143 fatal("%s: buffer error: %s",
144 __func__, ssh_err(r));
Darren Tuckera627d422013-06-02 07:31:17 +1000145 free(blob);
Damien Miller7ea845e2010-02-12 09:21:02 +1100146 add_key(keys[i], name);
147 }
Damien Miller7ea845e2010-02-12 09:21:02 +1100148 } else {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000149 if ((r = sshbuf_put_u8(msg, SSH_AGENT_FAILURE)) != 0)
150 fatal("%s: buffer error: %s", __func__, ssh_err(r));
djm@openbsd.org93f02102019-01-20 22:51:37 +0000151 if ((r = sshbuf_put_u32(msg, -nkeys)) != 0)
152 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100153 }
djm@openbsd.org93f02102019-01-20 22:51:37 +0000154 free(keys);
Darren Tuckera627d422013-06-02 07:31:17 +1000155 free(pin);
156 free(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000157 send_msg(msg);
158 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100159}
160
161static void
162process_del(void)
163{
164 char *name, *pin;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000165 struct sshbuf *msg;
166 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100167
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000168 if ((msg = sshbuf_new()) == NULL)
169 fatal("%s: sshbuf_new failed", __func__);
170 if ((r = sshbuf_get_cstring(iqueue, &name, NULL)) != 0 ||
171 (r = sshbuf_get_cstring(iqueue, &pin, NULL)) != 0)
172 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100173 del_keys_by_name(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000174 if ((r = sshbuf_put_u8(msg, pkcs11_del_provider(name) == 0 ?
175 SSH_AGENT_SUCCESS : SSH_AGENT_FAILURE)) != 0)
176 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Darren Tuckera627d422013-06-02 07:31:17 +1000177 free(pin);
178 free(name);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000179 send_msg(msg);
180 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100181}
182
183static void
184process_sign(void)
185{
186 u_char *blob, *data, *signature = NULL;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000187 size_t blen, dlen, slen = 0;
188 int r, ok = -1;
markus@openbsd.org54d90ac2017-05-30 08:52:19 +0000189 struct sshkey *key, *found;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000190 struct sshbuf *msg;
Damien Miller7ea845e2010-02-12 09:21:02 +1100191
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000192 /* XXX support SHA2 signature flags */
193 if ((r = sshbuf_get_string(iqueue, &blob, &blen)) != 0 ||
194 (r = sshbuf_get_string(iqueue, &data, &dlen)) != 0 ||
195 (r = sshbuf_get_u32(iqueue, NULL)) != 0)
196 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100197
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000198 if ((r = sshkey_from_blob(blob, blen, &key)) != 0)
199 error("%s: sshkey_from_blob: %s", __func__, ssh_err(r));
200 else {
Damien Miller7ea845e2010-02-12 09:21:02 +1100201 if ((found = lookup_key(key)) != NULL) {
Damien Miller86687062014-07-02 15:28:02 +1000202#ifdef WITH_OPENSSL
203 int ret;
204
djm@openbsd.org93f02102019-01-20 22:51:37 +0000205 if (key->type == KEY_RSA) {
206 slen = RSA_size(key->rsa);
207 signature = xmalloc(slen);
208 ret = RSA_private_encrypt(dlen, data, signature,
209 found->rsa, RSA_PKCS1_PADDING);
210 if (ret != -1) {
211 slen = ret;
212 ok = 0;
213 }
Darren Tucker97370f62019-05-17 10:54:51 +1000214#ifdef OPENSSL_HAS_ECC
djm@openbsd.org93f02102019-01-20 22:51:37 +0000215 } else if (key->type == KEY_ECDSA) {
dtucker@openbsd.org5c8d14c2019-05-16 08:47:27 +0000216 u_int xslen = ECDSA_size(key->ecdsa);
217
djm@openbsd.org93f02102019-01-20 22:51:37 +0000218 signature = xmalloc(xslen);
219 /* "The parameter type is ignored." */
220 ret = ECDSA_sign(-1, data, dlen, signature,
221 &xslen, found->ecdsa);
222 if (ret != 0)
223 ok = 0;
224 else
225 error("%s: ECDSA_sign"
226 " returns %d", __func__, ret);
227 slen = xslen;
Darren Tucker97370f62019-05-17 10:54:51 +1000228#endif /* OPENSSL_HAS_ECC */
djm@openbsd.org93f02102019-01-20 22:51:37 +0000229 } else
230 error("%s: don't know how to sign with key "
231 "type %d", __func__, (int)key->type);
Damien Miller86687062014-07-02 15:28:02 +1000232#endif /* WITH_OPENSSL */
Damien Miller7ea845e2010-02-12 09:21:02 +1100233 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000234 sshkey_free(key);
Damien Miller7ea845e2010-02-12 09:21:02 +1100235 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000236 if ((msg = sshbuf_new()) == NULL)
237 fatal("%s: sshbuf_new failed", __func__);
Damien Miller7ea845e2010-02-12 09:21:02 +1100238 if (ok == 0) {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000239 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_SIGN_RESPONSE)) != 0 ||
240 (r = sshbuf_put_string(msg, signature, slen)) != 0)
241 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100242 } else {
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000243 if ((r = sshbuf_put_u8(msg, SSH2_AGENT_FAILURE)) != 0)
244 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100245 }
Darren Tuckera627d422013-06-02 07:31:17 +1000246 free(data);
247 free(blob);
248 free(signature);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000249 send_msg(msg);
250 sshbuf_free(msg);
Damien Miller7ea845e2010-02-12 09:21:02 +1100251}
252
253static void
254process(void)
255{
256 u_int msg_len;
257 u_int buf_len;
258 u_int consumed;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000259 u_char type;
260 const u_char *cp;
261 int r;
Damien Miller7ea845e2010-02-12 09:21:02 +1100262
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000263 buf_len = sshbuf_len(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100264 if (buf_len < 5)
265 return; /* Incomplete message. */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000266 cp = sshbuf_ptr(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100267 msg_len = get_u32(cp);
268 if (msg_len > MAX_MSG_LENGTH) {
269 error("bad message len %d", msg_len);
270 cleanup_exit(11);
271 }
272 if (buf_len < msg_len + 4)
273 return;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000274 if ((r = sshbuf_consume(iqueue, 4)) != 0 ||
275 (r = sshbuf_get_u8(iqueue, &type)) != 0)
276 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100277 buf_len -= 4;
Damien Miller7ea845e2010-02-12 09:21:02 +1100278 switch (type) {
279 case SSH_AGENTC_ADD_SMARTCARD_KEY:
280 debug("process_add");
281 process_add();
282 break;
283 case SSH_AGENTC_REMOVE_SMARTCARD_KEY:
284 debug("process_del");
285 process_del();
286 break;
287 case SSH2_AGENTC_SIGN_REQUEST:
288 debug("process_sign");
289 process_sign();
290 break;
291 default:
292 error("Unknown message %d", type);
293 break;
294 }
295 /* discard the remaining bytes from the current packet */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000296 if (buf_len < sshbuf_len(iqueue)) {
Damien Miller7ea845e2010-02-12 09:21:02 +1100297 error("iqueue grew unexpectedly");
298 cleanup_exit(255);
299 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000300 consumed = buf_len - sshbuf_len(iqueue);
Damien Miller7ea845e2010-02-12 09:21:02 +1100301 if (msg_len < consumed) {
302 error("msg_len %d < consumed %d", msg_len, consumed);
303 cleanup_exit(255);
304 }
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000305 if (msg_len > consumed) {
306 if ((r = sshbuf_consume(iqueue, msg_len - consumed)) != 0)
307 fatal("%s: buffer error: %s", __func__, ssh_err(r));
308 }
Damien Miller7ea845e2010-02-12 09:21:02 +1100309}
310
311void
312cleanup_exit(int i)
313{
314 /* XXX */
315 _exit(i);
316}
317
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000318
Damien Miller7ea845e2010-02-12 09:21:02 +1100319int
320main(int argc, char **argv)
321{
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000322 int r, ch, in, out, max, log_stderr = 0;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000323 ssize_t len;
Damien Miller7ea845e2010-02-12 09:21:02 +1100324 SyslogFacility log_facility = SYSLOG_FACILITY_AUTH;
325 LogLevel log_level = SYSLOG_LEVEL_ERROR;
326 char buf[4*4096];
Damien Miller7ea845e2010-02-12 09:21:02 +1100327 extern char *__progname;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000328 struct pollfd pfd[2];
Damien Miller7ea845e2010-02-12 09:21:02 +1100329
Damien Millerdfa41562010-02-12 10:06:28 +1100330 __progname = ssh_get_progname(argv[0]);
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000331 seed_rng();
332 TAILQ_INIT(&pkcs11_keylist);
Damien Millerdfa41562010-02-12 10:06:28 +1100333
Damien Miller7ea845e2010-02-12 09:21:02 +1100334 log_init(__progname, log_level, log_facility, log_stderr);
335
djm@openbsd.orgc7670b02019-01-21 12:53:35 +0000336 while ((ch = getopt(argc, argv, "v")) != -1) {
337 switch (ch) {
338 case 'v':
339 log_stderr = 1;
340 if (log_level == SYSLOG_LEVEL_ERROR)
341 log_level = SYSLOG_LEVEL_DEBUG1;
342 else if (log_level < SYSLOG_LEVEL_DEBUG3)
343 log_level++;
344 break;
345 default:
346 fprintf(stderr, "usage: %s [-v]\n", __progname);
347 exit(1);
348 }
349 }
350
351 log_init(__progname, log_level, log_facility, log_stderr);
352
353 pkcs11_init(0);
354
Damien Miller7ea845e2010-02-12 09:21:02 +1100355 in = STDIN_FILENO;
356 out = STDOUT_FILENO;
357
358 max = 0;
359 if (in > max)
360 max = in;
361 if (out > max)
362 max = out;
363
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000364 if ((iqueue = sshbuf_new()) == NULL)
365 fatal("%s: sshbuf_new failed", __func__);
366 if ((oqueue = sshbuf_new()) == NULL)
367 fatal("%s: sshbuf_new failed", __func__);
Damien Miller7ea845e2010-02-12 09:21:02 +1100368
djm@openbsd.org2c223872019-01-23 02:01:10 +0000369 while (1) {
370 memset(pfd, 0, sizeof(pfd));
371 pfd[0].fd = in;
372 pfd[1].fd = out;
Damien Miller7ea845e2010-02-12 09:21:02 +1100373
374 /*
375 * Ensure that we can read a full buffer and handle
376 * the worst-case length packet it can generate,
377 * otherwise apply backpressure by stopping reads.
378 */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000379 if ((r = sshbuf_check_reserve(iqueue, sizeof(buf))) == 0 &&
380 (r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
djm@openbsd.org2c223872019-01-23 02:01:10 +0000381 pfd[0].events = POLLIN;
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000382 else if (r != SSH_ERR_NO_BUFFER_SPACE)
383 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100384
djm@openbsd.org2c223872019-01-23 02:01:10 +0000385 if (sshbuf_len(oqueue) > 0)
386 pfd[1].events = POLLOUT;
Damien Miller7ea845e2010-02-12 09:21:02 +1100387
djm@openbsd.org2c223872019-01-23 02:01:10 +0000388 if ((r = poll(pfd, 2, -1 /* INFTIM */)) <= 0) {
389 if (r == 0 || errno == EINTR)
Damien Miller7ea845e2010-02-12 09:21:02 +1100390 continue;
djm@openbsd.org2c223872019-01-23 02:01:10 +0000391 fatal("poll: %s", strerror(errno));
Damien Miller7ea845e2010-02-12 09:21:02 +1100392 }
393
394 /* copy stdin to iqueue */
djm@openbsd.org2c223872019-01-23 02:01:10 +0000395 if ((pfd[0].revents & (POLLIN|POLLERR)) != 0) {
Damien Miller7ea845e2010-02-12 09:21:02 +1100396 len = read(in, buf, sizeof buf);
397 if (len == 0) {
398 debug("read eof");
399 cleanup_exit(0);
400 } else if (len < 0) {
401 error("read: %s", strerror(errno));
402 cleanup_exit(1);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000403 } else if ((r = sshbuf_put(iqueue, buf, len)) != 0) {
404 fatal("%s: buffer error: %s",
405 __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100406 }
407 }
408 /* send oqueue to stdout */
djm@openbsd.org2c223872019-01-23 02:01:10 +0000409 if ((pfd[1].revents & (POLLOUT|POLLHUP)) != 0) {
410 len = write(out, sshbuf_ptr(oqueue),
411 sshbuf_len(oqueue));
Damien Miller7ea845e2010-02-12 09:21:02 +1100412 if (len < 0) {
413 error("write: %s", strerror(errno));
414 cleanup_exit(1);
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000415 } else if ((r = sshbuf_consume(oqueue, len)) != 0) {
416 fatal("%s: buffer error: %s",
417 __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100418 }
419 }
420
421 /*
422 * Process requests from client if we can fit the results
423 * into the output buffer, otherwise stop processing input
424 * and let the output queue drain.
425 */
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000426 if ((r = sshbuf_check_reserve(oqueue, MAX_MSG_LENGTH)) == 0)
Damien Miller7ea845e2010-02-12 09:21:02 +1100427 process();
markus@openbsd.orgb0d34132018-01-08 15:18:46 +0000428 else if (r != SSH_ERR_NO_BUFFER_SPACE)
429 fatal("%s: buffer error: %s", __func__, ssh_err(r));
Damien Miller7ea845e2010-02-12 09:21:02 +1100430 }
431}
djm@openbsd.org670104b2019-09-06 05:23:55 +0000432
433#else /* WITH_OPENSSL */
434void
435cleanup_exit(int i)
436{
437 _exit(i);
438}
439
440int
441main(int argc, char **argv)
442{
443 fprintf(stderr, "PKCS#11 code is not enabled\n");
444 return 1;
445}
446#endif /* WITH_OPENSSL */
Damien Millerdfa41562010-02-12 10:06:28 +1100447#else /* ENABLE_PKCS11 */
448int
449main(int argc, char **argv)
450{
451 extern char *__progname;
452
453 __progname = ssh_get_progname(argv[0]);
454 log_init(__progname, SYSLOG_LEVEL_ERROR, SYSLOG_FACILITY_AUTH, 0);
455 fatal("PKCS#11 support disabled at compile time");
456}
457#endif /* ENABLE_PKCS11 */