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; }
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; }