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

📄 ipass.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
字号:
/* *	ipass.c - Ipass alliance routines * * These routines are called by the main program to talk to an Ipass server. * * The samples we have provided here may be used at a site running RADIUS *//* * * Copyright 1996 iPass Alliance Inc.  All rights reserved. * *	Portions may be copyright by: * *	Lucent Technologies Remote Access *	4464 Willow Road *	Pleasanton, CA   94588 * *	Copyright 1992-1999 Lucent Technologies, Inc. * *//* * Copyright (C) 1999 Francesco P. Lovergine. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions * are met: * 1. Redistributions of source code must retain the above copyright *    notice, and the entire permission notice in its entirety, *    including the disclaimer of warranties. * 2. Redistributions in binary form must reproduce the above copyright *    notice, this list of conditions and the following disclaimer in the *    documentation and/or other materials provided with the distribution. * 3. The name of the author may not be used to endorse or promote *    products derived from this software without specific prior *    written permission. * 4. Any modification to the program, as well as redistribution in binary *    or derived source form must be advertised to the author. * * THIS SOFTWARE IS PROVIDED `AS IS'' AND ANY EXPRESS OR IMPLIED * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE * DISCLAIMED.  IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, * INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES * (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR * SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, * STRICT LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) * ARISING IN ANY WAY OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED * OF THE POSSIBILITY OF SUCH DAMAGE. */#include "yard.h"				/* includes local md5.h */#include "global.h"#ifdef IPASS#ident	"@(#)$Name:  $:$Id: ipass.c,v 1.1.1.1.4.1 2004/08/02 18:40:07 flovergine Exp $"#include <ipassconf.h>#include <ipassgen.h>#ifdef HAVE_SYS_CDEFS_H# include <sys/cdefs.h>#endif#if HAVE_SYS_WAIT_H# include <sys/wait.h>#endif#ifndef WEXITSTATUS# define WEXITSTATUS(stat_val) ((unsigned)(stat_val) >> 8)#endif#ifndef WIFEXITED# define WIFEXITED(stat_val) (((stat_val) & 255) == 0)#endif#ifdef HAVE_MEMORY_H# include <memory.h>#endif#ifdef STDC_HEADERS# include <string.h>#else# ifndef HAVE_STRCHR#  define strchr index#  define strrchr rindex# endifchar *strchr(),*strrchr();# ifndef HAVE_MEMCPY#  define memcpy(d,s,n) bcopy((s),(d),(n))#  define memmove(d,s,n) bcopy((s),(d),(n))# endif#endif#include <arpa/inet.h>#include <arpa/nameser.h>#include <resolv.h>#define IPASS_REMOTE_ID_CHAR '@' struct sockaddr_in rad_addr,cli_addr;/* forward declarations */int ipassinit();int decode_passwd (char *, UINT4, char *, char *);void handle_response (int, AUTH_REQ *, ipinfo_t *, ipauth_t *, int, int);void dump_to_disk (char *, int, char *);int raddebug = 0;intipassinit( void ){	/* init iPass library */	return ipass_init(0, (char **) NULL, IPASS_PROGNM_AUTHD);}intrad_forw_ipass( AUTH_REQ *authreq,int radius_fd,char *buff ){	AUTH_HDR *auth;	ipinfo_t ipinfo;	ipauth_t ipauth;	ipacct_t ipacct;	char *ptr,*sptr, *p;	char ibuff[BUFSIZ];	char vector[16];	char passwd[128];	char user_name[IPASS_MAXNAMLEN+IPASS_MAXDOMLEN+1+1];	char nas_ip[(4*3)+3+1];	int attrvalue, i,j;	u_short length, attribute, attrlen;	int ret_code = 0;	time_t ttime;	auth = (AUTH_HDR*)buff;	ipinfo.service = IPASS_SERV_UNKNOWN; 	ipinfo.direction = IPASS_DIR_UNKNOWN;	ipinfo.nas_ses_id[0] = '\0';	ipauth.host_ip.s_addr = INADDR_ANY;	ipacct.user_ip.s_addr = INADDR_ANY;	ipacct.user_mask.s_addr = INADDR_ANY;	passwd[0] = '\0';	ipauth.passwd[0] = '\0';	switch(auth->code){		case PW_AUTHENTICATION_REQUEST:			trace("received authentication request, id: %d", auth->id);			break;		case PW_ACCOUNTING_REQUEST:			trace("received accounting request, id: %d", auth->id);			break;		default:			trace("received unknown request: %d", auth->code);			return;	}	ptr=&buff[4];	for (i=0;i<AUTH_VECTOR_LEN;i++)		vector[i] = *ptr++;	length=ntohs(auth->length);		ptr=&buff[0];	ptr+=AUTH_HDR_LEN;	length-=AUTH_HDR_LEN;/* now pointing at code of first data field */	if (raddebug){		dump_to_disk((char *)buff,(int)auth->length,"Request");	}	while (length > 2) {		attribute = *ptr++;		attrlen = *ptr++;		sptr=ptr;		if (attrlen < 2) {		/* malformed packet, can't do anything but quit */			length = 0;			continue;		}		if (attrlen == 2){		/*		   this is illegal, but one site who shall remain nameless 		   sends these packets all the time 		*/			length -= 2;			continue;		}		attrlen -= 2;		ptr+=attrlen-1;		attrvalue=*ptr++;		switch (attribute){			case PW_CLIENT_ID:				memcpy(&ipinfo.nas_ip, sptr, sizeof(UINT4));				sptr += 4;				break;			case PW_LOGIN_HOST:				memcpy(&ipauth.host_ip, sptr, sizeof(UINT4));				sptr += 4;				break;			case PW_PASSWORD:				for(i=0;i<attrlen;i++)					passwd[i]=*sptr++;				break;			case PW_CHAP_PASSWORD:				ipauth.chap_ident = *sptr++; /* get ident */				for(i=0;i<CHAP_VALUE_LENGTH;i++){					ipauth.chap_passwd[i]=*sptr++;					ipauth.chap_challenge[i]=vector[i];				}				break;			case PW_USER_NAME:				for(i=0;i<attrlen;i++)					user_name[i]=*sptr++;				user_name[i]='\0';				break;			case PW_FRAMED_PROTOCOL:				switch (attrvalue){					case PW_PPP:						ipinfo.service=IPASS_SERV_PPP;						break;					case PW_SLIP:						ipinfo.service=IPASS_SERV_SLIP;						break;					default:						break;				}				break;			case PW_FRAMED_ADDRESS: 				memcpy(&ipacct.user_ip, sptr, sizeof(UINT4));                                sptr += 4;				break;			case PW_FRAMED_NETMASK: 				memcpy(&ipacct.user_mask, sptr, sizeof(UINT4));                                sptr += 4;				break;			case PW_LOGIN_SERVICE:					switch (attrvalue){					case PW_TELNET:  						ipinfo.service=							IPASS_SERV_TELNET;  						break;					case PW_RLOGIN:						ipinfo.service=							IPASS_SERV_RLOGIN;						break;					default:						break;				}				break;			case PW_ACCT_SESSION_ID:				for (i=0;i<attrlen;i++)					ibuff[i]=*sptr++;				ibuff[i] = '\0';										strncpy(ipinfo.nas_ses_id, ibuff,					sizeof(ipinfo.nas_ses_id) - 1);			ipinfo.nas_ses_id[sizeof(ipinfo.nas_ses_id) - 1] = '\0';				break;			case PW_ACCT_STATUS_TYPE:				switch (attrvalue){				case PW_STATUS_START:					ipacct.acct_type = IPASS_ACCT_START;					break;				case PW_STATUS_STOP:					ipacct.acct_type = IPASS_ACCT_STOP;					break;				default:				trace("rad_forw_req: bad acct_status_type %d",					attrvalue);					return -1;				}				break;			case PW_CLIENT_PORT_ID:				ipinfo.nas_port = attrvalue; /* XXX ??? ntohl(attrvalue); */				break;			case PW_ACCT_SESSION_TIME:				ttime =  (*sptr++)<<24;				ttime |= (*sptr++)<<16;				ttime |= (*sptr++)<<8;				ttime |= (*sptr++);				ipacct.ses_len=ttime;				break;			default:				break;		}		length -= (attrlen + 2);	}        if ((p = strchr(user_name, IPASS_REMOTE_ID_CHAR)) == NULL) {		return -1;	}	if (ipass_setuserid(ipinfo.user_name,			    ipinfo.ipass_domain, user_name) == EOF)		return -1;	if (auth->code == PW_AUTHENTICATION_REQUEST){		if (passwd[0]) {			if (!decode_passwd(passwd, authreq->ipaddr,				   auth->vector, authreq->secret))				return -1;			strncpy(ipauth.passwd, passwd, 				sizeof(ipauth.passwd) - 1);			ipauth.passwd[sizeof(ipauth.passwd) - 1] = '\0';		}		ipass_remote_auth(&ipinfo, &ipauth);		if (ipauth.errcode != IPASS_STATUS_OK) {			trace("ipass_remote_auth: failed %d: %s",			      ipauth.errcode,			      ipauth.status ? ipauth.status : "<no-message>");			return -1;		}		ret_code = ipauth.auth_reply == IPASS_AUTH_OK ? 1 : 0;	}	else{		ipacct.ip = 0;		ipacct.op = 0;		ipacct.ic = 0;		ipacct.oc = 0;		ipass_remote_acct(&ipinfo, &ipacct);		if (ipacct.errcode != IPASS_STATUS_OK) {			trace("ipass_remote_acct: failed %d: %s",			      ipacct.errcode,			      ipacct.status ? ipacct.status : "<no-message>");			return -1;		}		ret_code = 1;	}	handle_response(radius_fd,authreq,		&ipinfo,&ipauth,auth->code,ret_code);	return 1;}/* handle_response - decode reply from ipass and send the return packet back to NAS*/voidhandle_response ( int radius_fd, AUTH_REQ *authreq, ipinfo_t *ipinfop, ipauth_t *ipauthp, int auth_code, int ret_code ){	AUTH_HDR *authreply;	int i;	char *ptr;	UINT4 lvalue;	u_short length;	unsigned char replybuff[4096];	unsigned char vector[AUTH_VECTOR_LEN];	struct sockaddr_in nas_addr;	authreply = (AUTH_HDR *)replybuff;	memset(replybuff,0,sizeof(replybuff));	/* start building reply packet */	authreply->id = authreq->id;	memcpy(authreply->vector,authreq->vector,AUTH_VECTOR_LEN);	length=AUTH_HDR_LEN;	authreply->code = PW_AUTHENTICATION_REJECT;	if (ret_code) {		ptr = (char *) authreply->data;		if (auth_code == PW_AUTHENTICATION_REQUEST) {			authreply->code = PW_AUTHENTICATION_ACK;			if ((ipauthp->serv_req == IPASS_SERV_RLOGIN)||			    (ipauthp->serv_req == IPASS_SERV_TELNET)||			    (ipauthp->serv_req == IPASS_SERV_PPP)||			    (ipauthp->serv_req == IPASS_SERV_SLIP)){				*ptr++ = PW_USER_SERVICE_TYPE;				*ptr = 6;				length += *ptr;				ptr += 4;				switch (ipauthp->serv_req) {				case IPASS_SERV_RLOGIN:				case IPASS_SERV_TELNET:					*ptr++ = PW_LOGIN_USER;					*ptr++ = PW_LOGIN_SERVICE;					*ptr = 6;					length += *ptr;					ptr += 4;					if (ipauthp->serv_req == IPASS_SERV_TELNET)						*ptr++ = PW_TELNET;					else						*ptr++ = PW_RLOGIN;					break;				case IPASS_SERV_PPP:				case IPASS_SERV_SLIP:					*ptr++ = PW_FRAMED_USER;					*ptr++ = PW_FRAMED_PROTOCOL;					*ptr = 6;					length += *ptr;					ptr += 4;					if (ipauthp->serv_req == IPASS_SERV_PPP)						*ptr++ = PW_PPP;					else						*ptr++ = PW_SLIP;					break;				}				if (ipauthp->host_ip.s_addr != INADDR_ANY) {					*ptr++ = PW_LOGIN_HOST; 					*ptr++ = sizeof(UINT4) + 2;					memcpy(ptr, &ipauthp->host_ip.s_addr, sizeof(UINT4));					ptr += sizeof(UINT4);					length += sizeof(UINT4) + 2;				}				if (ipauthp->host_port) {					*ptr++ = PW_LOGIN_TCP_PORT;					*ptr++ = sizeof(UINT4) + 2;					lvalue = htons(ipauthp->host_port);					memcpy(ptr, &lvalue, sizeof(UINT4));					ptr += sizeof(UINT4);					length += sizeof(UINT4) + 2;				}			}			else{			trace("unsupported iPass service request %d, ignored.",					      ipauthp->serv_req);			}		} else			authreply->code = PW_ACCOUNTING_RESPONSE;	}		authreply->length = htons(length);	memcpy(replybuff+length,authreq->secret,strlen(authreq->secret));	md5_calc(vector,replybuff,length+strlen(authreq->secret));	memcpy(authreply->vector,vector,AUTH_VECTOR_LEN);	/* don't need secret anymore, trash it from reply packet */	memset(replybuff+length,0,strlen(authreq->secret));	memset((char*) &nas_addr,0, sizeof(nas_addr));	nas_addr.sin_family      = AF_INET;	nas_addr.sin_addr.s_addr = htonl(authreq->ipaddr);	nas_addr.sin_port        = htons(authreq->udp_port);	if (sendto(radius_fd,(char*)replybuff,length,0,		(struct sockaddr*)&nas_addr,sizeof(nas_addr)) == -1) {		trace("remote sendto NAS %s failed, error %d",		      ipaddr2strp(ntohl(nas_addr.sin_addr.s_addr)), errno);	} else {		trace("remote sendto NAS %s okay",		      ipaddr2strp(ntohl(nas_addr.sin_addr.s_addr)));	}	if (raddebug) {		dump_to_disk((char *)replybuff,(int)length,"Reply");	}	return;}intdecode_passwd ( char *passwd, UINT4 ipaddr, char *vector, char *shared_secret ){	unsigned char md5obuf[256];	unsigned char md5ibuf[256];	int i,j;		for (i=0;i<strlen((char*)shared_secret);i++)		md5ibuf[i] = shared_secret[i];	for (j=0; i<AUTH_VECTOR_LEN+strlen((char*)shared_secret);i++,j++)		md5ibuf[i]=vector[j];	md5_calc(md5obuf,md5ibuf,AUTH_VECTOR_LEN+strlen((char*)shared_secret));	for(i = 0;i < AUTH_PASS_LEN;i++) {		passwd[i] ^= md5obuf[i];	}	passwd[i]='\0';	return(1);}/*	dump - display data at specified address*/voiddump_to_disk ( char *bp, int count, char *msg ){	int i,j, lines;	char ASC[17], *X2();	/**/	FILE *fp;	fp = fopen("/tmp/radlog","a");/**/	lines = count/16 + (count%16 != 0);	j=0;	fprintf(fp,"\n\n======== %s =======\n",msg);	while (lines-- > 0) {		fprintf(fp,"%3x  ",j);		j+=16;		for (i=0; i<16; i++,bp++,count--) {			if (count > 0) {				fprintf(fp,"%s ",X2(*bp));				ASC[i] = '.';				if (*bp >= ' ' && *bp <= '~') ASC[i] = *bp;				}			else {				fprintf(fp,"   ");				ASC[i] = ' ';				}			if (i == 7) fprintf(fp,"  ");			}		ASC[16] = 0;		fprintf(fp,"  *%s*\n",ASC);		}	/**/	fclose(fp);	/**/}char *X2 ( register int val ){	static char buff[3];	register int x;	x = (val>>4) & 0xf;	if (x >= 10)		x += 'A' - 10;	else		x+= '0';	buff[0] = (char) x;	x = val & 0xf;	if (x >= 10)		x += 'A' - 10;	else		x+= '0';	buff[1] = (char) x;	buff[2] = 0;	return(buff);}#if !defined(HAVE_STRERROR)/* * system has no strerror in standard libraries, so define our own */char *strerror(int err){	extern int sys_nerr;	extern char sys_errlist[];	static char *unknown = "unknown errno";	if (err < sys_nerr) {		return sys_errlist[err];	}	return unknown;}#endif#else /* IPASS *//* dummy entry points */intipassinit( void ) {	return 0;}intrad_forw_ipass( AUTH_REQ *authreq, int activefd, char *buffer ){	extern char	*progname;	char 		*req2strp();	log_err("%s: no ipass support, %s cannot be forwarded\n",		progname, req2strp(authreq));	return 0;}#endif /* IPASS */

⌨️ 快捷键说明

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