Home | History | Annotate | Line # | Download | only in libntp
authkeys.c revision 1.1.1.8
      1 /* This file contains test for both libntp/authkeys.c and libntp/authusekey.c */
      2 
      3 #include "config.h"
      4 
      5 #include "ntp.h"
      6 #include "ntp_stdlib.h"
      7 #include "ntp_calendar.h"
      8 
      9 #include "unity.h"
     10 
     11 #ifdef OPENSSL
     12 # include "openssl/err.h"
     13 # include "openssl/rand.h"
     14 # include "openssl/evp.h"
     15 #endif
     16 #include <limits.h>
     17 
     18 u_long current_time = 4;
     19 int counter = 0;
     20 
     21 void setUp(void);
     22 void tearDown(void);
     23 void AddTrustedKey(keyid_t keyno);
     24 void AddUntrustedKey(keyid_t keyno);
     25 
     26 
     27 void
     28 setUp(void)
     29 {
     30 	if (counter == 0) {
     31 		counter++;
     32 		init_auth(); // causes segfault if called more than once
     33 	}
     34 	/*
     35 	 * init_auth() is called by tests_main.cpp earlier.  It
     36 	 * does not initialize global variables like
     37 	 * authnumkeys, so let's reset them to zero here.
     38 	 */
     39 	authnumkeys = 0;
     40 
     41 	/*
     42 	 * Especially, empty the key cache!
     43 	 */
     44 	cache_keyid = 0;
     45 	cache_type = 0;
     46 	cache_flags = 0;
     47 	cache_secret = NULL;
     48 	cache_secretsize = 0;
     49 }
     50 
     51 void
     52 tearDown(void)
     53 {
     54 	/*NOP*/
     55 }
     56 
     57 
     58 static const int KEYTYPE = KEY_TYPE_MD5;
     59 static char      msgbuf[128];
     60 
     61 void
     62 AddTrustedKey(keyid_t keyno)
     63 {
     64 	/*
     65 	 * We need to add a MD5-key in addition to setting the
     66 	 * trust, because authhavekey() requires type != 0.
     67 	 */
     68 	MD5auth_setkey(keyno, KEYTYPE, NULL, 0, NULL);
     69 
     70 	authtrust(keyno, TRUE);
     71 }
     72 
     73 void
     74 AddUntrustedKey(keyid_t keyno)
     75 {
     76 	authtrust(keyno, FALSE);
     77 }
     78 
     79 void test_AddTrustedKeys(void);
     80 void test_AddTrustedKeys(void)
     81 {
     82 	const keyid_t KEYNO1 = 5;
     83 	const keyid_t KEYNO2 = 8;
     84 
     85 	AddTrustedKey(KEYNO1);
     86 	AddTrustedKey(KEYNO2);
     87 
     88 	TEST_ASSERT_TRUE(authistrusted(KEYNO1));
     89 	TEST_ASSERT_TRUE(authistrusted(KEYNO2));
     90 }
     91 
     92 void test_AddUntrustedKey(void);
     93 void test_AddUntrustedKey(void)
     94 {
     95 	const keyid_t KEYNO = 3;
     96 
     97 	AddUntrustedKey(KEYNO);
     98 
     99 	TEST_ASSERT_FALSE(authistrusted(KEYNO));
    100 }
    101 
    102 void test_HaveKeyCorrect(void);
    103 void test_HaveKeyCorrect(void)
    104 {
    105 	const keyid_t KEYNO = 3;
    106 
    107 	AddTrustedKey(KEYNO);
    108 
    109 	TEST_ASSERT_TRUE(auth_havekey(KEYNO));
    110 	TEST_ASSERT_TRUE(authhavekey(KEYNO));
    111 }
    112 
    113 void test_HaveKeyIncorrect(void);
    114 void test_HaveKeyIncorrect(void)
    115 {
    116 	const keyid_t KEYNO = 2;
    117 
    118 	TEST_ASSERT_FALSE(auth_havekey(KEYNO));
    119 	TEST_ASSERT_FALSE(authhavekey(KEYNO));
    120 }
    121 
    122 void test_AddWithAuthUseKey(void);
    123 void test_AddWithAuthUseKey(void)
    124 {
    125 	const keyid_t KEYNO = 5;
    126 	const char* KEY = "52a";
    127 
    128 	TEST_ASSERT_TRUE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
    129 }
    130 
    131 void test_EmptyKey(void);
    132 void test_EmptyKey(void)
    133 {
    134 	const keyid_t KEYNO = 3;
    135 	const char* KEY = "";
    136 
    137 	TEST_ASSERT_FALSE(authusekey(KEYNO, KEYTYPE, (const u_char*)KEY));
    138 }
    139 
    140 /* test the implementation of 'auth_log2' -- use a local copy of the code */
    141 
    142 static u_short
    143 auth_log2(
    144 	size_t x)
    145 {
    146 	int	s;
    147 	int	r = 0;
    148 	size_t  m = ~(size_t)0;
    149 
    150 	for (s = sizeof(size_t) / 2 * CHAR_BIT; s != 0; s >>= 1) {
    151 		m <<= s;
    152 		if (x & m)
    153 			r += s;
    154 		else
    155 			x <<= s;
    156 	}
    157 	return (u_short)r;
    158 }
    159 
    160 void test_auth_log2(void);
    161 void test_auth_log2(void)
    162 {
    163 	int	l2;
    164 	size_t	tv;
    165 
    166 	TEST_ASSERT_EQUAL_INT(0, auth_log2(0));
    167 	TEST_ASSERT_EQUAL_INT(0, auth_log2(1));
    168 	for (l2 = 1; l2 < sizeof(size_t)*CHAR_BIT; ++l2) {
    169 		tv = (size_t)1 << l2;
    170 		TEST_ASSERT_EQUAL_INT(l2, auth_log2(   tv   ));
    171 		TEST_ASSERT_EQUAL_INT(l2, auth_log2( tv + 1 ));
    172 		TEST_ASSERT_EQUAL_INT(l2, auth_log2(2*tv - 1));
    173 	}
    174 }
    175 
    176 /* Converting a string to a host address. Here we use 'getaddrinfo()' in
    177  * an independent implementation to avoid cross-reactions with the
    178  * object under test. 'inet_pton' is too dangerous to handle it
    179  * properly, and ultimate performance is *not* the goal here.
    180  */
    181 static int/*BOOL*/
    182 getaddr(
    183 	int af,
    184 	const char *astr,
    185 	sockaddr_u * addr)
    186 {
    187 	struct addrinfo  hint;
    188 	struct addrinfo *ares;
    189 
    190 	memset(&hint, 0, sizeof(hint));
    191 	hint.ai_flags = AI_NUMERICHOST;
    192 	hint.ai_family = af;
    193 	if (getaddrinfo(astr, NULL, &hint, &ares))
    194 		return FALSE;
    195 	if (ares->ai_addrlen > sizeof(*addr))
    196 		memcpy(addr, ares->ai_addr, sizeof(*addr));
    197 	else
    198 		memcpy(addr, ares->ai_addr, ares->ai_addrlen);
    199 	freeaddrinfo(ares);
    200 	return TRUE;
    201 }
    202 
    203 void test_AddrMatch_anull(void);
    204 void test_AddrMatch_anull(void)
    205 {
    206 	/* Check the not-an-address logic with a prefix/check length of
    207 	 * zero bits. Any compare with a NULL or AF_UNSPEC address
    208 	 * returns inequality (aka FALSE).
    209 	 */
    210 	sockaddr_u   ip4, ip6, ipn;
    211 
    212 	memset(&ipn, 0, sizeof(ipn));
    213 	AF(&ipn) = AF_UNSPEC;
    214 
    215 	TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
    216 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1"        , &ip6));
    217 
    218 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, NULL, 0));
    219 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ipn, 0));
    220 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip4, 0));
    221 	TEST_ASSERT_FALSE(keyacc_amatch(NULL, &ip6, 0));
    222 
    223 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, NULL, 0));
    224 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ipn, 0));
    225 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip4, 0));
    226 	TEST_ASSERT_FALSE(keyacc_amatch(&ipn, &ip6, 0));
    227 
    228 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, NULL, 0));
    229 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ipn, 0));
    230 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, NULL, 0));
    231 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ipn, 0));
    232 }
    233 
    234 void test_AddrMatch_self4(void);
    235 void test_AddrMatch_self4(void)
    236 {
    237 	sockaddr_u   ip4;
    238 	unsigned int bits;
    239 
    240 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.1.1", &ip4));
    241 	for (bits = 0; bits < 40; ++bits)
    242 		TEST_ASSERT_TRUE(keyacc_amatch(&ip4, &ip4, bits));
    243 }
    244 
    245 void test_AddrMatch_self6(void);
    246 void test_AddrMatch_self6(void)
    247 {
    248 	sockaddr_u   ip6;
    249 	unsigned int bits;
    250 
    251 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1" , &ip6));
    252 	for (bits = 0; bits < 136; ++bits)
    253 		TEST_ASSERT_TRUE(keyacc_amatch(&ip6, &ip6, bits));
    254 }
    255 
    256 void test_AddrMatch_afmix(void);
    257 void test_AddrMatch_afmix(void)
    258 {
    259 	sockaddr_u ip6, ip4;
    260 
    261 	TEST_ASSERT_TRUE(getaddr(AF_INET , "192.128.1.1", &ip4));
    262 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "::1"        , &ip6));
    263 
    264 	TEST_ASSERT_FALSE(keyacc_amatch(&ip4, &ip6, 0));
    265 	TEST_ASSERT_FALSE(keyacc_amatch(&ip6, &ip4, 0));
    266 }
    267 
    268 void test_AddrMatch_ipv4(void);
    269 void test_AddrMatch_ipv4(void)
    270 {
    271 	sockaddr_u   a1, a2;
    272 	unsigned int bits;
    273 	int          want;
    274 
    275 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.1", &a1));
    276 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.3.1", &a2));
    277 
    278 	/* the first 23 bits are equal, so any prefix <= 23 should match */
    279 	for (bits = 0; bits < 40; ++bits) {
    280 		snprintf(msgbuf, sizeof(msgbuf),
    281 			 "keyacc_amatch(*,*,%u) wrong", bits);
    282 		want = (bits <= 23);
    283 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
    284 	}
    285 
    286 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.127", &a1));
    287 	TEST_ASSERT_TRUE(getaddr(AF_INET, "192.128.2.128", &a2));
    288 
    289 	/* the first 24 bits are equal, so any prefix <= 24 should match */
    290 	for (bits = 0; bits < 40; ++bits) {
    291 		snprintf(msgbuf, sizeof(msgbuf),
    292 			 "keyacc_amatch(*,*,%u) wrong", bits);
    293 		want = (bits <= 24);
    294 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
    295 	}
    296 }
    297 
    298 void test_AddrMatch_ipv6(void);
    299 void test_AddrMatch_ipv6(void)
    300 {
    301 	sockaddr_u   a1, a2;
    302 	unsigned int bits;
    303 	int          want;
    304 
    305 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:FFFF", &a1));
    306 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::3:FFFF", &a2));
    307 
    308 	/* the first 111 bits are equal, so any prefix <= 111 should match */
    309 	for (bits = 0; bits < 136; ++bits) {
    310 		snprintf(msgbuf, sizeof(msgbuf),
    311 			 "keyacc_amatch(*,*,%u) wrong", bits);
    312 		want = (bits <= 111);
    313 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
    314 	}
    315 
    316 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:7FFF", &a1));
    317 	TEST_ASSERT_TRUE(getaddr(AF_INET6, "FEDC:BA98:7654:3210::2:8000", &a2));
    318 
    319 	/* the first 112 bits are equal, so any prefix <= 112 should match */
    320 	for (bits = 0; bits < 136; ++bits) {
    321 		snprintf(msgbuf, sizeof(msgbuf),
    322 			 "keyacc_amatch(*,*,%u) wrong", bits);
    323 		want = (bits <= 112);
    324 		TEST_ASSERT_EQUAL_MESSAGE(want, keyacc_amatch(&a1, &a2, bits), msgbuf);
    325 	}
    326 }
    327