File:  [ELWIX - Embedded LightWeight unIX -] / embedaddon / coova-chilli / src / test-radius.c
Revision 1.1.1.1 (vendor branch): download - view: text, annotated - select for diffs - revision graph
Tue Feb 21 22:48:25 2012 UTC (12 years, 3 months ago) by misho
Branches: coova-chilli, MAIN
CVS tags: v1_0_12, HEAD
coova-chilli

/*
 * Copyright (c) 2006-2007 David Bird <david@coova.com>
 *
 */
#include "system.h"
#include "syserr.h"
#include "cmdline.h"
#include "dhcp.h"
#include "radius.h"
#include "radius_chillispot.h"
#include "radius_wispr.h"
#include "redir.h"
#include "chilli.h"
#include "options.h"

static int chilliauth_cb(struct radius_t *radius,
			 struct radius_packet_t *pack,
			 struct radius_packet_t *pack_req, void *cbp) {
  struct radius_attr_t *attr = NULL;
  /*char attrs[RADIUS_ATTR_VLEN+1];*/
  size_t offset = 0;
  
  if (!pack) { 
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Radius request timed out");
    return 0;
  }

  if ((pack->code != RADIUS_CODE_ACCESS_REJECT) && 
      (pack->code != RADIUS_CODE_ACCESS_CHALLENGE) &&
      (pack->code != RADIUS_CODE_ACCESS_ACCEPT)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, 
	    "Unknown radius access reply code %d", pack->code);
    return 0;
  }

  /* ACCESS-ACCEPT */
  if (pack->code != RADIUS_CODE_ACCESS_ACCEPT) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Administrative-User Login Failed");
    return 0;
  }

  while (!radius_getnextattr(pack, &attr, 
			     RADIUS_ATTR_VENDOR_SPECIFIC,
			     RADIUS_VENDOR_CHILLISPOT,
			     RADIUS_ATTR_CHILLISPOT_CONFIG, 
			     0, &offset)) {
    char value[RADIUS_ATTR_VLEN+1] = "";
    strncpy(value, (const char *)attr->v.t, attr->l - 2);
    printf("%s\n", value);
  }

  return 0;
  
}

int static test_radius() {
  struct radius_t *radius;
  struct radius_packet_t radius_pack;
  struct timeval idleTime;
  int starttime;
  int maxfd = 0;
  fd_set fds;
  int status;

  if (!options.adminuser || !options.adminpasswd) return 1;

  if (radius_new(&radius, &options.radiuslisten, 0, 0, NULL, 0, NULL, NULL, NULL)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, "Failed to create radius");
    return -1;
  }

  radius_set(radius, 0, (options.debug & DEBUG_RADIUS));

  radius_set_cb_auth_conf(radius, chilliauth_cb); 

  {int cnt=0; for (; cnt < RADIUS_QUEUESIZE * 2; cnt++) {

  if (radius_default_pack(radius, &radius_pack, RADIUS_CODE_ACCESS_REQUEST)) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, "radius_default_pack() failed");
    return -1;
  }
  
  radius_addattr(radius, &radius_pack, RADIUS_ATTR_USER_NAME, 0, 0, 0,
		 (uint8_t *)options.adminuser, strlen(options.adminuser));

  radius_addattr(radius, &radius_pack, RADIUS_ATTR_USER_PASSWORD, 0, 0, 0,
		 (uint8_t *)options.adminpasswd, strlen(options.adminpasswd));

  radius_addnasip(radius, &radius_pack);

  radius_addattr(radius, &radius_pack, RADIUS_ATTR_SERVICE_TYPE, 0, 0,
		 RADIUS_SERVICE_TYPE_ADMIN_USER, NULL, 0); 
  
  if (options.radiusnasid)
    radius_addattr(radius, &radius_pack, RADIUS_ATTR_NAS_IDENTIFIER, 0, 0, 0,
		   (uint8_t *)options.radiusnasid, strlen(options.radiusnasid));
  
  if (options.nasmac)
    radius_addattr(radius, &radius_pack, RADIUS_ATTR_CALLED_STATION_ID, 0, 0, 0,
		   (uint8_t *)options.nasmac, strlen(options.nasmac)); 

  radius_addattr(radius, &radius_pack, RADIUS_ATTR_NAS_PORT_TYPE, 0, 0,
		 options.radiusnasporttype, NULL, 0);

  if (options.radiuslocationid)
    radius_addattr(radius, &radius_pack, RADIUS_ATTR_VENDOR_SPECIFIC,
		   RADIUS_VENDOR_WISPR, RADIUS_ATTR_WISPR_LOCATION_ID, 0,
		   (uint8_t *)options.radiuslocationid, strlen(options.radiuslocationid));

  if (options.radiuslocationname)
    radius_addattr(radius, &radius_pack, RADIUS_ATTR_VENDOR_SPECIFIC,
		   RADIUS_VENDOR_WISPR, RADIUS_ATTR_WISPR_LOCATION_NAME, 0,
		   (uint8_t *)options.radiuslocationname, 
		   strlen(options.radiuslocationname));
  
  radius_addattr(radius, &radius_pack, RADIUS_ATTR_MESSAGE_AUTHENTICATOR, 
		 0, 0, 0, NULL, RADIUS_MD5LEN);

  radius_req(radius, &radius_pack, NULL); 

  if (radius->fd <= 0) {
    sys_err(LOG_ERR, __FILE__, __LINE__, 0, "not a valid socket!");
    return -1;
  } 

  maxfd = radius->fd;

  starttime = time(NULL);
  while ((starttime + REDIR_RADIUS_MAX_TIME) > time(NULL)) {
    FD_ZERO(&fds);
    FD_SET(radius->fd, &fds);
    
    idleTime.tv_sec = 0;
    idleTime.tv_usec = REDIR_RADIUS_SELECT_TIME;
    radius_timeleft(radius, &idleTime);

    switch (status = select(maxfd + 1, &fds, NULL, NULL, &idleTime)) {
    case -1:
      sys_err(LOG_ERR, __FILE__, __LINE__, errno, "select() returned -1!");
      break;  
    case 0:
      radius_timeout(radius);
    default:
      break;
    }

    if (status > 0) {
      if (FD_ISSET(radius->fd, &fds)) {
	if (radius_decaps(radius) < 0) {
	  sys_err(LOG_ERR, __FILE__, __LINE__, 0, "radius_ind() failed!");
	}
	break;
      }
    }
  }  

   }};

  radius_free(radius);
  return 0;
}

int main(int argc, char **argv)
{
  if (process_options(argc, argv, 1))
    exit(1);
  
  return test_radius();
}

FreeBSD-CVSweb <freebsd-cvsweb@FreeBSD.org>