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

📄 radclient.c

📁 radius server在linux下的源码
💻 C
📖 第 1 页 / 共 2 页
字号:
/* * radclient.c	General radius packet debug tool. * * Version:	$Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $ * *   This program is free software; you can redistribute it and/or modify *   it under the terms of the GNU General Public License as published by *   the Free Software Foundation; either version 2 of the License, or *   (at your option) any later version. * *   This program is distributed in the hope that it will be useful, *   but WITHOUT ANY WARRANTY; without even the implied warranty of *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the *   GNU General Public License for more details. * *   You should have received a copy of the GNU General Public License *   along with this program; if not, write to the Free Software *   Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA * * Copyright 2000  The FreeRADIUS server project * Copyright 2000  Miquel van Smoorenburg <miquels@cistron.nl> * Copyright 2000  Alan DeKok <aland@ox.org> */static const char rcsid[] = "$Id: radclient.c,v 1.72.2.1 2004/06/02 15:31:53 aland Exp $";#include "autoconf.h"#include "libradius.h"#include <stdio.h>#include <stdlib.h>#ifdef HAVE_UNISTD_H#	include <unistd.h>#endif#include <string.h>#include <ctype.h>#include <netdb.h>#include <sys/socket.h>#ifdef HAVE_NETINET_IN_H#	include <netinet/in.h>#endif#ifdef HAVE_SYS_SELECT_H#	include <sys/select.h>#endif#ifdef HAVE_GETOPT_H#	include <getopt.h>#endif#include <assert.h>#include "conf.h"#include "radpaths.h"#include "missing.h"static int retries = 10;static float timeout = 3;static const char *secret = NULL;static int do_output = 1;static int totalapp = 0;static int totaldeny = 0;static int totallost = 0;static int server_port = 0;static int packet_code = 0;static uint32_t server_ipaddr = 0;static int resend_count = 1;static int done = 1;static int sockfd;static int radius_id[256];static int last_used_id = -1;static rbtree_t *filename_tree = NULL;static rbtree_t *request_tree = NULL;static int sleep_time = -1;typedef struct radclient_t {	struct		radclient_t *prev;	struct		radclient_t *next;	const char	*filename;	int		packet_number; /* in the file */	char		password[256];	time_t		timestamp;	RADIUS_PACKET	*request;	RADIUS_PACKET	*reply;	int		resend;	int		tries;	int		done;} radclient_t;static radclient_t *radclient_head = NULL;static radclient_t *radclient_tail = NULL;static void usage(void){	fprintf(stderr, "Usage: radclient [options] server[:port] <command> [<secret>]\n");	fprintf(stderr, "  <command>    One of auth, acct, status, or disconnect.\n");	fprintf(stderr, "  -c count    Send each packet 'count' times.\n");	fprintf(stderr, "  -d raddb    Set dictionary directory.\n");	fprintf(stderr, "  -f file     Read packets from file, not stdin.\n");	fprintf(stderr, "  -r retries  If timeout, retry sending the packet 'retries' times.\n");	fprintf(stderr, "  -t timeout  Wait 'timeout' seconds before retrying (may be a floating point number).\n");	fprintf(stderr, "  -i id       Set request id to 'id'.  Values may be 0..255\n");	fprintf(stderr, "  -S file     read secret from file, not command line.\n");	fprintf(stderr, "  -q          Do not print anything out.\n");	fprintf(stderr, "  -s          Print out summary information of auth results.\n");	fprintf(stderr, "  -v          Show program version information.\n");	fprintf(stderr, "  -x          Debugging mode.\n");	exit(1);}/* *	Free a radclient struct, which may (or may not) *	already be in the list. */static void radclient_free(radclient_t *radclient){	radclient_t *prev, *next;	if (radclient->request) rad_free(&radclient->request);	if (radclient->reply) rad_free(&radclient->reply);	prev = radclient->prev;	next = radclient->next;	if (prev) {		assert(radclient_head != radclient);		prev->next = next;	} else if (radclient_head) {		assert(radclient_head == radclient);		radclient_head = next;	}	if (next) {		assert(radclient_tail != radclient);		next->prev = prev;	} else if (radclient_tail) {		assert(radclient_tail == radclient);		radclient_tail = prev;	}	free(radclient);}/* *	Initialize a radclient data structure */static radclient_t *radclient_init(const char *filename){	FILE *fp;	VALUE_PAIR *vp;	radclient_t *start, *radclient, *prev = NULL;	int filedone = 0;	int packet_number = 1;	start = NULL;	assert(filename != NULL);	/*	 *	Determine where to read the VP's from.	 */	if (strcmp(filename, "-") != 0) {		fp = fopen(filename, "r");		if (!fp) {			fprintf(stderr, "radclient: Error opening %s: %s\n",				filename, strerror(errno));			return NULL;		}	} else {		fp = stdin;	}	/*	 *	Loop until the file is done.	 */	do {		/*		 *	Allocate it.		 */		radclient = malloc(sizeof(*radclient));		if (!radclient) {			perror("radclient: ");			return NULL; /* memory leak "start" */		}		memset(radclient, 0, sizeof(*radclient));		radclient->request = rad_alloc(1);		if (!radclient->request) {			librad_perror("radclient: ");			radclient_free(radclient);			return NULL; /* memory leak "start" */		}		radclient->filename = filename;		radclient->request->id = -1; /* allocate when sending */		radclient->packet_number = packet_number++;		/*		 *	Read the VP's.		 */		radclient->request->vps = readvp2(fp, &filedone, "radclient:");		if (!radclient->request->vps) {			radclient_free(radclient);			return start; /* done: return the list */		}		/*		 *	Keep a copy of the the User-Password attribute.		 */		if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {			strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));			/*			 *	Otherwise keep a copy of the CHAP-Password attribute.			 */		} else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {			strNcpy(radclient->password, (char *)vp->strvalue, sizeof(vp->strvalue));		} else {			radclient->password[0] = '\0';		}		/*		 *  Fix up Digest-Attributes issues		 */		for (vp = radclient->request->vps; vp != NULL; vp = vp->next) {			switch (vp->attribute) {			default:				break;				/*				 *	Allow it to set the packet type in				 *	the attributes read from the file.				 */			case PW_PACKET_TYPE:				radclient->request->code = vp->lvalue;				break;			case PW_PACKET_DST_PORT:				radclient->request->dst_port = (vp->lvalue & 0xffff);				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;			}		} /* loop over the VP's we read in */		if (!start) {			start = radclient;			prev = start;		} else {			prev->next = radclient;			radclient->prev = prev;			prev = radclient;		}	} while (!filedone); /* loop until the file is done. */	if (fp != stdin) fclose(fp);	/*	 *	And we're done.	 */	return start;}/* *	Sanity check each argument. */static int radclient_sane(radclient_t *radclient){	if (radclient->request->dst_port == 0) {		radclient->request->dst_port = server_port;	}	radclient->request->dst_ipaddr = server_ipaddr;	if (radclient->request->code == 0) {		if (packet_code == -1) {			fprintf(stderr, "radclient: Request was \"auto\", but request %d in file %s did not contain Packet-Type\n",				radclient->packet_number, radclient->filename);			return -1;		}		radclient->request->code = packet_code;	}	radclient->request->sockfd = sockfd;	return 0;}/* *	For request handline. */static int filename_cmp(const void *one, const void *two){	return strcmp((const char *) one, (const char *) two);}static int filename_walk(void *data){	const char	*filename = data;	radclient_t	*radclient;	/*	 *	Initialize the request we're about	 *	to send.	 */	radclient = radclient_init(filename);	if (!radclient) {		exit(1);	}	if (!radclient_head) {		assert(radclient_tail == NULL);		radclient_head = radclient;	} else {		assert(radclient_tail->next == NULL);		radclient_tail->next = radclient;		radclient->prev = radclient_tail;	}	/*	 *	We may have had a list of "radclient" structures	 *	returned to us.	 */	while (radclient->next) radclient = radclient->next;	radclient_tail = radclient;	return 0;}/* *	Compare two RADIUS_PACKET data structures, based on a number *	of criteria. */static int request_cmp(const void *one, const void *two){	const radclient_t *a = one;	const radclient_t *b = two;	/*	 *	The following code looks unreasonable, but it's	 *	the only way to make the comparisons work.	 */	if (a->request->id < b->request->id) return -1;	if (a->request->id > b->request->id) return +1;	if (a->request->dst_ipaddr < b->request->dst_ipaddr) return -1;	if (a->request->dst_ipaddr > b->request->dst_ipaddr) return +1;	if (a->request->dst_port < b->request->dst_port) return -1;	if (a->request->dst_port > b->request->dst_port) return +1;	/*	 *	Everything's equal.  Say so.	 */	return 0;}/* *	"Free" a request. */static void request_free(void *data){	radclient_t *radclient = (radclient_t *) data;	if (!radclient || !radclient->request ||	    (radclient->request->id < 0)) {		return;	}	/*	 *	One more unused RADIUS ID.	 */	radius_id[radclient->request->id] = 0;	radclient->request->id = -1;	/*	 *	If we've already sent a packet, free up the old one,	 *	and ensure that the next packet has a unique	 *	authentication vector.	 */	if (radclient->request->data) {		free(radclient->request->data);		radclient->request->data = NULL;	}	if (radclient->reply) rad_free(&radclient->reply);}/* *	Send one packet. */static int send_one_packet(radclient_t *radclient){	int i;	assert(radclient->done == 0);	/*	 *	Remember when we have to wake up, to re-send the	 *	request, of we didn't receive a response.	 */	if ((sleep_time == -1) ||	    (sleep_time > (int) timeout)) {		sleep_time = (int) timeout;	}	/*	 *	Haven't sent the packet yet.  Initialize it.	 */	if (radclient->request->id == -1) {		int found = 0;		assert(radclient->reply == NULL);		/*		 *	Find a free packet Id		 */		for (i = 0; i < 256; i++) {			if (radius_id[(last_used_id + i) & 0xff] == 0) {				last_used_id = (last_used_id + i) & 0xff;				radius_id[last_used_id] = 1;				radclient->request->id = last_used_id++;				found = 1;				break;			}		}		/*		 *	Didn't find a free packet ID, we're not done,		 *	we don't sleep, and we stop trying to process		 *	this packet.		 */		if (!found) {			done = 0;			sleep_time = 0;			return 0;		}		assert(radclient->request->id != -1);		assert(radclient->request->data == NULL);		librad_md5_calc(radclient->request->vector, radclient->request->vector,				sizeof(radclient->request->vector));		/*		 *	Update the password, so it can be encrypted with the		 *	new authentication vector.		 */		if (radclient->password[0] != '\0') {			VALUE_PAIR *vp;			if ((vp = pairfind(radclient->request->vps, PW_PASSWORD)) != NULL) {				strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);				vp->length = strlen(radclient->password);			} else if ((vp = pairfind(radclient->request->vps, PW_CHAP_PASSWORD)) != NULL) {				strNcpy((char *)vp->strvalue, radclient->password, strlen(radclient->password) + 1);				vp->length = strlen(radclient->password);				rad_chap_encode(radclient->request, (char *) vp->strvalue, radclient->request->id, vp);				vp->length = 17;			}		}		radclient->timestamp = time(NULL);		radclient->tries = 1;		radclient->resend++;		/*

⌨️ 快捷键说明

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