radiusniff.c
上传用户:quanlove
上传日期:2007-01-08
资源大小:17k
文件大小:24k
- /*
-
- RADIUS traffic sNIFFer
- Copyleft 2000 by FreeLSD <freelsd@freelsd.net>
-
- Some portion of code from snmpsniffer.c (c) by Nuno Leitao
- NOTICE:
- You may copy, distribute or modify this code, as long as you
- keep this copyleft notice intact.
- PS. dont try to run... ;)
-
- Greets to all ADM!@#$% and w00w00 ppl.
-
- */
- #include <unistd.h>
- #include <sys/types.h>
- #include <sys/socket.h>
- #include <stdlib.h>
- #include <string.h>
- #include <signal.h>
- #include <stdio.h>
- #include <errno.h>
- #include <netinet/in_systm.h>
- #include <netinet/in.h>
- #include <netinet/ip.h>
- #include <netinet/udp.h>
- #include <netdb.h>
- #include <arpa/inet.h>
- #include <pcap.h>
- #include "md5.h"
- #define VERSION "0.2 (lame & dirty)"
- #ifdef NOT_HAVE_SNPRINTF
- #include <stdarg.h>
- #define snprintf int_snprintf
- int int_snprintf (char *buf, int len, char *fmt,...)
- {
- va_list args;
- int ret;
- va_start (args, fmt);
- ret = vsprintf (buf, fmt, args);
- va_end (args);
- return (ret);
- }
- #endif
- /* ------------------------------------------------------------------ */
- #ifdef LINUX
- #include <linux/if_ether.h>
- #define EthernetHeader struct ethhdr
- #define IPHeader struct iphdr
- #define UDPHeader struct udphdr
- #define UDP_SrcPort(x) (x->source)
- #define UDP_DstPort(x) (x->dest)
- #define IP_SrcAddr(x) (x->saddr)
- #define IP_DstAddr(x) (x->daddr)
- #endif
- /* The default case is Solaris. */
- #ifndef EthernetHeader
- #include <net/if.h>
- #include <netinet/if_ether.h>
- #define EthernetHeader struct ether_header
- #define IPHeader struct ip
- #define UDPHeader struct udphdr
- #define UDP_SrcPort(x) (x->uh_sport)
- #define UDP_DstPort(x) (x->uh_dport)
- #define IP_SrcAddr(x) (x->ip_src)
- #define IP_DstAddr(x) (x->ip_dst)
- #endif /* EthernetHeader */
- #define MAXBUFFER 65536
- #ifndef DICTIONARY_FILENAME
- #define DICTIONARY_FILENAME "dictionary"
- #endif
- #ifndef CLIENTS_FILENAME
- #define CLIENTS_FILENAME "clients"
- #endif
- #define RADIUS_ATTR_STR 1
- #define RADIUS_ATTR_INT 2
- #define RADIUS_ATTR_DATE 3
- #define RADIUS_ATTR_IPADDR 4
- #define RADIUS_ATTR_ABINARY 5 /* Ascend specific */
- typedef struct _DICT_VALUE {
- int value;
- char *name;
- char *attrname;
- void *next;
- } DICT_VALUE;
- typedef struct _DICT_ATTR {
- int value;
- int type;
- char *name;
- void *next;
- } DICT_ATTR;
- /* we ignore any greater */
- #define MAX_SECRET_STRING 253
- typedef struct _CLIENTS {
- struct in_addr ipaddr;
- char secret[MAX_SECRET_STRING];
- void *next;
- } CLIENTS;
- /* radius attr packet for parsing process */
- typedef struct RAD_ATTR_PACKET {
- int code;
- int type;
- int length;
- char *buff;
- int buff_length;
- char *name;
- void *next;
- } RAD_ATTR_PACKET;
- /* radius packet struct for parsing process */
- typedef struct RAD_PACKET {
- time_t time;
- struct sockaddr_in src;
- struct sockaddr_in dst;
-
- unsigned char code;
- unsigned char ident;
- unsigned short length;
- unsigned char auth[16];
- char buff[4096];
- unsigned int buff_length;
- struct RAD_ATTR_PACKET *attr; /* parsed attr's chain */
- } RAD_PACKET;
- /* ethernet packet */
- struct etherpacket {
- EthernetHeader eth;
- IPHeader ip;
- UDPHeader udp;
- char buff[MAXBUFFER];
- } eth_packet;
- /* The following are hooks to the positions in the struct.
- */
- IPHeader *ip;
- UDPHeader *udp;
- /*-------------------------------------------------------------------------*/
- int quiet = 0;
- int account = 0; /* only accounting info */
- int resolve = 0; /* dont resolve hostnames as default */
- int verbose = 0; /* silence as default */
- pcap_t *PCAP; /* PCAP handler for interface */
- char *dict_filename = DICTIONARY_FILENAME;
- char *clients_filename = NULL; /* individual clients secret */
- CLIENTS *secret_clients = NULL;
- char *secret_passwd = NULL; /* global secret passwd */
- DICT_ATTR *dictionary_attr = NULL;
- DICT_VALUE *dictionary_value = NULL;
- char *ParseRadiusCode(unsigned int code)
- {
- char *ret;
-
- switch (code) {
- case 1: ret = "Access-Request"; break;
- case 2: ret = "Access-Accept"; break;
- case 3: ret = "Access-Reject"; break;
- case 4: ret = "Accounting-Request"; break;
- case 5: ret = "Accounting-Response"; break;
- case 11: ret = "Access-Challenge"; break;
- case 12: ret = "Status-Server (experemental)"; break;
- case 13: ret = "Status=Client (experemental)"; break;
- case 255: ret = "Reserved"; break;
- default:
- return NULL;
- }
- return ret;
- }
- char *ParseRadiusAuth(char *auth)
- {
- static char ret[80];
- int i;
- for (i = 0; i < 16; i++) {
- snprintf(ret+i*2, 80-i*2, "%02x", (unsigned int)*( unsigned char *)(auth+i));
- }
- return ret;
- }
- DICT_ATTR *GetAttrFromDict(int key)
- {
- DICT_ATTR *attr = dictionary_attr;
-
- while (attr != NULL) {
- if (attr->value == key) return attr;
- attr = attr->next;
- }
- return NULL;
- }
- DICT_VALUE *GetValueFromDict(int attrkey, int key)
- {
- DICT_VALUE *value = dictionary_value;
- DICT_ATTR *attr;
- char *str;
-
- if ((attr = GetAttrFromDict(attrkey)) == NULL) return NULL;
- str = attr->name;
- while (value != NULL) {
- if (strlen(value->attrname) == strlen(str) &&
- strncmp(value->attrname, str, strlen(str)) == 0 &&
- value->value == key)
- return value;
- value = value->next;
- }
- return NULL;
- }
- char *GetHostSecret(struct in_addr *ipaddr)
- {
- CLIENTS *cur = secret_clients;
- while (cur != NULL) {
- if (memcmp(ipaddr, &cur->ipaddr, sizeof(struct in_addr)) == 0)
- return cur->secret;
- cur = cur->next;
- }
-
- /* if global secret passwd is setted, we use it as default
- for nondefined hosts */
- if (secret_passwd != NULL) return secret_passwd;
- return NULL;
- }
- void OutHex(unsigned char *buff, unsigned int len)
- {
- printf("(%d) ", len);
- while (len-- != 0) {
- printf("%02x", (unsigned int)*buff);
- buff++;
- }
- }
- void OutAscii(unsigned char *buff, unsigned int len)
- {
- while (len-- != 0 && *buff != 0) {
- printf("%c", (unsigned char)*buff);
- buff++;
- }
- }
- void FreeRadiusPacketStruct(RAD_PACKET *rad)
- {
- int counter = 0;
- RAD_ATTR_PACKET *pkt;
- if (rad == NULL) return;
- while ((pkt = rad->attr) != NULL) {
- rad->attr = rad->attr->next;
- counter++;
- free(pkt);
- }
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "free %d objectsn", counter);
- #endif
- }
- int OutRadiusPacket(RAD_PACKET *rad)
- {
- struct tm *curr_time;
- struct hostent *host;
- char src_str[128], dst_str[128];
- RAD_ATTR_PACKET *attr = rad->attr;
- DICT_VALUE *value;
- unsigned long val;
- struct sockaddr_in addr;
- char str[4096], *code_str;
- int empty;
- curr_time = localtime(&rad->time);
- memset(src_str, 0, sizeof(src_str));
- strncpy(src_str, (char *)inet_ntoa(rad->src.sin_addr), 127);
- memset(dst_str, 0, sizeof(dst_str));
- strncpy(dst_str, (char *)inet_ntoa(rad->dst.sin_addr), 127);
- if (resolve) {
- if ((host = gethostbyaddr((char *) &rad->src.sin_addr,
- sizeof(rad->src.sin_addr), AF_INET)))
- strncpy(src_str, host->h_name, 127);
- if ((host = gethostbyaddr((char *) &rad->dst.sin_addr,
- sizeof(rad->dst.sin_addr), AF_INET)))
- strncpy(dst_str, host->h_name, 127);
- }
-
- if (!account) {
- /* out all packets */
- printf("%.2d:%.2d:%.2d ",
- curr_time->tm_hour, curr_time->tm_min, curr_time->tm_sec);
- printf("%s:%u > %s:%un", src_str, ntohs(rad->src.sin_port),
- dst_str, ntohs(rad->dst.sin_port));
- code_str = ParseRadiusCode(rad->code);
- if (code_str == NULL) {
- printf(" code : Undefined (%0x02X)nn", rad->code);
- return -1;
- }
- printf(" code : %sn", ParseRadiusCode(rad->code));
- if (verbose) {
- printf(" iden : 0x%02xn len : 0x%03xn auth : %sn",
- rad->ident, rad->length, ParseRadiusAuth(rad->auth));
- }
- while (attr) {
- printf("t%s = ", attr->name);
- if (attr->buff_length <= 0) empty = 1; else empty = 0;
-
- switch (attr->type) {
- case RADIUS_ATTR_DATE:
- if (empty) break;
- memcpy(&val, attr->buff, sizeof(long));
- val = ntohl(val);
- printf("%08Xh (date)n", val);
- break;
- case RADIUS_ATTR_INT:
- if (empty) break;
- memcpy(&val, attr->buff, sizeof(long));
- val = ntohl(val);
- if ((value = GetValueFromDict(attr->code, val)) == NULL) {
- printf("%dn", val);
- } else {
- printf("%sn", value->name);
- }
- break;
- case RADIUS_ATTR_IPADDR:
- if (empty) break;
- memcpy ((void *) &(addr.sin_addr), (void *)(attr->buff),
- sizeof(struct in_addr));
- printf("%sn", inet_ntoa(addr.sin_addr));
- break;
- case RADIUS_ATTR_ABINARY:
- if (empty) printf("""n");
- else {
- if ( attr->code == 2 && GetHostSecret(&rad->src.sin_addr) != NULL ) {
- /* password */
- char cr[1024];
- char digest[32];
- char *hostsecret = GetHostSecret(&rad->src.sin_addr);
- int i;
- memcpy(cr, hostsecret, strlen(hostsecret));
- memcpy(cr + strlen(hostsecret), rad->auth, 16);
- MD5Calc(digest, cr, strlen(hostsecret) + 16);
- memset(cr, 0, sizeof(cr));
- printf(""");
- for ( i = 0; i < attr->buff_length; i++ )
- attr->buff[i] ^= digest[i % 16];
- OutAscii(attr->buff, attr->buff_length);
- printf("" ");
- }
- OutHex(attr->buff, attr->buff_length);
- printf("n");
- }
- break;
- case RADIUS_ATTR_STR:
- if (empty) printf("""n");
- else {
- memcpy(str, (attr->buff), attr->buff_length);
- str[attr->buff_length] = 0;
- printf(""%s"n", str);
- }
- break;
- default:
- printf("<undefined type>n");
- break;
- }
- attr = attr->next;
- }
- printf("n");
- } else {
- /* out only short accounting packets */
- if (rad->code != 4 && rad->code != 5) return 0;
- printf("%.2d:%.2d:%.2d ",
- curr_time->tm_hour, curr_time->tm_min, curr_time->tm_sec);
- printf("%s:%u > %s:%u ", src_str, ntohs(rad->src.sin_port),
- dst_str, ntohs(rad->dst.sin_port));
- if (rad->code == 4) printf("Req ");
- else printf("Res ");
- while (attr) {
- printf("%s = ", attr->name);
- if (attr->buff_length <= 0) empty = 1; else empty = 0;
-
- switch (attr->type) {
- case RADIUS_ATTR_DATE:
- if (empty) break;
- memcpy(&val, attr->buff, sizeof(long));
- val = ntohl(val);
- printf("%08Xh (date)", val);
- break;
- case RADIUS_ATTR_INT:
- if (empty) break;
- memcpy(&val, attr->buff, sizeof(long));
- val = ntohl(val);
- if ((value = GetValueFromDict(attr->code, val)) == NULL) {
- printf("%d", val);
- } else {
- printf("%s", value->name);
- }
- break;
- case RADIUS_ATTR_IPADDR:
- if (empty) break;
- memcpy ((void *) &(addr.sin_addr), (void *)(attr->buff),
- sizeof(struct in_addr));
- printf("%s", inet_ntoa(addr.sin_addr));
- break;
- case RADIUS_ATTR_ABINARY:
- if (empty) printf("""");
- else {
- OutHex(attr->buff, attr->buff_length);
- }
- break;
- case RADIUS_ATTR_STR:
- if (empty) printf("""");
- else {
- memcpy(str, (attr->buff), attr->buff_length);
- str[attr->buff_length] = 0;
- printf(""%s"", str);
- }
- break;
- default:
- printf("<undefined type>");
- break;
- }
- attr = attr->next;
- if (attr) printf(", ");
- }
- printf("n");
- }
- return 0;
- }
- /* redefine type for some of non ascii attributes */
- int HookAttr(int code, int type)
- {
- switch (code) {
- case 2: /* Password (out like md5) */
- case 3: /* Challenge-Response (CHAP Password) */
- case 17: /* Change-Password (only for Ascend)*/
- case 19: /* Callback-Number (no ascii) */
- case 20: /* Callback-Id (no ascii) */
- case 24: /* State (no ascii) */
- case 25: /* Class (no ascii) */
- case 26: /* Vendor_Specific */
- case 214: /* Ascend-Send-Secret */
- case 215: /* Ascend-Receive-Secret */
- return RADIUS_ATTR_ABINARY;
- }
- return type;
- }
- int ParseRadiusAttr(RAD_PACKET *rad)
- {
- DICT_ATTR *attr;
- DICT_VALUE *value;
- unsigned long val;
- struct sockaddr_in addr;
- RAD_ATTR_PACKET *rattr, *last = NULL;
- int counter = 0;
- unsigned char *buff = rad->buff;
- int len = rad->buff_length;
- if (len <= 0) return -1;
- while (len > 0) {
- rattr = malloc(sizeof(RAD_ATTR_PACKET));
- if (rattr == NULL) {
- fprintf(stderr, "ERROR: Out of memory (while parsing in progress)n");
- return -1;
- }
- counter++;
- rattr->code = (unsigned char)*buff;
- rattr->length = (unsigned char)*(buff+1);
- if ((attr = GetAttrFromDict(rattr->code)) == NULL) {
- fprintf(stderr, "ERROR: Undefined attr (type:%02Xh, length:%d)n",
- rattr->code, rattr->length);
- return -1;
- }
- rattr->name = attr->name;
- rattr->type = HookAttr(rattr->code, attr->type);
- rattr->buff = buff+2;
- rattr->buff_length = rattr->length-2; /* without code and len */
- rattr->next = NULL;
- if (last == NULL) rad->attr = rattr;
- else last->next = rattr;
- last = rattr;
- /* continue for next attr */
- len -= rattr->length;
- buff += rattr->length;
- }
- if (len != 0) {
- fprintf(stderr, "ERROR: wrong packet... non aligned internal structn");
- return -1;
- }
- #ifdef DEBUG_MALLOC
- fprintf(stderr, "malloc %d objectsn", counter);
- #endif
- return 0;
- }
- int CheckDoublePacket(RAD_PACKET *rad)
- {
- return 0; /* not implemented yet */
- }
- void FilterProc(char *user_data, struct pcap_pkthdr *p_header, const char *packet)
- {
- unsigned int packet_size = p_header->caplen;
- char *rad_pkt;
- int rad_pkt_len;
- RAD_PACKET RAD; /* Parsed RADIUS packet struct */
- memset(&RAD, 0, sizeof(RAD));
-
- /* get time incoming packet */
- RAD.time = time(NULL);
- if (packet_size > MAXBUFFER) return; /* prevent overrun ;) */
- memcpy(ð_packet, packet, packet_size);
-
- /* fill sockaddr_in */
- RAD.src.sin_family = AF_INET;
- RAD.src.sin_port = UDP_SrcPort (udp);
- memcpy ((void *) &(RAD.src.sin_addr), (void *) &(IP_SrcAddr (ip)),
- sizeof (struct in_addr));
- RAD.dst.sin_family = AF_INET;
- RAD.dst.sin_port = UDP_DstPort (udp);
- memcpy ((void *) &(RAD.dst.sin_addr), (void *) &(IP_DstAddr (ip)),
- sizeof (struct in_addr));
- rad_pkt = (char *)((eth_packet.buff)-2);
- rad_pkt_len = packet_size-sizeof(eth_packet.ip)-sizeof(eth_packet.udp);
- /* check size of received packet and according rfc drop wrong packets */
- if (rad_pkt_len < 20 || rad_pkt_len > 4096) {
- fprintf(stderr, "ERROR: %s:%u > %s:%u - non RADIUS packet (bad UDP length: %d)n",
- (char *) inet_ntoa(RAD.src.sin_addr), ntohs(RAD.src.sin_port),
- (char *) inet_ntoa(RAD.dst.sin_addr), ntohs(RAD.dst.sin_port),
- rad_pkt_len);
- return;
- }
-
- /* fill radius packet struct */
- RAD.code = *(char *)rad_pkt;
- RAD.ident = *(unsigned char *)(rad_pkt+1);
- RAD.length = ntohs(*(unsigned short *)(rad_pkt+2));
- memcpy(RAD.auth, (char *)(rad_pkt+4), 16);
- RAD.buff_length = RAD.length - 20; /* without code,ident,length,auth */
- if (RAD.buff_length >= 0 && RAD.buff_length <= 4096 - 20 )
- memcpy(RAD.buff, (char *)(rad_pkt+20), RAD.buff_length);
- else {
- fprintf(stderr, "ERROR: %s:%u > %s:%u - non RADIUS packet (bad length in packet: %d)n",
- (char *) inet_ntoa(RAD.src.sin_addr), ntohs(RAD.src.sin_port),
- (char *) inet_ntoa(RAD.dst.sin_addr), ntohs(RAD.dst.sin_port),
- RAD.buff_length);
- return;
- }
- if (quiet && CheckDoublePacket(&RAD)) return;
- if (ParseRadiusAttr(&RAD) == 0) OutRadiusPacket(&RAD);
- FreeRadiusPacketStruct(&RAD);
-
- return;
- }
- void HookProto(void)
- {
- ip = (IPHeader *) (((unsigned long) ð_packet.ip) - 2);
- udp = (UDPHeader *) (((unsigned long) ð_packet.udp) - 2);
- }
- pcap_t *OpenPromisc(char *eth, int snaplen, int promisc, int to_ms)
- {
- pcap_t *h;
- char ebuf[PCAP_ERRBUF_SIZE];
- h = pcap_open_live(eth, snaplen, promisc, to_ms, ebuf);
- if( !h )
- fprintf(stderr, "ERROR: Can't open interface %s.n%sn", eth, ebuf);
- return h;
- }
- void ClosePromisc(void)
- {
- pcap_close(PCAP);
- }
- #define MAX_FILTER_STR 4096
- int MakeFilter(pcap_t *h, char *eth, unsigned short pradius, unsigned short pradacct, char *filter)
- {
- struct bpf_program bpf;
- bpf_u_int32 net, mask;
- char ebuf[PCAP_ERRBUF_SIZE];
- char buf[MAX_FILTER_STR];
- if (pcap_lookupnet(eth, &net, &mask, ebuf) == -1) {
- fprintf(stderr, "ERROR: Can't lookup interface %sn%sn", eth, ebuf);
- return -1;
- }
- snprintf(buf, MAX_FILTER_STR,
- "(udp and (port %d or port %d) %s)",
- ntohs(pradius), ntohs(pradacct), filter);
- if (pcap_compile(h, &bpf, buf, 1, mask) == -1) {
- fprintf(stderr, "ERROR: Can't compile BPF filter '%s'n", buf);
- return -1;
- }
- if (pcap_setfilter(h, &bpf) == -1) {
- fprintf(stderr, "ERROR: Can't set BPF filter '%s'n", buf);
- }
-
- return 0;
- }
- void Terminate(int signal)
- {
- ClosePromisc();
- exit(0);
- }
- int LoadDictionary(char *fname)
- {
- FILE *in;
- char buff[1024];
- int line = 0;
- char attrstr[512], namestr[512], valuestr[512], typestr[512];
- DICT_ATTR dicta, *attr;
- DICT_VALUE dictv, *value;
-
-
- if ((in = fopen(fname,"r")) == NULL) {
- fprintf(stderr, "ERROR: Can't open dictionary file '%s'n", fname);
- return -1;
- }
- while (fgets(buff, sizeof(buff), in) != NULL) {
- line++;
- if (*buff == 0 || *buff == '#' || *buff == 'n') continue;
- if (strncmp(buff, "ATTRIBUTE", 9) == 0) {
- if (sscanf(buff, "%s%s%s%s", attrstr, namestr, valuestr, typestr) != 4) {
- fprintf(stderr, "ERROR: Can't understand ATTRIBUTE on line %dn", line);
- return -1;
- }
- if (strlen(namestr) > 31) {
- fprintf(stderr, "ERROR: Invalid name length on line %dn", line);
- return -1;
- }
- if (!isdigit(*valuestr)) {
- fprintf(stderr, "ERROR: Invalid value on line %dn", line);
- return -1;
- }
- dicta.value = atoi(valuestr);
- if (strcmp(typestr, "string") == 0) dicta.type = RADIUS_ATTR_STR;
- else if (strcmp(typestr, "integer") == 0) dicta.type = RADIUS_ATTR_INT;
- else if (strcmp(typestr, "ipaddr") == 0) dicta.type = RADIUS_ATTR_IPADDR;
- else if (strcmp(typestr, "date") == 0) dicta.type = RADIUS_ATTR_DATE;
- else if (strcmp(typestr, "abinary") == 0) dicta.type = RADIUS_ATTR_ABINARY;
- else {
- fprintf(stderr, "ERROR: Invalid type on line %dn", line);
- return -1;
- }
- if ((dicta.name = malloc(strlen(namestr)+1)) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- strncpy(dicta.name, namestr, strlen(namestr)+1);
-
- /* insert new ATTR */
- if ((attr = malloc(sizeof(DICT_ATTR))) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- memcpy(attr, &dicta, sizeof(DICT_ATTR));
- attr->next = dictionary_attr;
- dictionary_attr = attr;
- #ifdef DEBUG
- fprintf(stderr,"attr: %sn", attr->name);
- #endif
- }
- else if (strncmp(buff, "VALUE", 5) == 0) {
- if (sscanf(buff, "%s%s%s%s", typestr, attrstr, namestr, valuestr) != 4) {
- fprintf(stderr, "ERROR: Can't understand VALUE on line %dn", line);
- return -1;
- }
- if (strlen(attrstr) > 31) {
- fprintf(stderr, "ERROR: Invalid attribute length on line %dn", line);
- return -1;
- }
- if (strlen(namestr) > 31) {
- fprintf(stderr, "ERROR: Invalid name length on line %dn", line);
- return -1;
- }
- if (!isdigit(*valuestr)) {
- fprintf(stderr, "ERROR: Invalid value on line %dn", line);
- return -1;
- }
- dictv.value = atoi(valuestr);
- if ((dictv.name = malloc(strlen(namestr)+1)) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- strncpy(dictv.name, namestr, strlen(namestr)+1);
- if ((dictv.attrname = malloc(strlen(attrstr)+1)) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- strncpy(dictv.attrname, attrstr, strlen(attrstr)+1);
- /* insert net VALUE */
- if ((value = malloc(sizeof(DICT_VALUE))) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- memcpy(value, &dictv, sizeof(DICT_VALUE));
- value->next = dictionary_value;
- dictionary_value = value;
- #ifdef DEBUG
- fprintf(stderr,"valu: %s (attr:%s)n", value->name, value->attrname);
- #endif
- }
- }
- fclose(in);
- return 0;
- }
- int LoadClients(char *fname)
- {
- FILE *in = fopen(fname,"r");
- char buff[1024];
- CLIENTS host, *ins_host;
- int line = 0;
- char ip[128], sec[512];
- if (in == NULL) {
- fprintf(stderr, "ERROR: Can't open clients file '%s'n", fname);
- return -1;
- }
- while (fgets(buff, sizeof(buff), in) != NULL) {
- line++;
- if (*buff == 0 || *buff == '#' || *buff == 'n') continue;
- if (sscanf(buff, "%s%s", ip, sec) != 2) {
- fprintf(stderr, "ERROR: Can't understand line %dn", line);
- return -1;
- }
-
- if (inet_aton(ip,&host.ipaddr) == 0) {
- fprintf(stderr, "ERROR: Can't convert ip addr on line %dn", line);
- return -1;
- }
- if (sizeof(host.secret) < strlen(sec)) {
- fprintf(stderr, "ERROR: Too long secret on line %dn", line);
- return -1;
- }
- memcpy(host.secret,sec,strlen(sec)+1);
- /* insert new client secret password here */
- if ((ins_host = malloc(sizeof(CLIENTS))) == NULL) {
- fprintf(stderr, "ERROR: Out of memn");
- return -1;
- }
- memcpy(ins_host, &host, sizeof(CLIENTS));
- ins_host->next = secret_clients;
- secret_clients = ins_host;
- }
- fclose(in);
- return 0;
- }
- int main(int argc, char *argv[])
- {
- char *filter = "";
- char ebuf[PCAP_ERRBUF_SIZE];
- char *eth = NULL;
- int arg, error = 0;
- struct servent *serv_ent;
- unsigned short radius_port, radacct_port;
- /*
- fprintf(stderr, "eth_packet size: %dn", sizeof(eth_packet));
- */
-
- while ((arg = getopt(argc, argv, "Vavri:f:d:c:qp:")) != -1) {
- switch( arg ) {
- case 'v': /* be verbose */
- verbose++;
- break;
- case 'i': /* set interface name */
- eth = strdup(optarg);
- break;
- case 'f': /* pcap filter expression */
- filter = strdup(optarg);
- break;
- case 'r': /* resolve hostnames */
- resolve++;
- break;
- case 'd': /* set dictonary */
- dict_filename = strdup(optarg);
- break;
- case 'c': /* place where i can get secret passwords */
- clients_filename = strdup(optarg);
- break;
- case 's': /* there u can define default secret password */
- secret_passwd = strdup(optarg);
- break;
- case 'q': /* quiet output */
- quiet++;
- break;
- case 'a': /* output accounting info only */
- account++;
- break;
- case 'V':
- fprintf(stderr, "RADIUS sNIFFer by FreeLSD. Version %sn", VERSION);
- fprintf(stderr, "http://www.freelsd.net/securityn");
- exit(0);
- default:
- error++;
- break;
- }
- }
-
- if (error) {
- fprintf(stderr, "Usage: radiusniff [-vVrqa] [-i interface] [-f expression]n");
- fprintf(stderr, " [-d dictionary ] [-c clients] [-s passwd]n");
- exit(1);
- }
- if (!eth) {
- if (!(eth = pcap_lookupdev(ebuf))) {
- fprintf(stderr, "ERROR: Can't find device for sniffing.n%sn",ebuf);
- exit(1);
- }
- }
- if (access(dict_filename, R_OK) != 0) {
- fprintf(stderr, "ERROR: Can't access to dictonary file '%s'n", dict_filename);
- exit(1);
- }
- if (LoadDictionary(dict_filename) != 0) exit(1);
- if (clients_filename) {
- if (access(clients_filename, R_OK) != 0) {
- fprintf(stderr, "ERROR: Can't access to clients file '%s', ignored...n", clients_filename);
- clients_filename = NULL;
- } else if (LoadClients(clients_filename) != 0) exit(1);
- }
-
- HookProto();
- signal(SIGINT, Terminate);
- signal(SIGTERM, Terminate);
- signal(SIGKILL, Terminate);
- signal(SIGQUIT, Terminate);
-
- serv_ent = getservbyname("radius","udp");
- serv_ent ? (radius_port = serv_ent->s_port) : (radius_port = htons(1645));
- serv_ent = getservbyname("radacct","udp");
- serv_ent ? (radacct_port = serv_ent->s_port) : (radacct_port = htons(1646));
- if (!(PCAP = OpenPromisc(eth, 10000, 1, 0))) exit(1);
- if (MakeFilter(PCAP, eth, radius_port, radacct_port, filter) != 0) exit(1);
- /* Let's make STDOUT line buffered */
- setlinebuf(stdout);
- /* start main loop */
- pcap_loop(PCAP, -1, (void *)FilterProc, NULL);
-
- ClosePromisc();
- }