diff options
Diffstat (limited to 'debian/patches/selinux-role.patch')
-rw-r--r-- | debian/patches/selinux-role.patch | 482 |
1 files changed, 482 insertions, 0 deletions
diff --git a/debian/patches/selinux-role.patch b/debian/patches/selinux-role.patch new file mode 100644 index 000000000..30db352dd --- /dev/null +++ b/debian/patches/selinux-role.patch | |||
@@ -0,0 +1,482 @@ | |||
1 | Description: 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. | ||
5 | Author: Manoj Srivastava <srivasta@debian.org> | ||
6 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1641 | ||
7 | Bug-Debian: http://bugs.debian.org/394795 | ||
8 | Last-Update: 2010-02-27 | ||
9 | |||
10 | Index: 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 | void *jpake_ctx; | ||
21 | #ifdef BSD_AUTH | ||
22 | Index: b/auth1.c | ||
23 | =================================================================== | ||
24 | --- a/auth1.c | ||
25 | +++ b/auth1.c | ||
26 | @@ -383,7 +383,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 | @@ -392,11 +392,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) | ||
53 | Index: b/auth2.c | ||
54 | =================================================================== | ||
55 | --- a/auth2.c | ||
56 | +++ b/auth2.c | ||
57 | @@ -217,7 +217,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 | @@ -229,8 +229,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 | @@ -254,8 +259,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 | } else if (strcmp(user, authctxt->user) != 0 || | ||
90 | strcmp(service, authctxt->service) != 0) { | ||
91 | Index: b/monitor.c | ||
92 | =================================================================== | ||
93 | --- a/monitor.c | ||
94 | +++ b/monitor.c | ||
95 | @@ -137,6 +137,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 | @@ -215,6 +216,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 | @@ -699,6 +701,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 | |||
119 | @@ -732,14 +735,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 | xfree(authctxt->style); | ||
131 | authctxt->style = NULL; | ||
132 | } | ||
133 | |||
134 | + if (strlen(authctxt->role) == 0) { | ||
135 | + xfree(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 | + xfree(authctxt->role); | ||
153 | + authctxt->role = NULL; | ||
154 | + } | ||
155 | + | ||
156 | return (0); | ||
157 | } | ||
158 | |||
159 | @@ -1327,7 +1353,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); | ||
168 | Index: b/monitor.h | ||
169 | =================================================================== | ||
170 | --- a/monitor.h | ||
171 | +++ b/monitor.h | ||
172 | @@ -30,7 +30,7 @@ | ||
173 | |||
174 | enum monitor_reqtype { | ||
175 | MONITOR_REQ_MODULI, MONITOR_ANS_MODULI, | ||
176 | - MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, | ||
177 | + MONITOR_REQ_FREE, MONITOR_REQ_AUTHSERV, MONITOR_REQ_AUTHROLE, | ||
178 | MONITOR_REQ_SIGN, MONITOR_ANS_SIGN, | ||
179 | MONITOR_REQ_PWNAM, MONITOR_ANS_PWNAM, | ||
180 | MONITOR_REQ_AUTH2_READ_BANNER, MONITOR_ANS_AUTH2_READ_BANNER, | ||
181 | Index: b/monitor_wrap.c | ||
182 | =================================================================== | ||
183 | --- a/monitor_wrap.c | ||
184 | +++ b/monitor_wrap.c | ||
185 | @@ -280,10 +280,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 | @@ -292,11 +292,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 | ||
228 | Index: b/monitor_wrap.h | ||
229 | =================================================================== | ||
230 | --- a/monitor_wrap.h | ||
231 | +++ b/monitor_wrap.h | ||
232 | @@ -40,7 +40,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 *); | ||
242 | Index: 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 | @@ -54,9 +60,9 @@ | ||
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; | ||
267 | + security_context_t sc = NULL; | ||
268 | char *sename = NULL, *lvl = NULL; | ||
269 | int r; | ||
270 | |||
271 | @@ -69,9 +75,16 @@ | ||
272 | #endif | ||
273 | |||
274 | #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL | ||
275 | - r = get_default_context_with_level(sename, lvl, NULL, &sc); | ||
276 | + if (role != NULL && role[0]) | ||
277 | + r = get_default_context_with_rolelevel(sename, role, lvl, NULL, | ||
278 | + &sc); | ||
279 | + else | ||
280 | + r = get_default_context_with_level(sename, lvl, NULL, &sc); | ||
281 | #else | ||
282 | - r = get_default_context(sename, NULL, &sc); | ||
283 | + if (role != NULL && role[0]) | ||
284 | + r = get_default_context_with_role(sename, role, NULL, &sc); | ||
285 | + else | ||
286 | + r = get_default_context(sename, NULL, &sc); | ||
287 | #endif | ||
288 | |||
289 | if (r != 0) { | ||
290 | @@ -102,7 +115,7 @@ | ||
291 | |||
292 | /* Set the execution context to the default for the specified user */ | ||
293 | void | ||
294 | -ssh_selinux_setup_exec_context(char *pwname) | ||
295 | +ssh_selinux_setup_exec_context(char *pwname, const char *role) | ||
296 | { | ||
297 | security_context_t user_ctx = NULL; | ||
298 | |||
299 | @@ -111,7 +124,7 @@ | ||
300 | |||
301 | debug3("%s: setting execution context", __func__); | ||
302 | |||
303 | - user_ctx = ssh_selinux_getctxbyname(pwname); | ||
304 | + user_ctx = ssh_selinux_getctxbyname(pwname, role); | ||
305 | if (setexeccon(user_ctx) != 0) { | ||
306 | switch (security_getenforce()) { | ||
307 | case -1: | ||
308 | @@ -133,7 +146,7 @@ | ||
309 | |||
310 | /* Set the TTY context for the specified user */ | ||
311 | void | ||
312 | -ssh_selinux_setup_pty(char *pwname, const char *tty) | ||
313 | +ssh_selinux_setup_pty(char *pwname, const char *tty, const char *role) | ||
314 | { | ||
315 | security_context_t new_tty_ctx = NULL; | ||
316 | security_context_t user_ctx = NULL; | ||
317 | @@ -144,7 +157,7 @@ | ||
318 | |||
319 | debug3("%s: setting TTY context on %s", __func__, tty); | ||
320 | |||
321 | - user_ctx = ssh_selinux_getctxbyname(pwname); | ||
322 | + user_ctx = ssh_selinux_getctxbyname(pwname, role); | ||
323 | |||
324 | /* XXX: should these calls fatal() upon failure in enforcing mode? */ | ||
325 | |||
326 | Index: b/openbsd-compat/port-linux.h | ||
327 | =================================================================== | ||
328 | --- a/openbsd-compat/port-linux.h | ||
329 | +++ b/openbsd-compat/port-linux.h | ||
330 | @@ -21,8 +21,8 @@ | ||
331 | |||
332 | #ifdef WITH_SELINUX | ||
333 | int ssh_selinux_enabled(void); | ||
334 | -void ssh_selinux_setup_pty(char *, const char *); | ||
335 | -void ssh_selinux_setup_exec_context(char *); | ||
336 | +void ssh_selinux_setup_pty(char *, const char *, const char *); | ||
337 | +void ssh_selinux_setup_exec_context(char *, const char *); | ||
338 | void ssh_selinux_change_context(const char *); | ||
339 | #endif | ||
340 | |||
341 | Index: b/platform.c | ||
342 | =================================================================== | ||
343 | --- a/platform.c | ||
344 | +++ b/platform.c | ||
345 | @@ -134,7 +134,7 @@ | ||
346 | * called if sshd is running as root. | ||
347 | */ | ||
348 | void | ||
349 | -platform_setusercontext_post_groups(struct passwd *pw) | ||
350 | +platform_setusercontext_post_groups(struct passwd *pw, const char *role) | ||
351 | { | ||
352 | #if !defined(HAVE_LOGIN_CAP) && defined(USE_PAM) | ||
353 | /* | ||
354 | @@ -181,7 +181,7 @@ | ||
355 | } | ||
356 | #endif /* HAVE_SETPCRED */ | ||
357 | #ifdef WITH_SELINUX | ||
358 | - ssh_selinux_setup_exec_context(pw->pw_name); | ||
359 | + ssh_selinux_setup_exec_context(pw->pw_name, role); | ||
360 | #endif | ||
361 | } | ||
362 | |||
363 | Index: b/platform.h | ||
364 | =================================================================== | ||
365 | --- a/platform.h | ||
366 | +++ b/platform.h | ||
367 | @@ -26,7 +26,7 @@ | ||
368 | void platform_post_fork_child(void); | ||
369 | int platform_privileged_uidswap(void); | ||
370 | void platform_setusercontext(struct passwd *); | ||
371 | -void platform_setusercontext_post_groups(struct passwd *); | ||
372 | +void platform_setusercontext_post_groups(struct passwd *, const char *); | ||
373 | char *platform_get_krb5_client(const char *); | ||
374 | char *platform_krb5_get_principal_name(const char *); | ||
375 | |||
376 | Index: b/session.c | ||
377 | =================================================================== | ||
378 | --- a/session.c | ||
379 | +++ b/session.c | ||
380 | @@ -1467,7 +1467,7 @@ | ||
381 | |||
382 | /* Set login name, uid, gid, and groups. */ | ||
383 | void | ||
384 | -do_setusercontext(struct passwd *pw) | ||
385 | +do_setusercontext(struct passwd *pw, const char *role) | ||
386 | { | ||
387 | char *chroot_path, *tmp; | ||
388 | |||
389 | @@ -1495,7 +1495,7 @@ | ||
390 | endgrent(); | ||
391 | #endif | ||
392 | |||
393 | - platform_setusercontext_post_groups(pw); | ||
394 | + platform_setusercontext_post_groups(pw, role); | ||
395 | |||
396 | if (options.chroot_directory != NULL && | ||
397 | strcasecmp(options.chroot_directory, "none") != 0) { | ||
398 | @@ -1618,7 +1618,7 @@ | ||
399 | |||
400 | /* Force a password change */ | ||
401 | if (s->authctxt->force_pwchange) { | ||
402 | - do_setusercontext(pw); | ||
403 | + do_setusercontext(pw, s->authctxt->role); | ||
404 | child_close_fds(); | ||
405 | do_pwchange(s); | ||
406 | exit(1); | ||
407 | @@ -1645,7 +1645,7 @@ | ||
408 | /* When PAM is enabled we rely on it to do the nologin check */ | ||
409 | if (!options.use_pam) | ||
410 | do_nologin(pw); | ||
411 | - do_setusercontext(pw); | ||
412 | + do_setusercontext(pw, s->authctxt->role); | ||
413 | /* | ||
414 | * PAM session modules in do_setusercontext may have | ||
415 | * generated messages, so if this in an interactive | ||
416 | @@ -2057,7 +2057,7 @@ | ||
417 | tty_parse_modes(s->ttyfd, &n_bytes); | ||
418 | |||
419 | if (!use_privsep) | ||
420 | - pty_setowner(s->pw, s->tty); | ||
421 | + pty_setowner(s->pw, s->tty, s->authctxt->role); | ||
422 | |||
423 | /* Set window size from the packet. */ | ||
424 | pty_change_window_size(s->ptyfd, s->row, s->col, s->xpixel, s->ypixel); | ||
425 | Index: b/session.h | ||
426 | =================================================================== | ||
427 | --- a/session.h | ||
428 | +++ b/session.h | ||
429 | @@ -76,7 +76,7 @@ | ||
430 | Session *session_new(void); | ||
431 | Session *session_by_tty(char *); | ||
432 | void session_close(Session *); | ||
433 | -void do_setusercontext(struct passwd *); | ||
434 | +void do_setusercontext(struct passwd *, const char *); | ||
435 | void child_set_env(char ***envp, u_int *envsizep, const char *name, | ||
436 | const char *value); | ||
437 | |||
438 | Index: b/sshd.c | ||
439 | =================================================================== | ||
440 | --- a/sshd.c | ||
441 | +++ b/sshd.c | ||
442 | @@ -707,7 +707,7 @@ | ||
443 | RAND_seed(rnd, sizeof(rnd)); | ||
444 | |||
445 | /* Drop privileges */ | ||
446 | - do_setusercontext(authctxt->pw); | ||
447 | + do_setusercontext(authctxt->pw, authctxt->role); | ||
448 | |||
449 | skip: | ||
450 | /* It is safe now to apply the key state */ | ||
451 | Index: b/sshpty.c | ||
452 | =================================================================== | ||
453 | --- a/sshpty.c | ||
454 | +++ b/sshpty.c | ||
455 | @@ -200,7 +200,7 @@ | ||
456 | } | ||
457 | |||
458 | void | ||
459 | -pty_setowner(struct passwd *pw, const char *tty) | ||
460 | +pty_setowner(struct passwd *pw, const char *tty, const char *role) | ||
461 | { | ||
462 | struct group *grp; | ||
463 | gid_t gid; | ||
464 | @@ -227,7 +227,7 @@ | ||
465 | strerror(errno)); | ||
466 | |||
467 | #ifdef WITH_SELINUX | ||
468 | - ssh_selinux_setup_pty(pw->pw_name, tty); | ||
469 | + ssh_selinux_setup_pty(pw->pw_name, tty, role); | ||
470 | #endif | ||
471 | |||
472 | if (st.st_uid != pw->pw_uid || st.st_gid != gid) { | ||
473 | Index: b/sshpty.h | ||
474 | =================================================================== | ||
475 | --- a/sshpty.h | ||
476 | +++ b/sshpty.h | ||
477 | @@ -24,4 +24,4 @@ | ||
478 | void pty_release(const char *); | ||
479 | void pty_make_controlling_tty(int *, const char *); | ||
480 | void pty_change_window_size(int, u_int, u_int, u_int, u_int); | ||
481 | -void pty_setowner(struct passwd *, const char *); | ||
482 | +void pty_setowner(struct passwd *, const char *, const char *); | ||