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