summaryrefslogtreecommitdiffstats
path: root/route.c
diff options
context:
space:
mode:
authorjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-07-26 07:27:03 +0000
committerjames <james@e7ae566f-a301-0410-adde-c780ea21d3b5>2008-07-26 07:27:03 +0000
commit5a2e9a2587372aeb4b74fa1aadf53283ed7cae10 (patch)
treebc79922f81699bc51c2ac047309e6ab594eebcd2 /route.c
parent26bb4c740b12cf3f606f657103a1695c23f6b72f (diff)
downloadopenvpn-5a2e9a2587372aeb4b74fa1aadf53283ed7cae10.tar.gz
openvpn-5a2e9a2587372aeb4b74fa1aadf53283ed7cae10.tar.xz
openvpn-5a2e9a2587372aeb4b74fa1aadf53283ed7cae10.zip
Completely revamped the system for calling external programs and scripts:
* All external programs and scripts are now called by execve() on unix and CreateProcess on Windows. * The system() function is no longer used. * Argument lists for external programs and scripts are now built by the new argv_printf function which natively outputs to string arrays (i.e. char *argv[] lists), never truncates its output, and eliminates the security issues inherent in formatting and parsing command lines, and dealing with argument quoting. * The --script-security directive has been added to offer policy controls on OpenVPN's execution of external programs and scripts. Also added a new plugin example (openvpn/plugin/examples/log.c) that logs information to stdout for every plugin method called by OpenVPN. git-svn-id: http://svn.openvpn.net/projects/openvpn/branches/BETA21/openvpn@3122 e7ae566f-a301-0410-adde-c780ea21d3b5
Diffstat (limited to 'route.c')
-rw-r--r--route.c159
1 files changed, 89 insertions, 70 deletions
diff --git a/route.c b/route.c
index 2d9e85a..47a6013 100644
--- a/route.c
+++ b/route.c
@@ -34,6 +34,7 @@
#include "misc.h"
#include "socket.h"
#include "manage.h"
+#include "win32.h"
#include "memdbg.h"
@@ -743,7 +744,7 @@ void
add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
{
struct gc_arena gc;
- struct buffer buf;
+ struct argv argv;
const char *network;
const char *netmask;
const char *gateway;
@@ -753,7 +754,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
return;
gc_init (&gc);
- buf = alloc_buf_gc (256, &gc);
+ argv_init (&argv);
network = print_in_addr_t (r->network, 0, &gc);
netmask = print_in_addr_t (r->netmask, 0, &gc);
@@ -771,35 +772,38 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
#if defined(TARGET_LINUX)
#ifdef CONFIG_FEATURE_IPROUTE
- buf_printf (&buf, "%s route add %s/%d via %s",
+ argv_printf (&argv, "%s route add %s/%d via %s",
iproute_path,
network,
count_netmask_bits(netmask),
gateway);
if (r->metric_defined)
- buf_printf (&buf, " metric %d", r->metric);
+ argv_printf_cat (&argv, "metric %d", r->metric);
#else
- buf_printf (&buf, ROUTE_PATH " add -net %s netmask %s gw %s",
+ argv_printf (&argv, "%s add -net %s netmask %s gw %s",
+ ROUTE_PATH,
network,
netmask,
gateway);
if (r->metric_defined)
- buf_printf (&buf, " metric %d", r->metric);
+ argv_printf_cat (&argv, "metric %d", r->metric);
#endif /*CONFIG_FEATURE_IPROUTE*/
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: Linux route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Linux route add command failed");
#elif defined (WIN32)
- buf_printf (&buf, ROUTE_PATH " ADD %s MASK %s %s",
- network,
- netmask,
- gateway);
+ argv_printf (&argv, "%s%s ADD %s MASK %s %s",
+ get_win_sys_path(),
+ WIN_ROUTE_PATH_SUFFIX,
+ network,
+ netmask,
+ gateway);
if (r->metric_defined)
- buf_printf (&buf, " METRIC %d", r->metric);
+ argv_printf_cat (&argv, "METRIC %d", r->metric);
- msg (D_ROUTE, "%s", BSTR (&buf));
+ argv_msg (D_ROUTE, &argv);
if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
{
@@ -809,7 +813,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
{
netcmd_semaphore_lock ();
- status = system_check (BSTR (&buf), es, 0, "ERROR: Windows route add command failed");
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed");
netcmd_semaphore_release ();
}
else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
@@ -820,7 +824,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
{
msg (D_ROUTE, "Route addition fallback to route.exe");
netcmd_semaphore_lock ();
- status = system_check (BSTR (&buf), es, 0, "ERROR: Windows route add command failed [adaptive]");
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Windows route add command failed [adaptive]");
netcmd_semaphore_release ();
}
}
@@ -833,88 +837,93 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
/* example: route add 192.0.2.32 -netmask 255.255.255.224 somegateway */
- buf_printf (&buf, ROUTE_PATH " add");
+ argv_printf (&argv, "%s add",
+ ROUTE_PATH);
#if 0
if (r->metric_defined)
- buf_printf (&buf, " -rtt %d", r->metric);
+ argv_printf_cat (&argv, "-rtt %d", r->metric);
#endif
- buf_printf (&buf, " %s -netmask %s %s",
+ argv_printf_cat (&argv, "%s -netmask %s %s",
network,
netmask,
gateway);
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: Solaris route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route add command failed");
#elif defined(TARGET_FREEBSD)
- buf_printf (&buf, ROUTE_PATH " add");
+ argv_printf (&argv, "%s add",
+ ROUTE_PATH);
#if 0
if (r->metric_defined)
- buf_printf (&buf, " -rtt %d", r->metric);
+ argv_printf_cat (&argv, "-rtt %d", r->metric);
#endif
- buf_printf (&buf, " -net %s %s %s",
+ argv_printf_cat (&argv, "-net %s %s %s",
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: FreeBSD route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route add command failed");
#elif defined(TARGET_DRAGONFLY)
- buf_printf (&buf, ROUTE_PATH " add");
+ argv_printf (&argv, "%s add",
+ ROUTE_PATH);
#if 0
if (r->metric_defined)
- buf_printf (&buf, " -rtt %d", r->metric);
+ argv_printf_cat (&argv, "-rtt %d", r->metric);
#endif
- buf_printf (&buf, " -net %s %s %s",
+ argv_printf_cat (&argv, "-net %s %s %s",
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: DragonFly route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route add command failed");
#elif defined(TARGET_DARWIN)
- buf_printf (&buf, ROUTE_PATH " add");
+ argv_printf (&argv, "%s add",
+ ROUTE_PATH);
#if 0
if (r->metric_defined)
- buf_printf (&buf, " -rtt %d", r->metric);
+ argv_printf_cat (&argv, "-rtt %d", r->metric);
#endif
- buf_printf (&buf, " -net %s %s %s",
+ argv_printf_cat (&argv, "-net %s %s %s",
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: OS X route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: OS X route add command failed");
#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
- buf_printf (&buf, ROUTE_PATH " add");
+ argv_printf (&argv, "%s add",
+ ROUTE_PATH);
#if 0
if (r->metric_defined)
- buf_printf (&buf, " -rtt %d", r->metric);
+ argv_printf_cat (&argv, "-rtt %d", r->metric);
#endif
- buf_printf (&buf, " -net %s %s -netmask %s",
+ argv_printf_cat (&argv, "-net %s %s -netmask %s",
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- status = system_check (BSTR (&buf), es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
+ argv_msg (D_ROUTE, &argv);
+ status = openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route add command failed");
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
@@ -922,6 +931,7 @@ add_route (struct route *r, const struct tuntap *tt, unsigned int flags, const s
done:
r->defined = status;
+ argv_reset (&argv);
gc_free (&gc);
}
@@ -929,7 +939,7 @@ static void
delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags, const struct env_set *es)
{
struct gc_arena gc;
- struct buffer buf;
+ struct argv argv;
const char *network;
const char *netmask;
const char *gateway;
@@ -938,37 +948,40 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags
return;
gc_init (&gc);
+ argv_init (&argv);
- buf = alloc_buf_gc (256, &gc);
network = print_in_addr_t (r->network, 0, &gc);
netmask = print_in_addr_t (r->netmask, 0, &gc);
gateway = print_in_addr_t (r->gateway, 0, &gc);
#if defined(TARGET_LINUX)
#ifdef CONFIG_FEATURE_IPROUTE
- buf_printf (&buf, "%s route del %s/%d",
+ argv_printf (&argv, "%s route del %s/%d",
iproute_path,
network,
count_netmask_bits(netmask));
#else
- buf_printf (&buf, ROUTE_PATH " del -net %s netmask %s",
+ argv_printf (&argv, "%s del -net %s netmask %s",
+ ROUTE_PATH,
network,
netmask);
#endif /*CONFIG_FEATURE_IPROUTE*/
if (r->metric_defined)
- buf_printf (&buf, " metric %d", r->metric);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: Linux route delete command failed");
+ argv_printf_cat (&argv, "metric %d", r->metric);
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: Linux route delete command failed");
#elif defined (WIN32)
- buf_printf (&buf, ROUTE_PATH " DELETE %s MASK %s %s",
- network,
- netmask,
- gateway);
+ argv_printf (&argv, "%s%s DELETE %s MASK %s %s",
+ get_win_sys_path(),
+ WIN_ROUTE_PATH_SUFFIX,
+ network,
+ netmask,
+ gateway);
- msg (D_ROUTE, "%s", BSTR (&buf));
+ argv_msg (D_ROUTE, &argv);
if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_IPAPI)
{
@@ -978,7 +991,7 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags
else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_EXE)
{
netcmd_semaphore_lock ();
- system_check (BSTR (&buf), es, 0, "ERROR: Windows route delete command failed");
+ openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed");
netcmd_semaphore_release ();
}
else if ((flags & ROUTE_METHOD_MASK) == ROUTE_METHOD_ADAPTIVE)
@@ -989,7 +1002,7 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags
{
msg (D_ROUTE, "Route deletion fallback to route.exe");
netcmd_semaphore_lock ();
- system_check (BSTR (&buf), es, 0, "ERROR: Windows route delete command failed [adaptive]");
+ openvpn_execve_check (&argv, es, 0, "ERROR: Windows route delete command failed [adaptive]");
netcmd_semaphore_release ();
}
}
@@ -1000,58 +1013,64 @@ delete_route (const struct route *r, const struct tuntap *tt, unsigned int flags
#elif defined (TARGET_SOLARIS)
- buf_printf (&buf, ROUTE_PATH " delete %s -netmask %s %s",
+ argv_printf (&argv, "%s delete %s -netmask %s %s",
+ ROUTE_PATH,
network,
netmask,
gateway);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: Solaris route delete command failed");
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: Solaris route delete command failed");
#elif defined(TARGET_FREEBSD)
- buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s",
+ argv_printf (&argv, "%s delete -net %s %s %s",
+ ROUTE_PATH,
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: FreeBSD route delete command failed");
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: FreeBSD route delete command failed");
#elif defined(TARGET_DRAGONFLY)
- buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s",
+ argv_printf (&argv, "%s delete -net %s %s %s",
+ ROUTE_PATH,
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: DragonFly route delete command failed");
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: DragonFly route delete command failed");
#elif defined(TARGET_DARWIN)
- buf_printf (&buf, ROUTE_PATH " delete -net %s %s %s",
+ argv_printf (&argv, "%s delete -net %s %s %s",
+ ROUTE_PATH,
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: OS X route delete command failed");
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: OS X route delete command failed");
#elif defined(TARGET_OPENBSD) || defined(TARGET_NETBSD)
- buf_printf (&buf, ROUTE_PATH " delete -net %s %s -netmask %s",
+ argv_printf (&argv, "%s delete -net %s %s -netmask %s",
+ ROUTE_PATH,
network,
gateway,
netmask);
- msg (D_ROUTE, "%s", BSTR (&buf));
- system_check (BSTR (&buf), es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
+ argv_msg (D_ROUTE, &argv);
+ openvpn_execve_check (&argv, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed");
#else
msg (M_FATAL, "Sorry, but I don't know how to do 'route' commands on this operating system. Try putting your routes in a --route-up script");
#endif
+ argv_reset (&argv);
gc_free (&gc);
}