diff options
Diffstat (limited to 'debian')
-rw-r--r-- | debian/changelog | 6 | ||||
-rw-r--r-- | debian/patches/debian-config.patch | 2 | ||||
-rw-r--r-- | debian/patches/user-group-modes.patch | 155 |
3 files changed, 131 insertions, 32 deletions
diff --git a/debian/changelog b/debian/changelog index 5790f4643..a27f3b57f 100644 --- a/debian/changelog +++ b/debian/changelog | |||
@@ -4,6 +4,12 @@ openssh (1:5.5p1-4) UNRELEASED; urgency=low | |||
4 | * Add powerpcspe to architecture list for libselinux1-dev build-dependency | 4 | * Add powerpcspe to architecture list for libselinux1-dev build-dependency |
5 | (closes: #579843). | 5 | (closes: #579843). |
6 | 6 | ||
7 | [ Colin Watson ] | ||
8 | * Allow ~/.ssh/authorized_keys and other secure files to be | ||
9 | group-writable, provided that the group in question contains only the | ||
10 | file's owner; this extends a patch previously applied to ~/.ssh/config | ||
11 | (closes: #581919). | ||
12 | |||
7 | -- Colin Watson <cjwatson@debian.org> Tue, 04 May 2010 13:32:17 +0100 | 13 | -- Colin Watson <cjwatson@debian.org> Tue, 04 May 2010 13:32:17 +0100 |
8 | 14 | ||
9 | openssh (1:5.5p1-3) unstable; urgency=low | 15 | openssh (1:5.5p1-3) unstable; urgency=low |
diff --git a/debian/patches/debian-config.patch b/debian/patches/debian-config.patch index a395d43a0..ac77919e6 100644 --- a/debian/patches/debian-config.patch +++ b/debian/patches/debian-config.patch | |||
@@ -24,7 +24,7 @@ Index: b/readconf.c | |||
24 | =================================================================== | 24 | =================================================================== |
25 | --- a/readconf.c | 25 | --- a/readconf.c |
26 | +++ b/readconf.c | 26 | +++ b/readconf.c |
27 | @@ -1152,7 +1152,7 @@ | 27 | @@ -1132,7 +1132,7 @@ |
28 | if (options->forward_x11 == -1) | 28 | if (options->forward_x11 == -1) |
29 | options->forward_x11 = 0; | 29 | options->forward_x11 = 0; |
30 | if (options->forward_x11_trusted == -1) | 30 | if (options->forward_x11_trusted == -1) |
diff --git a/debian/patches/user-group-modes.patch b/debian/patches/user-group-modes.patch index 4d7ebe566..8cf862049 100644 --- a/debian/patches/user-group-modes.patch +++ b/debian/patches/user-group-modes.patch | |||
@@ -1,10 +1,11 @@ | |||
1 | Description: Allow harmless group-writability | 1 | Description: Allow harmless group-writability |
2 | Allow ~/.ssh/config to be group-writable, provided that the group in | 2 | Allow secure files (~/.ssh/config, ~/.ssh/authorized_keys, etc.) to be |
3 | question contains only the file's owner. Rejected upstream for IMO | 3 | group-writable, provided that the group in question contains only the |
4 | incorrect reasons (e.g. a misunderstanding about the contents of | 4 | file's owner. Rejected upstream for IMO incorrect reasons (e.g. a |
5 | gr->gr_mem). Given that per-user groups and umask 002 are the default | 5 | misunderstanding about the contents of gr->gr_mem). Given that |
6 | setup in Debian (for good reasons - this makes operating in setgid | 6 | per-user groups and umask 002 are the default setup in Debian (for good |
7 | directories with other groups much easier), we need to permit this. | 7 | reasons - this makes operating in setgid directories with other groups |
8 | much easier), we need to permit this by default. | ||
8 | Author: Colin Watson <cjwatson@debian.org> | 9 | Author: Colin Watson <cjwatson@debian.org> |
9 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 | 10 | Bug: https://bugzilla.mindrot.org/show_bug.cgi?id=1060 |
10 | Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 | 11 | Bug-Debian: http://bugs.debian.org/cgi-bin/bugreport.cgi?bug=314347 |
@@ -23,36 +24,13 @@ Index: b/readconf.c | |||
23 | 24 | ||
24 | #include "xmalloc.h" | 25 | #include "xmalloc.h" |
25 | #include "ssh.h" | 26 | #include "ssh.h" |
26 | @@ -1000,11 +1002,30 @@ | 27 | @@ -1003,8 +1005,7 @@ |
27 | |||
28 | if (checkperm) { | ||
29 | struct stat sb; | ||
30 | + int bad_modes = 0; | ||
31 | 28 | ||
32 | if (fstat(fileno(f), &sb) == -1) | 29 | if (fstat(fileno(f), &sb) == -1) |
33 | fatal("fstat %s: %s", filename, strerror(errno)); | 30 | fatal("fstat %s: %s", filename, strerror(errno)); |
34 | - if (((sb.st_uid != 0 && sb.st_uid != getuid()) || | 31 | - if (((sb.st_uid != 0 && sb.st_uid != getuid()) || |
35 | - (sb.st_mode & 022) != 0)) | 32 | - (sb.st_mode & 022) != 0)) |
36 | + if (sb.st_uid != 0 && sb.st_uid != getuid()) | 33 | + if (!secure_permissions(&sb, getuid())) |
37 | + bad_modes = 1; | ||
38 | + if ((sb.st_mode & 020) != 0) { | ||
39 | + /* If the file is group-writable, the group in | ||
40 | + * question must have at most one member, namely the | ||
41 | + * file's owner. | ||
42 | + */ | ||
43 | + struct passwd *pw = getpwuid(sb.st_uid); | ||
44 | + struct group *gr = getgrgid(sb.st_gid); | ||
45 | + if (!pw || !gr) | ||
46 | + bad_modes = 1; | ||
47 | + else if (gr->gr_mem[0]) { | ||
48 | + if (strcmp(pw->pw_name, gr->gr_mem[0]) || | ||
49 | + gr->gr_mem[1]) | ||
50 | + bad_modes = 1; | ||
51 | + } | ||
52 | + } | ||
53 | + if ((sb.st_mode & 002) != 0) | ||
54 | + bad_modes = 1; | ||
55 | + if (bad_modes) | ||
56 | fatal("Bad owner or permissions on %s", filename); | 34 | fatal("Bad owner or permissions on %s", filename); |
57 | } | 35 | } |
58 | 36 | ||
@@ -82,3 +60,118 @@ Index: b/ssh_config.5 | |||
82 | .It Pa /etc/ssh/ssh_config | 60 | .It Pa /etc/ssh/ssh_config |
83 | Systemwide configuration file. | 61 | Systemwide configuration file. |
84 | This file provides defaults for those | 62 | This file provides defaults for those |
63 | Index: b/auth.c | ||
64 | =================================================================== | ||
65 | --- a/auth.c | ||
66 | +++ b/auth.c | ||
67 | @@ -385,8 +385,7 @@ | ||
68 | user_hostfile = tilde_expand_filename(userfile, pw->pw_uid); | ||
69 | if (options.strict_modes && | ||
70 | (stat(user_hostfile, &st) == 0) && | ||
71 | - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || | ||
72 | - (st.st_mode & 022) != 0)) { | ||
73 | + !secure_permissions(&st, pw->pw_uid)) { | ||
74 | logit("Authentication refused for %.100s: " | ||
75 | "bad owner or modes for %.200s", | ||
76 | pw->pw_name, user_hostfile); | ||
77 | @@ -438,8 +437,7 @@ | ||
78 | |||
79 | /* check the open file to avoid races */ | ||
80 | if (fstat(fileno(f), &st) < 0 || | ||
81 | - (st.st_uid != 0 && st.st_uid != uid) || | ||
82 | - (st.st_mode & 022) != 0) { | ||
83 | + !secure_permissions(&st, uid)) { | ||
84 | snprintf(err, errlen, "bad ownership or modes for file %s", | ||
85 | buf); | ||
86 | return -1; | ||
87 | @@ -455,8 +453,7 @@ | ||
88 | |||
89 | debug3("secure_filename: checking '%s'", buf); | ||
90 | if (stat(buf, &st) < 0 || | ||
91 | - (st.st_uid != 0 && st.st_uid != uid) || | ||
92 | - (st.st_mode & 022) != 0) { | ||
93 | + !secure_permissions(&st, uid)) { | ||
94 | snprintf(err, errlen, | ||
95 | "bad ownership or modes for directory %s", buf); | ||
96 | return -1; | ||
97 | Index: b/misc.c | ||
98 | =================================================================== | ||
99 | --- a/misc.c | ||
100 | +++ b/misc.c | ||
101 | @@ -45,8 +45,9 @@ | ||
102 | #include <netdb.h> | ||
103 | #ifdef HAVE_PATHS_H | ||
104 | # include <paths.h> | ||
105 | -#include <pwd.h> | ||
106 | #endif | ||
107 | +#include <pwd.h> | ||
108 | +#include <grp.h> | ||
109 | #ifdef SSH_TUN_OPENBSD | ||
110 | #include <net/if.h> | ||
111 | #endif | ||
112 | @@ -638,6 +639,30 @@ | ||
113 | } | ||
114 | |||
115 | int | ||
116 | +secure_permissions(struct stat *st, uid_t uid) | ||
117 | +{ | ||
118 | + if (st->st_uid != 0 && st->st_uid != uid) | ||
119 | + return 0; | ||
120 | + if ((st->st_mode & 020) != 0) { | ||
121 | + /* If the file is group-writable, the group in question must | ||
122 | + * have at most one member, namely the file's owner. | ||
123 | + */ | ||
124 | + struct passwd *pw = getpwuid(st->st_uid); | ||
125 | + struct group *gr = getgrgid(st->st_gid); | ||
126 | + if (!pw || !gr) | ||
127 | + return 0; | ||
128 | + else if (gr->gr_mem[0]) { | ||
129 | + if (strcmp(pw->pw_name, gr->gr_mem[0]) || | ||
130 | + gr->gr_mem[1]) | ||
131 | + return 0; | ||
132 | + } | ||
133 | + } | ||
134 | + if ((st->st_mode & 002) != 0) | ||
135 | + return 0; | ||
136 | + return 1; | ||
137 | +} | ||
138 | + | ||
139 | +int | ||
140 | tun_open(int tun, int mode) | ||
141 | { | ||
142 | #if defined(CUSTOM_SYS_TUN_OPEN) | ||
143 | Index: b/misc.h | ||
144 | =================================================================== | ||
145 | --- a/misc.h | ||
146 | +++ b/misc.h | ||
147 | @@ -91,4 +91,6 @@ | ||
148 | int ask_permission(const char *, ...) __attribute__((format(printf, 1, 2))); | ||
149 | int read_keyfile_line(FILE *, const char *, char *, size_t, u_long *); | ||
150 | |||
151 | +int secure_permissions(struct stat *st, uid_t uid); | ||
152 | + | ||
153 | #endif /* _MISC_H */ | ||
154 | Index: b/auth-rhosts.c | ||
155 | =================================================================== | ||
156 | --- a/auth-rhosts.c | ||
157 | +++ b/auth-rhosts.c | ||
158 | @@ -256,8 +256,7 @@ | ||
159 | return 0; | ||
160 | } | ||
161 | if (options.strict_modes && | ||
162 | - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || | ||
163 | - (st.st_mode & 022) != 0)) { | ||
164 | + !secure_permissions(&st, pw->pw_uid)) { | ||
165 | logit("Rhosts authentication refused for %.100s: " | ||
166 | "bad ownership or modes for home directory.", pw->pw_name); | ||
167 | auth_debug_add("Rhosts authentication refused for %.100s: " | ||
168 | @@ -283,8 +282,7 @@ | ||
169 | * allowing access to their account by anyone. | ||
170 | */ | ||
171 | if (options.strict_modes && | ||
172 | - ((st.st_uid != 0 && st.st_uid != pw->pw_uid) || | ||
173 | - (st.st_mode & 022) != 0)) { | ||
174 | + !secure_permissions(&st, pw->pw_uid)) { | ||
175 | logit("Rhosts authentication refused for %.100s: bad modes for %.200s", | ||
176 | pw->pw_name, buf); | ||
177 | auth_debug_add("Bad file modes for %.200s", buf); | ||