OpenVPN
tun_afunix.c
Go to the documentation of this file.
1/*
2 * OpenVPN -- An application to securely tunnel IP networks
3 * over a single TCP/UDP port, with support for SSL/TLS-based
4 * session authentication and key exchange,
5 * packet encryption, packet authentication, and
6 * packet compression.
7 *
8 * Copyright (C) 2002-2024 OpenVPN Inc <sales@openvpn.net>
9 *
10 * This program is free software; you can redistribute it and/or modify
11 * it under the terms of the GNU General Public License version 2
12 * as published by the Free Software Foundation.
13 *
14 * This program is distributed in the hope that it will be useful,
15 * but WITHOUT ANY WARRANTY; without even the implied warranty of
16 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
17 * GNU General Public License for more details.
18 *
19 * You should have received a copy of the GNU General Public License along
20 * with this program; if not, write to the Free Software Foundation, Inc.,
21 * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
22 */
23
24#ifdef HAVE_CONFIG_H
25#include "config.h"
26#endif
27
28#include "syshead.h"
29
30#include "tun.h"
31#include "fdmisc.h"
32#include "run_command.h"
33#include "manage.h"
34#include "win32.h"
35#include "wfp_block.h"
36#include "argv.h"
37#include "options.h"
38#include "socket.h"
39
40#ifndef WIN32
41/* Windows does implement some AF_UNIX functionality but key features
42 * like socketpair() and SOCK_DGRAM are missing */
43
44#include <string.h>
45#include <unistd.h>
46#include <sys/wait.h>
47#include <signal.h>
48#include <stdlib.h>
49
50
51
52static void
53tun_afunix_exec_child(const char *dev_node, struct tuntap *tt, struct env_set *env)
54{
55 const char *msgprefix = "ERROR: failure executing process for tun:";
56 struct argv argv = argv_new();
57
58 /* since we know that dev-node starts with unix: we can just skip that
59 * to get the program name */
60 const char *program = dev_node + strlen("unix:");
61
62 argv_printf(&argv, "%s", program);
63
65 msgprefix);
66 if (!openvpn_waitpid_check(tt->afunix.childprocess, msgprefix, M_WARN))
67 {
68 tt->afunix.childprocess = 0;
69 }
71}
72
73void
75 int mtu,
76 struct tuntap *tt,
77 struct env_set *orig_env)
78{
79 struct gc_arena gc = gc_new();
80
81 int fds[2];
82 if (!(socketpair(AF_UNIX, SOCK_DGRAM, 0, fds) == 0))
83 {
84 msg(M_ERR, "Cannot create socket pair for AF_UNIX socket to external "
85 "program");
86 return;
87 }
88
89
90 /* Ensure that the buffer sizes are decently sized. Otherwise macOS will
91 * just have 2048 */
92 struct socket_buffer_size newsizes = {65536, 65536 };
93 socket_set_buffers(fds[0], &newsizes, false);
94 socket_set_buffers(fds[1], &newsizes, false);
95
96 /* Use the first file descriptor for our side and avoid passing it
97 * to the child */
98 tt->fd = fds[1];
99 set_cloexec(tt->fd);
100
101 /* Make a copy of the env, so we do not need to delete our custom
102 * environment variables later */
103 struct env_set *env = env_set_create(&gc);
104 env_set_inherit(env, orig_env);
105
106 setenv_int(env, "TUNTAP_SOCKET_FD", fds[0]);
107 setenv_str(env, "TUNTAP_DEV_TYPE", dev_type_string(o->dev, o->dev_type));
108 setenv_int(env, "TUNTAP_MTU", mtu);
110 {
111 setenv_str(env, "ifconfig_gateway", o->route_default_gateway);
112 }
113 if (o->lladdr)
114 {
115 setenv_str(env, "TUNTAP_LLADDR", o->lladdr);
116 }
117
118 tun_afunix_exec_child(o->dev_node, tt, env);
119
120 close(fds[0]);
121
122 /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */
123 tt->actual_name = string_alloc("internal:af_unix", NULL);
124
125 gc_free(&gc);
126}
127
128void
130{
131 ASSERT(tt);
132 if (tt->fd >= 0)
133 {
134 close(tt->fd);
135 tt->fd = 0;
136 }
137 kill(tt->afunix.childprocess, SIGINT);
138
139 free(tt->actual_name);
140 free(tt);
141}
142
143ssize_t
144write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
145{
146 const char *msg = "ERROR: failure during write to AF_UNIX socket: ";
148 {
149 tt->afunix.childprocess = 0;
150 return -ENXIO;
151 }
152
153 return write(tt->fd, buf, len);
154}
155
156ssize_t
157read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
158{
159 const char *msg = "ERROR: failure during read from AF_UNIX socket: ";
161 {
162 tt->afunix.childprocess = 0;
163 }
164 /* do an actual read on the file descriptor even in the error case since
165 * we otherwise loop on this on this from select and spam the console
166 * with error messages */
167 return read(tt->fd, buf, len);
168}
169#else /* ifndef WIN32 */
170void
171open_tun_afunix(const char *dev, const char *dev_type, int mtu,
172 struct tuntap *tt, struct env_set env)
173{
174 msg(M_ERR, "AF_UNIX socket support not available on this platform");
175}
176
177void
178close_tun_afunix(struct tuntap *tt)
179{
180 /* should never be called as open_tun_afunix always fails */
181 ASSERT(0);
182}
183
184ssize_t
185write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
186{
187 /* should never be called as open_tun_afunix always fails */
188 ASSERT(0);
189}
190
191ssize_t
192read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
193{
194 /* should never be called as open_tun_afunix always fails */
195 ASSERT(0);
196}
197
198#endif /* ifndef WIN32 */
void argv_free(struct argv *a)
Frees all memory allocations allocated by the struct argv related functions.
Definition argv.c:102
bool argv_printf(struct argv *argres, const char *format,...)
printf() variant which populates a struct argv.
Definition argv.c:440
struct argv argv_new(void)
Allocates a new struct argv and ensures it is initialised.
Definition argv.c:88
char * string_alloc(const char *str, struct gc_arena *gc)
Definition buffer.c:649
static void gc_free(struct gc_arena *a)
Definition buffer.h:1033
static struct gc_arena gc_new(void)
Definition buffer.h:1025
void setenv_int(struct env_set *es, const char *name, int value)
Definition env_set.c:267
void setenv_str(struct env_set *es, const char *name, const char *value)
Definition env_set.c:283
void env_set_inherit(struct env_set *es, const struct env_set *src)
Definition env_set.c:238
struct env_set * env_set_create(struct gc_arena *gc)
Definition env_set.c:156
void set_cloexec(socket_descriptor_t fd)
Definition fdmisc.c:79
@ write
@ read
#define M_ERR
Definition error.h:105
#define msg(flags,...)
Definition error.h:144
#define ASSERT(x)
Definition error.h:195
#define M_WARN
Definition error.h:91
bool openvpn_waitpid_check(pid_t pid, const char *msg_prefix, int msglevel)
Checks if a running process is still running.
int openvpn_execve_check(const struct argv *a, const struct env_set *es, const unsigned int flags, const char *error_message)
#define S_NOWAITPID
instead of waiting for child process to exit and report the status, return the pid of the child proce...
Definition run_command.h:52
void socket_set_buffers(socket_descriptor_t fd, const struct socket_buffer_size *sbs, bool reduce_size)
Sets the receive and send buffer sizes of a socket descriptor.
Definition socket.c:928
pid_t childprocess
Definition tun.h:171
Definition argv.h:35
Garbage collection arena used to keep track of dynamically allocated memory.
Definition buffer.h:117
const char * dev_type
Definition options.h:317
const char * route_default_gateway
Definition options.h:427
const char * dev_node
Definition options.h:318
const char * lladdr
Definition options.h:319
const char * dev
Definition options.h:316
Definition tun.h:181
char * actual_name
Definition tun.h:205
afunix_context_t afunix
Definition tun.h:250
struct gc_arena gc
Definition test_ssl.c:155
const char * dev_type_string(const char *dev, const char *dev_type)
Definition tun.c:486
void open_tun_afunix(struct options *o, int mtu, struct tuntap *tt, struct env_set *orig_env)
Opens an AF_UNIX based tun device.
Definition tun_afunix.c:74
static void tun_afunix_exec_child(const char *dev_node, struct tuntap *tt, struct env_set *env)
Definition tun_afunix.c:53
ssize_t read_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
Reads a packet from a AF_UNIX based tun device.
Definition tun_afunix.c:157
void close_tun_afunix(struct tuntap *tt)
Closes the socket used for the AF_UNIX based device.
Definition tun_afunix.c:129
ssize_t write_tun_afunix(struct tuntap *tt, uint8_t *buf, int len)
Writes a packet to a AF_UNIX based tun device.
Definition tun_afunix.c:144