summaryrefslogtreecommitdiff
path: root/debian/patches/selinux-role.patch
diff options
context:
space:
mode:
Diffstat (limited to 'debian/patches/selinux-role.patch')
-rw-r--r--debian/patches/selinux-role.patch479
1 files changed, 479 insertions, 0 deletions
diff --git a/debian/patches/selinux-role.patch b/debian/patches/selinux-role.patch
new file mode 100644
index 000000000..f3376c20a
--- /dev/null
+++ b/debian/patches/selinux-role.patch
@@ -0,0 +1,479 @@
1Description: Handle SELinux authorisation roles
2 Rejected upstream due to discomfort with magic usernames; a better approach
3 will need an SSH protocol change. In the meantime, this came from Debian's
4 SELinux maintainer, so we'll keep it until we have something better.
5Author: Manoj Srivastava <srivasta@debian.org>
6Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641
7Bug-Debian: http://bugs.debian.org/394795
8Last-Update: 2013-09-14
9
10Index: b/auth.h
11===================================================================
12--- a/auth.h
13+++ b/auth.h
14@@ -59,6 +59,7 @@
15 char *service;
16 struct passwd *pw; /* set if 'valid' */
17 char *style;
18+ char *role;
19 void *kbdintctxt;
20 char *info; /* Extra info for next auth_log */
21 void *jpake_ctx;
22Index: b/auth1.c
23===================================================================
24--- a/auth1.c
25+++ b/auth1.c
26@@ -380,7 +380,7 @@
27 do_authentication(Authctxt *authctxt)
28 {
29 u_int ulen;
30- char *user, *style = NULL;
31+ char *user, *style = NULL, *role = NULL;
32
33 /* Get the name of the user that we wish to log in as. */
34 packet_read_expect(SSH_CMSG_USER);
35@@ -389,11 +389,17 @@
36 user = packet_get_cstring(&ulen);
37 packet_check_eom();
38
39+ if ((role = strchr(user, '/')) != NULL)
40+ *role++ = '\0';
41+
42 if ((style = strchr(user, ':')) != NULL)
43 *style++ = '\0';
44+ else if (role && (style = strchr(role, ':')) != NULL)
45+ *style++ = '\0';
46
47 authctxt->user = user;
48 authctxt->style = style;
49+ authctxt->role = role;
50
51 /* Verify that the user is a valid user. */
52 if ((authctxt->pw = PRIVSEP(getpwnamallow(user))) != NULL)
53Index: b/auth2.c
54===================================================================
55--- a/auth2.c
56+++ b/auth2.c
57@@ -222,7 +222,7 @@
58 {
59 Authctxt *authctxt = ctxt;
60 Authmethod *m = NULL;
61- char *user, *service, *method, *style = NULL;
62+ char *user, *service, *method, *style = NULL, *role = NULL;
63 int authenticated = 0;
64
65 if (authctxt == NULL)
66@@ -234,8 +234,13 @@
67 debug("userauth-request for user %s service %s method %s", user, service, method);
68 debug("attempt %d failures %d", authctxt->attempt, authctxt->failures);
69
70+ if ((role = strchr(user, '/')) != NULL)
71+ *role++ = 0;
72+
73 if ((style = strchr(user, ':')) != NULL)
74 *style++ = 0;
75+ else if (role && (style = strchr(role, ':')) != NULL)
76+ *style++ = '\0';
77
78 if (authctxt->attempt++ == 0) {
79 /* setup auth context */
80@@ -259,8 +264,9 @@
81 use_privsep ? " [net]" : "");
82 authctxt->service = xstrdup(service);
83 authctxt->style = style ? xstrdup(style) : NULL;
84+ authctxt->role = role ? xstrdup(role) : NULL;
85 if (use_privsep)
86- mm_inform_authserv(service, style);
87+ mm_inform_authserv(service, style, role);
88 userauth_banner();
89 if (auth2_setup_methods_lists(authctxt) != 0)
90 packet_disconnect("no authentication methods enabled");
91Index: b/monitor.c
92===================================================================
93--- a/monitor.c
94+++ b/monitor.c
95@@ -146,6 +146,7 @@
96 int mm_answer_pwnamallow(int, Buffer *);
97 int mm_answer_auth2_read_banner(int, Buffer *);
98 int mm_answer_authserv(int, Buffer *);
99+int mm_answer_authrole(int, Buffer *);
100 int mm_answer_authpassword(int, Buffer *);
101 int mm_answer_bsdauthquery(int, Buffer *);
102 int mm_answer_bsdauthrespond(int, Buffer *);
103@@ -227,6 +228,7 @@
104 {MONITOR_REQ_SIGN, MON_ONCE, mm_answer_sign},
105 {MONITOR_REQ_PWNAM, MON_ONCE, mm_answer_pwnamallow},
106 {MONITOR_REQ_AUTHSERV, MON_ONCE, mm_answer_authserv},
107+ {MONITOR_REQ_AUTHROLE, MON_ONCE, mm_answer_authrole},
108 {MONITOR_REQ_AUTH2_READ_BANNER, MON_ONCE, mm_answer_auth2_read_banner},
109 {MONITOR_REQ_AUTHPASSWORD, MON_AUTH, mm_answer_authpassword},
110 #ifdef USE_PAM
111@@ -844,6 +846,7 @@
112 else {
113 /* Allow service/style information on the auth context */
114 monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1);
115+ monitor_permit(mon_dispatch, MONITOR_REQ_AUTHROLE, 1);
116 monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1);
117 }
118 #ifdef USE_PAM
119@@ -874,14 +877,37 @@
120
121 authctxt->service = buffer_get_string(m, NULL);
122 authctxt->style = buffer_get_string(m, NULL);
123- debug3("%s: service=%s, style=%s",
124- __func__, authctxt->service, authctxt->style);
125+ authctxt->role = buffer_get_string(m, NULL);
126+ debug3("%s: service=%s, style=%s, role=%s",
127+ __func__, authctxt->service, authctxt->style, authctxt->role);
128
129 if (strlen(authctxt->style) == 0) {
130 free(authctxt->style);
131 authctxt->style = NULL;
132 }
133
134+ if (strlen(authctxt->role) == 0) {
135+ free(authctxt->role);
136+ authctxt->role = NULL;
137+ }
138+
139+ return (0);
140+}
141+
142+int
143+mm_answer_authrole(int sock, Buffer *m)
144+{
145+ monitor_permit_authentications(1);
146+
147+ authctxt->role = buffer_get_string(m, NULL);
148+ debug3("%s: role=%s",
149+ __func__, authctxt->role);
150+
151+ if (strlen(authctxt->role) == 0) {
152+ free(authctxt->role);
153+ authctxt->role = NULL;
154+ }
155+
156 return (0);
157 }
158
159@@ -1486,7 +1512,7 @@
160 res = pty_allocate(&s->ptyfd, &s->ttyfd, s->tty, sizeof(s->tty));
161 if (res == 0)
162 goto error;
163- pty_setowner(authctxt->pw, s->tty);
164+ pty_setowner(authctxt->pw, s->tty, authctxt->role);
165
166 buffer_put_int(m, 1);
167 buffer_put_cstring(m, s->tty);
168Index: b/monitor.h
169===================================================================
170--- a/monitor.h
171+++ b/monitor.h
172@@ -73,6 +73,8 @@
173 MONITOR_REQ_GSSSIGN = 150, MONITOR_ANS_GSSSIGN = 151,
174 MONITOR_REQ_GSSUPCREDS = 152, MONITOR_ANS_GSSUPCREDS = 153,
175
176+ MONITOR_REQ_AUTHROLE = 154,
177+
178 };
179
180 struct mm_master;
181Index: b/monitor_wrap.c
182===================================================================
183--- a/monitor_wrap.c
184+++ b/monitor_wrap.c
185@@ -320,10 +320,10 @@
186 return (banner);
187 }
188
189-/* Inform the privileged process about service and style */
190+/* Inform the privileged process about service, style, and role */
191
192 void
193-mm_inform_authserv(char *service, char *style)
194+mm_inform_authserv(char *service, char *style, char *role)
195 {
196 Buffer m;
197
198@@ -332,11 +332,29 @@
199 buffer_init(&m);
200 buffer_put_cstring(&m, service);
201 buffer_put_cstring(&m, style ? style : "");
202+ buffer_put_cstring(&m, role ? role : "");
203
204 mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHSERV, &m);
205
206 buffer_free(&m);
207 }
208+
209+/* Inform the privileged process about role */
210+
211+void
212+mm_inform_authrole(char *role)
213+{
214+ Buffer m;
215+
216+ debug3("%s entering", __func__);
217+
218+ buffer_init(&m);
219+ buffer_put_cstring(&m, role ? role : "");
220+
221+ mm_request_send(pmonitor->m_recvfd, MONITOR_REQ_AUTHROLE, &m);
222+
223+ buffer_free(&m);
224+}
225
226 /* Do the password authentication */
227 int
228Index: b/monitor_wrap.h
229===================================================================
230--- a/monitor_wrap.h
231+++ b/monitor_wrap.h
232@@ -41,7 +41,8 @@
233 int mm_is_monitor(void);
234 DH *mm_choose_dh(int, int, int);
235 int mm_key_sign(Key *, u_char **, u_int *, u_char *, u_int);
236-void mm_inform_authserv(char *, char *);
237+void mm_inform_authserv(char *, char *, char *);
238+void mm_inform_authrole(char *);
239 struct passwd *mm_getpwnamallow(const char *);
240 char *mm_auth2_read_banner(void);
241 int mm_auth_password(struct Authctxt *, char *);
242Index: b/openbsd-compat/port-linux.c
243===================================================================
244--- a/openbsd-compat/port-linux.c
245+++ b/openbsd-compat/port-linux.c
246@@ -29,6 +29,12 @@
247 #include <string.h>
248 #include <stdio.h>
249
250+#ifdef WITH_SELINUX
251+#include "key.h"
252+#include "hostfile.h"
253+#include "auth.h"
254+#endif
255+
256 #include "log.h"
257 #include "xmalloc.h"
258 #include "port-linux.h"
259@@ -58,7 +64,7 @@
260
261 /* Return the default security context for the given username */
262 static security_context_t
263-ssh_selinux_getctxbyname(char *pwname)
264+ssh_selinux_getctxbyname(char *pwname, const char *role)
265 {
266 security_context_t sc = NULL;
267 char *sename = NULL, *lvl = NULL;
268@@ -73,9 +79,16 @@
269 #endif
270
271 #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
272- r = get_default_context_with_level(sename, lvl, NULL, &sc);
273+ if (role != NULL && role[0])
274+ r = get_default_context_with_rolelevel(sename, role, lvl, NULL,
275+ &sc);
276+ else
277+ r = get_default_context_with_level(sename, lvl, NULL, &sc);
278 #else
279- r = get_default_context(sename, NULL, &sc);
280+ if (role != NULL && role[0])
281+ r = get_default_context_with_role(sename, role, NULL, &sc);
282+ else
283+ r = get_default_context(sename, NULL, &sc);
284 #endif
285
286 if (r != 0) {
287@@ -105,7 +118,7 @@
288
289 /* Set the execution context to the default for the specified user */
290 void
291-ssh_selinux_setup_exec_context(char *pwname)
292+ssh_selinux_setup_exec_context(char *pwname, const char *role)
293 {
294 security_context_t user_ctx = NULL;
295
296@@ -114,7 +127,7 @@
297
298 debug3("%s: setting execution context", __func__);
299
300- user_ctx = ssh_selinux_getctxbyname(pwname);
301+ user_ctx = ssh_selinux_getctxbyname(pwname, role);
302 if (setexeccon(user_ctx) != 0) {
303 switch (security_getenforce()) {
304 case -1:
305@@ -136,7 +149,7 @@
306
307 /* Set the TTY context for the specified user */
308 void
309-ssh_selinux_setup_pty(char *pwname, const char *tty)
310+ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role)
311 {
312 security_context_t new_tty_ctx = NULL;
313 security_context_t user_ctx = NULL;
314@@ -147,7 +160,7 @@
315
316 debug3("%s: setting TTY context on %s", __func__, tty);
317
318- user_ctx = ssh_selinux_getctxbyname(pwname);
319+ user_ctx = ssh_selinux_getctxbyname(pwname, role);
320
321 /* XXX: should these calls fatal() upon failure in enforcing mode? */
322
323Index: b/openbsd-compat/port-linux.h
324===================================================================
325--- a/openbsd-compat/port-linux.h
326+++ b/openbsd-compat/port-linux.h
327@@ -21,8 +21,8 @@
328
329 #ifdef WITH_SELINUX
330 int ssh_selinux_enabled(void);
331-void ssh_selinux_setup_pty(char *, const char *);
332-void ssh_selinux_setup_exec_context(char *);
333+void ssh_selinux_setup_pty(char *, const char *, const char *);
334+void ssh_selinux_setup_exec_context(char *, const char *);
335 void ssh_selinux_change_context(const char *);
336 void ssh_selinux_setfscreatecon(const char *);
337 #endif
338Index: b/platform.c
339===================================================================
340--- a/platform.c
341+++ b/platform.c
342@@ -134,7 +134,7 @@
343 * called if sshd is running as root.
344 */
345 void
346-platform_setusercontext_post_groups(struct passwd *pw)
347+platform_setusercontext_post_groups(struct passwd *pw, const char *role)
348 {
349 #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM)
350 /*
351@@ -181,7 +181,7 @@
352 }
353 #endif /* HAVE_SETPCRED */
354 #ifdef WITH_SELINUX
355- ssh_selinux_setup_exec_context(pw->pw_name);
356+ ssh_selinux_setup_exec_context(pw->pw_name, role);
357 #endif
358 }
359
360Index: b/platform.h
361===================================================================
362--- a/platform.h
363+++ b/platform.h
364@@ -26,7 +26,7 @@
365 void platform_post_fork_child(void);
366 int platform_privileged_uidswap(void);
367 void platform_setusercontext(struct passwd *);
368-void platform_setusercontext_post_groups(struct passwd *);
369+void platform_setusercontext_post_groups(struct passwd *, const char *);
370 char *platform_get_krb5_client(const char *);
371 char *platform_krb5_get_principal_name(const char *);
372 int platform_sys_dir_uid(uid_t);
373Index: b/session.c
374===================================================================
375--- a/session.c
376+++ b/session.c
377@@ -1474,7 +1474,7 @@
378
379 /* Set login name, uid, gid, and groups. */
380 void
381-do_setusercontext(struct passwd *pw)
382+do_setusercontext(struct passwd *pw, const char *role)
383 {
384 char *chroot_path, *tmp;
385
386@@ -1502,7 +1502,7 @@
387 endgrent();
388 #endif
389
390- platform_setusercontext_post_groups(pw);
391+ platform_setusercontext_post_groups(pw, role);
392
393 if (options.chroot_directory != NULL &&
394 strcasecmp(options.chroot_directory, "none") != 0) {
395@@ -1646,7 +1646,7 @@
396
397 /* Force a password change */
398 if (s->authctxt->force_pwchange) {
399- do_setusercontext(pw);
400+ do_setusercontext(pw, s->authctxt->role);
401 child_close_fds();
402 do_pwchange(s);
403 exit(1);
404@@ -1673,7 +1673,7 @@
405 /* When PAM is enabled we rely on it to do the nologin check */
406 if (!options.use_pam)
407 do_nologin(pw);
408- do_setusercontext(pw);
409+ do_setusercontext(pw, s->authctxt->role);
410 /*
411 * PAM session modules in do_setusercontext may have
412 * generated messages, so if this in an interactive
413@@ -2084,7 +2084,7 @@
414 tty_parse_modes(s->ttyfd, &n_bytes);
415
416 if (!use_privsep)
417- pty_setowner(s->pw, s->tty);
418+ pty_setowner(s->pw, s->tty, s->authctxt->role);
419
420 /* Set window size from the packet. */
421 pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel);
422Index: b/session.h
423===================================================================
424--- a/session.h
425+++ b/session.h
426@@ -76,7 +76,7 @@
427 Session *session_new(void);
428 Session *session_by_tty(char *);
429 void session_close(Session *);
430-void do_setusercontext(struct passwd *);
431+void do_setusercontext(struct passwd *, const char *);
432 void child_set_env(char ***envp, u_int *envsizep, const char *name,
433 const char *value);
434
435Index: b/sshd.c
436===================================================================
437--- a/sshd.c
438+++ b/sshd.c
439@@ -753,7 +753,7 @@
440 RAND_seed(rnd, sizeof(rnd));
441
442 /* Drop privileges */
443- do_setusercontext(authctxt->pw);
444+ do_setusercontext(authctxt->pw, authctxt->role);
445
446 skip:
447 /* It is safe now to apply the key state */
448Index: b/sshpty.c
449===================================================================
450--- a/sshpty.c
451+++ b/sshpty.c
452@@ -200,7 +200,7 @@
453 }
454
455 void
456-pty_setowner(struct passwd *pw, const char *tty)
457+pty_setowner(struct passwd *pw, const char *tty, const char *role)
458 {
459 struct group *grp;
460 gid_t gid;
461@@ -227,7 +227,7 @@
462 strerror(errno));
463
464 #ifdef WITH_SELINUX
465- ssh_selinux_setup_pty(pw->pw_name, tty);
466+ ssh_selinux_setup_pty(pw->pw_name, tty, role);
467 #endif
468
469 if (st.st_uid != pw->pw_uid || st.st_gid != gid) {
470Index: b/sshpty.h
471===================================================================
472--- a/sshpty.h
473+++ b/sshpty.h
474@@ -24,4 +24,4 @@
475 void pty_release(const char *);
476 void pty_make_controlling_tty(int *, const char *);
477 void pty_change_window_size(int, u_int, u_int, u_int, u_int);
478-void pty_setowner(struct passwd *, const char *);
479+void pty_setowner(struct passwd *, const char *, const char *);