summaryrefslogtreecommitdiff
path: root/misc.c
diff options
context:
space:
mode:
Diffstat (limited to 'misc.c')
-rw-r--r--misc.c139
1 files changed, 115 insertions, 24 deletions
diff --git a/misc.c b/misc.c
index 634b5060a..42eeb425a 100644
--- a/misc.c
+++ b/misc.c
@@ -1,4 +1,4 @@
1/* $OpenBSD: misc.c,v 1.137 2019/01/23 21:50:56 dtucker Exp $ */ 1/* $OpenBSD: misc.c,v 1.142 2019/09/03 08:32:11 djm Exp $ */
2/* 2/*
3 * Copyright (c) 2000 Markus Friedl. All rights reserved. 3 * Copyright (c) 2000 Markus Friedl. All rights reserved.
4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 4 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
@@ -97,7 +97,7 @@ set_nonblock(int fd)
97 int val; 97 int val;
98 98
99 val = fcntl(fd, F_GETFL); 99 val = fcntl(fd, F_GETFL);
100 if (val < 0) { 100 if (val == -1) {
101 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 101 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
102 return (-1); 102 return (-1);
103 } 103 }
@@ -121,7 +121,7 @@ unset_nonblock(int fd)
121 int val; 121 int val;
122 122
123 val = fcntl(fd, F_GETFL); 123 val = fcntl(fd, F_GETFL);
124 if (val < 0) { 124 if (val == -1) {
125 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno)); 125 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
126 return (-1); 126 return (-1);
127 } 127 }
@@ -551,7 +551,7 @@ put_host_port(const char *host, u_short port)
551 551
552 if (port == 0 || port == SSH_DEFAULT_PORT) 552 if (port == 0 || port == SSH_DEFAULT_PORT)
553 return(xstrdup(host)); 553 return(xstrdup(host));
554 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) 554 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) == -1)
555 fatal("put_host_port: asprintf: %s", strerror(errno)); 555 fatal("put_host_port: asprintf: %s", strerror(errno));
556 debug3("put_host_port: %s", hoststr); 556 debug3("put_host_port: %s", hoststr);
557 return hoststr; 557 return hoststr;
@@ -1050,13 +1050,18 @@ char *
1050percent_expand(const char *string, ...) 1050percent_expand(const char *string, ...)
1051{ 1051{
1052#define EXPAND_MAX_KEYS 16 1052#define EXPAND_MAX_KEYS 16
1053 u_int num_keys, i, j; 1053 u_int num_keys, i;
1054 struct { 1054 struct {
1055 const char *key; 1055 const char *key;
1056 const char *repl; 1056 const char *repl;
1057 } keys[EXPAND_MAX_KEYS]; 1057 } keys[EXPAND_MAX_KEYS];
1058 char buf[4096]; 1058 struct sshbuf *buf;
1059 va_list ap; 1059 va_list ap;
1060 int r;
1061 char *ret;
1062
1063 if ((buf = sshbuf_new()) == NULL)
1064 fatal("%s: sshbuf_new failed", __func__);
1060 1065
1061 /* Gather keys */ 1066 /* Gather keys */
1062 va_start(ap, string); 1067 va_start(ap, string);
@@ -1073,14 +1078,13 @@ percent_expand(const char *string, ...)
1073 va_end(ap); 1078 va_end(ap);
1074 1079
1075 /* Expand string */ 1080 /* Expand string */
1076 *buf = '\0';
1077 for (i = 0; *string != '\0'; string++) { 1081 for (i = 0; *string != '\0'; string++) {
1078 if (*string != '%') { 1082 if (*string != '%') {
1079 append: 1083 append:
1080 buf[i++] = *string; 1084 if ((r = sshbuf_put_u8(buf, *string)) != 0) {
1081 if (i >= sizeof(buf)) 1085 fatal("%s: sshbuf_put_u8: %s",
1082 fatal("%s: string too long", __func__); 1086 __func__, ssh_err(r));
1083 buf[i] = '\0'; 1087 }
1084 continue; 1088 continue;
1085 } 1089 }
1086 string++; 1090 string++;
@@ -1089,18 +1093,23 @@ percent_expand(const char *string, ...)
1089 goto append; 1093 goto append;
1090 if (*string == '\0') 1094 if (*string == '\0')
1091 fatal("%s: invalid format", __func__); 1095 fatal("%s: invalid format", __func__);
1092 for (j = 0; j < num_keys; j++) { 1096 for (i = 0; i < num_keys; i++) {
1093 if (strchr(keys[j].key, *string) != NULL) { 1097 if (strchr(keys[i].key, *string) != NULL) {
1094 i = strlcat(buf, keys[j].repl, sizeof(buf)); 1098 if ((r = sshbuf_put(buf, keys[i].repl,
1095 if (i >= sizeof(buf)) 1099 strlen(keys[i].repl))) != 0) {
1096 fatal("%s: string too long", __func__); 1100 fatal("%s: sshbuf_put: %s",
1101 __func__, ssh_err(r));
1102 }
1097 break; 1103 break;
1098 } 1104 }
1099 } 1105 }
1100 if (j >= num_keys) 1106 if (i >= num_keys)
1101 fatal("%s: unknown key %%%c", __func__, *string); 1107 fatal("%s: unknown key %%%c", __func__, *string);
1102 } 1108 }
1103 return (xstrdup(buf)); 1109 if ((ret = sshbuf_dup_string(buf)) == NULL)
1110 fatal("%s: sshbuf_dup_string failed", __func__);
1111 sshbuf_free(buf);
1112 return ret;
1104#undef EXPAND_MAX_KEYS 1113#undef EXPAND_MAX_KEYS
1105} 1114}
1106 1115
@@ -1186,7 +1195,7 @@ tun_open(int tun, int mode, char **ifname)
1186 return -1; 1195 return -1;
1187 } 1196 }
1188 1197
1189 if (fd < 0) { 1198 if (fd == -1) {
1190 debug("%s: %s open: %s", __func__, name, strerror(errno)); 1199 debug("%s: %s open: %s", __func__, name, strerror(errno));
1191 return -1; 1200 return -1;
1192 } 1201 }
@@ -1625,7 +1634,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
1625 } 1634 }
1626 1635
1627 sock = socket(PF_UNIX, SOCK_STREAM, 0); 1636 sock = socket(PF_UNIX, SOCK_STREAM, 0);
1628 if (sock < 0) { 1637 if (sock == -1) {
1629 saved_errno = errno; 1638 saved_errno = errno;
1630 error("%s: socket: %.100s", __func__, strerror(errno)); 1639 error("%s: socket: %.100s", __func__, strerror(errno));
1631 errno = saved_errno; 1640 errno = saved_errno;
@@ -1635,7 +1644,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
1635 if (unlink(path) != 0 && errno != ENOENT) 1644 if (unlink(path) != 0 && errno != ENOENT)
1636 error("unlink(%s): %.100s", path, strerror(errno)); 1645 error("unlink(%s): %.100s", path, strerror(errno));
1637 } 1646 }
1638 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) { 1647 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
1639 saved_errno = errno; 1648 saved_errno = errno;
1640 error("%s: cannot bind to path %s: %s", 1649 error("%s: cannot bind to path %s: %s",
1641 __func__, path, strerror(errno)); 1650 __func__, path, strerror(errno));
@@ -1643,7 +1652,7 @@ unix_listener(const char *path, int backlog, int unlink_first)
1643 errno = saved_errno; 1652 errno = saved_errno;
1644 return -1; 1653 return -1;
1645 } 1654 }
1646 if (listen(sock, backlog) < 0) { 1655 if (listen(sock, backlog) == -1) {
1647 saved_errno = errno; 1656 saved_errno = errno;
1648 error("%s: cannot listen on path %s: %s", 1657 error("%s: cannot listen on path %s: %s",
1649 __func__, path, strerror(errno)); 1658 __func__, path, strerror(errno));
@@ -1924,7 +1933,7 @@ safe_path(const char *name, struct stat *stp, const char *pw_dir,
1924 } 1933 }
1925 strlcpy(buf, cp, sizeof(buf)); 1934 strlcpy(buf, cp, sizeof(buf));
1926 1935
1927 if (stat(buf, &st) < 0 || 1936 if (stat(buf, &st) == -1 ||
1928 !secure_permissions(&st, uid)) { 1937 !secure_permissions(&st, uid)) {
1929 snprintf(err, errlen, 1938 snprintf(err, errlen,
1930 "bad ownership or modes for directory %s", buf); 1939 "bad ownership or modes for directory %s", buf);
@@ -1958,7 +1967,7 @@ safe_path_fd(int fd, const char *file, struct passwd *pw,
1958 struct stat st; 1967 struct stat st;
1959 1968
1960 /* check the open file to avoid races */ 1969 /* check the open file to avoid races */
1961 if (fstat(fd, &st) < 0) { 1970 if (fstat(fd, &st) == -1) {
1962 snprintf(err, errlen, "cannot stat file %s: %s", 1971 snprintf(err, errlen, "cannot stat file %s: %s",
1963 file, strerror(errno)); 1972 file, strerror(errno));
1964 return -1; 1973 return -1;
@@ -2166,3 +2175,85 @@ path_absolute(const char *path)
2166{ 2175{
2167 return (*path == '/') ? 1 : 0; 2176 return (*path == '/') ? 1 : 0;
2168} 2177}
2178
2179void
2180skip_space(char **cpp)
2181{
2182 char *cp;
2183
2184 for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
2185 ;
2186 *cpp = cp;
2187}
2188
2189/* authorized_key-style options parsing helpers */
2190
2191/*
2192 * Match flag 'opt' in *optsp, and if allow_negate is set then also match
2193 * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
2194 * if negated option matches.
2195 * If the option or negated option matches, then *optsp is updated to
2196 * point to the first character after the option.
2197 */
2198int
2199opt_flag(const char *opt, int allow_negate, const char **optsp)
2200{
2201 size_t opt_len = strlen(opt);
2202 const char *opts = *optsp;
2203 int negate = 0;
2204
2205 if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
2206 opts += 3;
2207 negate = 1;
2208 }
2209 if (strncasecmp(opts, opt, opt_len) == 0) {
2210 *optsp = opts + opt_len;
2211 return negate ? 0 : 1;
2212 }
2213 return -1;
2214}
2215
2216char *
2217opt_dequote(const char **sp, const char **errstrp)
2218{
2219 const char *s = *sp;
2220 char *ret;
2221 size_t i;
2222
2223 *errstrp = NULL;
2224 if (*s != '"') {
2225 *errstrp = "missing start quote";
2226 return NULL;
2227 }
2228 s++;
2229 if ((ret = malloc(strlen((s)) + 1)) == NULL) {
2230 *errstrp = "memory allocation failed";
2231 return NULL;
2232 }
2233 for (i = 0; *s != '\0' && *s != '"';) {
2234 if (s[0] == '\\' && s[1] == '"')
2235 s++;
2236 ret[i++] = *s++;
2237 }
2238 if (*s == '\0') {
2239 *errstrp = "missing end quote";
2240 free(ret);
2241 return NULL;
2242 }
2243 ret[i] = '\0';
2244 s++;
2245 *sp = s;
2246 return ret;
2247}
2248
2249int
2250opt_match(const char **opts, const char *term)
2251{
2252 if (strncasecmp((*opts), term, strlen(term)) == 0 &&
2253 (*opts)[strlen(term)] == '=') {
2254 *opts += strlen(term) + 1;
2255 return 1;
2256 }
2257 return 0;
2258}
2259