1 /* 2 * CDDL HEADER START 3 * 4 * The contents of this file are subject to the terms of the 5 * Common Development and Distribution License (the "License"). 6 * You may not use this file except in compliance with the License. 7 * 8 * You can obtain a copy of the license at usr/src/OPENSOLARIS.LICENSE 9 * or http://www.opensolaris.org/os/licensing. 10 * See the License for the specific language governing permissions 11 * and limitations under the License. 12 * 13 * When distributing Covered Code, include this CDDL HEADER in each 14 * file and include the License file at usr/src/OPENSOLARIS.LICENSE. 15 * If applicable, add the following below this CDDL HEADER, with the 16 * fields enclosed by brackets "[]" replaced with your own identifying 17 * information: Portions Copyright [yyyy] [name of copyright owner] 18 * 19 * CDDL HEADER END 20 * 21 * Copyright (c) 2004, 2010, Oracle and/or its affiliates. All rights reserved. 22 */ 23 24 #include <fcntl.h> 25 #include <sys/types.h> 26 #include <sys/types.h> 27 #include <sys/stat.h> 28 #include <sys/socket.h> 29 30 #include <pwd.h> 31 32 #include "includes.h" 33 #include "atomicio.h" 34 #include "auth.h" 35 #include "bufaux.h" 36 #include "buffer.h" 37 #include "cipher.h" 38 #include "compat.h" 39 #include "dispatch.h" 40 #include "getput.h" 41 #include "kex.h" 42 #include "log.h" 43 #include "mac.h" 44 #include "packet.h" 45 #include "uidswap.h" 46 #include "ssh2.h" 47 #include "sshlogin.h" 48 #include "xmalloc.h" 49 #include "altprivsep.h" 50 #include "canohost.h" 51 #include "engine.h" 52 #include "servconf.h" 53 54 #ifdef HAVE_BSM 55 #include "bsmaudit.h" 56 adt_session_data_t *ah = NULL; 57 #endif /* HAVE_BSM */ 58 59 #ifdef GSSAPI 60 #include "ssh-gss.h" 61 extern Gssctxt *xxx_gssctxt; 62 #endif /* GSSAPI */ 63 64 extern Kex *xxx_kex; 65 extern u_char *session_id2; 66 extern int session_id2_len; 67 68 static Buffer to_monitor; 69 static Buffer from_monitor; 70 71 /* 72 * Sun's Alternative Privilege Separation basics: 73 * 74 * Abstract 75 * -------- 76 * 77 * sshd(1M) fork()s and drops privs in the child while retaining privs 78 * in the parent (a.k.a., the monitor). The unprivileged sshd and the 79 * monitor talk over a pipe using a simple protocol. 80 * 81 * The monitor protocol is all about having the monitor carry out the 82 * only operations that require privileges OR access to privileged 83 * resources. These are: utmpx/wtmpx record keeping, auditing, and 84 * SSHv2 re-keying. 85 * 86 * Re-Keying 87 * --------- 88 * 89 * Re-keying is the only protocol version specific aspect of sshd in 90 * which the monitor gets involved. 91 * 92 * The monitor processes all SSHv2 re-key protocol packets, but the 93 * unprivileged sshd process does the transport layer crypto for those 94 * packets. 95 * 96 * The monitor and its unprivileged sshd child process treat 97 * SSH_MSG_NEWKEYS SSH2 messages specially: a) the monitor does not call 98 * set_newkeys(), but b) the child asks the monitor for the set of 99 * negotiated algorithms, key, IV and what not for the relevant 100 * transport direction and then calls set_newkeys(). 101 * 102 * Monitor Protocol 103 * ---------------- 104 * 105 * Monitor IPC message formats are similar to SSHv2 messages, minus 106 * compression, encryption, padding and MACs: 107 * 108 * - 4 octet message length 109 * - message data 110 * - 1 octet message type 111 * - message data 112 * 113 * In broad strokes: 114 * 115 * - IPC: pipe, exit(2)/wait4(2) 116 * 117 * - threads: the monitor and child are single-threaded 118 * 119 * - monitor main loop: a variant of server_loop2(), for re-keying only 120 * - unpriv child main loop: server_loop2(), as usual 121 * 122 * - protocol: 123 * - key exchange packets are always forwarded as is to the monitor 124 * - newkeys, record_login(), record_logout() are special packets 125 * using the packet type range reserved for local extensions 126 * 127 * - the child drops privs and runs like a normal sshd, except that it 128 * sets dispatch handlers for key exchange packets that forward the 129 * packets to the monitor 130 * 131 * Event loops: 132 * 133 * - all monitor protocols are synchronous: because the SSHv2 rekey 134 * protocols are synchronous and because the other monitor operations 135 * are synchronous (or have no replies), 136 * 137 * - server_loop2() is modified to check the monitor pipe for rekey 138 * packets to forward to the client 139 * 140 * - and dispatch handlers are set, upon receipt of KEXINIT (and reset 141 * when NEWKEYS is sent out) to forward incoming rekey packets to the 142 * monitor. 143 * 144 * - the monitor runs an event loop not unlike server_loop2() and runs 145 * key exchanges almost exactly as a pre-altprivsep sshd would 146 * 147 * - unpriv sshd exit -> monitor cleanup (including audit logout) and exit 148 * 149 * - fatal() in monitor -> forcibly shutdown() socket and kill/wait for 150 * child (so that the audit event for the logout better reflects 151 * reality -- i.e., logged out means logged out, but for bg jobs) 152 * 153 * Message formats: 154 * 155 * - key exchange packets/replies forwarded "as is" 156 * 157 * - all other monitor requests are sent as SSH2_PRIV_MSG_ALTPRIVSEP and have a 158 * sub-type identifier (one octet) 159 * - private request sub-types include: 160 * - get new shared secret from last re-key 161 * - record login (utmpx/wtmpx), request data contains three arguments: 162 * pid, ttyname, program name 163 * - record logout (utmpx/wtmpx), request data contains one argument: pid 164 * 165 * Reply sub-types include: 166 * 167 * - NOP (for record_login/logout) 168 * - new shared secret from last re-key 169 */ 170 171 static int aps_started = 0; 172 static int is_monitor = 0; 173 174 static pid_t monitor_pid, child_pid; 175 static int pipe_fds[2]; 176 static int pipe_fd = -1; 177 static Buffer input_pipe, output_pipe; /* for pipe I/O */ 178 179 static Authctxt *xxx_authctxt; 180 181 /* Monitor functions */ 182 extern void aps_monitor_loop(Authctxt *authctxt, pid_t child_pid); 183 static void aps_record_login(void); 184 static void aps_record_logout(void); 185 static void aps_start_rekex(void); 186 Authctxt *aps_read_auth_context(void); 187 188 /* main functions for handling the monitor */ 189 static pid_t altprivsep_start_monitor(Authctxt **authctxt); 190 static void altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid); 191 static int altprivsep_started(void); 192 static int altprivsep_is_monitor(void); 193 194 /* calls _to_ monitor from unprivileged process */ 195 static void altprivsep_get_newkeys(enum kex_modes mode); 196 197 /* monitor-side fatal_cleanup callbacks */ 198 static void altprivsep_shutdown_sock(void *arg); 199 200 /* Altprivsep packet utilities for communication with the monitor */ 201 static void altprivsep_packet_start(u_char); 202 static int altprivsep_packet_send(void); 203 static int altprivsep_fwd_packet(u_char type); 204 205 static int altprivsep_packet_read(void); 206 static void altprivsep_packet_read_expect(int type); 207 208 static void altprivsep_packet_put_char(int ch); 209 static void altprivsep_packet_put_int(u_int value); 210 static void altprivsep_packet_put_cstring(const char *str); 211 static void altprivsep_packet_put_raw(const void *buf, u_int len); 212 213 static u_int altprivsep_packet_get_char(void); 214 static void *altprivsep_packet_get_raw(u_int *length_ptr); 215 static void *altprivsep_packet_get_string(u_int *length_ptr); 216 217 Kex *prepare_for_ssh2_kex(void); 218 219 /* 220 * Start monitor from privileged sshd process. 221 * 222 * Return values are like fork(2); the parent is the monitor. The caller should 223 * fatal() on error. 224 * 225 * Note that the monitor waits until the still privileged child finishes the 226 * authentication. The child drops its privileges after the authentication. 227 */ 228 static pid_t 229 altprivsep_start_monitor(Authctxt **authctxt) 230 { 231 pid_t pid; 232 int junk; 233 234 if (aps_started) 235 fatal("Monitor startup failed: missing state"); 236 237 buffer_init(&output_pipe); 238 buffer_init(&input_pipe); 239 240 if (pipe(pipe_fds) != 0) { 241 error("Monitor startup failure: could not create pipes: %s", 242 strerror(errno)); 243 return (-1); 244 } 245 246 (void) fcntl(pipe_fds[0], F_SETFD, FD_CLOEXEC); 247 (void) fcntl(pipe_fds[1], F_SETFD, FD_CLOEXEC); 248 249 monitor_pid = getpid(); 250 251 if ((pid = fork()) > 0) { 252 /* 253 * From now on, all debug messages from monitor will have prefix 254 * "monitor " 255 */ 256 set_log_txt_prefix("monitor "); 257 (void) prepare_for_ssh2_kex(); 258 packet_set_server(); 259 /* parent */ 260 child_pid = pid; 261 262 debug2("Monitor pid %ld, unprivileged child pid %ld", 263 monitor_pid, child_pid); 264 265 (void) close(pipe_fds[1]); 266 pipe_fd = pipe_fds[0]; 267 268 /* 269 * Signal readiness of the monitor and then read the 270 * authentication context from the child. 271 */ 272 (void) write(pipe_fd, &pid, sizeof (pid)); 273 packet_set_monitor(pipe_fd); 274 xxx_authctxt = *authctxt = aps_read_auth_context(); 275 276 if (fcntl(pipe_fd, F_SETFL, O_NONBLOCK) < 0) 277 error("fcntl O_NONBLOCK: %.100s", strerror(errno)); 278 279 aps_started = 1; 280 is_monitor = 1; 281 282 debug2("Monitor started"); 283 284 return (pid); 285 } 286 287 if (pid < 0) { 288 debug2("Monitor startup failure: could not fork unprivileged" 289 " process: %s", strerror(errno)); 290 return (pid); 291 } 292 293 /* this is the child that will later drop privileges */ 294 295 /* note that Solaris has bi-directional pipes so one pipe is enough */ 296 (void) close(pipe_fds[0]); 297 pipe_fd = pipe_fds[1]; 298 299 /* wait for monitor to be ready */ 300 debug2("Waiting for monitor"); 301 (void) read(pipe_fd, &junk, sizeof (junk)); 302 debug2("Monitor signalled readiness"); 303 304 buffer_init(&to_monitor); 305 buffer_init(&from_monitor); 306 307 /* AltPrivSep interfaces are set up */ 308 aps_started = 1; 309 return (pid); 310 } 311 312 int 313 altprivsep_get_pipe_fd(void) 314 { 315 return (pipe_fd); 316 } 317 318 /* 319 * This function is used in the unprivileged child for all packets in the range 320 * between SSH2_MSG_KEXINIT and SSH2_MSG_TRANSPORT_MAX. 321 */ 322 void 323 altprivsep_rekey(int type, u_int32_t seq, void *ctxt) 324 { 325 Kex *kex = (Kex *)ctxt; 326 327 if (kex == NULL) 328 fatal("Missing key exchange context in unprivileged process"); 329 330 if (type != SSH2_MSG_NEWKEYS) { 331 debug2("Forwarding re-key packet (%d) to monitor", type); 332 if (!altprivsep_fwd_packet(type)) 333 fatal("altprivsep_rekey: Monitor not responding"); 334 } 335 336 /* tell server_loop2() that we're re-keying */ 337 kex->done = 0; 338 339 /* NEWKEYS is special: get the new keys for client->server direction */ 340 if (type == SSH2_MSG_NEWKEYS) { 341 debug2("received SSH2_MSG_NEWKEYS packet - " 342 "getting new inbound keys from the monitor"); 343 altprivsep_get_newkeys(MODE_IN); 344 kex->done = 1; 345 } 346 } 347 348 void 349 altprivsep_process_input(fd_set *rset) 350 { 351 void *data; 352 int type; 353 u_int dlen; 354 355 if (pipe_fd == -1) 356 return; 357 358 if (!FD_ISSET(pipe_fd, rset)) 359 return; 360 361 debug2("reading from pipe to monitor (%d)", pipe_fd); 362 if ((type = altprivsep_packet_read()) == -1) 363 fatal("altprivsep_process_input: Monitor not responding"); 364 365 if (!compat20) 366 return; /* shouldn't happen! but be safe */ 367 368 if (type == 0) 369 return; /* EOF -- nothing to do here */ 370 371 if (type >= SSH2_MSG_MAX) 372 fatal("Received garbage from monitor"); 373 374 debug2("Read packet type %d from pipe to monitor", (u_int)type); 375 376 if (type == SSH2_PRIV_MSG_ALTPRIVSEP) 377 return; /* shouldn't happen! */ 378 379 /* NEWKEYS is special: get the new keys for server->client direction */ 380 if (type == SSH2_MSG_NEWKEYS) { 381 debug2("forwarding SSH2_MSG_NEWKEYS packet we got from monitor to " 382 "the client"); 383 packet_start(SSH2_MSG_NEWKEYS); 384 packet_send(); 385 debug2("getting new outbound keys from the monitor"); 386 altprivsep_get_newkeys(MODE_OUT); 387 return; 388 } 389 390 data = altprivsep_packet_get_raw(&dlen); 391 392 packet_start((u_char)type); 393 394 if (data != NULL && dlen > 0) 395 packet_put_raw(data, dlen); 396 397 packet_send(); 398 } 399 400 static void 401 altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid) 402 { 403 aps_monitor_loop(authctxt, child_pid); 404 } 405 406 static int 407 altprivsep_started(void) 408 { 409 return (aps_started); 410 } 411 412 static int 413 altprivsep_is_monitor(void) 414 { 415 return (is_monitor); 416 } 417 418 /* 419 * A fatal cleanup function to forcibly shutdown the connection socket 420 */ 421 static void 422 altprivsep_shutdown_sock(void *arg) 423 { 424 int sock; 425 426 if (arg == NULL) 427 return; 428 429 sock = *(int *)arg; 430 431 (void) shutdown(sock, SHUT_RDWR); 432 } 433 434 /* Calls _to_ monitor from unprivileged process */ 435 static int 436 altprivsep_fwd_packet(u_char type) 437 { 438 u_int len; 439 void *data; 440 441 altprivsep_packet_start(type); 442 data = packet_get_raw(&len); 443 altprivsep_packet_put_raw(data, len); 444 445 /* packet_send()s any replies from the monitor to the client */ 446 return (altprivsep_packet_send()); 447 } 448 449 extern Newkeys *current_keys[MODE_MAX]; 450 451 /* To be called from packet.c:set_newkeys() before referencing current_keys */ 452 static void 453 altprivsep_get_newkeys(enum kex_modes mode) 454 { 455 Newkeys *newkeys; 456 Comp *comp; 457 Enc *enc; 458 Mac *mac; 459 u_int len; 460 461 if (!altprivsep_started()) 462 return; 463 464 if (altprivsep_is_monitor()) 465 return; /* shouldn't happen */ 466 467 /* request new keys */ 468 altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 469 altprivsep_packet_put_char(APS_MSG_NEWKEYS_REQ); 470 altprivsep_packet_put_int((u_int)mode); 471 altprivsep_packet_send(); 472 altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 473 if (altprivsep_packet_get_char() != APS_MSG_NEWKEYS_REP) 474 fatal("Received garbage from monitor during re-keying"); 475 476 newkeys = xmalloc(sizeof (*newkeys)); 477 memset(newkeys, 0, sizeof (*newkeys)); 478 479 enc = &newkeys->enc; 480 mac = &newkeys->mac; 481 comp = &newkeys->comp; 482 483 /* Cipher name, key, IV */ 484 enc->name = altprivsep_packet_get_string(NULL); 485 if ((enc->cipher = cipher_by_name(enc->name)) == NULL) 486 fatal("Monitor negotiated an unknown cipher during re-key"); 487 488 enc->key = altprivsep_packet_get_string(&enc->key_len); 489 enc->iv = altprivsep_packet_get_string(&enc->block_size); 490 491 /* MAC name */ 492 mac->name = altprivsep_packet_get_string(NULL); 493 if (mac_setup(mac, mac->name) < 0) 494 fatal("Monitor negotiated an unknown MAC algorithm " 495 "during re-key"); 496 497 mac->key = altprivsep_packet_get_string(&len); 498 if (len > mac->key_len) 499 fatal("%s: bad mac key length: %d > %d", __func__, len, 500 mac->key_len); 501 502 /* Compression algorithm name */ 503 comp->name = altprivsep_packet_get_string(NULL); 504 if (strcmp(comp->name, "zlib") != 0 && strcmp(comp->name, "none") != 0) 505 fatal("Monitor negotiated an unknown compression " 506 "algorithm during re-key"); 507 508 comp->type = 0; 509 comp->enabled = 0; /* forces compression re-init, as per-spec */ 510 if (strcmp(comp->name, "zlib") == 0) 511 comp->type = 1; 512 513 /* 514 * Now install new keys 515 * 516 * For now abuse kex.c/packet.c non-interfaces. Someday, when 517 * the many internal interfaces are parametrized, made reentrant 518 * and thread-safe, made more consistent, and when necessary-but- 519 * currently-missing interfaces are added then this bit of 520 * ugliness can be revisited. 521 * 522 * The ugliness is in the set_newkeys(), its name and the lack 523 * of a (Newkeys *) parameter, which forces us to pass the 524 * newkeys through current_keys[mode]. But this saves us some 525 * lines of code for now, though not comments. 526 * 527 * Also, we've abused, in the code above, knowledge of what 528 * set_newkeys() expects the current_keys[mode] to contain. 529 */ 530 current_keys[mode] = newkeys; 531 set_newkeys(mode); 532 533 } 534 535 void 536 altprivsep_record_login(pid_t pid, const char *ttyname) 537 { 538 altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 539 altprivsep_packet_put_char(APS_MSG_RECORD_LOGIN); 540 altprivsep_packet_put_int(pid); 541 altprivsep_packet_put_cstring(ttyname); 542 altprivsep_packet_send(); 543 altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 544 } 545 546 void 547 altprivsep_record_logout(pid_t pid) 548 { 549 altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 550 altprivsep_packet_put_char(APS_MSG_RECORD_LOGOUT); 551 altprivsep_packet_put_int(pid); 552 altprivsep_packet_send(); 553 altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 554 } 555 556 void 557 altprivsep_start_rekex(void) 558 { 559 altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 560 altprivsep_packet_put_char(APS_MSG_START_REKEX); 561 altprivsep_packet_send(); 562 altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 563 } 564 565 /* 566 * The monitor needs some information that its child learns during the 567 * authentication process. Since the child was forked before the key exchange 568 * and authentication started it must send some context to the monitor after the 569 * authentication is finished. Less obvious part - monitor needs the session ID 570 * since it is used in the key generation process after the key (re-)exchange is 571 * finished. 572 */ 573 void 574 altprivsep_send_auth_context(Authctxt *authctxt) 575 { 576 debug("sending auth context to the monitor"); 577 altprivsep_packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 578 altprivsep_packet_put_char(APS_MSG_AUTH_CONTEXT); 579 altprivsep_packet_put_int(authctxt->pw->pw_uid); 580 altprivsep_packet_put_int(authctxt->pw->pw_gid); 581 altprivsep_packet_put_cstring(authctxt->pw->pw_name); 582 altprivsep_packet_put_raw(session_id2, session_id2_len); 583 debug("will send %d bytes of auth context to the monitor", 584 buffer_len(&to_monitor)); 585 altprivsep_packet_send(); 586 altprivsep_packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 587 } 588 589 static void aps_send_newkeys(void); 590 591 /* Monitor side dispatch handler for SSH2_PRIV_MSG_ALTPRIVSEP */ 592 /* ARGSUSED */ 593 void 594 aps_input_altpriv_msg(int type, u_int32_t seq, void *ctxt) 595 { 596 u_char req_type; 597 598 req_type = packet_get_char(); 599 600 switch (req_type) { 601 case APS_MSG_NEWKEYS_REQ: 602 aps_send_newkeys(); 603 break; 604 case APS_MSG_RECORD_LOGIN: 605 aps_record_login(); 606 break; 607 case APS_MSG_RECORD_LOGOUT: 608 aps_record_logout(); 609 break; 610 case APS_MSG_START_REKEX: 611 aps_start_rekex(); 612 break; 613 default: 614 break; 615 } 616 } 617 618 /* Monitor-side handlers for APS_MSG_* */ 619 static 620 void 621 aps_send_newkeys(void) 622 { 623 Newkeys *newkeys; 624 Enc *enc; 625 Mac *mac; 626 Comp *comp; 627 enum kex_modes mode; 628 629 /* get direction for which newkeys are wanted */ 630 mode = (enum kex_modes) packet_get_int(); 631 packet_check_eom(); 632 633 /* get those newkeys */ 634 newkeys = kex_get_newkeys(mode); 635 enc = &newkeys->enc; 636 mac = &newkeys->mac; 637 comp = &newkeys->comp; 638 639 /* 640 * Negotiated algorithms, client->server and server->client, for 641 * cipher, mac and compression. 642 */ 643 packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 644 packet_put_char(APS_MSG_NEWKEYS_REP); 645 packet_put_cstring(enc->name); 646 packet_put_string(enc->key, enc->key_len); 647 packet_put_string(enc->iv, enc->block_size); 648 packet_put_cstring(mac->name); 649 packet_put_string(mac->key, mac->key_len); 650 packet_put_cstring(comp->name); 651 652 packet_send(); 653 free_keys(newkeys); 654 } 655 656 struct _aps_login_rec { 657 pid_t lr_pid; 658 char *lr_tty; 659 struct _aps_login_rec *next; 660 }; 661 662 typedef struct _aps_login_rec aps_login_rec; 663 664 static aps_login_rec *aps_login_list = NULL; 665 666 static 667 void 668 aps_record_login(void) 669 { 670 aps_login_rec *new_rec; 671 struct stat sbuf; 672 size_t proc_path_len; 673 char *proc_path; 674 675 new_rec = xmalloc(sizeof (aps_login_rec)); 676 memset(new_rec, 0, sizeof (aps_login_rec)); 677 678 new_rec->lr_pid = packet_get_int(); 679 new_rec->lr_tty = packet_get_string(NULL); 680 681 proc_path_len = snprintf(NULL, 0, "/proc/%d", new_rec->lr_pid); 682 proc_path = xmalloc(proc_path_len + 1); 683 (void) snprintf(proc_path, proc_path_len + 1, "/proc/%d", 684 new_rec->lr_pid); 685 686 if (stat(proc_path, &sbuf) || 687 sbuf.st_uid != xxx_authctxt->pw->pw_uid || 688 stat(new_rec->lr_tty, &sbuf) < 0 || 689 sbuf.st_uid != xxx_authctxt->pw->pw_uid) { 690 debug2("Spurious record_login request from unprivileged sshd"); 691 xfree(proc_path); 692 xfree(new_rec->lr_tty); 693 xfree(new_rec); 694 return; 695 } 696 697 /* Insert new record on list */ 698 new_rec->next = aps_login_list; 699 aps_login_list = new_rec; 700 701 record_login(new_rec->lr_pid, new_rec->lr_tty, NULL, 702 xxx_authctxt->user); 703 704 packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 705 packet_send(); 706 707 xfree(proc_path); 708 } 709 710 static 711 void 712 aps_record_logout(void) 713 { 714 aps_login_rec **p, *q; 715 pid_t pid; 716 717 pid = packet_get_int(); 718 packet_check_eom(); 719 720 for (p = &aps_login_list; *p != NULL; p = &q->next) { 721 q = *p; 722 if (q->lr_pid == pid) { 723 record_logout(q->lr_pid, q->lr_tty, NULL, 724 xxx_authctxt->user); 725 726 /* dequeue */ 727 *p = q->next; 728 xfree(q->lr_tty); 729 xfree(q); 730 break; 731 } 732 } 733 734 packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 735 packet_send(); 736 } 737 738 static 739 void 740 aps_start_rekex(void) 741 { 742 /* 743 * Send confirmation. We could implement it without that but it doesn't 744 * bring any harm to do that and we are consistent with other subtypes 745 * of our private SSH2_PRIV_MSG_ALTPRIVSEP message type. 746 */ 747 packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 748 packet_send(); 749 750 /* 751 * KEX_INIT message could be the one that reached the limit. In that 752 * case, it was already forwarded to us from the unnprivileged child, 753 * and maybe even acted upon. Obviously we must not send another 754 * KEX_INIT message. 755 */ 756 if (!(xxx_kex->flags & KEX_INIT_SENT)) 757 kex_send_kexinit(xxx_kex); 758 else 759 debug2("rekeying already in progress"); 760 } 761 762 /* 763 * This is the monitor side of altprivsep_send_auth_context(). 764 */ 765 Authctxt * 766 aps_read_auth_context(void) 767 { 768 unsigned char *tmp; 769 Authctxt *authctxt; 770 771 /* 772 * After the successful authentication we get the context. Getting 773 * end-of-file means that authentication failed and we can exit as well. 774 */ 775 debug("reading the context from the child"); 776 packet_read_expect(SSH2_PRIV_MSG_ALTPRIVSEP); 777 debug3("got SSH2_PRIV_MSG_ALTPRIVSEP"); 778 if (packet_get_char() != APS_MSG_AUTH_CONTEXT) { 779 fatal("APS_MSG_AUTH_CONTEXT message subtype expected."); 780 } 781 782 authctxt = xcalloc(1, sizeof(Authctxt)); 783 authctxt->pw = xcalloc(1, sizeof(struct passwd)); 784 785 /* uid_t and gid_t are integers (UNIX spec) */ 786 authctxt->pw->pw_uid = packet_get_int(); 787 authctxt->pw->pw_gid = packet_get_int(); 788 authctxt->pw->pw_name = packet_get_string(NULL); 789 authctxt->user = xstrdup(authctxt->pw->pw_name); 790 debug3("uid/gid/username %d/%d/%s", authctxt->pw->pw_uid, 791 authctxt->pw->pw_gid, authctxt->user); 792 session_id2 = (unsigned char *)packet_get_raw((unsigned int*)&session_id2_len); 793 794 /* we don't have this for SSH1. In that case, session_id2_len is 0. */ 795 if (session_id2_len > 0) { 796 tmp = (unsigned char *)xmalloc(session_id2_len); 797 memcpy(tmp, session_id2, session_id2_len); 798 session_id2 = tmp; 799 debug3("read session ID (%d B)", session_id2_len); 800 xxx_kex->session_id = tmp; 801 xxx_kex->session_id_len = session_id2_len; 802 } 803 debug("finished reading the context"); 804 805 /* send confirmation */ 806 packet_start(SSH2_PRIV_MSG_ALTPRIVSEP); 807 packet_send(); 808 809 return (authctxt); 810 } 811 812 813 /* Utilities for communication with the monitor */ 814 static void 815 altprivsep_packet_start(u_char type) 816 { 817 buffer_clear(&to_monitor); 818 buffer_put_char(&to_monitor, type); 819 } 820 821 static void 822 altprivsep_packet_put_char(int ch) 823 { 824 buffer_put_char(&to_monitor, ch); 825 } 826 827 static void 828 altprivsep_packet_put_int(u_int value) 829 { 830 buffer_put_int(&to_monitor, value); 831 } 832 833 static void 834 altprivsep_packet_put_cstring(const char *str) 835 { 836 buffer_put_cstring(&to_monitor, str); 837 } 838 839 static void 840 altprivsep_packet_put_raw(const void *buf, u_int len) 841 { 842 buffer_append(&to_monitor, buf, len); 843 } 844 845 /* 846 * Send a monitor packet to the monitor. This function is blocking. 847 * 848 * Returns -1 if the monitor pipe has been closed earlier, fatal()s if 849 * there's any other problems. 850 */ 851 static int 852 altprivsep_packet_send(void) 853 { 854 ssize_t len; 855 u_int32_t plen; /* packet length */ 856 u_char plen_buf[sizeof (plen)]; 857 u_char padlen; /* padding length */ 858 fd_set *setp; 859 int err; 860 861 if (pipe_fd == -1) 862 return (-1); 863 864 if ((plen = buffer_len(&to_monitor)) == 0) 865 return (0); 866 867 /* 868 * We talk the SSHv2 binary packet protocol to the monitor, 869 * using the none cipher, mac and compression algorithms. 870 * 871 * But, interestingly, the none cipher has a block size of 8 872 * bytes, thus we must pad the packet. 873 * 874 * Also, encryption includes the packet length, so the padding 875 * must account for that field. I.e., (sizeof (packet length) + 876 * sizeof (padding length) + packet length + padding length) % 877 * block_size must == 0. 878 * 879 * Also, there must be at least four (4) bytes of padding. 880 */ 881 padlen = (8 - ((plen + sizeof (plen) + sizeof (padlen)) % 8)) % 8; 882 if (padlen < 4) 883 padlen += 8; 884 885 /* packet length counts padding and padding length field */ 886 plen += padlen + sizeof (padlen); 887 888 PUT_32BIT(plen_buf, plen); 889 890 setp = xmalloc(howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); 891 memset(setp, 0, howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); 892 FD_SET(pipe_fd, setp); 893 894 while (select(pipe_fd + 1, NULL, setp, NULL, NULL) == -1) { 895 if (errno == EAGAIN || errno == EINTR) 896 continue; 897 else 898 goto pipe_gone; 899 } 900 901 xfree(setp); 902 903 /* packet length field */ 904 len = atomicio(write, pipe_fd, plen_buf, sizeof (plen)); 905 906 if (len != sizeof (plen)) 907 goto pipe_gone; 908 909 /* padding length field */ 910 len = atomicio(write, pipe_fd, &padlen, sizeof (padlen)); 911 912 if (len != sizeof (padlen)) 913 goto pipe_gone; 914 915 len = atomicio(write, pipe_fd, buffer_ptr(&to_monitor), plen - 1); 916 917 if (len != (plen - 1)) 918 goto pipe_gone; 919 920 buffer_clear(&to_monitor); 921 922 return (1); 923 924 pipe_gone: 925 926 err = errno; 927 928 (void) close(pipe_fd); 929 930 pipe_fd = -1; 931 932 fatal("altprvsep_packet_send: Monitor not responding: %.100s", 933 strerror(err)); 934 935 /* NOTREACHED */ 936 return (0); 937 } 938 939 /* 940 * Read a monitor packet from the monitor. This function is blocking. 941 */ 942 static int 943 altprivsep_packet_read(void) 944 { 945 ssize_t len = -1; 946 u_int32_t plen; 947 u_char plen_buf[sizeof (plen)]; 948 u_char padlen; 949 fd_set *setp; 950 int err; 951 952 if (pipe_fd == -1) 953 return (-1); 954 955 setp = xmalloc(howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); 956 memset(setp, 0, howmany(pipe_fd + 1, NFDBITS) * sizeof (fd_mask)); 957 FD_SET(pipe_fd, setp); 958 959 while (select(pipe_fd + 1, setp, NULL, NULL, NULL) == -1) { 960 if (errno == EAGAIN || errno == EINTR) 961 continue; 962 else 963 goto pipe_gone; 964 } 965 966 xfree(setp); 967 968 /* packet length field */ 969 len = atomicio(read, pipe_fd, plen_buf, sizeof (plen)); 970 971 plen = GET_32BIT(plen_buf); 972 973 if (len != sizeof (plen)) 974 goto pipe_gone; 975 976 /* padding length field */ 977 len = atomicio(read, pipe_fd, &padlen, sizeof (padlen)); 978 979 if (len != sizeof (padlen)) 980 goto pipe_gone; 981 982 plen -= sizeof (padlen); 983 984 buffer_clear(&from_monitor); 985 buffer_append_space(&from_monitor, plen); 986 987 /* packet data + padding */ 988 len = atomicio(read, pipe_fd, buffer_ptr(&from_monitor), plen); 989 990 if (len != plen) 991 goto pipe_gone; 992 993 /* remove padding */ 994 if (padlen > 0) 995 buffer_consume_end(&from_monitor, padlen); 996 997 /* packet type */ 998 return (buffer_get_char(&from_monitor)); 999 1000 pipe_gone: 1001 1002 err = errno; 1003 1004 (void) close(pipe_fd); 1005 1006 pipe_fd = -1; 1007 1008 if (len < 0) 1009 fatal("altpriv_packet_read: Monitor not responding %.100s", 1010 strerror(err)); 1011 1012 debug2("Monitor pipe closed by monitor"); 1013 return (0); 1014 } 1015 1016 static void 1017 altprivsep_packet_read_expect(int expected) 1018 { 1019 int type; 1020 1021 type = altprivsep_packet_read(); 1022 1023 if (type <= 0) 1024 fatal("altprivsep_packet_read_expect: Monitor not responding"); 1025 1026 if (type != expected) 1027 fatal("Protocol error in privilege separation; expected " 1028 "packet type %d, got %d", expected, type); 1029 } 1030 1031 static u_int 1032 altprivsep_packet_get_char(void) 1033 { 1034 return (buffer_get_char(&from_monitor)); 1035 } 1036 void 1037 *altprivsep_packet_get_raw(u_int *length_ptr) 1038 { 1039 if (length_ptr != NULL) 1040 *length_ptr = buffer_len(&from_monitor); 1041 1042 return (buffer_ptr(&from_monitor)); 1043 } 1044 void 1045 *altprivsep_packet_get_string(u_int *length_ptr) 1046 { 1047 return (buffer_get_string(&from_monitor, length_ptr)); 1048 } 1049 1050 /* 1051 * Start and execute the code for the monitor which never returns from this 1052 * function. The child will return and continue in the caller. 1053 */ 1054 void 1055 altprivsep_start_and_do_monitor(int use_engine, int inetd, int newsock, 1056 int statup_pipe) 1057 { 1058 pid_t aps_child; 1059 Authctxt *authctxt; 1060 1061 /* 1062 * The monitor will packet_close() in packet_set_monitor() called from 1063 * altprivsep_start_monitor() below to clean up the socket stuff before 1064 * it switches to pipes for communication to the child. The socket fd is 1065 * closed there so we must dup it here - monitor needs that socket to 1066 * shutdown the connection in case of any problem; see comments below. 1067 * Note that current newsock was assigned to connection_(in|out) which 1068 * are the variables used in packet_close() to close the communication 1069 * socket. 1070 */ 1071 newsock = dup(newsock); 1072 1073 if ((aps_child = altprivsep_start_monitor(&authctxt)) == -1) 1074 fatal("Monitor could not be started."); 1075 1076 if (aps_child > 0) { 1077 /* ALTPRIVSEP Monitor */ 1078 1079 /* 1080 * The ALTPRIVSEP monitor here does: 1081 * 1082 * - record keeping and auditing 1083 * - PAM cleanup 1084 */ 1085 1086 /* this is for MaxStartups and the child takes care of that */ 1087 (void) close(statup_pipe); 1088 (void) pkcs11_engine_load(use_engine); 1089 1090 /* 1091 * If the monitor fatal()s it will audit/record a logout, so 1092 * we'd better do something to really mean it: shutdown the 1093 * socket but leave the child alone -- it's been disconnected 1094 * and we hope it exits, but killing any pid from a privileged 1095 * monitor could be dangerous. 1096 * 1097 * NOTE: Order matters -- these fatal cleanups must come before 1098 * the audit logout fatal cleanup as these functions are called 1099 * in LIFO. 1100 */ 1101 fatal_add_cleanup((void (*)(void *))altprivsep_shutdown_sock, 1102 (void *)&newsock); 1103 1104 if (compat20) { 1105 debug3("Recording SSHv2 session login in wtmpx"); 1106 /* 1107 * record_login() relies on connection_in to be the 1108 * socket to get the peer address. The problem is that 1109 * connection_in had to be set to the pipe descriptor in 1110 * altprivsep_start_monitor(). It's not nice but the 1111 * easiest way to get the peer's address is to 1112 * temporarily set connection_in to the socket's file 1113 * descriptor. 1114 */ 1115 packet_set_fds(inetd == 1 ? -1 : newsock, 0); 1116 record_login(getpid(), NULL, "sshd", authctxt->user); 1117 packet_set_fds(0, 1); 1118 } 1119 1120 #ifdef HAVE_BSM 1121 /* Initialize the group list, audit sometimes needs it. */ 1122 if (initgroups(authctxt->pw->pw_name, 1123 authctxt->pw->pw_gid) < 0) { 1124 perror("initgroups"); 1125 exit (1); 1126 } 1127 1128 /* 1129 * The monitor process fork()ed before the authentication 1130 * process started so at this point we have an unaudited 1131 * context. Thus we need to obtain the audit session data 1132 * from the authentication process (aps_child) which will 1133 * have the correct audit context for the user logging in. 1134 * To do so we pass along the process-ID of the aps_child 1135 * process so that it is referenced for this audit session 1136 * rather than referencing the monitor's unaudited context. 1137 */ 1138 audit_sshd_login(&ah, aps_child); 1139 1140 fatal_add_cleanup((void (*)(void *))audit_sshd_logout, 1141 (void *)&ah); 1142 #endif /* HAVE_BSM */ 1143 1144 #ifdef GSSAPI 1145 fatal_add_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds, 1146 (void *)&xxx_gssctxt); 1147 #endif /* GSSAPI */ 1148 1149 altprivsep_do_monitor(authctxt, aps_child); 1150 1151 /* If we got here the connection is dead. */ 1152 fatal_remove_cleanup((void (*)(void *))altprivsep_shutdown_sock, 1153 (void *)&newsock); 1154 1155 if (compat20) { 1156 debug3("Recording SSHv2 session logout in wtmpx"); 1157 record_logout(getpid(), NULL, "sshd", authctxt->user); 1158 } 1159 1160 /* 1161 * Make sure the socket is closed. The monitor can't call 1162 * packet_close here as it's done a packet_set_connection() 1163 * with the pipe to the child instead of the socket. 1164 */ 1165 (void) shutdown(newsock, SHUT_RDWR); 1166 1167 #ifdef GSSAPI 1168 fatal_remove_cleanup((void (*)(void *))ssh_gssapi_cleanup_creds, 1169 &xxx_gssctxt); 1170 ssh_gssapi_cleanup_creds(xxx_gssctxt); 1171 ssh_gssapi_server_mechs(NULL); /* release cached mechs list */ 1172 #endif /* GSSAPI */ 1173 1174 #ifdef HAVE_BSM 1175 fatal_remove_cleanup((void (*)(void *))audit_sshd_logout, (void *)&ah); 1176 audit_sshd_logout(&ah); 1177 #endif /* HAVE_BSM */ 1178 1179 exit(0); 1180 } else { 1181 /* 1182 * This is the child, close the dup()ed file descriptor for a 1183 * socket. It's not needed in the child. 1184 */ 1185 close(newsock); 1186 } 1187 } 1188