11305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* $OpenBSD: misc.c,v 1.85 2011/03/29 18:54:17 stevesk Exp $ */ 21305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 31305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2000 Markus Friedl. All rights reserved. 41305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Copyright (c) 2005,2006 Damien Miller. All rights reserved. 51305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 61305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Redistribution and use in source and binary forms, with or without 71305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * modification, are permitted provided that the following conditions 81305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * are met: 91305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1. Redistributions of source code must retain the above copyright 101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer. 111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2. Redistributions in binary form must reproduce the above copyright 121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * notice, this list of conditions and the following disclaimer in the 131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * documentation and/or other materials provided with the distribution. 141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR 161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED. 181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT, 191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT 201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, 211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY 221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF 241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. 251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "includes.h" 281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/types.h> 301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/ioctl.h> 311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/socket.h> 321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <sys/param.h> 331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdarg.h> 351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdio.h> 361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <stdlib.h> 371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <string.h> 381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <time.h> 391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <unistd.h> 401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in.h> 421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/in_systm.h> 431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/ip.h> 441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netinet/tcp.h> 451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <errno.h> 471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <fcntl.h> 481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <netdb.h> 491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PATHS_H 501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood# include <paths.h> 511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <pwd.h> 521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef SSH_TUN_OPENBSD 541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include <net/if.h> 551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "xmalloc.h" 581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "misc.h" 591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "log.h" 601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#include "ssh.h" 611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* remove newline at end of string */ 631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchop(char *s) 651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *t = s; 671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*t) { 681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*t == '\n' || *t == '\r') { 691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *t = '\0'; 701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood t++; 731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return s; 751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* set/unset filedescriptor to non-blocking */ 791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodset_nonblock(int fd) 811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int val; 831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val = fcntl(fd, F_GETFL, 0); 851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (val < 0) { 861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (val & O_NONBLOCK) { 901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("fd %d is O_NONBLOCK", fd); 911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("fd %d setting O_NONBLOCK", fd); 941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val |= O_NONBLOCK; 951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fcntl(fd, F_SETFL, val) == -1) { 961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd, 971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 1011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 1041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodunset_nonblock(int fd) 1051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int val; 1071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val = fcntl(fd, F_GETFL, 0); 1091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (val < 0) { 1101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("fcntl(%d, F_GETFL, 0): %s", fd, strerror(errno)); 1111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!(val & O_NONBLOCK)) { 1141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("fd %d is not O_NONBLOCK", fd); 1151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 1161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("fd %d clearing O_NONBLOCK", fd); 1181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val &= ~O_NONBLOCK; 1191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fcntl(fd, F_SETFL, val) == -1) { 1201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s", 1211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd, strerror(errno)); 1221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 1231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (0); 1251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 1281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodssh_gai_strerror(int gaierr) 1291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (gaierr == EAI_SYSTEM) 1311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return strerror(errno); 1321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return gai_strerror(gaierr); 1331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* disable nagle on socket */ 1361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 1371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodset_nodelay(int fd) 1381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int opt; 1401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood socklen_t optlen; 1411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood optlen = sizeof opt; 1431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) { 1441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("getsockopt TCP_NODELAY: %.100s", strerror(errno)); 1451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 1461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (opt == 1) { 1481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("fd %d is TCP_NODELAY", fd); 1491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 1501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood opt = 1; 1521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug2("fd %d setting TCP_NODELAY", fd); 1531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1) 1541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsockopt TCP_NODELAY: %.100s", strerror(errno)); 1551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Characters considered whitespace in strsep calls. */ 1581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define WHITESPACE " \t\r\n" 1591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define QUOTE "\"" 1601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* return next token in configuration line */ 1621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 1631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstrdelim(char **s) 1641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 1651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *old; 1661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int wspace = 0; 1671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == NULL) 1691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 1701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood old = *s; 1721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s = strpbrk(*s, WHITESPACE QUOTE "="); 1741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == NULL) 1751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (old); 1761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s[0] == '\"') { 1781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memmove(*s, *s + 1, strlen(*s)); /* move nul too */ 1791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Find matching quote */ 1801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((*s = strpbrk(*s, QUOTE)) == NULL) { 1811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (NULL); /* no matching quote */ 1821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 1831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s[0] = '\0'; 1841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s += strspn(*s + 1, WHITESPACE) + 1; 1851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (old); 1861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 1881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Allow only one '=' to be skipped */ 1901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s[0] == '=') 1911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood wspace = 1; 1921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s[0] = '\0'; 1931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip any extra whitespace after first token */ 1951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s += strspn(*s + 1, WHITESPACE) + 1; 1961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s[0] == '=' && !wspace) 1971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s += strspn(*s + 1, WHITESPACE) + 1; 1981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 1991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (old); 2001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstruct passwd * 2031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpwcopy(struct passwd *pw) 2041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd *copy = xcalloc(1, sizeof(*copy)); 2061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_name = xstrdup(pw->pw_name); 208d62cf1eb84c245692d63a45c9ef71583bd2bfda1Mike Lockwood copy->pw_passwd = pw->pw_passwd ? xstrdup(pw->pw_passwd) : NULL; 209d62cf1eb84c245692d63a45c9ef71583bd2bfda1Mike Lockwood#ifdef HAVE_PW_GECOS_IN_PASSWD 2101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_gecos = xstrdup(pw->pw_gecos); 211d62cf1eb84c245692d63a45c9ef71583bd2bfda1Mike Lockwood#endif 2121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_uid = pw->pw_uid; 2131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_gid = pw->pw_gid; 2141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PW_EXPIRE_IN_PASSWD 2151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_expire = pw->pw_expire; 2161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PW_CHANGE_IN_PASSWD 2181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_change = pw->pw_change; 2191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef HAVE_PW_CLASS_IN_PASSWD 2211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_class = xstrdup(pw->pw_class); 2221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 2231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_dir = xstrdup(pw->pw_dir); 2241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood copy->pw_shell = xstrdup(pw->pw_shell); 2251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return copy; 2261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Convert ASCII string to TCP/IP port number. 2301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Port must be >=0 and <=65535. 2311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Return -1 if invalid. 2321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 2331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 2341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooda2port(const char *s) 2351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood long long port; 2371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *errstr; 2381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood port = strtonum(s, 0, 65535, &errstr); 2401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errstr != NULL) 2411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 2421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (int)port; 2431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 2461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwooda2tun(const char *s, int *remote) 2471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 2481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *errstr = NULL; 2491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *sp, *ep; 2501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int tun; 2511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (remote != NULL) { 2531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *remote = SSH_TUNID_ANY; 2541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood sp = xstrdup(s); 2551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((ep = strchr(sp, ':')) == NULL) { 2561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(sp); 2571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (a2tun(s, NULL)); 2581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ep[0] = '\0'; ep++; 2601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *remote = a2tun(ep, NULL); 2611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tun = a2tun(sp, NULL); 2621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(sp); 2631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (*remote == SSH_TUNID_ERR ? *remote : tun); 2641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 2651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcasecmp(s, "any") == 0) 2671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (SSH_TUNID_ANY); 2681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr); 2701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errstr != NULL) 2711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (SSH_TUNID_ERR); 2721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (tun); 2741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 2751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define SECONDS 1 2771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define MINUTES (SECONDS * 60) 2781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define HOURS (MINUTES * 60) 2791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define DAYS (HOURS * 24) 2801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define WEEKS (DAYS * 7) 2811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 2821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 2831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Convert a time string into seconds; format is 2841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * a sequence of: 2851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * time[qualifier] 2861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Valid time qualifiers are: 2881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * <none> seconds 2891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * s|S seconds 2901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * m|M minutes 2911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * h|H hours 2921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * d|D days 2931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * w|W weeks 2941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Examples: 2961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 90m 90 minutes 2971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1h30m 90 minutes 2981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 2d 2 days 2991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 1w 1 week 3001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * 3011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Return -1 if time string is invalid. 3021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodlong 3041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconvtime(const char *s) 3051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood long total, secs; 3071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *p; 3081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *endp; 3091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood errno = 0; 3111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood total = 0; 3121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = s; 3131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (p == NULL || *p == '\0') 3151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (*p) { 3181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs = strtol(p, &endp, 10); 3191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (p == endp || 3201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (errno == ERANGE && (secs == LONG_MIN || secs == LONG_MAX)) || 3211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs < 0) 3221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (*endp++) { 3251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '\0': 3261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood endp--; 3271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 's': 3291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'S': 3301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'm': 3321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'M': 3331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs *= MINUTES; 3341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'h': 3361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'H': 3371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs *= HOURS; 3381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'd': 3401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'D': 3411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs *= DAYS; 3421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'w': 3441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case 'W': 3451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood secs *= WEEKS; 3461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 3471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 3481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood total += secs; 3511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (total < 0) 3521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 3531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p = endp; 3541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 3551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return total; 3571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 3601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns a standardized host+port identifier string. 3611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Caller must free returned string. 3621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 3641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodput_host_port(const char *host, u_short port) 3651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *hoststr; 3671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (port == 0 || port == SSH_DEFAULT_PORT) 3691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return(xstrdup(host)); 3701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (asprintf(&hoststr, "[%s]:%d", host, (int)port) < 0) 3711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("put_host_port: asprintf: %s", strerror(errno)); 3721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("put_host_port: %s", hoststr); 3731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return hoststr; 3741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 3751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 3771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Search for next delimiter between hostnames/addresses and ports. 3781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Argument may be modified (for termination). 3791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Returns *cp if parsing succeeds. 3801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * *cp is set to the start of the next delimiter, if one was found. 3811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * If this is the last field, *cp is set to NULL. 3821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 3831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 3841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodhpdelim(char **cp) 3851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 3861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *s, *old; 3871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cp == NULL || *cp == NULL) 3891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 3901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 3911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood old = s = *cp; 3921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*s == '[') { 3931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((s = strchr(s, ']')) == NULL) 3941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 3951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 3961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s++; 3971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if ((s = strpbrk(s, ":/")) == NULL) 3981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood s = *cp + strlen(*cp); /* skip to end (see first case below) */ 3991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood switch (*s) { 4011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '\0': 4021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cp = NULL; /* no more fields*/ 4031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case ':': 4061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood case '/': 4071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *s = '\0'; /* terminate */ 4081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *cp = s + 1; 4091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 4101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood default: 4121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 4131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return old; 4161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 4191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcleanhostname(char *host) 4201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*host == '[' && host[strlen(host) - 1] == ']') { 4221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood host[strlen(host) - 1] = '\0'; 4231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (host + 1); 4241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else 4251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return host; 4261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 4291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodcolon(char *cp) 4301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int flag = 0; 4321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == ':') /* Leading colon is part of file name. */ 4341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 4351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == '[') 4361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flag = 1; 4371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (; *cp; ++cp) { 4391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == '@' && *(cp+1) == '[') 4401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood flag = 1; 4411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == ']' && *(cp+1) == ':' && flag) 4421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (cp+1); 4431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == ':' && !flag) 4441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (cp); 4451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == '/') 4461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 4471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 4481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return NULL; 4491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* function to assist building execv() arguments */ 4521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodaddargs(arglist *args, char *fmt, ...) 4541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list ap; 4561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 4571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int nalloc; 4581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int r; 4591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_start(ap, fmt); 4611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = vasprintf(&cp, fmt, ap); 4621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_end(ap); 4631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r == -1) 4641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("addargs: argument too long"); 4651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nalloc = args->nalloc; 4671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (args->list == NULL) { 4681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nalloc = 32; 4691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->num = 0; 4701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (args->num+2 >= nalloc) 4711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood nalloc *= 2; 4721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->list = xrealloc(args->list, nalloc, sizeof(char *)); 4741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->nalloc = nalloc; 4751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->list[args->num++] = cp; 4761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->list[args->num] = NULL; 4771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 4801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodreplacearg(arglist *args, u_int which, char *fmt, ...) 4811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 4821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list ap; 4831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *cp; 4841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int r; 4851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_start(ap, fmt); 4871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = vasprintf(&cp, fmt, ap); 4881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_end(ap); 4891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r == -1) 4901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("replacearg: argument too long"); 4911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (which >= args->num) 4931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("replacearg: tried to replace invalid arg %d >= %d", 4941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood which, args->num); 4951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(args->list[which]); 4961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->list[which] = cp; 4971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 4981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 4991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 5001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodfreeargs(arglist *args) 5011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 5031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (args->list != NULL) { 5051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < args->num; i++) 5061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(args->list[i]); 5071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood xfree(args->list); 5081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->nalloc = args->num = 0; 5091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood args->list = NULL; 5101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 5141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Expands tildes in the file name. Returns data allocated by xmalloc. 5151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Warning: this calls getpw*. 5161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 5181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtilde_expand_filename(const char *filename, uid_t uid) 5191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *path; 5211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char user[128], ret[MAXPATHLEN]; 5221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct passwd *pw; 5231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int len, slash; 5241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*filename != '~') 5261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (xstrdup(filename)); 5271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename++; 5281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood path = strchr(filename, '/'); 5301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (path != NULL && path > filename) { /* ~user/path */ 5311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood slash = path - filename; 5321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (slash > sizeof(user) - 1) 5331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: ~username too long"); 5341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood memcpy(user, filename, slash); 5351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood user[slash] = '\0'; 5361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((pw = getpwnam(user)) == NULL) 5371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: No such user %s", user); 5381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */ 5391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: No such uid %ld", (long)uid); 5401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlcpy(ret, pw->pw_dir, sizeof(ret)) >= sizeof(ret)) 5421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: Path too long"); 5431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Make sure directory has a trailing '/' */ 5451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood len = strlen(pw->pw_dir); 5461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((len == 0 || pw->pw_dir[len - 1] != '/') && 5471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(ret, "/", sizeof(ret)) >= sizeof(ret)) 5481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: Path too long"); 5491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Skip leading '/' from specified path */ 5511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (path != NULL) 5521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename = path + 1; 5531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strlcat(ret, filename, sizeof(ret)) >= sizeof(ret)) 5541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("tilde_expand_filename: Path too long"); 5551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (xstrdup(ret)); 5571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 5581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 5601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Expand a string with a set of %[char] escapes. A number of escapes may be 5611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * specified as (char *escape_chars, char *replacement) pairs. The list must 5621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * be terminated by a NULL escape_char. Returns replaced string in memory 5631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * allocated by xmalloc. 5641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 5651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 5661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodpercent_expand(const char *string, ...) 5671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 5681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#define EXPAND_MAX_KEYS 16 5691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int num_keys, i, j; 5701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct { 5711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *key; 5721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *repl; 5731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } keys[EXPAND_MAX_KEYS]; 5741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char buf[4096]; 5751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_list ap; 5761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Gather keys */ 5781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_start(ap, string); 5791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) { 5801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood keys[num_keys].key = va_arg(ap, char *); 5811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (keys[num_keys].key == NULL) 5821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 5831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood keys[num_keys].repl = va_arg(ap, char *); 5841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (keys[num_keys].repl == NULL) 5851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: NULL replacement", __func__); 5861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 5871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL) 5881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: too many keys", __func__); 5891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood va_end(ap); 5901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 5911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Expand string */ 5921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *buf = '\0'; 5931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; *string != '\0'; string++) { 5941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*string != '%') { 5951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood append: 5961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[i++] = *string; 5971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i >= sizeof(buf)) 5981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: string too long", __func__); 5991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood buf[i] = '\0'; 6001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 6011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood string++; 6031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* %% case */ 6041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*string == '%') 6051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto append; 6061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (j = 0; j < num_keys; j++) { 6071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strchr(keys[j].key, *string) != NULL) { 6081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood i = strlcat(buf, keys[j].repl, sizeof(buf)); 6091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (i >= sizeof(buf)) 6101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: string too long", __func__); 6111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (j >= num_keys) 6151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: unknown key %%%c", __func__, *string); 6161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (xstrdup(buf)); 6181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#undef EXPAND_MAX_KEYS 6191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* 6221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * Read an entire line from a public key file into a static buffer, discarding 6231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood * lines that exceed the buffer size. Returns 0 on success, -1 on failure. 6241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood */ 6251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 6261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodread_keyfile_line(FILE *f, const char *filename, char *buf, size_t bufsz, 6271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_long *lineno) 6281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fgets(buf, bufsz, f) != NULL) { 6301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buf[0] == '\0') 6311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 6321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood (*lineno)++; 6331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (buf[strlen(buf) - 1] == '\n' || feof(f)) { 6341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return 0; 6351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: %s line %lu exceeds size limit", __func__, 6371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood filename, *lineno); 6381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* discard remainder of line */ 6391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (fgetc(f) != '\n' && !feof(f)) 6401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ; /* nothing */ 6411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 6441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 6451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 6471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtun_open(int tun, int mode) 6481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 6491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#if defined(CUSTOM_SYS_TUN_OPEN) 6501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (sys_tun_open(tun, mode)); 6511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#elif defined(SSH_TUN_OPENBSD) 6521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct ifreq ifr; 6531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char name[100]; 6541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int fd = -1, sock; 6551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Open the tunnel device */ 6571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (tun <= SSH_TUNID_MAX) { 6581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(name, sizeof(name), "/dev/tun%d", tun); 6591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fd = open(name, O_RDWR); 6601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (tun == SSH_TUNID_ANY) { 6611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (tun = 100; tun >= 0; tun--) { 6621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(name, sizeof(name), "/dev/tun%d", tun); 6631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((fd = open(name, O_RDWR)) >= 0) 6641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 6651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else { 6671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: invalid tunnel %u", __func__, tun); 6681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 6691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd < 0) { 6721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: %s open failed: %s", __func__, name, strerror(errno)); 6731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 6741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 6751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: %s mode %d fd %d", __func__, name, mode, fd); 6771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set the tunnel device operation mode */ 6791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "tun%d", tun); 6801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1) 6811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failed; 6821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) 6841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failed; 6851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Set interface mode */ 6871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ifr.ifr_flags &= ~IFF_UP; 6881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (mode == SSH_TUNMODE_ETHERNET) 6891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ifr.ifr_flags |= IFF_LINK0; 6901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood else 6911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ifr.ifr_flags &= ~IFF_LINK0; 6921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) 6931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failed; 6941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 6951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Bring interface up */ 6961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ifr.ifr_flags |= IFF_UP; 6971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) 6981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood goto failed; 6991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 7011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (fd); 7021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood failed: 7041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fd >= 0) 7051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(fd); 7061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (sock >= 0) 7071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(sock); 7081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug("%s: failed to set %s mode %d: %s", __func__, name, 7091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood mode, strerror(errno)); 7101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 7111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#else 7121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("Tunnel interfaces are not supported on this platform"); 7131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (-1); 7141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 7151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 7181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsanitise_stdfd(void) 7191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int nullfd, dupfd; 7211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) { 7231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "Couldn't open /dev/null: %s\n", 7241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strerror(errno)); 7251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 7261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (++dupfd <= 2) { 7281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Only clobber closed fds */ 7291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (fcntl(dupfd, F_GETFL, 0) >= 0) 7301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood continue; 7311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (dup2(nullfd, dupfd) == -1) { 7321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fprintf(stderr, "dup2: %s\n", strerror(errno)); 7331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood exit(1); 7341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (nullfd > 2) 7371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood close(nullfd); 7381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodchar * 7411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodtohex(const void *vp, size_t l) 7421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *p = (const u_char *)vp; 7441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char b[3], *r; 7451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood size_t i, hl; 7461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (l > 65536) 7481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return xstrdup("tohex: length > 65536"); 7491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood hl = l * 2 + 1; 7511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = xcalloc(1, hl); 7521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; i < l; i++) { 7531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(b, sizeof(b), "%02x", p[i]); 7541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood strlcat(r, b, hl); 7551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 7561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (r); 7571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int64_t 7601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_u64(const void *vp) 7611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *p = (const u_char *)vp; 7631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int64_t v; 7641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v = (u_int64_t)p[0] << 56; 7661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[1] << 48; 7671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[2] << 40; 7681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[3] << 32; 7691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[4] << 24; 7701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[5] << 16; 7711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[6] << 8; 7721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int64_t)p[7]; 7731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (v); 7751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int32_t 7781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_u32(const void *vp) 7791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *p = (const u_char *)vp; 7811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int32_t v; 7821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v = (u_int32_t)p[0] << 24; 7841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int32_t)p[1] << 16; 7851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int32_t)p[2] << 8; 7861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int32_t)p[3]; 7871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (v); 7891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 7901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodu_int16_t 7921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodget_u16(const void *vp) 7931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 7941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const u_char *p = (const u_char *)vp; 7951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int16_t v; 7961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 7971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v = (u_int16_t)p[0] << 8; 7981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood v |= (u_int16_t)p[1]; 7991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return (v); 8011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodput_u64(void *vp, u_int64_t v) 8051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *p = (u_char *)vp; 8071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[0] = (u_char)(v >> 56) & 0xff; 8091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[1] = (u_char)(v >> 48) & 0xff; 8101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[2] = (u_char)(v >> 40) & 0xff; 8111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[3] = (u_char)(v >> 32) & 0xff; 8121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[4] = (u_char)(v >> 24) & 0xff; 8131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[5] = (u_char)(v >> 16) & 0xff; 8141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[6] = (u_char)(v >> 8) & 0xff; 8151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[7] = (u_char)v & 0xff; 8161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodput_u32(void *vp, u_int32_t v) 8201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *p = (u_char *)vp; 8221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[0] = (u_char)(v >> 24) & 0xff; 8241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[1] = (u_char)(v >> 16) & 0xff; 8251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[2] = (u_char)(v >> 8) & 0xff; 8261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[3] = (u_char)v & 0xff; 8271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodput_u16(void *vp, u_int16_t v) 8321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_char *p = (u_char *)vp; 8341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[0] = (u_char)(v >> 8) & 0xff; 8361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood p[1] = (u_char)v & 0xff; 8371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodms_subtract_diff(struct timeval *start, int *ms) 8411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timeval diff, finish; 8431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gettimeofday(&finish, NULL); 8451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timersub(&finish, start, &diff); 8461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000); 8471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodms_to_timeval(struct timeval *tv, int ms) 8511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ms < 0) 8531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ms = 0; 8541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv->tv_sec = ms / 1000; 8551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood tv->tv_usec = (ms % 1000) * 1000; 8561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodbandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen) 8601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->buflen = buflen; 8621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->rate = kbps; 8631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->thresh = bw->rate; 8641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->lamt = 0; 8651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timerclear(&bw->bwstart); 8661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timerclear(&bw->bwend); 8671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 8681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Callback from read/write loop to insert bandwidth-limiting delays */ 8701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 8711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodbandwidth_limit(struct bwlimit *bw, size_t read_len) 8721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 8731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int64_t waitlen; 8741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood struct timespec ts, rm; 8751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!timerisset(&bw->bwstart)) { 8771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gettimeofday(&bw->bwstart, NULL); 8781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 8801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->lamt += read_len; 8821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bw->lamt < bw->thresh) 8831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gettimeofday(&bw->bwend, NULL); 8861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timersub(&bw->bwend, &bw->bwstart, &bw->bwend); 8871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (!timerisset(&bw->bwend)) 8881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 8891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->lamt *= 8; 8911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood waitlen = (double)1000000L * bw->lamt / bw->rate; 8921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->bwstart.tv_sec = waitlen / 1000000L; 8941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->bwstart.tv_usec = waitlen % 1000000L; 8951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (timercmp(&bw->bwstart, &bw->bwend, >)) { 8971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood timersub(&bw->bwstart, &bw->bwend, &bw->bwend); 8981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 8991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Adjust the wait time */ 9001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bw->bwend.tv_sec) { 9011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->thresh /= 2; 9021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bw->thresh < bw->buflen / 4) 9031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->thresh = bw->buflen / 4; 9041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } else if (bw->bwend.tv_usec < 10000) { 9051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->thresh *= 2; 9061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (bw->thresh > bw->buflen * 8) 9071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->thresh = bw->buflen * 8; 9081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts); 9111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood while (nanosleep(&ts, &rm) == -1) { 9121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (errno != EINTR) 9131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood break; 9141305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood ts = rm; 9151305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9161305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9171305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9181305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood bw->lamt = 0; 9191305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood gettimeofday(&bw->bwstart, NULL); 9201305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9211305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9221305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood/* Make a template filename for mk[sd]temp() */ 9231305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 9241305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodmktemp_proto(char *s, size_t len) 9251305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9261305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *tmpdir; 9271305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int r; 9281305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9291305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if ((tmpdir = getenv("TMPDIR")) != NULL) { 9301305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir); 9311305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r > 0 && (size_t)r < len) 9321305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return; 9331305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9341305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX"); 9351305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (r < 0 || (size_t)r >= len) 9361305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood fatal("%s: template string too short", __func__); 9371305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9381305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9391305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodstatic const struct { 9401305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood const char *name; 9411305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int value; 9421305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} ipqos[] = { 9431305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af11", IPTOS_DSCP_AF11 }, 9441305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af12", IPTOS_DSCP_AF12 }, 9451305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af13", IPTOS_DSCP_AF13 }, 9461305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af14", IPTOS_DSCP_AF21 }, 9471305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af22", IPTOS_DSCP_AF22 }, 9481305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af23", IPTOS_DSCP_AF23 }, 9491305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af31", IPTOS_DSCP_AF31 }, 9501305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af32", IPTOS_DSCP_AF32 }, 9511305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af33", IPTOS_DSCP_AF33 }, 9521305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af41", IPTOS_DSCP_AF41 }, 9531305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af42", IPTOS_DSCP_AF42 }, 9541305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "af43", IPTOS_DSCP_AF43 }, 9551305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs0", IPTOS_DSCP_CS0 }, 9561305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs1", IPTOS_DSCP_CS1 }, 9571305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs2", IPTOS_DSCP_CS2 }, 9581305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs3", IPTOS_DSCP_CS3 }, 9591305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs4", IPTOS_DSCP_CS4 }, 9601305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs5", IPTOS_DSCP_CS5 }, 9611305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs6", IPTOS_DSCP_CS6 }, 9621305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "cs7", IPTOS_DSCP_CS7 }, 9631305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "ef", IPTOS_DSCP_EF }, 9641305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "lowdelay", IPTOS_LOWDELAY }, 9651305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "throughput", IPTOS_THROUGHPUT }, 9661305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { "reliability", IPTOS_RELIABILITY }, 9671305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood { NULL, -1 } 9681305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood}; 9691305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9701305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodint 9711305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodparse_ipqos(const char *cp) 9721305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9731305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood u_int i; 9741305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood char *ep; 9751305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood long val; 9761305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9771305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (cp == NULL) 9781305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 9791305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; ipqos[i].name != NULL; i++) { 9801305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (strcasecmp(cp, ipqos[i].name) == 0) 9811305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ipqos[i].value; 9821305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 9831305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood /* Try parsing as an integer */ 9841305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood val = strtol(cp, &ep, 0); 9851305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255) 9861305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return -1; 9871305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return val; 9881305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 9891305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9901305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodconst char * 9911305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodiptos2str(int iptos) 9921305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 9931305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int i; 9941305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood static char iptos_str[sizeof "0xff"]; 9951305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 9961305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood for (i = 0; ipqos[i].name != NULL; i++) { 9971305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (ipqos[i].value == iptos) 9981305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return ipqos[i].name; 9991305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood } 10001305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos); 10011305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood return iptos_str; 10021305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 10031305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodvoid 10041305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwoodsock_set_v6only(int s) 10051305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood{ 10061305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#ifdef IPV6_V6ONLY 10071305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood int on = 1; 10081305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood 10091305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood debug3("%s: set socket %d IPV6_V6ONLY", __func__, s); 10101305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1) 10111305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood error("setsockopt IPV6_V6ONLY: %s", strerror(errno)); 10121305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood#endif 10131305e95ba6ff9fa202d0818caf10405df4b0f648Mike Lockwood} 1014