diff options
-rw-r--r-- | ChangeLog | 13 | ||||
-rw-r--r-- | auth-rsa.c | 70 | ||||
-rw-r--r-- | auth.c | 10 | ||||
-rw-r--r-- | auth.h | 4 | ||||
-rw-r--r-- | auth2-pubkey.c | 13 | ||||
-rw-r--r-- | monitor.c | 9 | ||||
-rw-r--r-- | monitor_wrap.c | 9 | ||||
-rw-r--r-- | pathnames.h | 5 | ||||
-rw-r--r-- | servconf.c | 54 | ||||
-rw-r--r-- | servconf.h | 8 | ||||
-rw-r--r-- | sshd.8 | 12 | ||||
-rw-r--r-- | sshd_config | 7 | ||||
-rw-r--r-- | sshd_config.5 | 11 |
13 files changed, 151 insertions, 74 deletions
@@ -1,3 +1,16 @@ | |||
1 | 20110529 | ||
2 | - (djm) OpenBSD CVS Sync | ||
3 | - djm@cvs.openbsd.org 2011/05/23 03:30:07 | ||
4 | [auth-rsa.c auth.c auth.h auth2-pubkey.c monitor.c monitor_wrap.c] | ||
5 | [pathnames.h servconf.c servconf.h sshd.8 sshd_config sshd_config.5] | ||
6 | allow AuthorizedKeysFile to specify multiple files, separated by spaces. | ||
7 | Bring back authorized_keys2 as a default search path (to avoid breaking | ||
8 | existing users of this file), but override this in sshd_config so it will | ||
9 | be no longer used on fresh installs. Maybe in 2015 we can remove it | ||
10 | entierly :) | ||
11 | |||
12 | feedback and ok markus@ dtucker@ | ||
13 | |||
1 | 20110520 | 14 | 20110520 |
2 | - (djm) [session.c] call setexeccon() before executing passwd for pw | 15 | - (djm) [session.c] call setexeccon() before executing passwd for pw |
3 | changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@ | 16 | changes; bz#1891 reported by jchadima AT redhat.com; ok dtucker@ |
diff --git a/auth-rsa.c b/auth-rsa.c index 4edaab056..4ab46cd51 100644 --- a/auth-rsa.c +++ b/auth-rsa.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth-rsa.c,v 1.79 2010/12/03 23:55:27 djm Exp $ */ | 1 | /* $OpenBSD: auth-rsa.c,v 1.80 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 3 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
@@ -160,44 +160,27 @@ auth_rsa_challenge_dialog(Key *key) | |||
160 | return (success); | 160 | return (success); |
161 | } | 161 | } |
162 | 162 | ||
163 | /* | 163 | static int |
164 | * check if there's user key matching client_n, | 164 | rsa_key_allowed_in_file(struct passwd *pw, char *file, |
165 | * return key if login is allowed, NULL otherwise | 165 | const BIGNUM *client_n, Key **rkey) |
166 | */ | ||
167 | |||
168 | int | ||
169 | auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | ||
170 | { | 166 | { |
171 | char line[SSH_MAX_PUBKEY_BYTES], *file; | 167 | char line[SSH_MAX_PUBKEY_BYTES]; |
172 | int allowed = 0; | 168 | int allowed = 0; |
173 | u_int bits; | 169 | u_int bits; |
174 | FILE *f; | 170 | FILE *f; |
175 | u_long linenum = 0; | 171 | u_long linenum = 0; |
176 | Key *key; | 172 | Key *key; |
177 | 173 | ||
178 | /* Temporarily use the user's uid. */ | ||
179 | temporarily_use_uid(pw); | ||
180 | |||
181 | /* The authorized keys. */ | ||
182 | file = authorized_keys_file(pw); | ||
183 | debug("trying public RSA key file %s", file); | 174 | debug("trying public RSA key file %s", file); |
184 | f = auth_openkeyfile(file, pw, options.strict_modes); | 175 | if ((f = auth_openkeyfile(file, pw, options.strict_modes)) == NULL) |
185 | if (!f) { | 176 | return 0; |
186 | xfree(file); | ||
187 | restore_uid(); | ||
188 | return (0); | ||
189 | } | ||
190 | |||
191 | /* Flag indicating whether the key is allowed. */ | ||
192 | allowed = 0; | ||
193 | |||
194 | key = key_new(KEY_RSA1); | ||
195 | 177 | ||
196 | /* | 178 | /* |
197 | * Go though the accepted keys, looking for the current key. If | 179 | * Go though the accepted keys, looking for the current key. If |
198 | * found, perform a challenge-response dialog to verify that the | 180 | * found, perform a challenge-response dialog to verify that the |
199 | * user really has the corresponding private key. | 181 | * user really has the corresponding private key. |
200 | */ | 182 | */ |
183 | key = key_new(KEY_RSA1); | ||
201 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { | 184 | while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) { |
202 | char *cp; | 185 | char *cp; |
203 | char *key_options; | 186 | char *key_options; |
@@ -235,7 +218,10 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | |||
235 | } | 218 | } |
236 | /* cp now points to the comment part. */ | 219 | /* cp now points to the comment part. */ |
237 | 220 | ||
238 | /* Check if the we have found the desired key (identified by its modulus). */ | 221 | /* |
222 | * Check if the we have found the desired key (identified | ||
223 | * by its modulus). | ||
224 | */ | ||
239 | if (BN_cmp(key->rsa->n, client_n) != 0) | 225 | if (BN_cmp(key->rsa->n, client_n) != 0) |
240 | continue; | 226 | continue; |
241 | 227 | ||
@@ -264,11 +250,7 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | |||
264 | break; | 250 | break; |
265 | } | 251 | } |
266 | 252 | ||
267 | /* Restore the privileged uid. */ | ||
268 | restore_uid(); | ||
269 | |||
270 | /* Close the file. */ | 253 | /* Close the file. */ |
271 | xfree(file); | ||
272 | fclose(f); | 254 | fclose(f); |
273 | 255 | ||
274 | /* return key if allowed */ | 256 | /* return key if allowed */ |
@@ -276,7 +258,33 @@ auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | |||
276 | *rkey = key; | 258 | *rkey = key; |
277 | else | 259 | else |
278 | key_free(key); | 260 | key_free(key); |
279 | return (allowed); | 261 | |
262 | return allowed; | ||
263 | } | ||
264 | |||
265 | /* | ||
266 | * check if there's user key matching client_n, | ||
267 | * return key if login is allowed, NULL otherwise | ||
268 | */ | ||
269 | |||
270 | int | ||
271 | auth_rsa_key_allowed(struct passwd *pw, BIGNUM *client_n, Key **rkey) | ||
272 | { | ||
273 | char *file; | ||
274 | u_int i, allowed = 0; | ||
275 | |||
276 | temporarily_use_uid(pw); | ||
277 | |||
278 | for (i = 0; !allowed && i < options.num_authkeys_files; i++) { | ||
279 | file = expand_authorized_keys( | ||
280 | options.authorized_keys_files[i], pw); | ||
281 | allowed = rsa_key_allowed_in_file(pw, file, client_n, rkey); | ||
282 | xfree(file); | ||
283 | } | ||
284 | |||
285 | restore_uid(); | ||
286 | |||
287 | return allowed; | ||
280 | } | 288 | } |
281 | 289 | ||
282 | /* | 290 | /* |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.c,v 1.92 2011/05/11 04:47:06 djm Exp $ */ | 1 | /* $OpenBSD: auth.c,v 1.93 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -331,7 +331,7 @@ auth_root_allowed(char *method) | |||
331 | * | 331 | * |
332 | * This returns a buffer allocated by xmalloc. | 332 | * This returns a buffer allocated by xmalloc. |
333 | */ | 333 | */ |
334 | static char * | 334 | char * |
335 | expand_authorized_keys(const char *filename, struct passwd *pw) | 335 | expand_authorized_keys(const char *filename, struct passwd *pw) |
336 | { | 336 | { |
337 | char *file, ret[MAXPATHLEN]; | 337 | char *file, ret[MAXPATHLEN]; |
@@ -355,12 +355,6 @@ expand_authorized_keys(const char *filename, struct passwd *pw) | |||
355 | } | 355 | } |
356 | 356 | ||
357 | char * | 357 | char * |
358 | authorized_keys_file(struct passwd *pw) | ||
359 | { | ||
360 | return expand_authorized_keys(options.authorized_keys_file, pw); | ||
361 | } | ||
362 | |||
363 | char * | ||
364 | authorized_principals_file(struct passwd *pw) | 358 | authorized_principals_file(struct passwd *pw) |
365 | { | 359 | { |
366 | if (options.authorized_principals_file == NULL) | 360 | if (options.authorized_principals_file == NULL) |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth.h,v 1.68 2011/05/11 04:47:06 djm Exp $ */ | 1 | /* $OpenBSD: auth.h,v 1.69 2011/05/23 03:30:07 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 4 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
@@ -168,7 +168,7 @@ char *get_challenge(Authctxt *); | |||
168 | int verify_response(Authctxt *, const char *); | 168 | int verify_response(Authctxt *, const char *); |
169 | void abandon_challenge_response(Authctxt *); | 169 | void abandon_challenge_response(Authctxt *); |
170 | 170 | ||
171 | char *authorized_keys_file(struct passwd *); | 171 | char *expand_authorized_keys(const char *, struct passwd *pw); |
172 | char *authorized_principals_file(struct passwd *); | 172 | char *authorized_principals_file(struct passwd *); |
173 | 173 | ||
174 | FILE *auth_openkeyfile(const char *, struct passwd *, int); | 174 | FILE *auth_openkeyfile(const char *, struct passwd *, int); |
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index a97509c28..137887ecd 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.28 2011/05/11 04:47:06 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.29 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -436,7 +436,7 @@ user_cert_trusted_ca(struct passwd *pw, Key *key) | |||
436 | int | 436 | int |
437 | user_key_allowed(struct passwd *pw, Key *key) | 437 | user_key_allowed(struct passwd *pw, Key *key) |
438 | { | 438 | { |
439 | int success; | 439 | u_int success, i; |
440 | char *file; | 440 | char *file; |
441 | 441 | ||
442 | if (auth_key_is_revoked(key)) | 442 | if (auth_key_is_revoked(key)) |
@@ -448,9 +448,12 @@ user_key_allowed(struct passwd *pw, Key *key) | |||
448 | if (success) | 448 | if (success) |
449 | return success; | 449 | return success; |
450 | 450 | ||
451 | file = authorized_keys_file(pw); | 451 | for (i = 0; !success && i < options.num_authkeys_files; i++) { |
452 | success = user_key_allowed2(pw, key, file); | 452 | file = expand_authorized_keys( |
453 | xfree(file); | 453 | options.authorized_keys_files[i], pw); |
454 | success = user_key_allowed2(pw, key, file); | ||
455 | xfree(file); | ||
456 | } | ||
454 | 457 | ||
455 | return success; | 458 | return success; |
456 | } | 459 | } |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.112 2011/05/20 03:25:45 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.113 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -632,6 +632,7 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
632 | char *username; | 632 | char *username; |
633 | struct passwd *pwent; | 633 | struct passwd *pwent; |
634 | int allowed = 0; | 634 | int allowed = 0; |
635 | u_int i; | ||
635 | 636 | ||
636 | debug3("%s", __func__); | 637 | debug3("%s", __func__); |
637 | 638 | ||
@@ -676,9 +677,14 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
676 | if (options.x != NULL) \ | 677 | if (options.x != NULL) \ |
677 | buffer_put_cstring(m, options.x); \ | 678 | buffer_put_cstring(m, options.x); \ |
678 | } while (0) | 679 | } while (0) |
680 | #define M_CP_STRARRAYOPT(x, nx) do { \ | ||
681 | for (i = 0; i < options.nx; i++) \ | ||
682 | buffer_put_cstring(m, options.x[i]); \ | ||
683 | } while (0) | ||
679 | /* See comment in servconf.h */ | 684 | /* See comment in servconf.h */ |
680 | COPY_MATCH_STRING_OPTS(); | 685 | COPY_MATCH_STRING_OPTS(); |
681 | #undef M_CP_STROPT | 686 | #undef M_CP_STROPT |
687 | #undef M_CP_STRARRAYOPT | ||
682 | 688 | ||
683 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); | 689 | debug3("%s: sending MONITOR_ANS_PWNAM: %d", __func__, allowed); |
684 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); | 690 | mm_request_send(sock, MONITOR_ANS_PWNAM, m); |
@@ -691,7 +697,6 @@ mm_answer_pwnamallow(int sock, Buffer *m) | |||
691 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); | 697 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTHSERV, 1); |
692 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); | 698 | monitor_permit(mon_dispatch, MONITOR_REQ_AUTH2_READ_BANNER, 1); |
693 | } | 699 | } |
694 | |||
695 | #ifdef USE_PAM | 700 | #ifdef USE_PAM |
696 | if (options.use_pam) | 701 | if (options.use_pam) |
697 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); | 702 | monitor_permit(mon_dispatch, MONITOR_REQ_PAM_START, 1); |
diff --git a/monitor_wrap.c b/monitor_wrap.c index d3f274021..7a90b3ba3 100644 --- a/monitor_wrap.c +++ b/monitor_wrap.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor_wrap.c,v 1.71 2011/05/20 03:25:45 djm Exp $ */ | 1 | /* $OpenBSD: monitor_wrap.c,v 1.72 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> | 3 | * Copyright 2002 Niels Provos <provos@citi.umich.edu> |
4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> | 4 | * Copyright 2002 Markus Friedl <markus@openbsd.org> |
@@ -211,7 +211,7 @@ mm_getpwnamallow(const char *username) | |||
211 | { | 211 | { |
212 | Buffer m; | 212 | Buffer m; |
213 | struct passwd *pw; | 213 | struct passwd *pw; |
214 | u_int len; | 214 | u_int len, i; |
215 | ServerOptions *newopts; | 215 | ServerOptions *newopts; |
216 | 216 | ||
217 | debug3("%s entering", __func__); | 217 | debug3("%s entering", __func__); |
@@ -250,9 +250,14 @@ out: | |||
250 | if (newopts->x != NULL) \ | 250 | if (newopts->x != NULL) \ |
251 | newopts->x = buffer_get_string(&m, NULL); \ | 251 | newopts->x = buffer_get_string(&m, NULL); \ |
252 | } while (0) | 252 | } while (0) |
253 | #define M_CP_STRARRAYOPT(x, nx) do { \ | ||
254 | for (i = 0; i < newopts->nx; i++) \ | ||
255 | newopts->x[i] = buffer_get_string(&m, NULL); \ | ||
256 | } while (0) | ||
253 | /* See comment in servconf.h */ | 257 | /* See comment in servconf.h */ |
254 | COPY_MATCH_STRING_OPTS(); | 258 | COPY_MATCH_STRING_OPTS(); |
255 | #undef M_CP_STROPT | 259 | #undef M_CP_STROPT |
260 | #undef M_CP_STRARRAYOPT | ||
256 | 261 | ||
257 | copy_set_server_options(&options, newopts, 1); | 262 | copy_set_server_options(&options, newopts, 1); |
258 | xfree(newopts); | 263 | xfree(newopts); |
diff --git a/pathnames.h b/pathnames.h index 787bdb676..c3d9abff5 100644 --- a/pathnames.h +++ b/pathnames.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: pathnames.h,v 1.21 2011/05/11 04:47:06 djm Exp $ */ | 1 | /* $OpenBSD: pathnames.h,v 1.22 2011/05/23 03:30:07 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -96,6 +96,9 @@ | |||
96 | */ | 96 | */ |
97 | #define _PATH_SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" | 97 | #define _PATH_SSH_USER_PERMITTED_KEYS ".ssh/authorized_keys" |
98 | 98 | ||
99 | /* backward compat for protocol v2 */ | ||
100 | #define _PATH_SSH_USER_PERMITTED_KEYS2 ".ssh/authorized_keys2" | ||
101 | |||
99 | /* | 102 | /* |
100 | * Per-user and system-wide ssh "rc" files. These files are executed with | 103 | * Per-user and system-wide ssh "rc" files. These files are executed with |
101 | * /bin/sh before starting the shell or command if they exist. They will be | 104 | * /bin/sh before starting the shell or command if they exist. They will be |
diff --git a/servconf.c b/servconf.c index daed26a66..74710c41f 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.c,v 1.218 2011/05/20 03:25:45 djm Exp $ */ | 1 | /* $OpenBSD: servconf.c,v 1.219 2011/05/23 03:30:07 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 3 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
4 | * All rights reserved | 4 | * All rights reserved |
@@ -126,7 +126,7 @@ initialize_server_options(ServerOptions *options) | |||
126 | options->use_dns = -1; | 126 | options->use_dns = -1; |
127 | options->client_alive_interval = -1; | 127 | options->client_alive_interval = -1; |
128 | options->client_alive_count_max = -1; | 128 | options->client_alive_count_max = -1; |
129 | options->authorized_keys_file = NULL; | 129 | options->num_authkeys_files = 0; |
130 | options->num_accept_env = 0; | 130 | options->num_accept_env = 0; |
131 | options->permit_tun = -1; | 131 | options->permit_tun = -1; |
132 | options->num_permitted_opens = -1; | 132 | options->num_permitted_opens = -1; |
@@ -263,8 +263,12 @@ fill_default_server_options(ServerOptions *options) | |||
263 | options->client_alive_interval = 0; | 263 | options->client_alive_interval = 0; |
264 | if (options->client_alive_count_max == -1) | 264 | if (options->client_alive_count_max == -1) |
265 | options->client_alive_count_max = 3; | 265 | options->client_alive_count_max = 3; |
266 | if (options->authorized_keys_file == NULL) | 266 | if (options->num_authkeys_files == 0) { |
267 | options->authorized_keys_file = xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); | 267 | options->authorized_keys_files[options->num_authkeys_files++] = |
268 | xstrdup(_PATH_SSH_USER_PERMITTED_KEYS); | ||
269 | options->authorized_keys_files[options->num_authkeys_files++] = | ||
270 | xstrdup(_PATH_SSH_USER_PERMITTED_KEYS2); | ||
271 | } | ||
268 | if (options->permit_tun == -1) | 272 | if (options->permit_tun == -1) |
269 | options->permit_tun = SSH_TUNMODE_NO; | 273 | options->permit_tun = SSH_TUNMODE_NO; |
270 | if (options->zero_knowledge_password_authentication == -1) | 274 | if (options->zero_knowledge_password_authentication == -1) |
@@ -430,6 +434,7 @@ static struct { | |||
430 | { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, | 434 | { "clientaliveinterval", sClientAliveInterval, SSHCFG_GLOBAL }, |
431 | { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, | 435 | { "clientalivecountmax", sClientAliveCountMax, SSHCFG_GLOBAL }, |
432 | { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, | 436 | { "authorizedkeysfile", sAuthorizedKeysFile, SSHCFG_ALL }, |
437 | { "authorizedkeysfile2", sDeprecated, SSHCFG_ALL }, | ||
433 | { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, | 438 | { "useprivilegeseparation", sUsePrivilegeSeparation, SSHCFG_GLOBAL}, |
434 | { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, | 439 | { "acceptenv", sAcceptEnv, SSHCFG_GLOBAL }, |
435 | { "permittunnel", sPermitTunnel, SSHCFG_ALL }, | 440 | { "permittunnel", sPermitTunnel, SSHCFG_ALL }, |
@@ -1241,11 +1246,22 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1241 | * AuthorizedKeysFile /etc/ssh_keys/%u | 1246 | * AuthorizedKeysFile /etc/ssh_keys/%u |
1242 | */ | 1247 | */ |
1243 | case sAuthorizedKeysFile: | 1248 | case sAuthorizedKeysFile: |
1244 | charptr = &options->authorized_keys_file; | 1249 | if (*activep && options->num_authkeys_files == 0) { |
1245 | goto parse_tilde_filename; | 1250 | while ((arg = strdelim(&cp)) && *arg != '\0') { |
1251 | if (options->num_authkeys_files >= | ||
1252 | MAX_AUTHKEYS_FILES) | ||
1253 | fatal("%s line %d: " | ||
1254 | "too many authorized keys files.", | ||
1255 | filename, linenum); | ||
1256 | options->authorized_keys_files[ | ||
1257 | options->num_authkeys_files++] = | ||
1258 | tilde_expand_filename(arg, getuid()); | ||
1259 | } | ||
1260 | } | ||
1261 | return 0; | ||
1262 | |||
1246 | case sAuthorizedPrincipalsFile: | 1263 | case sAuthorizedPrincipalsFile: |
1247 | charptr = &options->authorized_principals_file; | 1264 | charptr = &options->authorized_principals_file; |
1248 | parse_tilde_filename: | ||
1249 | arg = strdelim(&cp); | 1265 | arg = strdelim(&cp); |
1250 | if (!arg || *arg == '\0') | 1266 | if (!arg || *arg == '\0') |
1251 | fatal("%s line %d: missing file name.", | 1267 | fatal("%s line %d: missing file name.", |
@@ -1464,6 +1480,12 @@ parse_server_match_config(ServerOptions *options, const char *user, | |||
1464 | dst->n = src->n; \ | 1480 | dst->n = src->n; \ |
1465 | } \ | 1481 | } \ |
1466 | } while(0) | 1482 | } while(0) |
1483 | #define M_CP_STRARRAYOPT(n, num_n) do {\ | ||
1484 | if (src->num_n != 0) { \ | ||
1485 | for (dst->num_n = 0; dst->num_n < src->num_n; dst->num_n++) \ | ||
1486 | dst->n[dst->num_n] = xstrdup(src->n[dst->num_n]); \ | ||
1487 | } \ | ||
1488 | } while(0) | ||
1467 | 1489 | ||
1468 | /* | 1490 | /* |
1469 | * Copy any supported values that are set. | 1491 | * Copy any supported values that are set. |
@@ -1508,12 +1530,14 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
1508 | */ | 1530 | */ |
1509 | if (preauth) | 1531 | if (preauth) |
1510 | return; | 1532 | return; |
1533 | |||
1511 | M_CP_STROPT(adm_forced_command); | 1534 | M_CP_STROPT(adm_forced_command); |
1512 | M_CP_STROPT(chroot_directory); | 1535 | M_CP_STROPT(chroot_directory); |
1513 | } | 1536 | } |
1514 | 1537 | ||
1515 | #undef M_CP_INTOPT | 1538 | #undef M_CP_INTOPT |
1516 | #undef M_CP_STROPT | 1539 | #undef M_CP_STROPT |
1540 | #undef M_CP_STRARRAYOPT | ||
1517 | 1541 | ||
1518 | void | 1542 | void |
1519 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, | 1543 | parse_server_config(ServerOptions *options, const char *filename, Buffer *conf, |
@@ -1627,7 +1651,18 @@ dump_cfg_strarray(ServerOpCodes code, u_int count, char **vals) | |||
1627 | u_int i; | 1651 | u_int i; |
1628 | 1652 | ||
1629 | for (i = 0; i < count; i++) | 1653 | for (i = 0; i < count; i++) |
1630 | printf("%s %s\n", lookup_opcode_name(code), vals[i]); | 1654 | printf("%s %s\n", lookup_opcode_name(code), vals[i]); |
1655 | } | ||
1656 | |||
1657 | static void | ||
1658 | dump_cfg_strarray_oneline(ServerOpCodes code, u_int count, char **vals) | ||
1659 | { | ||
1660 | u_int i; | ||
1661 | |||
1662 | printf("%s", lookup_opcode_name(code)); | ||
1663 | for (i = 0; i < count; i++) | ||
1664 | printf(" %s", vals[i]); | ||
1665 | printf("\n"); | ||
1631 | } | 1666 | } |
1632 | 1667 | ||
1633 | void | 1668 | void |
@@ -1725,7 +1760,6 @@ dump_config(ServerOptions *o) | |||
1725 | dump_cfg_string(sCiphers, o->ciphers); | 1760 | dump_cfg_string(sCiphers, o->ciphers); |
1726 | dump_cfg_string(sMacs, o->macs); | 1761 | dump_cfg_string(sMacs, o->macs); |
1727 | dump_cfg_string(sBanner, o->banner); | 1762 | dump_cfg_string(sBanner, o->banner); |
1728 | dump_cfg_string(sAuthorizedKeysFile, o->authorized_keys_file); | ||
1729 | dump_cfg_string(sForceCommand, o->adm_forced_command); | 1763 | dump_cfg_string(sForceCommand, o->adm_forced_command); |
1730 | dump_cfg_string(sChrootDirectory, o->chroot_directory); | 1764 | dump_cfg_string(sChrootDirectory, o->chroot_directory); |
1731 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); | 1765 | dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); |
@@ -1738,6 +1772,8 @@ dump_config(ServerOptions *o) | |||
1738 | dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); | 1772 | dump_cfg_string(sLogFacility, log_facility_name(o->log_facility)); |
1739 | 1773 | ||
1740 | /* string array arguments */ | 1774 | /* string array arguments */ |
1775 | dump_cfg_strarray_oneline(sAuthorizedKeysFile, o->num_authkeys_files, | ||
1776 | o->authorized_keys_files); | ||
1741 | dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, | 1777 | dump_cfg_strarray(sHostKeyFile, o->num_host_key_files, |
1742 | o->host_key_files); | 1778 | o->host_key_files); |
1743 | dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, | 1779 | dump_cfg_strarray(sHostKeyFile, o->num_host_cert_files, |
diff --git a/servconf.h b/servconf.h index 953ef8650..31e621bde 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.97 2011/05/20 03:25:45 djm Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.98 2011/05/23 03:30:07 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -27,6 +27,7 @@ | |||
27 | #define MAX_HOSTCERTS 256 /* Max # host certificates. */ | 27 | #define MAX_HOSTCERTS 256 /* Max # host certificates. */ |
28 | #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ | 28 | #define MAX_ACCEPT_ENV 256 /* Max # of env vars. */ |
29 | #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ | 29 | #define MAX_MATCH_GROUPS 256 /* Max # of groups for Match. */ |
30 | #define MAX_AUTHKEYS_FILES 256 /* Max # of authorized_keys files. */ | ||
30 | 31 | ||
31 | /* permit_root_login */ | 32 | /* permit_root_login */ |
32 | #define PERMIT_NOT_SET -1 | 33 | #define PERMIT_NOT_SET -1 |
@@ -145,7 +146,8 @@ typedef struct { | |||
145 | * disconnect the session | 146 | * disconnect the session |
146 | */ | 147 | */ |
147 | 148 | ||
148 | char *authorized_keys_file; /* File containing public keys */ | 149 | u_int num_authkeys_files; /* Files containing public keys */ |
150 | char *authorized_keys_files[MAX_AUTHKEYS_FILES]; | ||
149 | 151 | ||
150 | char *adm_forced_command; | 152 | char *adm_forced_command; |
151 | 153 | ||
@@ -171,8 +173,8 @@ typedef struct { | |||
171 | M_CP_STROPT(banner); \ | 173 | M_CP_STROPT(banner); \ |
172 | M_CP_STROPT(trusted_user_ca_keys); \ | 174 | M_CP_STROPT(trusted_user_ca_keys); \ |
173 | M_CP_STROPT(revoked_keys_file); \ | 175 | M_CP_STROPT(revoked_keys_file); \ |
174 | M_CP_STROPT(authorized_keys_file); \ | ||
175 | M_CP_STROPT(authorized_principals_file); \ | 176 | M_CP_STROPT(authorized_principals_file); \ |
177 | M_CP_STRARRAYOPT(authorized_keys_files, num_authkeys_files); \ | ||
176 | } while (0) | 178 | } while (0) |
177 | 179 | ||
178 | void initialize_server_options(ServerOptions *); | 180 | void initialize_server_options(ServerOptions *); |
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd.8,v 1.260 2010/10/28 18:33:28 jmc Exp $ | 36 | .\" $OpenBSD: sshd.8,v 1.261 2011/05/23 03:30:07 djm Exp $ |
37 | .Dd $Mdocdate: October 28 2010 $ | 37 | .Dd $Mdocdate: May 23 2011 $ |
38 | .Dt SSHD 8 | 38 | .Dt SSHD 8 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -462,10 +462,12 @@ is run, and if that | |||
462 | does not exist either, xauth is used to add the cookie. | 462 | does not exist either, xauth is used to add the cookie. |
463 | .Sh AUTHORIZED_KEYS FILE FORMAT | 463 | .Sh AUTHORIZED_KEYS FILE FORMAT |
464 | .Cm AuthorizedKeysFile | 464 | .Cm AuthorizedKeysFile |
465 | specifies the file containing public keys for | 465 | specifies the file or files containing public keys for |
466 | public key authentication; | 466 | public key authentication; |
467 | if none is specified, the default is | 467 | if none is specified, the default is both |
468 | .Pa ~/.ssh/authorized_keys . | 468 | .Pa ~/.ssh/authorized_keys |
469 | and | ||
470 | .Pa ~/.ssh/authorized_keys2 . | ||
469 | Each line of the file contains one | 471 | Each line of the file contains one |
470 | key (empty lines and lines starting with a | 472 | key (empty lines and lines starting with a |
471 | .Ql # | 473 | .Ql # |
diff --git a/sshd_config b/sshd_config index 9b0d9fa20..473e86654 100644 --- a/sshd_config +++ b/sshd_config | |||
@@ -1,4 +1,4 @@ | |||
1 | # $OpenBSD: sshd_config,v 1.83 2011/05/06 01:03:35 dtucker Exp $ | 1 | # $OpenBSD: sshd_config,v 1.84 2011/05/23 03:30:07 djm Exp $ |
2 | 2 | ||
3 | # This is the sshd server system-wide configuration file. See | 3 | # This is the sshd server system-wide configuration file. See |
4 | # sshd_config(5) for more information. | 4 | # sshd_config(5) for more information. |
@@ -44,7 +44,10 @@ | |||
44 | 44 | ||
45 | #RSAAuthentication yes | 45 | #RSAAuthentication yes |
46 | #PubkeyAuthentication yes | 46 | #PubkeyAuthentication yes |
47 | #AuthorizedKeysFile .ssh/authorized_keys | 47 | |
48 | # The default is to check both .ssh/authorized_keys and .ssh/authorized_keys2 | ||
49 | # but this is overridden so installations will only check .ssh/authorized_keys | ||
50 | AuthorizedKeysFile .ssh/authorized_keys | ||
48 | 51 | ||
49 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts | 52 | # For this to work you will also need host keys in /etc/ssh/ssh_known_hosts |
50 | #RhostsRSAAuthentication no | 53 | #RhostsRSAAuthentication no |
diff --git a/sshd_config.5 b/sshd_config.5 index c3d6df30a..b23e0f789 100644 --- a/sshd_config.5 +++ b/sshd_config.5 | |||
@@ -33,8 +33,8 @@ | |||
33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF | 33 | .\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF |
34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. | 34 | .\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. |
35 | .\" | 35 | .\" |
36 | .\" $OpenBSD: sshd_config.5,v 1.131 2010/12/08 04:02:47 djm Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.132 2011/05/23 03:30:07 djm Exp $ |
37 | .Dd $Mdocdate: December 8 2010 $ | 37 | .Dd $Mdocdate: May 23 2011 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -168,8 +168,11 @@ After expansion, | |||
168 | .Cm AuthorizedKeysFile | 168 | .Cm AuthorizedKeysFile |
169 | is taken to be an absolute path or one relative to the user's home | 169 | is taken to be an absolute path or one relative to the user's home |
170 | directory. | 170 | directory. |
171 | The default is | 171 | The default is both |
172 | .Dq .ssh/authorized_keys . | 172 | .Dq .ssh/authorized_keys |
173 | and | ||
174 | .Dq .ssh/authorized_keys2 . | ||
175 | Multiple files may be listed separated by whitespace. | ||
173 | .It Cm AuthorizedPrincipalsFile | 176 | .It Cm AuthorizedPrincipalsFile |
174 | Specifies a file that lists principal names that are accepted for | 177 | Specifies a file that lists principal names that are accepted for |
175 | certificate authentication. | 178 | certificate authentication. |