Beispiel #1
0
int rc_find_server (rc_handle *rh, const char *server_name, uint32_t *ip_addr, char *secret)
{
	int		i;
	size_t          len;
	int             result = 0;
	FILE           *clientfd;
	char           *h;
	char           *s;
	char            buffer[128];
	char            hostnm[AUTH_ID_LEN + 1];
	char	       *buffer_save;
	char	       *hostnm_save;
	SERVER	       *authservers;
	SERVER	       *acctservers;

	/* Lookup the IP address of the radius server */
	if ((*ip_addr = rc_get_ipaddr (server_name)) == (uint32_t) 0)
		return -1;

	/* Check to see if the server secret is defined in the rh config */
	if( (authservers = rc_conf_srv(rh, "authserver")) != NULL ) 
	{
		for( i = 0; i < authservers->max; i++ )
		{
			if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) &&
			    (authservers->secret[i] != NULL) )
			{
				memset (secret, '\0', MAX_SECRET_LENGTH);
				len = strlen (authservers->secret[i]);
				if (len > MAX_SECRET_LENGTH)
				{
					len = MAX_SECRET_LENGTH;
				}
				strncpy (secret, authservers->secret[i], (size_t) len);
				secret[MAX_SECRET_LENGTH] = '\0';
				return 0;
			}
		}
	}

	if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL ) 
	{
		for( i = 0; i < acctservers->max; i++ )
		{
			if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) &&
			    (acctservers->secret[i] != NULL) )
			{
				memset (secret, '\0', MAX_SECRET_LENGTH);
				len = strlen (acctservers->secret[i]);
				if (len > MAX_SECRET_LENGTH)
				{
					len = MAX_SECRET_LENGTH;
				}
				strncpy (secret, acctservers->secret[i], (size_t) len);
				secret[MAX_SECRET_LENGTH] = '\0';
				return 0;
			}
		}
	}

	/* We didn't find it in the rh_config or the servername is too long so look for a 
	 * servers file to define the secret(s)
	 */

	if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL)
	{
		rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers"));
		return -1;
	}

	while (fgets (buffer, sizeof (buffer), clientfd) != NULL)
	{
		if (*buffer == '#')
			continue;

		if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */
			continue;

		memset (hostnm, '\0', AUTH_ID_LEN);
		len = strlen (h);
		if (len > AUTH_ID_LEN)
		{
			len = AUTH_ID_LEN;
		}
		strncpy (hostnm, h, (size_t) len);
		hostnm[AUTH_ID_LEN] = '\0';

		if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */
			continue;

		memset (secret, '\0', MAX_SECRET_LENGTH);
		len = strlen (s);
		if (len > MAX_SECRET_LENGTH)
		{
			len = MAX_SECRET_LENGTH;
		}
		strncpy (secret, s, (size_t) len);
		secret[MAX_SECRET_LENGTH] = '\0';

		if (!strchr (hostnm, '/')) /* If single name form */
		{
			if (find_match (ip_addr, hostnm) == 0)
			{
				result++;
				break;
			}
		}
		else /* <name1>/<name2> "paired" form */
		{
			strtok_r(hostnm, "/", &hostnm_save);
			if (rc_is_myname(hostnm) == 0)
			{	     /* If we're the 1st name, target is 2nd */
				if (find_match (ip_addr, hostnm_save) == 0)
				{
					result++;
					break;
				}
			}
			else	/* If we were 2nd name, target is 1st name */
			{
				if (find_match (ip_addr, hostnm) == 0)
				{
					result++;
					break;
				}
			}
		}
	}
	fclose (clientfd);
	if (result == 0)
	{
		memset (buffer, '\0', sizeof (buffer));
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s",
			 server_name, rc_conf_str(rh, "servers"));
		return -1;
	}
	return 0;
}
Beispiel #2
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 #3
0
static int test_config(char *filename)
{
#if 0
	struct stat st;
	char	    *file;
#endif

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

	if (rc_conf_int("radius_timeout") <= 0)
	{
		error("%s: radius_timeout <= 0 is illegal", filename);
		return (-1);
	}
	if (rc_conf_int("radius_retries") <= 0)
	{
		error("%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)) {
			error("%s: not a regular file: %s", filename, file);
			return (-1);
		}
	} else {
		error("%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)) {
			error("%s: not a regular file: %s", filename, file);
			return (-1);
		}
	} else {
		error("%s: file not found: %s", filename, file);
		return (-1);
	}
#endif

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

	return 0;
}
int main (int argc, char **argv)
{
	int	result = ERROR_RC;
   	int	c,i;
	char	*p, msg[4096];
	SERVER	*srv;
	char	*path_radiusclient_conf = RC_CONFIG_FILE;
	rc_handle *rh;

	extern int optind;

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

	rc_openlog(pname);

	while ((c = getopt(argc,argv,"hVf:")) > 0)
	{
		switch(c) {
			case 'f':
				path_radiusclient_conf = optarg;
				break;
			case 'V':
				version();
				break;
			case 'h':
				usage();
				break;
			default:
				exit(ERROR_RC);
				break;
		}
	}

	argc -= optind;
	argv += optind;

	if ((rh = rc_read_config(path_radiusclient_conf)) == NULL)
		exit(ERROR_RC);

	if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
		exit (ERROR_RC);

	if (argc > 0) {
		for (i = 0; i < argc; i++) {
			if ((p = strchr(argv[i], ':')) == NULL) {
				result = rc_check(rh, argv[i],rc_getport(AUTH), msg);
			} else if (!strcmp(p+1, "auth")) {
				*p = '\0';
				result = rc_check(rh, argv[i],rc_getport(AUTH), msg);
			} else if (!strcmp(p+1, "acct")) {
				*p = '\0';
				result = rc_check(rh, argv[i],rc_getport(ACCT), msg);
			} else {
				*p = '\0';
				result = rc_check(rh, argv[i], atoi(p+1), msg);
			}
			if (result == OK_RC)
				fputs(msg, stdout);
			else
				printf(SC_STATUS_FAILED);
		}
	} else {
		srv = rc_conf_srv(rh, "authserver");
		for(i=0; i<srv->max ; i++)
		{
			result = rc_check(rh, srv->name[i], srv->port[i], msg);
			fputs(msg, stdout);
		}

		srv = rc_conf_srv(rh, "acctserver");
		for(i=0; i<srv->max ; i++)
		{
			result = rc_check(rh, srv->name[i], srv->port[i], msg);
			fputs(msg, stdout);
		}
	}
}
/** 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_getmtime();
		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_getmtime())
	{
		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_getmtime() - 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;
}
/** Locate a server in the rh config or if not found, check for a servers file
 *
 * @param rh a handle to parsed configuration.
 * @param server_name the name of the server.
 * @param info: will hold a pointer to addrinfo
 * @param secret will hold the server's secret (of %MAX_SECRET_LENGTH).
 * @param flags %AUTH or %ACCT
 
 * @return 0 on success, -1 on failure.
 */
int rc_find_server_addr (rc_handle const *rh, char const *server_name,
                         struct addrinfo** info, char *secret, unsigned flags)
{
	int		i;
	int             result = 0;
	FILE           *clientfd;
	char           *h;
	char           *s;
	char            buffer[128];
	char            hostnm[AUTH_ID_LEN + 1];
	char	       *buffer_save;
	char	       *hostnm_save;
	SERVER	       *authservers;
	SERVER	       *acctservers;
	struct addrinfo *tmpinfo = NULL;

	/* Lookup the IP address of the radius server */
	if ((*info = rc_getaddrinfo (server_name, flags==AUTH?PW_AI_AUTH:PW_AI_ACCT)) == NULL)
		return -1;

	if (flags == AUTH) {
		/* Check to see if the server secret is defined in the rh config */
		if( (authservers = rc_conf_srv(rh, "authserver")) != NULL )
		{
			for( i = 0; i < authservers->max; i++ )
			{
				if( (strncmp(server_name, authservers->name[i], strlen(server_name)) == 0) &&
				    (authservers->secret[i] != NULL) )
				{
					memset (secret, '\0', MAX_SECRET_LENGTH);
					strlcpy (secret, authservers->secret[i], MAX_SECRET_LENGTH);
					return 0;
				}
			}
		}
	} else if (flags == ACCT) {
		if( (acctservers = rc_conf_srv(rh, "acctserver")) != NULL )
		{
			for( i = 0; i < acctservers->max; i++ )
			{
				if( (strncmp(server_name, acctservers->name[i], strlen(server_name)) == 0) &&
				    (acctservers->secret[i] != NULL) )
				{
					memset (secret, '\0', MAX_SECRET_LENGTH);
					strlcpy (secret, acctservers->secret[i], MAX_SECRET_LENGTH);
					return 0;
				}
			}
		}
	}

	/* We didn't find it in the rh_config or the servername is too long so look for a
	 * servers file to define the secret(s)
	 */

	if ((clientfd = fopen (rc_conf_str(rh, "servers"), "r")) == NULL)
	{
		rc_log(LOG_ERR, "rc_find_server: couldn't open file: %s: %s", strerror(errno), rc_conf_str(rh, "servers"));
		goto fail;
	}

	while (fgets (buffer, sizeof (buffer), clientfd) != NULL)
	{
		if (*buffer == '#')
			continue;

		if ((h = strtok_r(buffer, " \t\n", &buffer_save)) == NULL) /* first hostname */
			continue;

		strlcpy (hostnm, h, AUTH_ID_LEN);

		if ((s = strtok_r (NULL, " \t\n", &buffer_save)) == NULL) /* and secret field */
			continue;

		strlcpy (secret, s, MAX_SECRET_LENGTH);

		if (!strchr (hostnm, '/')) /* If single name form */
		{
			tmpinfo = rc_getaddrinfo(hostnm, 0);
			if (tmpinfo)
			{
				result = find_match (*info, tmpinfo);
				if (result == 0)
				{
					result++;
					break;
				}

				freeaddrinfo(tmpinfo);
				tmpinfo = NULL;
			}
		}
		else /* <name1>/<name2> "paired" form */
		{
			strtok_r(hostnm, "/", &hostnm_save);
			tmpinfo = rc_getaddrinfo(hostnm, 0);
			if (tmpinfo)
			{
				if (rc_is_myname(tmpinfo) == 0)
				{	     /* If we're the 1st name, target is 2nd */
					if (find_match (*info, tmpinfo) == 0)
					{
						result++;
						break;
					}
				}
				else	/* If we were 2nd name, target is 1st name */
				{
					if (find_match (*info, tmpinfo) == 0)
					{
						result++;
						break;
					}
				}
				freeaddrinfo(tmpinfo);
				tmpinfo = NULL;
			}
		}
	}
	fclose (clientfd);
	if (result == 0)
	{
		memset (buffer, '\0', sizeof (buffer));
		memset (secret, '\0', MAX_SECRET_LENGTH);
		rc_log(LOG_ERR, "rc_find_server: couldn't find RADIUS server %s in %s",
			 server_name, rc_conf_str(rh, "servers"));
		goto fail;
	}
	
	result = 0;
	goto cleanup;

 fail:
 	freeaddrinfo(*info);
 	result = -1;

 cleanup:
 	if (tmpinfo)
 		freeaddrinfo(tmpinfo);

	return result;
}