]> git.ipfire.org Git - people/pmueller/ipfire-3.x.git/blob - openssh/patches/openssh-5.9p1-akc.patch
openssh: Don't pull in -server and -client.
[people/pmueller/ipfire-3.x.git] / openssh / patches / openssh-5.9p1-akc.patch
1 diff -up openssh-5.9p1/auth2-pubkey.c.akc openssh-5.9p1/auth2-pubkey.c
2 --- openssh-5.9p1/auth2-pubkey.c.akc 2011-09-14 07:24:40.876512251 +0200
3 +++ openssh-5.9p1/auth2-pubkey.c 2011-09-14 07:24:43.318458515 +0200
4 @@ -27,6 +27,7 @@
5
6 #include <sys/types.h>
7 #include <sys/stat.h>
8 +#include <sys/wait.h>
9
10 #include <fcntl.h>
11 #include <pwd.h>
12 @@ -276,27 +277,15 @@ match_principals_file(char *file, struct
13
14 /* return 1 if user allows given key */
15 static int
16 -user_key_allowed2(struct passwd *pw, Key *key, char *file)
17 +user_search_key_in_file(FILE *f, char *file, Key* key, struct passwd *pw)
18 {
19 char line[SSH_MAX_PUBKEY_BYTES];
20 const char *reason;
21 int found_key = 0;
22 - FILE *f;
23 u_long linenum = 0;
24 Key *found;
25 char *fp;
26
27 - /* Temporarily use the user's uid. */
28 - temporarily_use_uid(pw);
29 -
30 - debug("trying public key file %s", file);
31 - f = auth_openkeyfile(file, pw, options.strict_modes);
32 -
33 - if (!f) {
34 - restore_uid();
35 - return 0;
36 - }
37 -
38 found_key = 0;
39 found = key_new(key_is_cert(key) ? KEY_UNSPEC : key->type);
40
41 @@ -389,8 +378,6 @@ user_key_allowed2(struct passwd *pw, Key
42 break;
43 }
44 }
45 - restore_uid();
46 - fclose(f);
47 key_free(found);
48 if (!found_key)
49 debug2("key not found");
50 @@ -452,13 +439,191 @@ user_cert_trusted_ca(struct passwd *pw,
51 return ret;
52 }
53
54 -/* check whether given key is in .ssh/authorized_keys* */
55 +/* return 1 if user allows given key */
56 +static int
57 +user_key_allowed2(struct passwd *pw, Key *key, char *file)
58 +{
59 + FILE *f;
60 + int found_key = 0;
61 +
62 + /* Temporarily use the user's uid. */
63 + temporarily_use_uid(pw);
64 +
65 + debug("trying public key file %s", file);
66 + f = auth_openkeyfile(file, pw, options.strict_modes);
67 +
68 + if (f) {
69 + found_key = user_search_key_in_file (f, file, key, pw);
70 + fclose(f);
71 + }
72 +
73 + restore_uid();
74 + return found_key;
75 +}
76 +
77 +#ifdef WITH_AUTHORIZED_KEYS_COMMAND
78 +
79 +#define WHITESPACE " \t\r\n"
80 +
81 +/* return 1 if user allows given key */
82 +static int
83 +user_key_via_command_allowed2(struct passwd *pw, Key *key)
84 +{
85 + FILE *f;
86 + int found_key = 0;
87 + char *progname = NULL;
88 + char *cp;
89 + struct passwd *runas_pw;
90 + struct stat st;
91 + int childdescriptors[2], i;
92 + pid_t pstat, pid, child;
93 +
94 + if (options.authorized_keys_command == NULL || options.authorized_keys_command[0] != '/')
95 + return 0;
96 +
97 + /* get the run as identity from config */
98 + runas_pw = (options.authorized_keys_command_runas == NULL)? pw
99 + : getpwnam (options.authorized_keys_command_runas);
100 + if (!runas_pw) {
101 + error("%s: getpwnam(\"%s\"): %s", __func__,
102 + options.authorized_keys_command_runas, strerror(errno));
103 + return 0;
104 + }
105 +
106 + /* Temporarily use the specified uid. */
107 + if (runas_pw->pw_uid != 0)
108 + temporarily_use_uid(runas_pw);
109 +
110 + progname = xstrdup(options.authorized_keys_command);
111 +
112 + debug3("%s: checking program '%s'", __func__, progname);
113 +
114 + if (stat (progname, &st) < 0) {
115 + error("%s: stat(\"%s\"): %s", __func__,
116 + progname, strerror(errno));
117 + goto go_away;
118 + }
119 +
120 + if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
121 + error("bad ownership or modes for AuthorizedKeysCommand \"%s\"",
122 + progname);
123 + goto go_away;
124 + }
125 +
126 + if (!S_ISREG(st.st_mode)) {
127 + error("AuthorizedKeysCommand \"%s\" is not a regular file",
128 + progname);
129 + goto go_away;
130 + }
131 +
132 + /*
133 + * Descend the path, checking that each component is a
134 + * root-owned directory with strict permissions.
135 + */
136 + do {
137 + if ((cp = strrchr(progname, '/')) == NULL)
138 + break;
139 + else
140 + *cp = '\0';
141 +
142 + debug3("%s: checking component '%s'", __func__, (*progname == '\0' ? "/" : progname));
143 +
144 + if (stat((*progname == '\0' ? "/" : progname), &st) != 0) {
145 + error("%s: stat(\"%s\"): %s", __func__,
146 + progname, strerror(errno));
147 + goto go_away;
148 + }
149 + if (st.st_uid != 0 || (st.st_mode & 022) != 0) {
150 + error("bad ownership or modes for AuthorizedKeysCommand path component \"%s\"",
151 + progname);
152 + goto go_away;
153 + }
154 + if (!S_ISDIR(st.st_mode)) {
155 + error("AuthorizedKeysCommand path component \"%s\" is not a directory",
156 + progname);
157 + goto go_away;
158 + }
159 + } while (1);
160 +
161 + /* open the pipe and read the keys */
162 + if (pipe(childdescriptors)) {
163 + error("failed to pipe(2) for AuthorizedKeysCommand: %s",
164 + strerror(errno));
165 + goto go_away;
166 + }
167 +
168 + child = fork();
169 + if (child == -1) {
170 + error("failed to fork(2) for AuthorizedKeysCommand: %s",
171 + strerror(errno));
172 + goto go_away;
173 + } else if (child == 0) {
174 + /* we're in the child process here -- we should never return from this block. */
175 + /* permanently drop privs in child process */
176 + if (runas_pw->pw_uid != 0) {
177 + restore_uid();
178 + permanently_set_uid(runas_pw);
179 + }
180 +
181 + close(childdescriptors[0]);
182 + /* put the write end of the pipe on stdout (FD 1) */
183 + if (dup2(childdescriptors[1], 1) == -1) {
184 + error("failed to dup2(2) from AuthorizedKeysCommand: %s",
185 + strerror(errno));
186 + _exit(127);
187 + }
188 +
189 + debug3("about to execl() AuthorizedKeysCommand: \"%s\" \"%s\"", options.authorized_keys_command, pw->pw_name);
190 + /* see session.c:child_close_fds() */
191 + for (i = 3; i < 64; ++i) {
192 + close(i);
193 + }
194 +
195 + execl(options.authorized_keys_command, options.authorized_keys_command, pw->pw_name, NULL);
196 +
197 + /* if we got here, it didn't work */
198 + error("failed to execl AuthorizedKeysCommand: %s", strerror(errno)); /* this won't work because we closed the fds above */
199 + _exit(127);
200 + }
201 +
202 + close(childdescriptors[1]);
203 + f = fdopen(childdescriptors[0], "r");
204 + if (!f) {
205 + error("%s: could not buffer FDs from AuthorizedKeysCommand (\"%s\", \"r\"): %s", __func__,
206 + options.authorized_keys_command, strerror (errno));
207 + goto go_away;
208 + }
209 +
210 + found_key = user_search_key_in_file (f, options.authorized_keys_command, key, pw);
211 + fclose (f);
212 + do {
213 + pid = waitpid(child, &pstat, 0);
214 + } while (pid == -1 && errno == EINTR);
215 +
216 + /* what about the return value from the child process? */
217 +go_away:
218 + if (progname)
219 + xfree (progname);
220 +
221 + if (runas_pw->pw_uid != 0)
222 + restore_uid();
223 + return found_key;
224 +}
225 +#endif
226 +
227 +/* check whether given key is in <AuthorizedKeysCommand or .ssh/authorized_keys* */
228 int
229 user_key_allowed(struct passwd *pw, Key *key)
230 {
231 u_int success, i;
232 char *file;
233
234 +#ifdef WITH_AUTHORIZED_KEYS_COMMAND
235 + success = user_key_via_command_allowed2(pw, key);
236 + if (success > 0)
237 + return success;
238 +#endif
239 +
240 if (auth_key_is_revoked(key))
241 return 0;
242 if (key_is_cert(key) && auth_key_is_revoked(key->cert->signature_key))
243 diff -up openssh-5.9p1/configure.ac.akc openssh-5.9p1/configure.ac
244 --- openssh-5.9p1/configure.ac.akc 2011-09-14 07:24:42.863494886 +0200
245 +++ openssh-5.9p1/configure.ac 2011-09-14 07:24:43.441583848 +0200
246 @@ -1421,6 +1421,18 @@ AC_ARG_WITH([audit],
247 esac ]
248 )
249
250 +# Check whether user wants AuthorizedKeysCommand support
251 +AKC_MSG="no"
252 +AC_ARG_WITH(authorized-keys-command,
253 + [ --with-authorized-keys-command Enable AuthorizedKeysCommand support],
254 + [
255 + if test "x$withval" != "xno" ; then
256 + AC_DEFINE([WITH_AUTHORIZED_KEYS_COMMAND], 1, [Enable AuthorizedKeysCommand support])
257 + AKC_MSG="yes"
258 + fi
259 + ]
260 +)
261 +
262 dnl Checks for library functions. Please keep in alphabetical order
263 AC_CHECK_FUNCS([ \
264 arc4random \
265 @@ -4239,6 +4251,7 @@ echo " SELinux support
266 echo " Smartcard support: $SCARD_MSG"
267 echo " S/KEY support: $SKEY_MSG"
268 echo " TCP Wrappers support: $TCPW_MSG"
269 +echo " AuthorizedKeysCommand support: $AKC_MSG"
270 echo " MD5 password support: $MD5_MSG"
271 echo " libedit support: $LIBEDIT_MSG"
272 echo " Solaris process contract support: $SPC_MSG"
273 diff -up openssh-5.9p1/servconf.c.akc openssh-5.9p1/servconf.c
274 --- openssh-5.9p1/servconf.c.akc 2011-09-14 07:24:29.402475399 +0200
275 +++ openssh-5.9p1/servconf.c 2011-09-14 07:56:27.158585590 +0200
276 @@ -139,6 +139,8 @@ initialize_server_options(ServerOptions
277 options->num_permitted_opens = -1;
278 options->adm_forced_command = NULL;
279 options->chroot_directory = NULL;
280 + options->authorized_keys_command = NULL;
281 + options->authorized_keys_command_runas = NULL;
282 options->zero_knowledge_password_authentication = -1;
283 options->revoked_keys_file = NULL;
284 options->trusted_user_ca_keys = NULL;
285 @@ -348,6 +350,7 @@ typedef enum {
286 sZeroKnowledgePasswordAuthentication, sHostCertificate,
287 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
288 sKexAlgorithms, sIPQoS,
289 + sAuthorizedKeysCommand, sAuthorizedKeysCommandRunAs,
290 sDeprecated, sUnsupported
291 } ServerOpCodes;
292
293 @@ -487,6 +490,13 @@ static struct {
294 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_ALL },
295 { "kexalgorithms", sKexAlgorithms, SSHCFG_GLOBAL },
296 { "ipqos", sIPQoS, SSHCFG_ALL },
297 +#ifdef WITH_AUTHORIZED_KEYS_COMMAND
298 + { "authorizedkeyscommand", sAuthorizedKeysCommand, SSHCFG_ALL },
299 + { "authorizedkeyscommandrunas", sAuthorizedKeysCommandRunAs, SSHCFG_ALL },
300 +#else
301 + { "authorizedkeyscommand", sUnsupported, SSHCFG_ALL },
302 + { "authorizedkeyscommandrunas", sUnsupported, SSHCFG_ALL },
303 +#endif
304 { NULL, sBadOption, 0 }
305 };
306
307 @@ -1462,6 +1472,24 @@ process_server_config_line(ServerOptions
308 }
309 break;
310
311 + case sAuthorizedKeysCommand:
312 + len = strspn(cp, WHITESPACE);
313 + if (*activep && options->authorized_keys_command == NULL)
314 + options->authorized_keys_command = xstrdup(cp + len);
315 + return 0;
316 +
317 + case sAuthorizedKeysCommandRunAs:
318 + charptr = &options->authorized_keys_command_runas;
319 +
320 + arg = strdelim(&cp);
321 + if (!arg || *arg == '\0')
322 + fatal("%s line %d: missing account.",
323 + filename, linenum);
324 +
325 + if (*activep && *charptr == NULL)
326 + *charptr = xstrdup(arg);
327 + break;
328 +
329 case sDeprecated:
330 logit("%s line %d: Deprecated option %s",
331 filename, linenum, arg);
332 @@ -1573,6 +1601,8 @@ copy_set_server_options(ServerOptions *d
333 M_CP_INTOPT(zero_knowledge_password_authentication);
334 M_CP_INTOPT(second_zero_knowledge_password_authentication);
335 M_CP_INTOPT(two_factor_authentication);
336 + M_CP_STROPT(authorized_keys_command);
337 + M_CP_STROPT(authorized_keys_command_runas);
338 M_CP_INTOPT(permit_root_login);
339 M_CP_INTOPT(permit_empty_passwd);
340
341 @@ -1839,6 +1869,8 @@ dump_config(ServerOptions *o)
342 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
343 dump_cfg_string(sAuthorizedPrincipalsFile,
344 o->authorized_principals_file);
345 + dump_cfg_string(sAuthorizedKeysCommand, o->authorized_keys_command);
346 + dump_cfg_string(sAuthorizedKeysCommandRunAs, o->authorized_keys_command_runas);
347
348 /* string arguments requiring a lookup */
349 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
350 diff -up openssh-5.9p1/servconf.h.akc openssh-5.9p1/servconf.h
351 --- openssh-5.9p1/servconf.h.akc 2011-09-14 07:24:29.511480441 +0200
352 +++ openssh-5.9p1/servconf.h 2011-09-14 07:24:43.678459183 +0200
353 @@ -174,6 +174,8 @@ typedef struct {
354 char *revoked_keys_file;
355 char *trusted_user_ca_keys;
356 char *authorized_principals_file;
357 + char *authorized_keys_command;
358 + char *authorized_keys_command_runas;
359 } ServerOptions;
360
361 /*
362 diff -up openssh-5.9p1/sshd_config.0.akc openssh-5.9p1/sshd_config.0
363 --- openssh-5.9p1/sshd_config.0.akc 2011-09-07 01:16:30.000000000 +0200
364 +++ openssh-5.9p1/sshd_config.0 2011-09-14 07:24:43.791460201 +0200
365 @@ -71,6 +71,23 @@ DESCRIPTION
366
367 See PATTERNS in ssh_config(5) for more information on patterns.
368
369 + AuthorizedKeysCommand
370 +
371 + Specifies a program to be used for lookup of the user's
372 + public keys. The program will be invoked with its first
373 + argument the name of the user being authorized, and should produce
374 + on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS
375 + in sshd(8)). By default (or when set to the empty string) there is no
376 + AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully
377 + authorize the user, authorization falls through to the
378 + AuthorizedKeysFile. Note that this option has an effect
379 + only with PubkeyAuthentication turned on.
380 +
381 + AuthorizedKeysCommandRunAs
382 + Specifies the user under whose account the AuthorizedKeysCommand is run.
383 + Empty string (the default value) means the user being authorized
384 + is used.
385 +
386 AuthorizedKeysFile
387 Specifies the file that contains the public keys that can be used
388 for user authentication. The format is described in the
389 @@ -401,7 +418,8 @@ DESCRIPTION
390
391 Only a subset of keywords may be used on the lines following a
392 Match keyword. Available keywords are AllowAgentForwarding,
393 - AllowTcpForwarding, AuthorizedKeysFile, AuthorizedPrincipalsFile,
394 + AllowTcpForwarding, AuthorizedKeysFile, AuthorizedKeysCommand,
395 + AuthorizedKeysCommandRunAs, AuthorizedPrincipalsFile,
396 Banner, ChrootDirectory, ForceCommand, GatewayPorts,
397 GSSAPIAuthentication, HostbasedAuthentication,
398 HostbasedUsesNameFromPacketOnly, KbdInteractiveAuthentication,
399 diff -up openssh-5.9p1/sshd_config.5.akc openssh-5.9p1/sshd_config.5
400 --- openssh-5.9p1/sshd_config.5.akc 2011-09-14 07:24:29.793520372 +0200
401 +++ openssh-5.9p1/sshd_config.5 2011-09-14 07:24:43.912583678 +0200
402 @@ -706,6 +706,8 @@ Available keywords are
403 .Cm AllowAgentForwarding ,
404 .Cm AllowTcpForwarding ,
405 .Cm AuthorizedKeysFile ,
406 +.Cm AuthorizedKeysCommand ,
407 +.Cm AuthorizedKeysCommandRunAs ,
408 .Cm AuthorizedPrincipalsFile ,
409 .Cm Banner ,
410 .Cm ChrootDirectory ,
411 @@ -718,6 +720,7 @@ Available keywords are
412 .Cm KerberosAuthentication ,
413 .Cm MaxAuthTries ,
414 .Cm MaxSessions ,
415 +.Cm PubkeyAuthentication ,
416 .Cm PasswordAuthentication ,
417 .Cm PermitEmptyPasswords ,
418 .Cm PermitOpen ,
419 @@ -926,6 +929,20 @@ Specifies a list of revoked public keys.
420 Keys listed in this file will be refused for public key authentication.
421 Note that if this file is not readable, then public key authentication will
422 be refused for all users.
423 +.It Cm AuthorizedKeysCommand
424 +Specifies a program to be used for lookup of the user's
425 +public keys. The program will be invoked with its first
426 +argument the name of the user being authorized, and should produce
427 +on standard output AuthorizedKeys lines (see AUTHORIZED_KEYS
428 +in sshd(8)). By default (or when set to the empty string) there is no
429 +AuthorizedKeysCommand run. If the AuthorizedKeysCommand does not successfully
430 +authorize the user, authorization falls through to the
431 +AuthorizedKeysFile. Note that this option has an effect
432 +only with PubkeyAuthentication turned on.
433 +.It Cm AuthorizedKeysCommandRunAs
434 +Specifies the user under whose account the AuthorizedKeysCommand is run. Empty
435 +string (the default value) means the user being authorized is used.
436 +.Dq
437 .It Cm RhostsRSAAuthentication
438 Specifies whether rhosts or /etc/hosts.equiv authentication together
439 with successful RSA host authentication is allowed.
440 diff -up openssh-5.9p1/sshd_config.akc openssh-5.9p1/sshd_config
441 --- openssh-5.9p1/sshd_config.akc 2011-09-14 07:24:29.620461608 +0200
442 +++ openssh-5.9p1/sshd_config 2011-09-14 07:24:44.034462546 +0200
443 @@ -49,6 +49,9 @@
444 # but this is overridden so installations will only check .ssh/authorized_keys
445 AuthorizedKeysFile .ssh/authorized_keys
446
447 +#AuthorizedKeysCommand none
448 +#AuthorizedKeysCommandRunAs nobody
449 +
450 # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts
451 #RhostsRSAAuthentication no
452 # similar for protocol version 2