Esempio n. 1
0
int main(int argc, char **argv) {
  struct radius_packet_t radius_pack;
  struct in_addr radiuslisten;

  struct timeval timeout;

  int maxfd = 0;
  fd_set fdread;
  fd_set fdwrite;
  fd_set fdexcep;

  ssize_t status;

  int keep_going = 1;
  int reload_config = 1;

  int selfpipe;

  options_init();

  selfpipe = selfpipe_init();

  chilli_signals(&keep_going, &reload_config);

  process_options(argc, argv, 1);

  radiuslisten.s_addr = htonl(INADDR_ANY);

  memset(&server, 0, sizeof(server));

  if (!(server.env = initssl_cli())) {
    syslog(LOG_ERR, "Failed to create ssl environment");
    return -1;
  }

  if (radius_new(&server.radius_auth, &radiuslisten,
		 _options.radiusauthport ? _options.radiusauthport : RADIUS_AUTHPORT,
		 0, 0)) {
    syslog(LOG_ERR, "Failed to create radius");
    return -1;
  }

  if (radius_new(&server.radius_acct, &radiuslisten,
		 _options.radiusacctport ? _options.radiusacctport : RADIUS_ACCTPORT,
		 0, 0)) {
    syslog(LOG_ERR, "Failed to create radius");
    return -1;
  }

  if (_options.coaport) {
    if (radius_new(&server.radius_cli, &radiuslisten, 0, 0, 0) ||
	radius_init_q(server.radius_cli, 8)) {
      syslog(LOG_ERR, "Failed to create radius");
      return -1;
    }
    radius_set(server.radius_cli, 0, 0);
    radius_set_cb_auth_conf(server.radius_cli, cb_radius_auth_conf);
  }

  radius_set(server.radius_auth, 0, 0);
  radius_set(server.radius_acct, 0, 0);

  if (_options.gid && setgid(_options.gid)) {
    syslog(LOG_ERR, "%d setgid(%d) failed while running with gid = %d\n",
           errno, _options.gid, getgid());
  }

  if (_options.uid && setuid(_options.uid)) {
    syslog(LOG_ERR, "%d setuid(%d) failed while running with uid = %d\n",
           errno, _options.uid, getuid());
  }

  while (keep_going) {

    if (reload_config) {
      reload_options(argc, argv);
      reload_config = 0;
    }

    FD_ZERO(&fdread);
    FD_ZERO(&fdwrite);
    FD_ZERO(&fdexcep);

    FD_SET(selfpipe, &fdread);
    FD_SET(server.radius_auth->fd, &fdread);
    FD_SET(server.radius_acct->fd, &fdread);

    if (server.radius_auth->fd > maxfd)
      maxfd = server.radius_auth->fd;

    if (server.radius_acct->fd > maxfd)
      maxfd = server.radius_acct->fd;

    if (server.conn.sock) {
      FD_SET(server.conn.sock, &fdread);
      if (server.conn.sock > maxfd)
	maxfd = server.conn.sock;
    }

    if (server.radius_cli) {
      FD_SET(server.radius_cli->fd, &fdread);
      if (server.radius_cli->fd > maxfd)
	maxfd = server.radius_cli->fd;
    }

    timeout.tv_sec = 1;
    timeout.tv_usec = 0;

    status = select(maxfd + 1, &fdread, &fdwrite, &fdexcep, &timeout);

    switch (status) {
      case -1:
        if (errno != EINTR)
          syslog(LOG_ERR, "%s: select() returned -1!", strerror(errno));
        break;

      case 0:
      default:
        if (status > 0) {
          struct sockaddr_in addr;
          socklen_t fromlen = sizeof(addr);

          if (FD_ISSET(selfpipe, &fdread)) {
            chilli_handle_signal(0, 0);
          }

          if (FD_ISSET(server.radius_auth->fd, &fdread)) {
            /*
             *    ---> Authentication
             */

            if ((status = recvfrom(server.radius_auth->fd, &radius_pack, sizeof(radius_pack), 0,
                                   (struct sockaddr *) &addr, &fromlen)) <= 0) {
              syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno));

              return -1;
            }

            memcpy(&server.auth_peer, &addr, sizeof(addr));

            process_radius(&radius_pack, status);
          }

          if (FD_ISSET(server.radius_acct->fd, &fdread)) {
            /*
             *    ---> Accounting
             */

            syslog(LOG_DEBUG, "received accounting");

            if ((status = recvfrom(server.radius_acct->fd, &radius_pack, sizeof(radius_pack), 0,
                                   (struct sockaddr *) &addr, &fromlen)) <= 0) {
              syslog(LOG_ERR, "%s: recvfrom() failed", strerror(errno));
              return -1;
            }

            memcpy(&server.acct_peer, &addr, sizeof(addr));

            process_radius(&radius_pack, status);
          }

          if (server.radius_cli) {
            if (FD_ISSET(server.radius_cli->fd, &fdread)) {
              radius_decaps(server.radius_cli, 0);
            }
          }

          if (server.conn.sock) {
            if (FD_ISSET(server.conn.sock, &fdread)) {
              process_radius_reply();
            }
          }
        }

        break;
    }
  }

  selfpipe_finish();

  return 0;
}
Esempio n. 2
0
void SimpleDynamics::radius_set_op(Machine* machine) {
  radius_set(machine->stack.peek(0).asNumber());
}
int static chilliauth() {
  unsigned char hwaddr[6];
  struct radius_t *radius=0;
  struct timeval idleTime;
  int endtime, now;
  int maxfd = 0;
  fd_set fds;
  int status;
  int ret=-1;

  if (!_options.adminuser || !_options.adminpasswd) {
    log_err(0, "Must be used with --adminuser and --adminpasswd");
    return 1;
  }

  if (radius_new(&radius, &_options.radiuslisten, 0, 0, 0) ||
      radius_init_q(radius, 4)) {
    log_err(0, "Failed to create radius");
    return ret;
  }

  /* get dhcpif mac */
  memset(hwaddr, 0, sizeof(hwaddr));

#ifdef SIOCGIFHWADDR
  if (!_options.nasmac && _options.dhcpif) {
    struct ifreq ifr;
    int fd;
    if ((fd = socket(AF_INET, SOCK_DGRAM, 0)) >= 0) {
      memset(&ifr, 0, sizeof(ifr));
      safe_strncpy(ifr.ifr_name, _options.dhcpif, IFNAMSIZ);
      if (ioctl(fd, SIOCGIFHWADDR, &ifr) < 0) {
	log_err(errno, "ioctl(d=%d, request=%d) failed", fd, SIOCGIFHWADDR);
      }
      memcpy(hwaddr, ifr.ifr_hwaddr.sa_data, PKT_ETH_ALEN);
      close(fd);
    }
  }
#endif

  radius_set(radius, hwaddr, (_options.debug & DEBUG_RADIUS));
  radius_set_cb_auth_conf(radius, chilliauth_cb); 

  ret = chilli_auth_radius(radius);

  if (radius->fd <= 0) {
    log_err(0, "not a valid socket!");
    return ret;
  } 

  maxfd = radius->fd;

  now = time(NULL);
  endtime = now + ADMIN_TIMEOUT; 

  while (endtime > now) {

    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:
      log_err(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) < 0) {
	  log_err(0, "radius_ind() failed!");
	}
	else {
	  ret = 0;
	}
	break;
      }
    }

    now = time(NULL);
  }  

  radius_free(radius);
  return ret;
}