]> andersk Git - openssh.git/blame - monitor.c
Stupid djm commits experimental code to head instead of branch
[openssh.git] / monitor.c
CommitLineData
91885a4d 1/*
2 * Copyright 2001 Niels Provos <provos@citi.umich.edu>
3 * All rights reserved.
4 *
5 * Redistribution and use in source and binary forms, with or without
6 * modification, are permitted provided that the following conditions
7 * are met:
8 * 1. Redistributions of source code must retain the above copyright
9 * notice, this list of conditions and the following disclaimer.
10 * 2. Redistributions in binary form must reproduce the above copyright
11 * notice, this list of conditions and the following disclaimer in the
12 * documentation and/or other materials provided with the distribution.
13 *
14 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
15 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
16 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
17 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
18 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
19 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
20 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
21 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
22 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
23 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
24 */
25
26#include "includes.h"
27RCSID("$OpenBSD$");
28
29#include <openssl/dh.h>
30
31#include "ssh.h"
32#include "auth.h"
33#include "kex.h"
34#include "dh.h"
35#include "zlib.h"
36#include "packet.h"
37#include "auth-options.h"
38#include "sshpty.h"
39#include "channels.h"
40#include "session.h"
41#include "log.h"
42#include "monitor.h"
43#include "monitor_mm.h"
44#include "monitor_wrap.h"
45#include "monitor_fdpass.h"
46#include "xmalloc.h"
47#include "misc.h"
48#include "buffer.h"
49#include "bufaux.h"
50
51/* Imports */
52extern Newkeys *current_keys[];
53extern z_stream incoming_stream;
54extern z_stream outgoing_stream;
55extern int compat20;
56extern int mm_sendfd;
57
58/* State exported from the child */
59
60struct {
61 z_stream incoming;
62 z_stream outgoing;
63 u_char *keyin;
64 u_int keyinlen;
65 u_char *keyout;
66 u_int keyoutlen;
67} child_state;
68
69/* Prototype for authentication functions */
70
71int hostbased_key_allowed(struct passwd *, const char *, char *, Key *);
72int user_key_allowed(struct passwd *, Key *);
73Key *get_hostkey_by_index(int);
74
75void session_pty_cleanup(void *);
76
77static Authctxt *authctxt;
78
79struct mon_table {
80 enum monitor_reqtype type;
81 int flags;
82 int (*f)(int, Buffer *);
83};
84
85#define MON_PROTOONE 0x0001 /* Used in protocol 1 */
86#define MON_PROTOTWO 0x0002 /* Used in protocol 2 */
87#define MON_AUTH 0x0004 /* Authentication Request */
88
89#define MON_BOTH (MON_PROTOONE|MON_PROTOTWO)
90
91#define MON_PERMIT 0x1000 /* Request is permitted */
92
93struct mon_table mon_dispatch_proto20[] = {
94 {MONITOR_REQ_MODULI, MON_PROTOTWO, mm_answer_moduli},
95 {MONITOR_REQ_SIGN, MON_PROTOTWO, mm_answer_sign},
96 {MONITOR_REQ_PWNAM, MON_BOTH, mm_answer_pwnamallow},
97 {MONITOR_REQ_AUTHSERV, MON_BOTH, mm_answer_authserv},
98 {MONITOR_REQ_AUTHPASSWORD, MON_BOTH | MON_AUTH, mm_answer_authpassword},
99 {MONITOR_REQ_KEYALLOWED, MON_BOTH | MON_AUTH, mm_answer_keyallowed},
100 {MONITOR_REQ_KEYVERIFY, MON_BOTH | MON_AUTH, mm_answer_keyverify},
101 {0, 0, NULL}
102};
103
104struct mon_table mon_dispatch_postauth20[] = {
105 {MONITOR_REQ_MODULI, MON_PROTOTWO, mm_answer_moduli},
106 {MONITOR_REQ_SIGN, MON_PROTOTWO, mm_answer_sign},
107 {MONITOR_REQ_PTY, MON_BOTH, mm_answer_pty},
108 {MONITOR_REQ_TERM, MON_BOTH, mm_answer_term},
109 {0, 0, NULL}
110};
111
112struct mon_table mon_dispatch_proto15[] = {
113 {0, 0, NULL}
114};
115
116struct mon_table *mon_dispatch;
117
118/* Specifies if a certain message is allowed at the moment */
119
120void
121monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit)
122{
123 while (ent->f != NULL) {
124 if (ent->type == type) {
125 ent->flags &= ~MON_PERMIT;
126 ent->flags |= permit ? MON_PERMIT : 0;
127 return;
128 }
129 ent++;
130 }
131}
132
133void
134monitor_permit_authentications(int permit)
135{
136 struct mon_table *ent = mon_dispatch;
137
138 while (ent->f != NULL) {
139 if (ent->flags & MON_AUTH) {
140 ent->flags &= ~MON_PERMIT;
141 ent->flags |= permit ? MON_PERMIT : 0;
142 }
143 ent++;
144 }
145}
146
147#define FD_CLOSEONEXEC(x) do { \
148 if (fcntl(x, F_SETFD, 1) == -1) \
149 fatal("fcntl(%d, F_SETFD)", x); \
150} while (0)
151
152void
153monitor_socketpair(int *pair)
154{
155 if (socketpair(PF_LOCAL, SOCK_STREAM, 0, pair) == -1)
156 fatal("%s: socketpair", __FUNCTION__);
157 FD_CLOSEONEXEC(pair[0]);
158 FD_CLOSEONEXEC(pair[1]);
159}
160
161Authctxt *
162monitor_child_preauth(int socket)
163{
164 debug3("preauth child monitor started");
165
166 if (compat20) {
167 mon_dispatch = mon_dispatch_proto20;
168
169 /* Permit requests for moduli and signatures */
170 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
171 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
172 } else
173 mon_dispatch = mon_dispatch_proto15;
174
175 authctxt = authctxt_new();
176
177 /* The first few requests do not require asynchronous access */
178 for (;;) {
179 if (monitor_read(socket, mon_dispatch))
180 break;
181 }
182
183 debug("%s: %s has been authenticated by privileged process",
184 __FUNCTION__, authctxt->user);
185
186 if (compat20) {
187 mm_get_keystate(socket);
188 } else {
189 fatal("Use loose");
190 }
191
192 return (authctxt);
193}
194
195void
196monitor_child_postauth(int socket)
197{
198 if (compat20) {
199 mon_dispatch = mon_dispatch_postauth20;
200
201 /* Permit requests for moduli and signatures */
202 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1);
203 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1);
204 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1);
205
206 if (!no_pty_flag)
207 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1);
208 } else
209 mon_dispatch = mon_dispatch_proto15;
210
211 for (;;) {
212 if (monitor_read(socket, mon_dispatch))
213 break;
214 }
215}
216
217int
218monitor_read(int socket, struct mon_table *ent)
219{
220 Buffer m;
221 int ret;
222 u_char type;
223
224 buffer_init(&m);
225
226 mm_request_receive(socket, &m);
227 type = buffer_get_char(&m);
228
229 debug3("%s: checking request %d", __FUNCTION__, type);
230
231 while (ent->f != NULL) {
232 if (ent->type == type)
233 break;
234 ent++;
235 }
236
237 if (ent->f != NULL) {
238 if (!(ent->flags & MON_PERMIT))
239 fatal("%s: unpermitted request %d", __FUNCTION__,
240 type);
241 ret = (*ent->f)(socket, &m);
242 buffer_free(&m);
243 return ret;
244 }
245
246 fatal("%s: unsupported request: %d\n", __FUNCTION__, type);
247
248 /* NOTREACHED */
249 return (-1);
250}
251
252int
253mm_answer_moduli(int socket, Buffer *m)
254{
255 DH *dh;
256 int min, want, max;
257
258 /* Turn off requests for moduli */
259 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 0);
260
261 min = buffer_get_int(m);
262 want = buffer_get_int(m);
263 max = buffer_get_int(m);
264
265 debug3("%s: got parameters: %d %d %d",
266 __FUNCTION__, min, want, max);
267 /* We need to check here, too, in case the child got corrupted */
268 if (max < min || want < min || max < want)
269 fatal("%s: bad parameters: %d %d %d",
270 __FUNCTION__, min, want, max);
271
272 buffer_clear(m);
273
274 dh = choose_dh(min, want, max);
275 if (dh == NULL) {
276 buffer_put_char(m, 0);
277 return (0);
278 } else {
279 /* Send first bignum */
280 buffer_put_char(m, 1);
281 buffer_put_bignum2(m, dh->p);
282 buffer_put_bignum2(m, dh->g);
283
284 DH_free(dh);
285 }
286 mm_request_send(socket, MONITOR_ANS_MODULI, m);
287 return (0);
288}
289
290int
291mm_answer_sign(int socket, Buffer *m)
292{
293 Key *key;
294 u_char *p;
295 u_char *signature;
296 u_int siglen, datlen;
297 int keyid;
298
299 debug3("%s", __FUNCTION__);
300
301 keyid = buffer_get_int(m);
302 p = buffer_get_string(m, &datlen);
303
304 if ((key = get_hostkey_by_index(keyid)) == NULL)
305 fatal("%s: no hostkey from index %d", __FUNCTION__, keyid);
306 if (key_sign(key, &signature, &siglen, p, datlen) < 0)
307 fatal("%s: key_sign failed", __FUNCTION__);
308
309 debug3("%s: signature %p(%d)", __FUNCTION__, signature, siglen);
310
311 buffer_clear(m);
312 buffer_put_string(m, signature, siglen);
313
314 xfree(p);
315 xfree(signature);
316
317 /* Turn on permissions for getpwnam */
318 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1);
319
320 mm_request_send(socket, MONITOR_ANS_SIGN, m);
321 return (0);
322}
323
324/* Retrieves the password entry and also checks if the user is permitted */
325
326int
327mm_answer_pwnamallow(int socket, Buffer *m)
328{
329 char *login;
330 struct passwd *pwent;
331 int allowed;
332
333 debug3("%s", __FUNCTION__);
334
335 if (authctxt->attempt++ != 0)
336 fatal("%s: multiple attempts for getpwnam", __FUNCTION__);
337
338 login = buffer_get_string(m, NULL);
339
340 /* XXX - probably latch the username here */
341 pwent = getpwnam(login);
342 authctxt->user = xstrdup(login);
343 setproctitle("%s [priv]", pwent ? login : "unknown");
344 xfree(login);
345
346 /* Allow service/style information on the auth context */
347 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
348
349 buffer_clear(m);
350
351 if (pwent == NULL) {
352 buffer_put_char(m, 0);
353 mm_request_send(socket, MONITOR_ANS_PWNAM, m);
354 return (0);
355 }
356
357 /* Check if we permit this user */
358 allowed = allowed_user(pwent);
359
360 if (allowed) {
361 authctxt->pw = pwcopy(pwent);
362 authctxt->valid = 1;
363 }
364 buffer_put_char(m, allowed);
365 buffer_put_string(m, pwent, sizeof(struct passwd));
366 buffer_put_cstring(m, pwent->pw_name);
367 buffer_put_cstring(m, "*");
368 buffer_put_cstring(m, pwent->pw_gecos);
369 buffer_put_cstring(m, pwent->pw_class);
370 buffer_put_cstring(m, pwent->pw_dir);
371 buffer_put_cstring(m, pwent->pw_shell);
372
373 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __FUNCTION__, allowed);
374 mm_request_send(socket, MONITOR_ANS_PWNAM, m);
375
376 return (0);
377}
378
379int
380mm_answer_authserv(int socket, Buffer *m)
381{
382 /* Disallow service/style information on the auth context */
383 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 0);
384
385 monitor_permit_authentications(1);
386
387 authctxt->service = buffer_get_string(m, NULL);
388 authctxt->style = buffer_get_string(m, NULL);
389 if (strlen(authctxt->style) == 0) {
390 xfree(authctxt->style);
391 authctxt->style = NULL;
392 }
393
394 debug3("%s: service=%s, style=%s",
395 __FUNCTION__, authctxt->service, authctxt->style);
396
397 return (0);
398}
399
400int
401mm_answer_authpassword(int socket, Buffer *m)
402{
403 char *passwd;
404 int authenticated;
405
406 passwd = buffer_get_string(m, NULL);
407 /* Only authenticate if the context is valid */
408 authenticated = authctxt->valid && auth_password(authctxt, passwd);
409 memset(passwd, 0, strlen(passwd));
410 xfree(passwd);
411
412 buffer_clear(m);
413 buffer_put_int(m, authenticated);
414
415 debug3("%s: sending result %d", __FUNCTION__, authenticated);
416 mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m);
417
418 /* Causes monitor loop to terminate if authenticated */
419 return (authenticated);
420}
421
422int
423mm_answer_keyallowed(int socket, Buffer *m)
424{
425 Key *key;
426 u_char *cuser, *chost, *blob;
427 u_int bloblen;
428 enum mm_keytype type = 0;
429 int allowed = 0;
430
431 debug3("%s entering", __FUNCTION__);
432
433 type = buffer_get_int(m);
434 cuser = buffer_get_string(m, NULL);
435 chost = buffer_get_string(m, NULL);
436 blob = buffer_get_string(m, &bloblen);
437
438 key = key_from_blob(blob, bloblen);
439
440 debug3("%s: key_from_blob: %p", __FUNCTION__, key);
441
442 if (key != NULL && authctxt->pw != NULL) {
443 switch(type) {
444 case MM_USERKEY:
445 allowed = user_key_allowed(authctxt->pw, key);
446 break;
447 case MM_HOSTKEY:
448 allowed = hostbased_key_allowed(authctxt->pw,
449 cuser, chost, key);
450 break;
451 default:
452 fatal("%s: unknown key type %d", __FUNCTION__,
453 type);
454 break;
455 }
456 key_free(key);
457 }
458 xfree(chost);
459 xfree(cuser);
460 xfree(blob);
461
462 debug3("%s: key %p is %s",
463 __FUNCTION__, key, allowed ? "allowed" : "disallowed");
464
465 buffer_clear(m);
466 buffer_put_int(m, allowed);
467
468 mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m);
469 return (0);
470}
471
472int
473mm_answer_keyverify(int socket, Buffer *m)
474{
475 Key *key;
476 u_char *signature, *data, *cuser, *chost, *blob;
477 u_int signaturelen, datalen, bloblen;
478 int type;
479 int verified = 0;
480
481 type = buffer_get_int(m);
482 cuser = buffer_get_string(m, NULL);
483 chost = buffer_get_string(m, NULL);
484 blob = buffer_get_string(m, &bloblen);
485 signature = buffer_get_string(m, &signaturelen);
486 data = buffer_get_string(m, &datalen);
487
488 key = key_from_blob(blob, bloblen);
489 if (key == NULL)
490 fatal("%s: bad public key blob", __FUNCTION__);
491
492 if (authctxt->pw == NULL || !user_key_allowed(authctxt->pw, key))
493 fatal("%s: user not allowed", __FUNCTION__);
494 verified = key_verify(key, signature, signaturelen, data, datalen);
495 debug3("%s: key %p signature %s",
496 __FUNCTION__, key, verified ? "verified" : "unverified");
497
498 key_free(key);
499 xfree(chost);
500 xfree(cuser);
501 xfree(blob);
502 xfree(signature);
503 xfree(data);
504
505 buffer_clear(m);
506 buffer_put_int(m, verified);
507 mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m);
508
509 return (verified);
510}
511
512int
513mm_answer_pty(int socket, Buffer *m)
514{
515 Session *s;
516 int res;
517
518 debug3("%s entering", __FUNCTION__);
519
520 buffer_clear(m);
521 s = session_new();
522 if (s == NULL)
523 goto error;
524 s->authctxt = authctxt;
525 s->pw = authctxt->pw;
526 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
527 if (res == 0)
528 goto error;
529 fatal_add_cleanup(session_pty_cleanup, (void *)s);
530 pty_setowner(authctxt->pw, s->tty);
531
532 buffer_put_int(m, 1);
533 buffer_put_cstring(m, s->tty);
534 mm_request_send(socket, MONITOR_ANS_PTY, m);
535
536 mm_send_fd(mm_sendfd, s->ptyfd);
537 mm_send_fd(mm_sendfd, s->ttyfd);
538 return (0);
539
540 error:
541 if (s != NULL)
542 session_close(s);
543 buffer_put_int(m, 0);
544 mm_request_send(socket, MONITOR_ANS_PTY, m);
545 return (0);
546}
547
548int
549mm_answer_term(int socket, Buffer *req)
550{
551 debug3("%s: tearing down sessions", __FUNCTION__);
552
553 /* The child is terminating */
554 session_destroy_all();
555
556 return (1);
557}
558
559void
560mm_apply_keystate(struct mm_master *mm)
561{
562 /* XXX - delegate to child? */
563 set_newkeys(MODE_IN);
564 set_newkeys(MODE_OUT);
565
566 packet_set_keycontext(MODE_OUT, child_state.keyout);
567 xfree(child_state.keyout);
568 packet_set_keycontext(MODE_IN, child_state.keyin);
569 xfree(child_state.keyin);
570
571 memcpy(&incoming_stream, &child_state.incoming,
572 sizeof(incoming_stream));
573 memcpy(&outgoing_stream, &child_state.outgoing,
574 sizeof(outgoing_stream));
575
576 /* Update with new address */
577 mm_init_compression(mm);
578}
579
580/* This function requries careful sanity checking */
581
582void
583mm_get_keystate(int socket)
584{
585 Buffer m;
586 u_char *blob, *p;
587 u_int bloblen, plen;
588
589 debug3("%s: Waiting for new keys", __FUNCTION__);
590
591 buffer_init(&m);
592 mm_request_receive_expect(socket, MONITOR_REQ_KEYEXPORT, &m);
593
594 blob = buffer_get_string(&m, &bloblen);
595 current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen);
596 xfree(blob);
597
598 debug3("%s: Waiting for second key", __FUNCTION__);
599 blob = buffer_get_string(&m, &bloblen);
600 current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen);
601 xfree(blob);
602
603 /* Now get sequence numbers for the packets */
604 packet_set_seqnr(MODE_OUT, buffer_get_int(&m));
605 packet_set_seqnr(MODE_IN, buffer_get_int(&m));
606
607 /* Get the key context */
608 child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen);
609 child_state.keyin = buffer_get_string(&m, &child_state.keyinlen);
610
611 debug3("%s: Getting compression state", __FUNCTION__);
612 /* Get compression state */
613 p = buffer_get_string(&m, &plen);
614 if (plen != sizeof(child_state.outgoing))
615 fatal("%s: bad request size", __FUNCTION__);
616 memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing));
617 xfree(p);
618
619 p = buffer_get_string(&m, &plen);
620 if (plen != sizeof(child_state.incoming))
621 fatal("%s: bad request size", __FUNCTION__);
622 memcpy(&child_state.incoming, p, sizeof(child_state.incoming));
623 xfree(p);
624
625 buffer_free(&m);
626}
627
628
629/* Allocation functions for zlib */
630void *
631mm_zalloc(struct mm_master *mm, u_int ncount, u_int size)
632{
633 void *address;
634
635 address = mm_malloc(mm, size * ncount);
636
637 return (address);
638}
639
640void
641mm_zfree(struct mm_master *mm, void *address)
642{
643 mm_free(mm, address);
644}
645
646void
647mm_init_compression(struct mm_master *mm)
648{
649 outgoing_stream.zalloc = (alloc_func)mm_zalloc;
650 outgoing_stream.zfree = (free_func)mm_zfree;
651 outgoing_stream.opaque = mm;
652
653 incoming_stream.zalloc = (alloc_func)mm_zalloc;
654 incoming_stream.zfree = (free_func)mm_zfree;
655 incoming_stream.opaque = mm;
656}
This page took 0.177371 seconds and 5 git commands to generate.