Beispiel #1
0
int rc_acct_proxy(VALUE_PAIR *send)
{
	SEND_DATA       data;
	int		result;
	char		msg[4096];
	int		i;
	SERVER		*acctserver = rc_conf_srv("authserver");
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	result = ERROR_RC;
	for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
			    acctserver->port[i], timeout, retries);

		result = rc_send_server (&data, msg, NULL);
	}

	rc_avpair_free(data.receive_pairs);

	return result;
}
Beispiel #2
0
int rc_check(char *host, unsigned short port, char *msg)
{
	SEND_DATA       data;
	int		result;
	UINT4		service_type;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier,
         * although it isn't neccessary
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in Service-Type
	 */

	service_type = PW_ADMINISTRATIVE;
	rc_avpair_add(&(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, VENDOR_NONE);

	rc_buildreq(&data, PW_STATUS_SERVER, host, port, timeout, retries);
	result = rc_send_server (&data, msg, NULL);

	rc_avpair_free(data.receive_pairs);

	return result;
}
Beispiel #3
0
/** Asks the server hostname on the specified port for a status message
 *
 * @param rh a handle to parsed configuration.
 * @param host the name of the server.
 * @param secret the secret used by the server.
 * @param port the server's port number.
 * @param msg must be an array of PW_MAX_MSG_SIZE or NULL; will contain the concatenation of any
 *	PW_REPLY_MESSAGE received.
 * @return OK_RC (0) on success, negative on failure as return value.
 */
int rc_check(rc_handle *rh, char *host, char *secret, unsigned short port, char *msg)
{
	SEND_DATA       data;
	int		result;
	uint32_t	service_type;
	int		timeout = rc_conf_int(rh, "radius_timeout");
	int		retries = rc_conf_int(rh, "radius_retries");
	rc_type		type;

	data.send_pairs = data.receive_pairs = NULL;

	if (rh->so_type == RC_SOCKET_TLS || rh->so_type == RC_SOCKET_DTLS)
		type = AUTH;
	else
		type = ACCT;

	/*
	 * Fill in Service-Type
	 */

	service_type = PW_ADMINISTRATIVE;
	rc_avpair_add(rh, &(data.send_pairs), PW_SERVICE_TYPE, &service_type, 0, 0);

	rc_buildreq(rh, &data, PW_STATUS_SERVER, host, port, secret, timeout, retries);
	result = rc_send_server (rh, &data, msg, type);

	rc_avpair_free(data.receive_pairs);

	return result;
}
Beispiel #4
0
int rc_acct_using_server(SERVER *acctserver,
			 UINT4 client_port,
			 VALUE_PAIR *send)
{
	SEND_DATA       data;
	VALUE_PAIR	*adt_vp;
	int		result;
	time_t		start_time, dtime;
	char		msg[4096];
	int		i;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in NAS-Port
	 */

	if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL)
		return (ERROR_RC);

	/*
	 * Fill in Acct-Delay-Time
	 */

	dtime = 0;
	if ((adt_vp = rc_avpair_add(&(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, VENDOR_NONE)) == NULL)
		return (ERROR_RC);

	start_time = time(NULL);
	result = ERROR_RC;
	for(i=0; (i<acctserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCOUNTING_REQUEST, acctserver->name[i],
			    acctserver->port[i], timeout, retries);

		dtime = time(NULL) - start_time;
		rc_avpair_assign(adt_vp, &dtime, 0);

		result = rc_send_server (&data, msg, NULL);
	}

	rc_avpair_free(data.receive_pairs);

	return result;
}
Beispiel #5
0
static RETSIGTYPE
alarm_handler(int sn)
{
	fprintf(stderr, SC_TIMEOUT, rc_conf_int("login_timeout"));
	sleep(1);
	exit(ERROR_RC);	
}
Beispiel #6
0
int rc_auth_using_server(SERVER *authserver,
			 UINT4 client_port,
			 VALUE_PAIR *send,
			 VALUE_PAIR **received,
			 char *msg, REQUEST_INFO *info)
{
	SEND_DATA       data;
	int		result;
	int		i;
	int		timeout = rc_conf_int("radius_timeout");
	int		retries = rc_conf_int("radius_retries");

	data.send_pairs = send;
	data.receive_pairs = NULL;

	/*
	 * Fill in NAS-IP-Address or NAS-Identifier
	 */

	if (rc_get_nas_id(&(data.send_pairs)) == ERROR_RC)
	    return (ERROR_RC);

	/*
	 * Fill in NAS-Port
	 */

	if (rc_avpair_add(&(data.send_pairs), PW_NAS_PORT, &client_port, 0, VENDOR_NONE) == NULL)
		return (ERROR_RC);

	result = ERROR_RC;
	for(i=0; (i<authserver->max) && (result != OK_RC) && (result != BADRESP_RC)
		; i++)
	{
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(&data, PW_ACCESS_REQUEST, authserver->name[i],
			    authserver->port[i], timeout, retries);

		result = rc_send_server (&data, msg, info);
	}

	*received = data.receive_pairs;

	return result;
}
Beispiel #7
0
/** Tests the configuration the user supplied
 *
 * @param rh a handle to parsed configuration.
 * @param filename a name of a configuration file.
 * @return 0 on success, -1 when failure.
 */
int rc_test_config(rc_handle *rh, char const *filename)
{
	SERVER *srv;

	srv = rc_conf_srv(rh, "authserver");
	if (!srv || !srv->max)
	{
		rc_log(LOG_ERR,"%s: no authserver specified", filename);
		return -1;
	}

	srv = rc_conf_srv(rh, "acctserver");
	if (!srv || !srv->max)
	{
		/* it is allowed not to have acct servers */
		if (rh->so_type != RC_SOCKET_TLS && rh->so_type != RC_SOCKET_DTLS)
			rc_log(LOG_DEBUG,"%s: no acctserver specified", filename);
	}
	if (!rc_conf_str(rh, "dictionary"))
	{
		rc_log(LOG_ERR,"%s: no dictionary specified", filename);
		return -1;
	}

	if (rc_conf_int(rh, "radius_timeout") <= 0)
	{
		rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename);
		return -1;
	}
	if (rc_conf_int(rh, "radius_retries") <= 0)
	{
		rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename);
		return -1;
	}

	if (apply_config(rh) == -1) {
		return -1;
	}

	return 0;
}
Beispiel #8
0
int
main (int argc, char **argv)
{
	char		username[128];
	char		passwd[AUTH_PASS_LEN + 1];
	int 		tries, remaining, c;
	UINT4		client_port;
	void 		(*login_func)(char *);	
	FILE		*fp;
	char 		buf[4096];
	char		tty[1024], *p;
	int		noissue = 0;
	int		maxtries = 0;
	char		*ttyn  = NULL;
	char            *path_radiusclient_conf = RC_CONFIG_FILE;

        extern char *optarg;
        extern int optind;

	pname = (pname = strrchr(argv[0],'/'))?pname+1:argv[0];
	
	rc_openlog(pname);

	while ((c = getopt(argc,argv,"f:m:i:nhV")) > 0)
	{
		switch(c) {
			case 'f':
				path_radiusclient_conf = optarg;
				break;
			case 'i':
				ttyn = optarg;
				break;
			case 'n':
				noissue = 1;
				break;
			case 'm':
				maxtries = atoi(optarg);
				break;
			case 'V':
				version();
				break;
			case 'h':
				usage();
				break;
			default:
				exit(ERROR_RC);
				break;
		}
	}

	if (rc_read_config(path_radiusclient_conf) != 0)
		exit(ERROR_RC);
	
	if (rc_read_dictionary(rc_conf_str("dictionary")) != 0)
		exit (ERROR_RC);

	if (rc_read_mapfile(rc_conf_str("mapfile")) != 0)
		exit (ERROR_RC);

	if (ttyn != NULL)
	{
		client_port = rc_map2id(ttyn);
		
		if ((p = strrchr(ttyn, '/')) == NULL)
			strncpy(tty, ttyn, sizeof(tty));
		else
			strncpy(tty, p+1, sizeof(tty));
	}
	else
	{
		ttyn = ttyname(0);
		if (ttyn)
		{
			if ((p = strrchr(ttyn, '/')) == NULL)
				strncpy(tty, ttyn, sizeof(tty));
			else
				strncpy(tty, p+1, sizeof(tty));

			client_port = rc_map2id(ttyn);
		}
		else 
		{
			*tty = '\0';
			client_port = 0;
		}
	}

#ifdef SETVBUF_REVERSED
	setvbuf(stdout, _IONBF, NULL, 0);
#else
	setvbuf(stdout, NULL, _IONBF, 0);
#endif

	if ((argc - optind) == 1)
	{
		strncpy(username,argv[optind], sizeof(username));
	}
	else
	{
		*username = '******';
		
		if (!noissue) {
			if (rc_conf_str("issue") && ((fp = fopen(rc_conf_str("issue"), "r")) != NULL))
			{
				while (fgets(buf, sizeof(buf), fp) != NULL)
					fputs(subst_placeholders(buf, tty), stdout);

				fflush(stdout);
				fclose(fp);
			} else {
				fputs(subst_placeholders(SC_DEFAULT_ISSUE, tty), stdout);
				fflush(stdout);
			}
		}
	}

	if ((env = rc_new_env(ENV_SIZE)) == NULL)
	{
		rc_log(LOG_CRIT, "rc_new_env: FATAL: out of memory");
		abort();
	}
	
#ifdef SECURITY_DISABLED
	if (rc_import_env(env,environ) < 0)
	{
		rc_log(LOG_CRIT, "rc_import_env: FATAL: not enough space for environment (increase ENV_SIZE)");
		abort();
	}
#else
	rc_add_env(env, "IFS", " ");
	rc_add_env(env, "PATH", RC_SECURE_PATH);
#endif

	signal(SIGALRM, alarm_handler);

	remaining = rc_conf_int("login_timeout");
	
	if (!maxtries)
		maxtries = rc_conf_int("login_tries");
		
	tries = 1;
	while (tries <= maxtries)
	{
	 alarm(remaining);

	 while (!*username) {
	 	p = rc_getstr (SC_LOGIN, 1);
	 	if (p)
	 		strncpy(username, p, sizeof(username));
	 	else
	 		exit (ERROR_RC);
	 }
	 p = rc_getstr(SC_PASSWORD,0);
	 if (p) 
	 	strncpy (passwd, p, sizeof (passwd));		
	 else 
		exit (ERROR_RC);

	 remaining = alarm(0);
	 
	 login_func = NULL;

 	 if (rc_conf_int("auth_order") & AUTH_LOCAL_FST)
 	 {
 	 	login_func = auth_local(username, passwd);
 	 		
 	 	if (!login_func)
 	 		if (rc_conf_int("auth_order") & AUTH_RADIUS_SND)
 	 			login_func = auth_radius(client_port, username, passwd);
 	 }
 	 else
 	 {
		login_func = auth_radius(client_port, username, passwd);
 	 	if (!login_func)
 	 		if (rc_conf_int("auth_order") & AUTH_LOCAL_SND)
 	 			login_func = auth_local(username, passwd);
 	 }

	 memset(passwd, '\0', sizeof(passwd));

	 if (login_func != NULL)
	 	if (login_allowed(tty)) {
	 		(*login_func)(username);
		} else {
			sleep(1);
			exit (ERROR_RC);
		}

	 *username = '******';
	 
	 if ((++tries) <= maxtries) {
		alarm(remaining);
	 	sleep(tries * 2);
	 	remaining = alarm(0);
	 }

	}

	fprintf(stderr, SC_EXCEEDED);
	sleep(1);
	
	exit (ERROR_RC);
}
Beispiel #9
0
static int test_config(char *filename)
{
#if 0
	struct stat st;
	char	    *file;
#endif

	if (!(rc_conf_srv("authserver")->max))
	{
		errorlog("%s: no authserver specified", filename);
		return (-1);
	}
	if (!(rc_conf_srv("acctserver")->max))
	{
		errorlog("%s: no acctserver specified", filename);
		return (-1);
	}
	if (!rc_conf_str("servers"))
	{
		errorlog("%s: no servers file specified", filename);
		return (-1);
	}
	if (!rc_conf_str("dictionary"))
	{
		errorlog("%s: no dictionary specified", filename);
		return (-1);
	}

	if (rc_conf_int("radius_timeout") <= 0)
	{
		errorlog("%s: radius_timeout <= 0 is illegal", filename);
		return (-1);
	}
	if (rc_conf_int("radius_retries") <= 0)
	{
		errorlog("%s: radius_retries <= 0 is illegal", filename);
		return (-1);
	}

#if 0
	file = rc_conf_str("login_local");
	if (stat(file, &st) == 0)
	{
		if (!S_ISREG(st.st_mode)) {
			errorlog("%s: not a regular file: %s", filename, file);
			return (-1);
		}
	} else {
		errorlog("%s: file not found: %s", filename, file);
		return (-1);
	}
	file = rc_conf_str("login_radius");
	if (stat(file, &st) == 0)
	{
		if (!S_ISREG(st.st_mode)) {
			errorlog("%s: not a regular file: %s", filename, file);
			return (-1);
		}
	} else {
		errorlog("%s: file not found: %s", filename, file);
		return (-1);
	}
#endif

	if (rc_conf_int("login_tries") <= 0)
	{
		errorlog("%s: login_tries <= 0 is illegal", filename);
		return (-1);
	}
	if (rc_conf_str("seqfile") == NULL)
	{
		errorlog("%s: seqfile not specified", filename);
		return (-1);
	}
	if (rc_conf_int("login_timeout") <= 0)
	{
		errorlog("%s: login_timeout <= 0 is illegal", filename);
		return (-1);
	}
	if (rc_conf_str("mapfile") == NULL)
	{
		errorlog("%s: mapfile not specified", filename);
		return (-1);
	}
	if (rc_conf_str("nologin") == NULL)
	{
		errorlog("%s: nologin not specified", filename);
		return (-1);
	}

	return 0;
}
Beispiel #10
0
/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a server
 *
 * @param rh a handle to parsed configuration.
 * @param client_port the client port number to use (may be zero to use any available).
 * @param send a #VALUE_PAIR array of values (e.g., %PW_USER_NAME).
 * @param received an allocated array of received values.
 * @param msg must be an array of %PW_MAX_MSG_SIZE or %NULL; will contain the concatenation of any
 *	%PW_REPLY_MESSAGE received.
 * @param add_nas_port if non-zero it will include %PW_NAS_PORT in sent pairs.
 * @param request_type one of standard RADIUS codes (e.g., %PW_ACCESS_REQUEST).
 * @return received value_pairs in received, messages from the server in msg and %OK_RC (0) on success, negative
 *	on failure as return value.
 */
int rc_aaa(rc_handle *rh, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received,
	   char *msg, int add_nas_port, int request_type)
{
	SEND_DATA       data;
	VALUE_PAIR	*adt_vp = NULL;
	int		result;
	int		i, skip_count;
	SERVER		*aaaserver;
	int		timeout = rc_conf_int(rh, "radius_timeout");
	int		retries = rc_conf_int(rh, "radius_retries");
	int		radius_deadtime = rc_conf_int(rh, "radius_deadtime");
	double		start_time = 0;
	double		now = 0;
	time_t		dtime;
	unsigned	type;

	if (request_type != PW_ACCOUNTING_REQUEST) {
		aaaserver = rc_conf_srv(rh, "authserver");
		type = AUTH;
	} else {
		aaaserver = rc_conf_srv(rh, "acctserver");
		type = ACCT;
	}
	if (aaaserver == NULL)
		return ERROR_RC;

	data.send_pairs = send;
	data.receive_pairs = NULL;

	if (add_nas_port != 0) {
		/*
		 * Fill in NAS-Port
		 */
		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
		    &client_port, 0, 0) == NULL)
			return ERROR_RC;
	}

	if (request_type == PW_ACCOUNTING_REQUEST) {
		/*
		 * Fill in Acct-Delay-Time
		 */
		dtime = 0;
		now = rc_getctime();
		adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
		if (adt_vp == NULL) {
			adt_vp = rc_avpair_add(rh, &(data.send_pairs),
			    PW_ACCT_DELAY_TIME, &dtime, 0, 0);
			if (adt_vp == NULL)
				return ERROR_RC;
			start_time = now;
		} else {
			start_time = now - adt_vp->lvalue;
		}
	}

	skip_count = 0;
	result = ERROR_RC;
	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
	    ; i++, now = rc_getctime())
	{
		if (aaaserver->deadtime_ends[i] != -1 &&
		    aaaserver->deadtime_ends[i] > start_time) {
			skip_count++;
			continue;
		}
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);

		if (request_type == PW_ACCOUNTING_REQUEST) {
			dtime = now - start_time;
			rc_avpair_assign(adt_vp, &dtime, 0);
		}

		result = rc_send_server (rh, &data, msg, type);
		if (result == TIMEOUT_RC && radius_deadtime > 0)
			aaaserver->deadtime_ends[i] = start_time + (double)radius_deadtime;
	}
	if (result == OK_RC || result == REJECT_RC || skip_count == 0)
		goto exit;

	result = ERROR_RC;
	for (i=0; (i < aaaserver->max) && (result != OK_RC) && (result != REJECT_RC)
	    ; i++)
	{
		if (aaaserver->deadtime_ends[i] == -1 ||
		    aaaserver->deadtime_ends[i] <= start_time) {
			continue;
		}
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(rh, &data, request_type, aaaserver->name[i],
		    aaaserver->port[i], aaaserver->secret[i], timeout, retries);

		if (request_type == PW_ACCOUNTING_REQUEST) {
			dtime = rc_getctime() - start_time;
			rc_avpair_assign(adt_vp, &dtime, 0);
		}

		result = rc_send_server (rh, &data, msg, type);
		if (result != TIMEOUT_RC)
			aaaserver->deadtime_ends[i] = -1;
	}

exit:
	if (request_type != PW_ACCOUNTING_REQUEST) {
		*received = data.receive_pairs;
	} else {
		rc_avpair_free(data.receive_pairs);
	}

	return result;
}
Beispiel #11
0
int test_config(rc_handle *rh, const char *filename)
{
#if 0
	struct stat st;
	char	    *file;
#endif

	if (!(rc_conf_srv(rh, "authserver")->max))
	{
		rc_log(LOG_ERR,"%s: no authserver specified", filename);
		return -1;
	}
	if (!(rc_conf_srv(rh, "acctserver")->max))
	{
		rc_log(LOG_ERR,"%s: no acctserver specified", filename);
		return -1;
	}
	if (!rc_conf_str(rh, "servers"))
	{
		rc_log(LOG_ERR,"%s: no servers file specified", filename);
		return -1;
	}
	if (!rc_conf_str(rh, "dictionary"))
	{
		rc_log(LOG_ERR,"%s: no dictionary specified", filename);
		return -1;
	}

	if (rc_conf_int(rh, "radius_timeout") <= 0)
	{
		rc_log(LOG_ERR,"%s: radius_timeout <= 0 is illegal", filename);
		return -1;
	}
	if (rc_conf_int(rh, "radius_retries") <= 0)
	{
		rc_log(LOG_ERR,"%s: radius_retries <= 0 is illegal", filename);
		return -1;
	}
	if (rc_conf_int(rh, "radius_deadtime") < 0)
	{
		rc_log(LOG_ERR,"%s: radius_deadtime is illegal", filename);
		return -1;
	}
#if 0
	file = rc_conf_str(rh, "login_local");
	if (stat(file, &st) == 0)
	{
		if (!S_ISREG(st.st_mode)) {
			rc_log(LOG_ERR,"%s: not a regular file: %s", filename, file);
			return -1;
		}
	} else {
		rc_log(LOG_ERR,"%s: file not found: %s", filename, file);
		return -1;
	}
	file = rc_conf_str(rh, "login_radius");
	if (stat(file, &st) == 0)
	{
		if (!S_ISREG(st.st_mode)) {
			rc_log(LOG_ERR,"%s: not a regular file: %s", filename, file);
			return -1;
		}
	} else {
		rc_log(LOG_ERR,"%s: file not found: %s", filename, file);
		return -1;
	}
#endif

	if (rc_conf_int(rh, "login_tries") <= 0)
	{
		rc_log(LOG_ERR,"%s: login_tries <= 0 is illegal", filename);
		return -1;
	}
	if (rc_conf_str(rh, "seqfile") == NULL)
	{
		rc_log(LOG_ERR,"%s: seqfile not specified", filename);
		return -1;
	}
	if (rc_conf_int(rh, "login_timeout") <= 0)
	{
		rc_log(LOG_ERR,"%s: login_timeout <= 0 is illegal", filename);
		return -1;
	}
	if (rc_conf_str(rh, "mapfile") == NULL)
	{
		rc_log(LOG_ERR,"%s: mapfile not specified", filename);
		return -1;
	}
	if (rc_conf_str(rh, "nologin") == NULL)
	{
		rc_log(LOG_ERR,"%s: nologin not specified", filename);
		return -1;
	}

	return 0;
}
Beispiel #12
0
//int rc_aaa(rc_handle *rh, char *host, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, int request_type)
int rc_aaa(rc_handle *rh, const string & host, uint32_t client_port, VALUE_PAIR *send, VALUE_PAIR **received, char *msg, int add_nas_port, int request_type)
{
        fprintf(stdout, "rc_aaa::Start\n");
	SEND_DATA       data;
	VALUE_PAIR	*adt_vp;
	int		result;
	int		i, skip_count;
	SERVER		aaaserver;
	int		timeout = rc_conf_int(rh, "radius_timeout");
	int		retries = rc_conf_int(rh, "radius_retries");
	int		radius_deadtime = rc_conf_int(rh, "radius_deadtime");
	double		start_time;
	time_t		dtime;

	if (request_type != PW_ACCOUNTING_REQUEST)
        {
//		aaaserver = rc_conf_srv(rh, "authserver");
//                fprintf(stdout, "rc_aaa::authserver\n");
//		 rc_conf_srv(rh, "authserver", &aaaserver);
            
//            aaaserver.name = host;
	}
        else
        {
//		aaaserver = rc_conf_srv(rh, "acctserver");
//                fprintf(stdout, "rc_aaa::acctserver\n");
	}
        
//        char srvName[15] = "192.168.10.102";
//        strcpy(srvName ,aaaserver.name);
//        fprintf(stdout, "srvName: %s\n", srvName);
//        fprintf(stdout, "aaaserver.name: %s\n", aaaserver.name);

/*
	if (aaaserver == NULL)
        {
            return ERROR_RC;
        }
*/
        if( !host.empty() )
        {
            aaaserver.name = host;
        }
        
	data.send_pairs = send;
	data.receive_pairs = NULL;

	if (add_nas_port != 0) {
		/*
		 * Fill in NAS-Port
		 */
		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT, &client_port, 0, 0) == NULL)
			return ERROR_RC;
	}

	if (request_type == PW_ACCOUNTING_REQUEST) {
		/*
		 * Fill in Acct-Delay-Time
		 */
		dtime = 0;
		if ((adt_vp = rc_avpair_add(rh, &(data.send_pairs), PW_ACCT_DELAY_TIME, &dtime, 0, 0)) == NULL)
			return ERROR_RC;
	}

	start_time = rc_getctime();
	skip_count = 0;
	result = ERROR_RC;
//        fprintf(stdout, "rc_aaa::aaaserver.max %d\n", aaaserver.max);
        aaaserver.max = 1;
	for (i=0; (i < aaaserver.max) && (result != OK_RC) && (result != BADRESP_RC); i++)
	{
		if (aaaserver.deadtime_ends != -1 && aaaserver.deadtime_ends > start_time)
                {
			skip_count++;
			continue;
		}
		if (data.receive_pairs != NULL)
                {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
                
		rc_buildreq(rh, &data, request_type, aaaserver.name.c_str(), aaaserver.port, aaaserver.secret.c_str(), timeout, retries);
                fprintf(stdout, "rc_buildreq:  data.server: %s\n", data.server.c_str());
                fprintf(stdout, "rc_buildreq:  data.secret: %s\n", data.secret.c_str());
                fprintf(stdout, "rc_buildreq:  data.svc_port: %i\n", data.svc_port);
//                fprintf(stdout, "aaaserver.name %s, port: %s, secert %s\n", aaaserver.name[i], aaaserver.port[i], aaaserver.secret[i]);

		if (request_type == PW_ACCOUNTING_REQUEST) {
			dtime = rc_getctime() - start_time;
			rc_avpair_assign(adt_vp, &dtime, 0);
		}

		result = rc_send_server (rh, &data, msg);
		if (result == TIMEOUT_RC && radius_deadtime > 0)
			aaaserver.deadtime_ends = start_time + (double)radius_deadtime;
	}
	if (result == OK_RC || result == BADRESP_RC || skip_count == 0)
		goto exit;

	result = ERROR_RC;
	for (i=0; (i < aaaserver.max) && (result != OK_RC) && (result != BADRESP_RC)
	    ; i++)
	{
		if (aaaserver.deadtime_ends == -1 ||
		    aaaserver.deadtime_ends <= start_time) {
			continue;
		}
		if (data.receive_pairs != NULL) {
			rc_avpair_free(data.receive_pairs);
			data.receive_pairs = NULL;
		}
		rc_buildreq(rh, &data, request_type, aaaserver.name.c_str(), aaaserver.port, aaaserver.secret.c_str(), timeout, retries);

		if (request_type == PW_ACCOUNTING_REQUEST) {
			dtime = rc_getctime() - start_time;
			rc_avpair_assign(adt_vp, &dtime, 0);
		}
                fprintf(stdout, "rc_aaa::rc_send_server Start\n");
		result = rc_send_server (rh, &data, msg);
                fprintf(stdout, "rc_aaa::rc_send_server End\n");
		if (result != TIMEOUT_RC)
			aaaserver.deadtime_ends = -1;
	}

exit:
	if (request_type != PW_ACCOUNTING_REQUEST) {
		*received = data.receive_pairs;
	} else {
		rc_avpair_free(data.receive_pairs);
	}
        printf("rc_aaa return: %d\n", result);
	return result;
}
Beispiel #13
0
/** Builds an authentication/accounting request for port id client_port with the value_pairs send and submits it to a specified server.
 * This function keeps its state in ctx after a successful operation. It can be deallocated using
 * rc_aaa_ctx_free().
 *
 * @param rh a handle to parsed configuration.
 * @param ctx if non-NULL it will contain the context of the request; Its initial value should be NULL and it must be released using rc_aaa_ctx_free().
 * @param aaaserver a non-NULL SERVER to send the message to.
 * @param client_port the client port number to use (may be zero to use any available).
 * @param send a VALUE_PAIR array of values (e.g., PW_USER_NAME).
 * @param received an allocated array of received values.
 * @param msg must be an array of PW_MAX_MSG_SIZE or NULL; will contain the concatenation of any
 *	PW_REPLY_MESSAGE received.
 * @param add_nas_port if non-zero it will include PW_NAS_PORT in sent pairs.
 * @param request_type one of standard RADIUS codes (e.g., PW_ACCESS_REQUEST).
 * @return received value_pairs in received, messages from the server in msg and OK_RC (0) on success, negative
 *	on failure as return value.
 */
int rc_aaa_ctx_server(rc_handle *rh, RC_AAA_CTX **ctx, SERVER *aaaserver,
                      rc_type type,
                      uint32_t client_port,
                      VALUE_PAIR *send, VALUE_PAIR **received,
                      char *msg, int add_nas_port, rc_standard_codes request_type)
{
	SEND_DATA       data;
	VALUE_PAIR	*adt_vp = NULL;
	int		result;
	int		timeout = rc_conf_int(rh, "radius_timeout");
	int		retries = rc_conf_int(rh, "radius_retries");
	double		start_time = 0;
	double		now = 0;
	time_t		dtime;
        int             servernum;

	data.send_pairs = send;
	data.receive_pairs = NULL;

        /*
         * if there is more than zero servers, then divide waiting time
         * among all the servers.
         */
        if(aaaserver->max > 0) {
          if(timeout > 0) {
            timeout = (timeout+1) / aaaserver->max;
          }
          if(retries > 0) {
            retries = (retries+1) / aaaserver->max;
          }
        }

	if (add_nas_port != 0 && rc_avpair_get(data.send_pairs, PW_NAS_PORT, 0) == NULL) {
		/*
		 * Fill in NAS-Port
		 */
		if (rc_avpair_add(rh, &(data.send_pairs), PW_NAS_PORT,
		    &client_port, 0, 0) == NULL)
			return ERROR_RC;
	}

	if (request_type == PW_ACCOUNTING_REQUEST) {
		/*
		 * Fill in Acct-Delay-Time
		 */
		dtime = 0;
		now = rc_getctime();
		adt_vp = rc_avpair_get(data.send_pairs, PW_ACCT_DELAY_TIME, 0);
		if (adt_vp == NULL) {
			adt_vp = rc_avpair_add(rh, &(data.send_pairs),
			    PW_ACCT_DELAY_TIME, &dtime, 0, 0);
			if (adt_vp == NULL)
				return ERROR_RC;
			start_time = now;
		} else {
			start_time = now - adt_vp->lvalue;
		}
	}

	if (data.receive_pairs != NULL) {
		rc_avpair_free(data.receive_pairs);
		data.receive_pairs = NULL;
	}

        servernum=0;
        do {
          rc_buildreq(rh, &data, request_type, aaaserver->name[servernum],
                      aaaserver->port[servernum],
                      aaaserver->secret[servernum], timeout, retries);

          if (request_type == PW_ACCOUNTING_REQUEST) {
            dtime = rc_getctime() - start_time;
            rc_avpair_assign(adt_vp, &dtime, 0);
          }

          result = rc_send_server_ctx (rh, ctx, &data, msg, type);

          if (request_type != PW_ACCOUNTING_REQUEST) {
            *received = data.receive_pairs;
          } else {
            rc_avpair_free(data.receive_pairs);
          }

          if(result == OK_RC) {
            DEBUG(LOG_INFO,
                  "servernum %u returned success", servernum);
            return result;
          }

          //rc_log(LOG_ERR,
          //       "servernum %u returned error: %d", servernum, result);
          servernum++;
        } while(servernum < aaaserver->max && result == TIMEOUT_RC);

	return result;
}