diff options
-rw-r--r-- | auth2-pubkey.c | 22 | ||||
-rw-r--r-- | monitor.c | 63 | ||||
-rw-r--r-- | servconf.c | 33 | ||||
-rw-r--r-- | servconf.h | 6 | ||||
-rw-r--r-- | sshd_config.5 | 27 |
5 files changed, 119 insertions, 32 deletions
diff --git a/auth2-pubkey.c b/auth2-pubkey.c index 2b6986709..0ef982a48 100644 --- a/auth2-pubkey.c +++ b/auth2-pubkey.c | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: auth2-pubkey.c,v 1.95 2019/11/25 00:51:37 djm Exp $ */ | 1 | /* $OpenBSD: auth2-pubkey.c,v 1.96 2019/11/25 00:52:46 djm Exp $ */ |
2 | /* | 2 | /* |
3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. | 3 | * Copyright (c) 2000 Markus Friedl. All rights reserved. |
4 | * | 4 | * |
@@ -68,6 +68,7 @@ | |||
68 | #include "ssherr.h" | 68 | #include "ssherr.h" |
69 | #include "channels.h" /* XXX for session.h */ | 69 | #include "channels.h" /* XXX for session.h */ |
70 | #include "session.h" /* XXX for child_set_env(); refactor? */ | 70 | #include "session.h" /* XXX for child_set_env(); refactor? */ |
71 | #include "sk-api.h" | ||
71 | 72 | ||
72 | /* import */ | 73 | /* import */ |
73 | extern ServerOptions options; | 74 | extern ServerOptions options; |
@@ -96,7 +97,7 @@ userauth_pubkey(struct ssh *ssh) | |||
96 | u_char *pkblob = NULL, *sig = NULL, have_sig; | 97 | u_char *pkblob = NULL, *sig = NULL, have_sig; |
97 | size_t blen, slen; | 98 | size_t blen, slen; |
98 | int r, pktype; | 99 | int r, pktype; |
99 | int authenticated = 0; | 100 | int req_presence = 0, authenticated = 0; |
100 | struct sshauthopt *authopts = NULL; | 101 | struct sshauthopt *authopts = NULL; |
101 | struct sshkey_sig_details *sig_details = NULL; | 102 | struct sshkey_sig_details *sig_details = NULL; |
102 | 103 | ||
@@ -217,10 +218,25 @@ userauth_pubkey(struct ssh *ssh) | |||
217 | ssh->compat, &sig_details)) == 0) { | 218 | ssh->compat, &sig_details)) == 0) { |
218 | authenticated = 1; | 219 | authenticated = 1; |
219 | } | 220 | } |
220 | if (sig_details != NULL) { | 221 | if (authenticated == 1 && sig_details != NULL) { |
222 | auth2_record_info(authctxt, "signature count = %u", | ||
223 | sig_details->sk_counter); | ||
221 | debug("%s: sk_counter = %u, sk_flags = 0x%02x", | 224 | debug("%s: sk_counter = %u, sk_flags = 0x%02x", |
222 | __func__, sig_details->sk_counter, | 225 | __func__, sig_details->sk_counter, |
223 | sig_details->sk_flags); | 226 | sig_details->sk_flags); |
227 | req_presence = (options.pubkey_auth_options & | ||
228 | PUBKEYAUTH_TOUCH_REQUIRED); | ||
229 | if (req_presence && (sig_details->sk_flags & | ||
230 | SSH_SK_USER_PRESENCE_REQD) == 0) { | ||
231 | error("public key %s signature for %s%s from " | ||
232 | "%.128s port %d rejected: user presence " | ||
233 | "(key touch) requirement not met ", key_s, | ||
234 | authctxt->valid ? "" : "invalid user ", | ||
235 | authctxt->user, ssh_remote_ipaddr(ssh), | ||
236 | ssh_remote_port(ssh)); | ||
237 | authenticated = 0; | ||
238 | goto done; | ||
239 | } | ||
224 | } | 240 | } |
225 | auth2_record_key(authctxt, authenticated, key); | 241 | auth2_record_key(authctxt, authenticated, key); |
226 | } else { | 242 | } else { |
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: monitor.c,v 1.202 2019/11/25 00:51:37 djm Exp $ */ | 1 | /* $OpenBSD: monitor.c,v 1.203 2019/11/25 00:52:46 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> |
@@ -95,6 +95,7 @@ | |||
95 | #include "authfd.h" | 95 | #include "authfd.h" |
96 | #include "match.h" | 96 | #include "match.h" |
97 | #include "ssherr.h" | 97 | #include "ssherr.h" |
98 | #include "sk-api.h" | ||
98 | 99 | ||
99 | #ifdef GSSAPI | 100 | #ifdef GSSAPI |
100 | static Gssctxt *gsscontext = NULL; | 101 | static Gssctxt *gsscontext = NULL; |
@@ -542,7 +543,7 @@ monitor_read(struct ssh *ssh, struct monitor *pmonitor, struct mon_table *ent, | |||
542 | 543 | ||
543 | /* allowed key state */ | 544 | /* allowed key state */ |
544 | static int | 545 | static int |
545 | monitor_allowed_key(u_char *blob, u_int bloblen) | 546 | monitor_allowed_key(const u_char *blob, u_int bloblen) |
546 | { | 547 | { |
547 | /* make sure key is allowed */ | 548 | /* make sure key is allowed */ |
548 | if (key_blob == NULL || key_bloblen != bloblen || | 549 | if (key_blob == NULL || key_bloblen != bloblen || |
@@ -1247,7 +1248,7 @@ mm_answer_keyallowed(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1247 | } | 1248 | } |
1248 | 1249 | ||
1249 | static int | 1250 | static int |
1250 | monitor_valid_userblob(u_char *data, u_int datalen) | 1251 | monitor_valid_userblob(const u_char *data, u_int datalen) |
1251 | { | 1252 | { |
1252 | struct sshbuf *b; | 1253 | struct sshbuf *b; |
1253 | const u_char *p; | 1254 | const u_char *p; |
@@ -1256,10 +1257,8 @@ monitor_valid_userblob(u_char *data, u_int datalen) | |||
1256 | u_char type; | 1257 | u_char type; |
1257 | int r, fail = 0; | 1258 | int r, fail = 0; |
1258 | 1259 | ||
1259 | if ((b = sshbuf_new()) == NULL) | 1260 | if ((b = sshbuf_from(data, datalen)) == NULL) |
1260 | fatal("%s: sshbuf_new", __func__); | 1261 | fatal("%s: sshbuf_from", __func__); |
1261 | if ((r = sshbuf_put(b, data, datalen)) != 0) | ||
1262 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | ||
1263 | 1262 | ||
1264 | if (datafellows & SSH_OLD_SESSIONID) { | 1263 | if (datafellows & SSH_OLD_SESSIONID) { |
1265 | p = sshbuf_ptr(b); | 1264 | p = sshbuf_ptr(b); |
@@ -1314,8 +1313,8 @@ monitor_valid_userblob(u_char *data, u_int datalen) | |||
1314 | } | 1313 | } |
1315 | 1314 | ||
1316 | static int | 1315 | static int |
1317 | monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | 1316 | monitor_valid_hostbasedblob(const u_char *data, u_int datalen, |
1318 | char *chost) | 1317 | const char *cuser, const char *chost) |
1319 | { | 1318 | { |
1320 | struct sshbuf *b; | 1319 | struct sshbuf *b; |
1321 | const u_char *p; | 1320 | const u_char *p; |
@@ -1324,10 +1323,9 @@ monitor_valid_hostbasedblob(u_char *data, u_int datalen, char *cuser, | |||
1324 | int r, fail = 0; | 1323 | int r, fail = 0; |
1325 | u_char type; | 1324 | u_char type; |
1326 | 1325 | ||
1327 | if ((b = sshbuf_new()) == NULL) | 1326 | if ((b = sshbuf_from(data, datalen)) == NULL) |
1328 | fatal("%s: sshbuf_new", __func__); | 1327 | fatal("%s: sshbuf_new", __func__); |
1329 | if ((r = sshbuf_put(b, data, datalen)) != 0 || | 1328 | if ((r = sshbuf_get_string_direct(b, &p, &len)) != 0) |
1330 | (r = sshbuf_get_string_direct(b, &p, &len)) != 0) | ||
1331 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1329 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1332 | 1330 | ||
1333 | if ((session_id2 == NULL) || | 1331 | if ((session_id2 == NULL) || |
@@ -1387,15 +1385,15 @@ int | |||
1387 | mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | 1385 | mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) |
1388 | { | 1386 | { |
1389 | struct sshkey *key; | 1387 | struct sshkey *key; |
1390 | u_char *signature, *data, *blob; | 1388 | const u_char *signature, *data, *blob; |
1391 | char *sigalg; | 1389 | char *sigalg = NULL, *fp = NULL; |
1392 | size_t signaturelen, datalen, bloblen; | 1390 | size_t signaturelen, datalen, bloblen; |
1393 | int r, ret, valid_data = 0, encoded_ret; | 1391 | int r, ret, req_presence = 0, valid_data = 0, encoded_ret; |
1394 | struct sshkey_sig_details *sig_details = NULL; | 1392 | struct sshkey_sig_details *sig_details = NULL; |
1395 | 1393 | ||
1396 | if ((r = sshbuf_get_string(m, &blob, &bloblen)) != 0 || | 1394 | if ((r = sshbuf_get_string_direct(m, &blob, &bloblen)) != 0 || |
1397 | (r = sshbuf_get_string(m, &signature, &signaturelen)) != 0 || | 1395 | (r = sshbuf_get_string_direct(m, &signature, &signaturelen)) != 0 || |
1398 | (r = sshbuf_get_string(m, &data, &datalen)) != 0 || | 1396 | (r = sshbuf_get_string_direct(m, &data, &datalen)) != 0 || |
1399 | (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) | 1397 | (r = sshbuf_get_cstring(m, &sigalg, NULL)) != 0) |
1400 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); | 1398 | fatal("%s: buffer error: %s", __func__, ssh_err(r)); |
1401 | 1399 | ||
@@ -1430,23 +1428,36 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1430 | if (!valid_data) | 1428 | if (!valid_data) |
1431 | fatal("%s: bad signature data blob", __func__); | 1429 | fatal("%s: bad signature data blob", __func__); |
1432 | 1430 | ||
1431 | if ((fp = sshkey_fingerprint(key, options.fingerprint_hash, | ||
1432 | SSH_FP_DEFAULT)) == NULL) | ||
1433 | fatal("%s: sshkey_fingerprint failed", __func__); | ||
1434 | |||
1433 | ret = sshkey_verify(key, signature, signaturelen, data, datalen, | 1435 | ret = sshkey_verify(key, signature, signaturelen, data, datalen, |
1434 | sigalg, ssh->compat, &sig_details); | 1436 | sigalg, ssh->compat, &sig_details); |
1435 | debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, | 1437 | debug3("%s: %s %p signature %s%s%s", __func__, auth_method, key, |
1436 | (ret == 0) ? "verified" : "unverified", | 1438 | (ret == 0) ? "verified" : "unverified", |
1437 | (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); | 1439 | (ret != 0) ? ": " : "", (ret != 0) ? ssh_err(ret) : ""); |
1438 | auth2_record_key(authctxt, ret == 0, key); | ||
1439 | 1440 | ||
1440 | free(blob); | 1441 | if (ret == 0 && key_blobtype == MM_USERKEY && sig_details != NULL) { |
1441 | free(signature); | 1442 | req_presence = (options.pubkey_auth_options & |
1442 | free(data); | 1443 | PUBKEYAUTH_TOUCH_REQUIRED); |
1443 | free(sigalg); | 1444 | if (req_presence && |
1445 | (sig_details->sk_flags & SSH_SK_USER_PRESENCE_REQD) == 0) { | ||
1446 | error("public key %s %s signature for %s%s from %.128s " | ||
1447 | "port %d rejected: user presence (key touch) " | ||
1448 | "requirement not met ", sshkey_type(key), fp, | ||
1449 | authctxt->valid ? "" : "invalid user ", | ||
1450 | authctxt->user, ssh_remote_ipaddr(ssh), | ||
1451 | ssh_remote_port(ssh)); | ||
1452 | ret = SSH_ERR_SIGNATURE_INVALID; | ||
1453 | } | ||
1454 | } | ||
1455 | auth2_record_key(authctxt, ret == 0, key); | ||
1444 | 1456 | ||
1445 | if (key_blobtype == MM_USERKEY) | 1457 | if (key_blobtype == MM_USERKEY) |
1446 | auth_activate_options(ssh, key_opts); | 1458 | auth_activate_options(ssh, key_opts); |
1447 | monitor_reset_key_state(); | 1459 | monitor_reset_key_state(); |
1448 | 1460 | ||
1449 | sshkey_free(key); | ||
1450 | sshbuf_reset(m); | 1461 | sshbuf_reset(m); |
1451 | 1462 | ||
1452 | /* encode ret != 0 as positive integer, since we're sending u32 */ | 1463 | /* encode ret != 0 as positive integer, since we're sending u32 */ |
@@ -1462,6 +1473,10 @@ mm_answer_keyverify(struct ssh *ssh, int sock, struct sshbuf *m) | |||
1462 | sshkey_sig_details_free(sig_details); | 1473 | sshkey_sig_details_free(sig_details); |
1463 | mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); | 1474 | mm_request_send(sock, MONITOR_ANS_KEYVERIFY, m); |
1464 | 1475 | ||
1476 | free(sigalg); | ||
1477 | free(fp); | ||
1478 | sshkey_free(key); | ||
1479 | |||
1465 | return ret == 0; | 1480 | return ret == 0; |
1466 | } | 1481 | } |
1467 | 1482 | ||
diff --git a/servconf.c b/servconf.c index e2f44d38d..1f3beab4a 100644 --- a/servconf.c +++ b/servconf.c | |||
@@ -1,5 +1,5 @@ | |||
1 | 1 | ||
2 | /* $OpenBSD: servconf.c,v 1.353 2019/10/31 21:17:49 djm Exp $ */ | 2 | /* $OpenBSD: servconf.c,v 1.354 2019/11/25 00:52:46 djm Exp $ */ |
3 | /* | 3 | /* |
4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland | 4 | * Copyright (c) 1995 Tatu Ylonen <ylo@cs.hut.fi>, Espoo, Finland |
5 | * All rights reserved | 5 | * All rights reserved |
@@ -118,6 +118,7 @@ initialize_server_options(ServerOptions *options) | |||
118 | options->hostbased_key_types = NULL; | 118 | options->hostbased_key_types = NULL; |
119 | options->hostkeyalgorithms = NULL; | 119 | options->hostkeyalgorithms = NULL; |
120 | options->pubkey_authentication = -1; | 120 | options->pubkey_authentication = -1; |
121 | options->pubkey_auth_options = -1; | ||
121 | options->pubkey_key_types = NULL; | 122 | options->pubkey_key_types = NULL; |
122 | options->kerberos_authentication = -1; | 123 | options->kerberos_authentication = -1; |
123 | options->kerberos_or_local_passwd = -1; | 124 | options->kerberos_or_local_passwd = -1; |
@@ -341,6 +342,8 @@ fill_default_server_options(ServerOptions *options) | |||
341 | options->hostbased_uses_name_from_packet_only = 0; | 342 | options->hostbased_uses_name_from_packet_only = 0; |
342 | if (options->pubkey_authentication == -1) | 343 | if (options->pubkey_authentication == -1) |
343 | options->pubkey_authentication = 1; | 344 | options->pubkey_authentication = 1; |
345 | if (options->pubkey_auth_options == -1) | ||
346 | options->pubkey_auth_options = 0; | ||
344 | if (options->kerberos_authentication == -1) | 347 | if (options->kerberos_authentication == -1) |
345 | options->kerberos_authentication = 0; | 348 | options->kerberos_authentication = 0; |
346 | if (options->kerberos_or_local_passwd == -1) | 349 | if (options->kerberos_or_local_passwd == -1) |
@@ -509,7 +512,7 @@ typedef enum { | |||
509 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, | 512 | sAuthenticationMethods, sHostKeyAgent, sPermitUserRC, |
510 | sStreamLocalBindMask, sStreamLocalBindUnlink, | 513 | sStreamLocalBindMask, sStreamLocalBindUnlink, |
511 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, | 514 | sAllowStreamLocalForwarding, sFingerprintHash, sDisableForwarding, |
512 | sExposeAuthInfo, sRDomain, | 515 | sExposeAuthInfo, sRDomain, sPubkeyAuthOptions, |
513 | sDeprecated, sIgnore, sUnsupported | 516 | sDeprecated, sIgnore, sUnsupported |
514 | } ServerOpCodes; | 517 | } ServerOpCodes; |
515 | 518 | ||
@@ -551,6 +554,7 @@ static struct { | |||
551 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, | 554 | { "rsaauthentication", sDeprecated, SSHCFG_ALL }, |
552 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, | 555 | { "pubkeyauthentication", sPubkeyAuthentication, SSHCFG_ALL }, |
553 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, | 556 | { "pubkeyacceptedkeytypes", sPubkeyAcceptedKeyTypes, SSHCFG_ALL }, |
557 | { "pubkeyauthoptions", sPubkeyAuthOptions, SSHCFG_ALL }, | ||
554 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ | 558 | { "dsaauthentication", sPubkeyAuthentication, SSHCFG_GLOBAL }, /* alias */ |
555 | #ifdef KRB5 | 559 | #ifdef KRB5 |
556 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, | 560 | { "kerberosauthentication", sKerberosAuthentication, SSHCFG_ALL }, |
@@ -1468,6 +1472,24 @@ process_server_config_line(ServerOptions *options, char *line, | |||
1468 | charptr = &options->pubkey_key_types; | 1472 | charptr = &options->pubkey_key_types; |
1469 | goto parse_keytypes; | 1473 | goto parse_keytypes; |
1470 | 1474 | ||
1475 | case sPubkeyAuthOptions: | ||
1476 | intptr = &options->pubkey_auth_options; | ||
1477 | value = 0; | ||
1478 | while ((arg = strdelim(&cp)) && *arg != '\0') { | ||
1479 | if (strcasecmp(arg, "none") == 0) | ||
1480 | continue; | ||
1481 | if (strcasecmp(arg, "touch-required") == 0) | ||
1482 | value |= PUBKEYAUTH_TOUCH_REQUIRED; | ||
1483 | else { | ||
1484 | fatal("%s line %d: unsupported " | ||
1485 | "PubkeyAuthOptions option %s", | ||
1486 | filename, linenum, arg); | ||
1487 | } | ||
1488 | } | ||
1489 | if (*activep && *intptr == -1) | ||
1490 | *intptr = value; | ||
1491 | break; | ||
1492 | |||
1471 | case sKerberosAuthentication: | 1493 | case sKerberosAuthentication: |
1472 | intptr = &options->kerberos_authentication; | 1494 | intptr = &options->kerberos_authentication; |
1473 | goto parse_flag; | 1495 | goto parse_flag; |
@@ -2290,6 +2312,7 @@ copy_set_server_options(ServerOptions *dst, ServerOptions *src, int preauth) | |||
2290 | M_CP_INTOPT(password_authentication); | 2312 | M_CP_INTOPT(password_authentication); |
2291 | M_CP_INTOPT(gss_authentication); | 2313 | M_CP_INTOPT(gss_authentication); |
2292 | M_CP_INTOPT(pubkey_authentication); | 2314 | M_CP_INTOPT(pubkey_authentication); |
2315 | M_CP_INTOPT(pubkey_auth_options); | ||
2293 | M_CP_INTOPT(kerberos_authentication); | 2316 | M_CP_INTOPT(kerberos_authentication); |
2294 | M_CP_INTOPT(hostbased_authentication); | 2317 | M_CP_INTOPT(hostbased_authentication); |
2295 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); | 2318 | M_CP_INTOPT(hostbased_uses_name_from_packet_only); |
@@ -2711,4 +2734,10 @@ dump_config(ServerOptions *o) | |||
2711 | o->permit_user_env_whitelist); | 2734 | o->permit_user_env_whitelist); |
2712 | } | 2735 | } |
2713 | 2736 | ||
2737 | printf("pubkeyauthoptions"); | ||
2738 | if (o->pubkey_auth_options == 0) | ||
2739 | printf(" none"); | ||
2740 | if (o->pubkey_auth_options & PUBKEYAUTH_TOUCH_REQUIRED) | ||
2741 | printf(" touch-required"); | ||
2742 | printf("\n"); | ||
2714 | } | 2743 | } |
diff --git a/servconf.h b/servconf.h index 5483da051..9f202260a 100644 --- a/servconf.h +++ b/servconf.h | |||
@@ -1,4 +1,4 @@ | |||
1 | /* $OpenBSD: servconf.h,v 1.140 2019/04/18 18:56:16 dtucker Exp $ */ | 1 | /* $OpenBSD: servconf.h,v 1.141 2019/11/25 00:52:46 djm Exp $ */ |
2 | 2 | ||
3 | /* | 3 | /* |
4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> | 4 | * Author: Tatu Ylonen <ylo@cs.hut.fi> |
@@ -42,6 +42,9 @@ | |||
42 | /* Magic name for internal sftp-server */ | 42 | /* Magic name for internal sftp-server */ |
43 | #define INTERNAL_SFTP_NAME "internal-sftp" | 43 | #define INTERNAL_SFTP_NAME "internal-sftp" |
44 | 44 | ||
45 | /* PubkeyAuthOptions flags */ | ||
46 | #define PUBKEYAUTH_TOUCH_REQUIRED 1 | ||
47 | |||
45 | struct ssh; | 48 | struct ssh; |
46 | struct fwd_perm_list; | 49 | struct fwd_perm_list; |
47 | 50 | ||
@@ -114,6 +117,7 @@ typedef struct { | |||
114 | char *ca_sign_algorithms; /* Allowed CA signature algorithms */ | 117 | char *ca_sign_algorithms; /* Allowed CA signature algorithms */ |
115 | int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ | 118 | int pubkey_authentication; /* If true, permit ssh2 pubkey authentication. */ |
116 | char *pubkey_key_types; /* Key types allowed for public key */ | 119 | char *pubkey_key_types; /* Key types allowed for public key */ |
120 | int pubkey_auth_options; /* -1 or mask of PUBKEYAUTH_* flags */ | ||
117 | int kerberos_authentication; /* If true, permit Kerberos | 121 | int kerberos_authentication; /* If true, permit Kerberos |
118 | * authentication. */ | 122 | * authentication. */ |
119 | int kerberos_or_local_passwd; /* If true, permit kerberos | 123 | int kerberos_or_local_passwd; /* If true, permit kerberos |
diff --git a/sshd_config.5 b/sshd_config.5 index 5052ca200..60077e394 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.292 2019/11/18 04:55:02 djm Exp $ | 36 | .\" $OpenBSD: sshd_config.5,v 1.293 2019/11/25 00:52:46 djm Exp $ |
37 | .Dd $Mdocdate: November 18 2019 $ | 37 | .Dd $Mdocdate: November 25 2019 $ |
38 | .Dt SSHD_CONFIG 5 | 38 | .Dt SSHD_CONFIG 5 |
39 | .Os | 39 | .Os |
40 | .Sh NAME | 40 | .Sh NAME |
@@ -1444,6 +1444,29 @@ ssh-ed25519,rsa-sha2-512,rsa-sha2-256,ssh-rsa | |||
1444 | .Pp | 1444 | .Pp |
1445 | The list of available key types may also be obtained using | 1445 | The list of available key types may also be obtained using |
1446 | .Qq ssh -Q key . | 1446 | .Qq ssh -Q key . |
1447 | .It Cm PubkeyAuthOptions | ||
1448 | Sets one or more public key authentication options. | ||
1449 | Two option keywords are currently supported: | ||
1450 | .Cm none (the default; indicating no additional options are enabled) | ||
1451 | and | ||
1452 | .Cm touch-required . | ||
1453 | .Pp | ||
1454 | The | ||
1455 | .Cm touch-required | ||
1456 | option causes public key authentication using a security key algorithm | ||
1457 | (i.e. | ||
1458 | .Cm ecdsa-sk | ||
1459 | or | ||
1460 | .Cm ed25519-sk ) | ||
1461 | to always require the signature to attest that a physically present user | ||
1462 | explicitly confirmed the authentication (usually by touching the security key). | ||
1463 | By default, | ||
1464 | .Xr sshd 8 | ||
1465 | requires key touch unless overridden with an authorized_keys option. | ||
1466 | The | ||
1467 | .Cm touch-required | ||
1468 | flag disables this override. | ||
1469 | This option has no effect for other, non-security key public key types. | ||
1447 | .It Cm PubkeyAuthentication | 1470 | .It Cm PubkeyAuthentication |
1448 | Specifies whether public key authentication is allowed. | 1471 | Specifies whether public key authentication is allowed. |
1449 | The default is | 1472 | The default is |