⭐ 欢迎来到虫虫下载站! | 📦 资源下载 📁 资源专辑 ℹ️ 关于我们
⭐ 虫虫下载站

📄 radeapclient.c

📁 RADIUS认证协议
💻 C
📖 第 1 页 / 共 2 页
字号:
	newvp = paircreate(ATTRIBUTE_EAP_SIM_KEY, PW_TYPE_OCTETS);	memcpy(newvp->strvalue,    eapsim_mk.K_aut, EAPSIM_AUTH_SIZE);	newvp->length = EAPSIM_AUTH_SIZE;	pairreplace(&(rep->vps), newvp);	return 1;}/* * 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(req->vps, PW_STATE)) == NULL)	{		return 0;	}	if ((eapid = paircopy2(req->vps, ATTRIBUTE_EAP_ID)) == 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)) == NULL)	{		/* must be initial request */		statevp = paircreate(ATTRIBUTE_EAP_SIM_STATE, PW_TYPE_INTEGER);		statevp->lvalue = eapsim_client_init;		pairreplace(&(resp->vps), statevp);	}	state = statevp->lvalue;	/*	 * map the attributes, and authenticate them.	 */	unmap_eapsim_types(req);	printf("<+++ EAP-sim decoded packet:\n");	vp_printlist(stdout, req->vps);	if((vp = pairfind(req->vps, ATTRIBUTE_EAP_SIM_SUBTYPE)) == NULL)	{		return 0;	}	subtype = vp->lvalue;	/*	 * 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->lvalue = newstate;	return 1;}static int respond_eap_md5(RADIUS_PACKET *req,			   RADIUS_PACKET *rep){	VALUE_PAIR *vp, *id, *state;	int valuesize, namesize;	unsigned char identifier;	unsigned char *value;	unsigned char *name;	MD5_CTX	context;	char    response[16];	cleanresp(rep);	if ((state = paircopy2(req->vps, PW_STATE)) == NULL)	{		fprintf(stderr, "radeapclient: no state attribute found\n");		return 0;	}	if ((id = paircopy2(req->vps, ATTRIBUTE_EAP_ID)) == NULL)	{		fprintf(stderr, "radeapclient: no EAP-ID attribute found\n");		return 0;	}	identifier = id->lvalue;	if ((vp = pairfind(req->vps, ATTRIBUTE_EAP_BASE+PW_EAP_MD5)) == NULL)	{		fprintf(stderr, "radeapclient: no EAP-MD5 attribute found\n");		return 0;	}	/* got the details of the MD5 challenge */	valuesize = vp->strvalue[0];	value = &vp->strvalue[1];	name  = &vp->strvalue[valuesize+1];	namesize = vp->length - (valuesize + 1);	/* sanitize items */	if(valuesize > vp->length)	{		fprintf(stderr, "radeapclient: md5 valuesize if too big (%d > %d)\n",			valuesize, vp->length);		return 0;	}	/* now do the CHAP operation ourself, rather than build the	 * buffer. We could also call rad_chap_encode, but it wants	 * a CHAP-Challenge, which we don't want to bother with.	 */	librad_MD5Init(&context);	librad_MD5Update(&context, &identifier, 1);	librad_MD5Update(&context, password, strlen(password));	librad_MD5Update(&context, value, valuesize);	librad_MD5Final(response, &context);	vp = paircreate(ATTRIBUTE_EAP_BASE+PW_EAP_MD5, PW_TYPE_OCTETS);	vp->strvalue[0]=16;	memcpy(&vp->strvalue[1], response, 16);	vp->length = 17;	pairreplace(&(rep->vps), vp);	pairreplace(&(rep->vps), id);	/* copy the state object in */	pairreplace(&(rep->vps), state);	return 1;}static int sendrecv_eap(RADIUS_PACKET *rep){	RADIUS_PACKET *req = NULL;	VALUE_PAIR *vp, *vpnext;	int tried_eap_md5 = 0;	/*	 *	Keep a copy of the the User-Password attribute.	 */	if ((vp = pairfind(rep->vps, ATTRIBUTE_EAP_MD5_PASSWORD)) != NULL) {		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));	} else 	if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));		/*		 *	Otherwise keep a copy of the CHAP-Password attribute.		 */	} else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {		strNcpy(password, (char *)vp->strvalue, sizeof(vp->strvalue));	} else {		*password = '\0';	} again:	rep->id++;	printf("\n+++> About to send encoded packet:\n");	vp_printlist(stdout, rep->vps);	/*	 * if there are EAP types, encode them into an EAP-Message	 *	 */	map_eap_types(rep);	/*	 *  Fix up Digest-Attributes issues	 */	for (vp = rep->vps; vp != NULL; vp = vp->next) {		switch (vp->attribute) {		default:			break;		case PW_DIGEST_REALM:		case PW_DIGEST_NONCE:		case PW_DIGEST_METHOD:		case PW_DIGEST_URI:		case PW_DIGEST_QOP:		case PW_DIGEST_ALGORITHM:		case PW_DIGEST_BODY_DIGEST:		case PW_DIGEST_CNONCE:		case PW_DIGEST_NONCE_COUNT:		case PW_DIGEST_USER_NAME:			/* overlapping! */			memmove(&vp->strvalue[2], &vp->strvalue[0], vp->length);			vp->strvalue[0] = vp->attribute - PW_DIGEST_REALM + 1;			vp->length += 2;			vp->strvalue[1] = vp->length;			vp->attribute = PW_DIGEST_ATTRIBUTES;			break;		}	}	/*	 *	If we've already sent a packet, free up the old	 *	one, and ensure that the next packet has a unique	 *	ID and authentication vector.	 */	if (rep->data) {		free(rep->data);		rep->data = NULL;	}	librad_md5_calc(rep->vector, rep->vector,			sizeof(rep->vector));	if (*password != '\0') {		if ((vp = pairfind(rep->vps, PW_PASSWORD)) != NULL) {			strNcpy((char *)vp->strvalue, password, strlen(password) + 1);			vp->length = strlen(password);		} else if ((vp = pairfind(rep->vps, PW_CHAP_PASSWORD)) != NULL) {			strNcpy((char *)vp->strvalue, password, strlen(password) + 1);			vp->length = strlen(password);			rad_chap_encode(rep, (char *) vp->strvalue, rep->id, vp);			vp->length = 17;		}	} /* there WAS a password */	/* send the response, wait for the next request */	send_packet(rep, &req);	/* okay got back the packet, go and decode the EAP-Message. */	unmap_eap_types(req);	printf("<+++ EAP decoded packet:\n");	vp_printlist(stdout, req->vps);	/* now look for the code type. */	for (vp = req->vps; vp != NULL; vp = vpnext) {		vpnext = vp->next;		switch (vp->attribute) {		default:			break;		case ATTRIBUTE_EAP_BASE+PW_EAP_MD5:			if(respond_eap_md5(req, rep) && tried_eap_md5 < 3)			{				tried_eap_md5++;				goto again;			}			break;		case ATTRIBUTE_EAP_BASE+PW_EAP_SIM:			if(respond_eap_sim(req, rep))			{				goto again;			}			break;		}	}	return 1;}int main(int argc, char **argv){	RADIUS_PACKET *req;	char *p;	int c;	int port = 0;	char *filename = NULL;	FILE *fp;	int count = 1;	int id;	id = ((int)getpid() & 0xff);	librad_debug = 0;	radlog_dest = RADLOG_STDERR;	while ((c = getopt(argc, argv, "c:d:f:hi:qst:r:S:xXv")) != EOF)	{		switch(c) {		case 'c':			if (!isdigit((int) *optarg))				usage();			count = atoi(optarg);			break;		case 'd':			radius_dir = optarg;			break;		case 'f':			filename = optarg;			break;		case 'q':			do_output = 0;			break;		case 'x':		        debug_flag++;			librad_debug++;			break;		case 'X':		  sha1_data_problems = 1;		  break;		case 'r':			if (!isdigit((int) *optarg))				usage();			retries = atoi(optarg);			break;		case 'i':			if (!isdigit((int) *optarg))				usage();			id = atoi(optarg);			if ((id < 0) || (id > 255)) {				usage();			}			break;		case 's':			do_summary = 1;			break;		case 't':			if (!isdigit((int) *optarg))				usage();			timeout = atof(optarg);			break;		case 'v':			printf("radclient: $Id: radeapclient.c,v 1.7 2004/02/26 19:04:29 aland Exp $ built on " __DATE__ " at " __TIME__ "\n");			exit(0);			break;               case 'S':		       fp = fopen(optarg, "r");                       if (!fp) {                               fprintf(stderr, "radclient: Error opening %s: %s\n",                                       optarg, strerror(errno));                               exit(1);                       }                       if (fgets(filesecret, sizeof(filesecret), fp) == NULL) {                               fprintf(stderr, "radclient: Error reading %s: %s\n",                                       optarg, strerror(errno));                               exit(1);                       }		       fclose(fp);                       /* truncate newline */		       p = filesecret + strlen(filesecret) - 1;		       while ((p >= filesecret) &&			      (*p < ' ')) {			       *p = '\0';			       --p;		       }                       if (strlen(filesecret) < 2) {                               fprintf(stderr, "radclient: Secret in %s is too short\n", optarg);                               exit(1);                       }                       secret = filesecret;		       break;		case 'h':		default:			usage();			break;		}	}	argc -= (optind - 1);	argv += (optind - 1);	if ((argc < 3)  ||	    ((secret == NULL) && (argc < 4))) {		usage();	}	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 0	{		FILE *randinit;		if((randinit = fopen("/dev/urandom", "r")) == NULL)		{			perror("/dev/urandom");		} else {			fread(randctx.randrsl, 256, 1, randinit);			fclose(randinit);		}	}	lrad_randinit(&randctx, 1);#endif	req->id = id;	/*	 *	Strip port from hostname if needed.	 */	if ((p = strchr(argv[1], ':')) != NULL) {		*p++ = 0;		port = atoi(p);	}	/*	 *	See what kind of request we want to send.	 */	if (strcmp(argv[2], "auth") == 0) {		if (port == 0) port = getport("radius");		if (port == 0) port = PW_AUTH_UDP_PORT;		req->code = PW_AUTHENTICATION_REQUEST;	} else if (strcmp(argv[2], "acct") == 0) {		if (port == 0) port = getport("radacct");		if (port == 0) port = PW_ACCT_UDP_PORT;		req->code = PW_ACCOUNTING_REQUEST;		do_summary = 0;	} else if (strcmp(argv[2], "status") == 0) {		if (port == 0) port = getport("radius");		if (port == 0) port = PW_AUTH_UDP_PORT;		req->code = PW_STATUS_SERVER;	} else if (strcmp(argv[2], "disconnect") == 0) {		if (port == 0) port = PW_POD_UDP_PORT;		req->code = PW_DISCONNECT_REQUEST;	} else if (isdigit((int) argv[2][0])) {		if (port == 0) port = getport("radius");		if (port == 0) port = PW_AUTH_UDP_PORT;		req->code = atoi(argv[2]);	} else {		usage();	}	/*	 *	Ensure that the configuration is initialized.	 */	memset(&mainconfig, 0, sizeof(mainconfig));	/*	 *	Resolve hostname.	 */	req->dst_port = port;	req->dst_ipaddr = ip_getaddr(argv[1]);	if (req->dst_ipaddr == INADDR_NONE) {		fprintf(stderr, "radclient: Failed to find IP address for host %s\n", argv[1]);		exit(1);	}	/*	 *	Add the secret.	 */	if (argv[3]) secret = argv[3];	/*	 *	Read valuepairs.	 *	Maybe read them, from stdin, if there's no	 *	filename, or if the filename is '-'.	 */	if (filename && (strcmp(filename, "-") != 0)) {		fp = fopen(filename, "r");		if (!fp) {			fprintf(stderr, "radclient: Error opening %s: %s\n",				filename, strerror(errno));			exit(1);		}	} else {		fp = stdin;	}	/*	 *	Send request.	 */	if ((req->sockfd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {		perror("radclient: socket: ");		exit(1);	}	while(!filedone) {		if(req->vps) pairfree(&req->vps);		if ((req->vps = readvp2(fp, &filedone, "radeapclient:"))		    == NULL) {			break;		}		sendrecv_eap(req);	}	if(do_summary) {		printf("\n\t   Total approved auths:  %d\n", totalapp);		printf("\t     Total denied auths:  %d\n", totaldeny);	}	return 0;}

⌨️ 快捷键说明

复制代码 Ctrl + C
搜索代码 Ctrl + F
全屏模式 F11
切换主题 Ctrl + Shift + D
显示快捷键 ?
增大字号 Ctrl + =
减小字号 Ctrl + -