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