From 1143bc13fbc7142cef7b3403d9789291a909601e Mon Sep 17 00:00:00 2001 From: dtucker Date: Tue, 8 Feb 2022 08:59:12 +0000 Subject: [PATCH] Switch hpdelim interface to accept only ":" as delimiter. Historicallly, hpdelim accepted ":" or "/" as a port delimiter between hosts (or addresses) and ports. These days most of the uses for "/" are no longer accepted, so there are several places where it checks the delimiter to disallow it. Make hpdelim accept only ":" and use hpdelim2 in the other cases. ok djm@ --- usr.bin/ssh/auth-options.c | 4 ++-- usr.bin/ssh/misc.c | 10 ++++++++-- usr.bin/ssh/readconf.c | 9 ++++----- usr.bin/ssh/servconf.c | 21 +++++++++------------ usr.bin/ssh/session.c | 4 ++-- usr.bin/ssh/ssh.c | 9 ++++----- 6 files changed, 29 insertions(+), 28 deletions(-) diff --git a/usr.bin/ssh/auth-options.c b/usr.bin/ssh/auth-options.c index f63cbc19dcc..eda5466c918 100644 --- a/usr.bin/ssh/auth-options.c +++ b/usr.bin/ssh/auth-options.c @@ -1,4 +1,4 @@ -/* $OpenBSD: auth-options.c,v 1.97 2021/07/24 01:55:19 djm Exp $ */ +/* $OpenBSD: auth-options.c,v 1.98 2022/02/08 08:59:12 dtucker Exp $ */ /* * Copyright (c) 2018 Damien Miller * @@ -279,7 +279,7 @@ handle_permit(const char **optsp, int allow_bare_port, } cp = tmp; /* validate syntax before recording it. */ - host = hpdelim(&cp); + host = hpdelim2(&cp, NULL); if (host == NULL || strlen(host) >= NI_MAXHOST) { free(tmp); free(opt); diff --git a/usr.bin/ssh/misc.c b/usr.bin/ssh/misc.c index 239d77a29eb..1c86f684c71 100644 --- a/usr.bin/ssh/misc.c +++ b/usr.bin/ssh/misc.c @@ -1,4 +1,4 @@ -/* $OpenBSD: misc.c,v 1.172 2022/01/08 07:32:45 djm Exp $ */ +/* $OpenBSD: misc.c,v 1.173 2022/02/08 08:59:12 dtucker Exp $ */ /* * Copyright (c) 2000 Markus Friedl. All rights reserved. * Copyright (c) 2005-2020 Damien Miller. All rights reserved. @@ -672,10 +672,16 @@ hpdelim2(char **cp, char *delim) return old; } +/* The common case: only accept colon as delimiter. */ char * hpdelim(char **cp) { - return hpdelim2(cp, NULL); + char *r, delim; + + r = hpdelim2(cp, &delim); + if (delim == '/') + return NULL; + return r; } char * diff --git a/usr.bin/ssh/readconf.c b/usr.bin/ssh/readconf.c index 0d7f71fa04d..f7387e8d4f2 100644 --- a/usr.bin/ssh/readconf.c +++ b/usr.bin/ssh/readconf.c @@ -1,4 +1,4 @@ -/* $OpenBSD: readconf.c,v 1.365 2022/02/04 02:49:17 dtucker Exp $ */ +/* $OpenBSD: readconf.c,v 1.366 2022/02/08 08:59:12 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -929,7 +929,7 @@ process_config_line_depth(Options *options, struct passwd *pw, const char *host, const char *original_host, char *line, const char *filename, int linenum, int *activep, int flags, int *want_final_pass, int depth) { - char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p, ch; + char *str, **charptr, *endofnumber, *keyword, *arg, *arg2, *p; char **cpptr, ***cppptr, fwdarg[256]; u_int i, *uintptr, uvalue, max_entries = 0; int r, oactive, negated, opcode, *intptr, value, value2, cmdline = 0; @@ -1570,9 +1570,8 @@ parse_pubkey_algos: } while ((arg = argv_next(&ac, &av)) != NULL) { arg2 = xstrdup(arg); - ch = '\0'; - p = hpdelim2(&arg, &ch); - if (p == NULL || ch == '/') { + p = hpdelim(&arg); + if (p == NULL) { fatal("%s line %d: missing host in %s", filename, linenum, lookup_opcode_name(opcode)); diff --git a/usr.bin/ssh/servconf.c b/usr.bin/ssh/servconf.c index 03e1fe4d851..63a7303de65 100644 --- a/usr.bin/ssh/servconf.c +++ b/usr.bin/ssh/servconf.c @@ -1,5 +1,5 @@ -/* $OpenBSD: servconf.c,v 1.382 2021/09/06 00:36:01 millert Exp $ */ +/* $OpenBSD: servconf.c,v 1.383 2022/02/08 08:59:12 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -844,7 +844,7 @@ process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, { u_int i; int port; - char *host, *arg, *oarg, ch; + char *host, *arg, *oarg; int where = opcode == sPermitOpen ? FORWARD_LOCAL : FORWARD_REMOTE; const char *what = lookup_opcode_name(opcode); @@ -862,9 +862,8 @@ process_permitopen_list(struct ssh *ssh, ServerOpCodes opcode, /* Otherwise treat it as a list of permitted host:port */ for (i = 0; i < num_opens; i++) { oarg = arg = xstrdup(opens[i]); - ch = '\0'; - host = hpdelim2(&arg, &ch); - if (host == NULL || ch == '/') + host = hpdelim(&arg); + if (host == NULL) fatal_f("missing host in %s", what); host = cleanhostname(host); if (arg == NULL || ((port = permitopen_port(arg)) < 0)) @@ -1210,7 +1209,7 @@ process_server_config_line_depth(ServerOptions *options, char *line, struct connection_info *connectinfo, int *inc_flags, int depth, struct include_list *includes) { - char ch, *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; + char *str, ***chararrayptr, **charptr, *arg, *arg2, *p, *keyword; int cmdline = 0, *intptr, value, value2, n, port, oactive, r, found; SyslogFacility *log_facility_ptr; LogLevel *log_level_ptr; @@ -1323,9 +1322,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, p = arg; } else { arg2 = NULL; - ch = '\0'; - p = hpdelim2(&arg, &ch); - if (p == NULL || ch == '/') + p = hpdelim(&arg); + if (p == NULL) fatal("%s line %d: bad address:port usage", filename, linenum); p = cleanhostname(p); @@ -2154,9 +2152,8 @@ process_server_config_line_depth(ServerOptions *options, char *line, xasprintf(&arg2, "*:%s", arg); } else { arg2 = xstrdup(arg); - ch = '\0'; - p = hpdelim2(&arg, &ch); - if (p == NULL || ch == '/') { + p = hpdelim(&arg); + if (p == NULL) { fatal("%s line %d: %s missing host", filename, linenum, keyword); } diff --git a/usr.bin/ssh/session.c b/usr.bin/ssh/session.c index b0b987139a5..91416ea806b 100644 --- a/usr.bin/ssh/session.c +++ b/usr.bin/ssh/session.c @@ -1,4 +1,4 @@ -/* $OpenBSD: session.c,v 1.329 2021/08/11 05:20:17 djm Exp $ */ +/* $OpenBSD: session.c,v 1.330 2022/02/08 08:59:12 dtucker Exp $ */ /* * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland * All rights reserved @@ -290,7 +290,7 @@ set_fwdpermit_from_authopts(struct ssh *ssh, const struct sshauthopt *opts) for (i = 0; i < auth_opts->npermitopen; i++) { tmp = cp = xstrdup(auth_opts->permitopen[i]); /* This shouldn't fail as it has already been checked */ - if ((host = hpdelim(&cp)) == NULL) + if ((host = hpdelim2(&cp, NULL)) == NULL) fatal_f("internal error: hpdelim"); host = cleanhostname(host); if (cp == NULL || (port = permitopen_port(cp)) < 0) diff --git a/usr.bin/ssh/ssh.c b/usr.bin/ssh/ssh.c index b2cfbe17b87..ac6dedfa042 100644 --- a/usr.bin/ssh/ssh.c +++ b/usr.bin/ssh/ssh.c @@ -1,4 +1,4 @@ -/* $OpenBSD: ssh.c,v 1.572 2022/01/06 22:04:20 djm Exp $ */ +/* $OpenBSD: ssh.c,v 1.573 2022/02/08 08:59:12 dtucker Exp $ */ /* * Author: Tatu Ylonen * Copyright (c) 1995 Tatu Ylonen , Espoo, Finland @@ -1866,7 +1866,7 @@ ssh_init_forward_permissions(struct ssh *ssh, const char *what, char **opens, { u_int i; int port; - char *addr, *arg, *oarg, ch; + char *addr, *arg, *oarg; int where = FORWARD_LOCAL; channel_clear_permission(ssh, FORWARD_ADM, where); @@ -1883,9 +1883,8 @@ ssh_init_forward_permissions(struct ssh *ssh, const char *what, char **opens, /* Otherwise treat it as a list of permitted host:port */ for (i = 0; i < num_opens; i++) { oarg = arg = xstrdup(opens[i]); - ch = '\0'; - addr = hpdelim2(&arg, &ch); - if (addr == NULL || ch == '/') + addr = hpdelim(&arg); + if (addr == NULL) fatal_f("missing host in %s", what); addr = cleanhostname(addr); if (arg == NULL || ((port = permitopen_port(arg)) < 0)) -- 2.20.1