1
0
mirror of git://f0xx.org/ac/ac-mobile-android synced 2026-07-29 04:59:30 +03:00

Implement native iodine client and fix RA heartbeat URL resolution.

Bundle iodine 0.7.0 with JNI TUN bridge; apply BE iodine credentials on connect; canonical heartbeat URL fallback.

Co-authored-by: Cursor <cursoragent@cursor.com>
This commit is contained in:
Anton Afanasyeu
2026-07-12 19:44:38 +02:00
parent cd520cadd1
commit 2619848d1b
73 changed files with 14063 additions and 29 deletions

25
third-party/iodine/tests/Makefile vendored Normal file
View File

@@ -0,0 +1,25 @@
TEST = test
OBJS = test.o base32.o base64.o common.o read.o dns.o encoding.o login.o user.o fw_query.o
SRCOBJS = ../src/base32.o ../src/base64.o ../src/common.o ../src/read.o ../src/dns.o ../src/encoding.o ../src/login.o ../src/md5.o ../src/user.o ../src/fw_query.o
OS = `uname | tr "a-z" "A-Z"`
CHECK_PATH = /usr/local
LDFLAGS = -L$(CHECK_PATH)/lib `pkg-config check --libs` -lpthread `sh ../src/osflags $(TARGETOS) link`
CFLAGS = -std=c99 -g -Wall -D$(OS) `pkg-config check --cflags` -I../src -I$(CHECK_PATH)/include -pedantic `sh ../src/osflags $(TARGETOS) cflags`
all: $(TEST)
@LD_LIBRARY_PATH=${CHECK_PATH}/lib ./$(TEST)
$(TEST): $(OBJS) $(SRCOBJS)
@echo LD $(TEST)
@$(CC) -o $@ $(SRCOBJS) $(OBJS) $(LDFLAGS)
.c.o:
@echo CC $<
@$(CC) $(CFLAGS) -c $<
clean:
@echo "Cleaning tests/"
@rm -f *~ *.core $(TEST) $(OBJS)

133
third-party/iodine/tests/base32.c vendored Normal file
View File

@@ -0,0 +1,133 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "encoding.h"
#include "test.h"
#define TUPLES 5
static struct tuple
{
char *a;
char *b;
} testpairs[TUPLES] = {
{ "iodinetestingtesting", "nfxwi0lomv0gk21unfxgo3dfon0gs1th" },
{ "abc123", "mfrggmjsgm" },
{ "test", "orsxg3a" },
{ "tst", "orzxi" },
{ "", "" },
};
START_TEST(test_base32_encode)
{
size_t len;
char buf[4096];
int val;
len = sizeof(buf);
val = base32_ops.encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
ck_assert(val == strlen(testpairs[_i].b));
ck_assert_str_eq(buf, testpairs[_i].b);
}
END_TEST
START_TEST(test_base32_decode)
{
size_t len;
char buf[4096];
int val;
len = sizeof(buf);
val = base32_ops.decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
ck_assert(val == strlen(testpairs[_i].a));
ck_assert_str_eq(buf, testpairs[_i].a);
}
END_TEST
START_TEST(test_base32_5to8_8to5)
{
int i;
int c;
for (i = 0; i < 32; i++) {
c = b32_5to8(i);
ck_assert(b32_8to5(c) == i);
}
}
END_TEST
START_TEST(test_base32_blksize)
{
size_t rawlen;
size_t enclen;
char *rawbuf;
char *encbuf;
int i;
int val;
rawlen = base32_ops.blocksize_raw;
enclen = base32_ops.blocksize_encoded;
rawbuf = malloc(rawlen + 16);
encbuf = malloc(enclen + 16);
for (i = 0; i < rawlen; i++) {
rawbuf[i] = 'A';
}
rawbuf[i] = 0;
val = base32_ops.encode(encbuf, &enclen, rawbuf, rawlen);
ck_assert_msg(rawlen == 5, "raw length was %zu not 5", rawlen);
ck_assert_msg(enclen == 5, "encoded %zu bytes, not 5", enclen);
ck_assert_msg(val == 8, "encoded string %s was length %d", encbuf, val);
memset(rawbuf, 0, rawlen + 16);
enclen = val;
val = base32_ops.decode(rawbuf, &rawlen, encbuf, enclen);
ck_assert_msg(rawlen == 5, "raw length was %zu not 5", rawlen);
ck_assert_msg(val == 5, "val was not 5 but %d", val);
for (i = 0; i < rawlen; i++) {
ck_assert(rawbuf[i] == 'A');
}
}
END_TEST
TCase *
test_base32_create_tests(void)
{
TCase *tc;
tc = tcase_create("Base32");
tcase_add_loop_test(tc, test_base32_encode, 0, TUPLES);
tcase_add_loop_test(tc, test_base32_decode, 0, TUPLES);
tcase_add_test(tc, test_base32_5to8_8to5);
tcase_add_test(tc, test_base32_blksize);
return tc;
}

145
third-party/iodine/tests/base64.c vendored Normal file
View File

@@ -0,0 +1,145 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <errno.h>
#include "encoding.h"
#include "test.h"
#define TUPLES 5
static struct tuple
{
char *a;
char *b;
} testpairs[TUPLES] = {
{ "iodinetestingtesting", "Aw8KAw4LDgvZDgLUz2rLC2rPBMC" },
{ "abc1231", "ywjJmtiZmq" },
{
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
"\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
"\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40\x3F\x3F\x3C\xEF\xAE\x78"
"\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60"
"\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48"
"\x1C\x61\x44\x0C\x20\x40\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70"
"\xBE\xEB\x6C\xAE\xAA\x68\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
"+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
"776543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654"
"3210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
},
{
"\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xAA\x68"
"\x9E\x69\x64\x8E\x28\x60\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50"
"\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40\x3F\x3F\x3C\xEF\xAE\x78"
"\xDF\x6D\x74\xCF\x2C\x70\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60"
"\x7D\xE7\x5C\x6D\xA6\x58\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48"
"\x1C\x61\x44\x0C\x20\x40\xFF\xEF\x7C\xEF\xAE\x78\xDF\x6D\x74\xCF\x2C\x70"
"\xBE\xEB\x6C\xAE\xA1\x61\x91\x61\x61\x81\x28\x60\x7D\xE7\x5C\x6D\xA6\x58"
"\x5D\x65\x54\x4D\x24\x50\x3C\xE3\x4C\x2C\xA2\x48\x1C\x61\x44\x0C\x20\x40",
"+9876543210-ZYXWVUTSRQPONMLKJIHGFEDCBAzyxwvutsrqponmlkjihgfedcbapZ"
"776543210-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba+987654321"
"0-ZYXWVUTSRQfHKwfHGsHGFEDCBAzyxwvutsrqponmlkjihgfedcba"
},
{ "", "" }
};
START_TEST(test_base64_encode)
{
size_t len;
char buf[4096];
int val;
len = sizeof(buf);
val = base64_ops.encode(buf, &len, testpairs[_i].a, strlen(testpairs[_i].a));
ck_assert(val == strlen(testpairs[_i].b));
ck_assert_str_eq(buf, testpairs[_i].b);
}
END_TEST
START_TEST(test_base64_decode)
{
size_t len;
char buf[4096];
int val;
len = sizeof(buf);
val = base64_ops.decode(buf, &len, testpairs[_i].b, strlen(testpairs[_i].b));
ck_assert(val == strlen(testpairs[_i].a));
ck_assert_str_eq(buf, testpairs[_i].a);
}
END_TEST
START_TEST(test_base64_blksize)
{
size_t rawlen;
size_t enclen;
char *rawbuf;
char *encbuf;
int i;
int val;
rawlen = base64_ops.blocksize_raw;
enclen = base64_ops.blocksize_encoded;
rawbuf = malloc(rawlen + 16);
encbuf = malloc(enclen + 16);
for (i = 0; i < rawlen; i++) {
rawbuf[i] = 'A';
}
rawbuf[i] = 0;
val = base64_ops.encode(encbuf, &enclen, rawbuf, rawlen);
ck_assert_msg(rawlen == 3, "raw length was %zu not 3", rawlen);
ck_assert_msg(enclen == 3, "encoded %zu bytes, not 3", enclen);
ck_assert_msg(val == 4, "encoded string %s was length %d", encbuf, val);
memset(rawbuf, 0, rawlen + 16);
enclen = val;
val = base64_ops.decode(rawbuf, &rawlen, encbuf, enclen);
ck_assert_msg(rawlen == 3, "raw length was %zu not 3", rawlen);
ck_assert(val == 3);
for (i = 0; i < rawlen; i++) {
ck_assert(rawbuf[i] == 'A');
}
}
END_TEST
TCase *
test_base64_create_tests(void)
{
TCase *tc;
tc = tcase_create("Base64");
tcase_add_loop_test(tc, test_base64_encode, 0, TUPLES);
tcase_add_loop_test(tc, test_base64_decode, 0, TUPLES);
tcase_add_test(tc, test_base64_blksize);
return tc;
}

330
third-party/iodine/tests/common.c vendored Normal file
View File

@@ -0,0 +1,330 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <common.h>
#include <unistd.h>
#include <sys/socket.h>
#include <netdb.h>
START_TEST(test_topdomain_ok)
{
char *error = NULL;
ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error) == 0);
ck_assert(error == NULL);
/* Allowing wildcard */
ck_assert(check_topdomain("foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 1, &error) == 0);
ck_assert(error == NULL);
/* Not allowed to start with dot */
ck_assert(check_topdomain(".foo.0123456789.qwertyuiop.asdfghjkl.zxcvbnm.com", 0, &error));
ck_assert_str_eq("Starts with a dot", error);
/* Test missing error msg ptr */
ck_assert(check_topdomain(".foo", 0, NULL));
}
END_TEST
START_TEST(test_topdomain_length)
{
char *error;
/* Test empty and too short */
ck_assert(check_topdomain("", 0, &error));
ck_assert_str_eq("Too short (< 3)", error);
error = NULL;
ck_assert(check_topdomain("a", 0, &error));
ck_assert_str_eq("Too short (< 3)", error);
error = NULL;
ck_assert(check_topdomain(".a", 0, &error));
ck_assert_str_eq("Too short (< 3)", error);
error = NULL;
ck_assert(check_topdomain("a.", 0, &error));
ck_assert_str_eq("Too short (< 3)", error);
error = NULL;
ck_assert(check_topdomain("ab", 0, &error));
ck_assert_str_eq("Too short (< 3)", error);
error = NULL;
ck_assert(check_topdomain("a.b", 0, &error) == 0);
/* Test too long (over 128, need rest of space for data) */
ck_assert(check_topdomain(
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.foo129xxx", 0, &error));
ck_assert_str_eq("Too long (> 128)", error);
ck_assert(check_topdomain(
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.abcd12345.abcd12345.abcd12345."
"abcd12345.abcd12345.foo128xx", 0, &error) == 0);
}
END_TEST
START_TEST(test_topdomain_chunks)
{
char *error;
/* Must have at least one dot */
ck_assert(check_topdomain("abcde.gh", 0, &error) == 0);
ck_assert(check_topdomain("abcdefgh", 0, &error));
ck_assert_str_eq("No dots", error);
/* Not two consecutive dots */
ck_assert(check_topdomain("abc..defgh", 0, &error));
ck_assert_str_eq("Consecutive dots", error);
/* Not end with a dots */
ck_assert(check_topdomain("abc.defgh.", 0, &error));
ck_assert_str_eq("Ends with a dot", error);
/* No chunk longer than 63 chars */
ck_assert(check_topdomain("123456789012345678901234567890"
"123456789012345678901234567890333.com", 0, &error) == 0);
ck_assert(check_topdomain("123456789012345678901234567890"
"1234567890123456789012345678904444.com", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error);
ck_assert(check_topdomain("abc.123456789012345678901234567890"
"123456789012345678901234567890333.com", 0, &error) == 0);
ck_assert(check_topdomain("abc.123456789012345678901234567890"
"1234567890123456789012345678904444.com", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error);
ck_assert(check_topdomain("abc.123456789012345678901234567890"
"123456789012345678901234567890333", 0, &error) == 0);
ck_assert(check_topdomain("abc.123456789012345678901234567890"
"1234567890123456789012345678904444", 0, &error));
ck_assert_str_eq("Too long domain part (> 63)", error);
}
END_TEST
START_TEST(test_topdomain_wild)
{
char *error = NULL;
ck_assert(check_topdomain("*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*.a", 1, &error) == 0);
ck_assert(error == NULL);
ck_assert(check_topdomain("b*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("b*.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
ck_assert(check_topdomain("*b.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*b.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) must be followed by dot", error);
ck_assert(check_topdomain("*.*.a", 0, &error) == 1);
ck_assert_str_eq("Contains illegal character (allowed: [a-zA-Z0-9-.])", error);
error = NULL;
ck_assert(check_topdomain("*.*.a", 1, &error) == 1);
ck_assert_str_eq("Wildcard (*) only allowed as first char", error);
}
END_TEST
START_TEST(test_query_datalen)
{
char *topdomain = "r.foo.com";
/* With data */
ck_assert(query_datalen("foobar.r.foo.com", topdomain) == 7);
ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
ck_assert(query_datalen(".r.foo.com", topdomain) == 1);
/* Without data */
ck_assert(query_datalen("r.foo.com", topdomain) == 0);
ck_assert(query_datalen("R.foo.com", topdomain) == 0);
/* Shorter query name */
ck_assert(query_datalen("foo.com", topdomain) == -1);
/* Mismatched query name */
ck_assert(query_datalen("b.foo.com", topdomain) == -1);
ck_assert(query_datalen("*.foo.com", topdomain) == -1);
/* Query name overlaps topdomain, but is longer */
ck_assert(query_datalen("bar.foo.com", topdomain) == -1);
}
END_TEST
START_TEST(test_query_datalen_wild)
{
char *topdomain = "*.foo.com";
/* With data */
ck_assert(query_datalen("foobar.a.foo.com", topdomain) == 7);
ck_assert(query_datalen("foobar.r.FoO.Com", topdomain) == 7);
ck_assert(query_datalen("foo.bar.r.FoO.Com", topdomain) == 8);
ck_assert(query_datalen("foo.Ab.foo.cOm", topdomain) == 4);
ck_assert(query_datalen("foo.Abcd.Foo.com", topdomain) == 4);
ck_assert(query_datalen("***.STARs.foo.com", topdomain) == 4);
ck_assert(query_datalen(".a.foo.com", topdomain) == 1);
ck_assert(query_datalen(".ab.foo.com", topdomain) == 1);
/* Without data */
ck_assert(query_datalen("rr.foo.com", topdomain) == 0);
ck_assert(query_datalen("b.foo.com", topdomain) == 0);
ck_assert(query_datalen("B.foo.com", topdomain) == 0);
/* Shorter query name */
ck_assert(query_datalen("foo.com", topdomain) == -1);
/* Wildcard part of query name matching topdomain */
ck_assert(query_datalen("aa.*.foo.com", topdomain) == -1);
/* Mismatched query name */
ck_assert(query_datalen("bar.r.boo.com", topdomain) == -1);
}
END_TEST
START_TEST(test_parse_format_ipv4)
{
char *host = "192.168.2.10";
char *formatted;
struct sockaddr_storage addr;
struct sockaddr_in *v4addr;
int addr_len;
addr_len = get_addr(host, 53, AF_INET, 0, &addr);
ck_assert(addr_len == sizeof(struct sockaddr_in));
v4addr = (struct sockaddr_in *) &addr;
ck_assert(v4addr->sin_addr.s_addr == htonl(0xc0a8020a));
ck_assert(v4addr->sin_port == htons(53));
formatted = format_addr(&addr, addr_len);
ck_assert_str_eq(host, formatted);
}
END_TEST
START_TEST(test_parse_format_ipv4_listen_all)
{
char *host = "0.0.0.0";
char *formatted;
struct sockaddr_storage addr;
struct sockaddr_in *v4addr;
int addr_len;
addr_len = get_addr(NULL, 53, AF_INET, AI_PASSIVE, &addr);
ck_assert(addr_len == sizeof(struct sockaddr_in));
v4addr = (struct sockaddr_in *) &addr;
ck_assert(v4addr->sin_addr.s_addr == htonl(0x00000000));
ck_assert(v4addr->sin_port == htons(53));
formatted = format_addr(&addr, addr_len);
ck_assert_str_eq(host, formatted);
}
END_TEST
START_TEST(test_parse_format_ipv6)
{
char *host = "2001:0db8:0505:0::123:0abc";
char *compact = "2001:db8:505::123:abc";
unsigned char v6_bits[] = {
0x20, 0x01, 0x0d, 0xb8, 0x05, 0x05, 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x01, 0x23, 0x0a, 0xbc,
};
char *formatted;
struct sockaddr_storage addr;
struct sockaddr_in6 *v6addr;
int addr_len;
addr_len = get_addr(host, 53, AF_UNSPEC, 0, &addr);
ck_assert(addr_len == sizeof(struct sockaddr_in6));
v6addr = (struct sockaddr_in6 *) &addr;
ck_assert(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)) == 0);
ck_assert(v6addr->sin6_port == htons(53));
formatted = format_addr(&addr, addr_len);
ck_assert_str_eq(compact, formatted);
}
END_TEST
START_TEST(test_parse_format_ipv4_mapped_ipv6)
{
char *v4mapped = "::FFFF:192.168.2.10";
char *host = "192.168.2.10";
unsigned char v6_bits[] = {
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x00, 0x00, 0xff, 0xff, 0xc0, 0xa8, 0x02, 0x0a,
};
char *formatted;
struct sockaddr_storage addr;
struct sockaddr_in6 *v6addr;
int addr_len;
addr_len = get_addr(v4mapped, 53, AF_INET6, 0, &addr);
ck_assert(addr_len == sizeof(struct sockaddr_in6));
v6addr = (struct sockaddr_in6 *) &addr;
ck_assert(memcmp(&v6addr->sin6_addr, v6_bits, sizeof(v6_bits)) == 0);
ck_assert(v6addr->sin6_port == htons(53));
/* Format as IPv4 address */
formatted = format_addr(&addr, addr_len);
ck_assert_str_eq(host, formatted);
}
END_TEST
START_TEST(test_get_addr_err)
{
char *host = "192.168.2.10";
struct sockaddr_storage addr;
int addr_len;
int flags = AI_PASSIVE;
/* Invalid host */
addr_len = get_addr(NULL, -1, flags, 0, &addr);
ck_assert(addr_len == -1);
/* Invalid port */
addr_len = get_addr(host, -1, flags, 0, &addr);
ck_assert(addr_len == -1);
/* Invalid flag */
addr_len = get_addr(host, 53, flags | 0xFFF, 0, &addr);
ck_assert(addr_len == -1);
/* Invalid addr */
addr_len = get_addr(host, 53, flags, 0, (struct sockaddr_storage *)NULL);
ck_assert(addr_len == -1);
}
END_TEST
TCase *
test_common_create_tests(void)
{
TCase *tc;
int sock;
tc = tcase_create("Common");
tcase_add_test(tc, test_topdomain_ok);
tcase_add_test(tc, test_topdomain_length);
tcase_add_test(tc, test_topdomain_chunks);
tcase_add_test(tc, test_topdomain_wild);
tcase_add_test(tc, test_query_datalen);
tcase_add_test(tc, test_query_datalen_wild);
tcase_add_test(tc, test_parse_format_ipv4);
tcase_add_test(tc, test_parse_format_ipv4_listen_all);
tcase_add_test(tc, test_get_addr_err);
/* Tests require IPv6 support */
sock = socket(AF_INET6, SOCK_DGRAM, IPPROTO_UDP);
if (sock >= 0) {
close(sock);
tcase_add_test(tc, test_parse_format_ipv6);
tcase_add_test(tc, test_parse_format_ipv4_mapped_ipv6);
}
return tc;
}

268
third-party/iodine/tests/dns.c vendored Normal file
View File

@@ -0,0 +1,268 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <ctype.h>
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <arpa/nameser.h>
#ifdef DARWIN
#define BIND_8_COMPAT
#include <arpa/nameser_compat.h>
#endif
#include "common.h"
#include "dns.h"
#include "encoding.h"
#include "test.h"
static void dump_packet(char *, size_t);
static char query_packet[] =
"\x05\x39\x01\x00\x00\x01\x00\x00\x00\x00\x00\x01\x2D\x41\x6A\x62\x63"
"\x75\x79\x74\x63\x70\x65\x62\x30\x67\x71\x30\x6C\x74\x65\x62\x75\x78"
"\x67\x69\x64\x75\x6E\x62\x73\x73\x61\x33\x64\x66\x6F\x6E\x30\x63\x61"
"\x7A\x64\x62\x6F\x72\x71\x71\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00"
"\x0A\x00\x01\x00\x00\x29\x10\x00\x00\x00\x80\x00\x00\x00";
static char answer_packet[] =
"\x05\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05\x73\x69\x6C\x6C"
"\x79\x04\x68\x6F\x73\x74\x02\x6F\x66\x06\x69\x6F\x64\x69\x6E\x65\x04"
"\x63\x6F\x64\x65\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00\x0A\x00\x01"
"\xC0\x0C\x00\x0A\x00\x01\x00\x00\x00\x00\x00\x23\x74\x68\x69\x73\x20"
"\x69\x73\x20\x74\x68\x65\x20\x6D\x65\x73\x73\x61\x67\x65\x20\x74\x6F"
"\x20\x62\x65\x20\x64\x65\x6C\x69\x76\x65\x72\x65\x64";
static char answer_packet_high_trans_id[] =
"\x85\x39\x84\x00\x00\x01\x00\x01\x00\x00\x00\x00\x05\x73\x69\x6C\x6C"
"\x79\x04\x68\x6F\x73\x74\x02\x6F\x66\x06\x69\x6F\x64\x69\x6E\x65\x04"
"\x63\x6F\x64\x65\x04\x6B\x72\x79\x6F\x02\x73\x65\x00\x00\x0A\x00\x01"
"\xC0\x0C\x00\x0A\x00\x01\x00\x00\x00\x00\x00\x23\x74\x68\x69\x73\x20"
"\x69\x73\x20\x74\x68\x65\x20\x6D\x65\x73\x73\x61\x67\x65\x20\x74\x6F"
"\x20\x62\x65\x20\x64\x65\x6C\x69\x76\x65\x72\x65\x64";
static char *msgData = "this is the message to be delivered";
static char *topdomain = "kryo.se";
static char *innerData = "HELLO this is the test data";
START_TEST(test_encode_query)
{
char buf[512];
char resolv[512];
struct query q;
const struct encoder *enc;
char *d;
size_t len;
size_t enclen;
int ret;
enclen = sizeof(resolv);
memset(&buf, 0, sizeof(buf));
memset(&resolv, 0, sizeof(resolv));
memset(&q, 0, sizeof(struct query));
q.type = T_NULL;
q.id = 1337;
d = resolv;
enc = &base32_ops;
*d++ = 'A';
enc->encode(d, &enclen, innerData, strlen(innerData));
d = resolv + strlen(resolv);
if (*d != '.') {
*d++ = '.';
}
strcpy(d, topdomain);
len = sizeof(buf);
ret = dns_encode(buf, len, &q, QR_QUERY, resolv, strlen(resolv));
len = sizeof(query_packet) - 1; /* Skip extra null character */
if (strncmp(query_packet, buf, sizeof(query_packet)) || ret != len) {
printf("\n");
dump_packet(query_packet, len);
dump_packet(buf, ret);
}
ck_assert_msg(strncmp(query_packet, buf, sizeof(query_packet)) == 0,
"Did not compile expected packet");
ck_assert_msg(ret == len,
"Bad packet length: %d, expected %zu", ret, len);
}
END_TEST
START_TEST(test_decode_query)
{
char buf[512];
char *domain;
struct query q;
const struct encoder *enc;
size_t len;
memset(&q, 0, sizeof(struct query));
memset(&buf, 0, sizeof(buf));
q.id = 0;
len = sizeof(query_packet) - 1;
enc = &base32_ops;
dns_decode(buf, sizeof(buf), &q, QR_QUERY, query_packet, len);
domain = strstr(q.name, topdomain);
len = sizeof(buf);
unpack_data(buf, len, &(q.name[1]), (int) (domain - q.name) - 1, enc);
ck_assert_msg(strncmp(buf, innerData, strlen(innerData)) == 0,
"Did not extract expected host: '%s'", buf);
ck_assert_msg(strlen(buf) == strlen(innerData),
"Bad host length: %zu, expected %zu: '%s'",
strlen(buf), strlen(innerData), buf);
}
END_TEST
START_TEST(test_encode_response)
{
char buf[512];
char *host = "silly.host.of.iodine.code.kryo.se";
struct query q;
int len;
int ret;
len = sizeof(buf);
memset(&buf, 0, sizeof(buf));
memset(&q, 0, sizeof(struct query));
strncpy(q.name, host, strlen(host));
q.type = T_NULL;
q.id = 1337;
ret = dns_encode(buf, len, &q, QR_ANSWER, msgData, strlen(msgData));
len = sizeof(answer_packet) - 1; /* Skip extra null character */
ck_assert_msg(strncmp(answer_packet, buf, sizeof(answer_packet)) == 0,
"Did not compile expected packet");
ck_assert_msg(ret == len,
"Bad packet length: %d, expected %d", ret, len);
}
END_TEST
START_TEST(test_decode_response)
{
char buf[512];
struct query q;
int len;
int ret;
len = sizeof(buf);
memset(&buf, 0, sizeof(buf));
ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet, sizeof(answer_packet)-1);
ck_assert_msg(ret == strlen(msgData),
"Bad data length: %d, expected %zu", ret, strlen(msgData));
ck_assert_msg(strncmp(msgData, buf, strlen(msgData)) == 0,
"Did not extract expected data");
ck_assert(q.id == 0x0539);
}
END_TEST
START_TEST(test_decode_response_with_high_trans_id)
{
char buf[512];
struct query q;
int len;
int ret;
len = sizeof(buf);
memset(&buf, 0, sizeof(buf));
ret = dns_decode(buf, len, &q, QR_ANSWER, answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id)-1);
ck_assert_msg(ret == strlen(msgData),
"Bad data length: %d, expected %zu", ret, strlen(msgData));
ck_assert_msg(strncmp(msgData, buf, strlen(msgData)) == 0,
"Did not extract expected data");
ck_assert_msg(q.id == 0x8539,
"q.id was %08X instead of %08X!", q.id, 0x8539);
}
END_TEST
START_TEST(test_get_id_short_packet)
{
char buf[5];
int len;
unsigned short id;
len = sizeof(buf);
memset(&buf, 5, sizeof(buf));
id = dns_get_id(buf, len);
ck_assert(id == 0);
}
END_TEST
START_TEST(test_get_id_low)
{
unsigned short id;
id = dns_get_id(answer_packet, sizeof(answer_packet));
ck_assert(id == 1337);
}
END_TEST
START_TEST(test_get_id_high)
{
unsigned short id;
id = dns_get_id(answer_packet_high_trans_id, sizeof(answer_packet_high_trans_id));
ck_assert(id == 0x8539);
}
END_TEST
static void
dump_packet(char *buf, size_t len)
{
int pos;
for (pos = 0; pos < len; pos++) {
printf("\\x%02X", (unsigned char) buf[pos]);
}
printf("\n");
for (pos = 0; pos < len; pos++) {
if (isalnum((unsigned char) buf[pos])) {
printf(" %c ", (unsigned char) buf[pos]);
} else {
printf(" ");
}
}
printf("\n");
}
TCase *
test_dns_create_tests(void)
{
TCase *tc;
tc = tcase_create("Dns");
tcase_add_test(tc, test_encode_query);
tcase_add_test(tc, test_decode_query);
tcase_add_test(tc, test_encode_response);
tcase_add_test(tc, test_decode_response);
tcase_add_test(tc, test_decode_response_with_high_trans_id);
tcase_add_test(tc, test_get_id_short_packet);
tcase_add_test(tc, test_get_id_low);
tcase_add_test(tc, test_get_id_high);
return tc;
}

106
third-party/iodine/tests/encoding.c vendored Normal file
View File

@@ -0,0 +1,106 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include "encoding.h"
#include "test.h"
#define TUPLES 4
static struct tuple
{
char *a;
char *b;
} dottests[] = {
{ "aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaabaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaa"},
{ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa."},
{ "aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa",
"aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa.aaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaaa"},
{ "abc123", "abc123" },
{ NULL, NULL }
};
START_TEST(test_inline_dotify)
{
char temp[1024];
char *b;
memset(temp, 0, sizeof(temp));
strcpy(temp, dottests[_i].a);
b = temp;
inline_dotify(b, sizeof(temp));
ck_assert_str_eq(dottests[_i].b, temp);
}
END_TEST
START_TEST(test_inline_undotify)
{
char temp[1024];
char *b;
memset(temp, 0, sizeof(temp));
strcpy(temp, dottests[_i].b);
b = temp;
inline_undotify(b, sizeof(temp));
ck_assert_str_eq(dottests[_i].a, temp);
}
END_TEST
START_TEST(test_build_hostname)
{
char data[256];
char buf[1024];
char *topdomain = "a.c";
int buflen;
int i;
for (i = 0; i < sizeof(data); i++) {
data[i] = i & 0xFF;
}
buflen = sizeof(buf);
for (i = 1; i < sizeof(data); i++) {
int len = build_hostname(buf, buflen, data, i, topdomain, &base32_ops, sizeof(buf));
ck_assert(len <= i);
ck_assert_msg(strstr(buf, "..") == NULL,
"Found double dots when encoding data len %d! buf: %s", i, buf);
}
}
END_TEST
TCase *
test_encoding_create_tests(void)
{
TCase *tc;
tc = tcase_create("Encoding");
tcase_add_loop_test(tc, test_inline_dotify, 0, TUPLES);
tcase_add_loop_test(tc, test_inline_undotify, 0, TUPLES);
tcase_add_test(tc, test_build_hostname);
return tc;
}

88
third-party/iodine/tests/fw_query.c vendored Normal file
View File

@@ -0,0 +1,88 @@
/*
* Copyright (c) 2009-2014 Erik Ekman <yarrick@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include "fw_query.h"
#include "test.h"
START_TEST(test_fw_query_simple)
{
struct fw_query q;
struct fw_query *qp;
q.addrlen = 33;
q.id = 0x848A;
fw_query_init();
/* Test empty cache */
fw_query_get(0x848A, &qp);
ck_assert(qp == NULL);
fw_query_put(&q);
/* Test cache with one entry */
fw_query_get(0x848A, &qp);
ck_assert(qp->addrlen == q.addrlen);
ck_assert(qp->id == q.id);
}
END_TEST
START_TEST(test_fw_query_edge)
{
struct fw_query q;
struct fw_query *qp;
int i;
fw_query_init();
q.addrlen = 33;
q.id = 0x848A;
fw_query_put(&q);
for (i = 1; i < FW_QUERY_CACHE_SIZE; i++) {
q.addrlen++;
q.id++;
fw_query_put(&q);
}
/* The query should still be cached */
fw_query_get(0x848A, &qp);
ck_assert(qp->addrlen == 33);
ck_assert(qp->id == 0x848A);
q.addrlen++;
q.id++;
fw_query_put(&q);
/* but now it is overwritten */
fw_query_get(0x848A, &qp);
ck_assert(qp == NULL);
}
END_TEST
TCase *
test_fw_query_create_tests(void)
{
TCase *tc;
tc = tcase_create("Forwarded query");
tcase_add_test(tc, test_fw_query_simple);
tcase_add_test(tc, test_fw_query_edge);
return tc;
}

71
third-party/iodine/tests/login.c vendored Normal file
View File

@@ -0,0 +1,71 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <string.h>
#include "test.h"
#include "login.h"
START_TEST(test_login_hash)
{
char ans[16];
char good[] = "\x2A\x8A\x12\xB4\xE0\x42\xEE\xAB\xD0\x19\x17\x1E\x44\xA0\x88\xCD";
char pass[32] = "iodine is the shit";
int len;
int seed;
len = sizeof(ans);
seed = 15;
memset(ans, 0, sizeof(ans));
login_calculate(ans, len, pass, seed);
ck_assert(strncmp(ans, good, len) == 0);
}
END_TEST
START_TEST(test_login_hash_short)
{
char ans[8];
char check[sizeof(ans)];
char pass[32] = "iodine is the shit";
int len;
int seed;
len = sizeof(ans);
seed = 15;
memset(ans, 0, sizeof(ans));
memset(check, 0, sizeof(check));
/* If len < 16, it should do nothing */
login_calculate(ans, len, pass, seed);
ck_assert(memcmp(ans, check, sizeof(ans)) == 0);
}
END_TEST
TCase *
test_login_create_tests(void)
{
TCase *tc;
tc = tcase_create("Login");
tcase_add_test(tc, test_login_hash);
tcase_add_test(tc, test_login_hash_short);
return tc;
}

292
third-party/iodine/tests/read.c vendored Normal file
View File

@@ -0,0 +1,292 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <sys/types.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <sys/stat.h>
#include <arpa/nameser.h>
#ifdef DARWIN
#define BIND_8_COMPAT
#include <arpa/nameser_compat.h>
#endif
#include <stdio.h>
#include <stdint.h>
#include <stdlib.h>
#include <string.h>
#include <check.h>
#include "common.h"
#include "encoding.h"
#include "dns.h"
#include "read.h"
#include "test.h"
START_TEST(test_read_putshort)
{
unsigned short k;
unsigned short l;
char* p;
int i;
for (i = 0; i < 65536; i++) {
p = (char*)&k;
putshort(&p, i);
ck_assert_msg(ntohs(k) == i,
"Bad value on putshort for %d: %d != %d",
i, ntohs(k), i);
p = (char*)&k;
readshort(NULL, &p, &l);
ck_assert_msg(l == i,
"Bad value on readshort for %d: %d != %d",
i, l, i);
}
}
END_TEST
START_TEST(test_read_putlong)
{
uint32_t k;
uint32_t l;
char* p;
int i;
int j;
for (i = 0; i < 32; i++) {
p = (char*)&k;
j = 0xf << i;
putlong(&p, j);
ck_assert_msg(ntohl(k) == j,
"Bad value on putlong for %d: %d != %d", i, ntohl(j), j);
p = (char*)&k;
readlong(NULL, &p, &l);
ck_assert_msg(l == j,
"Bad value on readlong for %d: %d != %d", i, l, j);
}
}
END_TEST
START_TEST(test_read_name_empty_loop)
{
unsigned char emptyloop[] = {
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
char buf[1024];
char *data;
int rv;
memset(buf, 0, sizeof(buf));
data = (char*) emptyloop + sizeof(HEADER);
buf[1023] = 'A';
rv = readname((char *) emptyloop, sizeof(emptyloop), &data, buf, 1023);
ck_assert(rv == 0);
ck_assert(buf[1023] == 'A');
}
END_TEST
START_TEST(test_read_name_inf_loop)
{
unsigned char infloop[] = {
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x01, 'A', 0xc0, 0x0c, 0x00, 0x01, 0x00, 0x01 };
char buf[1024];
char *data;
int rv;
memset(buf, 0, sizeof(buf));
data = (char*) infloop + sizeof(HEADER);
buf[4] = '\a';
rv = readname((char*) infloop, sizeof(infloop), &data, buf, 4);
ck_assert(rv == 3);
ck_assert(buf[4] == '\a');
}
END_TEST
START_TEST(test_read_name_longname)
{
unsigned char longname[] =
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x3FzBCDEFGHIJKLMNOPQURSTUVXYZ0123456789abcdefghijklmnopqrstuvxyzAA"
"\x00\x00\x01\x00\x01";
char buf[1024];
char *data;
int rv;
memset(buf, 0, sizeof(buf));
data = (char*) longname + sizeof(HEADER);
buf[256] = '\a';
rv = readname((char*) longname, sizeof(longname), &data, buf, 256);
ck_assert(rv == 256);
ck_assert(buf[256] == '\a');
}
END_TEST
START_TEST(test_read_name_onejump)
{
unsigned char onejump[] =
"AA\x81\x80\x00\x01\x00\x00\x00\x00\x00\x00"
"\x02hh\xc0\x15\x00\x01\x00\x01\x05zBCDE\x00";
char buf[1024];
char *data;
int rv;
memset(buf, 0, sizeof(buf));
data = (char*) onejump + sizeof(HEADER);
rv = readname((char*) onejump, sizeof(onejump), &data, buf, 256);
ck_assert(rv == 9);
}
END_TEST
START_TEST(test_read_name_badjump_start)
{
unsigned char badjump[] = {
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
unsigned char *jumper;
char buf[1024];
char *data;
int rv;
/* This test uses malloc to cause segfault if jump is executed */
memset(buf, 0, sizeof(buf));
jumper = malloc(sizeof(badjump));
if (jumper) {
memcpy(jumper, badjump, sizeof(badjump));
data = (char*) jumper + sizeof(HEADER);
rv = readname((char*) jumper, sizeof(badjump), &data, buf, 256);
ck_assert(rv == 0);
ck_assert(buf[0] == 0);
}
free(jumper);
}
END_TEST
START_TEST(test_read_name_badjump_second)
{
unsigned char badjump2[] = {
'A', 'A', 0x81, 0x80, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
0x02, 'B', 'A', 0xfe, 0xcc, 0x00, 0x01, 0x00, 0x01 };
unsigned char *jumper;
char buf[1024];
char *data;
int rv;
/* This test uses malloc to cause segfault if jump is executed */
memset(buf, 0, sizeof(buf));
jumper = malloc(sizeof(badjump2));
if (jumper) {
memcpy(jumper, badjump2, sizeof(badjump2));
data = (char*) jumper + sizeof(HEADER);
rv = readname((char*) jumper, sizeof(badjump2), &data, buf, 256);
ck_assert(rv == 4);
ck_assert_str_eq("BA.", buf);
}
free(jumper);
}
END_TEST
START_TEST(test_putname)
{
char out[] = "\x06" "BADGER\x06" "BADGER\x04" "KRYO\x02" "SE\x00";
char buf[256];
char *domain = "BADGER.BADGER.KRYO.SE";
char *b;
int ret;
memset(buf, 0, 256);
b = buf;
ret = putname(&b, 256, domain);
ck_assert(ret == strlen(domain) + 1);
ck_assert_msg(strncmp(buf, out, ret) == 0, "Happy flow failed");
}
END_TEST
START_TEST(test_putname_nodot)
{
char buf[256];
char *nodot =
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ"
"ABCDEFGHIJKLMNOPQRSTUVWXYZABCDEFGHIJKLMNOPQRSTUVWXYZ";
char *b;
int ret;
memset(buf, 0, 256);
b = buf;
ret = putname(&b, 256, nodot);
ck_assert(ret == -1);
ck_assert(b == buf);
}
END_TEST
START_TEST(test_putname_toolong)
{
char buf[256];
char *toolong =
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ."
"ABCDEFGHIJKLMNOPQRSTUVWXYZ.ABCDEFGHIJKLMNOPQRSTUVWXYZ.";
char *b;
int ret;
memset(buf, 0, 256);
b = buf;
ret = putname(&b, 256, toolong);
ck_assert(ret == -1);
ck_assert(b == buf);
}
END_TEST
TCase *
test_read_create_tests(void)
{
TCase *tc;
tc = tcase_create("Read");
tcase_set_timeout(tc, 60);
tcase_add_test(tc, test_read_putshort);
tcase_add_test(tc, test_read_putlong);
tcase_add_test(tc, test_read_name_empty_loop);
tcase_add_test(tc, test_read_name_inf_loop);
tcase_add_test(tc, test_read_name_longname);
tcase_add_test(tc, test_read_name_onejump);
tcase_add_test(tc, test_read_name_badjump_start);
tcase_add_test(tc, test_read_name_badjump_second);
tcase_add_test(tc, test_putname);
tcase_add_test(tc, test_putname_nodot);
tcase_add_test(tc, test_putname_toolong);
return tc;
}

70
third-party/iodine/tests/test.c vendored Normal file
View File

@@ -0,0 +1,70 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <stdarg.h>
#include <stdlib.h>
#include <string.h>
#include "test.h"
int
main(void)
{
SRunner *runner;
Suite *iodine;
TCase *test;
int failed;
iodine = suite_create("iodine");
test = test_base32_create_tests();
suite_add_tcase(iodine, test);
test = test_base64_create_tests();
suite_add_tcase(iodine, test);
test = test_common_create_tests();
suite_add_tcase(iodine, test);
test = test_dns_create_tests();
suite_add_tcase(iodine, test);
test = test_encoding_create_tests();
suite_add_tcase(iodine, test);
test = test_read_create_tests();
suite_add_tcase(iodine, test);
test = test_login_create_tests();
suite_add_tcase(iodine, test);
test = test_user_create_tests();
suite_add_tcase(iodine, test);
test = test_fw_query_create_tests();
suite_add_tcase(iodine, test);
runner = srunner_create(iodine);
srunner_run_all(runner, CK_NORMAL);
failed = srunner_ntests_failed(runner);
srunner_free(runner);
return (failed == 0) ? EXIT_SUCCESS : EXIT_FAILURE;
}

39
third-party/iodine/tests/test.h vendored Normal file
View File

@@ -0,0 +1,39 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#ifndef __TEST_H__
#define __TEST_H__
TCase *test_base32_create_tests(void);
TCase *test_base64_create_tests(void);
TCase *test_common_create_tests(void);
TCase *test_dns_create_tests(void);
TCase *test_encoding_create_tests(void);
TCase *test_read_create_tests(void);
TCase *test_login_create_tests(void);
TCase *test_user_create_tests(void);
TCase *test_fw_query_create_tests(void);
char *va_str(const char *, ...);
#if (CHECK_MAJOR_VERSION == 0 && \
((CHECK_MINOR_VERSION == 9 && CHECK_MICRO_VERSION < 2) || \
(CHECK_MINOR_VERSION < 9)))
#define tcase_set_timeout(...)
#endif
#endif

185
third-party/iodine/tests/user.c vendored Normal file
View File

@@ -0,0 +1,185 @@
/*
* Copyright (c) 2006-2014 Erik Ekman <yarrick@kryo.se>,
* 2006-2009 Bjorn Andersson <flex@kryo.se>
*
* Permission to use, copy, modify, and/or distribute this software for any
* purpose with or without fee is hereby granted, provided that the above
* copyright notice and this permission notice appear in all copies.
*
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
*/
#include <check.h>
#include <stdio.h>
#include <string.h>
#include <time.h>
#include <sys/socket.h>
#include <netinet/in.h>
#include <arpa/inet.h>
#include "common.h"
#include "encoding.h"
#include "user.h"
#include "test.h"
START_TEST(test_init_users)
{
in_addr_t ip;
char givenip[16];
int i;
int count;
ip = inet_addr("127.0.0.1");
count = init_users(ip, 27);
for (i = 0; i < count; i++) {
ck_assert(users[i].id == i);
ck_assert(users[i].q.id == 0);
ck_assert(users[i].inpacket.len == 0);
ck_assert(users[i].outpacket.len == 0);
snprintf(givenip, sizeof(givenip), "127.0.0.%d", i + 2);
ck_assert(users[i].tun_ip == inet_addr(givenip));
}
}
END_TEST
START_TEST(test_find_user_by_ip)
{
in_addr_t ip;
unsigned int testip;
ip = inet_addr("127.0.0.1");
init_users(ip, 27);
users[0].conn = CONN_DNS_NULL;
testip = (unsigned int) inet_addr("10.0.0.1");
ck_assert(find_user_by_ip(testip) == -1);
testip = (unsigned int) inet_addr("127.0.0.2");
ck_assert(find_user_by_ip(testip) == -1);
users[0].active = 1;
testip = (unsigned int) inet_addr("127.0.0.2");
ck_assert(find_user_by_ip(testip) == -1);
users[0].last_pkt = time(NULL);
testip = (unsigned int) inet_addr("127.0.0.2");
ck_assert(find_user_by_ip(testip) == -1);
users[0].authenticated = 1;
testip = (unsigned int) inet_addr("127.0.0.2");
ck_assert(find_user_by_ip(testip) == 0);
}
END_TEST
START_TEST(test_all_users_waiting_to_send)
{
in_addr_t ip;
ip = inet_addr("127.0.0.1");
init_users(ip, 27);
ck_assert(all_users_waiting_to_send() == 1);
users[0].conn = CONN_DNS_NULL;
users[0].active = 1;
ck_assert(all_users_waiting_to_send() == 1);
users[0].last_pkt = time(NULL);
users[0].outpacket.len = 0;
ck_assert(all_users_waiting_to_send() == 0);
#ifdef OUTPACKETQ_LEN
users[0].outpacketq_filled = 1;
#else
users[0].outpacket.len = 44;
#endif
ck_assert(all_users_waiting_to_send() == 1);
}
END_TEST
START_TEST(test_find_available_user)
{
in_addr_t ip;
int i;
ip = inet_addr("127.0.0.1");
init_users(ip, 27);
for (i = 0; i < USERS; i++) {
users[i].authenticated = 1;
users[i].authenticated_raw = 1;
ck_assert(find_available_user() == i);
ck_assert(users[i].authenticated == 0);
ck_assert(users[i].authenticated_raw == 0);
}
for (i = 0; i < USERS; i++) {
ck_assert(find_available_user() == -1);
}
users[3].active = 0;
ck_assert(find_available_user() == 3);
ck_assert(find_available_user() == -1);
users[3].last_pkt = 55;
ck_assert(find_available_user() == 3);
ck_assert(find_available_user() == -1);
}
END_TEST
START_TEST(test_find_available_user_small_net)
{
in_addr_t ip;
int i;
ip = inet_addr("127.0.0.1");
init_users(ip, 29); /* this should result in 5 enabled users */
for (i = 0; i < 5; i++) {
ck_assert(find_available_user() == i);
}
for (i = 0; i < USERS; i++) {
ck_assert(find_available_user() == -1);
}
users[3].active = 0;
ck_assert(find_available_user() == 3);
ck_assert(find_available_user() == -1);
users[3].last_pkt = 55;
ck_assert(find_available_user() == 3);
ck_assert(find_available_user() == -1);
}
END_TEST
TCase *
test_user_create_tests(void)
{
TCase *tc;
tc = tcase_create("User");
tcase_add_test(tc, test_init_users);
tcase_add_test(tc, test_find_user_by_ip);
tcase_add_test(tc, test_all_users_waiting_to_send);
tcase_add_test(tc, test_find_available_user);
tcase_add_test(tc, test_find_available_user_small_net);
return tc;
}