From ed9360a4dbbe9f5da0979389de32087a99301773 Mon Sep 17 00:00:00 2001 From: Mazet Laurent Date: Thu, 12 Jun 2025 19:18:07 +0200 Subject: [PATCH] split vpn into red and black modules --- test-rb.sh | 107 ++++++++++++++++++++++++++++++++++++ ulvpn-rb.sh | 93 ++++++++++++++++++++++++++++++++ ulvpn.c | 152 ++++++++++++++++++++++++++++++++++++---------------- 3 files changed, 306 insertions(+), 46 deletions(-) create mode 100755 test-rb.sh create mode 100755 ulvpn-rb.sh diff --git a/test-rb.sh b/test-rb.sh new file mode 100755 index 0000000..5c1fdb5 --- /dev/null +++ b/test-rb.sh @@ -0,0 +1,107 @@ +#!/bin/bash + +MODE="tx rx" +MTU=1440 +#VPN=./ulvpn.exe +MOREP=$(dirname $0)/../morep/morep_valid.exe + +MSG="TEST: This is a very long text" + +function mydata() { cat $1 | sed 's/.*=//'; } +function title () { echo -e "\033[0;1m$*\033[0;0m"; } +function pass () { echo -e "\033[1;32m$*\033[0;0m"; } +function warn () { echo -e "\033[1;33m$*\033[0;0m"; test; } +function fail () { echo -e "\033[1;31m$*\033[0;0m"; test; } + +ip addr list | grep 10\.1\.0\. || { ip link add eth0 type dummy && ip addr add dev eth0 10.1.0.1/24; } +DEV=lo + +rm -f in.log out.log + +pids= +{ +if [[ "$MODE" =~ tx ]]; then + stop= + while [ "x$stop" = "x" ]; do + echo -e "SLEEP 100\nR0839 MSG=0" | \ + $MOREP -v 2 \ + -r $DEV://00:00:00:00:00:00/0839 \ + -t $DEV://00:00:00:00:00:00/0829 \ + -l out.log | \ + awk '{print "CM R->B [rx]:", $0}'; + grep -q 54:45:53:54 out.log && stop=1 + done; + + $MOREP -v 2 \ + -r $DEV://00:00:00:00:00:00/0819 \ + -t $DEV://00:00:00:00:00:00/0809 \ + encrypted_data.eth | \ + awk '{print "CM R->B [tx]:", $0}'; +fi +} & +pids="$pids $!" + +{ +if [[ "$MODE" =~ rx ]]; then + stop= + while [ "x$stop" = "x" ]; do + echo -e "SLEEP 100\nR0819 MSG=2" | \ + $MOREP -v 2 \ + -r $DEV://00:00:00:00:00:00/0819 \ + -t $DEV://00:00:00:00:00:00/0809 \ + -l in.log | \ + awk '{print "CM B->R [rx]:", $0}'; + grep -q 54:45:53:54 in.log && stop=1 + done; + + $MOREP -v 2 \ + -r $DEV://00:00:00:00:00:00/0839 \ + -t $DEV://00:00:00:00:00:00/0829 \ + clear_data.eth | \ + awk '{print "CM B->R [tx]:", $0}'; +fi +} & +pids="$pids $!" + +{ sleep 1; echo $MSG | nc -uq0 10.2.1.1 3000; nc -luq0 3000 > text.log; } & +pids="$pids $!" + +#trap "for p in $pids; do kill -9 $p; done; ip addr del dev eth0 10.1.0.1/24 && ip link del eth0 type dummy || echo no need to remove eth0;" 0 1 2 15 + +$@ \ + -v 5 -V 4 \ + -d tun://tun0:$MTU \ + -l tun://10.2.0.1 -r tun://10.2.1.0 \ + -n udp \ + -n black \ + -y $DEV://00:00:00:00:00:00/0829 $DEV://00:00:00:00:00:00/0839 | \ + awk '{ print "red:", $0 }' & +pids="$pids $!" + +$@ \ + -v 5 -V 4 \ + -n tun \ + -t udp://10.1.0.1:1234 -u udp://10.1.0.1:1234 \ + -x $DEV://00:00:00:00:00:00/0809 $DEV://00:00:00:00:00:00/0819 \ + -n red | \ + awk '{ print "black:", $0 }' & +pids="$pids $!" + +sleep 4 + +for p in $pids; do + echo killing $p + pkill -TERM -P $p 2>/dev/null + kill -TERM $p 2>/dev/null +done +ip addr del dev eth0 10.1.0.1/24 && ip link del eth0 type dummy || echo no need to remove eth0 + +rc= +[[ "$MODE" =~ rx ]] && [ "$(mydata in.log)" = "$(mydata encrypted_data.eth)" ] && pass "encrypted data ok" || fail "encrypted data ko" +rc="$rc$?" +[[ "$MODE" =~ tx ]] && [ "$(mydata out.log|hd|tail -8)" = "$(mydata clear_data.eth|hd|tail -8)" ] && pass "clear data ok" || fail "clear data ko" +rc="$rc$?" +[ -f text.log ] && { echo $MSG | diff text.log - && pass "message ok" || fail "message ko"; } +rc="$rc$?" + +test "$rc" = "000" diff --git a/ulvpn-rb.sh b/ulvpn-rb.sh new file mode 100755 index 0000000..2eed51c --- /dev/null +++ b/ulvpn-rb.sh @@ -0,0 +1,93 @@ +#!/bin/bash + +MTU=1440 +[ $# -gt 0 ] && MTU=$1 + +LRED=lo://00:00:00:00:00:00 +LBLK=lo://00:00:00:00:00:00 +RRED=lo://00:00:00:00:00:00 +RBLK=lo://00:00:00:00:00:00 + +CRYPTOMOD=./cryptomod.exe +SIMULATOR=./simulator.exe +VPN=./ulvpn.exe + +ulimit -c unlimited + +title() { echo -e "\033[0;1m$@\033[0;0m"; } + +cat > provisioning.eth < 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ulvpn, ERROR, PRINTF ("%s: module not specified\n", progname)); + return 1; + } + if (strcmp (arg, "tun") == 0) { + devtun = NULL; + loctun = NULL; + remtun = NULL; + } else if (strcmp (arg, "udp") == 0) { + locudp = NULL; + remudp = NULL; + } else if (strcmp (arg, "black") == 0) { + cmlocblack = NULL; + cmremblack = NULL; + } else if (strcmp (arg, "red") == 0) { + cmlocred = NULL; + cmremred = NULL; + } else { + VERBOSE (ulvpn, ERROR, PRINTF ("%s: unknown module (%s)\n", progname, arg)); + return 1; + } + break; + case 'r': arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; if (arg == NULL) { @@ -317,13 +343,13 @@ int main (int argc, char **argv) } /* init udp and tun communication channels */ - int tun_fd = MAPEC_Connect (devtun, loctun, remtun); - if (tun_fd < 0) { + int tun_fd = -1; + if (((devtun) && (loctun) && (remtun)) && ((tun_fd = MAPEC_Connect (devtun, loctun, remtun)) < 0)) { VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s %s\n", devtun, loctun, remtun)); return -1; } - int udp_fd = MAPEC_Connect (locudp, remudp, NULL); - if (udp_fd < 0) { + int udp_fd = -1; + if (((locudp) && (remudp)) && ((udp_fd = MAPEC_Connect (locudp, remudp, NULL)) < 0)) { VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for %s %s\n", locudp, remudp)); return -1; } @@ -331,12 +357,20 @@ int main (int argc, char **argv) /* init crypto module communication channels */ int rxblack_fd = (cmlocblack) ? MOREP_Connect (cmlocblack) : -1; int txblack_fd = (cmremblack) ? MOREP_Connect (cmremblack) : -1; + if ((rxblack_fd < 0) && (txblack_fd < 0)) { + VERBOSE (ulvpn, INFO, PRINTF ("CM Black desactivated\n")); + } else if ((rxblack_fd < 0) || (txblack_fd < 0)) { + VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for CM Black %s %s\n", cmlocblack, cmremblack)); + return -1; + } int rxred_fd = (cmlocred) ? MOREP_Connect (cmlocred) : -1; int txred_fd = (cmremred) ? MOREP_Connect (cmremred) : -1; - int cmok = (rxblack_fd > -1) && (txblack_fd > -1) && (rxred_fd > -1) && (txred_fd > -1); - if (!cmok) { - VERBOSE (ulvpn, INFO, PRINTF ("CM desactivated\n")); + if ((rxred_fd < 0) && (txred_fd < 0)) { + } else if ((rxred_fd < 0) || (txred_fd < 0)) { + VERBOSE (ulvpn, ERROR, PRINTF ("can't open communication for CM red %s %s\n", cmlocred, cmremred)); + return -1; } + VERBOSE (ulvpn, INFO, PRINTF ("fids: %d %d %d %d %d %d\n", tun_fd, udp_fd, rxblack_fd, txblack_fd, rxred_fd, txred_fd)); /* signals */ @@ -351,19 +385,25 @@ int main (int argc, char **argv) fd_set readset; int max_fd = 0; - FD_SET (tun_fd, &readset); - if (max_fd < tun_fd) { - max_fd = tun_fd; + if (tun_fd >= 0) { + FD_SET (tun_fd, &readset); + if (max_fd < tun_fd) { + max_fd = tun_fd; + } } - FD_SET (udp_fd, &readset); - if (max_fd < udp_fd) { - max_fd = udp_fd; + if (udp_fd >= 0) { + FD_SET (udp_fd, &readset); + if (max_fd < udp_fd) { + max_fd = udp_fd; + } } - if (cmok) { + if (rxblack_fd >= 0) { FD_SET (rxblack_fd, &readset); if (max_fd < rxblack_fd) { max_fd = rxblack_fd; } + } + if (rxred_fd >= 0) { FD_SET (rxred_fd, &readset); if (max_fd < rxred_fd) { max_fd = rxred_fd; @@ -386,7 +426,7 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received %d bytes from tun\n", rxlen)); - if (cmok) { + if (txred_fd >= 0) { int txlen = pack_clear_data (buffer, rxlen, sizeof (buffer)); if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when packing clear data\n")); @@ -399,13 +439,15 @@ int main (int argc, char **argv) VERBOSE (ulvpn, DEBUG, PRINTF ("send %d bytes to CM red\n", txlen)); } } - } else { + } else if (udp_fd >= 0) { int txlen = MAPEC_Send (udp_fd, buffer, rxlen); if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n")); } else { VERBOSE (ulvpn, DEBUG, PRINTF ("sent %d bytes to udp\n", txlen)); } + } else { + VERBOSE (ulvpn, WARNING, PRINTF ("can't handle message from tun\n")); } } @@ -417,7 +459,7 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received %d bytes from udp\n", rxlen)); - if (cmok) { + if (txblack_fd >= 0) { int txlen = pack_encrypted_data (buffer, rxlen, sizeof (buffer)); if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when packing encrypted data\n")); @@ -430,13 +472,15 @@ int main (int argc, char **argv) VERBOSE (ulvpn, DEBUG, PRINTF ("send %d bytes to CM black\n", txlen)); } } - } else { + } else if (tun_fd >= 0) { int txlen = MAPEC_Send (tun_fd, buffer, rxlen); if (txlen <= 0) { VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to tun\n")); } else { VERBOSE (ulvpn, DEBUG, PRINTF ("sent %d bytes to tun\n", txlen)); } + } else { + VERBOSE (ulvpn, WARNING, PRINTF ("can't handle message from udp\n")); } } @@ -455,22 +499,26 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received %d bytes from CM black\n", rxlen)); - if (seqtx != seqrx) { + if ((rxred_fd >= 0) && (seqtx != seqrx)) { VERBOSE (ulvpn, WARNING, PRINTF ("incoherent seqnum (%d/%d)\n", seqtx, seqrx)); } if (msgtype == 0x01) { - int txlen = depack_encrypted_data (buffer, rxlen, sizeof (buffer)); - if (txlen <= 0) { - VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking encrypted data\n")); - } else { - VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen)); - txlen = MAPEC_Send (udp_fd, buffer, txlen); + if (udp_fd >= 0) { + int txlen = depack_encrypted_data (buffer, rxlen, sizeof (buffer)); if (txlen <= 0) { - VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n")); + VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking encrypted data\n")); } else { - VERBOSE (ulvpn, DEBUG, PRINTF ("sent to udp %d bytes\n", txlen)); - } + VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen)); + txlen = MAPEC_Send (udp_fd, buffer, txlen); + if (txlen <= 0) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to udp\n")); + } else { + VERBOSE (ulvpn, DEBUG, PRINTF ("sent to udp %d bytes\n", txlen)); + } + } + } else { + VERBOSE (ulvpn, WARNING, PRINTF ("can't handle message %d from CM black\n", msgtype)); } @@ -494,22 +542,26 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received %d bytes from CM red\n", rxlen)); - if (seqtx != seqrx) { + if ((rxblack_fd >= 0) && (seqtx != seqrx)) { VERBOSE (ulvpn, WARNING, PRINTF ("incoherent seqnum (%d/%d)\n", seqtx, seqrx)); } if (msgtype == 0x03) { - int txlen = depack_clear_data (buffer, rxlen, sizeof (buffer)); - if (txlen <= 0) { - VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking clear data\n")); - } else { - VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen)); - txlen = MAPEC_Send (tun_fd, buffer, txlen); + if (tun_fd >= 0) { + int txlen = depack_clear_data (buffer, rxlen, sizeof (buffer)); if (txlen <= 0) { - VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to tun\n")); - } else { - VERBOSE (ulvpn, DEBUG, PRINTF ("sent to tun %d bytes\n", txlen)); + VERBOSE (ulvpn, WARNING, PRINTF ("error when depacking clear data\n")); + } else { + VERBOSE (ulvpn, DEBUG, PRINTF ("depacking %d bytes\n", txlen)); + txlen = MAPEC_Send (tun_fd, buffer, txlen); + if (txlen <= 0) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when sending to tun\n")); + } else { + VERBOSE (ulvpn, DEBUG, PRINTF ("sent to tun %d bytes\n", txlen)); + } } + } else { + VERBOSE (ulvpn, WARNING, PRINTF ("can't handle message %d from CM red\n", msgtype)); } @@ -543,6 +595,13 @@ int main (int argc, char **argv) /* test: ulvpn.exe -x 2>&1 | grep 'black cm service not specified' */ /* test: ulvpn.exe -y 2>&1 | grep 'red cm service not specified' */ +/* test: ulvpn.exe -n 2>&1 | grep 'module not specified' */ +/* test: ulvpn.exe -n foo 2>&1 | grep 'unknown module' */ +/* test: ulvpn.exe -n tun -h | grep 'dev tun ((null))' */ +/* test: ulvpn.exe -n udp -h | grep 'local udp ((null))' */ +/* test: ulvpn.exe -n black -h | grep 'black CM service ((null)|(null))' */ +/* test: ulvpn.exe -n red -h | grep 'red CM service ((null)|(null))' */ + /* test: sudo -u `awk -F: '/sh$/ && $3 != 0 {print $1; exit}' /etc/passwd` ulvpn.exe; test $? -ne 0 */ /* test: ulvpn.exe -d tun://tun0:-1; test $? -ne 0 */ @@ -562,14 +621,15 @@ int main (int argc, char **argv) /* test: ulvpn.exe -u udp://nohost.nowhere:1235; test $? -ne 0 */ /* test: ulvpn.exe -u udp://localhost:-1; test $? -ne 0 */ -/* test: ulvpn.exe -v 5 -V 5 & pid=$!; sleep 1; ip route list dev tun0; rc=$?; sleep 1; kill -INT $pid; test $rc -eq 0 */ +/* test: ulvpn.exe -v 5 -V 5 & pid=$!; sleep 1; ip route list dev tun0; rc=$?; kill -INT $pid; sleep 1; test $rc -eq 0 */ -/* test: ulvpn.exe -v 5 -t udp://\*:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 1235 > pcap & pid2=$!; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; sleep 1; kill -TERM $pid1 $pid2; strings pcap | grep -q TEST */ -/* test: ulvpn.exe -v 5 -l tun://10.2.1.1 -r tun://10.2.0.0 -t udp://localhost:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 3000 > text & pid2=$!; sleep 1; cat pcap | nc -4Nuq0 -p 1235 localhost 1234; sleep 1; kill -TERM $pid1 $pid2; test "$(cat text)" = TEST */ +/* test: ulvpn.exe -v 5 -n black -n red -t udp://\*:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 1235 > pcap & pid2=$!; sleep 1; echo TEST | nc -Nuq0 10.2.1.1 3000; sleep 1; kill -TERM $pid1 $pid2; strings pcap | grep -q TEST */ +/* test: ulvpn.exe -v 5 -n black -n red -l tun://10.2.1.1 -r tun://10.2.0.0 -t udp://localhost:1234 -u udp://localhost:1235 & pid1=$!; sleep 1; nc -ul 3000 > text & pid2=$!; sleep 1; cat pcap | nc -4Nuq0 -p 1235 localhost 1234; sleep 1; kill -TERM $pid1 $pid2; test "$(cat text)" = TEST */ /* test: rm -f pcap text */ /* test: ip addr del dev eth0 10.1.0.1/24 && ip link del eth0 type dummy || echo no need to remove eth0 */ /* test: ./test.sh ulvpn.exe */ +/* test: ./test-rb.sh ulvpn.exe */ /* vim: set ts=4 sw=4 si et: */ -- 2.30.2