monitor_wrap.c revision 98675
1/*
2 * Copyright 2002 Niels Provos <provos@citi.umich.edu>
3 * Copyright 2002 Markus Friedl <markus@openbsd.org>
4 * All rights reserved.
5 *
6 * Redistribution and use in source and binary forms, with or without
7 * modification, are permitted provided that the following conditions
8 * are met:
9 * 1. Redistributions of source code must retain the above copyright
10 *    notice, this list of conditions and the following disclaimer.
11 * 2. Redistributions in binary form must reproduce the above copyright
12 *    notice, this list of conditions and the following disclaimer in the
13 *    documentation and/or other materials provided with the distribution.
14 *
15 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
16 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
17 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
18 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
19 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
20 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
21 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
22 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
23 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
24 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
25 */
26
27#include "includes.h"
28RCSID("$OpenBSD: monitor_wrap.c,v 1.11 2002/06/19 18:01:00 markus Exp $");
29
30#include <openssl/bn.h>
31#include <openssl/dh.h>
32
33#include "ssh.h"
34#include "dh.h"
35#include "kex.h"
36#include "auth.h"
37#include "buffer.h"
38#include "bufaux.h"
39#include "packet.h"
40#include "mac.h"
41#include "log.h"
42#include "zlib.h"
43#include "monitor.h"
44#include "monitor_wrap.h"
45#include "xmalloc.h"
46#include "atomicio.h"
47#include "monitor_fdpass.h"
48#include "getput.h"
49
50#include "auth.h"
51#include "channels.h"
52#include "session.h"
53
54/* Imports */
55extern int compat20;
56extern Newkeys *newkeys[];
57extern z_stream incoming_stream;
58extern z_stream outgoing_stream;
59extern struct monitor *pmonitor;
60extern Buffer input, output;
61
62void
63mm_request_send(int socket, enum monitor_reqtype type, Buffer *m)
64{
65	u_char buf[5];
66	u_int mlen = buffer_len(m);
67
68	debug3("%s entering: type %d", __func__, type);
69
70	PUT_32BIT(buf, mlen + 1);
71	buf[4] = (u_char) type;		/* 1st byte of payload is mesg-type */
72	if (atomicio(write, socket, buf, sizeof(buf)) != sizeof(buf))
73		fatal("%s: write", __func__);
74	if (atomicio(write, socket, buffer_ptr(m), mlen) != mlen)
75		fatal("%s: write", __func__);
76}
77
78void
79mm_request_receive(int socket, Buffer *m)
80{
81	u_char buf[4];
82	ssize_t res;
83	u_int msg_len;
84
85	debug3("%s entering", __func__);
86
87	res = atomicio(read, socket, buf, sizeof(buf));
88	if (res != sizeof(buf)) {
89		if (res == 0)
90			fatal_cleanup();
91		fatal("%s: read: %ld", __func__, (long)res);
92	}
93	msg_len = GET_32BIT(buf);
94	if (msg_len > 256 * 1024)
95		fatal("%s: read: bad msg_len %d", __func__, msg_len);
96	buffer_clear(m);
97	buffer_append_space(m, msg_len);
98	res = atomicio(read, socket, buffer_ptr(m), msg_len);
99	if (res != msg_len)
100		fatal("%s: read: %ld != msg_len", __func__, (long)res);
101}
102
103void
104mm_request_receive_expect(int socket, enum monitor_reqtype type, Buffer *m)
105{
106	u_char rtype;
107
108	debug3("%s entering: type %d", __func__, type);
109
110	mm_request_receive(socket, m);
111	rtype = buffer_get_char(m);
112	if (rtype != type)
113		fatal("%s: read: rtype %d != type %d", __func__,
114		    rtype, type);
115}
116
117DH *
118mm_choose_dh(int min, int nbits, int max)
119{
120	BIGNUM *p, *g;
121	int success = 0;
122	Buffer m;
123
124	buffer_init(&m);
125	buffer_put_int(&m, min);
126	buffer_put_int(&m, nbits);
127	buffer_put_int(&m, max);
128
129	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_MODULI, &m);
130
131	debug3("%s: waiting for MONITOR_ANS_MODULI", __func__);
132	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_MODULI, &m);
133
134	success = buffer_get_char(&m);
135	if (success == 0)
136		fatal("%s: MONITOR_ANS_MODULI failed", __func__);
137
138	if ((p = BN_new()) == NULL)
139		fatal("%s: BN_new failed", __func__);
140	if ((g = BN_new()) == NULL)
141		fatal("%s: BN_new failed", __func__);
142	buffer_get_bignum2(&m, p);
143	buffer_get_bignum2(&m, g);
144
145	debug3("%s: remaining %d", __func__, buffer_len(&m));
146	buffer_free(&m);
147
148	return (dh_new_group(g, p));
149}
150
151int
152mm_key_sign(Key *key, u_char **sigp, u_int *lenp, u_char *data, u_int datalen)
153{
154	Kex *kex = *pmonitor->m_pkex;
155	Buffer m;
156
157	debug3("%s entering", __func__);
158
159	buffer_init(&m);
160	buffer_put_int(&m, kex->host_key_index(key));
161	buffer_put_string(&m, data, datalen);
162
163	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SIGN, &m);
164
165	debug3("%s: waiting for MONITOR_ANS_SIGN", __func__);
166	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SIGN, &m);
167	*sigp  = buffer_get_string(&m, lenp);
168	buffer_free(&m);
169
170	return (0);
171}
172
173struct passwd *
174mm_getpwnamallow(const char *login)
175{
176	Buffer m;
177	struct passwd *pw;
178	u_int pwlen;
179
180	debug3("%s entering", __func__);
181
182	buffer_init(&m);
183	buffer_put_cstring(&m, login);
184
185	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PWNAM, &m);
186
187	debug3("%s: waiting for MONITOR_ANS_PWNAM", __func__);
188	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PWNAM, &m);
189
190	if (buffer_get_char(&m) == 0) {
191		buffer_free(&m);
192		return (NULL);
193	}
194	pw = buffer_get_string(&m, &pwlen);
195	if (pwlen != sizeof(struct passwd))
196		fatal("%s: struct passwd size mismatch", __func__);
197	pw->pw_name = buffer_get_string(&m, NULL);
198	pw->pw_passwd = buffer_get_string(&m, NULL);
199	pw->pw_gecos = buffer_get_string(&m, NULL);
200	pw->pw_class = buffer_get_string(&m, NULL);
201	pw->pw_dir = buffer_get_string(&m, NULL);
202	pw->pw_shell = buffer_get_string(&m, NULL);
203	buffer_free(&m);
204
205	return (pw);
206}
207
208char* mm_auth2_read_banner(void)
209{
210	Buffer m;
211	char *banner;
212
213	debug3("%s entering", __func__);
214
215	buffer_init(&m);
216	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTH2_READ_BANNER, &m);
217	buffer_clear(&m);
218
219	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTH2_READ_BANNER, &m);
220	banner = buffer_get_string(&m, NULL);
221	buffer_free(&m);
222
223	return (banner);
224}
225
226/* Inform the privileged process about service and style */
227
228void
229mm_inform_authserv(char *service, char *style)
230{
231	Buffer m;
232
233	debug3("%s entering", __func__);
234
235	buffer_init(&m);
236	buffer_put_cstring(&m, service);
237	buffer_put_cstring(&m, style ? style : "");
238
239	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
240
241	buffer_free(&m);
242}
243
244/* Do the password authentication */
245int
246mm_auth_password(Authctxt *authctxt, char *password)
247{
248	Buffer m;
249	int authenticated = 0;
250
251	debug3("%s entering", __func__);
252
253	buffer_init(&m);
254	buffer_put_cstring(&m, password);
255	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHPASSWORD, &m);
256
257	debug3("%s: waiting for MONITOR_ANS_AUTHPASSWORD", __func__);
258	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_AUTHPASSWORD, &m);
259
260	authenticated = buffer_get_int(&m);
261
262	buffer_free(&m);
263
264	debug3("%s: user %sauthenticated",
265	    __func__, authenticated ? "" : "not ");
266	return (authenticated);
267}
268
269int
270mm_user_key_allowed(struct passwd *pw, Key *key)
271{
272	return (mm_key_allowed(MM_USERKEY, NULL, NULL, key));
273}
274
275int
276mm_hostbased_key_allowed(struct passwd *pw, char *user, char *host,
277    Key *key)
278{
279	return (mm_key_allowed(MM_HOSTKEY, user, host, key));
280}
281
282int
283mm_auth_rhosts_rsa_key_allowed(struct passwd *pw, char *user,
284    char *host, Key *key)
285{
286	int ret;
287
288	key->type = KEY_RSA; /* XXX hack for key_to_blob */
289	ret = mm_key_allowed(MM_RSAHOSTKEY, user, host, key);
290	key->type = KEY_RSA1;
291	return (ret);
292}
293
294static void
295mm_send_debug(Buffer *m)
296{
297	char *msg;
298
299	while (buffer_len(m)) {
300		msg = buffer_get_string(m, NULL);
301		debug3("%s: Sending debug: %s", __func__, msg);
302		packet_send_debug("%s", msg);
303		xfree(msg);
304	}
305}
306
307int
308mm_key_allowed(enum mm_keytype type, char *user, char *host, Key *key)
309{
310	Buffer m;
311	u_char *blob;
312	u_int len;
313	int allowed = 0;
314
315	debug3("%s entering", __func__);
316
317	/* Convert the key to a blob and the pass it over */
318	if (!key_to_blob(key, &blob, &len))
319		return (0);
320
321	buffer_init(&m);
322	buffer_put_int(&m, type);
323	buffer_put_cstring(&m, user ? user : "");
324	buffer_put_cstring(&m, host ? host : "");
325	buffer_put_string(&m, blob, len);
326	xfree(blob);
327
328	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYALLOWED, &m);
329
330	debug3("%s: waiting for MONITOR_ANS_KEYALLOWED", __func__);
331	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYALLOWED, &m);
332
333	allowed = buffer_get_int(&m);
334
335	/* Send potential debug messages */
336	mm_send_debug(&m);
337
338	buffer_free(&m);
339
340	return (allowed);
341}
342
343/*
344 * This key verify needs to send the key type along, because the
345 * privileged parent makes the decision if the key is allowed
346 * for authentication.
347 */
348
349int
350mm_key_verify(Key *key, u_char *sig, u_int siglen, u_char *data, u_int datalen)
351{
352	Buffer m;
353	u_char *blob;
354	u_int len;
355	int verified = 0;
356
357	debug3("%s entering", __func__);
358
359	/* Convert the key to a blob and the pass it over */
360	if (!key_to_blob(key, &blob, &len))
361		return (0);
362
363	buffer_init(&m);
364	buffer_put_string(&m, blob, len);
365	buffer_put_string(&m, sig, siglen);
366	buffer_put_string(&m, data, datalen);
367	xfree(blob);
368
369	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYVERIFY, &m);
370
371	debug3("%s: waiting for MONITOR_ANS_KEYVERIFY", __func__);
372	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_KEYVERIFY, &m);
373
374	verified = buffer_get_int(&m);
375
376	buffer_free(&m);
377
378	return (verified);
379}
380
381/* Export key state after authentication */
382Newkeys *
383mm_newkeys_from_blob(u_char *blob, int blen)
384{
385	Buffer b;
386	u_int len;
387	Newkeys *newkey = NULL;
388	Enc *enc;
389	Mac *mac;
390	Comp *comp;
391
392	debug3("%s: %p(%d)", __func__, blob, blen);
393#ifdef DEBUG_PK
394	dump_base64(stderr, blob, blen);
395#endif
396	buffer_init(&b);
397	buffer_append(&b, blob, blen);
398
399	newkey = xmalloc(sizeof(*newkey));
400	enc = &newkey->enc;
401	mac = &newkey->mac;
402	comp = &newkey->comp;
403
404	/* Enc structure */
405	enc->name = buffer_get_string(&b, NULL);
406	buffer_get(&b, &enc->cipher, sizeof(enc->cipher));
407	enc->enabled = buffer_get_int(&b);
408	enc->block_size = buffer_get_int(&b);
409	enc->key = buffer_get_string(&b, &enc->key_len);
410	enc->iv = buffer_get_string(&b, &len);
411	if (len != enc->block_size)
412		fatal("%s: bad ivlen: expected %d != %d", __func__,
413		    enc->block_size, len);
414
415	if (enc->name == NULL || cipher_by_name(enc->name) != enc->cipher)
416		fatal("%s: bad cipher name %s or pointer %p", __func__,
417		    enc->name, enc->cipher);
418
419	/* Mac structure */
420	mac->name = buffer_get_string(&b, NULL);
421	if (mac->name == NULL || mac_init(mac, mac->name) == -1)
422		fatal("%s: can not init mac %s", __func__, mac->name);
423	mac->enabled = buffer_get_int(&b);
424	mac->key = buffer_get_string(&b, &len);
425	if (len > mac->key_len)
426		fatal("%s: bad mac key length: %d > %d", __func__, len,
427		    mac->key_len);
428	mac->key_len = len;
429
430	/* Comp structure */
431	comp->type = buffer_get_int(&b);
432	comp->enabled = buffer_get_int(&b);
433	comp->name = buffer_get_string(&b, NULL);
434
435	len = buffer_len(&b);
436	if (len != 0)
437		error("newkeys_from_blob: remaining bytes in blob %d", len);
438	buffer_free(&b);
439	return (newkey);
440}
441
442int
443mm_newkeys_to_blob(int mode, u_char **blobp, u_int *lenp)
444{
445	Buffer b;
446	int len;
447	u_char *buf;
448	Enc *enc;
449	Mac *mac;
450	Comp *comp;
451	Newkeys *newkey = newkeys[mode];
452
453	debug3("%s: converting %p", __func__, newkey);
454
455	if (newkey == NULL) {
456		error("%s: newkey == NULL", __func__);
457		return 0;
458	}
459	enc = &newkey->enc;
460	mac = &newkey->mac;
461	comp = &newkey->comp;
462
463	buffer_init(&b);
464	/* Enc structure */
465	buffer_put_cstring(&b, enc->name);
466	/* The cipher struct is constant and shared, you export pointer */
467	buffer_append(&b, &enc->cipher, sizeof(enc->cipher));
468	buffer_put_int(&b, enc->enabled);
469	buffer_put_int(&b, enc->block_size);
470	buffer_put_string(&b, enc->key, enc->key_len);
471	packet_get_keyiv(mode, enc->iv, enc->block_size);
472	buffer_put_string(&b, enc->iv, enc->block_size);
473
474	/* Mac structure */
475	buffer_put_cstring(&b, mac->name);
476	buffer_put_int(&b, mac->enabled);
477	buffer_put_string(&b, mac->key, mac->key_len);
478
479	/* Comp structure */
480	buffer_put_int(&b, comp->type);
481	buffer_put_int(&b, comp->enabled);
482	buffer_put_cstring(&b, comp->name);
483
484	len = buffer_len(&b);
485	buf = xmalloc(len);
486	memcpy(buf, buffer_ptr(&b), len);
487	memset(buffer_ptr(&b), 0, len);
488	buffer_free(&b);
489	if (lenp != NULL)
490		*lenp = len;
491	if (blobp != NULL)
492		*blobp = buf;
493	return len;
494}
495
496static void
497mm_send_kex(Buffer *m, Kex *kex)
498{
499	buffer_put_string(m, kex->session_id, kex->session_id_len);
500	buffer_put_int(m, kex->we_need);
501	buffer_put_int(m, kex->hostkey_type);
502	buffer_put_int(m, kex->kex_type);
503	buffer_put_string(m, buffer_ptr(&kex->my), buffer_len(&kex->my));
504	buffer_put_string(m, buffer_ptr(&kex->peer), buffer_len(&kex->peer));
505	buffer_put_int(m, kex->flags);
506	buffer_put_cstring(m, kex->client_version_string);
507	buffer_put_cstring(m, kex->server_version_string);
508}
509
510void
511mm_send_keystate(struct monitor *pmonitor)
512{
513	Buffer m;
514	u_char *blob, *p;
515	u_int bloblen, plen;
516
517	buffer_init(&m);
518
519	if (!compat20) {
520		u_char iv[24];
521		u_char *key;
522		u_int ivlen, keylen;
523
524		buffer_put_int(&m, packet_get_protocol_flags());
525
526		buffer_put_int(&m, packet_get_ssh1_cipher());
527
528		debug3("%s: Sending ssh1 KEY+IV", __func__);
529		keylen = packet_get_encryption_key(NULL);
530		key = xmalloc(keylen+1);	/* add 1 if keylen == 0 */
531		keylen = packet_get_encryption_key(key);
532		buffer_put_string(&m, key, keylen);
533		memset(key, 0, keylen);
534		xfree(key);
535
536		ivlen = packet_get_keyiv_len(MODE_OUT);
537		packet_get_keyiv(MODE_OUT, iv, ivlen);
538		buffer_put_string(&m, iv, ivlen);
539		ivlen = packet_get_keyiv_len(MODE_OUT);
540		packet_get_keyiv(MODE_IN, iv, ivlen);
541		buffer_put_string(&m, iv, ivlen);
542		goto skip;
543	} else {
544		/* Kex for rekeying */
545		mm_send_kex(&m, *pmonitor->m_pkex);
546	}
547
548	debug3("%s: Sending new keys: %p %p",
549	    __func__, newkeys[MODE_OUT], newkeys[MODE_IN]);
550
551	/* Keys from Kex */
552	if (!mm_newkeys_to_blob(MODE_OUT, &blob, &bloblen))
553		fatal("%s: conversion of newkeys failed", __func__);
554
555	buffer_put_string(&m, blob, bloblen);
556	xfree(blob);
557
558	if (!mm_newkeys_to_blob(MODE_IN, &blob, &bloblen))
559		fatal("%s: conversion of newkeys failed", __func__);
560
561	buffer_put_string(&m, blob, bloblen);
562	xfree(blob);
563
564	buffer_put_int(&m, packet_get_seqnr(MODE_OUT));
565	buffer_put_int(&m, packet_get_seqnr(MODE_IN));
566
567	debug3("%s: New keys have been sent", __func__);
568 skip:
569	/* More key context */
570	plen = packet_get_keycontext(MODE_OUT, NULL);
571	p = xmalloc(plen+1);
572	packet_get_keycontext(MODE_OUT, p);
573	buffer_put_string(&m, p, plen);
574	xfree(p);
575
576	plen = packet_get_keycontext(MODE_IN, NULL);
577	p = xmalloc(plen+1);
578	packet_get_keycontext(MODE_IN, p);
579	buffer_put_string(&m, p, plen);
580	xfree(p);
581
582	/* Compression state */
583	debug3("%s: Sending compression state", __func__);
584	buffer_put_string(&m, &outgoing_stream, sizeof(outgoing_stream));
585	buffer_put_string(&m, &incoming_stream, sizeof(incoming_stream));
586
587	/* Network I/O buffers */
588	buffer_put_string(&m, buffer_ptr(&input), buffer_len(&input));
589	buffer_put_string(&m, buffer_ptr(&output), buffer_len(&output));
590
591	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_KEYEXPORT, &m);
592	debug3("%s: Finished sending state", __func__);
593
594	buffer_free(&m);
595}
596
597int
598mm_pty_allocate(int *ptyfd, int *ttyfd, char *namebuf, int namebuflen)
599{
600	Buffer m;
601	u_char *p;
602	int success = 0;
603
604	buffer_init(&m);
605	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTY, &m);
606
607	debug3("%s: waiting for MONITOR_ANS_PTY", __func__);
608	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_PTY, &m);
609
610	success = buffer_get_int(&m);
611	if (success == 0) {
612		debug3("%s: pty alloc failed", __func__);
613		buffer_free(&m);
614		return (0);
615	}
616	p = buffer_get_string(&m, NULL);
617	buffer_free(&m);
618
619	strlcpy(namebuf, p, namebuflen); /* Possible truncation */
620	xfree(p);
621
622	*ptyfd = mm_receive_fd(pmonitor->m_recvfd);
623	*ttyfd = mm_receive_fd(pmonitor->m_recvfd);
624
625	/* Success */
626	return (1);
627}
628
629void
630mm_session_pty_cleanup2(void *session)
631{
632	Session *s = session;
633	Buffer m;
634
635	if (s->ttyfd == -1)
636		return;
637	buffer_init(&m);
638	buffer_put_cstring(&m, s->tty);
639	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_PTYCLEANUP, &m);
640	buffer_free(&m);
641
642	/* closed dup'ed master */
643	if (close(s->ptymaster) < 0)
644		error("close(s->ptymaster): %s", strerror(errno));
645
646	/* unlink pty from session */
647	s->ttyfd = -1;
648}
649
650/* Request process termination */
651
652void
653mm_terminate(void)
654{
655	Buffer m;
656
657	buffer_init(&m);
658	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_TERM, &m);
659	buffer_free(&m);
660}
661
662int
663mm_ssh1_session_key(BIGNUM *num)
664{
665	int rsafail;
666	Buffer m;
667
668	buffer_init(&m);
669	buffer_put_bignum2(&m, num);
670	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSKEY, &m);
671
672	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SESSKEY, &m);
673
674	rsafail = buffer_get_int(&m);
675	buffer_get_bignum2(&m, num);
676
677	buffer_free(&m);
678
679	return (rsafail);
680}
681
682static void
683mm_chall_setup(char **name, char **infotxt, u_int *numprompts,
684    char ***prompts, u_int **echo_on)
685{
686	*name = xstrdup("");
687	*infotxt = xstrdup("");
688	*numprompts = 1;
689	*prompts = xmalloc(*numprompts * sizeof(char*));
690	*echo_on = xmalloc(*numprompts * sizeof(u_int));
691	(*echo_on)[0] = 0;
692}
693
694int
695mm_bsdauth_query(void *ctx, char **name, char **infotxt,
696   u_int *numprompts, char ***prompts, u_int **echo_on)
697{
698	Buffer m;
699	int res;
700	char *challenge;
701
702	debug3("%s: entering", __func__);
703
704	buffer_init(&m);
705	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHQUERY, &m);
706
707	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_BSDAUTHQUERY,
708	    &m);
709	res = buffer_get_int(&m);
710	if (res == -1) {
711		debug3("%s: no challenge", __func__);
712		buffer_free(&m);
713		return (-1);
714	}
715
716	/* Get the challenge, and format the response */
717	challenge  = buffer_get_string(&m, NULL);
718	buffer_free(&m);
719
720	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
721	(*prompts)[0] = challenge;
722
723	debug3("%s: received challenge: %s", __func__, challenge);
724
725	return (0);
726}
727
728int
729mm_bsdauth_respond(void *ctx, u_int numresponses, char **responses)
730{
731	Buffer m;
732	int authok;
733
734	debug3("%s: entering", __func__);
735	if (numresponses != 1)
736		return (-1);
737
738	buffer_init(&m);
739	buffer_put_cstring(&m, responses[0]);
740	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_BSDAUTHRESPOND, &m);
741
742	mm_request_receive_expect(pmonitor->m_recvfd,
743	    MONITOR_ANS_BSDAUTHRESPOND, &m);
744
745	authok = buffer_get_int(&m);
746	buffer_free(&m);
747
748	return ((authok == 0) ? -1 : 0);
749}
750
751int
752mm_skey_query(void *ctx, char **name, char **infotxt,
753   u_int *numprompts, char ***prompts, u_int **echo_on)
754{
755	Buffer m;
756	int len, res;
757	char *p, *challenge;
758
759	debug3("%s: entering", __func__);
760
761	buffer_init(&m);
762	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYQUERY, &m);
763
764	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_SKEYQUERY,
765	    &m);
766	res = buffer_get_int(&m);
767	if (res == -1) {
768		debug3("%s: no challenge", __func__);
769		buffer_free(&m);
770		return (-1);
771	}
772
773	/* Get the challenge, and format the response */
774	challenge  = buffer_get_string(&m, NULL);
775	buffer_free(&m);
776
777	debug3("%s: received challenge: %s", __func__, challenge);
778
779	mm_chall_setup(name, infotxt, numprompts, prompts, echo_on);
780
781	len = strlen(challenge) + strlen(SKEY_PROMPT) + 1;
782	p = xmalloc(len);
783	strlcpy(p, challenge, len);
784	strlcat(p, SKEY_PROMPT, len);
785	(*prompts)[0] = p;
786	xfree(challenge);
787
788	return (0);
789}
790
791int
792mm_skey_respond(void *ctx, u_int numresponses, char **responses)
793{
794	Buffer m;
795	int authok;
796
797	debug3("%s: entering", __func__);
798	if (numresponses != 1)
799		return (-1);
800
801	buffer_init(&m);
802	buffer_put_cstring(&m, responses[0]);
803	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SKEYRESPOND, &m);
804
805	mm_request_receive_expect(pmonitor->m_recvfd,
806	    MONITOR_ANS_SKEYRESPOND, &m);
807
808	authok = buffer_get_int(&m);
809	buffer_free(&m);
810
811	return ((authok == 0) ? -1 : 0);
812}
813
814void
815mm_ssh1_session_id(u_char session_id[16])
816{
817	Buffer m;
818	int i;
819
820	debug3("%s entering", __func__);
821
822	buffer_init(&m);
823	for (i = 0; i < 16; i++)
824		buffer_put_char(&m, session_id[i]);
825
826	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_SESSID, &m);
827	buffer_free(&m);
828}
829
830int
831mm_auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey)
832{
833	Buffer m;
834	Key *key;
835	u_char *blob;
836	u_int blen;
837	int allowed = 0;
838
839	debug3("%s entering", __func__);
840
841	buffer_init(&m);
842	buffer_put_bignum2(&m, client_n);
843
844	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSAKEYALLOWED, &m);
845	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSAKEYALLOWED, &m);
846
847	allowed = buffer_get_int(&m);
848
849	if (allowed && rkey != NULL) {
850		blob = buffer_get_string(&m, &blen);
851		if ((key = key_from_blob(blob, blen)) == NULL)
852			fatal("%s: key_from_blob failed", __func__);
853		*rkey = key;
854		xfree(blob);
855	}
856	mm_send_debug(&m);
857	buffer_free(&m);
858
859	return (allowed);
860}
861
862BIGNUM *
863mm_auth_rsa_generate_challenge(Key *key)
864{
865	Buffer m;
866	BIGNUM *challenge;
867	u_char *blob;
868	u_int blen;
869
870	debug3("%s entering", __func__);
871
872	if ((challenge = BN_new()) == NULL)
873		fatal("%s: BN_new failed", __func__);
874
875	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
876	if (key_to_blob(key, &blob, &blen) == 0)
877		fatal("%s: key_to_blob failed", __func__);
878	key->type = KEY_RSA1;
879
880	buffer_init(&m);
881	buffer_put_string(&m, blob, blen);
882	xfree(blob);
883
884	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSACHALLENGE, &m);
885	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSACHALLENGE, &m);
886
887	buffer_get_bignum2(&m, challenge);
888	buffer_free(&m);
889
890	return (challenge);
891}
892
893int
894mm_auth_rsa_verify_response(Key *key, BIGNUM *p, u_char response[16])
895{
896	Buffer m;
897	u_char *blob;
898	u_int blen;
899	int success = 0;
900
901	debug3("%s entering", __func__);
902
903	key->type = KEY_RSA;    /* XXX cheat for key_to_blob */
904	if (key_to_blob(key, &blob, &blen) == 0)
905		fatal("%s: key_to_blob failed", __func__);
906	key->type = KEY_RSA1;
907
908	buffer_init(&m);
909	buffer_put_string(&m, blob, blen);
910	buffer_put_string(&m, response, 16);
911	xfree(blob);
912
913	mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_RSARESPONSE, &m);
914	mm_request_receive_expect(pmonitor->m_recvfd, MONITOR_ANS_RSARESPONSE, &m);
915
916	success = buffer_get_int(&m);
917	buffer_free(&m);
918
919	return (success);
920}
921