int generate_pkt ( struct pkt *x_pkt, const struct timeval *tv_xmt, int key_id, struct key *pkt_key ) { l_fp xmt; int pkt_len = LEN_PKT_NOMAC; memset(x_pkt, 0, sizeof(struct pkt)); TVTOTS(tv_xmt, &xmt); HTONL_FP(&xmt, &(x_pkt->xmt)); x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); x_pkt->ppoll = 8; /* FIXME! Modus broadcast + adr. check -> bdr. pkt */ set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, 4, 3); if (pkt_key != NULL) { int mac_size = 20; /* max room for MAC */ x_pkt->exten[0] = htonl(key_id); mac_size = make_mac((char *)x_pkt, pkt_len, mac_size, pkt_key, (char *)&x_pkt->exten[1]); if (mac_size) pkt_len += mac_size + 4; } return pkt_len; }
void test_MakeSHA1Mac(void) { #ifdef OPENSSL const char* PKT_DATA = "abcdefgh0123"; const int PKT_LEN = strlen(PKT_DATA); const char* EXPECTED_DIGEST = "\x17\xaa\x82\x97\xc7\x17\x13\x6a\x9b\xa9" "\x63\x85\xb4\xce\xbe\x94\xa0\x97\x16\x1d"; char actual[SHA1_LENGTH]; struct key sha1; sha1.next = NULL; sha1.key_id = 20; sha1.key_len = 7; memcpy(&sha1.key_seq, "sha1seq", sha1.key_len); memcpy(&sha1.type, "SHA1", 5); TEST_ASSERT_EQUAL(SHA1_LENGTH, make_mac(PKT_DATA, PKT_LEN, SHA1_LENGTH, &sha1, actual)); TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, SHA1_LENGTH); #else TEST_IGNORE_MESSAGE("OpenSSL not found, skipping..."); #endif /* OPENSSL */ }
void test_MakeCMac(void) { #ifdef OPENSSL const char* PKT_DATA = "abcdefgh0123"; const int PKT_LEN = strlen(PKT_DATA); const char* EXPECTED_DIGEST = "\xdd\x35\xd5\xf5\x14\x23\xd9\xd6" "\x38\x5d\x29\x80\xfe\x51\xb9\x6b"; char actual[CMAC_LENGTH]; struct key cmac; cmac.next = NULL; cmac.key_id = 30; cmac.key_len = CMAC_LENGTH; memcpy(&cmac.key_seq, "aes-128-cmac-seq", cmac.key_len); memcpy(&cmac.typen, CMAC, strlen(CMAC) + 1); TEST_ASSERT_EQUAL(CMAC_LENGTH, make_mac(PKT_DATA, PKT_LEN, CMAC_LENGTH, &cmac, actual)); TEST_ASSERT_EQUAL_MEMORY(EXPECTED_DIGEST, actual, CMAC_LENGTH); #else TEST_IGNORE_MESSAGE("OpenSSL not found, skipping..."); #endif /* OPENSSL */ }
void test_PacketSizeNotMultipleOfFourBytes(void) { const char* PKT_DATA = "123456"; const int PKT_LEN = 6; char actual[MD5_LENGTH]; struct key md5; md5.next = NULL; md5.key_id = 10; md5.key_len = 6; memcpy(&md5.key_seq, "md5seq", md5.key_len); memcpy(&md5.type, "MD5", 4); TEST_ASSERT_EQUAL(0, make_mac((char*)PKT_DATA, PKT_LEN, MD5_LENGTH, &md5, actual)); }
void test_CorrectAuthenticatedPacketSHA1(void) { PrepareAuthenticationTest(20, 15, "SHA1", "abcdefghijklmno"); TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); int pkt_len = LEN_PKT_NOMAC; // Prepare the packet. testpkt.exten[0] = htonl(20); int mac_len = make_mac((char*)&testpkt, pkt_len, MAX_MAC_LEN, key_ptr, (char*)&testpkt.exten[1]); pkt_len += 4 + mac_len; TEST_ASSERT_EQUAL(pkt_len, process_pkt(&testpkt, &testsock, pkt_len, MODE_SERVER, &testspkt, "UnitTest")); }
void test_AuthenticatedPacketUnknownKey(void) { // Activate authentication option PrepareAuthenticationTestMD5(30, 9, "123456789"); TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); // Prepare the packet. Observe that the Key-ID expected is 30, // but the packet has a key id of 50. int pkt_len = LEN_PKT_NOMAC; testpkt.exten[0] = htonl(50); int mac_len = make_mac((char*)&testpkt, pkt_len, MAX_MD5_LEN, key_ptr, (char*)&testpkt.exten[1]); pkt_len += 4 + mac_len; TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, process_pkt(&testpkt, &testsock, pkt_len, MODE_SERVER, &testspkt, "UnitTest")); }
void test_MakeMd5Mac(void) { const char* PKT_DATA = "abcdefgh0123"; const int PKT_LEN = strlen(PKT_DATA); const char* EXPECTED_DIGEST = "\x52\x6c\xb8\x38\xaf\x06\x5a\xfb\x6c\x98\xbb\xc0\x9b\x0a\x7a\x1b"; char actual[MD5_LENGTH]; struct key md5; md5.next = NULL; md5.key_id = 10; md5.key_len = 6; memcpy(&md5.key_seq, "md5seq", md5.key_len); memcpy(&md5.type, "MD5", 4); TEST_ASSERT_EQUAL(MD5_LENGTH, make_mac((char*)PKT_DATA, PKT_LEN, MD5_LENGTH, &md5, actual)); TEST_ASSERT_TRUE(memcmp(EXPECTED_DIGEST, actual, MD5_LENGTH) == 0); }
void test_CorrectAuthenticatedPacketMD5(void) { PrepareAuthenticationTestMD5(10, 15, "123456789abcdef"); TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); int pkt_len = LEN_PKT_NOMAC; /* Prepare the packet. */ testpkt.exten[0] = htonl(10); int mac_len = make_mac(&testpkt, pkt_len, MAX_MD5_LEN, key_ptr, &testpkt.exten[1]); pkt_len += 4 + mac_len; TEST_ASSERT_EQUAL(pkt_len, process_pkt(&testpkt, &testsock, pkt_len, MODE_SERVER, &testspkt, "UnitTest")); }
void test_GenerateAuthenticatedPacket(void) { static const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_MD5_LEN; struct key testkey; struct pkt testpkt; struct timeval xmt; l_fp expected_xmt, actual_xmt; char expected_mac[MAX_MD5_LEN]; testkey.next = NULL; testkey.key_id = 30; testkey.key_len = 9; memcpy(testkey.key_seq, "123456789", testkey.key_len); strlcpy(testkey.typen, "MD5", sizeof(testkey.typen)); testkey.typei = keytype_from_text(testkey.typen, NULL); GETTIMEOFDAY(&xmt, NULL); xmt.tv_sec += JAN_1970; TEST_ASSERT_EQUAL(EXPECTED_PKTLEN, generate_pkt(&testpkt, &xmt, testkey.key_id, &testkey)); TEST_ASSERT_EQUAL(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode)); TEST_ASSERT_EQUAL(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode)); TEST_ASSERT_EQUAL(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode)); TEST_ASSERT_EQUAL(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum)); TEST_ASSERT_EQUAL(8, testpkt.ppoll); TVTOTS(&xmt, &expected_xmt); NTOHL_FP(&testpkt.xmt, &actual_xmt); TEST_ASSERT_TRUE(LfpEquality(expected_xmt, actual_xmt)); TEST_ASSERT_EQUAL(testkey.key_id, ntohl(testpkt.exten[0])); TEST_ASSERT_EQUAL(MAX_MD5_LEN - 4, /* Remove the key_id, only keep the mac. */ make_mac(&testpkt, LEN_PKT_NOMAC, MAX_MD5_LEN-4, &testkey, expected_mac)); TEST_ASSERT_EQUAL_MEMORY(expected_mac, (char*)&testpkt.exten[1], MAX_MD5_LEN -4); }
void test_AuthenticatedPacketInvalid(void) { // Activate authentication option PrepareAuthenticationTestMD5(50, 9, "123456789"); TEST_ASSERT_TRUE(ENABLED_OPT(AUTHENTICATION)); // Prepare the packet. int pkt_len = LEN_PKT_NOMAC; testpkt.exten[0] = htonl(50); int mac_len = make_mac((char*)&testpkt, pkt_len, MAX_MD5_LEN, key_ptr, (char*)&testpkt.exten[1]); pkt_len += 4 + mac_len; // Now, alter the MAC so it becomes invalid. testpkt.exten[1] += 1; TEST_ASSERT_EQUAL(SERVER_AUTH_FAIL, process_pkt(&testpkt, &testsock, pkt_len, MODE_SERVER, &testspkt, "UnitTest")); }
int generate_pkt ( struct pkt *x_pkt, const struct timeval *tv_xmt, int key_id, struct key *pkt_key ) { l_fp xmt_fp; int pkt_len; int mac_size; pkt_len = LEN_PKT_NOMAC; ZERO(*x_pkt); TVTOTS(tv_xmt, &xmt_fp); HTONL_FP(&xmt_fp, &x_pkt->xmt); x_pkt->stratum = STRATUM_TO_PKT(STRATUM_UNSPEC); x_pkt->ppoll = 8; /* FIXME! Modus broadcast + adr. check -> bdr. pkt */ set_li_vn_mode(x_pkt, LEAP_NOTINSYNC, ntpver, 3); if (debug > 0) { printf("generate_pkt: key_id %d, key pointer %p\n", key_id, pkt_key); } if (pkt_key != NULL) { x_pkt->exten[0] = htonl(key_id); mac_size = make_mac(x_pkt, pkt_len, MAX_MDG_LEN, pkt_key, (char *)&x_pkt->exten[1]); if (mac_size > 0) pkt_len += mac_size + KEY_MAC_LEN; #ifdef DEBUG if (debug > 0) { printf("generate_pkt: mac_size is %d\n", mac_size); } #endif } return pkt_len; }
TEST_F(mainTest, GenerateAuthenticatedPacket) { key testkey; testkey.next = NULL; testkey.key_id = 30; testkey.key_len = 9; memcpy(testkey.key_seq, "123456789", testkey.key_len); memcpy(testkey.type, "MD5", 3); pkt testpkt; timeval xmt; GETTIMEOFDAY(&xmt, NULL); xmt.tv_sec += JAN_1970; const int EXPECTED_PKTLEN = LEN_PKT_NOMAC + MAX_MD5_LEN; EXPECT_EQ(EXPECTED_PKTLEN, generate_pkt(&testpkt, &xmt, testkey.key_id, &testkey)); EXPECT_EQ(LEAP_NOTINSYNC, PKT_LEAP(testpkt.li_vn_mode)); EXPECT_EQ(NTP_VERSION, PKT_VERSION(testpkt.li_vn_mode)); EXPECT_EQ(MODE_CLIENT, PKT_MODE(testpkt.li_vn_mode)); EXPECT_EQ(STRATUM_UNSPEC, PKT_TO_STRATUM(testpkt.stratum)); EXPECT_EQ(8, testpkt.ppoll); l_fp expected_xmt, actual_xmt; TVTOTS(&xmt, &expected_xmt); NTOHL_FP(&testpkt.xmt, &actual_xmt); EXPECT_TRUE(LfpEquality(expected_xmt, actual_xmt)); EXPECT_EQ(testkey.key_id, ntohl(testpkt.exten[0])); char expected_mac[MAX_MD5_LEN]; ASSERT_EQ(MAX_MD5_LEN - 4, // Remove the key_id, only keep the mac. make_mac((char*)&testpkt, LEN_PKT_NOMAC, MAX_MD5_LEN, &testkey, expected_mac)); EXPECT_TRUE(memcmp(expected_mac, (char*)&testpkt.exten[1], MAX_MD5_LEN -4) == 0); }
int main(int argc, char **argv) { int result, index; char *bptr, *tptr; char *app; int i, j, c; struct getap_state *gs; index = 0; app = argv[0]; i = j = 1; tptr = "tgtap%d"; bptr = "/proc/%d/hw/ioreg/ten_Gbe_v2"; gs = malloc(sizeof(struct getap_state)); if(gs == NULL){ fprintf(stderr, "%s: unable to allocate %d bytes\n", app, sizeof(struct getap_state)); return EX_USAGE; } gs->s_address_name[0] = '\0'; gs->s_gateway_name[0] = '\0'; gs->s_mac_name[0] = '\0'; gs->s_port = 0; gs->s_verbose = 1; gs->s_testing = 0; while (i < argc) { if (argv[i][0] == '-') { c = argv[i][j]; switch (c) { case 'h' : usage(app); return EX_OK; case 'v' : gs->s_verbose++; j++; break; case 'T' : gs->s_testing++; j++; break; case 'a' : case 'g' : case 'm' : case 'p' : case 'n' : case 't' : case 'b' : j++; if (argv[i][j] == '\0') { j = 0; i++; } if (i >= argc) { fprintf(stderr, "%s: -%c needs a parameter\n", app, c); return EX_USAGE; } switch(c){ case 'a' : strncpy(gs->s_address_name, argv[i] + j, IP_BUFFER - 1); gs->s_address_name[IP_BUFFER - 1] = '\0'; break; case 'g' : strncpy(gs->s_gateway_name, argv[i] + j, IP_BUFFER - 1); gs->s_gateway_name[IP_BUFFER - 1] = '\0'; break; case 'm' : strncpy(gs->s_mac_name, argv[i] + j, MAC_BUFFER - 1); gs->s_mac_name[MAC_BUFFER - 1] = '\0'; case 'p' : gs->s_port = atoi(argv[i] + j); break; case 'n' : index = atoi(argv[i] + j); break; case 't' : tptr = NULL; strncpy(gs->s_tap_name, argv[i] + j, NAME_BUFFER - 1); gs->s_tap_name[NAME_BUFFER - 1] = '\0'; break; case 'b' : bptr = NULL; strncpy(gs->s_borph_name, argv[i] + j, NAME_BUFFER - 1); gs->s_borph_name[NAME_BUFFER - 1] = '\0'; break; } i++; j = 1; break; case '\0': j = 1; i++; break; default: fprintf(stderr, "%s: unknown option -%c\n", app, argv[i][j]); return EX_USAGE; } } else { fprintf(stderr, "%s: bad argument %s\n", app, argv[i]); return EX_USAGE; } } if(tptr){ result = snprintf(gs->s_tap_name, NAME_BUFFER - 1, tptr, index); if((result < 0) || (result >= NAME_BUFFER)){ fprintf(stderr, "unable to expand %s: Value too long\n", tptr); return EX_USAGE; } } if(bptr){ result = snprintf(gs->s_borph_name, NAME_BUFFER - 1, bptr, getpid()); if((result < 0) || (result >= NAME_BUFFER)){ fprintf(stderr, "unable to expand %s: Value too long\n", bptr); return EX_USAGE; } } if(gs->s_address_name[0] == '\0'){ fprintf(stderr, "%s: need an ip address\n", app); return EX_OSERR; } if(gs->s_gateway_name[0] == '\0'){ /* risky, gateware may not like it */ strncpy(gs->s_gateway_name, gs->s_address_name, IP_BUFFER); } if(gs->s_mac_name[0] == '\0'){ make_mac(gs); } if(gs->s_verbose){ printf("%s: tap interface name: %s\n", app, gs->s_tap_name); printf("%s: borph file: %s\n", app, gs->s_borph_name); printf("%s: %s file interface \n", app, gs->s_testing ? "testing" : "borph"); printf("%s: ip address %s\n", app, gs->s_address_name); printf("%s: mac address %s\n", app, gs->s_mac_name); } gs->s_tfd = tap_open(gs->s_tap_name); if(gs->s_tfd < 0){ fprintf(stderr, "%s: unable to set up tap device %s: %s\n", app, gs->s_tap_name, strerror(errno)); return EX_OSERR; } if(setup_borph(gs) < 0){ fprintf(stderr, "%s: unable to initialise borph register file %s: %s\n", app, gs->s_borph_name, strerror(errno)); return EX_OSERR; } if(setup_tap(gs)){ fprintf(stderr, "%s: unable to configure tap device %s\n", app, gs->s_tap_name); return EX_OSERR; } printf("%s: my arp table index %d\n", app, gs->s_index); if(gs->s_verbose){ printf("%s: my network: 0x%08x\n", app, gs->s_network_binary); } run = 1; /* signal stuff */ mainloop(gs); tap_close(gs->s_tfd); close(gs->s_bfd); return EX_OK; }