misc.c revision 1.15 1 /* $NetBSD: misc.c,v 1.15 2017/04/18 18:41:46 christos Exp $ */
2 /* $OpenBSD: misc.c,v 1.109 2017/03/14 00:55:37 dtucker Exp $ */
3 /*
4 * Copyright (c) 2000 Markus Friedl. All rights reserved.
5 * Copyright (c) 2005,2006 Damien Miller. All rights reserved.
6 *
7 * Redistribution and use in source and binary forms, with or without
8 * modification, are permitted provided that the following conditions
9 * are met:
10 * 1. Redistributions of source code must retain the above copyright
11 * notice, this list of conditions and the following disclaimer.
12 * 2. Redistributions in binary form must reproduce the above copyright
13 * notice, this list of conditions and the following disclaimer in the
14 * documentation and/or other materials provided with the distribution.
15 *
16 * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
17 * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
18 * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
19 * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
20 * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
21 * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
22 * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
23 * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
24 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
25 * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
26 */
27
28 #include "includes.h"
29 __RCSID("$NetBSD: misc.c,v 1.15 2017/04/18 18:41:46 christos Exp $");
30 #include <sys/types.h>
31 #include <sys/ioctl.h>
32 #include <sys/socket.h>
33 #include <sys/time.h>
34 #include <sys/un.h>
35
36 #include <net/if.h>
37 #include <net/if_tun.h>
38 #include <netinet/in.h>
39 #include <netinet/ip.h>
40 #include <netinet/tcp.h>
41
42 #include <ctype.h>
43 #include <errno.h>
44 #include <fcntl.h>
45 #include <netdb.h>
46 #include <paths.h>
47 #include <pwd.h>
48 #include <limits.h>
49 #include <stdarg.h>
50 #include <stdio.h>
51 #include <stdlib.h>
52 #include <string.h>
53 #include <unistd.h>
54
55 #include "xmalloc.h"
56 #include "misc.h"
57 #include "log.h"
58 #include "ssh.h"
59
60 /* remove newline at end of string */
61 char *
62 chop(char *s)
63 {
64 char *t = s;
65 while (*t) {
66 if (*t == '\n' || *t == '\r') {
67 *t = '\0';
68 return s;
69 }
70 t++;
71 }
72 return s;
73
74 }
75
76 /* set/unset filedescriptor to non-blocking */
77 int
78 set_nonblock(int fd)
79 {
80 int val;
81
82 val = fcntl(fd, F_GETFL);
83 if (val < 0) {
84 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
85 return (-1);
86 }
87 if (val & O_NONBLOCK) {
88 debug3("fd %d is O_NONBLOCK", fd);
89 return (0);
90 }
91 debug2("fd %d setting O_NONBLOCK", fd);
92 val |= O_NONBLOCK;
93 if (fcntl(fd, F_SETFL, val) == -1) {
94 debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd,
95 strerror(errno));
96 return (-1);
97 }
98 return (0);
99 }
100
101 int
102 unset_nonblock(int fd)
103 {
104 int val;
105
106 val = fcntl(fd, F_GETFL);
107 if (val < 0) {
108 error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
109 return (-1);
110 }
111 if (!(val & O_NONBLOCK)) {
112 debug3("fd %d is not O_NONBLOCK", fd);
113 return (0);
114 }
115 debug("fd %d clearing O_NONBLOCK", fd);
116 val &= ~O_NONBLOCK;
117 if (fcntl(fd, F_SETFL, val) == -1) {
118 debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s",
119 fd, strerror(errno));
120 return (-1);
121 }
122 return (0);
123 }
124
125 const char *
126 ssh_gai_strerror(int gaierr)
127 {
128 if (gaierr == EAI_SYSTEM && errno != 0)
129 return strerror(errno);
130 return gai_strerror(gaierr);
131 }
132
133 /* disable nagle on socket */
134 void
135 set_nodelay(int fd)
136 {
137 int opt;
138 socklen_t optlen;
139
140 optlen = sizeof opt;
141 if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
142 debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));
143 return;
144 }
145 if (opt == 1) {
146 debug2("fd %d is TCP_NODELAY", fd);
147 return;
148 }
149 opt = 1;
150 debug2("fd %d setting TCP_NODELAY", fd);
151 if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
152 error("setsockopt TCP_NODELAY: %.100s", strerror(errno));
153 }
154
155 /* Characters considered whitespace in strsep calls. */
156 #define WHITESPACE " \t\r\n"
157 #define QUOTE "\""
158
159 /* return next token in configuration line */
160 char *
161 strdelim(char **s)
162 {
163 char *old;
164 int wspace = 0;
165
166 if (*s == NULL)
167 return NULL;
168
169 old = *s;
170
171 *s = strpbrk(*s, WHITESPACE QUOTE "=");
172 if (*s == NULL)
173 return (old);
174
175 if (*s[0] == '\"') {
176 memmove(*s, *s + 1, strlen(*s)); /* move nul too */
177 /* Find matching quote */
178 if ((*s = strpbrk(*s, QUOTE)) == NULL) {
179 return (NULL); /* no matching quote */
180 } else {
181 *s[0] = '\0';
182 *s += strspn(*s + 1, WHITESPACE) + 1;
183 return (old);
184 }
185 }
186
187 /* Allow only one '=' to be skipped */
188 if (*s[0] == '=')
189 wspace = 1;
190 *s[0] = '\0';
191
192 /* Skip any extra whitespace after first token */
193 *s += strspn(*s + 1, WHITESPACE) + 1;
194 if (*s[0] == '=' && !wspace)
195 *s += strspn(*s + 1, WHITESPACE) + 1;
196
197 return (old);
198 }
199
200 struct passwd *
201 pwcopy(struct passwd *pw)
202 {
203 struct passwd *copy = xcalloc(1, sizeof(*copy));
204
205 copy->pw_name = xstrdup(pw->pw_name);
206 copy->pw_passwd = xstrdup(pw->pw_passwd);
207 copy->pw_gecos = xstrdup(pw->pw_gecos);
208 copy->pw_uid = pw->pw_uid;
209 copy->pw_gid = pw->pw_gid;
210 copy->pw_expire = pw->pw_expire;
211 copy->pw_change = pw->pw_change;
212 copy->pw_class = xstrdup(pw->pw_class);
213 copy->pw_dir = xstrdup(pw->pw_dir);
214 copy->pw_shell = xstrdup(pw->pw_shell);
215 return copy;
216 }
217
218 /*
219 * Convert ASCII string to TCP/IP port number.
220 * Port must be >=0 and <=65535.
221 * Return -1 if invalid.
222 */
223 int
224 a2port(const char *s)
225 {
226 long long port;
227 const char *errstr;
228
229 port = strtonum(s, 0, 65535, &errstr);
230 if (errstr != NULL)
231 return -1;
232 return (int)port;
233 }
234
235 int
236 a2tun(const char *s, int *remote)
237 {
238 const char *errstr = NULL;
239 char *sp, *ep;
240 int tun;
241
242 if (remote != NULL) {
243 *remote = SSH_TUNID_ANY;
244 sp = xstrdup(s);
245 if ((ep = strchr(sp, ':')) == NULL) {
246 free(sp);
247 return (a2tun(s, NULL));
248 }
249 ep[0] = '\0'; ep++;
250 *remote = a2tun(ep, NULL);
251 tun = a2tun(sp, NULL);
252 free(sp);
253 return (*remote == SSH_TUNID_ERR ? *remote : tun);
254 }
255
256 if (strcasecmp(s, "any") == 0)
257 return (SSH_TUNID_ANY);
258
259 tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
260 if (errstr != NULL)
261 return (SSH_TUNID_ERR);
262
263 return (tun);
264 }
265
266 #define SECONDS 1
267 #define MINUTES (SECONDS * 60)
268 #define HOURS (MINUTES * 60)
269 #define DAYS (HOURS * 24)
270 #define WEEKS (DAYS * 7)
271
272 /*
273 * Convert a time string into seconds; format is
274 * a sequence of:
275 * time[qualifier]
276 *
277 * Valid time qualifiers are:
278 * <none> seconds
279 * s|S seconds
280 * m|M minutes
281 * h|H hours
282 * d|D days
283 * w|W weeks
284 *
285 * Examples:
286 * 90m 90 minutes
287 * 1h30m 90 minutes
288 * 2d 2 days
289 * 1w 1 week
290 *
291 * Return -1 if time string is invalid.
292 */
293 long
294 convtime(const char *s)
295 {
296 long total, secs, multiplier = 1;
297 const char *p;
298 char *endp;
299
300 errno = 0;
301 total = 0;
302 p = s;
303
304 if (p == NULL || *p == '\0')
305 return -1;
306
307 while (*p) {
308 secs = strtol(p, &endp, 10);
309 if (p == endp ||
310 (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) ||
311 secs < 0)
312 return -1;
313
314 switch (*endp++) {
315 case '\0':
316 endp--;
317 break;
318 case 's':
319 case 'S':
320 break;
321 case 'm':
322 case 'M':
323 multiplier = MINUTES;
324 break;
325 case 'h':
326 case 'H':
327 multiplier = HOURS;
328 break;
329 case 'd':
330 case 'D':
331 multiplier = DAYS;
332 break;
333 case 'w':
334 case 'W':
335 multiplier = WEEKS;
336 break;
337 default:
338 return -1;
339 }
340 if (secs >= LONG_MAX / multiplier)
341 return -1;
342 secs *= multiplier;
343 if (total >= LONG_MAX - secs)
344 return -1;
345 total += secs;
346 if (total < 0)
347 return -1;
348 p = endp;
349 }
350
351 return total;
352 }
353
354 /*
355 * Returns a standardized host+port identifier string.
356 * Caller must free returned string.
357 */
358 char *
359 put_host_port(const char *host, u_short port)
360 {
361 char *hoststr;
362
363 if (port == 0 || port == SSH_DEFAULT_PORT)
364 return(xstrdup(host));
365 if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0)
366 fatal("put_host_port: asprintf: %s", strerror(errno));
367 debug3("put_host_port: %s", hoststr);
368 return hoststr;
369 }
370
371 /*
372 * Search for next delimiter between hostnames/addresses and ports.
373 * Argument may be modified (for termination).
374 * Returns *cp if parsing succeeds.
375 * *cp is set to the start of the next delimiter, if one was found.
376 * If this is the last field, *cp is set to NULL.
377 */
378 char *
379 hpdelim(char **cp)
380 {
381 char *s, *old;
382
383 if (cp == NULL || *cp == NULL)
384 return NULL;
385
386 old = s = *cp;
387 if (*s == '[') {
388 if ((s = strchr(s, ']')) == NULL)
389 return NULL;
390 else
391 s++;
392 } else if ((s = strpbrk(s, ":/")) == NULL)
393 s = *cp + strlen(*cp); /* skip to end (see first case below) */
394
395 switch (*s) {
396 case '\0':
397 *cp = NULL; /* no more fields*/
398 break;
399
400 case ':':
401 case '/':
402 *s = '\0'; /* terminate */
403 *cp = s + 1;
404 break;
405
406 default:
407 return NULL;
408 }
409
410 return old;
411 }
412
413 char *
414 cleanhostname(char *host)
415 {
416 if (*host == '[' && host[strlen(host) - 1] == ']') {
417 host[strlen(host) - 1] = '\0';
418 return (host + 1);
419 } else
420 return host;
421 }
422
423 char *
424 colon(char *cp)
425 {
426 int flag = 0;
427
428 if (*cp == ':') /* Leading colon is part of file name. */
429 return NULL;
430 if (*cp == '[')
431 flag = 1;
432
433 for (; *cp; ++cp) {
434 if (*cp == '@' && *(cp+1) == '[')
435 flag = 1;
436 if (*cp == ']' && *(cp+1) == ':' && flag)
437 return (cp+1);
438 if (*cp == ':' && !flag)
439 return (cp);
440 if (*cp == '/')
441 return NULL;
442 }
443 return NULL;
444 }
445
446 /*
447 * Parse a [user@]host[:port] string.
448 * Caller must free returned user and host.
449 * Any of the pointer return arguments may be NULL (useful for syntax checking).
450 * If user was not specified then *userp will be set to NULL.
451 * If port was not specified then *portp will be -1.
452 * Returns 0 on success, -1 on failure.
453 */
454 int
455 parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
456 {
457 char *sdup, *cp, *tmp;
458 char *user = NULL, *host = NULL;
459 int port = -1, ret = -1;
460
461 if (userp != NULL)
462 *userp = NULL;
463 if (hostp != NULL)
464 *hostp = NULL;
465 if (portp != NULL)
466 *portp = -1;
467
468 if ((sdup = tmp = strdup(s)) == NULL)
469 return -1;
470 /* Extract optional username */
471 if ((cp = strchr(tmp, '@')) != NULL) {
472 *cp = '\0';
473 if (*tmp == '\0')
474 goto out;
475 if ((user = strdup(tmp)) == NULL)
476 goto out;
477 tmp = cp + 1;
478 }
479 /* Extract mandatory hostname */
480 if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
481 goto out;
482 host = xstrdup(cleanhostname(cp));
483 /* Convert and verify optional port */
484 if (tmp != NULL && *tmp != '\0') {
485 if ((port = a2port(tmp)) <= 0)
486 goto out;
487 }
488 /* Success */
489 if (userp != NULL) {
490 *userp = user;
491 user = NULL;
492 }
493 if (hostp != NULL) {
494 *hostp = host;
495 host = NULL;
496 }
497 if (portp != NULL)
498 *portp = port;
499 ret = 0;
500 out:
501 free(sdup);
502 free(user);
503 free(host);
504 return ret;
505 }
506
507 /* function to assist building execv() arguments */
508 void
509 addargs(arglist *args, const char *fmt, ...)
510 {
511 va_list ap;
512 char *cp;
513 u_int nalloc;
514 int r;
515
516 va_start(ap, fmt);
517 r = vasprintf(&cp, fmt, ap);
518 va_end(ap);
519 if (r == -1)
520 fatal("addargs: argument too long");
521
522 nalloc = args->nalloc;
523 if (args->list == NULL) {
524 nalloc = 32;
525 args->num = 0;
526 } else if (args->num+2 >= nalloc)
527 nalloc *= 2;
528
529 args->list = xreallocarray(args->list, nalloc, sizeof(char *));
530 args->nalloc = nalloc;
531 args->list[args->num++] = cp;
532 args->list[args->num] = NULL;
533 }
534
535 void
536 replacearg(arglist *args, u_int which, const char *fmt, ...)
537 {
538 va_list ap;
539 char *cp;
540 int r;
541
542 va_start(ap, fmt);
543 r = vasprintf(&cp, fmt, ap);
544 va_end(ap);
545 if (r == -1)
546 fatal("replacearg: argument too long");
547
548 if (which >= args->num)
549 fatal("replacearg: tried to replace invalid arg %d >= %d",
550 which, args->num);
551 free(args->list[which]);
552 args->list[which] = cp;
553 }
554
555 void
556 freeargs(arglist *args)
557 {
558 u_int i;
559
560 if (args->list != NULL) {
561 for (i = 0; i < args->num; i++)
562 free(args->list[i]);
563 free(args->list);
564 args->nalloc = args->num = 0;
565 args->list = NULL;
566 }
567 }
568
569 /*
570 * Expands tildes in the file name. Returns data allocated by xmalloc.
571 * Warning: this calls getpw*.
572 */
573 char *
574 tilde_expand_filename(const char *filename, uid_t uid)
575 {
576 const char *path, *sep;
577 char user[128], *ret, *homedir;
578 struct passwd *pw;
579 u_int len, slash;
580
581 if (*filename != '~')
582 return (xstrdup(filename));
583 filename++;
584
585 path = strchr(filename, '/');
586 if (path != NULL && path > filename) { /* ~user/path */
587 slash = path - filename;
588 if (slash > sizeof(user) - 1)
589 fatal("tilde_expand_filename: ~username too long");
590 memcpy(user, filename, slash);
591 user[slash] = '\0';
592 if ((pw = getpwnam(user)) == NULL)
593 fatal("tilde_expand_filename: No such user %s", user);
594 homedir = pw->pw_dir;
595 } else {
596 if ((pw = getpwuid(uid)) == NULL) /* ~/path */
597 fatal("tilde_expand_filename: No such uid %ld",
598 (long)uid);
599 homedir = pw->pw_dir;
600 }
601
602 /* Make sure directory has a trailing '/' */
603 len = strlen(homedir);
604 if (len == 0 || homedir[len - 1] != '/')
605 sep = "/";
606 else
607 sep = "";
608
609 /* Skip leading '/' from specified path */
610 if (path != NULL)
611 filename = path + 1;
612
613 if (xasprintf(&ret, "%s%s%s", homedir, sep, filename) >= PATH_MAX)
614 fatal("tilde_expand_filename: Path too long");
615
616 return (ret);
617 }
618
619 /*
620 * Expand a string with a set of %[char] escapes. A number of escapes may be
621 * specified as (char *escape_chars, char *replacement) pairs. The list must
622 * be terminated by a NULL escape_char. Returns replaced string in memory
623 * allocated by xmalloc.
624 */
625 char *
626 percent_expand(const char *string, ...)
627 {
628 #define EXPAND_MAX_KEYS 16
629 u_int num_keys, i, j;
630 struct {
631 const char *key;
632 const char *repl;
633 } keys[EXPAND_MAX_KEYS];
634 char buf[4096];
635 va_list ap;
636
637 /* Gather keys */
638 va_start(ap, string);
639 for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
640 keys[num_keys].key = va_arg(ap, char *);
641 if (keys[num_keys].key == NULL)
642 break;
643 keys[num_keys].repl = va_arg(ap, char *);
644 if (keys[num_keys].repl == NULL)
645 fatal("%s: NULL replacement", __func__);
646 }
647 if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
648 fatal("%s: too many keys", __func__);
649 va_end(ap);
650
651 /* Expand string */
652 *buf = '\0';
653 for (i = 0; *string != '\0'; string++) {
654 if (*string != '%') {
655 append:
656 buf[i++] = *string;
657 if (i >= sizeof(buf))
658 fatal("%s: string too long", __func__);
659 buf[i] = '\0';
660 continue;
661 }
662 string++;
663 /* %% case */
664 if (*string == '%')
665 goto append;
666 if (*string == '\0')
667 fatal("%s: invalid format", __func__);
668 for (j = 0; j < num_keys; j++) {
669 if (strchr(keys[j].key, *string) != NULL) {
670 i = strlcat(buf, keys[j].repl, sizeof(buf));
671 if (i >= sizeof(buf))
672 fatal("%s: string too long", __func__);
673 break;
674 }
675 }
676 if (j >= num_keys)
677 fatal("%s: unknown key %%%c", __func__, *string);
678 }
679 return (xstrdup(buf));
680 #undef EXPAND_MAX_KEYS
681 }
682
683 /*
684 * Read an entire line from a public key file into a static buffer, discarding
685 * lines that exceed the buffer size. Returns 0 on success, -1 on failure.
686 */
687 int
688 read_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz,
689 u_long *lineno)
690 {
691 while (fgets(buf, bufsz, f) != NULL) {
692 if (buf[0] == '\0')
693 continue;
694 (*lineno)++;
695 if (buf[strlen(buf) - 1] == '\n' || feof(f)) {
696 return 0;
697 } else {
698 debug("%s: %s line %lu exceeds size limit", __func__,
699 filename, *lineno);
700 /* discard remainder of line */
701 while (fgetc(f) != '\n' && !feof(f))
702 ; /* nothing */
703 }
704 }
705 return -1;
706 }
707
708 int
709 tun_open(int tun, int mode)
710 {
711 struct ifreq ifr;
712 char name[100];
713 int fd = -1, sock;
714 const char *tunbase = "tun";
715
716 if (mode == SSH_TUNMODE_ETHERNET)
717 tunbase = "tap";
718
719 /* Open the tunnel device */
720 if (tun <= SSH_TUNID_MAX) {
721 snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
722 fd = open(name, O_RDWR);
723 } else if (tun == SSH_TUNID_ANY) {
724 for (tun = 100; tun >= 0; tun--) {
725 snprintf(name, sizeof(name), "/dev/%s%d",
726 tunbase, tun);
727 if ((fd = open(name, O_RDWR)) >= 0)
728 break;
729 }
730 } else {
731 debug("%s: invalid tunnel %u", __func__, tun);
732 return -1;
733 }
734
735 if (fd < 0) {
736 debug("%s: %s open: %s", __func__, name, strerror(errno));
737 return -1;
738 }
739
740
741 #ifdef TUNSIFHEAD
742 /* Turn on tunnel headers */
743 int flag = 1;
744 if (mode != SSH_TUNMODE_ETHERNET &&
745 ioctl(fd, TUNSIFHEAD, &flag) == -1) {
746 debug("%s: ioctl(%d, TUNSIFHEAD, 1): %s", __func__, fd,
747 strerror(errno));
748 close(fd);
749 return -1;
750 }
751 #endif
752
753 debug("%s: %s mode %d fd %d", __func__, ifr.ifr_name, mode, fd);
754 /* Bring interface up if it is not already */
755 snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
756 if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
757 goto failed;
758
759 if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
760 debug("%s: get interface %s flags: %s", __func__,
761 ifr.ifr_name, strerror(errno));
762 goto failed;
763 }
764
765 if (!(ifr.ifr_flags & IFF_UP)) {
766 ifr.ifr_flags |= IFF_UP;
767 if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
768 debug("%s: activate interface %s: %s", __func__,
769 ifr.ifr_name, strerror(errno));
770 goto failed;
771 }
772 }
773
774 close(sock);
775 return fd;
776
777 failed:
778 if (fd >= 0)
779 close(fd);
780 if (sock >= 0)
781 close(sock);
782 debug("%s: failed to set %s mode %d: %s", __func__, ifr.ifr_name,
783 mode, strerror(errno));
784 return -1;
785 }
786
787 void
788 sanitise_stdfd(void)
789 {
790 int nullfd, dupfd;
791
792 if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
793 fprintf(stderr, "Couldn't open /dev/null: %s\n",
794 strerror(errno));
795 exit(1);
796 }
797 while (++dupfd <= STDERR_FILENO) {
798 /* Only populate closed fds. */
799 if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
800 if (dup2(nullfd, dupfd) == -1) {
801 fprintf(stderr, "dup2: %s\n", strerror(errno));
802 exit(1);
803 }
804 }
805 }
806 if (nullfd > STDERR_FILENO)
807 close(nullfd);
808 }
809
810 char *
811 tohex(const void *vp, size_t l)
812 {
813 const u_char *p = (const u_char *)vp;
814 char b[3], *r;
815 size_t i, hl;
816
817 if (l > 65536)
818 return xstrdup("tohex: length > 65536");
819
820 hl = l * 2 + 1;
821 r = xcalloc(1, hl);
822 for (i = 0; i < l; i++) {
823 snprintf(b, sizeof(b), "%02x", p[i]);
824 strlcat(r, b, hl);
825 }
826 return (r);
827 }
828
829 u_int64_t
830 get_u64(const void *vp)
831 {
832 const u_char *p = (const u_char *)vp;
833 u_int64_t v;
834
835 v = (u_int64_t)p[0] << 56;
836 v |= (u_int64_t)p[1] << 48;
837 v |= (u_int64_t)p[2] << 40;
838 v |= (u_int64_t)p[3] << 32;
839 v |= (u_int64_t)p[4] << 24;
840 v |= (u_int64_t)p[5] << 16;
841 v |= (u_int64_t)p[6] << 8;
842 v |= (u_int64_t)p[7];
843
844 return (v);
845 }
846
847 u_int32_t
848 get_u32(const void *vp)
849 {
850 const u_char *p = (const u_char *)vp;
851 u_int32_t v;
852
853 v = (u_int32_t)p[0] << 24;
854 v |= (u_int32_t)p[1] << 16;
855 v |= (u_int32_t)p[2] << 8;
856 v |= (u_int32_t)p[3];
857
858 return (v);
859 }
860
861 u_int32_t
862 get_u32_le(const void *vp)
863 {
864 const u_char *p = (const u_char *)vp;
865 u_int32_t v;
866
867 v = (u_int32_t)p[0];
868 v |= (u_int32_t)p[1] << 8;
869 v |= (u_int32_t)p[2] << 16;
870 v |= (u_int32_t)p[3] << 24;
871
872 return (v);
873 }
874
875 u_int16_t
876 get_u16(const void *vp)
877 {
878 const u_char *p = (const u_char *)vp;
879 u_int16_t v;
880
881 v = (u_int16_t)p[0] << 8;
882 v |= (u_int16_t)p[1];
883
884 return (v);
885 }
886
887 void
888 put_u64(void *vp, u_int64_t v)
889 {
890 u_char *p = (u_char *)vp;
891
892 p[0] = (u_char)(v >> 56) & 0xff;
893 p[1] = (u_char)(v >> 48) & 0xff;
894 p[2] = (u_char)(v >> 40) & 0xff;
895 p[3] = (u_char)(v >> 32) & 0xff;
896 p[4] = (u_char)(v >> 24) & 0xff;
897 p[5] = (u_char)(v >> 16) & 0xff;
898 p[6] = (u_char)(v >> 8) & 0xff;
899 p[7] = (u_char)v & 0xff;
900 }
901
902 void
903 put_u32(void *vp, u_int32_t v)
904 {
905 u_char *p = (u_char *)vp;
906
907 p[0] = (u_char)(v >> 24) & 0xff;
908 p[1] = (u_char)(v >> 16) & 0xff;
909 p[2] = (u_char)(v >> 8) & 0xff;
910 p[3] = (u_char)v & 0xff;
911 }
912
913 void
914 put_u32_le(void *vp, u_int32_t v)
915 {
916 u_char *p = (u_char *)vp;
917
918 p[0] = (u_char)v & 0xff;
919 p[1] = (u_char)(v >> 8) & 0xff;
920 p[2] = (u_char)(v >> 16) & 0xff;
921 p[3] = (u_char)(v >> 24) & 0xff;
922 }
923
924 void
925 put_u16(void *vp, u_int16_t v)
926 {
927 u_char *p = (u_char *)vp;
928
929 p[0] = (u_char)(v >> 8) & 0xff;
930 p[1] = (u_char)v & 0xff;
931 }
932
933 void
934 ms_subtract_diff(struct timeval *start, int *ms)
935 {
936 struct timeval diff, finish;
937
938 gettimeofday(&finish, NULL);
939 timersub(&finish, start, &diff);
940 *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
941 }
942
943 void
944 ms_to_timeval(struct timeval *tv, int ms)
945 {
946 if (ms < 0)
947 ms = 0;
948 tv->tv_sec = ms / 1000;
949 tv->tv_usec = (ms % 1000) * 1000;
950 }
951
952 time_t
953 monotime(void)
954 {
955 struct timespec ts;
956
957 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
958 fatal("clock_gettime: %s", strerror(errno));
959
960 return (ts.tv_sec);
961 }
962
963 double
964 monotime_double(void)
965 {
966 struct timespec ts;
967
968 if (clock_gettime(CLOCK_MONOTONIC, &ts) != 0)
969 fatal("clock_gettime: %s", strerror(errno));
970
971 return (ts.tv_sec + (double)ts.tv_nsec / 1000000000);
972 }
973
974 void
975 bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
976 {
977 bw->buflen = buflen;
978 bw->rate = kbps;
979 bw->thresh = bw->rate;
980 bw->lamt = 0;
981 timerclear(&bw->bwstart);
982 timerclear(&bw->bwend);
983 }
984
985 /* Callback from read/write loop to insert bandwidth-limiting delays */
986 void
987 bandwidth_limit(struct bwlimit *bw, size_t read_len)
988 {
989 u_int64_t waitlen;
990 struct timespec ts, rm;
991
992 if (!timerisset(&bw->bwstart)) {
993 gettimeofday(&bw->bwstart, NULL);
994 return;
995 }
996
997 bw->lamt += read_len;
998 if (bw->lamt < bw->thresh)
999 return;
1000
1001 gettimeofday(&bw->bwend, NULL);
1002 timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
1003 if (!timerisset(&bw->bwend))
1004 return;
1005
1006 bw->lamt *= 8;
1007 waitlen = (double)1000000L * bw->lamt / bw->rate;
1008
1009 bw->bwstart.tv_sec = waitlen / 1000000L;
1010 bw->bwstart.tv_usec = waitlen % 1000000L;
1011
1012 if (timercmp(&bw->bwstart, &bw->bwend, >)) {
1013 timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
1014
1015 /* Adjust the wait time */
1016 if (bw->bwend.tv_sec) {
1017 bw->thresh /= 2;
1018 if (bw->thresh < bw->buflen / 4)
1019 bw->thresh = bw->buflen / 4;
1020 } else if (bw->bwend.tv_usec < 10000) {
1021 bw->thresh *= 2;
1022 if (bw->thresh > bw->buflen * 8)
1023 bw->thresh = bw->buflen * 8;
1024 }
1025
1026 TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
1027 while (nanosleep(&ts, &rm) == -1) {
1028 if (errno != EINTR)
1029 break;
1030 ts = rm;
1031 }
1032 }
1033
1034 bw->lamt = 0;
1035 gettimeofday(&bw->bwstart, NULL);
1036 }
1037
1038 /* Make a template filename for mk[sd]temp() */
1039 void
1040 mktemp_proto(char *s, size_t len)
1041 {
1042 const char *tmpdir;
1043 int r;
1044
1045 if ((tmpdir = getenv("TMPDIR")) != NULL) {
1046 r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
1047 if (r > 0 && (size_t)r < len)
1048 return;
1049 }
1050 r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
1051 if (r < 0 || (size_t)r >= len)
1052 fatal("%s: template string too short", __func__);
1053 }
1054
1055 static const struct {
1056 const char *name;
1057 int value;
1058 } ipqos[] = {
1059 { "af11", IPTOS_DSCP_AF11 },
1060 { "af12", IPTOS_DSCP_AF12 },
1061 { "af13", IPTOS_DSCP_AF13 },
1062 { "af21", IPTOS_DSCP_AF21 },
1063 { "af22", IPTOS_DSCP_AF22 },
1064 { "af23", IPTOS_DSCP_AF23 },
1065 { "af31", IPTOS_DSCP_AF31 },
1066 { "af32", IPTOS_DSCP_AF32 },
1067 { "af33", IPTOS_DSCP_AF33 },
1068 { "af41", IPTOS_DSCP_AF41 },
1069 { "af42", IPTOS_DSCP_AF42 },
1070 { "af43", IPTOS_DSCP_AF43 },
1071 { "cs0", IPTOS_DSCP_CS0 },
1072 { "cs1", IPTOS_DSCP_CS1 },
1073 { "cs2", IPTOS_DSCP_CS2 },
1074 { "cs3", IPTOS_DSCP_CS3 },
1075 { "cs4", IPTOS_DSCP_CS4 },
1076 { "cs5", IPTOS_DSCP_CS5 },
1077 { "cs6", IPTOS_DSCP_CS6 },
1078 { "cs7", IPTOS_DSCP_CS7 },
1079 { "ef", IPTOS_DSCP_EF },
1080 { "lowdelay", IPTOS_LOWDELAY },
1081 { "throughput", IPTOS_THROUGHPUT },
1082 { "reliability", IPTOS_RELIABILITY },
1083 { NULL, -1 }
1084 };
1085
1086 int
1087 parse_ipqos(const char *cp)
1088 {
1089 u_int i;
1090 char *ep;
1091 long val;
1092
1093 if (cp == NULL)
1094 return -1;
1095 for (i = 0; ipqos[i].name != NULL; i++) {
1096 if (strcasecmp(cp, ipqos[i].name) == 0)
1097 return ipqos[i].value;
1098 }
1099 /* Try parsing as an integer */
1100 val = strtol(cp, &ep, 0);
1101 if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
1102 return -1;
1103 return val;
1104 }
1105
1106 const char *
1107 iptos2str(int iptos)
1108 {
1109 int i;
1110 static char iptos_str[sizeof "0xff"];
1111
1112 for (i = 0; ipqos[i].name != NULL; i++) {
1113 if (ipqos[i].value == iptos)
1114 return ipqos[i].name;
1115 }
1116 snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
1117 return iptos_str;
1118 }
1119
1120 void
1121 lowercase(char *s)
1122 {
1123 for (; *s; s++)
1124 *s = tolower((u_char)*s);
1125 }
1126
1127 int
1128 unix_listener(const char *path, int backlog, int unlink_first)
1129 {
1130 struct sockaddr_un sunaddr;
1131 int saved_errno, sock;
1132
1133 memset(&sunaddr, 0, sizeof(sunaddr));
1134 sunaddr.sun_family = AF_UNIX;
1135 if (strlcpy(sunaddr.sun_path, path, sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
1136 error("%s: \"%s\" too long for Unix domain socket", __func__,
1137 path);
1138 errno = ENAMETOOLONG;
1139 return -1;
1140 }
1141
1142 sock = socket(PF_UNIX, SOCK_STREAM, 0);
1143 if (sock < 0) {
1144 saved_errno = errno;
1145 error("socket: %.100s", strerror(errno));
1146 errno = saved_errno;
1147 return -1;
1148 }
1149 if (unlink_first == 1) {
1150 if (unlink(path) != 0 && errno != ENOENT)
1151 error("unlink(%s): %.100s", path, strerror(errno));
1152 }
1153 if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) < 0) {
1154 saved_errno = errno;
1155 error("bind: %.100s", strerror(errno));
1156 close(sock);
1157 error("%s: cannot bind to path: %s", __func__, path);
1158 errno = saved_errno;
1159 return -1;
1160 }
1161 if (listen(sock, backlog) < 0) {
1162 saved_errno = errno;
1163 error("listen: %.100s", strerror(errno));
1164 close(sock);
1165 unlink(path);
1166 error("%s: cannot listen on path: %s", __func__, path);
1167 errno = saved_errno;
1168 return -1;
1169 }
1170 return sock;
1171 }
1172
1173 /*
1174 * Compares two strings that maybe be NULL. Returns non-zero if strings
1175 * are both NULL or are identical, returns zero otherwise.
1176 */
1177 static int
1178 strcmp_maybe_null(const char *a, const char *b)
1179 {
1180 if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
1181 return 0;
1182 if (a != NULL && strcmp(a, b) != 0)
1183 return 0;
1184 return 1;
1185 }
1186
1187 /*
1188 * Compare two forwards, returning non-zero if they are identical or
1189 * zero otherwise.
1190 */
1191 int
1192 forward_equals(const struct Forward *a, const struct Forward *b)
1193 {
1194 if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
1195 return 0;
1196 if (a->listen_port != b->listen_port)
1197 return 0;
1198 if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
1199 return 0;
1200 if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
1201 return 0;
1202 if (a->connect_port != b->connect_port)
1203 return 0;
1204 if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
1205 return 0;
1206 /* allocated_port and handle are not checked */
1207 return 1;
1208 }
1209
1210 /* returns 1 if bind to specified port by specified user is permitted */
1211 int
1212 bind_permitted(int port, uid_t uid)
1213 {
1214 if (port < IPPORT_RESERVED && uid != 0)
1215 return 0;
1216 return 1;
1217 }
1218
1219 /* returns 1 if process is already daemonized, 0 otherwise */
1220 int
1221 daemonized(void)
1222 {
1223 int fd;
1224
1225 if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
1226 close(fd);
1227 return 0; /* have controlling terminal */
1228 }
1229 if (getppid() != 1)
1230 return 0; /* parent is not init */
1231 if (getsid(0) != getpid())
1232 return 0; /* not session leader */
1233 debug3("already daemonized");
1234 return 1;
1235 }
1236