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.c,v 1.16 2002/06/21 05:50:51 djm Exp $"); 29 RCSID("$FreeBSD$"); 30 31 #include <openssl/dh.h> 32 33 #ifdef SKEY 34 #include <opie.h> 35 #endif 36 37 #include "ssh.h" 38 #include "auth.h" 39 #include "kex.h" 40 #include "dh.h" 41 #include "zlib.h" 42 #include "packet.h" 43 #include "auth-options.h" 44 #include "sshpty.h" 45 #include "channels.h" 46 #include "session.h" 47 #include "sshlogin.h" 48 #include "canohost.h" 49 #include "log.h" 50 #include "servconf.h" 51 #include "monitor.h" 52 #include "monitor_mm.h" 53 #include "monitor_wrap.h" 54 #include "monitor_fdpass.h" 55 #include "xmalloc.h" 56 #include "misc.h" 57 #include "buffer.h" 58 #include "bufaux.h" 59 #include "compat.h" 60 #include "ssh2.h" 61 #include "mpaux.h" 62 63 /* Imports */ 64 extern ServerOptions options; 65 extern u_int utmp_len; 66 extern Newkeys *current_keys[]; 67 extern z_stream incoming_stream; 68 extern z_stream outgoing_stream; 69 extern u_char session_id[]; 70 extern Buffer input, output; 71 extern Buffer auth_debug; 72 extern int auth_debug_init; 73 74 /* State exported from the child */ 75 76 struct { 77 z_stream incoming; 78 z_stream outgoing; 79 u_char *keyin; 80 u_int keyinlen; 81 u_char *keyout; 82 u_int keyoutlen; 83 u_char *ivin; 84 u_int ivinlen; 85 u_char *ivout; 86 u_int ivoutlen; 87 u_char *ssh1key; 88 u_int ssh1keylen; 89 int ssh1cipher; 90 int ssh1protoflags; 91 u_char *input; 92 u_int ilen; 93 u_char *output; 94 u_int olen; 95 } child_state; 96 97 /* Functions on the montior that answer unprivileged requests */ 98 99 int mm_answer_moduli(int, Buffer *); 100 int mm_answer_sign(int, Buffer *); 101 int mm_answer_pwnamallow(int, Buffer *); 102 int mm_answer_auth2_read_banner(int, Buffer *); 103 int mm_answer_authserv(int, Buffer *); 104 int mm_answer_authpassword(int, Buffer *); 105 int mm_answer_bsdauthquery(int, Buffer *); 106 int mm_answer_bsdauthrespond(int, Buffer *); 107 int mm_answer_skeyquery(int, Buffer *); 108 int mm_answer_skeyrespond(int, Buffer *); 109 int mm_answer_keyallowed(int, Buffer *); 110 int mm_answer_keyverify(int, Buffer *); 111 int mm_answer_pty(int, Buffer *); 112 int mm_answer_pty_cleanup(int, Buffer *); 113 int mm_answer_term(int, Buffer *); 114 int mm_answer_rsa_keyallowed(int, Buffer *); 115 int mm_answer_rsa_challenge(int, Buffer *); 116 int mm_answer_rsa_response(int, Buffer *); 117 int mm_answer_sesskey(int, Buffer *); 118 int mm_answer_sessid(int, Buffer *); 119 120 static Authctxt *authctxt; 121 static BIGNUM *ssh1_challenge = NULL; /* used for ssh1 rsa auth */ 122 123 /* local state for key verify */ 124 static u_char *key_blob = NULL; 125 static u_int key_bloblen = 0; 126 static int key_blobtype = MM_NOKEY; 127 static u_char *hostbased_cuser = NULL; 128 static u_char *hostbased_chost = NULL; 129 static char *auth_method = "unknown"; 130 static int session_id2_len = 0; 131 static u_char *session_id2 = NULL; 132 133 struct mon_table { 134 enum monitor_reqtype type; 135 int flags; 136 int (*f)(int, Buffer *); 137 }; 138 139 #define MON_ISAUTH 0x0004 /* Required for Authentication */ 140 #define MON_AUTHDECIDE 0x0008 /* Decides Authentication */ 141 #define MON_ONCE 0x0010 /* Disable after calling */ 142 143 #define MON_AUTH (MON_ISAUTH|MON_AUTHDECIDE) 144 145 #define MON_PERMIT 0x1000 /* Request is permitted */ 146 147 struct mon_table mon_dispatch_proto20[] = { 148 {MONITOR_REQ_MODULI, MON_ONCE, mm_answer_moduli}, 149 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign}, 150 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 151 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv}, 152 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner}, 153 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 154 #ifdef BSD_AUTH 155 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, 156 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, 157 #endif 158 #ifdef SKEY 159 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, 160 {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, 161 #endif 162 {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, 163 {MONITOR_REQ_KEYVERIFY, MON_AUTH, mm_answer_keyverify}, 164 {0, 0, NULL} 165 }; 166 167 struct mon_table mon_dispatch_postauth20[] = { 168 {MONITOR_REQ_MODULI, 0, mm_answer_moduli}, 169 {MONITOR_REQ_SIGN, 0, mm_answer_sign}, 170 {MONITOR_REQ_PTY, 0, mm_answer_pty}, 171 {MONITOR_REQ_PTYCLEANUP, 0, mm_answer_pty_cleanup}, 172 {MONITOR_REQ_TERM, 0, mm_answer_term}, 173 {0, 0, NULL} 174 }; 175 176 struct mon_table mon_dispatch_proto15[] = { 177 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow}, 178 {MONITOR_REQ_SESSKEY, MON_ONCE, mm_answer_sesskey}, 179 {MONITOR_REQ_SESSID, MON_ONCE, mm_answer_sessid}, 180 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword}, 181 {MONITOR_REQ_RSAKEYALLOWED, MON_ISAUTH, mm_answer_rsa_keyallowed}, 182 {MONITOR_REQ_KEYALLOWED, MON_ISAUTH, mm_answer_keyallowed}, 183 {MONITOR_REQ_RSACHALLENGE, MON_ONCE, mm_answer_rsa_challenge}, 184 {MONITOR_REQ_RSARESPONSE, MON_ONCE|MON_AUTHDECIDE, mm_answer_rsa_response}, 185 #ifdef BSD_AUTH 186 {MONITOR_REQ_BSDAUTHQUERY, MON_ISAUTH, mm_answer_bsdauthquery}, 187 {MONITOR_REQ_BSDAUTHRESPOND, MON_AUTH,mm_answer_bsdauthrespond}, 188 #endif 189 #ifdef SKEY 190 {MONITOR_REQ_SKEYQUERY, MON_ISAUTH, mm_answer_skeyquery}, 191 {MONITOR_REQ_SKEYRESPOND, MON_AUTH, mm_answer_skeyrespond}, 192 #endif 193 {0, 0, NULL} 194 }; 195 196 struct mon_table mon_dispatch_postauth15[] = { 197 {MONITOR_REQ_PTY, MON_ONCE, mm_answer_pty}, 198 {MONITOR_REQ_PTYCLEANUP, MON_ONCE, mm_answer_pty_cleanup}, 199 {MONITOR_REQ_TERM, 0, mm_answer_term}, 200 {0, 0, NULL} 201 }; 202 203 struct mon_table *mon_dispatch; 204 205 /* Specifies if a certain message is allowed at the moment */ 206 207 static void 208 monitor_permit(struct mon_table *ent, enum monitor_reqtype type, int permit) 209 { 210 while (ent->f != NULL) { 211 if (ent->type == type) { 212 ent->flags &= ~MON_PERMIT; 213 ent->flags |= permit ? MON_PERMIT : 0; 214 return; 215 } 216 ent++; 217 } 218 } 219 220 static void 221 monitor_permit_authentications(int permit) 222 { 223 struct mon_table *ent = mon_dispatch; 224 225 while (ent->f != NULL) { 226 if (ent->flags & MON_AUTH) { 227 ent->flags &= ~MON_PERMIT; 228 ent->flags |= permit ? MON_PERMIT : 0; 229 } 230 ent++; 231 } 232 } 233 234 Authctxt * 235 monitor_child_preauth(struct monitor *pmonitor) 236 { 237 struct mon_table *ent; 238 int authenticated = 0; 239 240 debug3("preauth child monitor started"); 241 242 if (compat20) { 243 mon_dispatch = mon_dispatch_proto20; 244 245 /* Permit requests for moduli and signatures */ 246 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 247 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 248 } else { 249 mon_dispatch = mon_dispatch_proto15; 250 251 monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); 252 } 253 254 authctxt = authctxt_new(); 255 256 /* The first few requests do not require asynchronous access */ 257 while (!authenticated) { 258 authenticated = monitor_read(pmonitor, mon_dispatch, &ent); 259 if (authenticated) { 260 if (!(ent->flags & MON_AUTHDECIDE)) 261 fatal("%s: unexpected authentication from %d", 262 __func__, ent->type); 263 if (authctxt->pw->pw_uid == 0 && 264 !auth_root_allowed(auth_method)) 265 authenticated = 0; 266 } 267 268 if (ent->flags & MON_AUTHDECIDE) { 269 auth_log(authctxt, authenticated, auth_method, 270 compat20 ? " ssh2" : ""); 271 if (!authenticated) 272 authctxt->failures++; 273 } 274 } 275 276 if (!authctxt->valid) 277 fatal("%s: authenticated invalid user", __func__); 278 279 debug("%s: %s has been authenticated by privileged process", 280 __func__, authctxt->user); 281 282 mm_get_keystate(pmonitor); 283 284 return (authctxt); 285 } 286 287 void 288 monitor_child_postauth(struct monitor *pmonitor) 289 { 290 if (compat20) { 291 mon_dispatch = mon_dispatch_postauth20; 292 293 /* Permit requests for moduli and signatures */ 294 monitor_permit(mon_dispatch, MONITOR_REQ_MODULI, 1); 295 monitor_permit(mon_dispatch, MONITOR_REQ_SIGN, 1); 296 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 297 298 } else { 299 mon_dispatch = mon_dispatch_postauth15; 300 monitor_permit(mon_dispatch, MONITOR_REQ_TERM, 1); 301 } 302 if (!no_pty_flag) { 303 monitor_permit(mon_dispatch, MONITOR_REQ_PTY, 1); 304 monitor_permit(mon_dispatch, MONITOR_REQ_PTYCLEANUP, 1); 305 } 306 307 for (;;) 308 monitor_read(pmonitor, mon_dispatch, NULL); 309 } 310 311 void 312 monitor_sync(struct monitor *pmonitor) 313 { 314 if (options.compression) { 315 /* The member allocation is not visible, so sync it */ 316 mm_share_sync(&pmonitor->m_zlib, &pmonitor->m_zback); 317 } 318 } 319 320 int 321 monitor_read(struct monitor *pmonitor, struct mon_table *ent, 322 struct mon_table **pent) 323 { 324 Buffer m; 325 int ret; 326 u_char type; 327 328 buffer_init(&m); 329 330 mm_request_receive(pmonitor->m_sendfd, &m); 331 type = buffer_get_char(&m); 332 333 debug3("%s: checking request %d", __func__, type); 334 335 while (ent->f != NULL) { 336 if (ent->type == type) 337 break; 338 ent++; 339 } 340 341 if (ent->f != NULL) { 342 if (!(ent->flags & MON_PERMIT)) 343 fatal("%s: unpermitted request %d", __func__, 344 type); 345 ret = (*ent->f)(pmonitor->m_sendfd, &m); 346 buffer_free(&m); 347 348 /* The child may use this request only once, disable it */ 349 if (ent->flags & MON_ONCE) { 350 debug2("%s: %d used once, disabling now", __func__, 351 type); 352 ent->flags &= ~MON_PERMIT; 353 } 354 355 if (pent != NULL) 356 *pent = ent; 357 358 return ret; 359 } 360 361 fatal("%s: unsupported request: %d", __func__, type); 362 363 /* NOTREACHED */ 364 return (-1); 365 } 366 367 /* allowed key state */ 368 static int 369 monitor_allowed_key(u_char *blob, u_int bloblen) 370 { 371 /* make sure key is allowed */ 372 if (key_blob == NULL || key_bloblen != bloblen || 373 memcmp(key_blob, blob, key_bloblen)) 374 return (0); 375 return (1); 376 } 377 378 static void 379 monitor_reset_key_state(void) 380 { 381 /* reset state */ 382 if (key_blob != NULL) 383 xfree(key_blob); 384 if (hostbased_cuser != NULL) 385 xfree(hostbased_cuser); 386 if (hostbased_chost != NULL) 387 xfree(hostbased_chost); 388 key_blob = NULL; 389 key_bloblen = 0; 390 key_blobtype = MM_NOKEY; 391 hostbased_cuser = NULL; 392 hostbased_chost = NULL; 393 } 394 395 int 396 mm_answer_moduli(int socket, Buffer *m) 397 { 398 DH *dh; 399 int min, want, max; 400 401 min = buffer_get_int(m); 402 want = buffer_get_int(m); 403 max = buffer_get_int(m); 404 405 debug3("%s: got parameters: %d %d %d", 406 __func__, min, want, max); 407 /* We need to check here, too, in case the child got corrupted */ 408 if (max < min || want < min || max < want) 409 fatal("%s: bad parameters: %d %d %d", 410 __func__, min, want, max); 411 412 buffer_clear(m); 413 414 dh = choose_dh(min, want, max); 415 if (dh == NULL) { 416 buffer_put_char(m, 0); 417 return (0); 418 } else { 419 /* Send first bignum */ 420 buffer_put_char(m, 1); 421 buffer_put_bignum2(m, dh->p); 422 buffer_put_bignum2(m, dh->g); 423 424 DH_free(dh); 425 } 426 mm_request_send(socket, MONITOR_ANS_MODULI, m); 427 return (0); 428 } 429 430 int 431 mm_answer_sign(int socket, Buffer *m) 432 { 433 Key *key; 434 u_char *p; 435 u_char *signature; 436 u_int siglen, datlen; 437 int keyid; 438 439 debug3("%s", __func__); 440 441 keyid = buffer_get_int(m); 442 p = buffer_get_string(m, &datlen); 443 444 if (datlen != 20) 445 fatal("%s: data length incorrect: %d", __func__, datlen); 446 447 /* save session id, it will be passed on the first call */ 448 if (session_id2_len == 0) { 449 session_id2_len = datlen; 450 session_id2 = xmalloc(session_id2_len); 451 memcpy(session_id2, p, session_id2_len); 452 } 453 454 if ((key = get_hostkey_by_index(keyid)) == NULL) 455 fatal("%s: no hostkey from index %d", __func__, keyid); 456 if (key_sign(key, &signature, &siglen, p, datlen) < 0) 457 fatal("%s: key_sign failed", __func__); 458 459 debug3("%s: signature %p(%d)", __func__, signature, siglen); 460 461 buffer_clear(m); 462 buffer_put_string(m, signature, siglen); 463 464 xfree(p); 465 xfree(signature); 466 467 mm_request_send(socket, MONITOR_ANS_SIGN, m); 468 469 /* Turn on permissions for getpwnam */ 470 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); 471 472 return (0); 473 } 474 475 /* Retrieves the password entry and also checks if the user is permitted */ 476 477 int 478 mm_answer_pwnamallow(int socket, Buffer *m) 479 { 480 char *login; 481 struct passwd *pwent; 482 int allowed = 0; 483 484 debug3("%s", __func__); 485 486 if (authctxt->attempt++ != 0) 487 fatal("%s: multiple attempts for getpwnam", __func__); 488 489 login = buffer_get_string(m, NULL); 490 491 pwent = getpwnamallow(login); 492 493 authctxt->user = xstrdup(login); 494 setproctitle("%s [priv]", pwent ? login : "unknown"); 495 xfree(login); 496 497 buffer_clear(m); 498 499 if (pwent == NULL) { 500 buffer_put_char(m, 0); 501 goto out; 502 } 503 504 allowed = 1; 505 authctxt->pw = pwent; 506 authctxt->valid = 1; 507 508 buffer_put_char(m, 1); 509 buffer_put_string(m, pwent, sizeof(struct passwd)); 510 buffer_put_cstring(m, pwent->pw_name); 511 buffer_put_cstring(m, "*"); 512 buffer_put_cstring(m, pwent->pw_gecos); 513 buffer_put_cstring(m, pwent->pw_class); 514 buffer_put_cstring(m, pwent->pw_dir); 515 buffer_put_cstring(m, pwent->pw_shell); 516 517 out: 518 debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); 519 mm_request_send(socket, MONITOR_ANS_PWNAM, m); 520 521 /* For SSHv1 allow authentication now */ 522 if (!compat20) 523 monitor_permit_authentications(1); 524 else { 525 /* Allow service/style information on the auth context */ 526 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); 527 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); 528 } 529 530 531 return (0); 532 } 533 534 int mm_answer_auth2_read_banner(int socket, Buffer *m) 535 { 536 char *banner; 537 538 buffer_clear(m); 539 banner = auth2_read_banner(); 540 buffer_put_cstring(m, banner != NULL ? banner : ""); 541 mm_request_send(socket, MONITOR_ANS_AUTH2_READ_BANNER, m); 542 543 if (banner != NULL) 544 free(banner); 545 546 return (0); 547 } 548 549 int 550 mm_answer_authserv(int socket, Buffer *m) 551 { 552 monitor_permit_authentications(1); 553 554 authctxt->service = buffer_get_string(m, NULL); 555 authctxt->style = buffer_get_string(m, NULL); 556 debug3("%s: service=%s, style=%s", 557 __func__, authctxt->service, authctxt->style); 558 559 if (strlen(authctxt->style) == 0) { 560 xfree(authctxt->style); 561 authctxt->style = NULL; 562 } 563 564 return (0); 565 } 566 567 int 568 mm_answer_authpassword(int socket, Buffer *m) 569 { 570 static int call_count; 571 char *passwd; 572 int authenticated, plen; 573 574 passwd = buffer_get_string(m, &plen); 575 /* Only authenticate if the context is valid */ 576 authenticated = options.password_authentication && 577 authctxt->valid && auth_password(authctxt, passwd); 578 memset(passwd, 0, strlen(passwd)); 579 xfree(passwd); 580 581 buffer_clear(m); 582 buffer_put_int(m, authenticated); 583 584 debug3("%s: sending result %d", __func__, authenticated); 585 mm_request_send(socket, MONITOR_ANS_AUTHPASSWORD, m); 586 587 call_count++; 588 if (plen == 0 && call_count == 1) 589 auth_method = "none"; 590 else 591 auth_method = "password"; 592 593 /* Causes monitor loop to terminate if authenticated */ 594 return (authenticated); 595 } 596 597 #ifdef BSD_AUTH 598 int 599 mm_answer_bsdauthquery(int socket, Buffer *m) 600 { 601 char *name, *infotxt; 602 u_int numprompts; 603 u_int *echo_on; 604 char **prompts; 605 int res; 606 607 res = bsdauth_query(authctxt, &name, &infotxt, &numprompts, 608 &prompts, &echo_on); 609 610 buffer_clear(m); 611 buffer_put_int(m, res); 612 if (res != -1) 613 buffer_put_cstring(m, prompts[0]); 614 615 debug3("%s: sending challenge res: %d", __func__, res); 616 mm_request_send(socket, MONITOR_ANS_BSDAUTHQUERY, m); 617 618 if (res != -1) { 619 xfree(name); 620 xfree(infotxt); 621 xfree(prompts); 622 xfree(echo_on); 623 } 624 625 return (0); 626 } 627 628 int 629 mm_answer_bsdauthrespond(int socket, Buffer *m) 630 { 631 char *response; 632 int authok; 633 634 if (authctxt->as == 0) 635 fatal("%s: no bsd auth session", __func__); 636 637 response = buffer_get_string(m, NULL); 638 authok = options.challenge_response_authentication && 639 auth_userresponse(authctxt->as, response, 0); 640 authctxt->as = NULL; 641 debug3("%s: <%s> = <%d>", __func__, response, authok); 642 xfree(response); 643 644 buffer_clear(m); 645 buffer_put_int(m, authok); 646 647 debug3("%s: sending authenticated: %d", __func__, authok); 648 mm_request_send(socket, MONITOR_ANS_BSDAUTHRESPOND, m); 649 650 auth_method = "bsdauth"; 651 652 return (authok != 0); 653 } 654 #endif 655 656 #ifdef SKEY 657 int 658 mm_answer_skeyquery(int socket, Buffer *m) 659 { 660 struct opie opie; 661 char challenge[1024]; 662 int res; 663 664 res = opiechallenge(&opie, authctxt->user, challenge); 665 666 buffer_clear(m); 667 buffer_put_int(m, res); 668 if (res != -1) 669 buffer_put_cstring(m, challenge); 670 671 debug3("%s: sending challenge res: %d", __func__, res); 672 mm_request_send(socket, MONITOR_ANS_SKEYQUERY, m); 673 674 return (0); 675 } 676 677 int 678 mm_answer_skeyrespond(int socket, Buffer *m) 679 { 680 char *response; 681 int authok; 682 683 response = buffer_get_string(m, NULL); 684 685 authok = (options.challenge_response_authentication && 686 authctxt->valid && 687 opie_haskey(authctxt->pw->pw_name) == 0 && 688 opie_passverify(authctxt->pw->pw_name, response) != -1); 689 690 xfree(response); 691 692 buffer_clear(m); 693 buffer_put_int(m, authok); 694 695 debug3("%s: sending authenticated: %d", __func__, authok); 696 mm_request_send(socket, MONITOR_ANS_SKEYRESPOND, m); 697 698 auth_method = "skey"; 699 700 return (authok != 0); 701 } 702 #endif 703 704 static void 705 mm_append_debug(Buffer *m) 706 { 707 if (auth_debug_init && buffer_len(&auth_debug)) { 708 debug3("%s: Appending debug messages for child", __func__); 709 buffer_append(m, buffer_ptr(&auth_debug), 710 buffer_len(&auth_debug)); 711 buffer_clear(&auth_debug); 712 } 713 } 714 715 int 716 mm_answer_keyallowed(int socket, Buffer *m) 717 { 718 Key *key; 719 u_char *cuser, *chost, *blob; 720 u_int bloblen; 721 enum mm_keytype type = 0; 722 int allowed = 0; 723 724 debug3("%s entering", __func__); 725 726 type = buffer_get_int(m); 727 cuser = buffer_get_string(m, NULL); 728 chost = buffer_get_string(m, NULL); 729 blob = buffer_get_string(m, &bloblen); 730 731 key = key_from_blob(blob, bloblen); 732 733 if ((compat20 && type == MM_RSAHOSTKEY) || 734 (!compat20 && type != MM_RSAHOSTKEY)) 735 fatal("%s: key type and protocol mismatch", __func__); 736 737 debug3("%s: key_from_blob: %p", __func__, key); 738 739 if (key != NULL && authctxt->pw != NULL) { 740 switch(type) { 741 case MM_USERKEY: 742 allowed = options.pubkey_authentication && 743 user_key_allowed(authctxt->pw, key); 744 break; 745 case MM_HOSTKEY: 746 allowed = options.hostbased_authentication && 747 hostbased_key_allowed(authctxt->pw, 748 cuser, chost, key); 749 break; 750 case MM_RSAHOSTKEY: 751 key->type = KEY_RSA1; /* XXX */ 752 allowed = options.rhosts_rsa_authentication && 753 auth_rhosts_rsa_key_allowed(authctxt->pw, 754 cuser, chost, key); 755 break; 756 default: 757 fatal("%s: unknown key type %d", __func__, type); 758 break; 759 } 760 key_free(key); 761 } 762 763 /* clear temporarily storage (used by verify) */ 764 monitor_reset_key_state(); 765 766 if (allowed) { 767 /* Save temporarily for comparison in verify */ 768 key_blob = blob; 769 key_bloblen = bloblen; 770 key_blobtype = type; 771 hostbased_cuser = cuser; 772 hostbased_chost = chost; 773 } 774 775 debug3("%s: key %p is %s", 776 __func__, key, allowed ? "allowed" : "disallowed"); 777 778 buffer_clear(m); 779 buffer_put_int(m, allowed); 780 781 mm_append_debug(m); 782 783 mm_request_send(socket, MONITOR_ANS_KEYALLOWED, m); 784 785 if (type == MM_RSAHOSTKEY) 786 monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); 787 788 return (0); 789 } 790 791 static int 792 monitor_valid_userblob(u_char *data, u_int datalen) 793 { 794 Buffer b; 795 u_char *p; 796 u_int len; 797 int fail = 0; 798 799 buffer_init(&b); 800 buffer_append(&b, data, datalen); 801 802 if (datafellows & SSH_OLD_SESSIONID) { 803 p = buffer_ptr(&b); 804 len = buffer_len(&b); 805 if ((session_id2 == NULL) || 806 (len < session_id2_len) || 807 (memcmp(p, session_id2, session_id2_len) != 0)) 808 fail++; 809 buffer_consume(&b, session_id2_len); 810 } else { 811 p = buffer_get_string(&b, &len); 812 if ((session_id2 == NULL) || 813 (len != session_id2_len) || 814 (memcmp(p, session_id2, session_id2_len) != 0)) 815 fail++; 816 xfree(p); 817 } 818 if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) 819 fail++; 820 p = buffer_get_string(&b, NULL); 821 if (strcmp(authctxt->user, p) != 0) { 822 log("wrong user name passed to monitor: expected %s != %.100s", 823 authctxt->user, p); 824 fail++; 825 } 826 xfree(p); 827 buffer_skip_string(&b); 828 if (datafellows & SSH_BUG_PKAUTH) { 829 if (!buffer_get_char(&b)) 830 fail++; 831 } else { 832 p = buffer_get_string(&b, NULL); 833 if (strcmp("publickey", p) != 0) 834 fail++; 835 xfree(p); 836 if (!buffer_get_char(&b)) 837 fail++; 838 buffer_skip_string(&b); 839 } 840 buffer_skip_string(&b); 841 if (buffer_len(&b) != 0) 842 fail++; 843 buffer_free(&b); 844 return (fail == 0); 845 } 846 847 static int 848 monitor_valid_hostbasedblob(u_char *data, u_int datalen, u_char *cuser, 849 u_char *chost) 850 { 851 Buffer b; 852 u_char *p; 853 u_int len; 854 int fail = 0; 855 856 buffer_init(&b); 857 buffer_append(&b, data, datalen); 858 859 p = buffer_get_string(&b, &len); 860 if ((session_id2 == NULL) || 861 (len != session_id2_len) || 862 (memcmp(p, session_id2, session_id2_len) != 0)) 863 fail++; 864 xfree(p); 865 866 if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST) 867 fail++; 868 p = buffer_get_string(&b, NULL); 869 if (strcmp(authctxt->user, p) != 0) { 870 log("wrong user name passed to monitor: expected %s != %.100s", 871 authctxt->user, p); 872 fail++; 873 } 874 xfree(p); 875 buffer_skip_string(&b); /* service */ 876 p = buffer_get_string(&b, NULL); 877 if (strcmp(p, "hostbased") != 0) 878 fail++; 879 xfree(p); 880 buffer_skip_string(&b); /* pkalg */ 881 buffer_skip_string(&b); /* pkblob */ 882 883 /* verify client host, strip trailing dot if necessary */ 884 p = buffer_get_string(&b, NULL); 885 if (((len = strlen(p)) > 0) && p[len - 1] == '.') 886 p[len - 1] = '\0'; 887 if (strcmp(p, chost) != 0) 888 fail++; 889 xfree(p); 890 891 /* verify client user */ 892 p = buffer_get_string(&b, NULL); 893 if (strcmp(p, cuser) != 0) 894 fail++; 895 xfree(p); 896 897 if (buffer_len(&b) != 0) 898 fail++; 899 buffer_free(&b); 900 return (fail == 0); 901 } 902 903 int 904 mm_answer_keyverify(int socket, Buffer *m) 905 { 906 Key *key; 907 u_char *signature, *data, *blob; 908 u_int signaturelen, datalen, bloblen; 909 int verified = 0; 910 int valid_data = 0; 911 912 blob = buffer_get_string(m, &bloblen); 913 signature = buffer_get_string(m, &signaturelen); 914 data = buffer_get_string(m, &datalen); 915 916 if (hostbased_cuser == NULL || hostbased_chost == NULL || 917 !monitor_allowed_key(blob, bloblen)) 918 fatal("%s: bad key, not previously allowed", __func__); 919 920 key = key_from_blob(blob, bloblen); 921 if (key == NULL) 922 fatal("%s: bad public key blob", __func__); 923 924 switch (key_blobtype) { 925 case MM_USERKEY: 926 valid_data = monitor_valid_userblob(data, datalen); 927 break; 928 case MM_HOSTKEY: 929 valid_data = monitor_valid_hostbasedblob(data, datalen, 930 hostbased_cuser, hostbased_chost); 931 break; 932 default: 933 valid_data = 0; 934 break; 935 } 936 if (!valid_data) 937 fatal("%s: bad signature data blob", __func__); 938 939 verified = key_verify(key, signature, signaturelen, data, datalen); 940 debug3("%s: key %p signature %s", 941 __func__, key, verified ? "verified" : "unverified"); 942 943 key_free(key); 944 xfree(blob); 945 xfree(signature); 946 xfree(data); 947 948 monitor_reset_key_state(); 949 950 buffer_clear(m); 951 buffer_put_int(m, verified); 952 mm_request_send(socket, MONITOR_ANS_KEYVERIFY, m); 953 954 auth_method = key_blobtype == MM_USERKEY ? "publickey" : "hostbased"; 955 956 return (verified); 957 } 958 959 static void 960 mm_record_login(Session *s, struct passwd *pw) 961 { 962 socklen_t fromlen; 963 struct sockaddr_storage from; 964 965 /* 966 * Get IP address of client. If the connection is not a socket, let 967 * the address be 0.0.0.0. 968 */ 969 memset(&from, 0, sizeof(from)); 970 if (packet_connection_is_on_socket()) { 971 fromlen = sizeof(from); 972 if (getpeername(packet_get_connection_in(), 973 (struct sockaddr *) & from, &fromlen) < 0) { 974 debug("getpeername: %.100s", strerror(errno)); 975 fatal_cleanup(); 976 } 977 } 978 /* Record that there was a login on that tty from the remote host. */ 979 record_login(s->pid, s->tty, pw->pw_name, pw->pw_uid, 980 get_remote_name_or_ip(utmp_len, options.verify_reverse_mapping), 981 (struct sockaddr *)&from); 982 } 983 984 static void 985 mm_session_close(Session *s) 986 { 987 debug3("%s: session %d pid %d", __func__, s->self, s->pid); 988 if (s->ttyfd != -1) { 989 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ptyfd); 990 fatal_remove_cleanup(session_pty_cleanup2, (void *)s); 991 session_pty_cleanup2(s); 992 } 993 s->used = 0; 994 } 995 996 int 997 mm_answer_pty(int socket, Buffer *m) 998 { 999 extern struct monitor *pmonitor; 1000 Session *s; 1001 int res, fd0; 1002 1003 debug3("%s entering", __func__); 1004 1005 buffer_clear(m); 1006 s = session_new(); 1007 if (s == NULL) 1008 goto error; 1009 s->authctxt = authctxt; 1010 s->pw = authctxt->pw; 1011 s->pid = pmonitor->m_pid; 1012 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty)); 1013 if (res == 0) 1014 goto error; 1015 fatal_add_cleanup(session_pty_cleanup2, (void *)s); 1016 pty_setowner(authctxt->pw, s->tty); 1017 1018 buffer_put_int(m, 1); 1019 buffer_put_cstring(m, s->tty); 1020 mm_request_send(socket, MONITOR_ANS_PTY, m); 1021 1022 mm_send_fd(socket, s->ptyfd); 1023 mm_send_fd(socket, s->ttyfd); 1024 1025 /* We need to trick ttyslot */ 1026 if (dup2(s->ttyfd, 0) == -1) 1027 fatal("%s: dup2", __func__); 1028 1029 mm_record_login(s, authctxt->pw); 1030 1031 /* Now we can close the file descriptor again */ 1032 close(0); 1033 1034 /* make sure nothing uses fd 0 */ 1035 if ((fd0 = open(_PATH_DEVNULL, O_RDONLY)) < 0) 1036 fatal("%s: open(/dev/null): %s", __func__, strerror(errno)); 1037 if (fd0 != 0) 1038 error("%s: fd0 %d != 0", __func__, fd0); 1039 1040 /* slave is not needed */ 1041 close(s->ttyfd); 1042 s->ttyfd = s->ptyfd; 1043 /* no need to dup() because nobody closes ptyfd */ 1044 s->ptymaster = s->ptyfd; 1045 1046 debug3("%s: tty %s ptyfd %d", __func__, s->tty, s->ttyfd); 1047 1048 return (0); 1049 1050 error: 1051 if (s != NULL) 1052 mm_session_close(s); 1053 buffer_put_int(m, 0); 1054 mm_request_send(socket, MONITOR_ANS_PTY, m); 1055 return (0); 1056 } 1057 1058 int 1059 mm_answer_pty_cleanup(int socket, Buffer *m) 1060 { 1061 Session *s; 1062 char *tty; 1063 1064 debug3("%s entering", __func__); 1065 1066 tty = buffer_get_string(m, NULL); 1067 if ((s = session_by_tty(tty)) != NULL) 1068 mm_session_close(s); 1069 buffer_clear(m); 1070 xfree(tty); 1071 return (0); 1072 } 1073 1074 int 1075 mm_answer_sesskey(int socket, Buffer *m) 1076 { 1077 BIGNUM *p; 1078 int rsafail; 1079 1080 /* Turn off permissions */ 1081 monitor_permit(mon_dispatch, MONITOR_REQ_SESSKEY, 1); 1082 1083 if ((p = BN_new()) == NULL) 1084 fatal("%s: BN_new", __func__); 1085 1086 buffer_get_bignum2(m, p); 1087 1088 rsafail = ssh1_session_key(p); 1089 1090 buffer_clear(m); 1091 buffer_put_int(m, rsafail); 1092 buffer_put_bignum2(m, p); 1093 1094 BN_clear_free(p); 1095 1096 mm_request_send(socket, MONITOR_ANS_SESSKEY, m); 1097 1098 /* Turn on permissions for sessid passing */ 1099 monitor_permit(mon_dispatch, MONITOR_REQ_SESSID, 1); 1100 1101 return (0); 1102 } 1103 1104 int 1105 mm_answer_sessid(int socket, Buffer *m) 1106 { 1107 int i; 1108 1109 debug3("%s entering", __func__); 1110 1111 if (buffer_len(m) != 16) 1112 fatal("%s: bad ssh1 session id", __func__); 1113 for (i = 0; i < 16; i++) 1114 session_id[i] = buffer_get_char(m); 1115 1116 /* Turn on permissions for getpwnam */ 1117 monitor_permit(mon_dispatch, MONITOR_REQ_PWNAM, 1); 1118 1119 return (0); 1120 } 1121 1122 int 1123 mm_answer_rsa_keyallowed(int socket, Buffer *m) 1124 { 1125 BIGNUM *client_n; 1126 Key *key = NULL; 1127 u_char *blob = NULL; 1128 u_int blen = 0; 1129 int allowed = 0; 1130 1131 debug3("%s entering", __func__); 1132 1133 if (options.rsa_authentication && authctxt->valid) { 1134 if ((client_n = BN_new()) == NULL) 1135 fatal("%s: BN_new", __func__); 1136 buffer_get_bignum2(m, client_n); 1137 allowed = auth_rsa_key_allowed(authctxt->pw, client_n, &key); 1138 BN_clear_free(client_n); 1139 } 1140 buffer_clear(m); 1141 buffer_put_int(m, allowed); 1142 1143 /* clear temporarily storage (used by generate challenge) */ 1144 monitor_reset_key_state(); 1145 1146 if (allowed && key != NULL) { 1147 key->type = KEY_RSA; /* cheat for key_to_blob */ 1148 if (key_to_blob(key, &blob, &blen) == 0) 1149 fatal("%s: key_to_blob failed", __func__); 1150 buffer_put_string(m, blob, blen); 1151 1152 /* Save temporarily for comparison in verify */ 1153 key_blob = blob; 1154 key_bloblen = blen; 1155 key_blobtype = MM_RSAUSERKEY; 1156 key_free(key); 1157 } 1158 1159 mm_append_debug(m); 1160 1161 mm_request_send(socket, MONITOR_ANS_RSAKEYALLOWED, m); 1162 1163 monitor_permit(mon_dispatch, MONITOR_REQ_RSACHALLENGE, allowed); 1164 monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 0); 1165 return (0); 1166 } 1167 1168 int 1169 mm_answer_rsa_challenge(int socket, Buffer *m) 1170 { 1171 Key *key = NULL; 1172 u_char *blob; 1173 u_int blen; 1174 1175 debug3("%s entering", __func__); 1176 1177 if (!authctxt->valid) 1178 fatal("%s: authctxt not valid", __func__); 1179 blob = buffer_get_string(m, &blen); 1180 if (!monitor_allowed_key(blob, blen)) 1181 fatal("%s: bad key, not previously allowed", __func__); 1182 if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) 1183 fatal("%s: key type mismatch", __func__); 1184 if ((key = key_from_blob(blob, blen)) == NULL) 1185 fatal("%s: received bad key", __func__); 1186 1187 if (ssh1_challenge) 1188 BN_clear_free(ssh1_challenge); 1189 ssh1_challenge = auth_rsa_generate_challenge(key); 1190 1191 buffer_clear(m); 1192 buffer_put_bignum2(m, ssh1_challenge); 1193 1194 debug3("%s sending reply", __func__); 1195 mm_request_send(socket, MONITOR_ANS_RSACHALLENGE, m); 1196 1197 monitor_permit(mon_dispatch, MONITOR_REQ_RSARESPONSE, 1); 1198 return (0); 1199 } 1200 1201 int 1202 mm_answer_rsa_response(int socket, Buffer *m) 1203 { 1204 Key *key = NULL; 1205 u_char *blob, *response; 1206 u_int blen, len; 1207 int success; 1208 1209 debug3("%s entering", __func__); 1210 1211 if (!authctxt->valid) 1212 fatal("%s: authctxt not valid", __func__); 1213 if (ssh1_challenge == NULL) 1214 fatal("%s: no ssh1_challenge", __func__); 1215 1216 blob = buffer_get_string(m, &blen); 1217 if (!monitor_allowed_key(blob, blen)) 1218 fatal("%s: bad key, not previously allowed", __func__); 1219 if (key_blobtype != MM_RSAUSERKEY && key_blobtype != MM_RSAHOSTKEY) 1220 fatal("%s: key type mismatch: %d", __func__, key_blobtype); 1221 if ((key = key_from_blob(blob, blen)) == NULL) 1222 fatal("%s: received bad key", __func__); 1223 response = buffer_get_string(m, &len); 1224 if (len != 16) 1225 fatal("%s: received bad response to challenge", __func__); 1226 success = auth_rsa_verify_response(key, ssh1_challenge, response); 1227 1228 key_free(key); 1229 xfree(response); 1230 1231 auth_method = key_blobtype == MM_RSAUSERKEY ? "rsa" : "rhosts-rsa"; 1232 1233 /* reset state */ 1234 BN_clear_free(ssh1_challenge); 1235 ssh1_challenge = NULL; 1236 monitor_reset_key_state(); 1237 1238 buffer_clear(m); 1239 buffer_put_int(m, success); 1240 mm_request_send(socket, MONITOR_ANS_RSARESPONSE, m); 1241 1242 return (success); 1243 } 1244 1245 int 1246 mm_answer_term(int socket, Buffer *req) 1247 { 1248 extern struct monitor *pmonitor; 1249 int res, status; 1250 1251 debug3("%s: tearing down sessions", __func__); 1252 1253 /* The child is terminating */ 1254 session_destroy_all(&mm_session_close); 1255 1256 while (waitpid(pmonitor->m_pid, &status, 0) == -1) 1257 if (errno != EINTR) 1258 exit(1); 1259 1260 res = WIFEXITED(status) ? WEXITSTATUS(status) : 1; 1261 1262 /* Terminate process */ 1263 exit (res); 1264 } 1265 1266 void 1267 monitor_apply_keystate(struct monitor *pmonitor) 1268 { 1269 if (compat20) { 1270 set_newkeys(MODE_IN); 1271 set_newkeys(MODE_OUT); 1272 } else { 1273 packet_set_protocol_flags(child_state.ssh1protoflags); 1274 packet_set_encryption_key(child_state.ssh1key, 1275 child_state.ssh1keylen, child_state.ssh1cipher); 1276 xfree(child_state.ssh1key); 1277 } 1278 1279 /* for rc4 and other stateful ciphers */ 1280 packet_set_keycontext(MODE_OUT, child_state.keyout); 1281 xfree(child_state.keyout); 1282 packet_set_keycontext(MODE_IN, child_state.keyin); 1283 xfree(child_state.keyin); 1284 1285 if (!compat20) { 1286 packet_set_iv(MODE_OUT, child_state.ivout); 1287 xfree(child_state.ivout); 1288 packet_set_iv(MODE_IN, child_state.ivin); 1289 xfree(child_state.ivin); 1290 } 1291 1292 memcpy(&incoming_stream, &child_state.incoming, 1293 sizeof(incoming_stream)); 1294 memcpy(&outgoing_stream, &child_state.outgoing, 1295 sizeof(outgoing_stream)); 1296 1297 /* Update with new address */ 1298 if (options.compression) 1299 mm_init_compression(pmonitor->m_zlib); 1300 1301 /* Network I/O buffers */ 1302 /* XXX inefficient for large buffers, need: buffer_init_from_string */ 1303 buffer_clear(&input); 1304 buffer_append(&input, child_state.input, child_state.ilen); 1305 memset(child_state.input, 0, child_state.ilen); 1306 xfree(child_state.input); 1307 1308 buffer_clear(&output); 1309 buffer_append(&output, child_state.output, child_state.olen); 1310 memset(child_state.output, 0, child_state.olen); 1311 xfree(child_state.output); 1312 } 1313 1314 static Kex * 1315 mm_get_kex(Buffer *m) 1316 { 1317 Kex *kex; 1318 void *blob; 1319 u_int bloblen; 1320 1321 kex = xmalloc(sizeof(*kex)); 1322 memset(kex, 0, sizeof(*kex)); 1323 kex->session_id = buffer_get_string(m, &kex->session_id_len); 1324 if ((session_id2 == NULL) || 1325 (kex->session_id_len != session_id2_len) || 1326 (memcmp(kex->session_id, session_id2, session_id2_len) != 0)) 1327 fatal("mm_get_get: internal error: bad session id"); 1328 kex->we_need = buffer_get_int(m); 1329 kex->server = 1; 1330 kex->hostkey_type = buffer_get_int(m); 1331 kex->kex_type = buffer_get_int(m); 1332 blob = buffer_get_string(m, &bloblen); 1333 buffer_init(&kex->my); 1334 buffer_append(&kex->my, blob, bloblen); 1335 xfree(blob); 1336 blob = buffer_get_string(m, &bloblen); 1337 buffer_init(&kex->peer); 1338 buffer_append(&kex->peer, blob, bloblen); 1339 xfree(blob); 1340 kex->done = 1; 1341 kex->flags = buffer_get_int(m); 1342 kex->client_version_string = buffer_get_string(m, NULL); 1343 kex->server_version_string = buffer_get_string(m, NULL); 1344 kex->load_host_key=&get_hostkey_by_type; 1345 kex->host_key_index=&get_hostkey_index; 1346 1347 return (kex); 1348 } 1349 1350 /* This function requries careful sanity checking */ 1351 1352 void 1353 mm_get_keystate(struct monitor *pmonitor) 1354 { 1355 Buffer m; 1356 u_char *blob, *p; 1357 u_int bloblen, plen; 1358 1359 debug3("%s: Waiting for new keys", __func__); 1360 1361 buffer_init(&m); 1362 mm_request_receive_expect(pmonitor->m_sendfd, MONITOR_REQ_KEYEXPORT, &m); 1363 if (!compat20) { 1364 child_state.ssh1protoflags = buffer_get_int(&m); 1365 child_state.ssh1cipher = buffer_get_int(&m); 1366 child_state.ssh1key = buffer_get_string(&m, 1367 &child_state.ssh1keylen); 1368 child_state.ivout = buffer_get_string(&m, 1369 &child_state.ivoutlen); 1370 child_state.ivin = buffer_get_string(&m, &child_state.ivinlen); 1371 goto skip; 1372 } else { 1373 /* Get the Kex for rekeying */ 1374 *pmonitor->m_pkex = mm_get_kex(&m); 1375 } 1376 1377 blob = buffer_get_string(&m, &bloblen); 1378 current_keys[MODE_OUT] = mm_newkeys_from_blob(blob, bloblen); 1379 xfree(blob); 1380 1381 debug3("%s: Waiting for second key", __func__); 1382 blob = buffer_get_string(&m, &bloblen); 1383 current_keys[MODE_IN] = mm_newkeys_from_blob(blob, bloblen); 1384 xfree(blob); 1385 1386 /* Now get sequence numbers for the packets */ 1387 packet_set_seqnr(MODE_OUT, buffer_get_int(&m)); 1388 packet_set_seqnr(MODE_IN, buffer_get_int(&m)); 1389 1390 skip: 1391 /* Get the key context */ 1392 child_state.keyout = buffer_get_string(&m, &child_state.keyoutlen); 1393 child_state.keyin = buffer_get_string(&m, &child_state.keyinlen); 1394 1395 debug3("%s: Getting compression state", __func__); 1396 /* Get compression state */ 1397 p = buffer_get_string(&m, &plen); 1398 if (plen != sizeof(child_state.outgoing)) 1399 fatal("%s: bad request size", __func__); 1400 memcpy(&child_state.outgoing, p, sizeof(child_state.outgoing)); 1401 xfree(p); 1402 1403 p = buffer_get_string(&m, &plen); 1404 if (plen != sizeof(child_state.incoming)) 1405 fatal("%s: bad request size", __func__); 1406 memcpy(&child_state.incoming, p, sizeof(child_state.incoming)); 1407 xfree(p); 1408 1409 /* Network I/O buffers */ 1410 debug3("%s: Getting Network I/O buffers", __func__); 1411 child_state.input = buffer_get_string(&m, &child_state.ilen); 1412 child_state.output = buffer_get_string(&m, &child_state.olen); 1413 1414 buffer_free(&m); 1415 } 1416 1417 1418 /* Allocation functions for zlib */ 1419 void * 1420 mm_zalloc(struct mm_master *mm, u_int ncount, u_int size) 1421 { 1422 void *address; 1423 1424 address = mm_malloc(mm, size * ncount); 1425 1426 return (address); 1427 } 1428 1429 void 1430 mm_zfree(struct mm_master *mm, void *address) 1431 { 1432 mm_free(mm, address); 1433 } 1434 1435 void 1436 mm_init_compression(struct mm_master *mm) 1437 { 1438 outgoing_stream.zalloc = (alloc_func)mm_zalloc; 1439 outgoing_stream.zfree = (free_func)mm_zfree; 1440 outgoing_stream.opaque = mm; 1441 1442 incoming_stream.zalloc = (alloc_func)mm_zalloc; 1443 incoming_stream.zfree = (free_func)mm_zfree; 1444 incoming_stream.opaque = mm; 1445 } 1446 1447 /* XXX */ 1448 1449 #define FD_CLOSEONEXEC(x) do { \ 1450 if (fcntl(x, F_SETFD, 1) == -1) \ 1451 fatal("fcntl(%d, F_SETFD)", x); \ 1452 } while (0) 1453 1454 static void 1455 monitor_socketpair(int *pair) 1456 { 1457 if (socketpair(AF_UNIX, SOCK_STREAM, 0, pair) == -1) 1458 fatal("%s: socketpair", __func__); 1459 FD_CLOSEONEXEC(pair[0]); 1460 FD_CLOSEONEXEC(pair[1]); 1461 } 1462 1463 #define MM_MEMSIZE 65536 1464 1465 struct monitor * 1466 monitor_init(void) 1467 { 1468 struct monitor *mon; 1469 int pair[2]; 1470 1471 mon = xmalloc(sizeof(*mon)); 1472 1473 monitor_socketpair(pair); 1474 1475 mon->m_recvfd = pair[0]; 1476 mon->m_sendfd = pair[1]; 1477 1478 /* Used to share zlib space across processes */ 1479 if (options.compression) { 1480 mon->m_zback = mm_create(NULL, MM_MEMSIZE); 1481 mon->m_zlib = mm_create(mon->m_zback, 20 * MM_MEMSIZE); 1482 1483 /* Compression needs to share state across borders */ 1484 mm_init_compression(mon->m_zlib); 1485 } 1486 1487 return mon; 1488 } 1489 1490 void 1491 monitor_reinit(struct monitor *mon) 1492 { 1493 int pair[2]; 1494 1495 monitor_socketpair(pair); 1496 1497 mon->m_recvfd = pair[0]; 1498 mon->m_sendfd = pair[1]; 1499 } 1500