/[pkgs]/devel/openssh/openssh-5.3p1-mls.patch
ViewVC logotype

Contents of /devel/openssh/openssh-5.3p1-mls.patch

Parent Directory Parent Directory | Revision Log Revision Log


Revision 1.1 - (show annotations) (download) (as text)
Fri Oct 2 13:17:07 2009 UTC (7 weeks, 5 days ago) by jfch2222
Branch: MAIN
CVS Tags: openssh-5_3p1-10_fc13, openssh-5_3p1-4_fc13, openssh-5_3p1-1_fc13, openssh-5_3p1-2_fc13, openssh-5_3p1-5_fc13, openssh-5_3p1-3_fc13, openssh-5_3p1-6_fc13, openssh-5_3p1-9_fc13, openssh-5_3p1-7_fc13, openssh-5_3p1-8_fc13, HEAD
File MIME type: text/x-patch
Upgrade to new wersion 5.3p1
1 diff -up openssh-5.3p1/configure.ac.mls openssh-5.3p1/configure.ac
2 --- openssh-5.3p1/configure.ac.mls 2009-10-02 14:04:31.000000000 +0200
3 +++ openssh-5.3p1/configure.ac 2009-10-02 14:04:31.000000000 +0200
4 @@ -3404,6 +3404,7 @@ AC_ARG_WITH(selinux,
5 SSHDLIBS="$SSHDLIBS $LIBSELINUX"
6 LIBS="$LIBS $LIBSELINUX"
7 AC_CHECK_FUNCS(getseuserbyname get_default_context_with_level)
8 + AC_CHECK_FUNCS(setkeycreatecon)
9 LIBS="$save_LIBS"
10 fi ]
11 )
12 diff -up openssh-5.3p1/misc.c.mls openssh-5.3p1/misc.c
13 --- openssh-5.3p1/misc.c.mls 2009-02-21 22:47:02.000000000 +0100
14 +++ openssh-5.3p1/misc.c 2009-10-02 14:04:31.000000000 +0200
15 @@ -423,6 +423,7 @@ char *
16 colon(char *cp)
17 {
18 int flag = 0;
19 + int start = 1;
20
21 if (*cp == ':') /* Leading colon is part of file name. */
22 return (0);
23 @@ -436,8 +437,13 @@ colon(char *cp)
24 return (cp+1);
25 if (*cp == ':' && !flag)
26 return (cp);
27 - if (*cp == '/')
28 - return (0);
29 + if (start) {
30 + /* Slash on beginning or after dots only denotes file name. */
31 + if (*cp == '/')
32 + return (0);
33 + if (*cp != '.')
34 + start = 0;
35 + }
36 }
37 return (0);
38 }
39 diff -up openssh-5.3p1/openbsd-compat/port-linux.c.mls openssh-5.3p1/openbsd-compat/port-linux.c
40 --- openssh-5.3p1/openbsd-compat/port-linux.c.mls 2009-10-02 14:04:31.000000000 +0200
41 +++ openssh-5.3p1/openbsd-compat/port-linux.c 2009-10-02 14:04:31.000000000 +0200
42 @@ -33,12 +33,23 @@
43 #include "key.h"
44 #include "hostfile.h"
45 #include "auth.h"
46 +#include "xmalloc.h"
47
48 #include <selinux/selinux.h>
49 #include <selinux/flask.h>
50 +#include <selinux/context.h>
51 #include <selinux/get_context_list.h>
52 +#include <selinux/get_default_type.h>
53 +#include <selinux/av_permissions.h>
54 +
55 +#ifdef HAVE_LINUX_AUDIT
56 +#include <libaudit.h>
57 +#include <unistd.h>
58 +#endif
59
60 extern Authctxt *the_authctxt;
61 +extern int inetd_flag;
62 +extern int rexeced_flag;
63
64 /* Wrapper around is_selinux_enabled() to log its return value once only */
65 int
66 @@ -54,17 +65,173 @@ ssh_selinux_enabled(void)
67 return (enabled);
68 }
69
70 +/* Send audit message */
71 +static int
72 +send_audit_message(int success, security_context_t default_context,
73 + security_context_t selected_context)
74 +{
75 + int rc=0;
76 +#ifdef HAVE_LINUX_AUDIT
77 + char *msg = NULL;
78 + int audit_fd = audit_open();
79 + security_context_t default_raw=NULL;
80 + security_context_t selected_raw=NULL;
81 + rc = -1;
82 + if (audit_fd < 0) {
83 + if (errno == EINVAL || errno == EPROTONOSUPPORT ||
84 + errno == EAFNOSUPPORT)
85 + return 0; /* No audit support in kernel */
86 + error("Error connecting to audit system.");
87 + return rc;
88 + }
89 + if (selinux_trans_to_raw_context(default_context, &default_raw) < 0) {
90 + error("Error translating default context.");
91 + default_raw = NULL;
92 + }
93 + if (selinux_trans_to_raw_context(selected_context, &selected_raw) < 0) {
94 + error("Error translating selected context.");
95 + selected_raw = NULL;
96 + }
97 + if (asprintf(&msg, "sshd: default-context=%s selected-context=%s",
98 + default_raw ? default_raw : (default_context ? default_context: "?"),
99 + selected_context ? selected_raw : (selected_context ? selected_context :"?")) < 0) {
100 + error("Error allocating memory.");
101 + goto out;
102 + }
103 + if (audit_log_user_message(audit_fd, AUDIT_USER_ROLE_CHANGE,
104 + msg, NULL, NULL, NULL, success) <= 0) {
105 + error("Error sending audit message.");
106 + goto out;
107 + }
108 + rc = 0;
109 + out:
110 + free(msg);
111 + freecon(default_raw);
112 + freecon(selected_raw);
113 + close(audit_fd);
114 +#endif
115 + return rc;
116 +}
117 +
118 +static int
119 +mls_range_allowed(security_context_t src, security_context_t dst)
120 +{
121 + struct av_decision avd;
122 + int retval;
123 + unsigned int bit = CONTEXT__CONTAINS;
124 +
125 + debug("%s: src:%s dst:%s", __func__, src, dst);
126 + retval = security_compute_av(src, dst, SECCLASS_CONTEXT, bit, &avd);
127 + if (retval || ((bit & avd.allowed) != bit))
128 + return 0;
129 +
130 + return 1;
131 +}
132 +
133 +static int
134 +get_user_context(const char *sename, const char *role, const char *lvl,
135 + security_context_t *sc) {
136 +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
137 + if (lvl == NULL || lvl[0] == '\0' || get_default_context_with_level(sename, lvl, NULL, sc) != 0) {
138 + /* User may have requested a level completely outside of his
139 + allowed range. We get a context just for auditing as the
140 + range check below will certainly fail for default context. */
141 +#endif
142 + if (get_default_context(sename, NULL, sc) != 0) {
143 + *sc = NULL;
144 + return -1;
145 + }
146 +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
147 + }
148 +#endif
149 + if (role != NULL && role[0]) {
150 + context_t con;
151 + char *type=NULL;
152 + if (get_default_type(role, &type) != 0) {
153 + error("get_default_type: failed to get default type for '%s'",
154 + role);
155 + goto out;
156 + }
157 + con = context_new(*sc);
158 + if (!con) {
159 + goto out;
160 + }
161 + context_role_set(con, role);
162 + context_type_set(con, type);
163 + freecon(*sc);
164 + *sc = strdup(context_str(con));
165 + context_free(con);
166 + if (!*sc)
167 + return -1;
168 + }
169 +#ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
170 + if (lvl != NULL && lvl[0]) {
171 + /* verify that the requested range is obtained */
172 + context_t con;
173 + security_context_t obtained_raw;
174 + security_context_t requested_raw;
175 + con = context_new(*sc);
176 + if (!con) {
177 + goto out;
178 + }
179 + context_range_set(con, lvl);
180 + if (selinux_trans_to_raw_context(*sc, &obtained_raw) < 0) {
181 + context_free(con);
182 + goto out;
183 + }
184 + if (selinux_trans_to_raw_context(context_str(con), &requested_raw) < 0) {
185 + freecon(obtained_raw);
186 + context_free(con);
187 + goto out;
188 + }
189 +
190 + debug("get_user_context: obtained context '%s' requested context '%s'",
191 + obtained_raw, requested_raw);
192 + if (strcmp(obtained_raw, requested_raw)) {
193 + /* set the context to the real requested one but fail */
194 + freecon(requested_raw);
195 + freecon(obtained_raw);
196 + freecon(*sc);
197 + *sc = strdup(context_str(con));
198 + context_free(con);
199 + return -1;
200 + }
201 + freecon(requested_raw);
202 + freecon(obtained_raw);
203 + context_free(con);
204 + }
205 +#endif
206 + return 0;
207 + out:
208 + freecon(*sc);
209 + *sc = NULL;
210 + return -1;
211 +}
212 +
213 /* Return the default security context for the given username */
214 -static security_context_t
215 -ssh_selinux_getctxbyname(char *pwname)
216 +static int
217 +ssh_selinux_getctxbyname(char *pwname,
218 + security_context_t *default_sc, security_context_t *user_sc)
219 {
220 - security_context_t sc = NULL;
221 char *sename, *lvl;
222 + const char *reqlvl = NULL;
223 char *role = NULL;
224 - int r = 0;
225 + int r = -1;
226 + context_t con = NULL;
227 +
228 + *default_sc = NULL;
229 + *user_sc = NULL;
230 + if (the_authctxt) {
231 + if (the_authctxt->role != NULL) {
232 + char *slash;
233 + role = xstrdup(the_authctxt->role);
234 + if ((slash = strchr(role, '/')) != NULL) {
235 + *slash = '\0';
236 + reqlvl = slash + 1;
237 + }
238 + }
239 + }
240
241 - if (the_authctxt)
242 - role=the_authctxt->role;
243 #ifdef HAVE_GETSEUSERBYNAME
244 if ((r=getseuserbyname(pwname, &sename, &lvl)) != 0) {
245 sename = NULL;
246 @@ -72,38 +239,63 @@ ssh_selinux_getctxbyname(char *pwname)
247 }
248 #else
249 sename = pwname;
250 - lvl = NULL;
251 + lvl = "";
252 #endif
253
254 if (r == 0) {
255 #ifdef HAVE_GET_DEFAULT_CONTEXT_WITH_LEVEL
256 - if (role != NULL && role[0])
257 - r = get_default_context_with_rolelevel(sename, role, lvl, NULL, &sc);
258 - else
259 - r = get_default_context_with_level(sename, lvl, NULL, &sc);
260 + r = get_default_context_with_level(sename, lvl, NULL, default_sc);
261 #else
262 - if (role != NULL && role[0])
263 - r = get_default_context_with_role(sename, role, NULL, &sc);
264 - else
265 - r = get_default_context(sename, NULL, &sc);
266 + r = get_default_context(sename, NULL, default_sc);
267 #endif
268 }
269
270 - if (r != 0) {
271 - switch (security_getenforce()) {
272 - case -1:
273 - fatal("%s: ssh_selinux_getctxbyname: "
274 - "security_getenforce() failed", __func__);
275 - case 0:
276 - error("%s: Failed to get default SELinux security "
277 - "context for %s", __func__, pwname);
278 - break;
279 - default:
280 - fatal("%s: Failed to get default SELinux security "
281 - "context for %s (in enforcing mode)",
282 - __func__, pwname);
283 + if (r == 0) {
284 + /* If launched from xinetd, we must use current level */
285 + if (inetd_flag && !rexeced_flag) {
286 + security_context_t sshdsc=NULL;
287 +
288 + if (getcon_raw(&sshdsc) < 0)
289 + fatal("failed to allocate security context");
290 +
291 + if ((con=context_new(sshdsc)) == NULL)
292 + fatal("failed to allocate selinux context");
293 + reqlvl = context_range_get(con);
294 + freecon(sshdsc);
295 + if (reqlvl !=NULL && lvl != NULL && strcmp(reqlvl, lvl) == 0)
296 + /* we actually don't change level */
297 + reqlvl = "";
298 +
299 + debug("%s: current connection level '%s'", __func__, reqlvl);
300 + }
301 +
302 + if ((reqlvl != NULL && reqlvl[0]) || (role != NULL && role[0])) {
303 + r = get_user_context(sename, role, reqlvl, user_sc);
304 +
305 + if (r == 0 && reqlvl != NULL && reqlvl[0]) {
306 + security_context_t default_level_sc = *default_sc;
307 + if (role != NULL && role[0]) {
308 + if (get_user_context(sename, role, lvl, &default_level_sc) < 0)
309 + default_level_sc = *default_sc;
310 + }
311 + /* verify that the requested range is contained in the user range */
312 + if (mls_range_allowed(default_level_sc, *user_sc)) {
313 + logit("permit MLS level %s (user range %s)", reqlvl, lvl);
314 + } else {
315 + r = -1;
316 + error("deny MLS level %s (user range %s)", reqlvl, lvl);
317 + }
318 + if (default_level_sc != *default_sc)
319 + freecon(default_level_sc);
320 + }
321 + } else {
322 + *user_sc = *default_sc;
323 }
324 }
325 + if (r != 0) {
326 + error("%s: Failed to get default SELinux security "
327 + "context for %s", __func__, pwname);
328 + }
329
330 #ifdef HAVE_GETSEUSERBYNAME
331 if (sename != NULL)
332 @@ -111,14 +303,20 @@ ssh_selinux_getctxbyname(char *pwname)
333 if (lvl != NULL)
334 xfree(lvl);
335 #endif
336 + if (role != NULL)
337 + xfree(role);
338 + if (con)
339 + context_free(con);
340
341 - return (sc);
342 + return (r);
343 }
344
345 /* Set the execution context to the default for the specified user */
346 void
347 ssh_selinux_setup_exec_context(char *pwname)
348 {
349 + int r = 0;
350 + security_context_t default_ctx = NULL;
351 security_context_t user_ctx = NULL;
352
353 if (!ssh_selinux_enabled())
354 @@ -126,22 +324,45 @@ ssh_selinux_setup_exec_context(char *pwn
355
356 debug3("%s: setting execution context", __func__);
357
358 - user_ctx = ssh_selinux_getctxbyname(pwname);
359 - if (setexeccon(user_ctx) != 0) {
360 + r = ssh_selinux_getctxbyname(pwname, &default_ctx, &user_ctx);
361 + if (r >= 0) {
362 + r = setexeccon(user_ctx);
363 + if (r < 0) {
364 + error("%s: Failed to set SELinux execution context %s for %s",
365 + __func__, user_ctx, pwname);
366 + }
367 +#ifdef HAVE_SETKEYCREATECON
368 + else if (setkeycreatecon(user_ctx) < 0) {
369 + error("%s: Failed to set SELinux keyring creation context %s for %s",
370 + __func__, user_ctx, pwname);
371 + }
372 +#endif
373 + }
374 + if (user_ctx == NULL) {
375 + user_ctx = default_ctx;
376 + }
377 + if (r < 0 || user_ctx != default_ctx) {
378 + /* audit just the case when user changed a role or there was
379 + a failure */
380 + send_audit_message(r >= 0, default_ctx, user_ctx);
381 + }
382 + if (r < 0) {
383 switch (security_getenforce()) {
384 case -1:
385 fatal("%s: security_getenforce() failed", __func__);
386 case 0:
387 - error("%s: Failed to set SELinux execution "
388 - "context for %s", __func__, pwname);
389 + error("%s: SELinux failure. Continuing in permissive mode.",
390 + __func__);
391 break;
392 default:
393 - fatal("%s: Failed to set SELinux execution context "
394 - "for %s (in enforcing mode)", __func__, pwname);
395 + fatal("%s: SELinux failure. Aborting connection.",
396 + __func__);
397 }
398 }
399 - if (user_ctx != NULL)
400 + if (user_ctx != NULL && user_ctx != default_ctx)
401 freecon(user_ctx);
402 + if (default_ctx != NULL)
403 + freecon(default_ctx);
404
405 debug3("%s: done", __func__);
406 }
407 @@ -159,7 +380,10 @@ ssh_selinux_setup_pty(char *pwname, cons
408
409 debug3("%s: setting TTY context on %s", __func__, tty);
410
411 - user_ctx = ssh_selinux_getctxbyname(pwname);
412 + if (getexeccon(&user_ctx) < 0) {
413 + error("%s: getexeccon: %s", __func__, strerror(errno));
414 + goto out;
415 + }
416
417 /* XXX: should these calls fatal() upon failure in enforcing mode? */
418
419 diff -up openssh-5.3p1/session.c.mls openssh-5.3p1/session.c
420 --- openssh-5.3p1/session.c.mls 2009-08-20 08:20:50.000000000 +0200
421 +++ openssh-5.3p1/session.c 2009-10-02 14:06:12.000000000 +0200
422 @@ -1550,10 +1550,6 @@ do_setusercontext(struct passwd *pw)
423
424 if (getuid() != pw->pw_uid || geteuid() != pw->pw_uid)
425 fatal("Failed to set uids to %u.", (u_int) pw->pw_uid);
426 -
427 -#ifdef WITH_SELINUX
428 - ssh_selinux_setup_exec_context(pw->pw_name);
429 -#endif
430 }
431
432 static void
433 diff -up openssh-5.3p1/sshd.c.mls openssh-5.3p1/sshd.c
434 --- openssh-5.3p1/sshd.c.mls 2009-10-02 14:04:31.000000000 +0200
435 +++ openssh-5.3p1/sshd.c 2009-10-02 14:04:31.000000000 +0200
436 @@ -1896,6 +1896,9 @@ main(int ac, char **av)
437 restore_uid();
438 }
439 #endif
440 +#ifdef WITH_SELINUX
441 + ssh_selinux_setup_exec_context(authctxt->pw->pw_name);
442 +#endif
443 #ifdef USE_PAM
444 if (options.use_pam) {
445 do_pam_setcred(1);

admin@fedoraproject.org
ViewVC Help
Powered by ViewVC 1.1.2