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"
56adt_session_data_t *ah = NULL;
57#endif /* HAVE_BSM */
58
59#ifdef GSSAPI
60#include "ssh-gss.h"
61extern Gssctxt *xxx_gssctxt;
62#endif /* GSSAPI */
63
64extern Kex *xxx_kex;
65extern u_char *session_id2;
66extern int session_id2_len;
67
68static Buffer to_monitor;
69static 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
171static int aps_started = 0;
172static int is_monitor = 0;
173
174static pid_t monitor_pid, child_pid;
175static int pipe_fds[2];
176static int pipe_fd = -1;
177static Buffer input_pipe, output_pipe; /* for pipe I/O */
178
179static Authctxt *xxx_authctxt;
180
181/* Monitor functions */
182extern void aps_monitor_loop(Authctxt *authctxt, pid_t child_pid);
183static void aps_record_login(void);
184static void aps_record_logout(void);
185static void aps_start_rekex(void);
186Authctxt *aps_read_auth_context(void);
187
188/* main functions for handling the monitor */
189static pid_t	altprivsep_start_monitor(Authctxt **authctxt);
190static void	altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid);
191static int	altprivsep_started(void);
192static int	altprivsep_is_monitor(void);
193
194/* calls _to_ monitor from unprivileged process */
195static void	altprivsep_get_newkeys(enum kex_modes mode);
196
197/* monitor-side fatal_cleanup callbacks */
198static void	altprivsep_shutdown_sock(void *arg);
199
200/* Altprivsep packet utilities for communication with the monitor */
201static void	altprivsep_packet_start(u_char);
202static int	altprivsep_packet_send(void);
203static int	altprivsep_fwd_packet(u_char type);
204
205static int	altprivsep_packet_read(void);
206static void	altprivsep_packet_read_expect(int type);
207
208static void	altprivsep_packet_put_char(int ch);
209static void	altprivsep_packet_put_int(u_int value);
210static void	altprivsep_packet_put_cstring(const char *str);
211static void	altprivsep_packet_put_raw(const void *buf, u_int len);
212
213static u_int	 altprivsep_packet_get_char(void);
214static void	*altprivsep_packet_get_raw(u_int *length_ptr);
215static void	*altprivsep_packet_get_string(u_int *length_ptr);
216
217Kex		*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 */
228static pid_t
229altprivsep_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
312int
313altprivsep_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 */
322void
323altprivsep_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
348void
349altprivsep_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
400static void
401altprivsep_do_monitor(Authctxt *authctxt, pid_t child_pid)
402{
403	aps_monitor_loop(authctxt, child_pid);
404}
405
406static int
407altprivsep_started(void)
408{
409	return (aps_started);
410}
411
412static int
413altprivsep_is_monitor(void)
414{
415	return (is_monitor);
416}
417
418/*
419 * A fatal cleanup function to forcibly shutdown the connection socket
420 */
421static void
422altprivsep_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 */
435static int
436altprivsep_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
449extern Newkeys *current_keys[MODE_MAX];
450
451/* To be called from packet.c:set_newkeys() before referencing current_keys */
452static void
453altprivsep_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
535void
536altprivsep_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
546void
547altprivsep_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
556void
557altprivsep_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 */
573void
574altprivsep_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
589static void aps_send_newkeys(void);
590
591/* Monitor side dispatch handler for SSH2_PRIV_MSG_ALTPRIVSEP */
592/* ARGSUSED */
593void
594aps_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_* */
619static
620void
621aps_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
656struct _aps_login_rec {
657	pid_t			lr_pid;
658	char			*lr_tty;
659	struct _aps_login_rec	*next;
660};
661
662typedef struct _aps_login_rec aps_login_rec;
663
664static aps_login_rec *aps_login_list = NULL;
665
666static
667void
668aps_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
710static
711void
712aps_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
738static
739void
740aps_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 */
765Authctxt *
766aps_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 */
814static void
815altprivsep_packet_start(u_char type)
816{
817	buffer_clear(&to_monitor);
818	buffer_put_char(&to_monitor, type);
819}
820
821static void
822altprivsep_packet_put_char(int ch)
823{
824	buffer_put_char(&to_monitor, ch);
825}
826
827static void
828altprivsep_packet_put_int(u_int value)
829{
830	buffer_put_int(&to_monitor, value);
831}
832
833static void
834altprivsep_packet_put_cstring(const char *str)
835{
836	buffer_put_cstring(&to_monitor, str);
837}
838
839static void
840altprivsep_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 */
851static int
852altprivsep_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
924pipe_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 */
942static int
943altprivsep_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
1000pipe_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
1016static void
1017altprivsep_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
1031static u_int
1032altprivsep_packet_get_char(void)
1033{
1034	return (buffer_get_char(&from_monitor));
1035}
1036void
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}
1044void
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 */
1054void
1055altprivsep_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