misc.c 57 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276127712781279128012811282128312841285128612871288128912901291129212931294129512961297129812991300130113021303130413051306130713081309131013111312131313141315131613171318131913201321132213231324132513261327132813291330133113321333133413351336133713381339134013411342134313441345134613471348134913501351135213531354135513561357135813591360136113621363136413651366136713681369137013711372137313741375137613771378137913801381138213831384138513861387138813891390139113921393139413951396139713981399140014011402140314041405140614071408140914101411141214131414141514161417141814191420142114221423142414251426142714281429143014311432143314341435143614371438143914401441144214431444144514461447144814491450145114521453145414551456145714581459146014611462146314641465146614671468146914701471147214731474147514761477147814791480148114821483148414851486148714881489149014911492149314941495149614971498149915001501150215031504150515061507150815091510151115121513151415151516151715181519152015211522152315241525152615271528152915301531153215331534153515361537153815391540154115421543154415451546154715481549155015511552155315541555155615571558155915601561156215631564156515661567156815691570157115721573157415751576157715781579158015811582158315841585158615871588158915901591159215931594159515961597159815991600160116021603160416051606160716081609161016111612161316141615161616171618161916201621162216231624162516261627162816291630163116321633163416351636163716381639164016411642164316441645164616471648164916501651165216531654165516561657165816591660166116621663166416651666166716681669167016711672167316741675167616771678167916801681168216831684168516861687168816891690169116921693169416951696169716981699170017011702170317041705170617071708170917101711171217131714171517161717171817191720172117221723172417251726172717281729173017311732173317341735173617371738173917401741174217431744174517461747174817491750175117521753175417551756175717581759176017611762176317641765176617671768176917701771177217731774177517761777177817791780178117821783178417851786178717881789179017911792179317941795179617971798179918001801180218031804180518061807180818091810181118121813181418151816181718181819182018211822182318241825182618271828182918301831183218331834183518361837183818391840184118421843184418451846184718481849185018511852185318541855185618571858185918601861186218631864186518661867186818691870187118721873187418751876187718781879188018811882188318841885188618871888188918901891189218931894189518961897189818991900190119021903190419051906190719081909191019111912191319141915191619171918191919201921192219231924192519261927192819291930193119321933193419351936193719381939194019411942194319441945194619471948194919501951195219531954195519561957195819591960196119621963196419651966196719681969197019711972197319741975197619771978197919801981198219831984198519861987198819891990199119921993199419951996199719981999200020012002200320042005200620072008200920102011201220132014201520162017201820192020202120222023202420252026202720282029203020312032203320342035203620372038203920402041204220432044204520462047204820492050205120522053205420552056205720582059206020612062206320642065206620672068206920702071207220732074207520762077207820792080208120822083208420852086208720882089209020912092209320942095209620972098209921002101210221032104210521062107210821092110211121122113211421152116211721182119212021212122212321242125212621272128212921302131213221332134213521362137213821392140214121422143214421452146214721482149215021512152215321542155215621572158215921602161216221632164216521662167216821692170217121722173217421752176217721782179218021812182218321842185218621872188218921902191219221932194219521962197219821992200220122022203220422052206220722082209221022112212221322142215221622172218221922202221222222232224222522262227222822292230223122322233223422352236223722382239224022412242224322442245224622472248224922502251225222532254225522562257225822592260226122622263226422652266226722682269227022712272227322742275227622772278227922802281228222832284228522862287228822892290229122922293229422952296229722982299230023012302230323042305230623072308230923102311231223132314231523162317231823192320232123222323232423252326232723282329233023312332233323342335233623372338233923402341234223432344234523462347234823492350235123522353235423552356235723582359236023612362236323642365236623672368236923702371237223732374237523762377237823792380238123822383238423852386238723882389239023912392239323942395239623972398239924002401240224032404240524062407240824092410241124122413241424152416241724182419242024212422242324242425242624272428242924302431243224332434243524362437243824392440244124422443244424452446244724482449245024512452245324542455245624572458245924602461246224632464246524662467246824692470247124722473247424752476247724782479248024812482248324842485248624872488248924902491249224932494249524962497249824992500250125022503250425052506250725082509251025112512251325142515251625172518251925202521252225232524252525262527252825292530253125322533253425352536253725382539254025412542254325442545254625472548254925502551255225532554255525562557255825592560256125622563256425652566256725682569257025712572257325742575257625772578257925802581258225832584258525862587258825892590259125922593259425952596259725982599260026012602260326042605260626072608260926102611261226132614261526162617261826192620262126222623262426252626262726282629263026312632263326342635263626372638263926402641
  1. /* $OpenBSD: misc.c,v 1.153 2020/06/26 05:16:38 djm Exp $ */
  2. /*
  3. * Copyright (c) 2000 Markus Friedl. All rights reserved.
  4. * Copyright (c) 2005-2020 Damien Miller. All rights reserved.
  5. * Copyright (c) 2004 Henning Brauer <henning@openbsd.org>
  6. *
  7. * Permission to use, copy, modify, and distribute this software for any
  8. * purpose with or without fee is hereby granted, provided that the above
  9. * copyright notice and this permission notice appear in all copies.
  10. *
  11. * THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
  12. * WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
  13. * MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
  14. * ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
  15. * WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
  16. * ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
  17. * OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
  18. */
  19. #include "includes.h"
  20. #include <sys/types.h>
  21. #include <sys/ioctl.h>
  22. #include <sys/socket.h>
  23. #include <sys/stat.h>
  24. #include <sys/time.h>
  25. #include <sys/wait.h>
  26. #include <sys/un.h>
  27. #include <limits.h>
  28. #ifdef HAVE_LIBGEN_H
  29. # include <libgen.h>
  30. #endif
  31. #ifdef HAVE_POLL_H
  32. #include <poll.h>
  33. #endif
  34. #include <signal.h>
  35. #include <stdarg.h>
  36. #include <stdio.h>
  37. #include <stdlib.h>
  38. #include <string.h>
  39. #include <time.h>
  40. #include <unistd.h>
  41. #include <netinet/in.h>
  42. #include <netinet/in_systm.h>
  43. #include <netinet/ip.h>
  44. #include <netinet/tcp.h>
  45. #include <arpa/inet.h>
  46. #include <ctype.h>
  47. #include <errno.h>
  48. #include <fcntl.h>
  49. #include <netdb.h>
  50. #ifdef HAVE_PATHS_H
  51. # include <paths.h>
  52. #include <pwd.h>
  53. #endif
  54. #ifdef SSH_TUN_OPENBSD
  55. #include <net/if.h>
  56. #endif
  57. #include "xmalloc.h"
  58. #include "misc.h"
  59. #include "log.h"
  60. #include "ssh.h"
  61. #include "sshbuf.h"
  62. #include "ssherr.h"
  63. #include "platform.h"
  64. /* remove newline at end of string */
  65. char *
  66. chop(char *s)
  67. {
  68. char *t = s;
  69. while (*t) {
  70. if (*t == '\n' || *t == '\r') {
  71. *t = '\0';
  72. return s;
  73. }
  74. t++;
  75. }
  76. return s;
  77. }
  78. /* set/unset filedescriptor to non-blocking */
  79. int
  80. set_nonblock(int fd)
  81. {
  82. int val;
  83. val = fcntl(fd, F_GETFL);
  84. if (val == -1) {
  85. error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
  86. return (-1);
  87. }
  88. if (val & O_NONBLOCK) {
  89. debug3("fd %d is O_NONBLOCK", fd);
  90. return (0);
  91. }
  92. debug2("fd %d setting O_NONBLOCK", fd);
  93. val |= O_NONBLOCK;
  94. if (fcntl(fd, F_SETFL, val) == -1) {
  95. debug("fcntl(%d, F_SETFL, O_NONBLOCK): %s", fd,
  96. strerror(errno));
  97. return (-1);
  98. }
  99. return (0);
  100. }
  101. int
  102. unset_nonblock(int fd)
  103. {
  104. int val;
  105. val = fcntl(fd, F_GETFL);
  106. if (val == -1) {
  107. error("fcntl(%d, F_GETFL): %s", fd, strerror(errno));
  108. return (-1);
  109. }
  110. if (!(val & O_NONBLOCK)) {
  111. debug3("fd %d is not O_NONBLOCK", fd);
  112. return (0);
  113. }
  114. debug("fd %d clearing O_NONBLOCK", fd);
  115. val &= ~O_NONBLOCK;
  116. if (fcntl(fd, F_SETFL, val) == -1) {
  117. debug("fcntl(%d, F_SETFL, ~O_NONBLOCK): %s",
  118. fd, strerror(errno));
  119. return (-1);
  120. }
  121. return (0);
  122. }
  123. const char *
  124. ssh_gai_strerror(int gaierr)
  125. {
  126. if (gaierr == EAI_SYSTEM && errno != 0)
  127. return strerror(errno);
  128. return gai_strerror(gaierr);
  129. }
  130. /* disable nagle on socket */
  131. void
  132. set_nodelay(int fd)
  133. {
  134. int opt;
  135. socklen_t optlen;
  136. optlen = sizeof opt;
  137. if (getsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, &optlen) == -1) {
  138. debug("getsockopt TCP_NODELAY: %.100s", strerror(errno));
  139. return;
  140. }
  141. if (opt == 1) {
  142. debug2("fd %d is TCP_NODELAY", fd);
  143. return;
  144. }
  145. opt = 1;
  146. debug2("fd %d setting TCP_NODELAY", fd);
  147. if (setsockopt(fd, IPPROTO_TCP, TCP_NODELAY, &opt, sizeof opt) == -1)
  148. debug("setsockopt TCP_NODELAY: %.100s", strerror(errno));
  149. }
  150. /* Allow local port reuse in TIME_WAIT */
  151. int
  152. set_reuseaddr(int fd)
  153. {
  154. int on = 1;
  155. if (setsockopt(fd, SOL_SOCKET, SO_REUSEADDR, &on, sizeof(on)) == -1) {
  156. error("setsockopt SO_REUSEADDR fd %d: %s", fd, strerror(errno));
  157. return -1;
  158. }
  159. return 0;
  160. }
  161. /* Get/set routing domain */
  162. char *
  163. get_rdomain(int fd)
  164. {
  165. #if defined(HAVE_SYS_GET_RDOMAIN)
  166. return sys_get_rdomain(fd);
  167. #elif defined(__OpenBSD__)
  168. int rtable;
  169. char *ret;
  170. socklen_t len = sizeof(rtable);
  171. if (getsockopt(fd, SOL_SOCKET, SO_RTABLE, &rtable, &len) == -1) {
  172. error("Failed to get routing domain for fd %d: %s",
  173. fd, strerror(errno));
  174. return NULL;
  175. }
  176. xasprintf(&ret, "%d", rtable);
  177. return ret;
  178. #else /* defined(__OpenBSD__) */
  179. return NULL;
  180. #endif
  181. }
  182. int
  183. set_rdomain(int fd, const char *name)
  184. {
  185. #if defined(HAVE_SYS_SET_RDOMAIN)
  186. return sys_set_rdomain(fd, name);
  187. #elif defined(__OpenBSD__)
  188. int rtable;
  189. const char *errstr;
  190. if (name == NULL)
  191. return 0; /* default table */
  192. rtable = (int)strtonum(name, 0, 255, &errstr);
  193. if (errstr != NULL) {
  194. /* Shouldn't happen */
  195. error("Invalid routing domain \"%s\": %s", name, errstr);
  196. return -1;
  197. }
  198. if (setsockopt(fd, SOL_SOCKET, SO_RTABLE,
  199. &rtable, sizeof(rtable)) == -1) {
  200. error("Failed to set routing domain %d on fd %d: %s",
  201. rtable, fd, strerror(errno));
  202. return -1;
  203. }
  204. return 0;
  205. #else /* defined(__OpenBSD__) */
  206. error("Setting routing domain is not supported on this platform");
  207. return -1;
  208. #endif
  209. }
  210. /*
  211. * Wait up to *timeoutp milliseconds for events on fd. Updates
  212. * *timeoutp with time remaining.
  213. * Returns 0 if fd ready or -1 on timeout or error (see errno).
  214. */
  215. static int
  216. waitfd(int fd, int *timeoutp, short events)
  217. {
  218. struct pollfd pfd;
  219. struct timeval t_start;
  220. int oerrno, r;
  221. pfd.fd = fd;
  222. pfd.events = events;
  223. for (; *timeoutp >= 0;) {
  224. monotime_tv(&t_start);
  225. r = poll(&pfd, 1, *timeoutp);
  226. oerrno = errno;
  227. ms_subtract_diff(&t_start, timeoutp);
  228. errno = oerrno;
  229. if (r > 0)
  230. return 0;
  231. else if (r == -1 && errno != EAGAIN && errno != EINTR)
  232. return -1;
  233. else if (r == 0)
  234. break;
  235. }
  236. /* timeout */
  237. errno = ETIMEDOUT;
  238. return -1;
  239. }
  240. /*
  241. * Wait up to *timeoutp milliseconds for fd to be readable. Updates
  242. * *timeoutp with time remaining.
  243. * Returns 0 if fd ready or -1 on timeout or error (see errno).
  244. */
  245. int
  246. waitrfd(int fd, int *timeoutp) {
  247. return waitfd(fd, timeoutp, POLLIN);
  248. }
  249. /*
  250. * Attempt a non-blocking connect(2) to the specified address, waiting up to
  251. * *timeoutp milliseconds for the connection to complete. If the timeout is
  252. * <=0, then wait indefinitely.
  253. *
  254. * Returns 0 on success or -1 on failure.
  255. */
  256. int
  257. timeout_connect(int sockfd, const struct sockaddr *serv_addr,
  258. socklen_t addrlen, int *timeoutp)
  259. {
  260. int optval = 0;
  261. socklen_t optlen = sizeof(optval);
  262. /* No timeout: just do a blocking connect() */
  263. if (timeoutp == NULL || *timeoutp <= 0)
  264. return connect(sockfd, serv_addr, addrlen);
  265. set_nonblock(sockfd);
  266. for (;;) {
  267. if (connect(sockfd, serv_addr, addrlen) == 0) {
  268. /* Succeeded already? */
  269. unset_nonblock(sockfd);
  270. return 0;
  271. } else if (errno == EINTR)
  272. continue;
  273. else if (errno != EINPROGRESS)
  274. return -1;
  275. break;
  276. }
  277. if (waitfd(sockfd, timeoutp, POLLIN | POLLOUT) == -1)
  278. return -1;
  279. /* Completed or failed */
  280. if (getsockopt(sockfd, SOL_SOCKET, SO_ERROR, &optval, &optlen) == -1) {
  281. debug("getsockopt: %s", strerror(errno));
  282. return -1;
  283. }
  284. if (optval != 0) {
  285. errno = optval;
  286. return -1;
  287. }
  288. unset_nonblock(sockfd);
  289. return 0;
  290. }
  291. /* Characters considered whitespace in strsep calls. */
  292. #define WHITESPACE " \t\r\n"
  293. #define QUOTE "\""
  294. /* return next token in configuration line */
  295. static char *
  296. strdelim_internal(char **s, int split_equals)
  297. {
  298. char *old;
  299. int wspace = 0;
  300. if (*s == NULL)
  301. return NULL;
  302. old = *s;
  303. *s = strpbrk(*s,
  304. split_equals ? WHITESPACE QUOTE "=" : WHITESPACE QUOTE);
  305. if (*s == NULL)
  306. return (old);
  307. if (*s[0] == '\"') {
  308. memmove(*s, *s + 1, strlen(*s)); /* move nul too */
  309. /* Find matching quote */
  310. if ((*s = strpbrk(*s, QUOTE)) == NULL) {
  311. return (NULL); /* no matching quote */
  312. } else {
  313. *s[0] = '\0';
  314. *s += strspn(*s + 1, WHITESPACE) + 1;
  315. return (old);
  316. }
  317. }
  318. /* Allow only one '=' to be skipped */
  319. if (split_equals && *s[0] == '=')
  320. wspace = 1;
  321. *s[0] = '\0';
  322. /* Skip any extra whitespace after first token */
  323. *s += strspn(*s + 1, WHITESPACE) + 1;
  324. if (split_equals && *s[0] == '=' && !wspace)
  325. *s += strspn(*s + 1, WHITESPACE) + 1;
  326. return (old);
  327. }
  328. /*
  329. * Return next token in configuration line; splts on whitespace or a
  330. * single '=' character.
  331. */
  332. char *
  333. strdelim(char **s)
  334. {
  335. return strdelim_internal(s, 1);
  336. }
  337. /*
  338. * Return next token in configuration line; splts on whitespace only.
  339. */
  340. char *
  341. strdelimw(char **s)
  342. {
  343. return strdelim_internal(s, 0);
  344. }
  345. struct passwd *
  346. pwcopy(struct passwd *pw)
  347. {
  348. struct passwd *copy = xcalloc(1, sizeof(*copy));
  349. copy->pw_name = xstrdup(pw->pw_name);
  350. copy->pw_passwd = xstrdup(pw->pw_passwd);
  351. #ifdef HAVE_STRUCT_PASSWD_PW_GECOS
  352. copy->pw_gecos = xstrdup(pw->pw_gecos);
  353. #endif
  354. copy->pw_uid = pw->pw_uid;
  355. copy->pw_gid = pw->pw_gid;
  356. #ifdef HAVE_STRUCT_PASSWD_PW_EXPIRE
  357. copy->pw_expire = pw->pw_expire;
  358. #endif
  359. #ifdef HAVE_STRUCT_PASSWD_PW_CHANGE
  360. copy->pw_change = pw->pw_change;
  361. #endif
  362. #ifdef HAVE_STRUCT_PASSWD_PW_CLASS
  363. copy->pw_class = xstrdup(pw->pw_class);
  364. #endif
  365. copy->pw_dir = xstrdup(pw->pw_dir);
  366. copy->pw_shell = xstrdup(pw->pw_shell);
  367. return copy;
  368. }
  369. /*
  370. * Convert ASCII string to TCP/IP port number.
  371. * Port must be >=0 and <=65535.
  372. * Return -1 if invalid.
  373. */
  374. int
  375. a2port(const char *s)
  376. {
  377. struct servent *se;
  378. long long port;
  379. const char *errstr;
  380. port = strtonum(s, 0, 65535, &errstr);
  381. if (errstr == NULL)
  382. return (int)port;
  383. if ((se = getservbyname(s, "tcp")) != NULL)
  384. return ntohs(se->s_port);
  385. return -1;
  386. }
  387. int
  388. a2tun(const char *s, int *remote)
  389. {
  390. const char *errstr = NULL;
  391. char *sp, *ep;
  392. int tun;
  393. if (remote != NULL) {
  394. *remote = SSH_TUNID_ANY;
  395. sp = xstrdup(s);
  396. if ((ep = strchr(sp, ':')) == NULL) {
  397. free(sp);
  398. return (a2tun(s, NULL));
  399. }
  400. ep[0] = '\0'; ep++;
  401. *remote = a2tun(ep, NULL);
  402. tun = a2tun(sp, NULL);
  403. free(sp);
  404. return (*remote == SSH_TUNID_ERR ? *remote : tun);
  405. }
  406. if (strcasecmp(s, "any") == 0)
  407. return (SSH_TUNID_ANY);
  408. tun = strtonum(s, 0, SSH_TUNID_MAX, &errstr);
  409. if (errstr != NULL)
  410. return (SSH_TUNID_ERR);
  411. return (tun);
  412. }
  413. #define SECONDS 1
  414. #define MINUTES (SECONDS * 60)
  415. #define HOURS (MINUTES * 60)
  416. #define DAYS (HOURS * 24)
  417. #define WEEKS (DAYS * 7)
  418. /*
  419. * Convert a time string into seconds; format is
  420. * a sequence of:
  421. * time[qualifier]
  422. *
  423. * Valid time qualifiers are:
  424. * <none> seconds
  425. * s|S seconds
  426. * m|M minutes
  427. * h|H hours
  428. * d|D days
  429. * w|W weeks
  430. *
  431. * Examples:
  432. * 90m 90 minutes
  433. * 1h30m 90 minutes
  434. * 2d 2 days
  435. * 1w 1 week
  436. *
  437. * Return -1 if time string is invalid.
  438. */
  439. int
  440. convtime(const char *s)
  441. {
  442. long total, secs, multiplier;
  443. const char *p;
  444. char *endp;
  445. errno = 0;
  446. total = 0;
  447. p = s;
  448. if (p == NULL || *p == '\0')
  449. return -1;
  450. while (*p) {
  451. secs = strtol(p, &endp, 10);
  452. if (p == endp ||
  453. (errno == ERANGE && (secs == INT_MIN || secs == INT_MAX)) ||
  454. secs < 0)
  455. return -1;
  456. multiplier = 1;
  457. switch (*endp++) {
  458. case '\0':
  459. endp--;
  460. break;
  461. case 's':
  462. case 'S':
  463. break;
  464. case 'm':
  465. case 'M':
  466. multiplier = MINUTES;
  467. break;
  468. case 'h':
  469. case 'H':
  470. multiplier = HOURS;
  471. break;
  472. case 'd':
  473. case 'D':
  474. multiplier = DAYS;
  475. break;
  476. case 'w':
  477. case 'W':
  478. multiplier = WEEKS;
  479. break;
  480. default:
  481. return -1;
  482. }
  483. if (secs > INT_MAX / multiplier)
  484. return -1;
  485. secs *= multiplier;
  486. if (total > INT_MAX - secs)
  487. return -1;
  488. total += secs;
  489. if (total < 0)
  490. return -1;
  491. p = endp;
  492. }
  493. return total;
  494. }
  495. #define TF_BUFS 8
  496. #define TF_LEN 9
  497. const char *
  498. fmt_timeframe(time_t t)
  499. {
  500. char *buf;
  501. static char tfbuf[TF_BUFS][TF_LEN]; /* ring buffer */
  502. static int idx = 0;
  503. unsigned int sec, min, hrs, day;
  504. unsigned long long week;
  505. buf = tfbuf[idx++];
  506. if (idx == TF_BUFS)
  507. idx = 0;
  508. week = t;
  509. sec = week % 60;
  510. week /= 60;
  511. min = week % 60;
  512. week /= 60;
  513. hrs = week % 24;
  514. week /= 24;
  515. day = week % 7;
  516. week /= 7;
  517. if (week > 0)
  518. snprintf(buf, TF_LEN, "%02lluw%01ud%02uh", week, day, hrs);
  519. else if (day > 0)
  520. snprintf(buf, TF_LEN, "%01ud%02uh%02um", day, hrs, min);
  521. else
  522. snprintf(buf, TF_LEN, "%02u:%02u:%02u", hrs, min, sec);
  523. return (buf);
  524. }
  525. /*
  526. * Returns a standardized host+port identifier string.
  527. * Caller must free returned string.
  528. */
  529. char *
  530. put_host_port(const char *host, u_short port)
  531. {
  532. char *hoststr;
  533. if (port == 0 || port == SSH_DEFAULT_PORT)
  534. return(xstrdup(host));
  535. if (asprintf(&hoststr, "[%s]:%d", host, (int)port) == -1)
  536. fatal("put_host_port: asprintf: %s", strerror(errno));
  537. debug3("put_host_port: %s", hoststr);
  538. return hoststr;
  539. }
  540. /*
  541. * Search for next delimiter between hostnames/addresses and ports.
  542. * Argument may be modified (for termination).
  543. * Returns *cp if parsing succeeds.
  544. * *cp is set to the start of the next field, if one was found.
  545. * The delimiter char, if present, is stored in delim.
  546. * If this is the last field, *cp is set to NULL.
  547. */
  548. char *
  549. hpdelim2(char **cp, char *delim)
  550. {
  551. char *s, *old;
  552. if (cp == NULL || *cp == NULL)
  553. return NULL;
  554. old = s = *cp;
  555. if (*s == '[') {
  556. if ((s = strchr(s, ']')) == NULL)
  557. return NULL;
  558. else
  559. s++;
  560. } else if ((s = strpbrk(s, ":/")) == NULL)
  561. s = *cp + strlen(*cp); /* skip to end (see first case below) */
  562. switch (*s) {
  563. case '\0':
  564. *cp = NULL; /* no more fields*/
  565. break;
  566. case ':':
  567. case '/':
  568. if (delim != NULL)
  569. *delim = *s;
  570. *s = '\0'; /* terminate */
  571. *cp = s + 1;
  572. break;
  573. default:
  574. return NULL;
  575. }
  576. return old;
  577. }
  578. char *
  579. hpdelim(char **cp)
  580. {
  581. return hpdelim2(cp, NULL);
  582. }
  583. char *
  584. cleanhostname(char *host)
  585. {
  586. if (*host == '[' && host[strlen(host) - 1] == ']') {
  587. host[strlen(host) - 1] = '\0';
  588. return (host + 1);
  589. } else
  590. return host;
  591. }
  592. char *
  593. colon(char *cp)
  594. {
  595. int flag = 0;
  596. int start = 1;
  597. if (*cp == ':') /* Leading colon is part of file name. */
  598. return NULL;
  599. if (*cp == '[')
  600. flag = 1;
  601. for (; *cp; ++cp) {
  602. if (*cp == '@' && *(cp+1) == '[')
  603. flag = 1;
  604. if (*cp == ']' && *(cp+1) == ':' && flag)
  605. return (cp+1);
  606. if (*cp == ']' && *(cp+1) == '\0' && flag)
  607. return (cp+1);
  608. if (*cp == ':' && !flag)
  609. return (cp);
  610. if (*cp == '/')
  611. return NULL;
  612. if (start) {
  613. /* Slash on beginning or after dots only denotes file name. */
  614. if (*cp == '/')
  615. return (0);
  616. if (*cp != '.')
  617. start = 0;
  618. }
  619. }
  620. return NULL;
  621. }
  622. /*
  623. * Parse a [user@]host:[path] string.
  624. * Caller must free returned user, host and path.
  625. * Any of the pointer return arguments may be NULL (useful for syntax checking).
  626. * If user was not specified then *userp will be set to NULL.
  627. * If host was not specified then *hostp will be set to NULL.
  628. * If path was not specified then *pathp will be set to ".".
  629. * Returns 0 on success, -1 on failure.
  630. */
  631. int
  632. parse_user_host_path(const char *s, char **userp, char **hostp, char **pathp)
  633. {
  634. char *user = NULL, *host = NULL, *path = NULL;
  635. char *sdup, *tmp;
  636. int ret = -1;
  637. if (userp != NULL)
  638. *userp = NULL;
  639. if (hostp != NULL)
  640. *hostp = NULL;
  641. if (pathp != NULL)
  642. *pathp = NULL;
  643. sdup = xstrdup(s);
  644. /* Check for remote syntax: [user@]host:[path] */
  645. if ((tmp = colon(sdup)) == NULL)
  646. goto out;
  647. /* Extract optional path */
  648. *tmp++ = '\0';
  649. if (*tmp == '\0')
  650. tmp = ".";
  651. path = xstrdup(tmp);
  652. /* Extract optional user and mandatory host */
  653. tmp = strrchr(sdup, '@');
  654. if (tmp != NULL) {
  655. *tmp++ = '\0';
  656. host = xstrdup(cleanhostname(tmp));
  657. if (*sdup != '\0')
  658. user = xstrdup(sdup);
  659. } else {
  660. host = xstrdup(cleanhostname(sdup));
  661. user = NULL;
  662. }
  663. /* Success */
  664. if (userp != NULL) {
  665. *userp = user;
  666. user = NULL;
  667. }
  668. if (hostp != NULL) {
  669. *hostp = host;
  670. host = NULL;
  671. }
  672. if (pathp != NULL) {
  673. *pathp = path;
  674. path = NULL;
  675. }
  676. ret = 0;
  677. out:
  678. free(sdup);
  679. free(user);
  680. free(host);
  681. free(path);
  682. return ret;
  683. }
  684. /*
  685. * Parse a [user@]host[:port] string.
  686. * Caller must free returned user and host.
  687. * Any of the pointer return arguments may be NULL (useful for syntax checking).
  688. * If user was not specified then *userp will be set to NULL.
  689. * If port was not specified then *portp will be -1.
  690. * Returns 0 on success, -1 on failure.
  691. */
  692. int
  693. parse_user_host_port(const char *s, char **userp, char **hostp, int *portp)
  694. {
  695. char *sdup, *cp, *tmp;
  696. char *user = NULL, *host = NULL;
  697. int port = -1, ret = -1;
  698. if (userp != NULL)
  699. *userp = NULL;
  700. if (hostp != NULL)
  701. *hostp = NULL;
  702. if (portp != NULL)
  703. *portp = -1;
  704. if ((sdup = tmp = strdup(s)) == NULL)
  705. return -1;
  706. /* Extract optional username */
  707. if ((cp = strrchr(tmp, '@')) != NULL) {
  708. *cp = '\0';
  709. if (*tmp == '\0')
  710. goto out;
  711. if ((user = strdup(tmp)) == NULL)
  712. goto out;
  713. tmp = cp + 1;
  714. }
  715. /* Extract mandatory hostname */
  716. if ((cp = hpdelim(&tmp)) == NULL || *cp == '\0')
  717. goto out;
  718. host = xstrdup(cleanhostname(cp));
  719. /* Convert and verify optional port */
  720. if (tmp != NULL && *tmp != '\0') {
  721. if ((port = a2port(tmp)) <= 0)
  722. goto out;
  723. }
  724. /* Success */
  725. if (userp != NULL) {
  726. *userp = user;
  727. user = NULL;
  728. }
  729. if (hostp != NULL) {
  730. *hostp = host;
  731. host = NULL;
  732. }
  733. if (portp != NULL)
  734. *portp = port;
  735. ret = 0;
  736. out:
  737. free(sdup);
  738. free(user);
  739. free(host);
  740. return ret;
  741. }
  742. /*
  743. * Converts a two-byte hex string to decimal.
  744. * Returns the decimal value or -1 for invalid input.
  745. */
  746. static int
  747. hexchar(const char *s)
  748. {
  749. unsigned char result[2];
  750. int i;
  751. for (i = 0; i < 2; i++) {
  752. if (s[i] >= '0' && s[i] <= '9')
  753. result[i] = (unsigned char)(s[i] - '0');
  754. else if (s[i] >= 'a' && s[i] <= 'f')
  755. result[i] = (unsigned char)(s[i] - 'a') + 10;
  756. else if (s[i] >= 'A' && s[i] <= 'F')
  757. result[i] = (unsigned char)(s[i] - 'A') + 10;
  758. else
  759. return -1;
  760. }
  761. return (result[0] << 4) | result[1];
  762. }
  763. /*
  764. * Decode an url-encoded string.
  765. * Returns a newly allocated string on success or NULL on failure.
  766. */
  767. static char *
  768. urldecode(const char *src)
  769. {
  770. char *ret, *dst;
  771. int ch;
  772. ret = xmalloc(strlen(src) + 1);
  773. for (dst = ret; *src != '\0'; src++) {
  774. switch (*src) {
  775. case '+':
  776. *dst++ = ' ';
  777. break;
  778. case '%':
  779. if (!isxdigit((unsigned char)src[1]) ||
  780. !isxdigit((unsigned char)src[2]) ||
  781. (ch = hexchar(src + 1)) == -1) {
  782. free(ret);
  783. return NULL;
  784. }
  785. *dst++ = ch;
  786. src += 2;
  787. break;
  788. default:
  789. *dst++ = *src;
  790. break;
  791. }
  792. }
  793. *dst = '\0';
  794. return ret;
  795. }
  796. /*
  797. * Parse an (scp|ssh|sftp)://[user@]host[:port][/path] URI.
  798. * See https://tools.ietf.org/html/draft-ietf-secsh-scp-sftp-ssh-uri-04
  799. * Either user or path may be url-encoded (but not host or port).
  800. * Caller must free returned user, host and path.
  801. * Any of the pointer return arguments may be NULL (useful for syntax checking)
  802. * but the scheme must always be specified.
  803. * If user was not specified then *userp will be set to NULL.
  804. * If port was not specified then *portp will be -1.
  805. * If path was not specified then *pathp will be set to NULL.
  806. * Returns 0 on success, 1 if non-uri/wrong scheme, -1 on error/invalid uri.
  807. */
  808. int
  809. parse_uri(const char *scheme, const char *uri, char **userp, char **hostp,
  810. int *portp, char **pathp)
  811. {
  812. char *uridup, *cp, *tmp, ch;
  813. char *user = NULL, *host = NULL, *path = NULL;
  814. int port = -1, ret = -1;
  815. size_t len;
  816. len = strlen(scheme);
  817. if (strncmp(uri, scheme, len) != 0 || strncmp(uri + len, "://", 3) != 0)
  818. return 1;
  819. uri += len + 3;
  820. if (userp != NULL)
  821. *userp = NULL;
  822. if (hostp != NULL)
  823. *hostp = NULL;
  824. if (portp != NULL)
  825. *portp = -1;
  826. if (pathp != NULL)
  827. *pathp = NULL;
  828. uridup = tmp = xstrdup(uri);
  829. /* Extract optional ssh-info (username + connection params) */
  830. if ((cp = strchr(tmp, '@')) != NULL) {
  831. char *delim;
  832. *cp = '\0';
  833. /* Extract username and connection params */
  834. if ((delim = strchr(tmp, ';')) != NULL) {
  835. /* Just ignore connection params for now */
  836. *delim = '\0';
  837. }
  838. if (*tmp == '\0') {
  839. /* Empty username */
  840. goto out;
  841. }
  842. if ((user = urldecode(tmp)) == NULL)
  843. goto out;
  844. tmp = cp + 1;
  845. }
  846. /* Extract mandatory hostname */
  847. if ((cp = hpdelim2(&tmp, &ch)) == NULL || *cp == '\0')
  848. goto out;
  849. host = xstrdup(cleanhostname(cp));
  850. if (!valid_domain(host, 0, NULL))
  851. goto out;
  852. if (tmp != NULL && *tmp != '\0') {
  853. if (ch == ':') {
  854. /* Convert and verify port. */
  855. if ((cp = strchr(tmp, '/')) != NULL)
  856. *cp = '\0';
  857. if ((port = a2port(tmp)) <= 0)
  858. goto out;
  859. tmp = cp ? cp + 1 : NULL;
  860. }
  861. if (tmp != NULL && *tmp != '\0') {
  862. /* Extract optional path */
  863. if ((path = urldecode(tmp)) == NULL)
  864. goto out;
  865. }
  866. }
  867. /* Success */
  868. if (userp != NULL) {
  869. *userp = user;
  870. user = NULL;
  871. }
  872. if (hostp != NULL) {
  873. *hostp = host;
  874. host = NULL;
  875. }
  876. if (portp != NULL)
  877. *portp = port;
  878. if (pathp != NULL) {
  879. *pathp = path;
  880. path = NULL;
  881. }
  882. ret = 0;
  883. out:
  884. free(uridup);
  885. free(user);
  886. free(host);
  887. free(path);
  888. return ret;
  889. }
  890. /* function to assist building execv() arguments */
  891. void
  892. addargs(arglist *args, char *fmt, ...)
  893. {
  894. va_list ap;
  895. char *cp;
  896. u_int nalloc;
  897. int r;
  898. va_start(ap, fmt);
  899. r = vasprintf(&cp, fmt, ap);
  900. va_end(ap);
  901. if (r == -1)
  902. fatal("addargs: argument too long");
  903. nalloc = args->nalloc;
  904. if (args->list == NULL) {
  905. nalloc = 32;
  906. args->num = 0;
  907. } else if (args->num+2 >= nalloc)
  908. nalloc *= 2;
  909. args->list = xrecallocarray(args->list, args->nalloc, nalloc, sizeof(char *));
  910. args->nalloc = nalloc;
  911. args->list[args->num++] = cp;
  912. args->list[args->num] = NULL;
  913. }
  914. void
  915. replacearg(arglist *args, u_int which, char *fmt, ...)
  916. {
  917. va_list ap;
  918. char *cp;
  919. int r;
  920. va_start(ap, fmt);
  921. r = vasprintf(&cp, fmt, ap);
  922. va_end(ap);
  923. if (r == -1)
  924. fatal("replacearg: argument too long");
  925. if (which >= args->num)
  926. fatal("replacearg: tried to replace invalid arg %d >= %d",
  927. which, args->num);
  928. free(args->list[which]);
  929. args->list[which] = cp;
  930. }
  931. void
  932. freeargs(arglist *args)
  933. {
  934. u_int i;
  935. if (args->list != NULL) {
  936. for (i = 0; i < args->num; i++)
  937. free(args->list[i]);
  938. free(args->list);
  939. args->nalloc = args->num = 0;
  940. args->list = NULL;
  941. }
  942. }
  943. /*
  944. * Expands tildes in the file name. Returns data allocated by xmalloc.
  945. * Warning: this calls getpw*.
  946. */
  947. char *
  948. tilde_expand_filename(const char *filename, uid_t uid)
  949. {
  950. const char *path, *sep;
  951. char user[128], *ret;
  952. struct passwd *pw;
  953. u_int len, slash;
  954. if (*filename != '~')
  955. return (xstrdup(filename));
  956. filename++;
  957. path = strchr(filename, '/');
  958. if (path != NULL && path > filename) { /* ~user/path */
  959. slash = path - filename;
  960. if (slash > sizeof(user) - 1)
  961. fatal("tilde_expand_filename: ~username too long");
  962. memcpy(user, filename, slash);
  963. user[slash] = '\0';
  964. if ((pw = getpwnam(user)) == NULL)
  965. fatal("tilde_expand_filename: No such user %s", user);
  966. } else if ((pw = getpwuid(uid)) == NULL) /* ~/path */
  967. fatal("tilde_expand_filename: No such uid %ld", (long)uid);
  968. /* Make sure directory has a trailing '/' */
  969. len = strlen(pw->pw_dir);
  970. if (len == 0 || pw->pw_dir[len - 1] != '/')
  971. sep = "/";
  972. else
  973. sep = "";
  974. /* Skip leading '/' from specified path */
  975. if (path != NULL)
  976. filename = path + 1;
  977. if (xasprintf(&ret, "%s%s%s", pw->pw_dir, sep, filename) >= PATH_MAX)
  978. fatal("tilde_expand_filename: Path too long");
  979. return (ret);
  980. }
  981. /*
  982. * Expand a string with a set of %[char] escapes and/or ${ENVIRONMENT}
  983. * substitutions. A number of escapes may be specified as
  984. * (char *escape_chars, char *replacement) pairs. The list must be terminated
  985. * by a NULL escape_char. Returns replaced string in memory allocated by
  986. * xmalloc which the caller must free.
  987. */
  988. static char *
  989. vdollar_percent_expand(int *parseerror, int dollar, int percent,
  990. const char *string, va_list ap)
  991. {
  992. #define EXPAND_MAX_KEYS 16
  993. u_int num_keys = 0, i;
  994. struct {
  995. const char *key;
  996. const char *repl;
  997. } keys[EXPAND_MAX_KEYS];
  998. struct sshbuf *buf;
  999. int r, missingvar = 0;
  1000. char *ret = NULL, *var, *varend, *val;
  1001. size_t len;
  1002. if ((buf = sshbuf_new()) == NULL)
  1003. fatal("%s: sshbuf_new failed", __func__);
  1004. if (parseerror == NULL)
  1005. fatal("%s: null parseerror arg", __func__);
  1006. *parseerror = 1;
  1007. /* Gather keys if we're doing percent expansion. */
  1008. if (percent) {
  1009. for (num_keys = 0; num_keys < EXPAND_MAX_KEYS; num_keys++) {
  1010. keys[num_keys].key = va_arg(ap, char *);
  1011. if (keys[num_keys].key == NULL)
  1012. break;
  1013. keys[num_keys].repl = va_arg(ap, char *);
  1014. if (keys[num_keys].repl == NULL)
  1015. fatal("%s: NULL replacement for token %s", __func__, keys[num_keys].key);
  1016. }
  1017. if (num_keys == EXPAND_MAX_KEYS && va_arg(ap, char *) != NULL)
  1018. fatal("%s: too many keys", __func__);
  1019. if (num_keys == 0)
  1020. fatal("%s: percent expansion without token list",
  1021. __func__);
  1022. }
  1023. /* Expand string */
  1024. for (i = 0; *string != '\0'; string++) {
  1025. /* Optionally process ${ENVIRONMENT} expansions. */
  1026. if (dollar && string[0] == '$' && string[1] == '{') {
  1027. string += 2; /* skip over '${' */
  1028. if ((varend = strchr(string, '}')) == NULL) {
  1029. error("%s: environment variable '%s' missing "
  1030. "closing '}'", __func__, string);
  1031. goto out;
  1032. }
  1033. len = varend - string;
  1034. if (len == 0) {
  1035. error("%s: zero-length environment variable",
  1036. __func__);
  1037. goto out;
  1038. }
  1039. var = xmalloc(len + 1);
  1040. (void)strlcpy(var, string, len + 1);
  1041. if ((val = getenv(var)) == NULL) {
  1042. error("%s: env var ${%s} has no value",
  1043. __func__, var);
  1044. missingvar = 1;
  1045. } else {
  1046. debug3("%s: expand ${%s} -> '%s'", __func__,
  1047. var, val);
  1048. if ((r = sshbuf_put(buf, val, strlen(val))) !=0)
  1049. fatal("%s: sshbuf_put: %s", __func__,
  1050. ssh_err(r));
  1051. }
  1052. free(var);
  1053. string += len;
  1054. continue;
  1055. }
  1056. /*
  1057. * Process percent expansions if we have a list of TOKENs.
  1058. * If we're not doing percent expansion everything just gets
  1059. * appended here.
  1060. */
  1061. if (*string != '%' || !percent) {
  1062. append:
  1063. if ((r = sshbuf_put_u8(buf, *string)) != 0) {
  1064. fatal("%s: sshbuf_put_u8: %s",
  1065. __func__, ssh_err(r));
  1066. }
  1067. continue;
  1068. }
  1069. string++;
  1070. /* %% case */
  1071. if (*string == '%')
  1072. goto append;
  1073. if (*string == '\0') {
  1074. error("%s: invalid format", __func__);
  1075. goto out;
  1076. }
  1077. for (i = 0; i < num_keys; i++) {
  1078. if (strchr(keys[i].key, *string) != NULL) {
  1079. if ((r = sshbuf_put(buf, keys[i].repl,
  1080. strlen(keys[i].repl))) != 0) {
  1081. fatal("%s: sshbuf_put: %s",
  1082. __func__, ssh_err(r));
  1083. }
  1084. break;
  1085. }
  1086. }
  1087. if (i >= num_keys) {
  1088. error("%s: unknown key %%%c", __func__, *string);
  1089. goto out;
  1090. }
  1091. }
  1092. if (!missingvar && (ret = sshbuf_dup_string(buf)) == NULL)
  1093. fatal("%s: sshbuf_dup_string failed", __func__);
  1094. *parseerror = 0;
  1095. out:
  1096. sshbuf_free(buf);
  1097. return *parseerror ? NULL : ret;
  1098. #undef EXPAND_MAX_KEYS
  1099. }
  1100. /*
  1101. * Expand only environment variables.
  1102. * Note that although this function is variadic like the other similar
  1103. * functions, any such arguments will be unused.
  1104. */
  1105. char *
  1106. dollar_expand(int *parseerr, const char *string, ...)
  1107. {
  1108. char *ret;
  1109. int err;
  1110. va_list ap;
  1111. va_start(ap, string);
  1112. ret = vdollar_percent_expand(&err, 1, 0, string, ap);
  1113. va_end(ap);
  1114. if (parseerr != NULL)
  1115. *parseerr = err;
  1116. return ret;
  1117. }
  1118. /*
  1119. * Returns expanded string or NULL if a specified environment variable is
  1120. * not defined, or calls fatal if the string is invalid.
  1121. */
  1122. char *
  1123. percent_expand(const char *string, ...)
  1124. {
  1125. char *ret;
  1126. int err;
  1127. va_list ap;
  1128. va_start(ap, string);
  1129. ret = vdollar_percent_expand(&err, 0, 1, string, ap);
  1130. va_end(ap);
  1131. if (err)
  1132. fatal("%s failed", __func__);
  1133. return ret;
  1134. }
  1135. /*
  1136. * Returns expanded string or NULL if a specified environment variable is
  1137. * not defined, or calls fatal if the string is invalid.
  1138. */
  1139. char *
  1140. percent_dollar_expand(const char *string, ...)
  1141. {
  1142. char *ret;
  1143. int err;
  1144. va_list ap;
  1145. va_start(ap, string);
  1146. ret = vdollar_percent_expand(&err, 1, 1, string, ap);
  1147. va_end(ap);
  1148. if (err)
  1149. fatal("%s failed", __func__);
  1150. return ret;
  1151. }
  1152. int
  1153. tun_open(int tun, int mode, char **ifname)
  1154. {
  1155. #if defined(CUSTOM_SYS_TUN_OPEN)
  1156. return (sys_tun_open(tun, mode, ifname));
  1157. #elif defined(SSH_TUN_OPENBSD)
  1158. struct ifreq ifr;
  1159. char name[100];
  1160. int fd = -1, sock;
  1161. const char *tunbase = "tun";
  1162. if (ifname != NULL)
  1163. *ifname = NULL;
  1164. if (mode == SSH_TUNMODE_ETHERNET)
  1165. tunbase = "tap";
  1166. /* Open the tunnel device */
  1167. if (tun <= SSH_TUNID_MAX) {
  1168. snprintf(name, sizeof(name), "/dev/%s%d", tunbase, tun);
  1169. fd = open(name, O_RDWR);
  1170. } else if (tun == SSH_TUNID_ANY) {
  1171. for (tun = 100; tun >= 0; tun--) {
  1172. snprintf(name, sizeof(name), "/dev/%s%d",
  1173. tunbase, tun);
  1174. if ((fd = open(name, O_RDWR)) >= 0)
  1175. break;
  1176. }
  1177. } else {
  1178. debug("%s: invalid tunnel %u", __func__, tun);
  1179. return -1;
  1180. }
  1181. if (fd == -1) {
  1182. debug("%s: %s open: %s", __func__, name, strerror(errno));
  1183. return -1;
  1184. }
  1185. debug("%s: %s mode %d fd %d", __func__, name, mode, fd);
  1186. /* Bring interface up if it is not already */
  1187. snprintf(ifr.ifr_name, sizeof(ifr.ifr_name), "%s%d", tunbase, tun);
  1188. if ((sock = socket(PF_UNIX, SOCK_STREAM, 0)) == -1)
  1189. goto failed;
  1190. if (ioctl(sock, SIOCGIFFLAGS, &ifr) == -1) {
  1191. debug("%s: get interface %s flags: %s", __func__,
  1192. ifr.ifr_name, strerror(errno));
  1193. goto failed;
  1194. }
  1195. if (!(ifr.ifr_flags & IFF_UP)) {
  1196. ifr.ifr_flags |= IFF_UP;
  1197. if (ioctl(sock, SIOCSIFFLAGS, &ifr) == -1) {
  1198. debug("%s: activate interface %s: %s", __func__,
  1199. ifr.ifr_name, strerror(errno));
  1200. goto failed;
  1201. }
  1202. }
  1203. if (ifname != NULL)
  1204. *ifname = xstrdup(ifr.ifr_name);
  1205. close(sock);
  1206. return fd;
  1207. failed:
  1208. if (fd >= 0)
  1209. close(fd);
  1210. if (sock >= 0)
  1211. close(sock);
  1212. return -1;
  1213. #else
  1214. error("Tunnel interfaces are not supported on this platform");
  1215. return (-1);
  1216. #endif
  1217. }
  1218. void
  1219. sanitise_stdfd(void)
  1220. {
  1221. int nullfd, dupfd;
  1222. if ((nullfd = dupfd = open(_PATH_DEVNULL, O_RDWR)) == -1) {
  1223. fprintf(stderr, "Couldn't open /dev/null: %s\n",
  1224. strerror(errno));
  1225. exit(1);
  1226. }
  1227. while (++dupfd <= STDERR_FILENO) {
  1228. /* Only populate closed fds. */
  1229. if (fcntl(dupfd, F_GETFL) == -1 && errno == EBADF) {
  1230. if (dup2(nullfd, dupfd) == -1) {
  1231. fprintf(stderr, "dup2: %s\n", strerror(errno));
  1232. exit(1);
  1233. }
  1234. }
  1235. }
  1236. if (nullfd > STDERR_FILENO)
  1237. close(nullfd);
  1238. }
  1239. char *
  1240. tohex(const void *vp, size_t l)
  1241. {
  1242. const u_char *p = (const u_char *)vp;
  1243. char b[3], *r;
  1244. size_t i, hl;
  1245. if (l > 65536)
  1246. return xstrdup("tohex: length > 65536");
  1247. hl = l * 2 + 1;
  1248. r = xcalloc(1, hl);
  1249. for (i = 0; i < l; i++) {
  1250. snprintf(b, sizeof(b), "%02x", p[i]);
  1251. strlcat(r, b, hl);
  1252. }
  1253. return (r);
  1254. }
  1255. /*
  1256. * Extend string *sp by the specified format. If *sp is not NULL (or empty),
  1257. * then the separator 'sep' will be prepended before the formatted arguments.
  1258. * Extended strings are heap allocated.
  1259. */
  1260. void
  1261. xextendf(char **sp, const char *sep, const char *fmt, ...)
  1262. {
  1263. va_list ap;
  1264. char *tmp1, *tmp2;
  1265. va_start(ap, fmt);
  1266. xvasprintf(&tmp1, fmt, ap);
  1267. va_end(ap);
  1268. if (*sp == NULL || **sp == '\0') {
  1269. free(*sp);
  1270. *sp = tmp1;
  1271. return;
  1272. }
  1273. xasprintf(&tmp2, "%s%s%s", *sp, sep == NULL ? "" : sep, tmp1);
  1274. free(tmp1);
  1275. free(*sp);
  1276. *sp = tmp2;
  1277. }
  1278. u_int64_t
  1279. get_u64(const void *vp)
  1280. {
  1281. const u_char *p = (const u_char *)vp;
  1282. u_int64_t v;
  1283. v = (u_int64_t)p[0] << 56;
  1284. v |= (u_int64_t)p[1] << 48;
  1285. v |= (u_int64_t)p[2] << 40;
  1286. v |= (u_int64_t)p[3] << 32;
  1287. v |= (u_int64_t)p[4] << 24;
  1288. v |= (u_int64_t)p[5] << 16;
  1289. v |= (u_int64_t)p[6] << 8;
  1290. v |= (u_int64_t)p[7];
  1291. return (v);
  1292. }
  1293. u_int32_t
  1294. get_u32(const void *vp)
  1295. {
  1296. const u_char *p = (const u_char *)vp;
  1297. u_int32_t v;
  1298. v = (u_int32_t)p[0] << 24;
  1299. v |= (u_int32_t)p[1] << 16;
  1300. v |= (u_int32_t)p[2] << 8;
  1301. v |= (u_int32_t)p[3];
  1302. return (v);
  1303. }
  1304. u_int32_t
  1305. get_u32_le(const void *vp)
  1306. {
  1307. const u_char *p = (const u_char *)vp;
  1308. u_int32_t v;
  1309. v = (u_int32_t)p[0];
  1310. v |= (u_int32_t)p[1] << 8;
  1311. v |= (u_int32_t)p[2] << 16;
  1312. v |= (u_int32_t)p[3] << 24;
  1313. return (v);
  1314. }
  1315. u_int16_t
  1316. get_u16(const void *vp)
  1317. {
  1318. const u_char *p = (const u_char *)vp;
  1319. u_int16_t v;
  1320. v = (u_int16_t)p[0] << 8;
  1321. v |= (u_int16_t)p[1];
  1322. return (v);
  1323. }
  1324. void
  1325. put_u64(void *vp, u_int64_t v)
  1326. {
  1327. u_char *p = (u_char *)vp;
  1328. p[0] = (u_char)(v >> 56) & 0xff;
  1329. p[1] = (u_char)(v >> 48) & 0xff;
  1330. p[2] = (u_char)(v >> 40) & 0xff;
  1331. p[3] = (u_char)(v >> 32) & 0xff;
  1332. p[4] = (u_char)(v >> 24) & 0xff;
  1333. p[5] = (u_char)(v >> 16) & 0xff;
  1334. p[6] = (u_char)(v >> 8) & 0xff;
  1335. p[7] = (u_char)v & 0xff;
  1336. }
  1337. void
  1338. put_u32(void *vp, u_int32_t v)
  1339. {
  1340. u_char *p = (u_char *)vp;
  1341. p[0] = (u_char)(v >> 24) & 0xff;
  1342. p[1] = (u_char)(v >> 16) & 0xff;
  1343. p[2] = (u_char)(v >> 8) & 0xff;
  1344. p[3] = (u_char)v & 0xff;
  1345. }
  1346. void
  1347. put_u32_le(void *vp, u_int32_t v)
  1348. {
  1349. u_char *p = (u_char *)vp;
  1350. p[0] = (u_char)v & 0xff;
  1351. p[1] = (u_char)(v >> 8) & 0xff;
  1352. p[2] = (u_char)(v >> 16) & 0xff;
  1353. p[3] = (u_char)(v >> 24) & 0xff;
  1354. }
  1355. void
  1356. put_u16(void *vp, u_int16_t v)
  1357. {
  1358. u_char *p = (u_char *)vp;
  1359. p[0] = (u_char)(v >> 8) & 0xff;
  1360. p[1] = (u_char)v & 0xff;
  1361. }
  1362. void
  1363. ms_subtract_diff(struct timeval *start, int *ms)
  1364. {
  1365. struct timeval diff, finish;
  1366. monotime_tv(&finish);
  1367. timersub(&finish, start, &diff);
  1368. *ms -= (diff.tv_sec * 1000) + (diff.tv_usec / 1000);
  1369. }
  1370. void
  1371. ms_to_timeval(struct timeval *tv, int ms)
  1372. {
  1373. if (ms < 0)
  1374. ms = 0;
  1375. tv->tv_sec = ms / 1000;
  1376. tv->tv_usec = (ms % 1000) * 1000;
  1377. }
  1378. void
  1379. monotime_ts(struct timespec *ts)
  1380. {
  1381. struct timeval tv;
  1382. #if defined(HAVE_CLOCK_GETTIME) && (defined(CLOCK_BOOTTIME) || \
  1383. defined(CLOCK_MONOTONIC) || defined(CLOCK_REALTIME))
  1384. static int gettime_failed = 0;
  1385. if (!gettime_failed) {
  1386. # ifdef CLOCK_BOOTTIME
  1387. if (clock_gettime(CLOCK_BOOTTIME, ts) == 0)
  1388. return;
  1389. # endif /* CLOCK_BOOTTIME */
  1390. # ifdef CLOCK_MONOTONIC
  1391. if (clock_gettime(CLOCK_MONOTONIC, ts) == 0)
  1392. return;
  1393. # endif /* CLOCK_MONOTONIC */
  1394. # ifdef CLOCK_REALTIME
  1395. /* Not monotonic, but we're almost out of options here. */
  1396. if (clock_gettime(CLOCK_REALTIME, ts) == 0)
  1397. return;
  1398. # endif /* CLOCK_REALTIME */
  1399. debug3("clock_gettime: %s", strerror(errno));
  1400. gettime_failed = 1;
  1401. }
  1402. #endif /* HAVE_CLOCK_GETTIME && (BOOTTIME || MONOTONIC || REALTIME) */
  1403. gettimeofday(&tv, NULL);
  1404. ts->tv_sec = tv.tv_sec;
  1405. ts->tv_nsec = (long)tv.tv_usec * 1000;
  1406. }
  1407. void
  1408. monotime_tv(struct timeval *tv)
  1409. {
  1410. struct timespec ts;
  1411. monotime_ts(&ts);
  1412. tv->tv_sec = ts.tv_sec;
  1413. tv->tv_usec = ts.tv_nsec / 1000;
  1414. }
  1415. time_t
  1416. monotime(void)
  1417. {
  1418. struct timespec ts;
  1419. monotime_ts(&ts);
  1420. return ts.tv_sec;
  1421. }
  1422. double
  1423. monotime_double(void)
  1424. {
  1425. struct timespec ts;
  1426. monotime_ts(&ts);
  1427. return ts.tv_sec + ((double)ts.tv_nsec / 1000000000);
  1428. }
  1429. void
  1430. bandwidth_limit_init(struct bwlimit *bw, u_int64_t kbps, size_t buflen)
  1431. {
  1432. bw->buflen = buflen;
  1433. bw->rate = kbps;
  1434. bw->thresh = buflen;
  1435. bw->lamt = 0;
  1436. timerclear(&bw->bwstart);
  1437. timerclear(&bw->bwend);
  1438. }
  1439. /* Callback from read/write loop to insert bandwidth-limiting delays */
  1440. void
  1441. bandwidth_limit(struct bwlimit *bw, size_t read_len)
  1442. {
  1443. u_int64_t waitlen;
  1444. struct timespec ts, rm;
  1445. bw->lamt += read_len;
  1446. if (!timerisset(&bw->bwstart)) {
  1447. monotime_tv(&bw->bwstart);
  1448. return;
  1449. }
  1450. if (bw->lamt < bw->thresh)
  1451. return;
  1452. monotime_tv(&bw->bwend);
  1453. timersub(&bw->bwend, &bw->bwstart, &bw->bwend);
  1454. if (!timerisset(&bw->bwend))
  1455. return;
  1456. bw->lamt *= 8;
  1457. waitlen = (double)1000000L * bw->lamt / bw->rate;
  1458. bw->bwstart.tv_sec = waitlen / 1000000L;
  1459. bw->bwstart.tv_usec = waitlen % 1000000L;
  1460. if (timercmp(&bw->bwstart, &bw->bwend, >)) {
  1461. timersub(&bw->bwstart, &bw->bwend, &bw->bwend);
  1462. /* Adjust the wait time */
  1463. if (bw->bwend.tv_sec) {
  1464. bw->thresh /= 2;
  1465. if (bw->thresh < bw->buflen / 4)
  1466. bw->thresh = bw->buflen / 4;
  1467. } else if (bw->bwend.tv_usec < 10000) {
  1468. bw->thresh *= 2;
  1469. if (bw->thresh > bw->buflen * 8)
  1470. bw->thresh = bw->buflen * 8;
  1471. }
  1472. TIMEVAL_TO_TIMESPEC(&bw->bwend, &ts);
  1473. while (nanosleep(&ts, &rm) == -1) {
  1474. if (errno != EINTR)
  1475. break;
  1476. ts = rm;
  1477. }
  1478. }
  1479. bw->lamt = 0;
  1480. monotime_tv(&bw->bwstart);
  1481. }
  1482. /* Make a template filename for mk[sd]temp() */
  1483. void
  1484. mktemp_proto(char *s, size_t len)
  1485. {
  1486. const char *tmpdir;
  1487. int r;
  1488. if ((tmpdir = getenv("TMPDIR")) != NULL) {
  1489. r = snprintf(s, len, "%s/ssh-XXXXXXXXXXXX", tmpdir);
  1490. if (r > 0 && (size_t)r < len)
  1491. return;
  1492. }
  1493. r = snprintf(s, len, "/tmp/ssh-XXXXXXXXXXXX");
  1494. if (r < 0 || (size_t)r >= len)
  1495. fatal("%s: template string too short", __func__);
  1496. }
  1497. static const struct {
  1498. const char *name;
  1499. int value;
  1500. } ipqos[] = {
  1501. { "none", INT_MAX }, /* can't use 0 here; that's CS0 */
  1502. { "af11", IPTOS_DSCP_AF11 },
  1503. { "af12", IPTOS_DSCP_AF12 },
  1504. { "af13", IPTOS_DSCP_AF13 },
  1505. { "af21", IPTOS_DSCP_AF21 },
  1506. { "af22", IPTOS_DSCP_AF22 },
  1507. { "af23", IPTOS_DSCP_AF23 },
  1508. { "af31", IPTOS_DSCP_AF31 },
  1509. { "af32", IPTOS_DSCP_AF32 },
  1510. { "af33", IPTOS_DSCP_AF33 },
  1511. { "af41", IPTOS_DSCP_AF41 },
  1512. { "af42", IPTOS_DSCP_AF42 },
  1513. { "af43", IPTOS_DSCP_AF43 },
  1514. { "cs0", IPTOS_DSCP_CS0 },
  1515. { "cs1", IPTOS_DSCP_CS1 },
  1516. { "cs2", IPTOS_DSCP_CS2 },
  1517. { "cs3", IPTOS_DSCP_CS3 },
  1518. { "cs4", IPTOS_DSCP_CS4 },
  1519. { "cs5", IPTOS_DSCP_CS5 },
  1520. { "cs6", IPTOS_DSCP_CS6 },
  1521. { "cs7", IPTOS_DSCP_CS7 },
  1522. { "ef", IPTOS_DSCP_EF },
  1523. { "le", IPTOS_DSCP_LE },
  1524. { "lowdelay", IPTOS_LOWDELAY },
  1525. { "throughput", IPTOS_THROUGHPUT },
  1526. { "reliability", IPTOS_RELIABILITY },
  1527. { NULL, -1 }
  1528. };
  1529. int
  1530. parse_ipqos(const char *cp)
  1531. {
  1532. u_int i;
  1533. char *ep;
  1534. long val;
  1535. if (cp == NULL)
  1536. return -1;
  1537. for (i = 0; ipqos[i].name != NULL; i++) {
  1538. if (strcasecmp(cp, ipqos[i].name) == 0)
  1539. return ipqos[i].value;
  1540. }
  1541. /* Try parsing as an integer */
  1542. val = strtol(cp, &ep, 0);
  1543. if (*cp == '\0' || *ep != '\0' || val < 0 || val > 255)
  1544. return -1;
  1545. return val;
  1546. }
  1547. const char *
  1548. iptos2str(int iptos)
  1549. {
  1550. int i;
  1551. static char iptos_str[sizeof "0xff"];
  1552. for (i = 0; ipqos[i].name != NULL; i++) {
  1553. if (ipqos[i].value == iptos)
  1554. return ipqos[i].name;
  1555. }
  1556. snprintf(iptos_str, sizeof iptos_str, "0x%02x", iptos);
  1557. return iptos_str;
  1558. }
  1559. void
  1560. lowercase(char *s)
  1561. {
  1562. for (; *s; s++)
  1563. *s = tolower((u_char)*s);
  1564. }
  1565. int
  1566. unix_listener(const char *path, int backlog, int unlink_first)
  1567. {
  1568. struct sockaddr_un sunaddr;
  1569. int saved_errno, sock;
  1570. memset(&sunaddr, 0, sizeof(sunaddr));
  1571. sunaddr.sun_family = AF_UNIX;
  1572. if (strlcpy(sunaddr.sun_path, path,
  1573. sizeof(sunaddr.sun_path)) >= sizeof(sunaddr.sun_path)) {
  1574. error("%s: path \"%s\" too long for Unix domain socket",
  1575. __func__, path);
  1576. errno = ENAMETOOLONG;
  1577. return -1;
  1578. }
  1579. sock = socket(PF_UNIX, SOCK_STREAM, 0);
  1580. if (sock == -1) {
  1581. saved_errno = errno;
  1582. error("%s: socket: %.100s", __func__, strerror(errno));
  1583. errno = saved_errno;
  1584. return -1;
  1585. }
  1586. if (unlink_first == 1) {
  1587. if (unlink(path) != 0 && errno != ENOENT)
  1588. error("unlink(%s): %.100s", path, strerror(errno));
  1589. }
  1590. if (bind(sock, (struct sockaddr *)&sunaddr, sizeof(sunaddr)) == -1) {
  1591. saved_errno = errno;
  1592. error("%s: cannot bind to path %s: %s",
  1593. __func__, path, strerror(errno));
  1594. close(sock);
  1595. errno = saved_errno;
  1596. return -1;
  1597. }
  1598. if (listen(sock, backlog) == -1) {
  1599. saved_errno = errno;
  1600. error("%s: cannot listen on path %s: %s",
  1601. __func__, path, strerror(errno));
  1602. close(sock);
  1603. unlink(path);
  1604. errno = saved_errno;
  1605. return -1;
  1606. }
  1607. return sock;
  1608. }
  1609. void
  1610. sock_set_v6only(int s)
  1611. {
  1612. #if defined(IPV6_V6ONLY) && !defined(__OpenBSD__)
  1613. int on = 1;
  1614. debug3("%s: set socket %d IPV6_V6ONLY", __func__, s);
  1615. if (setsockopt(s, IPPROTO_IPV6, IPV6_V6ONLY, &on, sizeof(on)) == -1)
  1616. debug("setsockopt IPV6_V6ONLY: %s", strerror(errno));
  1617. #endif
  1618. }
  1619. /*
  1620. * Compares two strings that maybe be NULL. Returns non-zero if strings
  1621. * are both NULL or are identical, returns zero otherwise.
  1622. */
  1623. static int
  1624. strcmp_maybe_null(const char *a, const char *b)
  1625. {
  1626. if ((a == NULL && b != NULL) || (a != NULL && b == NULL))
  1627. return 0;
  1628. if (a != NULL && strcmp(a, b) != 0)
  1629. return 0;
  1630. return 1;
  1631. }
  1632. /*
  1633. * Compare two forwards, returning non-zero if they are identical or
  1634. * zero otherwise.
  1635. */
  1636. int
  1637. forward_equals(const struct Forward *a, const struct Forward *b)
  1638. {
  1639. if (strcmp_maybe_null(a->listen_host, b->listen_host) == 0)
  1640. return 0;
  1641. if (a->listen_port != b->listen_port)
  1642. return 0;
  1643. if (strcmp_maybe_null(a->listen_path, b->listen_path) == 0)
  1644. return 0;
  1645. if (strcmp_maybe_null(a->connect_host, b->connect_host) == 0)
  1646. return 0;
  1647. if (a->connect_port != b->connect_port)
  1648. return 0;
  1649. if (strcmp_maybe_null(a->connect_path, b->connect_path) == 0)
  1650. return 0;
  1651. /* allocated_port and handle are not checked */
  1652. return 1;
  1653. }
  1654. /* returns 1 if process is already daemonized, 0 otherwise */
  1655. int
  1656. daemonized(void)
  1657. {
  1658. int fd;
  1659. if ((fd = open(_PATH_TTY, O_RDONLY | O_NOCTTY)) >= 0) {
  1660. close(fd);
  1661. return 0; /* have controlling terminal */
  1662. }
  1663. if (getppid() != 1)
  1664. return 0; /* parent is not init */
  1665. if (getsid(0) != getpid())
  1666. return 0; /* not session leader */
  1667. debug3("already daemonized");
  1668. return 1;
  1669. }
  1670. /*
  1671. * Splits 's' into an argument vector. Handles quoted string and basic
  1672. * escape characters (\\, \", \'). Caller must free the argument vector
  1673. * and its members.
  1674. */
  1675. int
  1676. argv_split(const char *s, int *argcp, char ***argvp)
  1677. {
  1678. int r = SSH_ERR_INTERNAL_ERROR;
  1679. int argc = 0, quote, i, j;
  1680. char *arg, **argv = xcalloc(1, sizeof(*argv));
  1681. *argvp = NULL;
  1682. *argcp = 0;
  1683. for (i = 0; s[i] != '\0'; i++) {
  1684. /* Skip leading whitespace */
  1685. if (s[i] == ' ' || s[i] == '\t')
  1686. continue;
  1687. /* Start of a token */
  1688. quote = 0;
  1689. if (s[i] == '\'' || s[i] == '"')
  1690. quote = s[i++];
  1691. argv = xreallocarray(argv, (argc + 2), sizeof(*argv));
  1692. arg = argv[argc++] = xcalloc(1, strlen(s + i) + 1);
  1693. argv[argc] = NULL;
  1694. /* Copy the token in, removing escapes */
  1695. for (j = 0; s[i] != '\0'; i++) {
  1696. if (s[i] == '\\') {
  1697. if (s[i + 1] == '\'' ||
  1698. s[i + 1] == '\"' ||
  1699. s[i + 1] == '\\') {
  1700. i++; /* Skip '\' */
  1701. arg[j++] = s[i];
  1702. } else {
  1703. /* Unrecognised escape */
  1704. arg[j++] = s[i];
  1705. }
  1706. } else if (quote == 0 && (s[i] == ' ' || s[i] == '\t'))
  1707. break; /* done */
  1708. else if (quote != 0 && s[i] == quote)
  1709. break; /* done */
  1710. else
  1711. arg[j++] = s[i];
  1712. }
  1713. if (s[i] == '\0') {
  1714. if (quote != 0) {
  1715. /* Ran out of string looking for close quote */
  1716. r = SSH_ERR_INVALID_FORMAT;
  1717. goto out;
  1718. }
  1719. break;
  1720. }
  1721. }
  1722. /* Success */
  1723. *argcp = argc;
  1724. *argvp = argv;
  1725. argc = 0;
  1726. argv = NULL;
  1727. r = 0;
  1728. out:
  1729. if (argc != 0 && argv != NULL) {
  1730. for (i = 0; i < argc; i++)
  1731. free(argv[i]);
  1732. free(argv);
  1733. }
  1734. return r;
  1735. }
  1736. /*
  1737. * Reassemble an argument vector into a string, quoting and escaping as
  1738. * necessary. Caller must free returned string.
  1739. */
  1740. char *
  1741. argv_assemble(int argc, char **argv)
  1742. {
  1743. int i, j, ws, r;
  1744. char c, *ret;
  1745. struct sshbuf *buf, *arg;
  1746. if ((buf = sshbuf_new()) == NULL || (arg = sshbuf_new()) == NULL)
  1747. fatal("%s: sshbuf_new failed", __func__);
  1748. for (i = 0; i < argc; i++) {
  1749. ws = 0;
  1750. sshbuf_reset(arg);
  1751. for (j = 0; argv[i][j] != '\0'; j++) {
  1752. r = 0;
  1753. c = argv[i][j];
  1754. switch (c) {
  1755. case ' ':
  1756. case '\t':
  1757. ws = 1;
  1758. r = sshbuf_put_u8(arg, c);
  1759. break;
  1760. case '\\':
  1761. case '\'':
  1762. case '"':
  1763. if ((r = sshbuf_put_u8(arg, '\\')) != 0)
  1764. break;
  1765. /* FALLTHROUGH */
  1766. default:
  1767. r = sshbuf_put_u8(arg, c);
  1768. break;
  1769. }
  1770. if (r != 0)
  1771. fatal("%s: sshbuf_put_u8: %s",
  1772. __func__, ssh_err(r));
  1773. }
  1774. if ((i != 0 && (r = sshbuf_put_u8(buf, ' ')) != 0) ||
  1775. (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0) ||
  1776. (r = sshbuf_putb(buf, arg)) != 0 ||
  1777. (ws != 0 && (r = sshbuf_put_u8(buf, '"')) != 0))
  1778. fatal("%s: buffer error: %s", __func__, ssh_err(r));
  1779. }
  1780. if ((ret = malloc(sshbuf_len(buf) + 1)) == NULL)
  1781. fatal("%s: malloc failed", __func__);
  1782. memcpy(ret, sshbuf_ptr(buf), sshbuf_len(buf));
  1783. ret[sshbuf_len(buf)] = '\0';
  1784. sshbuf_free(buf);
  1785. sshbuf_free(arg);
  1786. return ret;
  1787. }
  1788. /* Returns 0 if pid exited cleanly, non-zero otherwise */
  1789. int
  1790. exited_cleanly(pid_t pid, const char *tag, const char *cmd, int quiet)
  1791. {
  1792. int status;
  1793. while (waitpid(pid, &status, 0) == -1) {
  1794. if (errno != EINTR) {
  1795. error("%s: waitpid: %s", tag, strerror(errno));
  1796. return -1;
  1797. }
  1798. }
  1799. if (WIFSIGNALED(status)) {
  1800. error("%s %s exited on signal %d", tag, cmd, WTERMSIG(status));
  1801. return -1;
  1802. } else if (WEXITSTATUS(status) != 0) {
  1803. do_log2(quiet ? SYSLOG_LEVEL_DEBUG1 : SYSLOG_LEVEL_INFO,
  1804. "%s %s failed, status %d", tag, cmd, WEXITSTATUS(status));
  1805. return -1;
  1806. }
  1807. return 0;
  1808. }
  1809. /*
  1810. * Check a given path for security. This is defined as all components
  1811. * of the path to the file must be owned by either the owner of
  1812. * of the file or root and no directories must be group or world writable.
  1813. *
  1814. * XXX Should any specific check be done for sym links ?
  1815. *
  1816. * Takes a file name, its stat information (preferably from fstat() to
  1817. * avoid races), the uid of the expected owner, their home directory and an
  1818. * error buffer plus max size as arguments.
  1819. *
  1820. * Returns 0 on success and -1 on failure
  1821. */
  1822. int
  1823. safe_path(const char *name, struct stat *stp, const char *pw_dir,
  1824. uid_t uid, char *err, size_t errlen)
  1825. {
  1826. char buf[PATH_MAX], homedir[PATH_MAX];
  1827. char *cp;
  1828. int comparehome = 0;
  1829. struct stat st;
  1830. if (realpath(name, buf) == NULL) {
  1831. snprintf(err, errlen, "realpath %s failed: %s", name,
  1832. strerror(errno));
  1833. return -1;
  1834. }
  1835. if (pw_dir != NULL && realpath(pw_dir, homedir) != NULL)
  1836. comparehome = 1;
  1837. if (!S_ISREG(stp->st_mode)) {
  1838. snprintf(err, errlen, "%s is not a regular file", buf);
  1839. return -1;
  1840. }
  1841. if ((!platform_sys_dir_uid(stp->st_uid) && stp->st_uid != uid) ||
  1842. (stp->st_mode & 022) != 0) {
  1843. snprintf(err, errlen, "bad ownership or modes for file %s",
  1844. buf);
  1845. return -1;
  1846. }
  1847. /* for each component of the canonical path, walking upwards */
  1848. for (;;) {
  1849. if ((cp = dirname(buf)) == NULL) {
  1850. snprintf(err, errlen, "dirname() failed");
  1851. return -1;
  1852. }
  1853. strlcpy(buf, cp, sizeof(buf));
  1854. if (stat(buf, &st) == -1 ||
  1855. (!platform_sys_dir_uid(st.st_uid) && st.st_uid != uid) ||
  1856. (st.st_mode & 022) != 0) {
  1857. snprintf(err, errlen,
  1858. "bad ownership or modes for directory %s", buf);
  1859. return -1;
  1860. }
  1861. /* If are past the homedir then we can stop */
  1862. if (comparehome && strcmp(homedir, buf) == 0)
  1863. break;
  1864. /*
  1865. * dirname should always complete with a "/" path,
  1866. * but we can be paranoid and check for "." too
  1867. */
  1868. if ((strcmp("/", buf) == 0) || (strcmp(".", buf) == 0))
  1869. break;
  1870. }
  1871. return 0;
  1872. }
  1873. /*
  1874. * Version of safe_path() that accepts an open file descriptor to
  1875. * avoid races.
  1876. *
  1877. * Returns 0 on success and -1 on failure
  1878. */
  1879. int
  1880. safe_path_fd(int fd, const char *file, struct passwd *pw,
  1881. char *err, size_t errlen)
  1882. {
  1883. struct stat st;
  1884. /* check the open file to avoid races */
  1885. if (fstat(fd, &st) == -1) {
  1886. snprintf(err, errlen, "cannot stat file %s: %s",
  1887. file, strerror(errno));
  1888. return -1;
  1889. }
  1890. return safe_path(file, &st, pw->pw_dir, pw->pw_uid, err, errlen);
  1891. }
  1892. /*
  1893. * Sets the value of the given variable in the environment. If the variable
  1894. * already exists, its value is overridden.
  1895. */
  1896. void
  1897. child_set_env(char ***envp, u_int *envsizep, const char *name,
  1898. const char *value)
  1899. {
  1900. char **env;
  1901. u_int envsize;
  1902. u_int i, namelen;
  1903. if (strchr(name, '=') != NULL) {
  1904. error("Invalid environment variable \"%.100s\"", name);
  1905. return;
  1906. }
  1907. /*
  1908. * If we're passed an uninitialized list, allocate a single null
  1909. * entry before continuing.
  1910. */
  1911. if (*envp == NULL && *envsizep == 0) {
  1912. *envp = xmalloc(sizeof(char *));
  1913. *envp[0] = NULL;
  1914. *envsizep = 1;
  1915. }
  1916. /*
  1917. * Find the slot where the value should be stored. If the variable
  1918. * already exists, we reuse the slot; otherwise we append a new slot
  1919. * at the end of the array, expanding if necessary.
  1920. */
  1921. env = *envp;
  1922. namelen = strlen(name);
  1923. for (i = 0; env[i]; i++)
  1924. if (strncmp(env[i], name, namelen) == 0 && env[i][namelen] == '=')
  1925. break;
  1926. if (env[i]) {
  1927. /* Reuse the slot. */
  1928. free(env[i]);
  1929. } else {
  1930. /* New variable. Expand if necessary. */
  1931. envsize = *envsizep;
  1932. if (i >= envsize - 1) {
  1933. if (envsize >= 1000)
  1934. fatal("child_set_env: too many env vars");
  1935. envsize += 50;
  1936. env = (*envp) = xreallocarray(env, envsize, sizeof(char *));
  1937. *envsizep = envsize;
  1938. }
  1939. /* Need to set the NULL pointer at end of array beyond the new slot. */
  1940. env[i + 1] = NULL;
  1941. }
  1942. /* Allocate space and format the variable in the appropriate slot. */
  1943. /* XXX xasprintf */
  1944. env[i] = xmalloc(strlen(name) + 1 + strlen(value) + 1);
  1945. snprintf(env[i], strlen(name) + 1 + strlen(value) + 1, "%s=%s", name, value);
  1946. }
  1947. /*
  1948. * Check and optionally lowercase a domain name, also removes trailing '.'
  1949. * Returns 1 on success and 0 on failure, storing an error message in errstr.
  1950. */
  1951. int
  1952. valid_domain(char *name, int makelower, const char **errstr)
  1953. {
  1954. size_t i, l = strlen(name);
  1955. u_char c, last = '\0';
  1956. static char errbuf[256];
  1957. if (l == 0) {
  1958. strlcpy(errbuf, "empty domain name", sizeof(errbuf));
  1959. goto bad;
  1960. }
  1961. if (!isalpha((u_char)name[0]) && !isdigit((u_char)name[0])) {
  1962. snprintf(errbuf, sizeof(errbuf), "domain name \"%.100s\" "
  1963. "starts with invalid character", name);
  1964. goto bad;
  1965. }
  1966. for (i = 0; i < l; i++) {
  1967. c = tolower((u_char)name[i]);
  1968. if (makelower)
  1969. name[i] = (char)c;
  1970. if (last == '.' && c == '.') {
  1971. snprintf(errbuf, sizeof(errbuf), "domain name "
  1972. "\"%.100s\" contains consecutive separators", name);
  1973. goto bad;
  1974. }
  1975. if (c != '.' && c != '-' && !isalnum(c) &&
  1976. c != '_') /* technically invalid, but common */ {
  1977. snprintf(errbuf, sizeof(errbuf), "domain name "
  1978. "\"%.100s\" contains invalid characters", name);
  1979. goto bad;
  1980. }
  1981. last = c;
  1982. }
  1983. if (name[l - 1] == '.')
  1984. name[l - 1] = '\0';
  1985. if (errstr != NULL)
  1986. *errstr = NULL;
  1987. return 1;
  1988. bad:
  1989. if (errstr != NULL)
  1990. *errstr = errbuf;
  1991. return 0;
  1992. }
  1993. /*
  1994. * Verify that a environment variable name (not including initial '$') is
  1995. * valid; consisting of one or more alphanumeric or underscore characters only.
  1996. * Returns 1 on valid, 0 otherwise.
  1997. */
  1998. int
  1999. valid_env_name(const char *name)
  2000. {
  2001. const char *cp;
  2002. if (name[0] == '\0')
  2003. return 0;
  2004. for (cp = name; *cp != '\0'; cp++) {
  2005. if (!isalnum((u_char)*cp) && *cp != '_')
  2006. return 0;
  2007. }
  2008. return 1;
  2009. }
  2010. const char *
  2011. atoi_err(const char *nptr, int *val)
  2012. {
  2013. const char *errstr = NULL;
  2014. long long num;
  2015. if (nptr == NULL || *nptr == '\0')
  2016. return "missing";
  2017. num = strtonum(nptr, 0, INT_MAX, &errstr);
  2018. if (errstr == NULL)
  2019. *val = (int)num;
  2020. return errstr;
  2021. }
  2022. int
  2023. parse_absolute_time(const char *s, uint64_t *tp)
  2024. {
  2025. struct tm tm;
  2026. time_t tt;
  2027. char buf[32], *fmt;
  2028. *tp = 0;
  2029. /*
  2030. * POSIX strptime says "The application shall ensure that there
  2031. * is white-space or other non-alphanumeric characters between
  2032. * any two conversion specifications" so arrange things this way.
  2033. */
  2034. switch (strlen(s)) {
  2035. case 8: /* YYYYMMDD */
  2036. fmt = "%Y-%m-%d";
  2037. snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2s", s, s + 4, s + 6);
  2038. break;
  2039. case 12: /* YYYYMMDDHHMM */
  2040. fmt = "%Y-%m-%dT%H:%M";
  2041. snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s",
  2042. s, s + 4, s + 6, s + 8, s + 10);
  2043. break;
  2044. case 14: /* YYYYMMDDHHMMSS */
  2045. fmt = "%Y-%m-%dT%H:%M:%S";
  2046. snprintf(buf, sizeof(buf), "%.4s-%.2s-%.2sT%.2s:%.2s:%.2s",
  2047. s, s + 4, s + 6, s + 8, s + 10, s + 12);
  2048. break;
  2049. default:
  2050. return SSH_ERR_INVALID_FORMAT;
  2051. }
  2052. memset(&tm, 0, sizeof(tm));
  2053. if (strptime(buf, fmt, &tm) == NULL)
  2054. return SSH_ERR_INVALID_FORMAT;
  2055. if ((tt = mktime(&tm)) < 0)
  2056. return SSH_ERR_INVALID_FORMAT;
  2057. /* success */
  2058. *tp = (uint64_t)tt;
  2059. return 0;
  2060. }
  2061. void
  2062. format_absolute_time(uint64_t t, char *buf, size_t len)
  2063. {
  2064. time_t tt = t > INT_MAX ? INT_MAX : t; /* XXX revisit in 2038 :P */
  2065. struct tm tm;
  2066. localtime_r(&tt, &tm);
  2067. strftime(buf, len, "%Y-%m-%dT%H:%M:%S", &tm);
  2068. }
  2069. /* check if path is absolute */
  2070. int
  2071. path_absolute(const char *path)
  2072. {
  2073. return (*path == '/') ? 1 : 0;
  2074. }
  2075. void
  2076. skip_space(char **cpp)
  2077. {
  2078. char *cp;
  2079. for (cp = *cpp; *cp == ' ' || *cp == '\t'; cp++)
  2080. ;
  2081. *cpp = cp;
  2082. }
  2083. /* authorized_key-style options parsing helpers */
  2084. /*
  2085. * Match flag 'opt' in *optsp, and if allow_negate is set then also match
  2086. * 'no-opt'. Returns -1 if option not matched, 1 if option matches or 0
  2087. * if negated option matches.
  2088. * If the option or negated option matches, then *optsp is updated to
  2089. * point to the first character after the option.
  2090. */
  2091. int
  2092. opt_flag(const char *opt, int allow_negate, const char **optsp)
  2093. {
  2094. size_t opt_len = strlen(opt);
  2095. const char *opts = *optsp;
  2096. int negate = 0;
  2097. if (allow_negate && strncasecmp(opts, "no-", 3) == 0) {
  2098. opts += 3;
  2099. negate = 1;
  2100. }
  2101. if (strncasecmp(opts, opt, opt_len) == 0) {
  2102. *optsp = opts + opt_len;
  2103. return negate ? 0 : 1;
  2104. }
  2105. return -1;
  2106. }
  2107. char *
  2108. opt_dequote(const char **sp, const char **errstrp)
  2109. {
  2110. const char *s = *sp;
  2111. char *ret;
  2112. size_t i;
  2113. *errstrp = NULL;
  2114. if (*s != '"') {
  2115. *errstrp = "missing start quote";
  2116. return NULL;
  2117. }
  2118. s++;
  2119. if ((ret = malloc(strlen((s)) + 1)) == NULL) {
  2120. *errstrp = "memory allocation failed";
  2121. return NULL;
  2122. }
  2123. for (i = 0; *s != '\0' && *s != '"';) {
  2124. if (s[0] == '\\' && s[1] == '"')
  2125. s++;
  2126. ret[i++] = *s++;
  2127. }
  2128. if (*s == '\0') {
  2129. *errstrp = "missing end quote";
  2130. free(ret);
  2131. return NULL;
  2132. }
  2133. ret[i] = '\0';
  2134. s++;
  2135. *sp = s;
  2136. return ret;
  2137. }
  2138. int
  2139. opt_match(const char **opts, const char *term)
  2140. {
  2141. if (strncasecmp((*opts), term, strlen(term)) == 0 &&
  2142. (*opts)[strlen(term)] == '=') {
  2143. *opts += strlen(term) + 1;
  2144. return 1;
  2145. }
  2146. return 0;
  2147. }
  2148. void
  2149. opt_array_append2(const char *file, const int line, const char *directive,
  2150. char ***array, int **iarray, u_int *lp, const char *s, int i)
  2151. {
  2152. if (*lp >= INT_MAX)
  2153. fatal("%s line %d: Too many %s entries", file, line, directive);
  2154. if (iarray != NULL) {
  2155. *iarray = xrecallocarray(*iarray, *lp, *lp + 1,
  2156. sizeof(**iarray));
  2157. (*iarray)[*lp] = i;
  2158. }
  2159. *array = xrecallocarray(*array, *lp, *lp + 1, sizeof(**array));
  2160. (*array)[*lp] = xstrdup(s);
  2161. (*lp)++;
  2162. }
  2163. void
  2164. opt_array_append(const char *file, const int line, const char *directive,
  2165. char ***array, u_int *lp, const char *s)
  2166. {
  2167. opt_array_append2(file, line, directive, array, NULL, lp, s, 0);
  2168. }
  2169. sshsig_t
  2170. ssh_signal(int signum, sshsig_t handler)
  2171. {
  2172. struct sigaction sa, osa;
  2173. /* mask all other signals while in handler */
  2174. memset(&sa, 0, sizeof(sa));
  2175. sa.sa_handler = handler;
  2176. sigfillset(&sa.sa_mask);
  2177. #if defined(SA_RESTART) && !defined(NO_SA_RESTART)
  2178. if (signum != SIGALRM)
  2179. sa.sa_flags = SA_RESTART;
  2180. #endif
  2181. if (sigaction(signum, &sa, &osa) == -1) {
  2182. debug3("sigaction(%s): %s", strsignal(signum), strerror(errno));
  2183. return SIG_ERR;
  2184. }
  2185. return osa.sa_handler;
  2186. }
  2187. int
  2188. stdfd_devnull(int do_stdin, int do_stdout, int do_stderr)
  2189. {
  2190. int devnull, ret = 0;
  2191. if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
  2192. error("open %s: %s", _PATH_DEVNULL,
  2193. strerror(errno));
  2194. return -1;
  2195. }
  2196. if ((do_stdin && dup2(devnull, STDIN_FILENO) == -1) ||
  2197. (do_stdout && dup2(devnull, STDOUT_FILENO) == -1) ||
  2198. (do_stderr && dup2(devnull, STDERR_FILENO) == -1)) {
  2199. error("dup2: %s", strerror(errno));
  2200. ret = -1;
  2201. }
  2202. if (devnull > STDERR_FILENO)
  2203. close(devnull);
  2204. return ret;
  2205. }
  2206. /*
  2207. * Runs command in a subprocess with a minimal environment.
  2208. * Returns pid on success, 0 on failure.
  2209. * The child stdout and stderr maybe captured, left attached or sent to
  2210. * /dev/null depending on the contents of flags.
  2211. * "tag" is prepended to log messages.
  2212. * NB. "command" is only used for logging; the actual command executed is
  2213. * av[0].
  2214. */
  2215. pid_t
  2216. subprocess(const char *tag, const char *command,
  2217. int ac, char **av, FILE **child, u_int flags,
  2218. struct passwd *pw, privdrop_fn *drop_privs, privrestore_fn *restore_privs)
  2219. {
  2220. FILE *f = NULL;
  2221. struct stat st;
  2222. int fd, devnull, p[2], i;
  2223. pid_t pid;
  2224. char *cp, errmsg[512];
  2225. u_int nenv = 0;
  2226. char **env = NULL;
  2227. /* If dropping privs, then must specify user and restore function */
  2228. if (drop_privs != NULL && (pw == NULL || restore_privs == NULL)) {
  2229. error("%s: inconsistent arguments", tag); /* XXX fatal? */
  2230. return 0;
  2231. }
  2232. if (pw == NULL && (pw = getpwuid(getuid())) == NULL) {
  2233. error("%s: no user for current uid", tag);
  2234. return 0;
  2235. }
  2236. if (child != NULL)
  2237. *child = NULL;
  2238. debug3("%s command \"%s\" running as %s (flags 0x%x)",
  2239. tag, command, pw->pw_name, flags);
  2240. /* Check consistency */
  2241. if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
  2242. (flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0) {
  2243. error("inconsistent flags");
  2244. return 0;
  2245. }
  2246. if (((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0) != (child == NULL)) {
  2247. error("inconsistent flags/output");
  2248. return 0;
  2249. }
  2250. /*
  2251. * If executing an explicit binary, then verify the it exists
  2252. * and appears safe-ish to execute
  2253. */
  2254. if (!path_absolute(av[0])) {
  2255. error("%s path is not absolute", tag);
  2256. return 0;
  2257. }
  2258. if (drop_privs != NULL)
  2259. drop_privs(pw);
  2260. if (stat(av[0], &st) == -1) {
  2261. error("Could not stat %s \"%s\": %s", tag,
  2262. av[0], strerror(errno));
  2263. goto restore_return;
  2264. }
  2265. if ((flags & SSH_SUBPROCESS_UNSAFE_PATH) == 0 &&
  2266. safe_path(av[0], &st, NULL, 0, errmsg, sizeof(errmsg)) != 0) {
  2267. error("Unsafe %s \"%s\": %s", tag, av[0], errmsg);
  2268. goto restore_return;
  2269. }
  2270. /* Prepare to keep the child's stdout if requested */
  2271. if (pipe(p) == -1) {
  2272. error("%s: pipe: %s", tag, strerror(errno));
  2273. restore_return:
  2274. if (restore_privs != NULL)
  2275. restore_privs();
  2276. return 0;
  2277. }
  2278. if (restore_privs != NULL)
  2279. restore_privs();
  2280. switch ((pid = fork())) {
  2281. case -1: /* error */
  2282. error("%s: fork: %s", tag, strerror(errno));
  2283. close(p[0]);
  2284. close(p[1]);
  2285. return 0;
  2286. case 0: /* child */
  2287. /* Prepare a minimal environment for the child. */
  2288. if ((flags & SSH_SUBPROCESS_PRESERVE_ENV) == 0) {
  2289. nenv = 5;
  2290. env = xcalloc(sizeof(*env), nenv);
  2291. child_set_env(&env, &nenv, "PATH", _PATH_STDPATH);
  2292. child_set_env(&env, &nenv, "USER", pw->pw_name);
  2293. child_set_env(&env, &nenv, "LOGNAME", pw->pw_name);
  2294. child_set_env(&env, &nenv, "HOME", pw->pw_dir);
  2295. if ((cp = getenv("LANG")) != NULL)
  2296. child_set_env(&env, &nenv, "LANG", cp);
  2297. }
  2298. for (i = 1; i < NSIG; i++)
  2299. ssh_signal(i, SIG_DFL);
  2300. if ((devnull = open(_PATH_DEVNULL, O_RDWR)) == -1) {
  2301. error("%s: open %s: %s", tag, _PATH_DEVNULL,
  2302. strerror(errno));
  2303. _exit(1);
  2304. }
  2305. if (dup2(devnull, STDIN_FILENO) == -1) {
  2306. error("%s: dup2: %s", tag, strerror(errno));
  2307. _exit(1);
  2308. }
  2309. /* Set up stdout as requested; leave stderr in place for now. */
  2310. fd = -1;
  2311. if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) != 0)
  2312. fd = p[1];
  2313. else if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0)
  2314. fd = devnull;
  2315. if (fd != -1 && dup2(fd, STDOUT_FILENO) == -1) {
  2316. error("%s: dup2: %s", tag, strerror(errno));
  2317. _exit(1);
  2318. }
  2319. closefrom(STDERR_FILENO + 1);
  2320. if (setresgid(pw->pw_gid, pw->pw_gid, pw->pw_gid) == -1) {
  2321. error("%s: setresgid %u: %s", tag, (u_int)pw->pw_gid,
  2322. strerror(errno));
  2323. _exit(1);
  2324. }
  2325. if (setresuid(pw->pw_uid, pw->pw_uid, pw->pw_uid) == -1) {
  2326. error("%s: setresuid %u: %s", tag, (u_int)pw->pw_uid,
  2327. strerror(errno));
  2328. _exit(1);
  2329. }
  2330. /* stdin is pointed to /dev/null at this point */
  2331. if ((flags & SSH_SUBPROCESS_STDOUT_DISCARD) != 0 &&
  2332. dup2(STDIN_FILENO, STDERR_FILENO) == -1) {
  2333. error("%s: dup2: %s", tag, strerror(errno));
  2334. _exit(1);
  2335. }
  2336. if (env != NULL)
  2337. execve(av[0], av, env);
  2338. else
  2339. execv(av[0], av);
  2340. error("%s %s \"%s\": %s", tag, env == NULL ? "execv" : "execve",
  2341. command, strerror(errno));
  2342. _exit(127);
  2343. default: /* parent */
  2344. break;
  2345. }
  2346. close(p[1]);
  2347. if ((flags & SSH_SUBPROCESS_STDOUT_CAPTURE) == 0)
  2348. close(p[0]);
  2349. else if ((f = fdopen(p[0], "r")) == NULL) {
  2350. error("%s: fdopen: %s", tag, strerror(errno));
  2351. close(p[0]);
  2352. /* Don't leave zombie child */
  2353. kill(pid, SIGTERM);
  2354. while (waitpid(pid, NULL, 0) == -1 && errno == EINTR)
  2355. ;
  2356. return 0;
  2357. }
  2358. /* Success */
  2359. debug3("%s pid %ld", tag, (long)pid);
  2360. if (child != NULL)
  2361. *child = f;
  2362. return pid;
  2363. }