From 1b35772b55e1442bfd45c8d0ddbed29d1b82d91e Mon Sep 17 00:00:00 2001 From: Mazet Laurent Date: Thu, 5 Jun 2025 19:58:47 +0200 Subject: [PATCH] add connections with CM (not tested) --- makefile | 2 +- mapec.c | 2 +- udp_valid.c | 1 - ulvpn.c | 190 ++++++++++++++++++++++++++++++++++++++++++++++++++-- 4 files changed, 187 insertions(+), 8 deletions(-) diff --git a/makefile b/makefile index 6e11254..af2f212 100644 --- a/makefile +++ b/makefile @@ -144,7 +144,7 @@ gcov_%: $(MAKE) purge $(MAKE) depends OPTIONS="-coverage -O0" $(MAKE) ${@:gcov_%=%}.exe - $(MAKE) test_$(@:gcov_%=%) + umask 000; $(MAKE) test_$(@:gcov_%=%) gcov `sed -e 's/\.exe:/.c/;s/\.o/.c/g;s/ -l[^ ]*//g' $(@:gcov_%=%.ld)` $(MAKE) purge grep '^ *#####' *.c.gcov || true diff --git a/mapec.c b/mapec.c index 87f427a..4f8877f 100644 --- a/mapec.c +++ b/mapec.c @@ -88,7 +88,7 @@ void free_all_mapecs (void) } } -void __attribute__ ((constructor)) _init_morep_ (void) +void __attribute__ ((constructor)) _init_mapec_ (void) { atexit (free_all_mapecs); } diff --git a/udp_valid.c b/udp_valid.c index 10fea07..1589960 100644 --- a/udp_valid.c +++ b/udp_valid.c @@ -490,7 +490,6 @@ int main (int argc, char **argv) } /* test: udp_valid.exe -h | grep usage */ -/* test: chmod a+w *.gcda */ /* test: udp_valid.exe -l 2>&1 | grep 'log file not specified' */ /* test: udp_valid.exe -r 2>&1 | grep 'receiver url not specified' */ /* test: udp_valid.exe -s 2>&1 | grep 'service name not specified' */ diff --git a/ulvpn.c b/ulvpn.c index 6138c73..d460120 100644 --- a/ulvpn.c +++ b/ulvpn.c @@ -14,7 +14,7 @@ /* depend: */ /* cflags: */ -/* linker: mapec.o */ +/* linker: mapec.o -lmorep */ #include #include @@ -24,17 +24,23 @@ #include #include +#include +#include +#include + #include "mapec.h" #include "verbose.h" char *progname = NULL; -char *version = "0.1"; +char *version = "0.9"; char *devtun = "tun://tun0:1440"; char *loctun = "tun://10.2.0.1"; char *remtun = "tun://10.2.1.0"; char *locudp = "udp://10.1.0.1:1234"; char *remudp = "udp://10.1.0.2:1235"; +char *cmblack = ""; +char *cmred = ""; int stop = 0; @@ -44,6 +50,12 @@ int stop = 0; DECLARE_VERBOSE_LEVEL (ulvpn, INFO); +typedef struct { + uint8_t aad[4]; + int red; + int black; +} cm_t; + void sig_handler (int sig) { switch (sig) { @@ -67,9 +79,143 @@ void usage (void) printf (" -u: remote udp (%s)\n", remudp); printf (" -v: program verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (ulvpn)); printf (" -V: library verbose level [%d..%d] (%d)\n", ERROR, TRACE, GET_VERBOSE_LEVEL (mapec)); + printf (" -x: black CM service (%s)\n", cmblack); + printf (" -y: red CM service (%s)\n", cmred); printf ("%s version %s\n", progname, version); } +int encrypt (uint8_t *buffer, int len, cm_t *cm) +{ + + /* create clear message */ + CLEAR_DATA_t msg = {0}; + msg.channel_id = 0; + msg.bypass_len = 0; + memcpy (msg.aad + sizeof (msg.aad) - sizeof (cm->aad), cm->aad, sizeof (cm->aad)); + int npad = 16 - (len % 16); + if (len + npad > (int)sizeof (msg.data)) { + VERBOSE (ulvpn, WARNING, PRINTF ("too long payload (%d)\n", len)); + len = sizeof (msg.data) - 1; + npad = 1; + } + VERBOSE (ulvpn, DEBUG, PRINTF ("padding %d byte%s\n", npad, (npad > 1) ? "s" : "")); + memcpy (msg.data, buffer, len); + msg.data[len + npad - 1] = npad; + //memset (buffer, 0, len); + msg.data_len = len + npad; + + /* serialize message and send it */ + uint8_t out[MAXPAYLOAD] = {0}; + int out_len = serial_clear_data (&msg, out, sizeof (out)); + if (out_len < 0) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when serializing clear message\n")); + return 0; + } + int seqtx = MOREP_Send (cm->red, 0x00, out, out_len); + + /* get encrypted message and check it */ + uint8_t in[MAXPAYLOAD] = {0}; + uint8_t msgtype = 0; + int in_len = 0; + int seqrx = MOREP_Receive (cm->black, &msgtype, in, &in_len); + if ((msgtype != 0x01) || (in_len != out_len + 16) || (seqtx != seqrx)) { + VERBOSE (ulvpn, WARNING, PRINTF ("non-coherent encrypyted message\n")); + return 0; + } + ENCRYPTED_DATA_t enc = {0}; + if (!deserial_encrypted_data (in, in_len, &enc)) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when deserializing encrypted message\n")); + return 0; + } + + /* build output message */ + len = 0; + //buf[len++] = enc.channel_id; + //check msg.bypass_len + memcpy (buffer + len, cm->aad, sizeof (cm->aad)); + len += sizeof (cm->aad); + memcpy (buffer + len, enc.iv, sizeof (enc.iv)); + len += sizeof (enc.iv); + memcpy (buffer + len, enc.data, enc.data_len); + len += enc.data_len; + + return len; +} + +int decrypt (uint8_t *buffer, int len, cm_t *cm) +{ + + /* create encrypted message */ + ENCRYPTED_DATA_t enc = {0}; + int i = 0; + //if (i + 1 > len) { + // VERBOSE (ulvpn, WARNING, PRINTF ("no channel id\n"); + // return 0; + //} + //enc.channel_id = buffer[i++]; + enc.bypass_len = 0; + if (i + (int)sizeof (cm->aad) > len) { + VERBOSE (ulvpn, ERROR, PRINTF ("incompleted aad\n")); + return 0; + } + memcpy (enc.aad + sizeof (enc.aad) - sizeof (cm->aad), buffer + i, sizeof (cm->aad)); + i += sizeof (cm->aad); + if (i + (int)sizeof (enc.iv) > len) { + VERBOSE (ulvpn, ERROR, PRINTF ("incompleted iv\n")); + return 0; + } + memcpy (enc.iv, buffer + i, sizeof (enc.iv)); + i += sizeof (enc.iv); + if (len - i < 32) { + VERBOSE (ulvpn, ERROR, PRINTF ("incompleted tag\n")); + return 0; + } + if ((len - i) % 16 != 0) { + VERBOSE (ulvpn, ERROR, PRINTF ("incompleted encrypted message\n")); + return 0; + } + memcpy (enc.data, buffer + i, len - i); + enc.data_len = len - i; + + /* serialize message and send it */ + uint8_t out[MAXPAYLOAD] = {0}; + int out_len = serial_encrypted_data (&enc, out, sizeof (out)); + if (out_len < 0) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when serializing encrypted message\n")); + return 0; + } + int seqtx = MOREP_Send (cm->black, 0x02, out, out_len); + + /* get clear message and check it */ + uint8_t in[MAXPAYLOAD] = {0}; + uint8_t msgtype = 0; + int in_len = 0; + int seqrx = MOREP_Receive (cm->red, &msgtype, in, &in_len); + if ((msgtype != 0x03) || (in_len != out_len - 16) || (seqtx != seqrx)) { + VERBOSE (ulvpn, WARNING, PRINTF ("non-coherent decrypted message\n")); + return 0; + } + CLEAR_DATA_t msg = {0}; + if (!deserial_clear_data (in, in_len, &msg)) { + VERBOSE (ulvpn, WARNING, PRINTF ("error when deserializing decrypted message\n")); + return 0; + } + + /* build output message */ + len = 0; + //buf[len++] = enc.channel_id; + //check msg.bypass_len + int npad = in[in_len - 1]; + if ((npad > 16) || (msg.data_len < npad)) { + VERBOSE (ulvpn, WARNING, PRINTF ("non-coherent padding (%d)\n", npad)); + return 0; + } + memcpy (buffer + len, enc.data, enc.data_len - npad); + len += enc.data_len - npad; + + return len; +} + int main (int argc, char **argv) { @@ -147,6 +293,22 @@ int main (int argc, char **argv) } CHANGE_VERBOSE_LEVEL (mapec, atoi (arg)); break; + case 'x': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ulvpn, ERROR, PRINTF ("%s: black cm service not specified\n", progname)); + return 1; + } + cmblack = arg; + break; + case 'y': + arg = (arg[2]) ? arg + 2 : (--argc > 0) ? *(++argv) : NULL; + if (arg == NULL) { + VERBOSE (ulvpn, ERROR, PRINTF ("%s: red cm service not specified\n", progname)); + return 1; + } + cmred = arg; + break; case 'h': default: usage (); @@ -166,6 +328,19 @@ int main (int argc, char **argv) return -1; } + /* init crypto module */ + cm_t cm = {{0, 0, 0, 0}, -1, -1}; + if ((cmblack) && (*cmblack)) { + cm.black = MOREP_Connect (cmblack); + } + if ((cmred) && (*cmred)) { + cm.red = MOREP_Connect (cmred); + } + int cmok = (cm.black >= 0) && (cm.red >= 0); + if (!cmok) { + VERBOSE (ulvpn, INFO, PRINTF ("CM desactivated\n")); + } + /* signals */ signal(SIGINT, sig_handler); signal(SIGTERM, sig_handler); @@ -199,7 +374,9 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received from tun %d bytes\n", r)); - //encrypt it + if (cmok) { + r = encrypt (buffer, r, &cm); + } r = MAPEC_Send (udp_fd, buffer, r); if (r < 0) { @@ -220,7 +397,9 @@ int main (int argc, char **argv) } else { VERBOSE (ulvpn, DEBUG, PRINTF ("received from udp %d bytes\n", r)); - //decrypt it + if (cmok) { + r = decrypt (buffer, r, &cm); + } r = MAPEC_Send (tun_fd, buffer, r); if (r < 0) { @@ -244,7 +423,6 @@ int main (int argc, char **argv) } /* test: ulvpn.exe -h | grep usage */ -/* test: chmod a+w *.gcda */ /* test: ulvpn.exe help 2>&1 | grep usage */ /* test: ulvpn.exe -d 2>&1 | grep 'dev tun not specified' */ /* test: ulvpn.exe -l 2>&1 | grep 'local tun not specified' */ @@ -253,6 +431,8 @@ int main (int argc, char **argv) /* test: ulvpn.exe -u 2>&1 | grep 'remote udp not specified' */ /* test: ulvpn.exe -v 2>&1 | grep 'verbose level not specified' */ /* test: ulvpn.exe -V 2>&1 | grep 'verbose level not specified' */ +/* 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: sudo -u `awk -F: '/sh$/ && $3 != 0 {print $1; exit}' /etc/passwd` ulvpn.exe; test $? -ne 0 */ -- 2.30.2