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

📄 radiusd.c

📁 This program is a RADIUS RFC-compliant daemon, which is derived from original Livingston Enterprise
💻 C
📖 第 1 页 / 共 5 页
字号:
  int		passlen;  char		*hold_vector;  char		pw_digest[16];  char		*string;  char		*ptr;  calc_digest((u_char*)pw_digest, authreq, (u_char*)secret);  /*   * Decrypt the password in the request.   */  if((auth_item = get_attribute(authreq->request,  			PW_PASSWORD)) == (VALUE_PAIR *)NULL) {  	return (char *)NULL;  }  passlen = auth_item->lvalue;  if(passlen > AUTH_MAXPASS_LEN) {  	log_err("encrypt_password: Password length %d > %d not allowed, truncating\n",passlen, AUTH_MAXPASS_LEN);  	passlen = AUTH_MAXPASS_LEN;  	auth_item->lvalue = AUTH_MAXPASS_LEN;  	auth_item->strvalue[AUTH_MAXPASS_LEN] = '\0';  }  string = auth_item->strvalue;  ptr = string;  for(i = 0;i < passlen;i += AUTH_PASS_LEN) {  	/* Encrypt using the digest */  	hold_vector = ptr;  	for(j = 0;j < AUTH_PASS_LEN;j++) {  		*ptr ^= pw_digest[j];  		ptr++;  	}  	/* Calculate the next digest if necessary */  	if(i < passlen) {  		calc_next_digest((u_char*)pw_digest, (u_char*)secret, (u_char*)hold_vector);  	}  }  *ptr = '\0';	/* this depends on the fact that auth_item->strvalue  			always has an extra byte available */  return string;}/*************************************************************************  *  *	Function: calc_digest  *  *	Purpose: Validates the requesting client NAS.  Calculates the  *		 digest to be used for decrypting the users password  *		 based on the clients private key.  *  *************************************************************************/void calc_digest(u_char *digest,AUTH_REQ *authreq,u_char *secret){  u_char	buffer[128];  int	secretlen;  /* Use the secret to setup the decryption digest */  memset(buffer, 0, sizeof(buffer));  secretlen = strlen((char *)secret);  memcpy((char *)buffer, (char *)secret,secretlen);  memcpy(buffer + secretlen, authreq->vector, AUTH_VECTOR_LEN);  md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN);  memset(buffer, 0, secretlen+AUTH_VECTOR_LEN);  return;}/*************************************************************************  *  *	Function: calc_next_digest  *  *	Purpose: Calculates the digest to be used for decrypting the   *	users password past the first 16 octets based on the clients  *	private key.  *  *************************************************************************/void calc_next_digest(u_char*digest,u_char*secret,u_char*vector){  u_char	buffer[128];  int	secretlen;  /* Use the secret to setup the decryption digest */  memset(buffer, 0, sizeof(buffer));  secretlen = strlen((const char *)secret);  strcpy((char *)buffer, (const char *)secret);  memcpy(buffer + secretlen, vector, AUTH_VECTOR_LEN);  md5_calc(digest, buffer, secretlen + AUTH_VECTOR_LEN);  memset(buffer, 0, sizeof(buffer));}/*************************************************************************  *  *	Function: client_hostname  *  *	Purpose: Return the cached client name if we have one.  Otherwise  *		 use the regular ip_hostname() function.  *  *************************************************************************/char* client_hostname(UINT4 ipaddr){  u_char secret[64];  char	hostnm[MAX_HOST_SIZE];  /* Look at the last used entry first */  if(ipaddr == cached_ipaddr) {  	return(cached_hostnm);  }  if(find_client(ipaddr, secret, sizeof(secret), hostnm, sizeof(hostnm)) != 0) {  	memset(secret, 0, sizeof(secret));  	return(cached_hostnm);	/* set by find_client() */  }  return(ip_hostname(ipaddr));}/*************************************************************************  *  *	Function: find_client  *  *	Purpose: Retrieve the client name and secret from the temporary  *		 DBM client database.  *  *************************************************************************/int find_client(UINT4 ipaddr,char*secret,int secretlen,char*hostnm,size_t hostnmlen){  GDBM_FILE       db;  char		buffer[MAX_LINE_SIZE];  char		ip_str[32];  datum		contentd;  datum		named;  int		ret;  char		fmt[16];  if (snprintf(fmt,sizeof(fmt), "%%%ds%%%ds", secretlen, hostnmlen)>=sizeof(fmt)) {    log_err("format too long\n");    return(-1);  }    /* Find the client in the database */  snprintf((char *)buffer,sizeof(buffer),"%s/%s", radius_dir,            RADIUS_CLIENT_CACHE);  if ((db = gdbm_open(buffer,0,GDBM_READER,0600,NULL )) == NULL)           {    log_err("could not read %s to find clients\n", buffer);    return(-1);    }  ipaddr2str(ip_str, sizeof(ip_str), ipaddr);  named.dptr = ip_str;  named.dsize = strlen(ip_str);  contentd = gdbm_fetch(db, named);  if(contentd.dsize == 0 || contentd.dptr == NULL) {  	gdbm_close(db);         	log_err("client %s not found in client cache\n",ip_str);  	if (contentd.dptr!=NULL) free(contentd.dptr);  	return(-1);  }  if (contentd.dsize >= MAX_LINE_SIZE) {  	gdbm_close(db);  	log_err("client %s length %d > %d in client cache\n", ip_str,  		contentd.dsize, MAX_LINE_SIZE-1);  	free(contentd.dptr);  	return(-1);  }  /* convoluted method of working around Solaris x86 2.5 bug */         memcpy(buffer,contentd.dptr,contentd.dsize-1);  buffer[contentd.dsize - 1] = '\n';  buffer[contentd.dsize] = '\0';  if((ret=sscanf((const char *)buffer, fmt, hostnm, secret)) != 2) {  	gdbm_close(db);  	log_err("client cache entry for %s could not be parsed (%d)\n", ip_str,ret);  	free(contentd.dptr);  	return(-1);  }  /* Build a cached hostname entry for client_hostname() to use */  strncpy(cached_hostnm, hostnm, MAX_HOST_SIZE);  cached_hostnm[MAX_HOST_SIZE-1] = '\0';  cached_ipaddr = ipaddr;  gdbm_close(db);  free(contentd.dptr);  return(0);}/*************************************************************************  *  *	Function: update_clients  *  *	Purpose: Check last modified time on clients file and build a  *		 new temporary DBM client database if the file has been  *		 changed.  *  *************************************************************************/int update_clients(void){  static time_t	last_update_time;  struct stat 	statbuf;  struct stat 	statbuf2;  datum		named;  datum		contentd;     	GDBM_FILE   	db;  FILE		*clientfd;  u_char		buffer[256];  u_char		oldcache[256];  u_char		newcache[256];  u_char		secret[64];  char		hostnm[128];  char		ip_str[64];  int		nclients;  int		rcode;  int		s1;  int		s2;  UINT4		ipaddr;  nclients = 0;  rcode = 0;  /* Check last modified time of clients file */  snprintf((char *)buffer,sizeof(buffer),"%s/%s", radius_dir, RADIUS_CLIENTS);  if(stat(buffer, &statbuf) != 0) {  	log_err("Error: clients file %s not found\n", buffer);  	return(-1);  }  if(statbuf.st_mtime == last_update_time) {  	/* nothing to update */  	return(0);  }  cached_ipaddr = 0;  /* Open the standard clients file */  if((clientfd = fopen((const char *)buffer, "r")) == (FILE *)NULL) {  	log_err("Error: could not read clients file %s\n", buffer);  	return(-1);  }  /* Open and truncate the clients DBM cache file */  snprintf((char *)oldcache,sizeof(oldcache),"%s/%s", radius_dir, RADIUS_CLIENT_CACHE);  snprintf((char *)newcache,sizeof(oldcache),"%s.lock", oldcache);     	if((db=gdbm_open(newcache,0,GDBM_NEWDB,0600,NULL)) == NULL) {         	log_err("Error: could not create temporary client cache file %s\n",newcache);         return(-1);     }  while(fgets((char *)buffer, sizeof(buffer), clientfd)  					!= (char *)NULL) {  	if(*buffer == '#') {  		continue;  	}  	if(sscanf((const char *)buffer, "%s%s", hostnm, secret) != 2) {  		continue;  	}  	if((ipaddr = get_ipaddr(hostnm)) != (UINT4)0) {  		ipaddr2str(ip_str, sizeof(ip_str), ipaddr);  		named.dptr = ip_str;  		named.dsize = strlen(ip_str);  		contentd.dptr = (char *)buffer;  		contentd.dsize = strlen(buffer);  		if(gdbm_store(db, named, contentd, GDBM_INSERT) != 0) {  			log_err("could not cache client datum for host %s\n", hostnm);  			rcode = -1;  		} else {  			nclients++;  		}  	}  }  gdbm_close(db);  fclose(clientfd);     	if (rename(newcache,oldcache) != 0) {             log_err("Error: could not move client cache file %s to %s,"                     "error %d\n",newcache,oldcache,errno);             return(-1);     	} else { debug("updated client cache with %d clients\n",nclients); }  if (rcode == 0) last_update_time = statbuf.st_mtime;  return(rcode);}/*************************************************************************  *  *	Function: debug_pair  *  *	Purpose: Print the Attribute-value pair to the desired File.  *  *************************************************************************/void debug_pair(VALUE_PAIR * pair){  if(debug_flag) { fprint_attr_val(stdout, pair); }}/*************************************************************************  *  *	Function: usage  *  *	Purpose: Display the syntax for starting this program.  *  *************************************************************************/void usage(void){  fprintf(stderr, "Usage: %s\n", progname);  fprintf(stderr, " [-a <acct_dir>] set accounting directory\n");  fprintf(stderr, " [-b] use GDBM for users file\n");  fprintf(stderr, " [-c] clear user stats database\n");  fprintf(stderr, " [-d <db_dir>] set radiusd database directory\n");  fprintf(stderr, " [-h] print this usage\n");  fprintf(stderr, " [-f <alt_passwd_file>] set alternate password file\n");  fprintf(stderr, " [-i <ip_address>] set alternate IP\n");  fprintf(stderr, " [-l <log_file>] set radius log file\n");  fprintf(stderr, " [-o] accept all-zero accounting requests authenticator\n");  fprintf(stderr, " [-p <udp_port>] set alternate radius port number\n");  fprintf(stderr, " [-q <max outstanding requests>] set incoming packets queue size\n");  fprintf(stderr, " [-s] do fork\n");  fprintf(stderr, " [-t <max seconds in queue>] set time out for requests queue\n");  fprintf(stderr, " [-v] print version\n");  fprintf(stderr, " [-w <max seconds for proxy>] set time out for proxy requests\n");  fprintf(stderr, " [-x] set debug mode on\n");#if defined(PAM)  fprintf(stderr, " [-P] set PAM auth mode on\n");  fprintf(stderr, " [-A] set PAM acct mode on\n");#endif  fprintf(stderr, " [-z] as -b -x -d . -a ra\n\n");  exit(-1);}/*************************************************************************  *  *	Function: config_init  *  *	Purpose: intializes configuration values  *  *		 expiration_seconds - When updating a user password,  *			the amount of time to add to the current time  *			to set the time when the password will expire.  *			This is stored as the VALUE Password-Expiration  *			in the dictionary as number of days.  *  *		warning_seconds - When acknowledging a user authentication  *			time remaining for valid password to notify user  *			of password expiration.  *  *************************************************************************/int config_init(void){  DICT_VALUE	*dval;  DICT_VALUE	*dict_valfind();  if((dval = dict_valfind("Password-Expiration")) == (DICT_VALUE *)NULL) {  	expiration_seconds = (UINT4)0;  }  else {  	expiration_seconds = dval->value * (UINT4)SECONDS_PER_DAY;  }  if((dval = dict_valfind("Password-Warning")) == (DICT_VALUE *)NULL) {  	warning_seconds = (UINT4)0;  }  else {  	warning_seconds = dval->value * (UINT4)SECONDS_PER_DAY;  }  strcpy(unknown,"unknown");	/* for client caching error return */  return(0);}/*************************************************************************  *  *	Function: set_expiration  *  *	Purpose: Set the new expiration time by updating or adding  	 the Expiration attribute-value pair.  *  *************************************************************************/int set_expiration(VALUE_PAIR*user_check,UINT4 expiration){  VALUE_PAIR	*exppair;  VALUE_PAIR	*prev;  struct timeval	tp;  struct timezone	tzp;  if(user_check == (VALUE_PAIR *)NULL) {  	return(-1);  }  /* Look for an existing expiration entry */  exppair = user_check;  prev = (VALUE_PAIR *)NULL;  while(exppair != (VALUE_PAIR *)NULL) {  	if(exppair->attribute == PW_EXPIRATION) {  		break;  	}  	prev = exppair;  	exppair = exppair->next;  }  if(exppair == (VALUE_PAIR *)NULL) {  	/* Add a new attr-value pair */  	exppair = pairalloc("set_expiration");    	/* Initialize it */  	strcpy(exppair->name, "Expiration");  	exppair->attribute = PW_EXPIRATION;  	exppair->type = PW_TYPE_DATE;  	/* Attach it to the list. */  	prev->next = exppair;  }  /* calculate a new expiration */  gettimeofday(&tp, &tzp);  exppair->lvalue = tp.tv_sec + expiration;  return(0);}/*************************************************************************  *  *	Function: pw_expired  *  *	Purpose: Tests to see if the users password has expired.  *  *	Return: Number of days before expiration if a warning is required  *		otherwise 0 for success and -1 for failure.  *  *************************************************************************/int pw_expired(UINT4 exptime){  struct timeval	tp;  struct timezone	tzp;  UINT4		exp_remain;  int		exp_remain_int;  if(expiration_seconds == (UINT4)0) {	/* expiration not enabled */  	return(0);  }  gettimeofday(&tp, &tzp);  if(tp.tv_sec > exptime) {  	return(-1);  }  if(warning_seconds != (UINT4)0) {  	if(tp.tv_sec > exptime - warning_seconds) {  		exp_remain = exptime - tp.tv_sec;  		exp_remain /= (UINT4)SECONDS_PER_DAY;  		exp_remain_int = exp_remain;  		return(exp_remain_int);  	}  }  return(0);}/*************************************************************************  *  *	Function: get_attribute  *  *	Purpose: Retrieve a specific value-pair from a list of value-pairs.  *  *************************************************************************/VALUE_PAIR* get_attribute(VALUE_PAIR*v

⌨️ 快捷键说明

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