/* * this code runs the EAP-SIM client state machine. * the *request* is from the server. * the *reponse* is to the server. * */ static int respond_eap_sim(RADIUS_PACKET *req, RADIUS_PACKET *resp) { enum eapsim_clientstates state, newstate; enum eapsim_subtype subtype; VALUE_PAIR *vp, *statevp, *radstate, *eapid; char statenamebuf[32], subtypenamebuf[32]; if ((radstate = paircopy2(NULL, req->vps, PW_STATE, 0, TAG_ANY)) == NULL) { return 0; } if ((eapid = paircopy2(NULL, req->vps, ATTRIBUTE_EAP_ID, 0, TAG_ANY)) == NULL) { return 0; } /* first, dig up the state from the request packet, setting * outselves to be in EAP-SIM-Start state if there is none. */ if((statevp = pairfind(resp->vps, ATTRIBUTE_EAP_SIM_STATE, 0, TAG_ANY)) == NULL) { /* must be initial request */ statevp = paircreate(resp, ATTRIBUTE_EAP_SIM_STATE, 0); statevp->vp_integer = eapsim_client_init; pairreplace(&(resp->vps), statevp); } state = statevp->vp_integer; /* * map the attributes, and authenticate them. */ unmap_eapsim_types(req); if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_SUBTYPE, 0, TAG_ANY)) == NULL) { return 0; } subtype = vp->vp_integer; /* * look for the appropriate state, and process incoming message */ switch(state) { case eapsim_client_init: switch(subtype) { case eapsim_start: newstate = process_eap_start(req, resp); break; case eapsim_challenge: case eapsim_notification: case eapsim_reauth: default: fprintf(stderr, "radeapclient: sim in state %s message %s is illegal. Reply dropped.\n", sim_state2name(state, statenamebuf, sizeof(statenamebuf)), sim_subtype2name(subtype, subtypenamebuf, sizeof(subtypenamebuf))); /* invalid state, drop message */ return 0; } break; case eapsim_client_start: switch(subtype) { case eapsim_start: /* NOT SURE ABOUT THIS ONE, retransmit, I guess */ newstate = process_eap_start(req, resp); break; case eapsim_challenge: newstate = process_eap_challenge(req, resp); break; default: fprintf(stderr, "radeapclient: sim in state %s message %s is illegal. Reply dropped.\n", sim_state2name(state, statenamebuf, sizeof(statenamebuf)), sim_subtype2name(subtype, subtypenamebuf, sizeof(subtypenamebuf))); /* invalid state, drop message */ return 0; } break; default: fprintf(stderr, "radeapclient: sim in illegal state %s\n", sim_state2name(state, statenamebuf, sizeof(statenamebuf))); return 0; } /* copy the eap state object in */ pairreplace(&(resp->vps), eapid); /* update stete info, and send new packet */ map_eapsim_types(resp); /* copy the radius state object in */ pairreplace(&(resp->vps), radstate); statevp->vp_integer = newstate; return 1; }
main(int argc, char *argv[]) { int filedone; RADIUS_PACKET *req,*req2; VALUE_PAIR *vp, *vpkey, *vpextra; extern unsigned int sha1_data_problems; req = NULL; req2 = NULL; filedone = 0; if(argc>1) { sha1_data_problems = 1; } if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) { librad_perror("radclient"); return 1; } if ((req = rad_alloc(1)) == NULL) { librad_perror("radclient"); exit(1); } if ((req2 = rad_alloc(1)) == NULL) { librad_perror("radclient"); exit(1); } while(!filedone) { if(req->vps) pairfree(&req->vps); if(req2->vps) pairfree(&req2->vps); if ((req->vps = readvp2(stdin, &filedone, "eapsimlib:")) == NULL) { break; } printf("\nRead:\n"); vp_printlist(stdout, req->vps); map_eapsim_types(req); map_eap_types(req); printf("Mapped to:\n"); vp_printlist(stdout, req->vps); /* find the EAP-Message, copy it to req2 */ vp = paircopy2(req->vps, PW_EAP_MESSAGE); if(vp == NULL) continue; pairadd(&req2->vps, vp); /* only call unmap for sim types here */ unmap_eap_types(req2); unmap_eapsim_types(req2); printf("Unmapped to:\n"); vp_printlist(stdout, req2->vps); vp = pairfind(req2->vps, ATTRIBUTE_EAP_SIM_BASE+PW_EAP_SIM_MAC); vpkey = pairfind(req->vps, ATTRIBUTE_EAP_SIM_KEY); vpextra = pairfind(req->vps, ATTRIBUTE_EAP_SIM_EXTRA); if(vp != NULL && vpkey != NULL && vpextra!=NULL) { uint8_t calcmac[16]; /* find the EAP-Message, copy it to req2 */ memset(calcmac, 0, sizeof(calcmac)); printf("Confirming MAC..."); if(eapsim_checkmac(req2->vps, vpkey->strvalue, vpextra->strvalue, vpextra->length, calcmac)) { printf("succeed\n"); } else { int i, j; printf("calculated MAC ("); for (i = 0; i < 20; i++) { if(j==4) { printf("_"); j=0; } j++; printf("%02x", calcmac[i]); } printf(" did not match\n"); } } fflush(stdout); } }
main(int argc, char *argv[]) { int filedone; RADIUS_PACKET *req,*req2; VALUE_PAIR *vp, *vpkey, *vpextra; extern unsigned int sha1_data_problems; req = NULL; req2 = NULL; filedone = 0; if(argc>1) { sha1_data_problems = 1; } if (dict_init(radius_dir, RADIUS_DICTIONARY) < 0) { ERROR("%s", fr_strerror()); return 1; } req = rad_alloc(NULL, true) if (!req) { ERROR("%s", fr_strerror()); exit(1); } req2 = rad_alloc(NULL, true); if (!req2) { ERROR("%s", fr_strerror()); exit(1); } while(!filedone) { if (req->vps) pairfree(&req->vps); if (req2->vps) pairfree(&req2->vps); if (readvp2(&req->vps, NULL, stdin, &filedone) < 0) { ERROR("%s", fr_strerror()); break; } if (fr_debug_flag > 1) { DEBUG("Read:"); vp_printlist(stdout, req->vps); } map_eapsim_types(req); map_eap_methods(req); if (fr_debug_flag > 1) { DEBUG("Mapped to:"); vp_printlist(stdout, req->vps); } /* find the EAP-Message, copy it to req2 */ vp = paircopy2(NULL, req->vps, PW_EAP_MESSAGE, 0, TAG_ANY); if(!vp) continue; pairadd(&req2->vps, vp); /* only call unmap for sim types here */ unmap_eap_methods(req2); unmap_eapsim_types(req2); if (fr_debug_flag > 1) { DEBUG("Unmapped to:"); vp_printlist(stdout, req2->vps); } vp = pairfind(req2->vps, PW_EAP_SIM_MAC, 0, TAG_ANY); vpkey = pairfind(req->vps, PW_EAP_SIM_KEY, 0, TAG_ANY); vpextra = pairfind(req->vps, PW_EAP_SIM_EXTRA, 0, TAG_ANY); if(vp != NULL && vpkey != NULL && vpextra!=NULL) { uint8_t calcmac[16]; /* find the EAP-Message, copy it to req2 */ memset(calcmac, 0, sizeof(calcmac)); DEBUG("Confirming MAC..."); if(eapsim_checkmac(req2->vps, vpkey->vp_strvalue, vpextra->vp_strvalue, vpextra->length, calcmac)) { DEBUG("succeed"); } else { int i, j; DEBUG("calculated MAC ("); for (i = 0; i < 20; i++) { if(j==4) { DEBUG("_"); j=0; } j++; DEBUG("%02x", calcmac[i]); } DEBUG("did not match"); } } fflush(stdout); } }