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
altprivsep_start_monitor(Authctxt ** authctxt)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
altprivsep_get_pipe_fd(void)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
altprivsep_rekey(int type,u_int32_t seq,void * ctxt)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
altprivsep_process_input(fd_set * rset)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
altprivsep_do_monitor(Authctxt * authctxt,pid_t child_pid)401 altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid)
402 {
403 aps_monitor_loop(authctxt, child_pid);
404 }
405
406 static int
altprivsep_started(void)407 altprivsep_started(void)
408 {
409 return (aps_started);
410 }
411
412 static int
altprivsep_is_monitor(void)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
altprivsep_shutdown_sock(void * arg)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
altprivsep_fwd_packet(u_char type)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
altprivsep_get_newkeys(enum kex_modes mode)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
altprivsep_record_login(pid_t pid,const char * ttyname)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
altprivsep_record_logout(pid_t pid)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
altprivsep_start_rekex(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
altprivsep_send_auth_context(Authctxt * authctxt)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
aps_input_altpriv_msg(int type,u_int32_t seq,void * ctxt)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
aps_send_newkeys(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
aps_record_login(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
aps_record_logout(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
aps_start_rekex(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 *
aps_read_auth_context(void)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
altprivsep_packet_start(u_char type)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
altprivsep_packet_put_char(int ch)822 altprivsep_packet_put_char(int ch)
823 {
824 buffer_put_char(&to_monitor, ch);
825 }
826
827 static void
altprivsep_packet_put_int(u_int value)828 altprivsep_packet_put_int(u_int value)
829 {
830 buffer_put_int(&to_monitor, value);
831 }
832
833 static void
altprivsep_packet_put_cstring(const char * str)834 altprivsep_packet_put_cstring(const char *str)
835 {
836 buffer_put_cstring(&to_monitor, str);
837 }
838
839 static void
altprivsep_packet_put_raw(const void * buf,u_int len)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
altprivsep_packet_send(void)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
altprivsep_packet_read(void)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
altprivsep_packet_read_expect(int expected)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
altprivsep_packet_get_char(void)1032 altprivsep_packet_get_char(void)
1033 {
1034 return (buffer_get_char(&from_monitor));
1035 }
1036 void
altprivsep_packet_get_raw(u_int * length_ptr)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
altprivsep_packet_get_string(u_int * length_ptr)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
altprivsep_start_and_do_monitor(int use_engine,int inetd,int newsock,int statup_pipe)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