diff options
Diffstat (limited to 'readconf.c')
-rw-r--r-- | readconf.c | 84 |
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 | ||
134 | static int read_config_file_depth(const char *filename, struct passwd *pw, | 135 | static 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); |
137 | static int process_config_line_depth(Options *options, struct passwd *pw, | 138 | static 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 | */ |
556 | static int | 560 | static int |
557 | match_cfg_line(Options *options, char **condition, struct passwd *pw, | 561 | match_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" |
847 | static int | 859 | static int |
848 | process_config_line_depth(Options *options, struct passwd *pw, const char *host, | 860 | process_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 | */ |
1790 | int | 1815 | int |
1791 | read_config_file(const char *filename, struct passwd *pw, const char *host, | 1816 | read_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 |
1801 | static int | 1827 | static int |
1802 | read_config_file_depth(const char *filename, struct passwd *pw, | 1828 | read_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); |