...
 
Commits (39)
graft docs
include TODO, CHANGES
include TODO CHANGES re6st/ovpn-*
#include <windows.h>
#include <stdio.h>
HANDLE open_pipe(const char *pname);
int main(int argc, char *argv[])
{
HANDLE pd;
DWORD m;
char buf[512];
int n;
char *s, *s1, *s2;
s = (char*)getenv("script_type");
if (s == NULL) {
fprintf(stderr, "no script_type\n");
return 1;
}
if (strcmp(s, "up") == 0)
return 0;
if (argc < 2) {
fprintf(stderr, "missing pipe\n");
return 1;
}
/* %(script_type)s %(common_name)s %(OPENVPN_external_ip)s */
s1 = (char*)getenv("common_name");
s2 = (char*)getenv("OPENVPN_external_ip");
if ( (s1 == NULL) || (s2 == NULL)) {
fprintf(stderr, "missing common_name and OPENVPN_external_ip\n");
return 1;
}
n = snprintf(buf, 512, "%s %s %s\n", s, s1, s2);
if (n >= 512) {
fprintf(stderr, "buffer overflow\n");
return 1;
}
pd = open_pipe(argv[1]);
if (pd == NULL) {
fprintf(stderr, "invalid pipe %s\n", argv[1]);
return 1;
}
if (!WriteFile(pd, buf, n, &m, NULL)) {
fprintf(stderr, "write pipe failed\n");
CloseHandle(pd);
return 1;
}
CloseHandle(pd);
return 0;
}
#include <windows.h>
extern sscanf (const char *, const char *, ...);
HANDLE open_pipe (const char *pname)
{
HANDLE proc, pipe_hdl, nio_hdl = NULL;
int pid, rwflags = 1; /* O_WRONLY */
sscanf (pname, "/proc/%d/fd/pipe:[%d]", &pid, (int *) &pipe_hdl);
if (!(proc = OpenProcess (PROCESS_DUP_HANDLE, FALSE, pid))) {
return NULL;
}
if (!DuplicateHandle (proc, pipe_hdl, GetCurrentProcess (), &nio_hdl,
0, FALSE, DUPLICATE_SAME_ACCESS)) {
return NULL;
}
CloseHandle (proc);
return nio_hdl;
}
#include <windows.h>
#include <stdio.h>
HANDLE open_pipe(const char *pname);
int main(int argc, char *argv[])
{
HANDLE pd;
DWORD m;
char buf[512];
int n;
char *s, *s1, *s2;
int fd;
s = (char*)getenv("script_type");
if (s == NULL) {
fprintf(stderr, "no script_type\n");
return 1;
}
s2 = (char*)getenv("trusted_ip");
if (s2 == NULL) {
fprintf(stderr, "no trusted_ip\n");
return 1;
}
if (strcmp(s, "client-connect") == 0) {
if (argc < 3) {
fprintf(stderr, "missing filename\n");
return 1;
}
n = snprintf(buf, 512, "push \"setenv-safe external_ip %s\"\n", s2);
if (n >= 512) {
fprintf(stderr, "buffer overflow\n");
return 1;
}
/* O_WRONLY == 1 */
fd = open(argv[2], 1);
if (fd == -1) {
fprintf(stderr, "open %s failed\n", argv[2]);
return 1;
}
if (write(fd, buf, n) == -1) {
fprintf(stderr, "write %s failed\n", argv[2]);
close(fd);
return 1;
}
close(fd);
}
if (argc < 2) {
fprintf(stderr, "missing pipe\n");
return 1;
}
if (strcmp(argv[1], "None") == 0)
return 0;
/* %(script_type)s %(common_name)s %(OPENVPN_external_ip)s */
s1 = (char*)getenv("common_name");
if (s1 == NULL) {
fprintf(stderr, "missing common_name\n");
return 1;
}
n = snprintf(buf, 512, "%s %s %s\n", s, s1, s2);
if (n >= 512) {
fprintf(stderr, "buffer overflow\n");
return 1;
}
pd = open_pipe(argv[1]);
if (pd == NULL) {
fprintf(stderr, "invalid pipe %s\n", argv[1]);
return 1;
}
if (!WriteFile(pd, buf, n, &m, NULL)) {
fprintf(stderr, "write pipe failed\n");
CloseHandle(pd);
return 1;
}
CloseHandle(pd);
return 0;
}
import logging, errno, os
import logging, errno, os, subprocess, sys
from . import utils
here = os.path.realpath(os.path.dirname(__file__))
ovpn_server = os.path.join(here, 'ovpn-server')
ovpn_client = os.path.join(here, 'ovpn-client')
if sys.platform == 'cygwin':
here = subprocess.check_output(['cygpath', '-m', here]).strip()
script_ext = '.exe'
else:
script_ext = ''
ovpn_server = os.path.join(here, 'ovpn-server' + script_ext)
ovpn_client = os.path.join(here, 'ovpn-client' + script_ext)
ovpn_log = None
def openvpn(iface, encrypt, *args, **kw):
args = ['openvpn',
'--dev-type', 'tap',
'--dev', iface,
'--persist-tun',
'--dev-node' if sys.platform == 'cygwin' else '--dev', iface,
'' if sys.platform == 'cygwin' else '--persist-tun',
'--persist-key',
'--script-security', '2',
'--mute-replay-warnings',
'--up', ovpn_client,
#'--user', 'nobody', '--group', 'nogroup',
] + list(args)
......@@ -25,7 +31,7 @@ def openvpn(iface, encrypt, *args, **kw):
def server(iface, max_clients, dh_path, pipe_fd, port, proto, encrypt, *args, **kw):
client_script = '%s %s' % (ovpn_server, pipe_fd)
client_script = '%s %s' % (ovpn_server, utils.get_pipename(pipe_fd))
if pipe_fd is not None:
args = ('--client-disconnect', client_script) + args
return openvpn(iface, encrypt,
......
import logging, random, socket, subprocess, time
import logging, platform, random, socket, subprocess, sys, time
from collections import deque
from . import plib, utils
......@@ -64,7 +64,7 @@ class Connection(object):
'--connect-retry-max', '3', '--tls-exit',
'--remap-usr1', 'SIGTERM',
'--ping-exit', str(timeout),
'--route-up', '%s %u' % (plib.ovpn_client, write_pipe),
'--route-up', '%s %s' % (plib.ovpn_client, utils.get_pipename(write_pipe)),
*ovpn_args)
_retry += 1
self._retry = _retry < len(self.address_list) and (
......
......@@ -154,6 +154,50 @@ def parse_address(address_list):
def binFromSubnet(subnet):
p, l = subnet.split('/')
return bin(int(p))[2:].rjust(int(l), '0')
if sys.platform == 'cygwin':
def _iterRoutes(self):
# Before Vista
if platform.system()[10:11] == '5':
args = ('netsh', 'interface', 'ipv6', 'show', 'route', 'verbose')
else:
args = ('ipwin', 'ipv6', 'show', 'route', 'verbose')
routing_table = subprocess.check_output(args, stderr=subprocess.STDOUT)
for line in routing_table.splitlines():
fs = line.split(':', 1)
test = fs[0].startswith
if test('Prefix'):
prefix, prefix_len = fs[1].split('/', 1)
elif test('Interface'):
yield (fs[1].strip(),
utils.binFromIp(prefix.strip()),
int(prefix_len))
else:
def _iterRoutes():
with open('/proc/net/ipv6_route') as f:
routing_table = f.read()
for line in routing_table.splitlines():
line = line.split()
iface = line[-1]
if 0 < int(line[5], 16) < 1 << 31: # positive metric
yield (iface, bin(int(line[0], 16))[2:].rjust(128, '0'),
int(line[1], 16))
_iterRoutes.__doc__ = """Iterates over all routes
Amongst all returned routes starting with re6st prefix:
- one is the local one with our prefix
- any route with null prefix will be ignored
- other are reachable routes installed by babeld
"""
def iterRoutes(network, exclude_prefix=None):
a = len(network)
for iface, ip, prefix_len in _iterRoutes():
if ip[:a] == network:
prefix = ip[a:prefix_len]
if prefix and prefix != exclude_prefix:
yield iface, prefix
if 1:
def _iterRoutes():
......@@ -205,3 +249,12 @@ def encrypt(cert, data):
if p.returncode:
raise subprocess.CalledProcessError(p.returncode, 'openssl', err)
return out
def get_pipename(pipe_id):
if pipe_id is not None:
path = '/proc/%u' % os.getpid()
with open(os.path.join(path, 'winpid'), 'r') as f:
winpid = f.readline()
r = os.path.realpath('%s/fd/%s' % (path, pipe_id)).split('/')
r[2] = winpid.strip()
return '/'.join(r)
......@@ -175,7 +175,8 @@ def main():
utils.makedirs(config.state)
db_path = os.path.join(config.state, 'peers.db')
if config.ovpnlog:
plib.ovpn_log = config.log
plib.ovpn_log = config.log if not sys.platform == 'cygwin' else \
subprocess.check_output(['cygpath', '-m', config.log]).strip()
signal.signal(signal.SIGHUP, lambda *args: sys.exit(-1))
signal.signal(signal.SIGTERM, lambda *args:
......@@ -313,6 +314,7 @@ def main():
elif server_tunnels:
required('dh')
for iface, (port, proto) in server_tunnels.iteritems():
ip('tuntap', 'dev', iface, 'mode', 'tap')
cleanup.append(plib.server(iface, config.max_clients,
config.dh, write_pipe, port, proto, config.encrypt,
'--ping-exit', str(timeout), *config.openvpn_args).stop)
......@@ -325,7 +327,11 @@ def main():
# not even remove it on exit.
subprocess.call(if_rt)
if_rt[4] = my_subnet
cleanup.append(lambda: subprocess.call(if_rt))
if sys.platform == 'cygwin':
ip('route', my_subnet, 'dev', config.main_interface)
else:
cleanup.append(lambda: subprocess.call(if_rt))
x = [my_network]
if config.gateway:
config.table = 0
......@@ -362,7 +368,9 @@ def main():
t = threading.Thread(target=check_no_default_route)
t.daemon = True
t.start()
ip('route', 'unreachable', *x)
if not sys.platform == 'cygwin':
ip('route', 'unreachable', *x)
config.babel_args += config.iface_list
cleanup.append(plib.router(subnet, config.hello, config.table,
......
......@@ -36,6 +36,8 @@ setup(
're6st': [
'ovpn-server',
'ovpn-client',
'ovpn-server.exe',
'ovpn-client.exe',
],
},
install_requires = ['pyOpenSSL >= 0.13', 'miniupnpc'],
......