Ejemplo n.º 1
0
int make_send_message(struct sip_msg* msg, int index, VALUE_PAIR **send) {

	pv_value_t pt;
	map_list *mp = sets[index]->parsed;

	for (; mp; mp = mp->next) {
		pv_get_spec_value(msg, mp->pv, &pt);

		if (pt.flags & PV_VAL_INT) {
			//LM_DBG("%.*s---->%d---->%d---->%d\n",mp->name.len, mp->name.s,
			//		pt.ri, mp->value, pt.flags);

			if (!rc_avpair_add(rh, send, ATTRID(mp->value), &pt.ri, -1, VENDOR(mp->value)))
				return -1;
		}
		else
		if (pt.flags & PV_VAL_STR) {
			//LM_DBG("%.*s----->%.*s---->%d---->%d---->%d\n",mp->name.len,
			//		mp->name.s, pt.rs.len, pt.rs.s, mp->value, pt.flags, pt.rs.len);
			if (rc_dict_getattr(rh,mp->value)->type == PW_TYPE_IPADDR) {
				uint32_t ipaddr=rc_get_ipaddr(pt.rs.s);
				if (!rc_avpair_add(rh, send, ATTRID(mp->value), &ipaddr, -1, VENDOR(mp->value)))
					return -1;
			} else {
				if (!rc_avpair_add(rh, send, ATTRID(mp->value), pt.rs.s, pt.rs.len, VENDOR(mp->value)))
					return -1;
			}
		}
	}
	return 0;
}
static int
rc_is_myname(char *hostname)
{
	struct in6_addr 	addr;
	struct in6_addr 	**paddr;
	struct 	hostent *hp;
	int	res;

	//rc_log(LOG_NOTICE,"rc_is_myname(%s)", hostname);
	if (rc_good_ipaddr(hostname) == 0) {
		if (rc_get_ipaddr(hostname, &addr) == 0) {
			//rc_log(LOG_NOTICE,"rc_is_myname(%s) return false", hostname);
			return -1;
		}
		return rc_ipaddr_local(&addr);
	}
	if ((hp = rc_gethostbyname(hostname)) == NULL)
		return -1;
	for (paddr = (struct in6_addr**)hp->h_addr_list; *paddr; paddr++) {
		addr = **(struct in6_addr **)paddr;
		res = rc_ipaddr_local(&addr);
		if (res == 0 || res == -1) {
			//rc_log(LOG_NOTICE,"rc_is_myname(%s) return %d", hostname, res);
			return res;
		}
	}
	//rc_log(LOG_NOTICE,"rc_is_myname(%s) return 1", hostname);
	return 1;
}
Ejemplo n.º 3
0
UINT4 rc_own_ipaddress(void)
{
	static UINT4 this_host_ipaddr = 0;

	if (!this_host_ipaddr) {
		if ((this_host_ipaddr = rc_get_ipaddr (hostname)) == 0) {
			error("rc_own_ipaddress: couldn't get own IP address");
			return 0;
		}
	}

	return this_host_ipaddr;
}
static int find_match (struct in6_addr *ip_addr, char *hostname)
{

	struct in6_addr  addr;
	char           **paddr;
	struct hostent  *hp;

	//rc_log(LOG_NOTICE,"find_match(%x:%x:%x:%x:%x:%x:%x:%x/%s)\n", NIP6ADDR(ip_addr), hostname);
	if (rc_good_ipaddr (hostname) == 0)
	{
		if (rc_get_ipaddr(hostname, &addr) == 0) {
			//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Success@1\n", NIP6ADDR(ip_addr), hostname);
			return 0;
		}
		if (IN6_ARE_ADDR_EQUAL(ip_addr, &addr))
		{
			//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Success@2\n", NIP6ADDR(ip_addr), hostname);
			return 0;
		}
		//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Failed@3\n", NIP6ADDR(ip_addr), hostname);
		return -1;
	}

	if ((hp = rc_gethostbyname(hostname)) == NULL)
	{
		//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Failed@4\n", NIP6ADDR(ip_addr), hostname);
		return -1;
	}

	for (paddr = hp->h_addr_list; *paddr; paddr++)
	{
		addr = ** (struct in6_addr **) paddr;

		//rc_log(LOG_NOTICE,"find_match Compare %x:%x:%x:%x:%x:%x:%x:%x/%x:%x:%x:%x:%x:%x:%x:%x\n", NIP6ADDR(ip_addr), NIP6ADDR(&addr));
		if (IN6_ARE_ADDR_EQUAL(ip_addr, &addr))
		{
			//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Success@5\n", NIP6ADDR(ip_addr), hostname);
			return 0;
		}
	}
	//rc_log(LOG_NOTICE,"find_match %x:%x:%x:%x:%x:%x:%x:%x/%s Failed@6\n", NIP6ADDR(ip_addr), hostname);
	return -1;
}
Ejemplo n.º 5
0
int rc_find_server (char *server_name, UINT4 *ip_addr, char *secret)
{
	UINT4	myipaddr = 0;
	int             len;
	int             result;
	FILE           *clientfd;
	char           *h;
	char           *s;
	char           *host2;
	char            buffer[128];
	char            hostnm[AUTH_ID_LEN + 1];

	/* Get the IP address of the authentication server */
	if ((*ip_addr = rc_get_ipaddr (server_name)) == (UINT4) 0)
		return (-1);

	if ((clientfd = fopen (rc_conf_str("servers"), "r")) == (FILE *) NULL)
	{
		errorlog("rc_find_server: couldn't open file: %m: %s", rc_conf_str("servers"));
		return (-1);
	}

	myipaddr = rc_own_ipaddress();

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

		if ((h = strtok (buffer, " \t\n")) == 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 (NULL, " \t\n")) == 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 (hostnm, "/");
			if (find_match (&myipaddr, hostnm) == 0)
			{	     /* If we're the 1st name, target is 2nd */
				host2 = strtok (NULL, " ");
				if (find_match (ip_addr, host2) == 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));
		errorlog("rc_find_server: couldn't find RADIUS server %s in %s",
		      server_name, rc_conf_str("servers"));
		return (-1);
	}
	return 0;
}
Ejemplo n.º 6
0
/*
	Radius implementation for the avp_add callback
 */
int rad_avp_add(aaa_conn* rh, aaa_message* message, aaa_map* name, void* value,
					int val_length, int vendor)
{
	uint32_t int4_val;
	str s;

	if (!rh) {
		LM_ERR("invalid aaa connection argument\n");
		return -1;
	}

	if (!message) {
		LM_ERR("invalid message argument\n");
		return -1;
	}

	if (!name) {
		LM_ERR("invalid name argument\n");
		return -1;
	}

	if (!value) {
		LM_ERR("invalid value argument\n");
		return -1;
	}

	if (vendor)
		vendor = VENDOR(vendor);

	/* check if this might be a string, we might have to do some conversions */
	if (val_length > -1) {
		if (name->type == PW_TYPE_IPADDR) {
			char ipstr[val_length + 1];
			memcpy( ipstr, value, val_length);
			ipstr[val_length] = 0;
			int4_val = rc_get_ipaddr((char*)&ipstr);
			LM_DBG("detected TYPE_IPADDR attribute %s = %s (%u)\n",
				name->name, ipstr, (unsigned int)int4_val);
			value = (void *)&int4_val;
			val_length = -1;
		} else if (name->type == PW_TYPE_INTEGER) {
			LM_DBG("detected TYPE_INTEGER attribute %s = %s\n",
				name->name, (char*)value);
			s.s = (char*)value;
			s.len = val_length;
			if (str2int( &s, (unsigned int*)(void*)&int4_val) != 0 ) {
				LM_ERR("error converting string to integer");
				return -1;
			}
			value = (void*)&int4_val;
			val_length = -1;
		}
	}

	if (rc_avpair_add (rh, (VALUE_PAIR**)(void*)&message->avpair, name->value,
	value, val_length, vendor)) {
		return 0;
	}

	LM_ERR("failure\n");
	return -1;
}
Ejemplo n.º 7
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;
}
Ejemplo n.º 8
0
int rc_avpair_parse (char *buffer, VALUE_PAIR **first_pair)
{
	int             mode;
	char            attrstr[AUTH_ID_LEN];
	char            valstr[AUTH_ID_LEN];
	DICT_ATTR      *attr = NULL;
	DICT_VALUE     *dval;
	VALUE_PAIR     *pair;
	VALUE_PAIR     *link;
	struct tm      *tm;
	time_t          timeval;

	mode = PARSE_MODE_NAME;
	while (*buffer != '\n' && *buffer != '\0')
	{
		if (*buffer == ' ' || *buffer == '\t')
		{
			buffer++;
			continue;
		}

		switch (mode)
		{
		    case PARSE_MODE_NAME:		/* Attribute Name */
			rc_fieldcpy (attrstr, &buffer);
			if ((attr =
				rc_dict_findattr (attrstr)) == (DICT_ATTR *) NULL)
			{
				error("rc_avpair_parse: unknown attribute");
				if (*first_pair) {
					rc_avpair_free(*first_pair);
					*first_pair = (VALUE_PAIR *) NULL;
				}
				return (-1);
			}
			mode = PARSE_MODE_EQUAL;
			break;

		    case PARSE_MODE_EQUAL:		/* Equal sign */
			if (*buffer == '=')
			{
				mode = PARSE_MODE_VALUE;
				buffer++;
			}
			else
			{
				error("rc_avpair_parse: missing or misplaced equal sign");
				if (*first_pair) {
					rc_avpair_free(*first_pair);
					*first_pair = (VALUE_PAIR *) NULL;
				}
				return (-1);
			}
			break;

		    case PARSE_MODE_VALUE:		/* Value */
			rc_fieldcpy (valstr, &buffer);

			if ((pair =
				(VALUE_PAIR *) malloc (sizeof (VALUE_PAIR)))
							== (VALUE_PAIR *) NULL)
			{
				novm("rc_avpair_parse");
				if (*first_pair) {
					rc_avpair_free(*first_pair);
					*first_pair = (VALUE_PAIR *) NULL;
				}
				return (-1);
			}
			strcpy (pair->name, attr->name);
			pair->attribute = attr->value;
			pair->type = attr->type;
			pair->vendorcode = attr->vendorcode;

			switch (pair->type)
			{

			    case PW_TYPE_STRING:
				strcpy ((char *)pair->strvalue, valstr);
				pair->lvalue = strlen(valstr);
				break;

			    case PW_TYPE_INTEGER:
				if (isdigit (*valstr))
				{
					pair->lvalue = atoi (valstr);
				}
				else
				{
					if ((dval = rc_dict_findval (valstr))
							== (DICT_VALUE *) NULL)
					{
						error("rc_avpair_parse: unknown attribute value: %s", valstr);
						if (*first_pair) {
							rc_avpair_free(*first_pair);
							*first_pair = (VALUE_PAIR *) NULL;
						}
						free (pair);
						return (-1);
					}
					else
					{
						pair->lvalue = dval->value;
					}
				}
				break;

			    case PW_TYPE_IPADDR:
				pair->lvalue = rc_get_ipaddr(valstr);
				break;

			    case PW_TYPE_DATE:
				timeval = time (0);
				tm = localtime (&timeval);
				tm->tm_hour = 0;
				tm->tm_min = 0;
				tm->tm_sec = 0;
				rc_str2tm (valstr, tm);
#ifdef TIMELOCAL
				pair->lvalue = (UINT4) timelocal (tm);
#else	/* TIMELOCAL */
				pair->lvalue = (UINT4) mktime (tm);
#endif	/* TIMELOCAL */
				break;

			    default:
				error("rc_avpair_parse: unknown attribute type %d", pair->type);
				if (*first_pair) {
					rc_avpair_free(*first_pair);
					*first_pair = (VALUE_PAIR *) NULL;
				}
				free (pair);
				return (-1);
			}
			pair->next = (VALUE_PAIR *) NULL;

			if (*first_pair == (VALUE_PAIR *) NULL)
			{
				*first_pair = pair;
			}
			else
			{
				link = *first_pair;
				while (link->next != (VALUE_PAIR *) NULL)
				{
					link = link->next;
				}
				link->next = pair;
			}

			mode = PARSE_MODE_NAME;
			break;

		    default:
			mode = PARSE_MODE_NAME;
			break;
		}
	}
	return (0);
}
Ejemplo n.º 9
0
int radius_auth(switch_channel_t *channel, char* called_number, char* username, char* password , char* auth_result/*, char* biling_model, char* credit_amount, char* currency, char* preffered_lang*/)
{
	int result = OK_RC;
	VALUE_PAIR *send = NULL;
	VALUE_PAIR *received = NULL;
	VALUE_PAIR 	*service_vp;
	DICT_ATTR   *pda;
	CONFIG_VSAS* PCONFIGVSAS = NULL;
	char *default_realm = NULL;
	rc_handle *rh = NULL;
	int attrid  =0;

	char msg[STR_LENGTH * 10 + 1];
	char username_realm[STR_LENGTH + 1];
	char value[STR_LENGTH + 1];
	int integer;

	memset(msg, 0, STR_LENGTH * 10);
	memset(username_realm, 0, STR_LENGTH);
	
	send = NULL;
	


	do
	{
		
#if EMBENDED_CONFIG

		CONFIG_CLIENT* PCONFIGCLIENT = CONFIGCLIENT;
		
		rh = rc_new();
		if (rh == NULL) 
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Failed to allocate initial structure.\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "allocate initial structure.\n");
	
		/* Initialize the config structure */
	
		rh = rc_config_init(rh);
		if (rh == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,"ERROR: Failed to initialze configuration.\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,"initialzed configuration.\n");
	
		while(PCONFIGCLIENT)
		{
			//if (rc_add_config(rh, "auth_order", "radius", "config", 0) != 0) 
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value);
			if (rc_add_config(rh, PCONFIGCLIENT->name, PCONFIGCLIENT->value, "config", 0) != 0) 
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "ERROR: Unable to set %s := %s.\n", PCONFIGCLIENT->name, PCONFIGCLIENT->value);
				
				result = ERROR_RC;
				break;
			}
			
			PCONFIGCLIENT = PCONFIGCLIENT->pNext;
		}
		
		if (result == ERROR_RC)
			break;

		
#else
		if ((rh = rc_read_config(!rc_config_file ? RC_CONFIG_FILE : rc_config_file)) == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius config file\n");
			
			result = ERROR_RC;
			break;
		}
		
#endif

		if (rc_read_dictionary(rh, rc_conf_str(rh, "dictionary")) != 0)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Error loading radius dictionary\n");
			
			result = ERROR_RC;
			break;
		}
		
		default_realm = rc_conf_str(rh, "default_realm");
		if (default_realm == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "default_realm is null object.\n");
			result = ERROR_RC;
			break;
		}
		
		strncpy(username_realm, username, sizeof(username_realm));

		if ((strchr(username_realm, '@') == NULL) && default_realm &&
		    (*default_realm != '\0'))
		{
			strncat(username_realm, "@", sizeof(username_realm)-strlen(username_realm)-1);
			strncat(username_realm, default_realm, sizeof(username_realm)-strlen(username_realm)-1);
		}
		
	
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
			"... radius: User-Name: %s\n", username);
		if (rc_avpair_add(rh, &send, PW_USER_NAME, username_realm, -1, 0)== NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : username\n");
			result = ERROR_RC;
			break;
		}
		
		switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
			"... radius: User-Password: %s\n", password);
		if (rc_avpair_add(rh, &send, PW_USER_PASSWORD, password, -1, 0) == NULL)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : password\n");
			result = ERROR_RC;
			break;
		}
		
		if (!called_number || strcmp(called_number, "") == 0)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
				"... radius: Called-station-Id is empty, ignoring...\n");
		}
		else
		{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
				"... radius: Called-station-Id: %s\n", called_number);
			if (rc_avpair_add(rh, &send, 30, called_number, -1, 0) == NULL)
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : Called-station-Id\n");
				result = ERROR_RC;
				break;
			}
		}

		
		PCONFIGVSAS = CONFIGVSAS;
	
		while(PCONFIGVSAS)
		{
			if (PCONFIGVSAS->direction == 1)
			{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name	);
				
				memset(value, 0, STR_LENGTH);
				GetValue(channel, PCONFIGVSAS, value);
				
				if (PCONFIGVSAS->pec != 0)
					attrid = PCONFIGVSAS->id | (PCONFIGVSAS->pec << 16);
				else
					attrid = PCONFIGVSAS->id ;
					
				pda = rc_dict_getattr(rh, attrid);
				
				if (pda == NULL)
				{
					result = ERROR_RC;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute: key:%s, not found in dictionary\n", PCONFIGVSAS->name);
					break;	
				}
				
				if (PCONFIGVSAS->pec != 0 && rc_dict_getvend(rh, PCONFIGVSAS->pec) == NULL)
				{
					result = ERROR_RC;
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown vendor specific id: key:%s, id:%dnot found in dictionary\n", PCONFIGVSAS->name, PCONFIGVSAS->pec);
					break;	
				}
				
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... dictionary data: id:%d, vendor id:%d, attr type:%d, attr name:%s (%d)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, pda->type, pda->name, attrid);
				
				switch(pda->type)
				{
					case PW_TYPE_STRING:
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%s) as string\n", PCONFIGVSAS->name, PCONFIGVSAS->value, value);
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, value, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;
						
					//case PW_TYPE_DATE:
					case PW_TYPE_INTEGER:
						integer = atoi(value);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as integer\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer);
						
						
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;
					case PW_TYPE_IPADDR:
						integer = rc_get_ipaddr(value);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "... radius: key:%s, value:%s (%d) as ipaddr\n", PCONFIGVSAS->name, PCONFIGVSAS->value, integer);
						
						
						if (rc_avpair_add(rh, &send, PCONFIGVSAS->id, &integer, -1, PCONFIGVSAS->pec) == NULL)
						{
							switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "An Error occured during rc_avpair_add : %s\n", PCONFIGVSAS->name);
							result = ERROR_RC;
							break;
						}
						break;						
						
					default:
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "Unknown attribute type: key:%s, type %d\n", PCONFIGVSAS->name, pda->type);
						break;
				}
			}
			
			PCONFIGVSAS = PCONFIGVSAS->pNext;
		}

		
		if (result != ERROR_RC)
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "sending radius packet ...\n"	);
			result = rc_auth(rh, 0, send, &received, msg);
		
	
			if (result == OK_RC)
			{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG,
					"RADIUS Authentication OK\n");
					
					strcpy(auth_result, "OK");
			}
			else
			{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
					" RADIUS Authentication failure (RC=%d)\n", 
					result);
					
					strcpy(auth_result, "NOK");
			}
			
			
			
			PCONFIGVSAS = CONFIGVSAS;
		
			while(PCONFIGVSAS)
			{
				if (PCONFIGVSAS->direction == 0)
				{
					switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Handle attribute: %s\n", PCONFIGVSAS->name	);
					if ((service_vp = rc_avpair_get(received, PCONFIGVSAS->id, PCONFIGVSAS->pec)) != NULL)
					{
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tattribute (%s) found in radius packet\n", PCONFIGVSAS->name);
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tset variable %s := %s\n", PCONFIGVSAS->value, service_vp->strvalue);
						
						switch_channel_set_variable(channel, PCONFIGVSAS->value, service_vp->strvalue);
					}
					else
					{
						switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "\tNo found out attribute id: %d, pec:%d, (%s)\n", PCONFIGVSAS->id, PCONFIGVSAS->pec, PCONFIGVSAS->name	);
					}
				}
				
				PCONFIGVSAS = PCONFIGVSAS->pNext;
			}
		}
		else
		{
			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "abort sending radius packet.\n"	);
			break;
		}
	
	} while(1 == 0);

	if (result == ERROR_RC)
	{
				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR,
				"An error occured during RADIUS Authentication(RC=%d)\n", 
				result);
	}
	
	free_radius_auth_value_pair(send, received, rh);
	
	return result;
}
Ejemplo n.º 10
0
int rc_send_server (rc_handle *rh, SEND_DATA *data, char *msg)
{
	int             sockfd;
	struct sockaddr_in sinlocal;
	struct sockaddr_in sinremote;
	AUTH_HDR       *auth, *recv_auth;
	uint32_t           auth_ipaddr, nas_ipaddr;
	char           *server_name;	/* Name of server to query */
	socklen_t       salen;
	int             result = 0;
	int             total_length;
	int             length;
	int             retry_max;
	size_t			secretlen;
	char            secret[MAX_SECRET_LENGTH + 1];
	unsigned char   vector[AUTH_VECTOR_LEN];
	char            recv_buffer[BUFFER_LEN];
	char            send_buffer[BUFFER_LEN];
	int		retries;
	VALUE_PAIR 	*vp;
	struct pollfd	pfd;
	double		start_time, timeout;

	server_name = data->server;
	if (server_name == NULL || server_name[0] == '\0')
		return ERROR_RC;

	if ((vp = rc_avpair_get(data->send_pairs, PW_SERVICE_TYPE, 0)) && \
	    (vp->lvalue == PW_ADMINISTRATIVE))
	{
		strcpy(secret, MGMT_POLL_SECRET);
		if ((auth_ipaddr = rc_get_ipaddr(server_name)) == 0)
			return ERROR_RC;
	}
	else
	{
		if(data->secret != NULL)
		{
			strncpy(secret, data->secret, MAX_SECRET_LENGTH);
		}
		/*
		else
		{
		*/
		if (rc_find_server (rh, server_name, &auth_ipaddr, secret) != 0)
		{
			rc_log(LOG_ERR, "rc_send_server: unable to find server: %s", server_name);
			return ERROR_RC;
		}
		/*}*/
	}

	DEBUG(LOG_ERR, "DEBUG: rc_send_server: creating socket to: %s", server_name);

	sockfd = socket (AF_INET, SOCK_DGRAM, 0);
	if (sockfd < 0)
	{
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: socket: %s", strerror(errno));
		return ERROR_RC;
	}

	memset((char *)&sinlocal, '\0', sizeof(sinlocal));
	sinlocal.sin_family = AF_INET;
	sinlocal.sin_addr.s_addr = htonl(rc_own_bind_ipaddress(rh));
	sinlocal.sin_port = htons((unsigned short) 0);
	if (bind(sockfd, SA(&sinlocal), sizeof(sinlocal)) < 0)
	{
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		rc_log(LOG_ERR, "rc_send_server: bind: %s: %s", server_name, strerror(errno));
		return ERROR_RC;
	}

	retry_max = data->retries;	/* Max. numbers to try for reply */
	retries = 0;			/* Init retry cnt for blocking call */

	memset ((char *)&sinremote, '\0', sizeof(sinremote));
	sinremote.sin_family = AF_INET;
	sinremote.sin_addr.s_addr = htonl (auth_ipaddr);
	sinremote.sin_port = htons ((unsigned short) data->svc_port);

	/*
	 * Fill in NAS-IP-Address (if needed)
	 */
	if (rc_avpair_get(data->send_pairs, PW_NAS_IP_ADDRESS, 0) == NULL) {
		if (sinlocal.sin_addr.s_addr == htonl(INADDR_ANY)) {
			if (rc_get_srcaddr(SA(&sinlocal), SA(&sinremote)) != 0) {
				close (sockfd);
				memset (secret, '\0', sizeof (secret));
				return ERROR_RC;
			}
		}
		nas_ipaddr = ntohl(sinlocal.sin_addr.s_addr);
		rc_avpair_add(rh, &(data->send_pairs), PW_NAS_IP_ADDRESS,
		    &nas_ipaddr, 0, 0);
	}

	/* Build a request */
	auth = (AUTH_HDR *) send_buffer;
	auth->code = data->code;
	auth->id = data->seq_nbr;

	if (data->code == PW_ACCOUNTING_REQUEST)
	{
		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);

		memset((char *) auth->vector, 0, AUTH_VECTOR_LEN);
		secretlen = strlen (secret);
		memcpy ((char *) auth + total_length, secret, secretlen);
		rc_md5_calc (vector, (unsigned char *) auth, total_length + secretlen);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);
	}
	else
	{
		rc_random_vector (vector);
		memcpy ((char *) auth->vector, (char *) vector, AUTH_VECTOR_LEN);

		total_length = rc_pack_list(data->send_pairs, secret, auth) + AUTH_HDR_LEN;

		auth->length = htons ((unsigned short) total_length);
	}

	DEBUG(LOG_ERR, "DEBUG: local %s : 0, remote %s : %u\n", 
		inet_ntoa(sinlocal.sin_addr),
		inet_ntoa(sinremote.sin_addr), data->svc_port);

	for (;;)
	{
		sendto (sockfd, (char *) auth, (unsigned int) total_length, (int) 0,
			SA(&sinremote), sizeof (struct sockaddr_in));

		pfd.fd = sockfd;
		pfd.events = POLLIN;
		pfd.revents = 0;
		start_time = rc_getctime();
		for (timeout = data->timeout; timeout > 0;
		    timeout -= rc_getctime() - start_time) {
			result = poll(&pfd, 1, timeout * 1000);
			if (result != -1 || errno != EINTR)
				break;
		}
		if (result == -1)
		{
			rc_log(LOG_ERR, "rc_send_server: poll: %s", strerror(errno));
			memset (secret, '\0', sizeof (secret));
			close (sockfd);
			return ERROR_RC;
		}
		if (result == 1 && (pfd.revents & POLLIN) != 0)
			break;

		/*
		 * Timed out waiting for response.  Retry "retry_max" times
		 * before giving up.  If retry_max = 0, don't retry at all.
		 */
		if (retries++ >= retry_max)
		{
			rc_log(LOG_ERR,
				"rc_send_server: no reply from RADIUS server %s:%u, %s",
				 rc_ip_hostname (auth_ipaddr), data->svc_port, inet_ntoa(sinremote.sin_addr));
			close (sockfd);
			memset (secret, '\0', sizeof (secret));
			return TIMEOUT_RC;
		}
	}
	salen = sizeof(sinremote);
	length = recvfrom (sockfd, (char *) recv_buffer,
			   (int) sizeof (recv_buffer),
			   (int) 0, SA(&sinremote), &salen);

	if (length <= 0)
	{
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: %s", server_name,\
			 data->svc_port, strerror(errno));
		close (sockfd);
		memset (secret, '\0', sizeof (secret));
		return ERROR_RC;
	}

	recv_auth = (AUTH_HDR *)recv_buffer;

	if (length < AUTH_HDR_LEN || length < ntohs(recv_auth->length)) {
		rc_log(LOG_ERR, "rc_send_server: recvfrom: %s:%d: reply is too short",
		    server_name, data->svc_port);
		close(sockfd);
		memset(secret, '\0', sizeof(secret));
		return ERROR_RC;
	}

	result = rc_check_reply (recv_auth, BUFFER_LEN, secret, vector, data->seq_nbr);

	length = ntohs(recv_auth->length)  - AUTH_HDR_LEN;
	if (length > 0) {
		data->receive_pairs = rc_avpair_gen(rh, NULL, recv_auth->data,
		    length, 0);
	} else {
		data->receive_pairs = NULL;
	}

	close (sockfd);
	memset (secret, '\0', sizeof (secret));

	if (result != OK_RC) return result;

	*msg = '\0';
	vp = data->receive_pairs;
	while (vp)
	{
		if ((vp = rc_avpair_get(vp, PW_REPLY_MESSAGE, 0)))
		{
			strcat(msg, vp->strvalue);
			strcat(msg, "\n");
			vp = vp->next;
		}
	}

	if ((recv_auth->code == PW_ACCESS_ACCEPT) ||
		(recv_auth->code == PW_PASSWORD_ACK) ||
		(recv_auth->code == PW_ACCOUNTING_RESPONSE))
	{
		result = OK_RC;
	}
	else if ((recv_auth->code == PW_ACCESS_REJECT) ||
		(recv_auth->code == PW_PASSWORD_REJECT))
	{
		result = REJECT_RC;
	}
	else
	{
		result = BADRESP_RC;
	}

	return result;
}