summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c110
1 files changed, 82 insertions, 28 deletions
diff --git a/readconf.c b/readconf.c
index ee46ad623..dc22360d1 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.239 2015/07/30 00:01:34 djm Exp $ */ 1/* $OpenBSD: readconf.c,v 1.250 2016/02/08 23:40:12 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
@@ -137,6 +137,7 @@ typedef enum {
137 oPasswordAuthentication, oRSAAuthentication, 137 oPasswordAuthentication, oRSAAuthentication,
138 oChallengeResponseAuthentication, oXAuthLocation, 138 oChallengeResponseAuthentication, oXAuthLocation,
139 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward, 139 oIdentityFile, oHostName, oPort, oCipher, oRemoteForward, oLocalForward,
140 oCertificateFile, oAddKeysToAgent,
140 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand, 141 oUser, oEscapeChar, oRhostsRSAAuthentication, oProxyCommand,
141 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts, 142 oGlobalKnownHostsFile, oUserKnownHostsFile, oConnectionAttempts,
142 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression, 143 oBatchMode, oCheckHostIP, oStrictHostKeyChecking, oCompression,
@@ -155,7 +156,7 @@ typedef enum {
155 oSendEnv, oControlPath, oControlMaster, oControlPersist, 156 oSendEnv, oControlPath, oControlMaster, oControlPersist,
156 oHashKnownHosts, 157 oHashKnownHosts,
157 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand, 158 oTunnel, oTunnelDevice, oLocalCommand, oPermitLocalCommand,
158 oVisualHostKey, oUseRoaming, 159 oVisualHostKey,
159 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass, 160 oKexAlgorithms, oIPQoS, oRequestTTY, oIgnoreUnknown, oProxyUseFdpass,
160 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots, 161 oCanonicalDomains, oCanonicalizeHostname, oCanonicalizeMaxDots,
161 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs, 162 oCanonicalizeFallbackLocal, oCanonicalizePermittedCNAMEs,
@@ -217,6 +218,8 @@ static struct {
217 { "identityfile", oIdentityFile }, 218 { "identityfile", oIdentityFile },
218 { "identityfile2", oIdentityFile }, /* obsolete */ 219 { "identityfile2", oIdentityFile }, /* obsolete */
219 { "identitiesonly", oIdentitiesOnly }, 220 { "identitiesonly", oIdentitiesOnly },
221 { "certificatefile", oCertificateFile },
222 { "addkeystoagent", oAddKeysToAgent },
220 { "hostname", oHostName }, 223 { "hostname", oHostName },
221 { "hostkeyalias", oHostKeyAlias }, 224 { "hostkeyalias", oHostKeyAlias },
222 { "proxycommand", oProxyCommand }, 225 { "proxycommand", oProxyCommand },
@@ -275,7 +278,7 @@ static struct {
275 { "localcommand", oLocalCommand }, 278 { "localcommand", oLocalCommand },
276 { "permitlocalcommand", oPermitLocalCommand }, 279 { "permitlocalcommand", oPermitLocalCommand },
277 { "visualhostkey", oVisualHostKey }, 280 { "visualhostkey", oVisualHostKey },
278 { "useroaming", oUseRoaming }, 281 { "useroaming", oDeprecated },
279 { "kexalgorithms", oKexAlgorithms }, 282 { "kexalgorithms", oKexAlgorithms },
280 { "ipqos", oIPQoS }, 283 { "ipqos", oIPQoS },
281 { "requesttty", oRequestTTY }, 284 { "requesttty", oRequestTTY },
@@ -383,6 +386,30 @@ clear_forwardings(Options *options)
383} 386}
384 387
385void 388void
389add_certificate_file(Options *options, const char *path, int userprovided)
390{
391 int i;
392
393 if (options->num_certificate_files >= SSH_MAX_CERTIFICATE_FILES)
394 fatal("Too many certificate files specified (max %d)",
395 SSH_MAX_CERTIFICATE_FILES);
396
397 /* Avoid registering duplicates */
398 for (i = 0; i < options->num_certificate_files; i++) {
399 if (options->certificate_file_userprovided[i] == userprovided &&
400 strcmp(options->certificate_files[i], path) == 0) {
401 debug2("%s: ignoring duplicate key %s", __func__, path);
402 return;
403 }
404 }
405
406 options->certificate_file_userprovided[options->num_certificate_files] =
407 userprovided;
408 options->certificate_files[options->num_certificate_files++] =
409 xstrdup(path);
410}
411
412void
386add_identity_file(Options *options, const char *dir, const char *filename, 413add_identity_file(Options *options, const char *dir, const char *filename,
387 int userprovided) 414 int userprovided)
388{ 415{
@@ -433,7 +460,7 @@ default_ssh_port(void)
433static int 460static int
434execute_in_shell(const char *cmd) 461execute_in_shell(const char *cmd)
435{ 462{
436 char *shell, *command_string; 463 char *shell;
437 pid_t pid; 464 pid_t pid;
438 int devnull, status; 465 int devnull, status;
439 extern uid_t original_real_uid; 466 extern uid_t original_real_uid;
@@ -441,12 +468,6 @@ execute_in_shell(const char *cmd)
441 if ((shell = getenv("SHELL")) == NULL) 468 if ((shell = getenv("SHELL")) == NULL)
442 shell = _PATH_BSHELL; 469 shell = _PATH_BSHELL;
443 470
444 /*
445 * Use "exec" to avoid "sh -c" processes on some platforms
446 * (e.g. Solaris)
447 */
448 xasprintf(&command_string, "exec %s", cmd);
449
450 /* Need this to redirect subprocess stdin/out */ 471 /* Need this to redirect subprocess stdin/out */
451 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) 472 if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1)
452 fatal("open(/dev/null): %s", strerror(errno)); 473 fatal("open(/dev/null): %s", strerror(errno));
@@ -471,7 +492,7 @@ execute_in_shell(const char *cmd)
471 492
472 argv[0] = shell; 493 argv[0] = shell;
473 argv[1] = "-c"; 494 argv[1] = "-c";
474 argv[2] = command_string; 495 argv[2] = xstrdup(cmd);
475 argv[3] = NULL; 496 argv[3] = NULL;
476 497
477 execv(argv[0], argv); 498 execv(argv[0], argv);
@@ -486,7 +507,6 @@ execute_in_shell(const char *cmd)
486 fatal("%s: fork: %.100s", __func__, strerror(errno)); 507 fatal("%s: fork: %.100s", __func__, strerror(errno));
487 508
488 close(devnull); 509 close(devnull);
489 free(command_string);
490 510
491 while (waitpid(pid, &status, 0) == -1) { 511 while (waitpid(pid, &status, 0) == -1) {
492 if (errno != EINTR && errno != EAGAIN) 512 if (errno != EINTR && errno != EAGAIN)
@@ -519,12 +539,15 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
519 */ 539 */
520 port = options->port <= 0 ? default_ssh_port() : options->port; 540 port = options->port <= 0 ? default_ssh_port() : options->port;
521 ruser = options->user == NULL ? pw->pw_name : options->user; 541 ruser = options->user == NULL ? pw->pw_name : options->user;
522 if (options->hostname != NULL) { 542 if (post_canon) {
543 host = xstrdup(options->hostname);
544 } else if (options->hostname != NULL) {
523 /* NB. Please keep in sync with ssh.c:main() */ 545 /* NB. Please keep in sync with ssh.c:main() */
524 host = percent_expand(options->hostname, 546 host = percent_expand(options->hostname,
525 "h", host_arg, (char *)NULL); 547 "h", host_arg, (char *)NULL);
526 } else 548 } else {
527 host = xstrdup(host_arg); 549 host = xstrdup(host_arg);
550 }
528 551
529 debug2("checking match for '%s' host %s originally %s", 552 debug2("checking match for '%s' host %s originally %s",
530 cp, host, original_host); 553 cp, host, original_host);
@@ -710,6 +733,15 @@ static const struct multistate multistate_yesnoask[] = {
710 { "ask", 2 }, 733 { "ask", 2 },
711 { NULL, -1 } 734 { NULL, -1 }
712}; 735};
736static const struct multistate multistate_yesnoaskconfirm[] = {
737 { "true", 1 },
738 { "false", 0 },
739 { "yes", 1 },
740 { "no", 0 },
741 { "ask", 2 },
742 { "confirm", 3 },
743 { NULL, -1 }
744};
713static const struct multistate multistate_addressfamily[] = { 745static const struct multistate multistate_addressfamily[] = {
714 { "inet", AF_INET }, 746 { "inet", AF_INET },
715 { "inet6", AF_INET6 }, 747 { "inet6", AF_INET6 },
@@ -984,16 +1016,12 @@ parse_time:
984 if (scan_scaled(arg, &val64) == -1) 1016 if (scan_scaled(arg, &val64) == -1)
985 fatal("%.200s line %d: Bad number '%s': %s", 1017 fatal("%.200s line %d: Bad number '%s': %s",
986 filename, linenum, arg, strerror(errno)); 1018 filename, linenum, arg, strerror(errno));
987 /* check for too-large or too-small limits */
988 if (val64 > UINT_MAX)
989 fatal("%.200s line %d: RekeyLimit too large",
990 filename, linenum);
991 if (val64 != 0 && val64 < 16) 1019 if (val64 != 0 && val64 < 16)
992 fatal("%.200s line %d: RekeyLimit too small", 1020 fatal("%.200s line %d: RekeyLimit too small",
993 filename, linenum); 1021 filename, linenum);
994 } 1022 }
995 if (*activep && options->rekey_limit == -1) 1023 if (*activep && options->rekey_limit == -1)
996 options->rekey_limit = (u_int32_t)val64; 1024 options->rekey_limit = val64;
997 if (s != NULL) { /* optional rekey interval present */ 1025 if (s != NULL) { /* optional rekey interval present */
998 if (strcmp(s, "none") == 0) { 1026 if (strcmp(s, "none") == 0) {
999 (void)strdelim(&s); /* discard */ 1027 (void)strdelim(&s); /* discard */
@@ -1018,6 +1046,24 @@ parse_time:
1018 } 1046 }
1019 break; 1047 break;
1020 1048
1049 case oCertificateFile:
1050 arg = strdelim(&s);
1051 if (!arg || *arg == '\0')
1052 fatal("%.200s line %d: Missing argument.",
1053 filename, linenum);
1054 if (*activep) {
1055 intptr = &options->num_certificate_files;
1056 if (*intptr >= SSH_MAX_CERTIFICATE_FILES) {
1057 fatal("%.200s line %d: Too many certificate "
1058 "files specified (max %d).",
1059 filename, linenum,
1060 SSH_MAX_CERTIFICATE_FILES);
1061 }
1062 add_certificate_file(options, arg,
1063 flags & SSHCONF_USERCONF);
1064 }
1065 break;
1066
1021 case oXAuthLocation: 1067 case oXAuthLocation:
1022 charptr=&options->xauth_location; 1068 charptr=&options->xauth_location;
1023 goto parse_string; 1069 goto parse_string;
@@ -1417,10 +1463,6 @@ parse_keytypes:
1417 } 1463 }
1418 break; 1464 break;
1419 1465
1420 case oUseRoaming:
1421 intptr = &options->use_roaming;
1422 goto parse_flag;
1423
1424 case oRequestTTY: 1466 case oRequestTTY:
1425 intptr = &options->request_tty; 1467 intptr = &options->request_tty;
1426 multistate_ptr = multistate_requesttty; 1468 multistate_ptr = multistate_requesttty;
@@ -1535,6 +1577,11 @@ parse_keytypes:
1535 charptr = &options->pubkey_key_types; 1577 charptr = &options->pubkey_key_types;
1536 goto parse_keytypes; 1578 goto parse_keytypes;
1537 1579
1580 case oAddKeysToAgent:
1581 intptr = &options->add_keys_to_agent;
1582 multistate_ptr = multistate_yesnoaskconfirm;
1583 goto parse_multistate;
1584
1538 case oDeprecated: 1585 case oDeprecated:
1539 debug("%s line %d: Deprecated option \"%s\"", 1586 debug("%s line %d: Deprecated option \"%s\"",
1540 filename, linenum, keyword); 1587 filename, linenum, keyword);
@@ -1668,6 +1715,7 @@ initialize_options(Options * options)
1668 options->hostkeyalgorithms = NULL; 1715 options->hostkeyalgorithms = NULL;
1669 options->protocol = SSH_PROTO_UNKNOWN; 1716 options->protocol = SSH_PROTO_UNKNOWN;
1670 options->num_identity_files = 0; 1717 options->num_identity_files = 0;
1718 options->num_certificate_files = 0;
1671 options->hostname = NULL; 1719 options->hostname = NULL;
1672 options->host_key_alias = NULL; 1720 options->host_key_alias = NULL;
1673 options->proxy_command = NULL; 1721 options->proxy_command = NULL;
@@ -1703,7 +1751,7 @@ initialize_options(Options * options)
1703 options->tun_remote = -1; 1751 options->tun_remote = -1;
1704 options->local_command = NULL; 1752 options->local_command = NULL;
1705 options->permit_local_command = -1; 1753 options->permit_local_command = -1;
1706 options->use_roaming = 0; 1754 options->add_keys_to_agent = -1;
1707 options->visual_host_key = -1; 1755 options->visual_host_key = -1;
1708 options->ip_qos_interactive = -1; 1756 options->ip_qos_interactive = -1;
1709 options->ip_qos_bulk = -1; 1757 options->ip_qos_bulk = -1;
@@ -1814,6 +1862,8 @@ fill_default_options(Options * options)
1814 /* options->hostkeyalgorithms, default set in myproposals.h */ 1862 /* options->hostkeyalgorithms, default set in myproposals.h */
1815 if (options->protocol == SSH_PROTO_UNKNOWN) 1863 if (options->protocol == SSH_PROTO_UNKNOWN)
1816 options->protocol = SSH_PROTO_2; 1864 options->protocol = SSH_PROTO_2;
1865 if (options->add_keys_to_agent == -1)
1866 options->add_keys_to_agent = 0;
1817 if (options->num_identity_files == 0) { 1867 if (options->num_identity_files == 0) {
1818 if (options->protocol & SSH_PROTO_1) { 1868 if (options->protocol & SSH_PROTO_1) {
1819 add_identity_file(options, "~/", 1869 add_identity_file(options, "~/",
@@ -1887,7 +1937,6 @@ fill_default_options(Options * options)
1887 options->tun_remote = SSH_TUNID_ANY; 1937 options->tun_remote = SSH_TUNID_ANY;
1888 if (options->permit_local_command == -1) 1938 if (options->permit_local_command == -1)
1889 options->permit_local_command = 0; 1939 options->permit_local_command = 0;
1890 options->use_roaming = 0;
1891 if (options->visual_host_key == -1) 1940 if (options->visual_host_key == -1)
1892 options->visual_host_key = 0; 1941 options->visual_host_key = 0;
1893 if (options->ip_qos_interactive == -1) 1942 if (options->ip_qos_interactive == -1)
@@ -2296,6 +2345,10 @@ dump_client_config(Options *o, const char *host)
2296 int i; 2345 int i;
2297 char vbuf[5]; 2346 char vbuf[5];
2298 2347
2348 /* This is normally prepared in ssh_kex2 */
2349 if (kex_assemble_names(KEX_DEFAULT_PK_ALG, &o->hostkeyalgorithms) != 0)
2350 fatal("%s: kex_assemble_names failed", __func__);
2351
2299 /* Most interesting options first: user, host, port */ 2352 /* Most interesting options first: user, host, port */
2300 dump_cfg_string(oUser, o->user); 2353 dump_cfg_string(oUser, o->user);
2301 dump_cfg_string(oHostName, host); 2354 dump_cfg_string(oHostName, host);
@@ -2356,7 +2409,7 @@ dump_client_config(Options *o, const char *host)
2356 dump_cfg_string(oBindAddress, o->bind_address); 2409 dump_cfg_string(oBindAddress, o->bind_address);
2357 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT); 2410 dump_cfg_string(oCiphers, o->ciphers ? o->ciphers : KEX_CLIENT_ENCRYPT);
2358 dump_cfg_string(oControlPath, o->control_path); 2411 dump_cfg_string(oControlPath, o->control_path);
2359 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms ? o->hostkeyalgorithms : KEX_DEFAULT_PK_ALG); 2412 dump_cfg_string(oHostKeyAlgorithms, o->hostkeyalgorithms);
2360 dump_cfg_string(oHostKeyAlias, o->host_key_alias); 2413 dump_cfg_string(oHostKeyAlias, o->host_key_alias);
2361 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types); 2414 dump_cfg_string(oHostbasedKeyTypes, o->hostbased_key_types);
2362 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices); 2415 dump_cfg_string(oKbdInteractiveDevices, o->kbd_interactive_devices);
@@ -2367,6 +2420,7 @@ dump_client_config(Options *o, const char *host)
2367 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider); 2420 dump_cfg_string(oPKCS11Provider, o->pkcs11_provider);
2368 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications); 2421 dump_cfg_string(oPreferredAuthentications, o->preferred_authentications);
2369 dump_cfg_string(oProxyCommand, o->proxy_command); 2422 dump_cfg_string(oProxyCommand, o->proxy_command);
2423 dump_cfg_string(oPubkeyAcceptedKeyTypes, o->pubkey_key_types);
2370 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys); 2424 dump_cfg_string(oRevokedHostKeys, o->revoked_host_keys);
2371 dump_cfg_string(oXAuthLocation, o->xauth_location); 2425 dump_cfg_string(oXAuthLocation, o->xauth_location);
2372 2426
@@ -2435,8 +2489,8 @@ dump_client_config(Options *o, const char *host)
2435 printf("%s\n", iptos2str(o->ip_qos_bulk)); 2489 printf("%s\n", iptos2str(o->ip_qos_bulk));
2436 2490
2437 /* oRekeyLimit */ 2491 /* oRekeyLimit */
2438 printf("rekeylimit %lld %d\n", 2492 printf("rekeylimit %llu %d\n",
2439 (long long)o->rekey_limit, o->rekey_interval); 2493 (unsigned long long)o->rekey_limit, o->rekey_interval);
2440 2494
2441 /* oStreamLocalBindMask */ 2495 /* oStreamLocalBindMask */
2442 printf("streamlocalbindmask 0%o\n", 2496 printf("streamlocalbindmask 0%o\n",