summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ChangeLog22
-rw-r--r--auth-options.c43
-rw-r--r--auth-options.h3
-rw-r--r--auth.c41
-rw-r--r--auth.h4
-rw-r--r--auth2-pubkey.c102
-rw-r--r--key.c4
-rw-r--r--servconf.c18
-rw-r--r--servconf.h3
-rw-r--r--sshd.815
-rw-r--r--sshd_config.541
11 files changed, 262 insertions, 34 deletions
diff --git a/ChangeLog b/ChangeLog
index 684609459..090e2352c 100644
--- a/ChangeLog
+++ b/ChangeLog
@@ -31,6 +31,28 @@
31 [sftp.c] 31 [sftp.c]
32 restore mput and mget which got lost in the tab-completion changes. 32 restore mput and mget which got lost in the tab-completion changes.
33 found by Kenneth Whitaker, ok djm@ 33 found by Kenneth Whitaker, ok djm@
34 - djm@cvs.openbsd.org 2010/05/07 11:30:30
35 [auth-options.c auth-options.h auth.c auth.h auth2-pubkey.c]
36 [key.c servconf.c servconf.h sshd.8 sshd_config.5]
37 add some optional indirection to matching of principal names listed
38 in certificates. Currently, a certificate must include the a user's name
39 to be accepted for authentication. This change adds the ability to
40 specify a list of certificate principal names that are acceptable.
41
42 When authenticating using a CA trusted through ~/.ssh/authorized_keys,
43 this adds a new principals="name1[,name2,...]" key option.
44
45 For CAs listed through sshd_config's TrustedCAKeys option, a new config
46 option "AuthorizedPrincipalsFile" specifies a per-user file containing
47 the list of acceptable names.
48
49 If either option is absent, the current behaviour of requiring the
50 username to appear in principals continues to apply.
51
52 These options are useful for role accounts, disjoint account namespaces
53 and "user@realm"-style naming policies in certificates.
54
55 feedback and ok markus@
34 56
3520100423 5720100423
36 - (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir 58 - (dtucker) [configure.ac] Bug #1756: Check for the existence of a lib64 dir
diff --git a/auth-options.c b/auth-options.c
index 60d5f749b..57a67ec79 100644
--- a/auth-options.c
+++ b/auth-options.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.c,v 1.50 2010/04/16 01:47:26 djm Exp $ */ 1/* $OpenBSD: auth-options.c,v 1.51 2010/05/07 11:30:29 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
@@ -55,6 +55,9 @@ struct envstring *custom_environment = NULL;
55/* "tunnel=" option. */ 55/* "tunnel=" option. */
56int forced_tun_device = -1; 56int forced_tun_device = -1;
57 57
58/* "principals=" option. */
59char *authorized_principals = NULL;
60
58extern ServerOptions options; 61extern ServerOptions options;
59 62
60void 63void
@@ -76,6 +79,10 @@ auth_clear_options(void)
76 xfree(forced_command); 79 xfree(forced_command);
77 forced_command = NULL; 80 forced_command = NULL;
78 } 81 }
82 if (authorized_principals) {
83 xfree(authorized_principals);
84 authorized_principals = NULL;
85 }
79 forced_tun_device = -1; 86 forced_tun_device = -1;
80 channel_clear_permitted_opens(); 87 channel_clear_permitted_opens();
81} 88}
@@ -141,6 +148,8 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
141 cp = "command=\""; 148 cp = "command=\"";
142 if (strncasecmp(opts, cp, strlen(cp)) == 0) { 149 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
143 opts += strlen(cp); 150 opts += strlen(cp);
151 if (forced_command != NULL)
152 xfree(forced_command);
144 forced_command = xmalloc(strlen(opts) + 1); 153 forced_command = xmalloc(strlen(opts) + 1);
145 i = 0; 154 i = 0;
146 while (*opts) { 155 while (*opts) {
@@ -167,6 +176,38 @@ auth_parse_options(struct passwd *pw, char *opts, char *file, u_long linenum)
167 opts++; 176 opts++;
168 goto next_option; 177 goto next_option;
169 } 178 }
179 cp = "principals=\"";
180 if (strncasecmp(opts, cp, strlen(cp)) == 0) {
181 opts += strlen(cp);
182 if (authorized_principals != NULL)
183 xfree(authorized_principals);
184 authorized_principals = xmalloc(strlen(opts) + 1);
185 i = 0;
186 while (*opts) {
187 if (*opts == '"')
188 break;
189 if (*opts == '\\' && opts[1] == '"') {
190 opts += 2;
191 authorized_principals[i++] = '"';
192 continue;
193 }
194 authorized_principals[i++] = *opts++;
195 }
196 if (!*opts) {
197 debug("%.100s, line %lu: missing end quote",
198 file, linenum);
199 auth_debug_add("%.100s, line %lu: missing end quote",
200 file, linenum);
201 xfree(authorized_principals);
202 authorized_principals = NULL;
203 goto bad_option;
204 }
205 authorized_principals[i] = '\0';
206 auth_debug_add("principals: %.900s",
207 authorized_principals);
208 opts++;
209 goto next_option;
210 }
170 cp = "environment=\""; 211 cp = "environment=\"";
171 if (options.permit_user_env && 212 if (options.permit_user_env &&
172 strncasecmp(opts, cp, strlen(cp)) == 0) { 213 strncasecmp(opts, cp, strlen(cp)) == 0) {
diff --git a/auth-options.h b/auth-options.h
index 20f0dbe3e..7455c9454 100644
--- a/auth-options.h
+++ b/auth-options.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth-options.h,v 1.19 2010/04/16 01:47:26 djm Exp $ */ 1/* $OpenBSD: auth-options.h,v 1.20 2010/05/07 11:30:29 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -31,6 +31,7 @@ extern char *forced_command;
31extern struct envstring *custom_environment; 31extern struct envstring *custom_environment;
32extern int forced_tun_device; 32extern int forced_tun_device;
33extern int key_is_cert_authority; 33extern int key_is_cert_authority;
34extern char *authorized_principals;
34 35
35int auth_parse_options(struct passwd *, char *, char *, u_long); 36int auth_parse_options(struct passwd *, char *, char *, u_long);
36void auth_clear_options(void); 37void auth_clear_options(void);
diff --git a/auth.c b/auth.c
index 89a936068..bec191a59 100644
--- a/auth.c
+++ b/auth.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.c,v 1.86 2010/03/05 02:58:11 djm Exp $ */ 1/* $OpenBSD: auth.c,v 1.87 2010/05/07 11:30:29 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -366,6 +366,14 @@ authorized_keys_file2(struct passwd *pw)
366 return expand_authorized_keys(options.authorized_keys_file2, pw); 366 return expand_authorized_keys(options.authorized_keys_file2, pw);
367} 367}
368 368
369char *
370authorized_principals_file(struct passwd *pw)
371{
372 if (options.authorized_principals_file == NULL)
373 return NULL;
374 return expand_authorized_keys(options.authorized_principals_file, pw);
375}
376
369/* return ok if key exists in sysfile or userfile */ 377/* return ok if key exists in sysfile or userfile */
370HostStatus 378HostStatus
371check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host, 379check_key_in_hostfiles(struct passwd *pw, Key *key, const char *host,
@@ -477,21 +485,18 @@ secure_filename(FILE *f, const char *file, struct passwd *pw,
477 return 0; 485 return 0;
478} 486}
479 487
480FILE * 488static FILE *
481auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes) 489auth_openfile(const char *file, struct passwd *pw, int strict_modes,
490 int log_missing, char *file_type)
482{ 491{
483 char line[1024]; 492 char line[1024];
484 struct stat st; 493 struct stat st;
485 int fd; 494 int fd;
486 FILE *f; 495 FILE *f;
487 496
488 /*
489 * Open the file containing the authorized keys
490 * Fail quietly if file does not exist
491 */
492 if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) { 497 if ((fd = open(file, O_RDONLY|O_NONBLOCK)) == -1) {
493 if (errno != ENOENT) 498 if (log_missing || errno != ENOENT)
494 debug("Could not open keyfile '%s': %s", file, 499 debug("Could not open %s '%s': %s", file_type, file,
495 strerror(errno)); 500 strerror(errno));
496 return NULL; 501 return NULL;
497 } 502 }
@@ -501,8 +506,8 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
501 return NULL; 506 return NULL;
502 } 507 }
503 if (!S_ISREG(st.st_mode)) { 508 if (!S_ISREG(st.st_mode)) {
504 logit("User %s authorized keys %s is not a regular file", 509 logit("User %s %s %s is not a regular file",
505 pw->pw_name, file); 510 pw->pw_name, file_type, file);
506 close(fd); 511 close(fd);
507 return NULL; 512 return NULL;
508 } 513 }
@@ -521,6 +526,20 @@ auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
521 return f; 526 return f;
522} 527}
523 528
529
530FILE *
531auth_openkeyfile(const char *file, struct passwd *pw, int strict_modes)
532{
533 return auth_openfile(file, pw, strict_modes, 1, "authorized keys");
534}
535
536FILE *
537auth_openprincipals(const char *file, struct passwd *pw, int strict_modes)
538{
539 return auth_openfile(file, pw, strict_modes, 0,
540 "authorized principals");
541}
542
524struct passwd * 543struct passwd *
525getpwnamallow(const char *user) 544getpwnamallow(const char *user)
526{ 545{
diff --git a/auth.h b/auth.h
index a65b87dd1..77317aee6 100644
--- a/auth.h
+++ b/auth.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth.h,v 1.65 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: auth.h,v 1.66 2010/05/07 11:30:29 djm Exp $ */
2 2
3/* 3/*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved. 4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
@@ -169,8 +169,10 @@ void abandon_challenge_response(Authctxt *);
169 169
170char *authorized_keys_file(struct passwd *); 170char *authorized_keys_file(struct passwd *);
171char *authorized_keys_file2(struct passwd *); 171char *authorized_keys_file2(struct passwd *);
172char *authorized_principals_file(struct passwd *);
172 173
173FILE *auth_openkeyfile(const char *, struct passwd *, int); 174FILE *auth_openkeyfile(const char *, struct passwd *, int);
175FILE *auth_openprincipals(const char *, struct passwd *, int);
174int auth_key_is_revoked(Key *); 176int auth_key_is_revoked(Key *);
175 177
176HostStatus 178HostStatus
diff --git a/auth2-pubkey.c b/auth2-pubkey.c
index 83ecd6590..6b4a99725 100644
--- a/auth2-pubkey.c
+++ b/auth2-pubkey.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: auth2-pubkey.c,v 1.23 2010/04/16 01:47:26 djm Exp $ */ 1/* $OpenBSD: auth2-pubkey.c,v 1.24 2010/05/07 11:30:29 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * 4 *
@@ -57,6 +57,7 @@
57#include "monitor_wrap.h" 57#include "monitor_wrap.h"
58#include "misc.h" 58#include "misc.h"
59#include "authfile.h" 59#include "authfile.h"
60#include "match.h"
60 61
61/* import */ 62/* import */
62extern ServerOptions options; 63extern ServerOptions options;
@@ -176,6 +177,63 @@ done:
176 return authenticated; 177 return authenticated;
177} 178}
178 179
180static int
181match_principals_option(const char *principal_list, struct KeyCert *cert)
182{
183 char *result;
184 u_int i;
185
186 /* XXX percent_expand() sequences for authorized_principals? */
187
188 for (i = 0; i < cert->nprincipals; i++) {
189 if ((result = match_list(cert->principals[i],
190 principal_list, NULL)) != NULL) {
191 debug3("matched principal from key options \"%.100s\"",
192 result);
193 xfree(result);
194 return 1;
195 }
196 }
197 return 0;
198}
199
200static int
201match_principals_file(const char *file, struct passwd *pw, struct KeyCert *cert)
202{
203 FILE *f;
204 char line[SSH_MAX_PUBKEY_BYTES], *cp;
205 u_long linenum = 0;
206 u_int i;
207
208 temporarily_use_uid(pw);
209 debug("trying authorized principals file %s", file);
210 if ((f = auth_openprincipals(file, pw, options.strict_modes)) == NULL) {
211 restore_uid();
212 return 0;
213 }
214 while (read_keyfile_line(f, file, line, sizeof(line), &linenum) != -1) {
215 /* Skip leading whitespace, empty and comment lines. */
216 for (cp = line; *cp == ' ' || *cp == '\t'; cp++)
217 ;
218 if (!*cp || *cp == '\n' || *cp == '#')
219 continue;
220 line[strcspn(line, "\n")] = '\0';
221
222 for (i = 0; i < cert->nprincipals; i++) {
223 if (strcmp(cp, cert->principals[i]) == 0) {
224 debug3("matched principal from file \"%.100s\"",
225 cert->principals[i]);
226 fclose(f);
227 restore_uid();
228 return 1;
229 }
230 }
231 }
232 fclose(f);
233 restore_uid();
234 return 0;
235}
236
179/* return 1 if user allows given key */ 237/* return 1 if user allows given key */
180static int 238static int
181user_key_allowed2(struct passwd *pw, Key *key, char *file) 239user_key_allowed2(struct passwd *pw, Key *key, char *file)
@@ -244,13 +302,26 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
244 SSH_FP_HEX); 302 SSH_FP_HEX);
245 debug("matching CA found: file %s, line %lu, %s %s", 303 debug("matching CA found: file %s, line %lu, %s %s",
246 file, linenum, key_type(found), fp); 304 file, linenum, key_type(found), fp);
247 if (key_cert_check_authority(key, 0, 0, pw->pw_name, 305 /*
248 &reason) != 0) { 306 * If the user has specified a list of principals as
307 * a key option, then prefer that list to matching
308 * their username in the certificate principals list.
309 */
310 if (authorized_principals != NULL &&
311 !match_principals_option(authorized_principals,
312 key->cert)) {
313 reason = "Certificate does not contain an "
314 "authorized principal";
315 fail_reason:
249 xfree(fp); 316 xfree(fp);
250 error("%s", reason); 317 error("%s", reason);
251 auth_debug_add("%s", reason); 318 auth_debug_add("%s", reason);
252 continue; 319 continue;
253 } 320 }
321 if (key_cert_check_authority(key, 0, 0,
322 authorized_principals == NULL ? pw->pw_name : NULL,
323 &reason) != 0)
324 goto fail_reason;
254 if (auth_cert_options(key, pw) != 0) { 325 if (auth_cert_options(key, pw) != 0) {
255 xfree(fp); 326 xfree(fp);
256 continue; 327 continue;
@@ -284,7 +355,7 @@ user_key_allowed2(struct passwd *pw, Key *key, char *file)
284static int 355static int
285user_cert_trusted_ca(struct passwd *pw, Key *key) 356user_cert_trusted_ca(struct passwd *pw, Key *key)
286{ 357{
287 char *ca_fp; 358 char *ca_fp, *principals_file = NULL;
288 const char *reason; 359 const char *reason;
289 int ret = 0; 360 int ret = 0;
290 361
@@ -301,11 +372,24 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
301 options.trusted_user_ca_keys); 372 options.trusted_user_ca_keys);
302 goto out; 373 goto out;
303 } 374 }
304 if (key_cert_check_authority(key, 0, 1, pw->pw_name, &reason) != 0) { 375 /*
305 error("%s", reason); 376 * If AuthorizedPrincipals is in use, then compare the certificate
306 auth_debug_add("%s", reason); 377 * principals against the names in that file rather than matching
307 goto out; 378 * against the username.
379 */
380 if ((principals_file = authorized_principals_file(pw)) != NULL) {
381 if (!match_principals_file(principals_file, pw, key->cert)) {
382 reason = "Certificate does not contain an "
383 "authorized principal";
384 fail_reason:
385 error("%s", reason);
386 auth_debug_add("%s", reason);
387 goto out;
388 }
308 } 389 }
390 if (key_cert_check_authority(key, 0, 1,
391 principals_file == NULL ? pw->pw_name : NULL, &reason) != 0)
392 goto fail_reason;
309 if (auth_cert_options(key, pw) != 0) 393 if (auth_cert_options(key, pw) != 0)
310 goto out; 394 goto out;
311 395
@@ -315,6 +399,8 @@ user_cert_trusted_ca(struct passwd *pw, Key *key)
315 ret = 1; 399 ret = 1;
316 400
317 out: 401 out:
402 if (principals_file != NULL)
403 xfree(principals_file);
318 if (ca_fp != NULL) 404 if (ca_fp != NULL)
319 xfree(ca_fp); 405 xfree(ca_fp);
320 return ret; 406 return ret;
diff --git a/key.c b/key.c
index 34f678b38..c4d9d5771 100644
--- a/key.c
+++ b/key.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: key.c,v 1.87 2010/04/16 01:47:26 djm Exp $ */ 1/* $OpenBSD: key.c,v 1.88 2010/05/07 11:30:29 djm Exp $ */
2/* 2/*
3 * read_bignum(): 3 * read_bignum():
4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland 4 * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland
@@ -1623,7 +1623,7 @@ key_cert_check_authority(const Key *k, int want_host, int require_principal,
1623 *reason = "Certificate lacks principal list"; 1623 *reason = "Certificate lacks principal list";
1624 return -1; 1624 return -1;
1625 } 1625 }
1626 } else { 1626 } else if (name != NULL) {
1627 principal_matches = 0; 1627 principal_matches = 0;
1628 for (i = 0; i < k->cert->nprincipals; i++) { 1628 for (i = 0; i < k->cert->nprincipals; i++) {
1629 if (strcmp(name, k->cert->principals[i]) == 0) { 1629 if (strcmp(name, k->cert->principals[i]) == 0) {
diff --git a/servconf.c b/servconf.c
index 7d027ddb9..c556986e3 100644
--- a/servconf.c
+++ b/servconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.c,v 1.207 2010/03/25 23:38:28 djm Exp $ */ 1/* $OpenBSD: servconf.c,v 1.208 2010/05/07 11:30:29 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
@@ -131,6 +131,7 @@ initialize_server_options(ServerOptions *options)
131 options->zero_knowledge_password_authentication = -1; 131 options->zero_knowledge_password_authentication = -1;
132 options->revoked_keys_file = NULL; 132 options->revoked_keys_file = NULL;
133 options->trusted_user_ca_keys = NULL; 133 options->trusted_user_ca_keys = NULL;
134 options->authorized_principals_file = NULL;
134} 135}
135 136
136void 137void
@@ -310,7 +311,7 @@ typedef enum {
310 sMatch, sPermitOpen, sForceCommand, sChrootDirectory, 311 sMatch, sPermitOpen, sForceCommand, sChrootDirectory,
311 sUsePrivilegeSeparation, sAllowAgentForwarding, 312 sUsePrivilegeSeparation, sAllowAgentForwarding,
312 sZeroKnowledgePasswordAuthentication, sHostCertificate, 313 sZeroKnowledgePasswordAuthentication, sHostCertificate,
313 sRevokedKeys, sTrustedUserCAKeys, 314 sRevokedKeys, sTrustedUserCAKeys, sAuthorizedPrincipalsFile,
314 sDeprecated, sUnsupported 315 sDeprecated, sUnsupported
315} ServerOpCodes; 316} ServerOpCodes;
316 317
@@ -432,6 +433,7 @@ static struct {
432 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL }, 433 { "hostcertificate", sHostCertificate, SSHCFG_GLOBAL },
433 { "revokedkeys", sRevokedKeys, SSHCFG_ALL }, 434 { "revokedkeys", sRevokedKeys, SSHCFG_ALL },
434 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL }, 435 { "trustedusercakeys", sTrustedUserCAKeys, SSHCFG_ALL },
436 { "authorizedprincipalsfile", sAuthorizedPrincipalsFile, SSHCFG_GLOBAL },
435 { NULL, sBadOption, 0 } 437 { NULL, sBadOption, 0 }
436}; 438};
437 439
@@ -1218,10 +1220,14 @@ process_server_config_line(ServerOptions *options, char *line,
1218 * AuthorizedKeysFile /etc/ssh_keys/%u 1220 * AuthorizedKeysFile /etc/ssh_keys/%u
1219 */ 1221 */
1220 case sAuthorizedKeysFile: 1222 case sAuthorizedKeysFile:
1223 charptr = &options->authorized_keys_file;
1224 goto parse_tilde_filename;
1221 case sAuthorizedKeysFile2: 1225 case sAuthorizedKeysFile2:
1222 charptr = (opcode == sAuthorizedKeysFile) ? 1226 charptr = &options->authorized_keys_file2;
1223 &options->authorized_keys_file : 1227 goto parse_tilde_filename;
1224 &options->authorized_keys_file2; 1228 case sAuthorizedPrincipalsFile:
1229 charptr = &options->authorized_principals_file;
1230 parse_tilde_filename:
1225 arg = strdelim(&cp); 1231 arg = strdelim(&cp);
1226 if (!arg || *arg == '\0') 1232 if (!arg || *arg == '\0')
1227 fatal("%s line %d: missing file name.", 1233 fatal("%s line %d: missing file name.",
@@ -1682,6 +1688,8 @@ dump_config(ServerOptions *o)
1682 dump_cfg_string(sChrootDirectory, o->chroot_directory); 1688 dump_cfg_string(sChrootDirectory, o->chroot_directory);
1683 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys); 1689 dump_cfg_string(sTrustedUserCAKeys, o->trusted_user_ca_keys);
1684 dump_cfg_string(sRevokedKeys, o->revoked_keys_file); 1690 dump_cfg_string(sRevokedKeys, o->revoked_keys_file);
1691 dump_cfg_string(sAuthorizedPrincipalsFile,
1692 o->authorized_principals_file);
1685 1693
1686 /* string arguments requiring a lookup */ 1694 /* string arguments requiring a lookup */
1687 dump_cfg_string(sLogLevel, log_level_name(o->log_level)); 1695 dump_cfg_string(sLogLevel, log_level_name(o->log_level));
diff --git a/servconf.h b/servconf.h
index 860009f9c..45d2a2ae3 100644
--- a/servconf.h
+++ b/servconf.h
@@ -1,4 +1,4 @@
1/* $OpenBSD: servconf.h,v 1.92 2010/03/04 10:36:03 djm Exp $ */ 1/* $OpenBSD: servconf.h,v 1.93 2010/05/07 11:30:30 djm Exp $ */
2 2
3/* 3/*
4 * Author: Tatu Ylonen <ylo@cs.hut.fi> 4 * Author: Tatu Ylonen <ylo@cs.hut.fi>
@@ -156,6 +156,7 @@ typedef struct {
156 char *chroot_directory; 156 char *chroot_directory;
157 char *revoked_keys_file; 157 char *revoked_keys_file;
158 char *trusted_user_ca_keys; 158 char *trusted_user_ca_keys;
159 char *authorized_principals_file;
159} ServerOptions; 160} ServerOptions;
160 161
161void initialize_server_options(ServerOptions *); 162void initialize_server_options(ServerOptions *);
diff --git a/sshd.8 b/sshd.8
index 5f1966005..6eb49238a 100644
--- a/sshd.8
+++ b/sshd.8
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd.8,v 1.255 2010/03/05 06:50:35 jmc Exp $ 37.\" $OpenBSD: sshd.8,v 1.256 2010/05/07 11:30:30 djm Exp $
38.Dd $Mdocdate: March 5 2010 $ 38.Dd $Mdocdate: May 7 2010 $
39.Dt SSHD 8 39.Dt SSHD 8
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -602,6 +602,17 @@ Multiple
602options may be applied separated by commas. 602options may be applied separated by commas.
603No pattern matching is performed on the specified hostnames, 603No pattern matching is performed on the specified hostnames,
604they must be literal domains or addresses. 604they must be literal domains or addresses.
605.It Cm principals="principals"
606On a
607.Cm cert-authority
608line, specifies allowed principals for certificate authentication as a
609comma-separated list.
610At least one name from the list must appear in the certificate's
611list of principals for the certificate to be accepted.
612This option is ignored for keys that are not marked as trusted certificate
613signers using the
614.Cm cert-authority
615option.
605.It Cm tunnel="n" 616.It Cm tunnel="n"
606Force a 617Force a
607.Xr tun 4 618.Xr tun 4
diff --git a/sshd_config.5 b/sshd_config.5
index 2f5410281..a5260d358 100644
--- a/sshd_config.5
+++ b/sshd_config.5
@@ -34,8 +34,8 @@
34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 34.\" (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 35.\" THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
36.\" 36.\"
37.\" $OpenBSD: sshd_config.5,v 1.120 2010/03/04 23:17:25 djm Exp $ 37.\" $OpenBSD: sshd_config.5,v 1.121 2010/05/07 11:30:30 djm Exp $
38.Dd $Mdocdate: March 4 2010 $ 38.Dd $Mdocdate: May 7 2010 $
39.Dt SSHD_CONFIG 5 39.Dt SSHD_CONFIG 5
40.Os 40.Os
41.Sh NAME 41.Sh NAME
@@ -167,6 +167,43 @@ is taken to be an absolute path or one relative to the user's home
167directory. 167directory.
168The default is 168The default is
169.Dq .ssh/authorized_keys . 169.Dq .ssh/authorized_keys .
170.It Cm AuthorizedPrincipalsFile
171Specifies a file that lists principal names that are accepted for
172certificate authentication.
173When using certificates signed by a key listed in
174.Cm TrustedUserCAKeys ,
175this file lists names, one of which must appear in the certificate for it
176to be accepted for authentication.
177Names are listed one per line; empty lines and comments starting with
178.Ql #
179are ignored.
180.Pp
181.Cm AuthorizedPrincipalsFile
182may contain tokens of the form %T which are substituted during connection
183setup.
184The following tokens are defined: %% is replaced by a literal '%',
185%h is replaced by the home directory of the user being authenticated, and
186%u is replaced by the username of that user.
187After expansion,
188.Cm AuthorizedPrincipalsFile
189is taken to be an absolute path or one relative to the user's home
190directory.
191.Pp
192The default is not to use a principals file - in this case, the username
193of the user must appear in a certificate's principals list for it to be
194accepted.
195Note that
196.Cm AuthorizedPrincipalsFile
197is only used when authentication proceeds using a CA listed in
198.Cm TrustedUserCAKeys
199and is not consulted for certification authorities trusted via
200.Pa ~/.ssh/authorized_keys ,
201though the
202.Cm principals=
203key option offers a similar facility (see
204.Xr sshd 8
205for details).
206.Pp
170.It Cm Banner 207.It Cm Banner
171The contents of the specified file are sent to the remote user before 208The contents of the specified file are sent to the remote user before
172authentication is allowed. 209authentication is allowed.