[Openvpn-devel] [PATCH 2/4] Add tap driver initialization and ifconfig for AIX.
From: Gert DoeringAIX is special... ifconfig only works if it can add the data to the ODM right away, so setup a local enviromnment set that has "ODMDIR=/etc/objrepos" in it (hard-coded, nobody changes that). Only --dev tap or --dev tapNN are supported right now. AIX has no tun driver (so tun mode would need to dynamically add/remove ethernet headers to/from AIX). Signed-off-by: Gert Doering --- src/openvpn/tun.c | 170 + 1 files changed, 170 insertions(+), 0 deletions(-) diff --git a/src/openvpn/tun.c b/src/openvpn/tun.c index 482f640..25d5473 100644 --- a/src/openvpn/tun.c +++ b/src/openvpn/tun.c @@ -1194,6 +1194,43 @@ do_ifconfig (struct tuntap *tt, openvpn_execve_check (, es, S_FATAL, "FreeBSD ifconfig inet6 failed"); } +#elif defined(TARGET_AIX) + { + /* AIX ifconfig will complain if it can't find ODM path in env */ + struct env_set *aix_es = env_set_create (NULL); + env_set_add( aix_es, "ODMDIR=/etc/objrepos" ); + + if (tun) + msg(M_FATAL, "no tun support on AIX (canthappen)"); + + /* example: ifconfig tap0 172.30.1.1 netmask 255.255.254.0 up */ + argv_printf (, +"%s %s %s netmask %s mtu %d up", + IFCONFIG_PATH, + actual, + ifconfig_local, + ifconfig_remote_netmask, + tun_mtu + ); + + argv_msg (M_INFO, ); + openvpn_execve_check (, aix_es, S_FATAL, "AIX ifconfig failed"); + tt->did_ifconfig = true; + + if ( do_ipv6 ) + { + argv_printf (, + "%s %s inet6 %s/%d", + IFCONFIG_PATH, + actual, + ifconfig_ipv6_local, + tt->netbits_ipv6 + ); + argv_msg (M_INFO, ); + openvpn_execve_check (, aix_es, S_FATAL, "AIX ifconfig inet6 failed"); + } + env_set_destroy (aix_es); + } #elif defined (WIN32) { /* @@ -2825,6 +2862,139 @@ read_tun (struct tuntap* tt, uint8_t *buf, int len) return read (tt->fd, buf, len); } +#elif defined(TARGET_AIX) + +void +open_tun (const char *dev, const char *dev_type, const char *dev_node, struct tuntap *tt) +{ + char tunname[256]; + char dynamic_name[20]; + const char *p; + struct argv argv; + + if (tt->type == DEV_TYPE_NULL) +{ + open_null (tt); + return; +} + + if ( tt->type == DEV_TYPE_TUN) +{ + msg(M_FATAL, "no support for 'tun' devices on AIX" ); +} + + if ( strncmp( dev, "tap", 3 ) != 0 || dev_node ) +{ + msg(M_FATAL, "'--dev %s' and/or '--dev-node' not supported on AIX, use '--dev tap0', 'tap1', etc.", dev ); +} + + if ( strcmp( dev, "tap" ) == 0 ) /* find first free tap dev */ +{ /* (= no /dev/tapN node) */ + int i; + for (i=0; i<99; i++ ) + { + openvpn_snprintf (tunname, sizeof (tunname), "/dev/tap%d", i); + if ( access( tunname, F_OK ) < 0 && errno == ENOENT ) + { break; } + } + if ( i >= 99 ) + msg( M_FATAL, "cannot find unused tap device" ); + + openvpn_snprintf( dynamic_name, sizeof(dynamic_name), "tap%d", i ); + dev = dynamic_name; +} + else /* name given, sanity check */ +{ + /* ensure that dev name is "tap+" *only* */ + p = [3]; + while( isdigit(*p) ) p++; + if ( *p != '\0' ) + msg( M_FATAL, "TAP device name must be '--dev tap'" ); + + openvpn_snprintf (tunname, sizeof (tunname), "/dev/%s", dev); +} + + /* pre-existing device? + */ + if ( access( tunname, F_OK ) < 0 && errno == ENOENT ) +{ + + /* tunnel device must be created with 'ifconfig tapN create' + */ + struct env_set *es = env_set_create (NULL); + argv_init (); + argv_printf (, "%s %s create", IFCONFIG_PATH, dev); + argv_msg (M_INFO, ); + env_set_add( es, "ODMDIR=/etc/objrepos" ); + openvpn_execve_check (, es, S_FATAL, "AIX 'create tun interface' failed"); + env_set_destroy (es); +} + else +{ + /* we didn't make it, we're not going to break it */ + tt->persistent_if = TRUE; +} + + if ((tt->fd = open (tunname, O_RDWR)) < 0) +{ + msg (M_ERR, "Cannot open TAP device '%s'", tunname); +} + + set_nonblock (tt->fd); + set_cloexec (tt->fd); /* don't pass fd to scripts */ + msg (M_INFO, "TUN/TAP device %s opened", tunname); + + /* tt->actual_name is passed to up and down scripts and used as the ifconfig dev name */ + tt->actual_name = string_alloc(dev, NULL); +} + +/* tap devices need to be manually destroyed on AIX + */ +void +close_tun (struct tuntap*
[Openvpn-devel] [PATCH 1/4] Recognize AIX, define TARGET_AIX
From: Gert Doeringforce "have_tap_header=yes", as configure won't like AIX headers otherwise (no tun related headers, just ). force ROUTE to be "/usr/sbin/route" - not executable by non-root users, so configure testing for executables will not find it force "ac_cv_header_net_if_h=no", because AIX' pulls in AIX' , which #defines ROUTE_H, disabling our "route.h"... (and we don't need on AIX anyway) Signed-off-by: Gert Doering --- configure.ac |7 +++ 1 files changed, 7 insertions(+), 0 deletions(-) diff --git a/configure.ac b/configure.ac index ea35d73..fe278e1 100644 --- a/configure.ac +++ b/configure.ac @@ -342,6 +342,13 @@ case "$host" in AC_DEFINE([TARGET_DRAGONFLY], [1], [Are we running on DragonFlyBSD?]) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["D"], [Target prefix]) ;; + *-aix*) + AC_DEFINE([TARGET_AIX], [1], [Are we running AIX?]) + AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["A"], [Target prefix]) + ROUTE="/usr/sbin/route" + have_tap_header="yes" + ac_cv_header_net_if_h="no" # exists, but breaks things + ;; *) AC_DEFINE_UNQUOTED([TARGET_PREFIX], ["X"], [Target prefix]) have_tap_header="yes" -- 1.6.4
[Openvpn-devel] [PATCH 3/4] implement adding/deleting routes on AIX, for IPv4 and IPv6
From: Gert DoeringAIX only has TAP interfaces, so always use gateway address as next hop, not interface name. AIX route works much more reliable if passed netbits than netmask - do so (introducing a new helper function netmask_to_netbits2()) --- src/openvpn/route.c | 60 +++ 1 files changed, 60 insertions(+), 0 deletions(-) diff --git a/src/openvpn/route.c b/src/openvpn/route.c index 5531eda..5428e76 100644 --- a/src/openvpn/route.c +++ b/src/openvpn/route.c @@ -1482,6 +1482,17 @@ add_route (struct route_ipv4 *r, argv_msg (D_ROUTE, ); status = openvpn_execve_check (, es, 0, "ERROR: OpenBSD/NetBSD route add command failed"); +#elif defined(TARGET_AIX) + + { + int netbits = netmask_to_netbits2(r->netmask); + argv_printf (, "%s add -net %s/%d %s", + ROUTE_PATH, + network, netbits, gateway); + argv_msg (D_ROUTE, ); + status = openvpn_execve_check (, es, 0, "ERROR: AIX 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"); #endif @@ -1701,6 +1712,14 @@ add_route_ipv6 (struct route_ipv6 *r6, const struct tuntap *tt, unsigned int fla argv_msg (D_ROUTE, ); status = openvpn_execve_check (, es, 0, "ERROR: NetBSD route add -inet6 command failed"); +#elif defined(TARGET_AIX) + + argv_printf (, "%s add -inet6 %s/%d %s", + ROUTE_PATH, + network, r6->netbits, gateway); + argv_msg (D_ROUTE, ); + status = openvpn_execve_check (, es, 0, "ERROR: AIX route add command failed"); + #else msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-up script"); #endif @@ -1859,8 +1878,21 @@ delete_route (struct route_ipv4 *r, argv_msg (D_ROUTE, ); openvpn_execve_check (, es, 0, "ERROR: OpenBSD/NetBSD route delete command failed"); + #elif defined(TARGET_ANDROID) msg (M_NONFATAL, "Sorry, deleting routes on Android is not possible. The VpnService API allows routes to be set on connect only."); + +#elif defined(TARGET_AIX) + + { + int netbits = netmask_to_netbits2(r->netmask); + argv_printf (, "%s delete -net %s/%d %s", + ROUTE_PATH, + network, netbits, gateway); + argv_msg (D_ROUTE, ); + openvpn_execve_check (, es, 0, "ERROR: AIX 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 @@ -2031,6 +2063,14 @@ delete_route_ipv6 (const struct route_ipv6 *r6, const struct tuntap *tt, unsigne argv_msg (D_ROUTE, ); openvpn_execve_check (, es, 0, "ERROR: NetBSD route delete -inet6 command failed"); +#elif defined(TARGET_AIX) + + argv_printf (, "%s delete -inet6 %s/%d %s", + ROUTE_PATH, + network, r6->netbits, gateway); + argv_msg (D_ROUTE, ); + openvpn_execve_check (, es, 0, "ERROR: AIX route add command failed"); + #else msg (M_FATAL, "Sorry, but I don't know how to do 'route ipv6' commands on this operating system. Try putting your routes in a --route-down script"); #endif @@ -2868,6 +2908,26 @@ netmask_to_netbits (const in_addr_t network, const in_addr_t netmask, int *netbi return false; } +/* similar to netmask_to_netbits(), but don't mess with base address + * etc., just convert to netbits - non-mappable masks are returned as "-1" + */ +int netmask_to_netbits2 (in_addr_t netmask) +{ + int i; + const int addrlen = sizeof (in_addr_t) * 8; + + for (i = 0; i <= addrlen; ++i) +{ + in_addr_t mask = netbits_to_netmask (i); + if (mask == netmask) + { + return i; + } +} + return -1; +} + + /* * get_bypass_addresses() is used by the redirect-gateway bypass-x * functions to build a route bypass to selected DHCP/DNS servers, -- 1.6.4
[Openvpn-devel] OpenVPN port to AIX
Hi, the following four patches port OpenVPN git/master to AIX. It might not be the most asked-for platform in the world, but since it finally grew a tap driver, it can be useful, so here it is :-) Drawbacks today: - AIX has no tun driver, so only --dev tap is supported - IPv4 ICMP packets are never fragmented, so t_client fails for IPv4 ping with 3000 bytes (while IPv6 works!) gert
[Openvpn-devel] Rekey and Defer sample plugin
Hello, I'm facing a problem with "defer" sample plugin and rekeying. I use plugin from https://github.com/OpenVPN/openvpn/tree/master/sample/sample-plugins/defer. Relevant part of openvpn config: > auth-user-pass-optional > setenv test_deferred_auth 2 > plugin /etc/openvpn/simple.so > reneg-sec 20 Everything works fine, plugin writes into auth control file in 2 secs and client got authenticated. When rekeying happends, plugin got called and writes again to auth control file, however after that connection breaks. Part of OpenVPN log: OPENVPN_PLUGIN_AUTH_USER_PASS_VERIFY DEFER u='' p='' acf='/tmp/openvpn_acf_8ec7b1fb155ede01c8bae22c6e4ad4ea.tmp' ( sleep 2 ; echo AUTH /tmp/openvpn_acf_8ec7b1fb155ede01c8bae22c6e4ad4ea.tmp 2 ; echo 1 >/tmp/openvpn_acf_8ec7b1fb155ede01c8bae22c6e4ad4ea.tmp ) & Tue Jun 10 13:25:50 2014 us=851659 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 PLUGIN_CALL: POST /etc/openvpn/simple.so/PLUGIN_AUTH_USER_PASS_VERIFY status=2 Tue Jun 10 13:25:50 2014 us=851680 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 TLS: Username/Password authentication deferred for username '' OPENVPN_PLUGIN_TLS_FINAL Tue Jun 10 13:25:50 2014 us=851695 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 PLUGIN_CALL: POST /etc/openvpn/simple.so/PLUGIN_TLS_FINAL status=0 Tue Jun 10 13:25:50 2014 us=851842 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 Data Channel Encrypt: Cipher 'BF-CBC' initialized with 128 bit key Tue Jun 10 13:25:50 2014 us=851850 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 Data Channel Encrypt: Using 160 bit message hash 'SHA1' for HMAC authentication Tue Jun 10 13:25:50 2014 us=851894 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 Data Channel Decrypt: Cipher 'BF-CBC' initialized with 128 bit key Tue Jun 10 13:25:50 2014 us=851902 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 Data Channel Decrypt: Using 160 bit message hash 'SHA1' for HMAC authentication Tue Jun 10 13:25:50 2014 us=853273 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 Control Channel: TLSv1, cipher TLSv1/SSLv3 DHE-RSA-AES256-SHA, 2048 bit RSA Tue Jun 10 13:25:51 2014 us=238477 588b4d7d-f8ec-4397-8156-43ed232c2dd8/10.64.1.101:1194 TLS Error: local/remote TLS keys are out of sync: [AF_INET]10.64.1.101:1194 [1] and after that lots of "TLS keys are out of sync". Is it kind of a bug in OpenVPN/sample plugin or am I missing something in configuration? Anything can be done (maybe in OpenVPN code) to make it work? -- -Lev