tun.c 14 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578
  1. /*
  2. * OpenConnect (SSL + DTLS) VPN client
  3. *
  4. * Copyright © 2008-2015 Intel Corporation.
  5. *
  6. * Author: David Woodhouse <dwmw2@infradead.org>
  7. *
  8. * This program is free software; you can redistribute it and/or
  9. * modify it under the terms of the GNU Lesser General Public License
  10. * version 2.1, as published by the Free Software Foundation.
  11. *
  12. * This program is distributed in the hope that it will be useful, but
  13. * WITHOUT ANY WARRANTY; without even the implied warranty of
  14. * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
  15. * Lesser General Public License for more details.
  16. */
  17. #include <config.h>
  18. #include "openconnect-internal.h"
  19. #include <unistd.h>
  20. #include <sys/types.h>
  21. #include <sys/stat.h>
  22. #include <fcntl.h>
  23. #include <sys/wait.h>
  24. #include <sys/ioctl.h>
  25. #include <sys/socket.h>
  26. #include <netinet/in_systm.h>
  27. #include <netinet/in.h>
  28. #include <netinet/ip.h>
  29. #include <net/if.h>
  30. #include <arpa/inet.h>
  31. #if defined(__APPLE__) && defined(HAVE_NET_UTUN_H)
  32. #include <sys/kern_control.h>
  33. #include <sys/sys_domain.h>
  34. #include <net/if_utun.h>
  35. #endif
  36. #include <errno.h>
  37. #include <ctype.h>
  38. #include <signal.h>
  39. #include <stdio.h>
  40. #include <stdlib.h>
  41. #include <string.h>
  42. /*
  43. * If an if_tun.h include file was found anywhere (by the Makefile), it's
  44. * included. Else, we end up assuming that we have BSD-style devices such
  45. * as /dev/tun0 etc.
  46. */
  47. #ifdef IF_TUN_HDR
  48. #include IF_TUN_HDR
  49. #endif
  50. /*
  51. * The OS X tun/tap driver doesn't provide a header file; you're expected
  52. * to define this for yourself.
  53. */
  54. #ifdef __APPLE__
  55. #define TUNSIFHEAD _IOW('t', 96, int)
  56. #endif
  57. /*
  58. * OpenBSD always puts the protocol family prefix onto packets. Other
  59. * systems let us enable that with the TUNSIFHEAD ioctl, and some of them
  60. * (e.g. FreeBSD) _need_ it otherwise they'll interpret IPv6 packets as IPv4.
  61. */
  62. #if defined(__OpenBSD__) || defined(TUNSIFHEAD)
  63. #define TUN_HAS_AF_PREFIX 1
  64. #endif
  65. #ifdef __sun__
  66. #include <stropts.h>
  67. #include <sys/sockio.h>
  68. #ifndef TUNNEWPPA
  69. #error "Install TAP driver from http://www.whiteboard.ne.jp/~admin2/tuntap/"
  70. #endif
  71. static int link_proto(struct openconnect_info *vpninfo, int unit_nr,
  72. const char *devname, uint64_t flags)
  73. {
  74. int ip_fd, mux_id, tun2_fd;
  75. struct lifreq ifr;
  76. tun2_fd = open("/dev/tun", O_RDWR);
  77. if (tun2_fd < 0) {
  78. vpn_perror(vpninfo, _("Could not open /dev/tun for plumbing"));
  79. return -EIO;
  80. }
  81. if (ioctl(tun2_fd, I_PUSH, "ip") < 0) {
  82. vpn_perror(vpninfo, _("Can't push IP"));
  83. close(tun2_fd);
  84. return -EIO;
  85. }
  86. sprintf(ifr.lifr_name, "tun%d", unit_nr);
  87. ifr.lifr_ppa = unit_nr;
  88. ifr.lifr_flags = flags;
  89. if (ioctl(tun2_fd, SIOCSLIFNAME, &ifr) < 0) {
  90. vpn_perror(vpninfo, _("Can't set ifname"));
  91. close(tun2_fd);
  92. return -1;
  93. }
  94. ip_fd = open(devname, O_RDWR);
  95. if (ip_fd < 0) {
  96. vpn_progress(vpninfo, PRG_ERR, _("Can't open %s: %s\n"),
  97. devname, strerror(errno));
  98. close(tun2_fd);
  99. return -1;
  100. }
  101. mux_id = ioctl(ip_fd, I_LINK, tun2_fd);
  102. if (mux_id < 0) {
  103. vpn_progress(vpninfo, PRG_ERR,
  104. _("Can't plumb %s for IPv%d: %s\n"),
  105. ifr.lifr_name, (flags == IFF_IPV4) ? 4 : 6,
  106. strerror(errno));
  107. close(tun2_fd);
  108. close(ip_fd);
  109. return -1;
  110. }
  111. close(tun2_fd);
  112. return ip_fd;
  113. }
  114. intptr_t os_setup_tun(struct openconnect_info *vpninfo)
  115. {
  116. int tun_fd = -1;
  117. static char tun_name[80];
  118. int unit_nr;
  119. tun_fd = open("/dev/tun", O_RDWR);
  120. if (tun_fd < 0) {
  121. vpn_perror(vpninfo, _("open /dev/tun"));
  122. return -EIO;
  123. }
  124. unit_nr = ioctl(tun_fd, TUNNEWPPA, -1);
  125. if (unit_nr < 0) {
  126. vpn_perror(vpninfo, _("Failed to create new tun"));
  127. close(tun_fd);
  128. return -EIO;
  129. }
  130. if (ioctl(tun_fd, I_SRDOPT, RMSGD) < 0) {
  131. vpn_perror(vpninfo, _("Failed to put tun file descriptor into message-discard mode"));
  132. close(tun_fd);
  133. return -EIO;
  134. }
  135. sprintf(tun_name, "tun%d", unit_nr);
  136. vpninfo->ifname = strdup(tun_name);
  137. vpninfo->ip_fd = link_proto(vpninfo, unit_nr, "/dev/udp", IFF_IPV4);
  138. if (vpninfo->ip_fd < 0) {
  139. close(tun_fd);
  140. return -EIO;
  141. }
  142. if (vpninfo->ip_info.addr6 || vpninfo->ip_info.netmask6) {
  143. vpninfo->ip6_fd = link_proto(vpninfo, unit_nr, "/dev/udp6", IFF_IPV6);
  144. if (vpninfo->ip6_fd < 0) {
  145. close(tun_fd);
  146. close(vpninfo->ip_fd);
  147. vpninfo->ip_fd = -1;
  148. return -EIO;
  149. }
  150. } else
  151. vpninfo->ip6_fd = -1;
  152. return tun_fd;
  153. }
  154. #elif defined(__native_client__)
  155. intptr_t os_setup_tun(struct openconnect_info *vpninfo)
  156. {
  157. vpn_progress(vpninfo, PRG_ERR,
  158. _("tun device is unsupported on this platform\n"));
  159. return -EOPNOTSUPP;
  160. }
  161. #else /* !__sun__ && !__native_client__ */
  162. static void ifreq_set_ifname(struct openconnect_info *vpninfo, struct ifreq *ifr)
  163. {
  164. char *ifname = openconnect_utf8_to_legacy(vpninfo, vpninfo->ifname);
  165. strncpy(ifr->ifr_name, ifname, sizeof(ifr->ifr_name) - 1);
  166. if (ifname != vpninfo->ifname)
  167. free(ifname);
  168. }
  169. #ifdef IFF_TUN /* Linux */
  170. intptr_t os_setup_tun(struct openconnect_info *vpninfo)
  171. {
  172. int tun_fd = -1;
  173. struct ifreq ifr;
  174. int tunerr;
  175. tun_fd = open("/dev/net/tun", O_RDWR);
  176. if (tun_fd < 0) {
  177. /* Android has /dev/tun instead of /dev/net/tun
  178. Since other systems might have too, just try it
  179. as a fallback instead of using ifdef __ANDROID__ */
  180. tunerr = errno;
  181. tun_fd = open("/dev/tun", O_RDWR);
  182. }
  183. if (tun_fd < 0) {
  184. /* If the error on /dev/tun is ENOENT, that's boring.
  185. Use the error we got on /dev/net/tun instead */
  186. if (errno != ENOENT)
  187. tunerr = errno;
  188. vpn_progress(vpninfo, PRG_ERR,
  189. _("Failed to open tun device: %s\n"),
  190. strerror(tunerr));
  191. return -EIO;
  192. }
  193. memset(&ifr, 0, sizeof(ifr));
  194. ifr.ifr_flags = IFF_TUN | IFF_NO_PI;
  195. if (vpninfo->ifname)
  196. ifreq_set_ifname(vpninfo, &ifr);
  197. if (ioctl(tun_fd, TUNSETIFF, (void *) &ifr) < 0) {
  198. int err = errno;
  199. vpn_progress(vpninfo, PRG_ERR,
  200. _("Failed to bind local tun device (TUNSETIFF): %s\n"),
  201. strerror(err));
  202. if (err == EPERM) {
  203. vpn_progress(vpninfo, PRG_ERR,
  204. _("To configure local networking, openconnect must be running as root\n"
  205. "See %s for more information\n"),
  206. "https://www.infradead.org/openconnect/nonroot.html");
  207. }
  208. close(tun_fd);
  209. return -EIO;
  210. }
  211. if (!vpninfo->ifname)
  212. vpninfo->ifname = strdup(ifr.ifr_name);
  213. return tun_fd;
  214. }
  215. #else /* BSD et al, including OS X */
  216. #ifdef SIOCIFCREATE
  217. static int bsd_open_tun(char *tun_name)
  218. {
  219. int fd;
  220. int s;
  221. struct ifreq ifr;
  222. fd = open(tun_name, O_RDWR);
  223. if (fd == -1) {
  224. s = socket(AF_INET, SOCK_DGRAM, 0);
  225. if (s < 0)
  226. return -1;
  227. memset(&ifr, 0, sizeof(ifr));
  228. strncpy(ifr.ifr_name, tun_name + 5, sizeof(ifr.ifr_name) - 1);
  229. if (!ioctl(s, SIOCIFCREATE, &ifr))
  230. fd = open(tun_name, O_RDWR);
  231. close(s);
  232. }
  233. return fd;
  234. }
  235. #else
  236. #define bsd_open_tun(tun_name) open(tun_name, O_RDWR)
  237. #endif
  238. intptr_t os_setup_tun(struct openconnect_info *vpninfo)
  239. {
  240. static char tun_name[80];
  241. int unit_nr = 0;
  242. int tun_fd = -1;
  243. #if defined(__APPLE__) && defined (HAVE_NET_UTUN_H)
  244. /* OS X (since 10.6) can do this as well as the traditional
  245. BSD devices supported via tuntaposx. */
  246. struct sockaddr_ctl sc;
  247. struct ctl_info ci;
  248. if (vpninfo->ifname) {
  249. char *endp = NULL;
  250. if (!strncmp(vpninfo->ifname, "tun", 3))
  251. goto do_bsdtun;
  252. if (strncmp(vpninfo->ifname, "utun", 4) ||
  253. (unit_nr = strtol(vpninfo->ifname + 4, &endp, 10), !endp) ||
  254. (unit_nr && vpninfo->ifname[4] == '0') ||
  255. *endp) {
  256. vpn_progress(vpninfo, PRG_ERR,
  257. _("Invalid interface name '%s'; must match 'utun%%d' or 'tun%%d'\n"),
  258. vpninfo->ifname);
  259. return -EINVAL;
  260. }
  261. }
  262. tun_fd = socket(PF_SYSTEM, SOCK_DGRAM, SYSPROTO_CONTROL);
  263. if (tun_fd < 0) {
  264. vpn_progress(vpninfo, PRG_ERR,
  265. _("Failed to open SYSPROTO_CONTROL socket: %s\n"),
  266. strerror(errno));
  267. goto utun_fail;
  268. }
  269. snprintf(ci.ctl_name, sizeof(ci.ctl_name), UTUN_CONTROL_NAME);
  270. if (ioctl(tun_fd, CTLIOCGINFO, &ci) == -1) {
  271. vpn_progress(vpninfo, PRG_ERR,
  272. _("Failed to query utun control id: %s\n"),
  273. strerror(errno));
  274. close(tun_fd);
  275. goto utun_fail;
  276. }
  277. sc.sc_id = ci.ctl_id;
  278. sc.sc_len = sizeof(sc);
  279. sc.sc_family = AF_SYSTEM;
  280. sc.ss_sysaddr = AF_SYS_CONTROL;
  281. do {
  282. sc.sc_unit = unit_nr + 1;
  283. if (!connect(tun_fd, (struct sockaddr *)&sc, sizeof(sc))) {
  284. if (!vpninfo->ifname &&
  285. asprintf(&vpninfo->ifname, "utun%d", unit_nr) == -1) {
  286. vpn_progress(vpninfo, PRG_ERR,
  287. _("Failed to allocate utun device name\n"));
  288. close(tun_fd);
  289. goto utun_fail;
  290. }
  291. return tun_fd;
  292. }
  293. unit_nr++;
  294. } while (sc.sc_unit < 255 && !vpninfo->ifname);
  295. vpn_progress(vpninfo, PRG_ERR,
  296. _("Failed to connect utun unit: %s\n"),
  297. strerror(errno));
  298. close(tun_fd);
  299. utun_fail:
  300. /* If we were explicitly asked for a utun device, fail. Else try tuntaposx */
  301. if (vpninfo->ifname)
  302. return -EIO;
  303. tun_fd = -1;
  304. do_bsdtun:
  305. #endif /* __APPLE__ && HAVE_NET_UTUN_H */
  306. if (vpninfo->ifname) {
  307. char *endp = NULL;
  308. if (strncmp(vpninfo->ifname, "tun", 3) ||
  309. ((void)strtol(vpninfo->ifname + 3, &endp, 10), !endp) ||
  310. *endp) {
  311. vpn_progress(vpninfo, PRG_ERR,
  312. _("Invalid interface name '%s'; must match 'tun%%d'\n"),
  313. vpninfo->ifname);
  314. return -EINVAL;
  315. }
  316. snprintf(tun_name, sizeof(tun_name),
  317. "/dev/%s", vpninfo->ifname);
  318. tun_fd = bsd_open_tun(tun_name);
  319. if (tun_fd < 0) {
  320. vpn_progress(vpninfo, PRG_ERR,
  321. _("Cannot open '%s': %s\n"),
  322. tun_name, strerror(errno));
  323. return -EINVAL;
  324. }
  325. }
  326. #ifdef HAVE_FDEVNAME_R
  327. /* We don't have to iterate over the possible devices; on FreeBSD
  328. at least, opening /dev/tun will give us the next available
  329. device. */
  330. if (tun_fd < 0) {
  331. tun_fd = open("/dev/tun", O_RDWR);
  332. if (tun_fd >= 0) {
  333. if (!fdevname_r(tun_fd, tun_name, sizeof(tun_name)) ||
  334. strncmp(tun_name, "tun", 3)) {
  335. close(tun_fd);
  336. tun_fd = -1;
  337. } else
  338. vpninfo->ifname = strdup(tun_name);
  339. }
  340. }
  341. #endif
  342. if (tun_fd < 0) {
  343. for (unit_nr = 0; unit_nr < 255; unit_nr++) {
  344. sprintf(tun_name, "/dev/tun%d", unit_nr);
  345. tun_fd = bsd_open_tun(tun_name);
  346. if (tun_fd >= 0)
  347. break;
  348. }
  349. if (tun_fd < 0) {
  350. vpn_progress(vpninfo, PRG_ERR,
  351. _("Failed to open tun device: %s\n"),
  352. strerror(errno));
  353. return -EIO;
  354. }
  355. vpninfo->ifname = strdup(tun_name + 5);
  356. }
  357. #ifdef TUNSIFHEAD
  358. unit_nr = 1;
  359. if (ioctl(tun_fd, TUNSIFHEAD, &unit_nr) < 0) {
  360. vpn_perror(vpninfo, _("TUNSIFHEAD"));
  361. close(tun_fd);
  362. return -EIO;
  363. }
  364. #endif
  365. return tun_fd;
  366. }
  367. #endif /* !IFF_TUN (i.e. BSD) */
  368. #endif /* !__sun__ */
  369. int openconnect_setup_tun_fd(struct openconnect_info *vpninfo, int tun_fd)
  370. {
  371. set_fd_cloexec(tun_fd);
  372. if (vpninfo->tun_fd != -1)
  373. unmonitor_fd(vpninfo, tun);
  374. vpninfo->tun_fd = tun_fd;
  375. if (set_sock_nonblock(tun_fd)) {
  376. vpn_progress(vpninfo, PRG_ERR, _("Failed to make tun socket nonblocking: %s\n"),
  377. strerror(errno));
  378. return -EIO;
  379. }
  380. #ifdef HAVE_VHOST
  381. if (!setup_vhost(vpninfo, tun_fd))
  382. return 0;
  383. #endif
  384. monitor_fd_new(vpninfo, tun);
  385. monitor_read_fd(vpninfo, tun);
  386. return 0;
  387. }
  388. int openconnect_setup_tun_script(struct openconnect_info *vpninfo,
  389. const char *tun_script)
  390. {
  391. pid_t child;
  392. int fds[2];
  393. STRDUP(vpninfo->vpnc_script, tun_script);
  394. vpninfo->script_tun = 1;
  395. prepare_script_env(vpninfo);
  396. if (socketpair(AF_UNIX, SOCK_DGRAM, 0, fds)) {
  397. vpn_progress(vpninfo, PRG_ERR, _("socketpair failed: %s\n"), strerror(errno));
  398. return -EIO;
  399. }
  400. child = fork();
  401. if (child < 0) {
  402. vpn_progress(vpninfo, PRG_ERR, _("fork failed: %s\n"), strerror(errno));
  403. return -EIO;
  404. } else if (!child) {
  405. if (setpgid(0, getpid()) < 0)
  406. perror(_("setpgid"));
  407. close(fds[0]);
  408. script_setenv_int(vpninfo, "VPNFD", fds[1]);
  409. apply_script_env(vpninfo->script_env);
  410. execl("/bin/sh", "/bin/sh", "-c", vpninfo->vpnc_script, NULL);
  411. perror(_("execl"));
  412. exit(1);
  413. }
  414. close(fds[1]);
  415. vpninfo->script_tun = child;
  416. vpninfo->ifname = strdup(_("(script)"));
  417. return openconnect_setup_tun_fd(vpninfo, fds[0]);
  418. }
  419. int os_read_tun(struct openconnect_info *vpninfo, struct pkt *pkt)
  420. {
  421. int prefix_size = 0;
  422. int len;
  423. #ifdef TUN_HAS_AF_PREFIX
  424. if (!vpninfo->script_tun)
  425. prefix_size = sizeof(int);
  426. #endif
  427. /* Sanity. Just non-blocking reads on a select()able file descriptor... */
  428. len = read(vpninfo->tun_fd, pkt->data - prefix_size, pkt->len + prefix_size);
  429. if (len <= prefix_size)
  430. return -1;
  431. pkt->len = len - prefix_size;
  432. return 0;
  433. }
  434. int os_write_tun(struct openconnect_info *vpninfo, struct pkt *pkt)
  435. {
  436. unsigned char *data = pkt->data;
  437. int len = pkt->len;
  438. #ifdef TUN_HAS_AF_PREFIX
  439. if (!vpninfo->script_tun) {
  440. struct ip *iph = (void *)data;
  441. int type;
  442. if (iph->ip_v == 6)
  443. type = AF_INET6;
  444. else if (iph->ip_v == 4)
  445. type = AF_INET;
  446. else {
  447. static int complained; /* static variable initialised to 0 */
  448. if (!complained) {
  449. complained = 1;
  450. vpn_progress(vpninfo, PRG_ERR,
  451. _("Unknown packet (len %d) received: %02x %02x %02x %02x...\n"),
  452. len, data[0], data[1], data[2], data[3]);
  453. }
  454. return 0;
  455. }
  456. data -= sizeof(int);
  457. len += sizeof(int);
  458. *(int *)data = htonl(type);
  459. }
  460. #endif
  461. if (write(vpninfo->tun_fd, data, len) < 0) {
  462. /* Handle death of "script" socket */
  463. if (vpninfo->script_tun && errno == ENOTCONN) {
  464. vpninfo->quit_reason = "Client connection terminated";
  465. return -1;
  466. }
  467. /* The tun device in the Linux kernel returns -ENOMEM when
  468. * the queue is full, so theoretically we could check for
  469. * that and retry too. But it doesn't let us poll() for
  470. * the no-longer-full situation, so let's not bother. */
  471. if (errno == ENOBUFS || errno == EAGAIN || errno == EWOULDBLOCK) {
  472. monitor_write_fd(vpninfo, tun);
  473. return -1;
  474. }
  475. vpn_progress(vpninfo, PRG_ERR,
  476. _("Failed to write incoming packet: %s\n"),
  477. strerror(errno));
  478. }
  479. return 0;
  480. }
  481. void os_shutdown_tun(struct openconnect_info *vpninfo)
  482. {
  483. if (vpninfo->script_tun) {
  484. /* nuke the whole process group */
  485. kill(-vpninfo->script_tun, SIGHUP);
  486. } else {
  487. script_config_tun(vpninfo, "disconnect");
  488. #ifdef __sun__
  489. close(vpninfo->ip_fd);
  490. vpninfo->ip_fd = -1;
  491. if (vpninfo->ip6_fd != -1) {
  492. close(vpninfo->ip6_fd);
  493. vpninfo->ip6_fd = -1;
  494. }
  495. #endif
  496. }
  497. #ifdef HAVE_VHOST
  498. shutdown_vhost(vpninfo);
  499. #endif
  500. if (vpninfo->vpnc_script)
  501. close(vpninfo->tun_fd);
  502. vpninfo->tun_fd = -1;
  503. }