summaryrefslogtreecommitdiff
path: root/readconf.c
diff options
context:
space:
mode:
Diffstat (limited to 'readconf.c')
-rw-r--r--readconf.c84
1 files changed, 62 insertions, 22 deletions
diff --git a/readconf.c b/readconf.c
index 6d046f063..2ba312441 100644
--- a/readconf.c
+++ b/readconf.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: readconf.c,v 1.300 2018/10/05 14:26:09 naddy Exp $ */ 1/* $OpenBSD: readconf.c,v 1.304 2019/03/01 02:08:50 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
@@ -67,6 +67,7 @@
67#include "uidswap.h" 67#include "uidswap.h"
68#include "myproposal.h" 68#include "myproposal.h"
69#include "digest.h" 69#include "digest.h"
70#include "ssh-gss.h"
70 71
71/* Format of the configuration file: 72/* Format of the configuration file:
72 73
@@ -133,10 +134,11 @@
133 134
134static int read_config_file_depth(const char *filename, struct passwd *pw, 135static int read_config_file_depth(const char *filename, struct passwd *pw,
135 const char *host, const char *original_host, Options *options, 136 const char *host, const char *original_host, Options *options,
136 int flags, int *activep, int depth); 137 int flags, int *activep, int *want_final_pass, int depth);
137static int process_config_line_depth(Options *options, struct passwd *pw, 138static int process_config_line_depth(Options *options, struct passwd *pw,
138 const char *host, const char *original_host, char *line, 139 const char *host, const char *original_host, char *line,
139 const char *filename, int linenum, int *activep, int flags, int depth); 140 const char *filename, int linenum, int *activep, int flags,
141 int *want_final_pass, int depth);
140 142
141/* Keyword tokens. */ 143/* Keyword tokens. */
142 144
@@ -162,7 +164,7 @@ typedef enum {
162 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout, 164 oEnableSSHKeysign, oRekeyLimit, oVerifyHostKeyDNS, oConnectTimeout,
163 oAddressFamily, oGssAuthentication, oGssDelegateCreds, 165 oAddressFamily, oGssAuthentication, oGssDelegateCreds,
164 oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey, 166 oGssTrustDns, oGssKeyEx, oGssClientIdentity, oGssRenewalRekey,
165 oGssServerIdentity, 167 oGssServerIdentity, oGssKexAlgorithms,
166 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly, 168 oServerAliveInterval, oServerAliveCountMax, oIdentitiesOnly,
167 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist, 169 oSendEnv, oSetEnv, oControlPath, oControlMaster, oControlPersist,
168 oHashKnownHosts, 170 oHashKnownHosts,
@@ -211,6 +213,7 @@ static struct {
211 { "gssapiclientidentity", oGssClientIdentity }, 213 { "gssapiclientidentity", oGssClientIdentity },
212 { "gssapiserveridentity", oGssServerIdentity }, 214 { "gssapiserveridentity", oGssServerIdentity },
213 { "gssapirenewalforcesrekey", oGssRenewalRekey }, 215 { "gssapirenewalforcesrekey", oGssRenewalRekey },
216 { "gssapikexalgorithms", oGssKexAlgorithms },
214# else 217# else
215 { "gssapiauthentication", oUnsupported }, 218 { "gssapiauthentication", oUnsupported },
216 { "gssapikeyexchange", oUnsupported }, 219 { "gssapikeyexchange", oUnsupported },
@@ -219,10 +222,11 @@ static struct {
219 { "gssapiclientidentity", oUnsupported }, 222 { "gssapiclientidentity", oUnsupported },
220 { "gssapiserveridentity", oUnsupported }, 223 { "gssapiserveridentity", oUnsupported },
221 { "gssapirenewalforcesrekey", oUnsupported }, 224 { "gssapirenewalforcesrekey", oUnsupported },
225 { "gssapikexalgorithms", oUnsupported },
222#endif 226#endif
223#ifdef ENABLE_PKCS11 227#ifdef ENABLE_PKCS11
224 { "smartcarddevice", oPKCS11Provider },
225 { "pkcs11provider", oPKCS11Provider }, 228 { "pkcs11provider", oPKCS11Provider },
229 { "smartcarddevice", oPKCS11Provider },
226# else 230# else
227 { "smartcarddevice", oUnsupported }, 231 { "smartcarddevice", oUnsupported },
228 { "pkcs11provider", oUnsupported }, 232 { "pkcs11provider", oUnsupported },
@@ -555,8 +559,8 @@ execute_in_shell(const char *cmd)
555 */ 559 */
556static int 560static int
557match_cfg_line(Options *options, char **condition, struct passwd *pw, 561match_cfg_line(Options *options, char **condition, struct passwd *pw,
558 const char *host_arg, const char *original_host, int post_canon, 562 const char *host_arg, const char *original_host, int final_pass,
559 const char *filename, int linenum) 563 int *want_final_pass, const char *filename, int linenum)
560{ 564{
561 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria; 565 char *arg, *oattrib, *attrib, *cmd, *cp = *condition, *host, *criteria;
562 const char *ruser; 566 const char *ruser;
@@ -570,7 +574,7 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
570 */ 574 */
571 port = options->port <= 0 ? default_ssh_port() : options->port; 575 port = options->port <= 0 ? default_ssh_port() : options->port;
572 ruser = options->user == NULL ? pw->pw_name : options->user; 576 ruser = options->user == NULL ? pw->pw_name : options->user;
573 if (post_canon) { 577 if (final_pass) {
574 host = xstrdup(options->hostname); 578 host = xstrdup(options->hostname);
575 } else if (options->hostname != NULL) { 579 } else if (options->hostname != NULL) {
576 /* NB. Please keep in sync with ssh.c:main() */ 580 /* NB. Please keep in sync with ssh.c:main() */
@@ -602,8 +606,16 @@ match_cfg_line(Options *options, char **condition, struct passwd *pw,
602 goto out; 606 goto out;
603 } 607 }
604 attributes++; 608 attributes++;
605 if (strcasecmp(attrib, "canonical") == 0) { 609 if (strcasecmp(attrib, "canonical") == 0 ||
606 r = !!post_canon; /* force bitmask member to boolean */ 610 strcasecmp(attrib, "final") == 0) {
611 /*
612 * If the config requests "Match final" then remember
613 * this so we can perform a second pass later.
614 */
615 if (strcasecmp(attrib, "final") == 0 &&
616 want_final_pass != NULL)
617 *want_final_pass = 1;
618 r = !!final_pass; /* force bitmask member to boolean */
607 if (r == (negate ? 1 : 0)) 619 if (r == (negate ? 1 : 0))
608 this_result = result = 0; 620 this_result = result = 0;
609 debug3("%.200s line %d: %smatched '%s'", 621 debug3("%.200s line %d: %smatched '%s'",
@@ -840,14 +852,14 @@ process_config_line(Options *options, struct passwd *pw, const char *host,
840 int linenum, int *activep, int flags) 852 int linenum, int *activep, int flags)
841{ 853{
842 return process_config_line_depth(options, pw, host, original_host, 854 return process_config_line_depth(options, pw, host, original_host,
843 line, filename, linenum, activep, flags, 0); 855 line, filename, linenum, activep, flags, NULL, 0);
844} 856}
845 857
846#define WHITESPACE " \t\r\n" 858#define WHITESPACE " \t\r\n"
847static int 859static int
848process_config_line_depth(Options *options, struct passwd *pw, const char *host, 860process_config_line_depth(Options *options, struct passwd *pw, const char *host,
849 const char *original_host, char *line, const char *filename, 861 const char *original_host, char *line, const char *filename,
850 int linenum, int *activep, int flags, int depth) 862 int linenum, int *activep, int flags, int *want_final_pass, int depth)
851{ 863{
852 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2; 864 char *s, **charptr, *endofnumber, *keyword, *arg, *arg2;
853 char **cpptr, fwdarg[256]; 865 char **cpptr, fwdarg[256];
@@ -1014,6 +1026,18 @@ parse_time:
1014 intptr = &options->gss_renewal_rekey; 1026 intptr = &options->gss_renewal_rekey;
1015 goto parse_flag; 1027 goto parse_flag;
1016 1028
1029 case oGssKexAlgorithms:
1030 arg = strdelim(&s);
1031 if (!arg || *arg == '\0')
1032 fatal("%.200s line %d: Missing argument.",
1033 filename, linenum);
1034 if (!kex_gss_names_valid(arg))
1035 fatal("%.200s line %d: Bad GSSAPI KexAlgorithms '%s'.",
1036 filename, linenum, arg ? arg : "<NONE>");
1037 if (*activep && options->gss_kex_algorithms == NULL)
1038 options->gss_kex_algorithms = xstrdup(arg);
1039 break;
1040
1017 case oBatchMode: 1041 case oBatchMode:
1018 intptr = &options->batch_mode; 1042 intptr = &options->batch_mode;
1019 goto parse_flag; 1043 goto parse_flag;
@@ -1375,7 +1399,8 @@ parse_keytypes:
1375 fatal("Host directive not supported as a command-line " 1399 fatal("Host directive not supported as a command-line "
1376 "option"); 1400 "option");
1377 value = match_cfg_line(options, &s, pw, host, original_host, 1401 value = match_cfg_line(options, &s, pw, host, original_host,
1378 flags & SSHCONF_POSTCANON, filename, linenum); 1402 flags & SSHCONF_FINAL, want_final_pass,
1403 filename, linenum);
1379 if (value < 0) 1404 if (value < 0)
1380 fatal("%.200s line %d: Bad Match condition", filename, 1405 fatal("%.200s line %d: Bad Match condition", filename,
1381 linenum); 1406 linenum);
@@ -1559,7 +1584,7 @@ parse_keytypes:
1559 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0) 1584 if (*arg == '~' && (flags & SSHCONF_USERCONF) == 0)
1560 fatal("%.200s line %d: bad include path %s.", 1585 fatal("%.200s line %d: bad include path %s.",
1561 filename, linenum, arg); 1586 filename, linenum, arg);
1562 if (*arg != '/' && *arg != '~') { 1587 if (!path_absolute(arg) && *arg != '~') {
1563 xasprintf(&arg2, "%s/%s", 1588 xasprintf(&arg2, "%s/%s",
1564 (flags & SSHCONF_USERCONF) ? 1589 (flags & SSHCONF_USERCONF) ?
1565 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg); 1590 "~/" _PATH_SSH_USER_DIR : SSHDIR, arg);
@@ -1586,7 +1611,7 @@ parse_keytypes:
1586 pw, host, original_host, options, 1611 pw, host, original_host, options,
1587 flags | SSHCONF_CHECKPERM | 1612 flags | SSHCONF_CHECKPERM |
1588 (oactive ? 0 : SSHCONF_NEVERMATCH), 1613 (oactive ? 0 : SSHCONF_NEVERMATCH),
1589 activep, depth + 1); 1614 activep, want_final_pass, depth + 1);
1590 if (r != 1 && errno != ENOENT) { 1615 if (r != 1 && errno != ENOENT) {
1591 fatal("Can't open user config file " 1616 fatal("Can't open user config file "
1592 "%.100s: %.100s", gl.gl_pathv[i], 1617 "%.100s: %.100s", gl.gl_pathv[i],
@@ -1789,19 +1814,20 @@ parse_keytypes:
1789 */ 1814 */
1790int 1815int
1791read_config_file(const char *filename, struct passwd *pw, const char *host, 1816read_config_file(const char *filename, struct passwd *pw, const char *host,
1792 const char *original_host, Options *options, int flags) 1817 const char *original_host, Options *options, int flags,
1818 int *want_final_pass)
1793{ 1819{
1794 int active = 1; 1820 int active = 1;
1795 1821
1796 return read_config_file_depth(filename, pw, host, original_host, 1822 return read_config_file_depth(filename, pw, host, original_host,
1797 options, flags, &active, 0); 1823 options, flags, &active, want_final_pass, 0);
1798} 1824}
1799 1825
1800#define READCONF_MAX_DEPTH 16 1826#define READCONF_MAX_DEPTH 16
1801static int 1827static int
1802read_config_file_depth(const char *filename, struct passwd *pw, 1828read_config_file_depth(const char *filename, struct passwd *pw,
1803 const char *host, const char *original_host, Options *options, 1829 const char *host, const char *original_host, Options *options,
1804 int flags, int *activep, int depth) 1830 int flags, int *activep, int *want_final_pass, int depth)
1805{ 1831{
1806 FILE *f; 1832 FILE *f;
1807 char *line = NULL; 1833 char *line = NULL;
@@ -1835,7 +1861,8 @@ read_config_file_depth(const char *filename, struct passwd *pw,
1835 /* Update line number counter. */ 1861 /* Update line number counter. */
1836 linenum++; 1862 linenum++;
1837 if (process_config_line_depth(options, pw, host, original_host, 1863 if (process_config_line_depth(options, pw, host, original_host,
1838 line, filename, linenum, activep, flags, depth) != 0) 1864 line, filename, linenum, activep, flags, want_final_pass,
1865 depth) != 0)
1839 bad_options++; 1866 bad_options++;
1840 } 1867 }
1841 free(line); 1868 free(line);
@@ -1885,6 +1912,7 @@ initialize_options(Options * options)
1885 options->gss_renewal_rekey = -1; 1912 options->gss_renewal_rekey = -1;
1886 options->gss_client_identity = NULL; 1913 options->gss_client_identity = NULL;
1887 options->gss_server_identity = NULL; 1914 options->gss_server_identity = NULL;
1915 options->gss_kex_algorithms = NULL;
1888 options->password_authentication = -1; 1916 options->password_authentication = -1;
1889 options->kbd_interactive_authentication = -1; 1917 options->kbd_interactive_authentication = -1;
1890 options->kbd_interactive_devices = NULL; 1918 options->kbd_interactive_devices = NULL;
@@ -2038,6 +2066,10 @@ fill_default_options(Options * options)
2038 options->gss_trust_dns = 0; 2066 options->gss_trust_dns = 0;
2039 if (options->gss_renewal_rekey == -1) 2067 if (options->gss_renewal_rekey == -1)
2040 options->gss_renewal_rekey = 0; 2068 options->gss_renewal_rekey = 0;
2069#ifdef GSSAPI
2070 if (options->gss_kex_algorithms == NULL)
2071 options->gss_kex_algorithms = strdup(GSS_KEX_DEFAULT_KEX);
2072#endif
2041 if (options->password_authentication == -1) 2073 if (options->password_authentication == -1)
2042 options->password_authentication = 1; 2074 options->password_authentication = 1;
2043 if (options->kbd_interactive_authentication == -1) 2075 if (options->kbd_interactive_authentication == -1)
@@ -2163,9 +2195,9 @@ fill_default_options(Options * options)
2163 defaults, all)) != 0) \ 2195 defaults, all)) != 0) \
2164 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \ 2196 fatal("%s: %s: %s", __func__, #what, ssh_err(r)); \
2165 } while (0) 2197 } while (0)
2166 ASSEMBLE(ciphers, KEX_SERVER_ENCRYPT, all_cipher); 2198 ASSEMBLE(ciphers, KEX_CLIENT_ENCRYPT, all_cipher);
2167 ASSEMBLE(macs, KEX_SERVER_MAC, all_mac); 2199 ASSEMBLE(macs, KEX_CLIENT_MAC, all_mac);
2168 ASSEMBLE(kex_algorithms, KEX_SERVER_KEX, all_kex); 2200 ASSEMBLE(kex_algorithms, KEX_CLIENT_KEX, all_kex);
2169 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key); 2201 ASSEMBLE(hostbased_key_types, KEX_DEFAULT_PK_ALG, all_key);
2170 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key); 2202 ASSEMBLE(pubkey_key_types, KEX_DEFAULT_PK_ALG, all_key);
2171 ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig); 2203 ASSEMBLE(ca_sign_algorithms, SSH_ALLOWED_CA_SIGALGS, all_sig);
@@ -2188,6 +2220,7 @@ fill_default_options(Options * options)
2188 CLEAR_ON_NONE(options->proxy_command); 2220 CLEAR_ON_NONE(options->proxy_command);
2189 CLEAR_ON_NONE(options->control_path); 2221 CLEAR_ON_NONE(options->control_path);
2190 CLEAR_ON_NONE(options->revoked_host_keys); 2222 CLEAR_ON_NONE(options->revoked_host_keys);
2223 CLEAR_ON_NONE(options->pkcs11_provider);
2191 if (options->jump_host != NULL && 2224 if (options->jump_host != NULL &&
2192 strcmp(options->jump_host, "none") == 0 && 2225 strcmp(options->jump_host, "none") == 0 &&
2193 options->jump_port == 0 && options->jump_user == NULL) { 2226 options->jump_port == 0 && options->jump_user == NULL) {
@@ -2656,7 +2689,14 @@ dump_client_config(Options *o, const char *host)
2656 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports); 2689 dump_cfg_fmtint(oGatewayPorts, o->fwd_opts.gateway_ports);
2657#ifdef GSSAPI 2690#ifdef GSSAPI
2658 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication); 2691 dump_cfg_fmtint(oGssAuthentication, o->gss_authentication);
2692 dump_cfg_fmtint(oGssKeyEx, o->gss_keyex);
2659 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds); 2693 dump_cfg_fmtint(oGssDelegateCreds, o->gss_deleg_creds);
2694 dump_cfg_fmtint(oGssTrustDns, o->gss_trust_dns);
2695 dump_cfg_fmtint(oGssRenewalRekey, o->gss_renewal_rekey);
2696 dump_cfg_string(oGssClientIdentity, o->gss_client_identity);
2697 dump_cfg_string(oGssServerIdentity, o->gss_server_identity);
2698 dump_cfg_string(oGssKexAlgorithms, o->gss_kex_algorithms ?
2699 o->gss_kex_algorithms : GSS_KEX_DEFAULT_KEX);
2660#endif /* GSSAPI */ 2700#endif /* GSSAPI */
2661 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts); 2701 dump_cfg_fmtint(oHashKnownHosts, o->hash_known_hosts);
2662 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication); 2702 dump_cfg_fmtint(oHostbasedAuthentication, o->hostbased_authentication);