📄 aaasimul.c
字号:
/* $Id: aaasimul.c,v 1.13 2001/10/20 17:39:14 jm Exp $ * Test AAA infrastructure simulator * * Dynamic hierarchial IP tunnel * Copyright (C) 2001, Jouni Malinen * * This program is free software; you can redistribute it and/or modify * it under the terms of the GNU General Public License version 2 as * published by the Free Software Foundation. See README and COPYING for * more details. */#include <stdlib.h>#include <stdio.h>#include <string.h>#include <assert.h>#include <sys/time.h>#include <sys/types.h>#include <unistd.h>#include <sys/socket.h>#include <netinet/in.h>#include <arpa/inet.h>#include "message.h"#include "agentadv.h"#include "debug.h"#include "agent_utils.h"#include "msgparser.h"#include "auth.h"#include "util.h"#include "dyn_ip.h"/* Test setup: * 192.168.1.1 FA (and simulated HA & AAA infrastructure running this program) * 192.168.1.2 MN (running dynmnd) */#define CHALLENGE_LEN 4#define MAXSHAREDSECRETLEN 32#define KEYMAT_LEN 8/* #define USE_STATIC_MN_HA_KEY_MATERIAL *//* * AUTH_ALG_{MD5=MD5_PREFIX_SUFFIX,RADIUS,HMAC_MD5,SHA1,HMAC_SHA1} * AAA_KEY_ALG_{MD5,HMAC_MD5,SHA1} */#define MN_HA_KEYGEN_ALG AUTH_ALG_HMAC_MD5#define MN_HA_AUTH_ALG_AAA AAA_KEY_ALG_HMAC_MD5#define MN_HA_AUTH_ALG AUTH_ALG_HMAC_MD5#define MN_FA_KEYGEN_ALG AUTH_ALG_HMAC_MD5#define MN_FA_AUTH_ALG_AAA AAA_KEY_ALG_SHA1#define MN_FA_AUTH_ALG AUTH_ALG_SHA1#define MN_AAA_AUTH_ALG AUTH_ALG_SHA1#define MN_AAA_SECRET "aaa-test"#define MN_AAA_SECRET_LEN 8#define MN_HA_LIFETIME 120#define MN_FA_LIFETIME 120#define AGENTADV_LIFETIME 600#define AGENTADV_INTERVAL 60static void send_agent_adv(int sock){ struct in_addr addr; struct challenge_ext *challenge; unsigned char *pos; int i; challenge = (struct challenge_ext *) malloc(sizeof(struct challenge_ext) + CHALLENGE_LEN); assert(challenge != NULL); challenge->type = AGENT_ADV_CHALLENGE_EXT; challenge->length = CHALLENGE_LEN; pos = (unsigned char *) MSG_CHALLENGE_EXT_DATA(challenge); for (i = 0; i < CHALLENGE_LEN; i++) pos[i] = random() % 256; inet_aton("192.168.1.1", &addr); set_agent_adv_data(600, addr, addr, AGENT_ADV_FOREIGN_AGENT | AGENT_ADV_REGISTRATION_REQUIRED | AGENT_ADV_BIDIR_TUNNELING, 0, AGENTADV_LIFETIME, NULL, 0); set_agent_adv_nai(NULL); set_agent_adv_challenge(challenge); inet_aton("192.168.1.2", &addr); send_agent_advertisement(sock, NULL, &addr, dyn_ip_get_ifindex("eth0")); free(challenge); set_agent_adv_challenge(NULL);}extern int opt_debug;#define BUFSIZE 8192void reply_msg(int s, struct sockaddr_in *from, struct msg_extensions *ext){ unsigned char buf[BUFSIZE]; unsigned char *pos, *tmp; struct reg_rep *rep; struct msg_extensions tmpext; int res; __u32 spi; unsigned char *nodeaddr; unsigned int nodeaddrlen; static unsigned char ha_secret[MAXSHAREDSECRETLEN]; static int ha_secret_len = -1; static unsigned char fa_secret[MAXSHAREDSECRETLEN]; static int fa_secret_len = -1; int i; struct challenge_ext *challenge; static int sync_timestamp = 0; /* 1; */ static int reply_count = 0; int test_mn_failed_auth_fa = 0; int test_broken_fa_auth = 0; static int next_fa_spi = 100000; reply_count++;#if 0 if (reply_count == 2) test_mn_failed_auth_fa = 1; if (reply_count == 2) test_broken_fa_auth = 1;#endif /* Check authentication extensions */ if (ext->mn_aaa_auth != NULL && auth_check_gen(MN_AAA_AUTH_ALG, MN_AAA_SECRET, MN_AAA_SECRET_LEN, ext->start, ext->mn_aaa_auth) == 0) { printf("ERROR: incorrect MN-AAA auth ext\n"); } if (ext->mh_auth != NULL && ha_secret_len > 0 && auth_check(MN_HA_AUTH_ALG, ha_secret, ha_secret_len, ext->start, ext->mh_auth) == 0) { printf("ERROR: incorrect MN-HA auth ext\n"); } if (ext->mf_auth != NULL && fa_secret_len > 0 && auth_check(MN_FA_AUTH_ALG, fa_secret, fa_secret_len, ext->start, ext->mf_auth) == 0) { printf("ERROR: incorrect MN-FA auth ext\n"); } /* Generate and send the reply */ if (ext->mn_ha_key_req_aaa != NULL) spi = ext->mn_ha_key_req_aaa->mn_spi; else spi = htonl(10000); pos = buf; rep = (struct reg_rep *) pos; rep->type = REG_REP; rep->code = REGREP_ACCEPTED; rep->lifetime = ext->req->lifetime; rep->home_addr = ext->req->home_addr; if (rep->home_addr.s_addr == 0) inet_aton("192.168.1.123", &rep->home_addr); inet_aton("192.168.1.100", &rep->ha_addr); rep->id[0] = ext->req->id[0]; rep->id[1] = ext->req->id[1]; if (sync_timestamp) { printf("Synchronizing timestamps..\n"); sync_timestamp = 0; rep->code = REGREP_ID_MISMATCH_HA; rep->id[0] = htonl(time(NULL) + UNIX_NTP_DIFF); } else if (test_mn_failed_auth_fa) { printf("Testing MN failed auth denial from FA\n"); rep->code = REGREP_MN_FAILED_AUTH_FA; } pos += sizeof(struct reg_rep); if (ext->mn_nai != NULL) { memcpy(pos, ext->mn_nai, GET_MN_NAI_EXT_LEN(ext->mn_nai)); pos += GET_MN_NAI_EXT_LEN(ext->mn_nai); } if (ext->mn_nai != NULL && ext->req->home_addr.s_addr == 0) { nodeaddr = MSG_MN_NAI_DATA(ext->mn_nai); nodeaddrlen = GET_MN_NAI_LEN(ext->mn_nai); } else { nodeaddr = (unsigned char *) &ext->req->home_addr; nodeaddrlen = 4; } if (!test_mn_failed_auth_fa && ext->mn_ha_key_req_aaa != NULL) { struct generalized_mn_ha_key_rep_ext *key = (struct generalized_mn_ha_key_rep_ext *) pos; struct mn_ha_key_material_from_aaa *keymat; unsigned char *tmp; key->type = GENERALIZED_MN_HA_KEY_REP_EXT; key->subtype = GEN_MN_HA_KEY_REP_KEY_MATERIAL_FROM_AAA; key->length = htons(4 + sizeof(*keymat) + KEYMAT_LEN); key->lifetime = htonl(MN_HA_LIFETIME); keymat = (struct mn_ha_key_material_from_aaa *) MSG_GEN_MN_HA_KEY_REP_DATA(key); keymat->aaa_spi = htonl(12345); keymat->ha_spi = htonl(12346); keymat->alg_id = htons(MN_HA_AUTH_ALG_AAA); keymat->replay_method = htons(AAA_KEY_REPLAY_TIMESTAMPS); tmp = (unsigned char *) (keymat + 1);#ifdef USE_STATIC_MN_HA_KEY_MATERIAL for (i = 0; i < KEYMAT_LEN; i++) *tmp++ = i;#else for (i = 0; i < KEYMAT_LEN; i++) *tmp++ = random() & 0xff;#endif pos += GET_GEN_MN_HA_KEY_REP_EXT_LEN(key); /* generate MN-HA key from key material */ ha_secret_len = MAXSHAREDSECRETLEN; printf("auth_generate_key: alg=%i, secret=aaa-test, " "keymat_len=%i, nodeaddrlen=%i\n", MN_HA_KEYGEN_ALG, KEYMAT_LEN, nodeaddrlen); if (auth_generate_key( MN_HA_KEYGEN_ALG, MN_AAA_SECRET, MN_AAA_SECRET_LEN, (unsigned char *) (keymat + 1), KEYMAT_LEN, nodeaddr, nodeaddrlen, ha_secret, &ha_secret_len)) { printf("MN-HA key generation failed\n"); return; } } if (!test_mn_failed_auth_fa && ha_secret_len >= 0) { printf("Adding MN-HA auth ext: alg=%i ha_secret=", MN_HA_AUTH_ALG); for (i = 0; i < ha_secret_len; i++) printf("%02x", ha_secret[i]); printf(" ha_secret_len=%i\n", ha_secret_len); pos += auth_add(MN_HA_AUTH_ALG, ha_secret, ha_secret_len, buf, (struct msg_auth *) pos, MH_AUTH, spi); } if (!test_mn_failed_auth_fa && ext->mn_fa_key_req_aaa != NULL) { struct generalized_mn_fa_key_rep_ext *key = (struct generalized_mn_fa_key_rep_ext *) pos; struct mn_fa_key_material_from_aaa *keymat; key->type = GENERALIZED_MN_FA_KEY_REP_EXT; key->subtype = GEN_MN_FA_KEY_REP_KEY_MATERIAL_FROM_AAA; key->length = htons(sizeof(*keymat) + KEYMAT_LEN); keymat = (struct mn_fa_key_material_from_aaa *) MSG_GEN_MN_FA_KEY_REP_DATA(key); keymat->lifetime = htonl(MN_FA_LIFETIME); keymat->aaa_spi = htonl(12345); keymat->fa_spi = htonl(next_fa_spi++); keymat->alg_id = htons(MN_FA_AUTH_ALG_AAA); tmp = (unsigned char *) (keymat + 1); for (i = 0; i < KEYMAT_LEN; i++) *tmp++ = random() & 0xff; pos += GET_GEN_MN_FA_KEY_REP_EXT_LEN(key); /* generate MN-FA key from key material */ fa_secret_len = MAXSHAREDSECRETLEN; printf("auth_generate_key: alg=%i, secret=aaa-test, " "keymat_len=%i, nodeaddrlen=%i\n", MN_FA_KEYGEN_ALG, KEYMAT_LEN, nodeaddrlen); if (auth_generate_key( MN_FA_KEYGEN_ALG, MN_AAA_SECRET, MN_AAA_SECRET_LEN, (unsigned char *) (keymat + 1), KEYMAT_LEN, nodeaddr, nodeaddrlen, fa_secret, &fa_secret_len)) { printf("MN-FA key generation failed\n"); return; } } challenge = (struct challenge_ext *) pos; challenge->type = MN_FA_CHALLENGE_EXT; challenge->length = CHALLENGE_LEN; tmp = (unsigned char *) MSG_CHALLENGE_EXT_DATA(challenge); for (i = 0; i < CHALLENGE_LEN; i++) tmp[i] = random() % 256; pos += GET_CHALLENGE_EXT_LEN(challenge); if ((!test_mn_failed_auth_fa || test_broken_fa_auth) && fa_secret_len >= 0) { printf("Adding MN-FA auth ext: alg=%i fa_secret=", MN_FA_AUTH_ALG); for (i = 0; i < fa_secret_len; i++) printf("%02x", fa_secret[i]); printf(" fa_secret_len=%i\n", fa_secret_len); pos += auth_add(MN_FA_AUTH_ALG, fa_secret, fa_secret_len, buf, (struct msg_auth *) pos, MF_AUTH, spi); if (test_broken_fa_auth) { printf("Testing broken MN-FA auth ext\n"); (*(pos - 1))++; fa_secret[0]++; } } printf("Sending following simulated registration reply:\n"); res = parse_msg(buf, pos - buf, &tmpext); if (res != 0) printf("msg_parse returned %i\n", res); /* send */ res = sendto(s, buf, pos - buf, 0, (struct sockaddr *) from, sizeof(*from)); if (res < 0) perror("sendto");}int main(int argc, char *argv[]){ int udp_sock; struct in_addr any; char buf[BUFSIZE]; time_t last_adv, now; static int delay_reply = 0; int icmp_sock; opt_debug = 1; any.s_addr = INADDR_ANY; udp_sock = dynamics_open_udp_socket(-1, any, 434, "eth0"); assert(udp_sock >= 0); icmp_sock = open_agent_icmp_adv_socket("eth0", AGENTADV_FILTER_SOL); assert(icmp_sock >= 0); send_agent_adv(icmp_sock); time(&last_adv); for (;;) { int len, res, left; struct msg_extensions ext; fd_set rfds; struct timeval tv; struct sockaddr_in from; socklen_t fromlen = sizeof(from); FD_ZERO(&rfds); FD_SET(udp_sock, &rfds); FD_SET(icmp_sock, &rfds); tv.tv_sec = 5; tv.tv_usec = 0; time(&now); left = last_adv + AGENTADV_INTERVAL - now; if (left < tv.tv_sec) tv.tv_sec = left < 0 ? 0 : left; res = select(FD_SETSIZE, &rfds, NULL, NULL, &tv); if (res < 0) { perror("select"); exit(1); } time(&now); if (now > last_adv + AGENTADV_INTERVAL) { send_agent_adv(icmp_sock); last_adv = now; } if (FD_ISSET(icmp_sock, &rfds)) { int r; struct sockaddr_ll from; struct in_addr to, fromaddr; r = check_icmp_sol(icmp_sock, &from, &to, &fromaddr); if (r == 0) send_agent_adv(icmp_sock); } if (!FD_ISSET(udp_sock, &rfds)) continue; len = recvfrom(udp_sock, buf, BUFSIZE, 0, (struct sockaddr *) &from, &fromlen); assert(len >= 0); printf("Received UDP message from %s:%i\n", inet_ntoa(from.sin_addr), ntohs(from.sin_port)); res = parse_msg(buf, len, &ext); if (res == 0 && ext.req != NULL) { if (delay_reply > 0) { printf("Delaying reply..\n"); sleep(10); delay_reply--; } reply_msg(udp_sock, &from, &ext); } } close(icmp_sock); close(udp_sock); return 0;}
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -