1 diff -up openssh-5.8p1/auth1.c.role openssh-5.8p1/auth1.c
2 --- openssh-5.8p1/auth1.c.role 2010-08-31 14:36:39.000000000 +0200
3 +++ openssh-5.8p1/auth1.c 2011-02-12 14:34:11.000000000 +0100
4 @@ -384,6 +384,9 @@ do_authentication(Authctxt *authctxt)
7 char *user, *style = NULL;
12 /* Get the name of the user that we wish to log in as. */
13 packet_read_expect(SSH_CMSG_USER);
14 @@ -392,11 +395,24 @@ do_authentication(Authctxt *authctxt)
15 user = packet_get_cstring(&ulen);
19 + if ((role = strchr(user, '/')) != NULL)
23 if ((style = strchr(user, ':')) != NULL)
27 + if (role && (style = strchr(role, ':')) != NULL)
31 authctxt->user = user;
32 authctxt->style = style;
34 + authctxt->role = role;
37 /* Verify that the user is a valid user. */
38 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
39 diff -up openssh-5.8p1/auth2.c.role openssh-5.8p1/auth2.c
40 --- openssh-5.8p1/auth2.c.role 2010-08-31 14:36:39.000000000 +0200
41 +++ openssh-5.8p1/auth2.c 2011-02-12 14:34:11.000000000 +0100
42 @@ -216,6 +216,9 @@ input_userauth_request(int type, u_int32
43 Authctxt *authctxt = ctxt;
45 char *user, *service, *method, *style = NULL;
49 int authenticated = 0;
52 @@ -227,6 +230,11 @@ input_userauth_request(int type, u_int32
53 debug("userauth-request for user %s service %s method %s", user, service, method);
54 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
57 + if ((role = strchr(user, '/')) != NULL)
61 if ((style = strchr(user, ':')) != NULL)
64 @@ -252,8 +260,15 @@ input_userauth_request(int type, u_int32
65 use_privsep ? " [net]" : "");
66 authctxt->service = xstrdup(service);
67 authctxt->style = style ? xstrdup(style) : NULL;
70 + authctxt->role = role ? xstrdup(role) : NULL;
73 mm_inform_authserv(service, style);
75 + mm_inform_authrole(role);
79 } else if (strcmp(user, authctxt->user) != 0 ||
80 strcmp(service, authctxt->service) != 0) {
81 diff -up openssh-5.8p1/auth2-gss.c.role openssh-5.8p1/auth2-gss.c
82 --- openssh-5.8p1/auth2-gss.c.role 2007-12-02 12:59:45.000000000 +0100
83 +++ openssh-5.8p1/auth2-gss.c 2011-02-12 14:34:11.000000000 +0100
84 @@ -258,6 +258,7 @@ input_gssapi_mic(int type, u_int32_t ple
85 Authctxt *authctxt = ctxt;
87 int authenticated = 0;
90 gss_buffer_desc mic, gssbuf;
92 @@ -270,7 +271,13 @@ input_gssapi_mic(int type, u_int32_t ple
93 mic.value = packet_get_string(&len);
96 - ssh_gssapi_buildmic(&b, authctxt->user, authctxt->service,
98 + if (authctxt->role && (strlen(authctxt->role) > 0))
99 + xasprintf(&micuser, "%s/%s", authctxt->user, authctxt->role);
102 + micuser = authctxt->user;
103 + ssh_gssapi_buildmic(&b, micuser, authctxt->service,
106 gssbuf.value = buffer_ptr(&b);
107 @@ -282,6 +289,8 @@ input_gssapi_mic(int type, u_int32_t ple
108 logit("GSSAPI MIC check failed");
111 + if (micuser != authctxt->user)
115 authctxt->postponed = 0;
116 diff -up openssh-5.8p1/auth2-hostbased.c.role openssh-5.8p1/auth2-hostbased.c
117 --- openssh-5.8p1/auth2-hostbased.c.role 2011-02-12 14:34:10.000000000 +0100
118 +++ openssh-5.8p1/auth2-hostbased.c 2011-02-12 14:34:11.000000000 +0100
119 @@ -106,7 +106,15 @@ userauth_hostbased(Authctxt *authctxt)
120 buffer_put_string(&b, session_id2, session_id2_len);
121 /* reconstruct packet */
122 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
123 - buffer_put_cstring(&b, authctxt->user);
125 + if (authctxt->role) {
126 + buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
127 + buffer_append(&b, authctxt->user, strlen(authctxt->user));
128 + buffer_put_char(&b, '/');
129 + buffer_append(&b, authctxt->role, strlen(authctxt->role));
132 + buffer_put_cstring(&b, authctxt->user);
133 buffer_put_cstring(&b, service);
134 buffer_put_cstring(&b, "hostbased");
135 buffer_put_string(&b, pkalg, alen);
136 diff -up openssh-5.8p1/auth2-pubkey.c.role openssh-5.8p1/auth2-pubkey.c
137 --- openssh-5.8p1/auth2-pubkey.c.role 2011-02-12 14:34:11.000000000 +0100
138 +++ openssh-5.8p1/auth2-pubkey.c 2011-02-12 14:34:11.000000000 +0100
139 @@ -122,7 +122,15 @@ userauth_pubkey(Authctxt *authctxt)
141 /* reconstruct packet */
142 buffer_put_char(&b, SSH2_MSG_USERAUTH_REQUEST);
143 - buffer_put_cstring(&b, authctxt->user);
145 + if (authctxt->role) {
146 + buffer_put_int(&b, strlen(authctxt->user)+strlen(authctxt->role)+1);
147 + buffer_append(&b, authctxt->user, strlen(authctxt->user));
148 + buffer_put_char(&b, '/');
149 + buffer_append(&b, authctxt->role, strlen(authctxt->role));
152 + buffer_put_cstring(&b, authctxt->user);
153 buffer_put_cstring(&b,
154 datafellows & SSH_BUG_PKSERVICE ?
156 diff -up openssh-5.8p1/auth.h.role openssh-5.8p1/auth.h
157 --- openssh-5.8p1/auth.h.role 2011-02-12 14:34:10.000000000 +0100
158 +++ openssh-5.8p1/auth.h 2011-02-12 14:34:11.000000000 +0100
159 @@ -58,6 +58,9 @@ struct Authctxt {
161 struct passwd *pw; /* set if 'valid' */
169 diff -up openssh-5.8p1/auth-pam.c.role openssh-5.8p1/auth-pam.c
170 --- openssh-5.8p1/auth-pam.c.role 2009-07-12 14:07:21.000000000 +0200
171 +++ openssh-5.8p1/auth-pam.c 2011-02-12 14:34:11.000000000 +0100
172 @@ -1069,7 +1069,7 @@ is_pam_session_open(void)
173 * during the ssh authentication process.
176 -do_pam_putenv(char *name, char *value)
177 +do_pam_putenv(char *name, const char *value)
180 #ifdef HAVE_PAM_PUTENV
181 diff -up openssh-5.8p1/auth-pam.h.role openssh-5.8p1/auth-pam.h
182 --- openssh-5.8p1/auth-pam.h.role 2004-09-11 14:17:26.000000000 +0200
183 +++ openssh-5.8p1/auth-pam.h 2011-02-12 14:34:11.000000000 +0100
184 @@ -38,7 +38,7 @@ void do_pam_session(void);
185 void do_pam_set_tty(const char *);
186 void do_pam_setcred(int );
187 void do_pam_chauthtok(void);
188 -int do_pam_putenv(char *, char *);
189 +int do_pam_putenv(char *, const char *);
190 char ** fetch_pam_environment(void);
191 char ** fetch_pam_child_environment(void);
192 void free_pam_environment(char **);
193 diff -up openssh-5.8p1/monitor.c.role openssh-5.8p1/monitor.c
194 --- openssh-5.8p1/monitor.c.role 2011-02-12 14:34:11.000000000 +0100
195 +++ openssh-5.8p1/monitor.c 2011-02-12 14:34:11.000000000 +0100
196 @@ -138,6 +138,9 @@ int mm_answer_sign(int, Buffer *);
197 int mm_answer_pwnamallow(int, Buffer *);
198 int mm_answer_auth2_read_banner(int, Buffer *);
199 int mm_answer_authserv(int, Buffer *);
201 +int mm_answer_authrole(int, Buffer *);
203 int mm_answer_authpassword(int, Buffer *);
204 int mm_answer_bsdauthquery(int, Buffer *);
205 int mm_answer_bsdauthrespond(int, Buffer *);
206 @@ -218,6 +221,9 @@ struct mon_table mon_dispatch_proto20[]
207 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
208 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
209 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
211 + {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
213 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
214 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
216 @@ -703,6 +709,9 @@ mm_answer_pwnamallow(int sock, Buffer *m
218 /* Allow service/style information on the auth context */
219 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
221 + monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
223 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
226 @@ -747,6 +756,25 @@ mm_answer_authserv(int sock, Buffer *m)
232 +mm_answer_authrole(int sock, Buffer *m)
234 + monitor_permit_authentications(1);
236 + authctxt->role = buffer_get_string(m, NULL);
237 + debug3("%s: role=%s",
238 + __func__, authctxt->role);
240 + if (strlen(authctxt->role) == 0) {
241 + xfree(authctxt->role);
242 + authctxt->role = NULL;
250 mm_answer_authpassword(int sock, Buffer *m)
252 @@ -1112,7 +1140,7 @@ static int
253 monitor_valid_userblob(u_char *data, u_int datalen)
261 @@ -1138,6 +1166,8 @@ monitor_valid_userblob(u_char *data, u_i
262 if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
264 p = buffer_get_string(&b, NULL);
265 + if ((r = strchr(p, '/')) != NULL)
267 if (strcmp(authctxt->user, p) != 0) {
268 logit("wrong user name passed to monitor: expected %s != %.100s",
270 @@ -1169,7 +1199,7 @@ monitor_valid_hostbasedblob(u_char *data
279 @@ -1186,6 +1216,8 @@ monitor_valid_hostbasedblob(u_char *data
280 if (buffer_get_char(&b) != SSH2_MSG_USERAUTH_REQUEST)
282 p = buffer_get_string(&b, NULL);
283 + if ((r = strchr(p, '/')) != NULL)
285 if (strcmp(authctxt->user, p) != 0) {
286 logit("wrong user name passed to monitor: expected %s != %.100s",
288 diff -up openssh-5.8p1/monitor.h.role openssh-5.8p1/monitor.h
289 --- openssh-5.8p1/monitor.h.role 2011-02-12 14:34:11.000000000 +0100
290 +++ openssh-5.8p1/monitor.h 2011-02-12 14:34:11.000000000 +0100
292 enum monitor_reqtype {
293 MONITOR_REQ_MODULI, MONITOR_ANS_MODULI,
294 MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV,
296 + MONITOR_REQ_AUTHROLE,
298 MONITOR_REQ_SIGN, MONITOR_ANS_SIGN,
299 MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM,
300 MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER,
301 diff -up openssh-5.8p1/monitor_wrap.c.role openssh-5.8p1/monitor_wrap.c
302 --- openssh-5.8p1/monitor_wrap.c.role 2011-02-12 14:34:11.000000000 +0100
303 +++ openssh-5.8p1/monitor_wrap.c 2011-02-12 14:34:11.000000000 +0100
304 @@ -298,6 +298,25 @@ mm_inform_authserv(char *service, char *
308 +/* Inform the privileged process about role */
312 +mm_inform_authrole(char *role)
316 + debug3("%s entering", __func__);
319 + buffer_put_cstring(&m, role ? role : "");
321 + mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
327 /* Do the password authentication */
329 mm_auth_password(Authctxt *authctxt, char *password)
330 diff -up openssh-5.8p1/monitor_wrap.h.role openssh-5.8p1/monitor_wrap.h
331 --- openssh-5.8p1/monitor_wrap.h.role 2011-02-12 14:34:11.000000000 +0100
332 +++ openssh-5.8p1/monitor_wrap.h 2011-02-12 14:34:11.000000000 +0100
333 @@ -41,6 +41,9 @@ int mm_is_monitor(void);
334 DH *mm_choose_dh(int, int, int);
335 int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
336 void mm_inform_authserv(char *, char *);
338 +void mm_inform_authrole(char *);
340 struct passwd *mm_getpwnamallow(const char *);
341 char *mm_auth2_read_banner(void);
342 int mm_auth_password(struct Authctxt *, char *);
343 diff -up openssh-5.8p1/openbsd-compat/Makefile.in.role openssh-5.8p1/openbsd-compat/Makefile.in
344 --- openssh-5.8p1/openbsd-compat/Makefile.in.role 2010-10-07 13:19:24.000000000 +0200
345 +++ openssh-5.8p1/openbsd-compat/Makefile.in 2011-02-12 14:34:11.000000000 +0100
346 @@ -20,7 +20,7 @@ OPENBSD=base64.o basename.o bindresvport
348 COMPAT=bsd-arc4random.o bsd-asprintf.o bsd-closefrom.o bsd-cray.o bsd-cygwin_util.o bsd-getpeereid.o bsd-misc.o bsd-nextstep.o bsd-openpty.o bsd-poll.o bsd-snprintf.o bsd-statvfs.o bsd-waitpid.o fake-rfc2553.o openssl-compat.o xmmap.o xcrypt.o
350 -PORTS=port-aix.o port-irix.o port-linux.o port-solaris.o port-tun.o port-uw.o
351 +PORTS=port-aix.o port-irix.o port-linux.o port-linux_part_2.o port-solaris.o port-tun.o port-uw.o
354 $(CC) $(CFLAGS) $(CPPFLAGS) -c $<
355 diff -up openssh-5.8p1/openbsd-compat/port-linux.c.role openssh-5.8p1/openbsd-compat/port-linux.c
356 --- openssh-5.8p1/openbsd-compat/port-linux.c.role 2011-02-12 14:34:11.000000000 +0100
357 +++ openssh-5.8p1/openbsd-compat/port-linux.c 2011-02-12 14:37:31.000000000 +0100
362 +#include "servconf.h"
363 #include "port-linux.h"
365 +#include "hostfile.h"
369 #include <selinux/selinux.h>
370 #include <selinux/flask.h>
371 #include <selinux/get_context_list.h>
373 -/* Wrapper around is_selinux_enabled() to log its return value once only */
375 -ssh_selinux_enabled(void)
377 - static int enabled = -1;
378 +extern ServerOptions options;
379 +extern Authctxt *the_authctxt;
380 +extern int inetd_flag;
381 +extern int rexeced_flag;
383 - if (enabled == -1) {
384 - enabled = (is_selinux_enabled() == 1);
385 - debug("SELinux support %s", enabled ? "enabled" : "disabled");
387 +ssh_selinux_get_role_level(char **role, const char **level)
391 + if (the_authctxt) {
392 + if (the_authctxt->role != NULL) {
394 + *role = xstrdup(the_authctxt->role);
395 + if ((slash = strchr(*role, '/')) != NULL) {
397 + *level = slash + 1;
405 /* Return the default security context for the given username */
406 static security_context_t
407 ssh_selinux_getctxbyname(char *pwname)
409 - security_context_t sc;
410 - char *sename = NULL, *lvl = NULL;
412 + security_context_t sc = NULL;
413 + char *sename, *lvl;
415 + const char *reqlvl;
418 + ssh_selinux_get_role_level(&role, &reqlvl);
419 #ifdef HAVE_GETSEUSERBYNAME
420 - if (getseuserbyname(pwname, &sename, &lvl) != 0)
422 + if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
432 #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
433 - r = get_default_context_with_level(sename, lvl, NULL, &sc);
434 + if (role != NULL && role[0])
435 + r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
437 + r = get_default_context_with_level(sename, lvl, NULL, &sc);
439 - r = get_default_context(sename, NULL, &sc);
440 + if (role != NULL && role[0])
441 + r = get_default_context_with_role(sename, role, NULL, &sc);
443 + r = get_default_context(sename, NULL, &sc);
448 switch (security_getenforce()) {
449 @@ -100,6 +125,36 @@ ssh_selinux_getctxbyname(char *pwname)
453 +/* Setup environment variables for pam_selinux */
455 +ssh_selinux_setup_pam_variables(void)
457 + const char *reqlvl;
462 + debug3("%s: setting execution context", __func__);
464 + ssh_selinux_get_role_level(&role, &reqlvl);
466 + rv = do_pam_putenv("SELINUX_ROLE_REQUESTED", role ? role : "");
468 + if (inetd_flag && !rexeced_flag) {
472 + rv = rv || do_pam_putenv("SELINUX_LEVEL_REQUESTED", reqlvl ? reqlvl: "");
475 + rv = rv || do_pam_putenv("SELINUX_USE_CURRENT_RANGE", use_current);
483 /* Set the execution context to the default for the specified user */
485 ssh_selinux_setup_exec_context(char *pwname)
486 @@ -109,6 +164,24 @@ ssh_selinux_setup_exec_context(char *pwn
487 if (!ssh_selinux_enabled())
490 + if (options.use_pam) {
491 + /* do not compute context, just setup environment for pam_selinux */
492 + if (ssh_selinux_setup_pam_variables()) {
493 + switch (security_getenforce()) {
495 + fatal("%s: security_getenforce() failed", __func__);
497 + error("%s: SELinux PAM variable setup failure. Continuing in permissive mode.",
501 + fatal("%s: SELinux PAM variable setup failure. Aborting connection.",
508 debug3("%s: setting execution context", __func__);
510 user_ctx = ssh_selinux_getctxbyname(pwname);
511 @@ -206,21 +279,6 @@ ssh_selinux_change_context(const char *n
516 -ssh_selinux_setfscreatecon(const char *path)
518 - security_context_t context;
520 - if (!ssh_selinux_enabled())
522 - if (path == NULL) {
523 - setfscreatecon(NULL);
526 - if (matchpathcon(path, 0700, &context) == 0)
527 - setfscreatecon(context);
530 #endif /* WITH_SELINUX */
532 #ifdef LINUX_OOM_ADJUST
533 diff -up openssh-5.8p1/openbsd-compat/port-linux_part_2.c.role openssh-5.8p1/openbsd-compat/port-linux_part_2.c
534 --- openssh-5.8p1/openbsd-compat/port-linux_part_2.c.role 2011-02-12 14:34:11.000000000 +0100
535 +++ openssh-5.8p1/openbsd-compat/port-linux_part_2.c 2011-02-12 14:34:11.000000000 +0100
537 +/* $Id: port-linux.c,v 1.11.4.2 2011/02/04 00:43:08 djm Exp $ */
540 + * Copyright (c) 2005 Daniel Walsh <dwalsh@redhat.com>
541 + * Copyright (c) 2006 Damien Miller <djm@openbsd.org>
543 + * Permission to use, copy, modify, and distribute this software for any
544 + * purpose with or without fee is hereby granted, provided that the above
545 + * copyright notice and this permission notice appear in all copies.
547 + * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
548 + * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
549 + * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
550 + * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
551 + * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
552 + * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
553 + * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
557 + * Linux-specific portability code - just SELinux support at present
560 +#include "includes.h"
562 +#if defined(WITH_SELINUX) || defined(LINUX_OOM_ADJUST)
569 +#include "xmalloc.h"
570 +#include "port-linux.h"
572 +#include "hostfile.h"
576 +#include <selinux/selinux.h>
577 +#include <selinux/flask.h>
578 +#include <selinux/get_context_list.h>
580 +/* Wrapper around is_selinux_enabled() to log its return value once only */
582 +ssh_selinux_enabled(void)
584 + static int enabled = -1;
586 + if (enabled == -1) {
587 + enabled = (is_selinux_enabled() == 1);
588 + debug("SELinux support %s", enabled ? "enabled" : "disabled");
595 +ssh_selinux_setfscreatecon(const char *path)
597 + security_context_t context;
599 + if (!ssh_selinux_enabled())
601 + if (path == NULL) {
602 + setfscreatecon(NULL);
605 + if (matchpathcon(path, 0700, &context) == 0)
606 + setfscreatecon(context);
609 +#endif /* WITH_SELINUX */
611 +#endif /* WITH_SELINUX || LINUX_OOM_ADJUST */