mirror of
https://gitlab.com/openconnect/ocserv.git
synced 2026-02-10 08:46:58 +08:00
Merge branch 'tmp-allow-small-prefix' into 'master'
Do not assign an IPv6 address to client that matches the network Closes #430 See merge request openconnect/ocserv!273
This commit is contained in:
@@ -72,7 +72,7 @@ Ubuntu16.04:
|
||||
- ./configure --without-nuttcp-tests
|
||||
- make -j$JOBS
|
||||
# this version of openconnect doesn't work with IPv6 only
|
||||
- make check -j$JOBS XFAIL_TESTS=ipv6-iface
|
||||
- make check -j$JOBS XFAIL_TESTS="ipv6-iface ipv6-small-net"
|
||||
tags:
|
||||
- shared
|
||||
- linux
|
||||
|
||||
2
NEWS
2
NEWS
@@ -1,6 +1,8 @@
|
||||
* Version 1.1.4 (unreleased)
|
||||
- Added newfstatat() and epoll_pwait() to the accepted list of seccomp
|
||||
calls. This improves compatibility with certain libcs and aarch64.
|
||||
- Do not allow assigning the same IPv6 as tun device address and to
|
||||
the client. This allows using /127 as prefix (#430)
|
||||
|
||||
|
||||
* Version 1.1.3 (released 2021-06-02)
|
||||
|
||||
@@ -142,11 +142,10 @@ void steal_ip_leases(struct proc_st* proc, struct proc_st *thief)
|
||||
}
|
||||
}
|
||||
|
||||
static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *net, struct sockaddr_storage *subnet)
|
||||
static int is_ipv6_ok(main_server_st *s, struct sockaddr_storage *ip, struct sockaddr_storage *tun, struct sockaddr_storage *subnet)
|
||||
{
|
||||
/* check that IP & mask don't match network - i.e., the network's IP is outside
|
||||
* that subnet; we use it in the tun device */
|
||||
if (memcmp(SA_IN6_U8_P(subnet), SA_IN6_U8_P(net), 16) == 0) {
|
||||
/* check that IP & mask don't match tun IP */
|
||||
if (ip_cmp(subnet, tun) == 0) {
|
||||
return 0;
|
||||
}
|
||||
|
||||
@@ -400,6 +399,15 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
for (i=0;i<sizeof(struct in6_addr);i++)
|
||||
SA_IN6_U8_P(&network)[i] &= (SA_IN6_U8_P(&mask)[i]);
|
||||
|
||||
proc->ipv6 = talloc_zero(proc, struct ip_lease_st);
|
||||
if (proc->ipv6 == NULL)
|
||||
return ERR_MEM;
|
||||
|
||||
/* LIP = network address + 1 */
|
||||
memcpy(&proc->ipv6->lip, &network, sizeof(struct sockaddr_in6));
|
||||
SA_IN6_U8_P(&proc->ipv6->lip)[15] |= 1;
|
||||
|
||||
proc->ipv6->lip_len = sizeof(struct sockaddr_in6);
|
||||
|
||||
if (proc->config->explicit_ipv6) {
|
||||
memset(&tmp, 0, sizeof(tmp));
|
||||
@@ -408,13 +416,10 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
|
||||
if (ret != 1) {
|
||||
mslog(s, NULL, LOG_ERR, "error reading explicit IP %s", proc->config->explicit_ipv6);
|
||||
return -1;
|
||||
ret = ERR_NO_IP;
|
||||
goto fail;
|
||||
}
|
||||
|
||||
proc->ipv6 = talloc_zero(proc, struct ip_lease_st);
|
||||
if (proc->ipv6 == NULL)
|
||||
return ERR_MEM;
|
||||
|
||||
((struct sockaddr_in6*)&tmp)->sin6_family = AF_INET6;
|
||||
memcpy(&proc->ipv6->rip, &tmp, sizeof(struct sockaddr_in6));
|
||||
proc->ipv6->rip_len = sizeof(struct sockaddr_in6);
|
||||
@@ -423,7 +428,7 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
for (i=0;i<sizeof(struct in6_addr);i++)
|
||||
SA_IN6_U8_P(&proc->ipv6->sig)[i] = SA_IN6_U8_P(&proc->ipv6->rip)[i] & SA_IN6_U8_P(&subnet_mask)[i];
|
||||
|
||||
if (is_ipv6_ok(s, &tmp, &network, &proc->ipv6->sig) == 0) {
|
||||
if (is_ipv6_ok(s, &tmp, &proc->ipv6->lip, &proc->ipv6->sig) == 0) {
|
||||
mslog(s, proc, LOG_DEBUG, "cannot assign explicit IP %s; it is in use or invalid",
|
||||
human_addr((void*)&tmp, sizeof(struct sockaddr_in6), buf, sizeof(buf)));
|
||||
ret = ERR_NO_IP;
|
||||
@@ -434,9 +439,6 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
}
|
||||
|
||||
/* assign "random" IP */
|
||||
proc->ipv6 = talloc_zero(proc, struct ip_lease_st);
|
||||
if (proc->ipv6 == NULL)
|
||||
return ERR_MEM;
|
||||
proc->ipv6->db = &s->ip_leases;
|
||||
|
||||
memcpy(&tmp, &network, sizeof(tmp));
|
||||
@@ -487,8 +489,8 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
}
|
||||
|
||||
/* check if it exists in the hash table */
|
||||
if (is_ipv6_ok(s, &rnd, &network, &proc->ipv6->sig) == 0) {
|
||||
mslog(s, proc, LOG_DEBUG, "cannot assign local IP %s; it is in use or invalid",
|
||||
if (is_ipv6_ok(s, &rnd, &proc->ipv6->lip, &proc->ipv6->sig) == 0) {
|
||||
mslog(s, proc, LOG_DEBUG, "cannot assign IP %s; it is in use or invalid",
|
||||
human_addr((void*)&rnd, sizeof(struct sockaddr_in6), buf, sizeof(buf)));
|
||||
continue;
|
||||
}
|
||||
@@ -504,12 +506,6 @@ int get_ipv6_lease(main_server_st* s, struct proc_st* proc)
|
||||
} while(1);
|
||||
|
||||
finish:
|
||||
/* LIP = network address + 1 */
|
||||
memcpy(&proc->ipv6->lip, &network, sizeof(struct sockaddr_in6));
|
||||
SA_IN6_U8_P(&proc->ipv6->lip)[15] |= 1;
|
||||
|
||||
proc->ipv6->lip_len = sizeof(struct sockaddr_in6);
|
||||
|
||||
proc->ipv6->prefix = subnet_prefix;
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -44,7 +44,7 @@ EXTRA_DIST = certs/ca-key.pem certs/ca.pem ns.sh common.sh certs/server-cert.pem
|
||||
data/disconnect-user2.config data/ping-leases.config data/haproxy-proxyproto.config \
|
||||
data/haproxy-proxyproto.cfg scripts/proxy-connectscript data/haproxy-proxyproto-v1.config \
|
||||
data/haproxy-proxyproto-v1.cfg scripts/proxy-connectscript-v1 data/test-multiple-client-ip.config \
|
||||
data/test-client-bypass-protocol.config
|
||||
data/test-client-bypass-protocol.config asan.supp
|
||||
|
||||
xfail_scripts =
|
||||
dist_check_SCRIPTS = ocpasswd-test
|
||||
@@ -61,7 +61,7 @@ dist_check_SCRIPTS += haproxy-connect test-iroute test-multi-cookie test-pass-sc
|
||||
test-cookie-invalidation test-user-config test-append-routes test-ban \
|
||||
multiple-routes json test-udp-listen-host test-max-same-1 test-script-multi-user \
|
||||
apple-ios ipv6-iface test-namespace-listen disconnect-user disconnect-user2 \
|
||||
ping-leases test-ban-local test-client-bypass-protocol
|
||||
ping-leases test-ban-local test-client-bypass-protocol ipv6-small-net
|
||||
|
||||
if RADIUS_ENABLED
|
||||
dist_check_SCRIPTS += radius-group radius-otp
|
||||
@@ -190,7 +190,8 @@ TESTS = $(check_PROGRAMS) $(dist_check_SCRIPTS) $(xfail_scripts)
|
||||
XFAIL_TESTS = $(xfail_scripts)
|
||||
|
||||
TESTS_ENVIRONMENT = srcdir="$(srcdir)" \
|
||||
top_builddir="$(top_builddir)"
|
||||
top_builddir="$(top_builddir)" \
|
||||
LSAN_OPTIONS=suppressions=asan.supp
|
||||
|
||||
if DISABLE_ASAN_BROKEN_TESTS
|
||||
TESTS_ENVIRONMENT += DISABLE_ASAN_BROKEN_TESTS=1
|
||||
|
||||
1
tests/asan.supp
Normal file
1
tests/asan.supp
Normal file
@@ -0,0 +1 @@
|
||||
leak:occtl
|
||||
91
tests/ipv6-small-net
Executable file
91
tests/ipv6-small-net
Executable file
@@ -0,0 +1,91 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Copyright (C) 2021 Nikos Mavrogiannopoulos
|
||||
#
|
||||
# This file is part of ocserv.
|
||||
#
|
||||
# ocserv is free software; you can redistribute it and/or modify it
|
||||
# under the terms of the GNU General Public License as published by the
|
||||
# Free Software Foundation; either version 2 of the License, or (at
|
||||
# your option) any later version.
|
||||
#
|
||||
# ocserv is distributed in the hope that it will be useful, but
|
||||
# WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU
|
||||
# General Public License for more details.
|
||||
#
|
||||
# You should have received a copy of the GNU General Public License
|
||||
# along with GnuTLS; if not, write to the Free Software Foundation,
|
||||
# Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
|
||||
SERV="${SERV:-../src/ocserv}"
|
||||
srcdir=${srcdir:-.}
|
||||
PIDFILE=ocserv-pid.$$.tmp
|
||||
CLIPID=oc-pid.$$.tmp
|
||||
IP=$(which ip)
|
||||
|
||||
. `dirname $0`/common.sh
|
||||
|
||||
eval "${GETPORT}"
|
||||
|
||||
if test -z "${IP}";then
|
||||
echo "no IP tool is present"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
if test "$(id -u)" != "0";then
|
||||
echo "This test must be run as root"
|
||||
exit 77
|
||||
fi
|
||||
|
||||
|
||||
echo "Testing ocserv and ipv6 iface application... "
|
||||
|
||||
function finish {
|
||||
set +e
|
||||
echo " * Cleaning up..."
|
||||
test -n "${PID}" && kill ${PID} >/dev/null 2>&1
|
||||
test -n "${PIDFILE}" && rm -f ${PIDFILE} >/dev/null 2>&1
|
||||
test -n "${CLIPID}" && kill $(cat ${CLIPID}) >/dev/null 2>&1
|
||||
test -n "${CLIPID}" && rm -f ${CLIPID} >/dev/null 2>&1
|
||||
test -n "${CONFIG}" && rm -f ${CONFIG} >/dev/null 2>&1
|
||||
}
|
||||
trap finish EXIT
|
||||
|
||||
ADDRESS=10.201.128.0
|
||||
CLI_ADDRESS=10.57.49.0
|
||||
VPNNET6=fc04:1b8e:bdca:11ca:576b:80e3:4956:f00c/127
|
||||
VPNADDR6=fc04:1b8e:bdca:11ca:576b:80e3:4956:f00d
|
||||
OCCTL_SOCKET=./ipv6-iface-$$.socket
|
||||
USERNAME=test
|
||||
|
||||
. `dirname $0`/ns.sh
|
||||
|
||||
update_config ipv6-iface.config
|
||||
if test "$VERBOSE" = 1;then
|
||||
DEBUG="-d 3"
|
||||
fi
|
||||
|
||||
${CMDNS2} ${SERV} -p ${PIDFILE} -f -c ${CONFIG} ${DEBUG} & PID=$!
|
||||
wait_server $PID
|
||||
|
||||
echo -n "Connecting to setup interface... "
|
||||
echo "test" | ${CMDNS1} $OPENCONNECT -q $ADDRESS:$PORT -u ${USERNAME} --servercert=d66b507ae074d03b02eafca40d35f87dd81049d3 -s ${srcdir}/scripts/vpnc-script --pid-file=${CLIPID} --passwd-on-stdin -b
|
||||
if test $? != 0;then
|
||||
echo "Could not connect to server"
|
||||
exit 1
|
||||
fi
|
||||
|
||||
echo ok
|
||||
|
||||
set -e
|
||||
echo " * ping remote address"
|
||||
|
||||
${CMDNS2} ping -6 -c 3 ${VPNADDR6}
|
||||
|
||||
echo ok
|
||||
|
||||
kill $PID
|
||||
wait
|
||||
|
||||
exit 0
|
||||
@@ -1 +1 @@
|
||||
explicit-ipv6 = fda9:4efe:7e3b:03ea::00
|
||||
explicit-ipv6 = fda9:4efe:7e3b:03ea::01
|
||||
|
||||
Reference in New Issue
Block a user