Exemple #1
0
LFUNC auth_radius(UINT4 client_port, char *username, char *passwd)
{

	VALUE_PAIR	*send, *received, *vp, *service_vp;
	UINT4		service, ftype, ctype;
	char		msg[4096], *p, username_realm[256];
	char            name[2048], value[2048]; /* more than enough */
	int		result;
	char		*default_realm, *service_str, *ftype_str;
	DICT_VALUE	*dval;

	send = received = NULL;

	/*
	 * Determine and fill in Service-Type
	 */

#ifdef SCP
	/* determine based on the username what kind of service is requested.
	   this allows you to use one password for all accounts, but the
	   Merit radiusd supplies you just with the right information you
	   need for the specified service type	-lf, 03/15/96 */

	switch (*username)
	{
		case 'S':
				service = PW_FRAMED;
				ftype = PW_SLIP;
				ctype = 0;
				username++;
				break;
		case 'C':
				service = PW_FRAMED;
				ftype = PW_SLIP;
				ctype = PW_VAN_JACOBSON_TCP_IP;
				username++;
				break;
		case 'P':
				service = PW_FRAMED;
				ftype = PW_PPP;
				ctype = 0;
				username++;
				break;
		default:
				service = PW_LOGIN;
				ftype = 0;
				ctype = 0;
				break;
	}
#else
	service = PW_LOGIN;
	ftype = 0;
	ctype = 0;
#endif

	if (rc_avpair_add(&send, PW_SERVICE_TYPE, &service, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	/* Fill in Framed-Protocol, if neccessary */

	if (ftype != 0)
	{
		if (rc_avpair_add(&send, PW_FRAMED_PROTOCOL, &ftype, 0, VENDOR_NONE) == NULL)
			return (LFUNC) NULL;
	}

	/* Fill in Framed-Compression, if neccessary */

	if (ctype != 0)
	{
		if (rc_avpair_add(&send, PW_FRAMED_COMPRESSION, &ctype, 0, VENDOR_NONE) == NULL)
			return (LFUNC) NULL;
	}

	/*
	 * Fill in User-Name
	 */

	 strncpy(username_realm, username, sizeof(username_realm));

	 /* Append default realm */
	 default_realm = rc_conf_str("default_realm");

	 if ((strchr(username_realm, '@') == NULL) && default_realm &&
	     ((*default_realm) != '\0'))
	 {
		strncat(username_realm, "@", sizeof(username_realm));
		strncat(username_realm, default_realm, sizeof(username_realm));
	 }

	if (rc_avpair_add(&send, PW_USER_NAME, username_realm, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	/*
	 * Fill in User-Password
	 */

	if (rc_avpair_add(&send, PW_USER_PASSWORD, passwd, 0, VENDOR_NONE) == NULL)
		return (LFUNC) NULL;

	result = rc_auth(client_port, send, &received, msg, NULL);

	if (result == OK_RC)
	{
		/* Set up a running count of attributes saved. */
		int acount[256], attr;

		memset(acount, 0, sizeof(acount));

		rc_add_env(env, "RADIUS_USER_NAME", username);

		vp = received;

		/* map-- keep track of the attributes so that we know
		   when to add the delimiters. Note that we can only
		   handle attributes < 256, which is the standard anyway. */

		while (vp)
		{
			strcpy(name, "RADIUS_");
			if (rc_avpair_tostr(vp, name+7, sizeof(name)-7, value, sizeof(value)) < 0) {
				rc_avpair_free(send);
				rc_avpair_free(received);
				return (LFUNC) NULL;
			}

			/* Translate "-" => "_" and uppercase*/
			for(p = name; *p; p++) {
				*p = toupper(*p);
				if (*p == '-') *p = '_';
			}

			/* Add to the attribute count and append the var
			   if necessary. */
			if ((attr = vp->attribute) < 256)
			{
				int count;
				if ((count = acount[attr]++) > 0) {
					char buf[10];
					sprintf(buf, "_%d", count);
					strcat(name,buf);
				}
			}

			if (rc_add_env(env, name, value) < 0)
			{
				rc_avpair_free(send);
				rc_avpair_free(received);
				return (LFUNC) NULL;
			}

			vp = vp->next;
		}

		service_str = "(unknown)";
		ftype_str = NULL;

		if ((service_vp = rc_avpair_get(received, PW_SERVICE_TYPE)) != NULL)
				if ((dval = rc_dict_getval(service_vp->lvalue, service_vp->name)) != NULL) {
					service_str = dval->name;
				}

		if (service_vp && (service_vp->lvalue == PW_FRAMED) &&
			((vp = rc_avpair_get(received, PW_FRAMED_PROTOCOL)) != NULL))
				if ((dval = rc_dict_getval(vp->lvalue, vp->name)) != NULL) {
					ftype_str = dval->name;
				}

		rc_log(LOG_NOTICE, "authentication OK, username %s, service %s%s%s",
				username, service_str,(ftype_str)?"/":"", (ftype_str)?ftype_str:"");

		if (msg && (*msg != '\0'))
			printf(SC_SERVER_REPLY, msg);
		else
			printf(SC_RADIUS_OK);

		rc_avpair_free(send);
		rc_avpair_free(received);

		return radius_login;
	}
	else
	{
		rc_log(LOG_NOTICE, "authentication FAILED, type RADIUS, username %s",
			   username_realm);
		if (msg && (*msg != '\0'))
			printf(SC_SERVER_REPLY, msg);
		else
			printf(SC_RADIUS_FAILED);
	}

	rc_avpair_free(send);
	if (received)
		rc_avpair_free(received);

	return (LFUNC) NULL;
}
Exemple #2
0
int rc_avpair_tostr (VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
{
	DICT_VALUE     *dval;
	char            buffer[32];
	struct in_addr  inad;
	unsigned char         *ptr;

	*name = *value = '\0';

	if (!pair || pair->name[0] == '\0') {
		error("rc_avpair_tostr: pair is NULL or empty");
		return (-1);
	}

	strncpy(name, pair->name, (size_t) ln);

	switch (pair->type)
	{
	    case PW_TYPE_STRING:
		lv--;
		ptr = (unsigned char *) pair->strvalue;
		while (*ptr != '\0')
		{
			if (!(isprint (*ptr)))
			{
				sprintf (buffer, "\\%03o", *ptr);
				strncat(value, buffer, (size_t) lv);
				lv -= 4;
				if (lv < 0) break;
			}
			else
			{
				strncat(value, (char *)ptr, 1);
				lv--;
				if (lv < 0) break;
			}
			ptr++;
		}
		break;

	    case PW_TYPE_INTEGER:
		dval = rc_dict_getval (pair->lvalue, pair->name);
		if (dval != (DICT_VALUE *) NULL)
		{
			strncpy(value, dval->name, (size_t) lv-1);
		}
		else
		{
			sprintf (buffer, "%d", pair->lvalue);
			strncpy(value, buffer, (size_t) lv);
		}
		break;

	    case PW_TYPE_IPADDR:
		inad.s_addr = htonl(pair->lvalue);
		strncpy (value, inet_ntoa (inad), (size_t) lv-1);
		break;

	    case PW_TYPE_DATE:
		strftime (buffer, sizeof (buffer), "%m/%d/%y %H:%M:%S",
			  gmtime ((time_t *) & pair->lvalue));
		strncpy(value, buffer, lv-1);
		break;

	    default:
		error("rc_avpair_tostr: unknown attribute type %d", pair->type);
		return (-1);
		break;
	}

	return 0;
}
/** Translate an av_pair into two strings
 *
 * @param rh a handle to parsed configuration.
 * @param pair a pointer to a VALUE_PAIR structure.
 * @param name the name of the pair.
 * @param ln the size of name.
 * @param value the value of the pair.
 * @param lv the size of value.
 * @return 0 on success, -1 on failure.
 */
int rc_avpair_tostr (rc_handle const *rh, VALUE_PAIR *pair, char *name, int ln, char *value, int lv)
{
	DICT_VALUE     *dval;
	char            buffer[32];
	struct in_addr  inad;
	unsigned char  *ptr;
	unsigned int    pos;

	*name = *value = '\0';

	if (!pair || pair->name[0] == '\0') {
		rc_log(LOG_ERR, "rc_avpair_tostr: pair is NULL or empty");
		return -1;
	}

	strlcpy(name, pair->name, (size_t) ln);

	switch (pair->type)
	{
	    case PW_TYPE_STRING:
	    	lv--;
	    	pos = 0;
		ptr = (unsigned char *) pair->strvalue;
		if (pair->attribute == PW_DIGEST_ATTRIBUTES) {
			pair->strvalue[*(ptr + 1)] = '\0';
			ptr += 2;
		}
		while (*ptr != '\0')
		{
			if (!(isprint (*ptr)))
			{
				if (lv >= 4) {
					snprintf (&value[pos], lv, "\\%03o", *ptr);
					pos += 4;
					lv -= 4;
				} else {
					break;
				}
			}
			else
			{
				if (lv > 0) {
					value[pos++] = *ptr;
					lv--;
				} else {
					break;
				}
			}
			ptr++;
		}
		if (lv > 0)
			value[pos++] = 0;
		else
			value[pos-1] = 0;
		break;

	    case PW_TYPE_INTEGER:
		dval = rc_dict_getval (rh, pair->lvalue, pair->name);
		if (dval != NULL)
		{
			strlcpy(value, dval->name, (size_t) lv);
		}
		else
		{
			snprintf(value, lv, "%ld", (long int)pair->lvalue);
		}
		break;

	    case PW_TYPE_IPADDR:
		inad.s_addr = htonl(pair->lvalue);
		strlcpy (value, inet_ntoa (inad), (size_t) lv);
		break;

	    case PW_TYPE_IPV6ADDR:
	    	if (inet_ntop(AF_INET6, pair->strvalue, value, lv) == NULL)
	    		return -1;
		break;

	    case PW_TYPE_IPV6PREFIX: {
	    	uint8_t ip[16];
	    	uint8_t txt[48];
	    	if (pair->lvalue < 2)
	    		return -1;

	    	memset(ip, 0, sizeof(ip));
	    	memcpy(ip, pair->strvalue+2, pair->lvalue-2);

	    	if (inet_ntop(AF_INET6, ip, txt, sizeof(txt)) == NULL)
	    		return -1;
		snprintf(value, lv, "%s/%u", txt, (unsigned)pair->strvalue[1]);

		break;
	    }
	    case PW_TYPE_DATE:
		strftime (value, lv, "%m/%d/%y %H:%M:%S",
			  gmtime ((time_t *) & pair->lvalue));
		break;

	    default:
		rc_log(LOG_ERR, "rc_avpair_tostr: unknown attribute type %d", pair->type);
		return -1;
		break;
	}

	return 0;
}
int
main (int argc, char **argv)
{
	int			result = ERROR_RC;
	VALUE_PAIR	*send = NULL;
   	UINT4		client_port;
   	int			c;
	VALUE_PAIR	*vp;
	DICT_VALUE  *dval;
	char *username, *service, *fproto, *type;
	char *path_radiusclient_conf = RC_CONFIG_FILE;
	char *ttyn = NULL;
	rc_handle *rh;

	extern char *optarg;

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

	rc_openlog(pname);

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

	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 (rc_read_mapfile(rh, rc_conf_str(rh, "mapfile")) != 0)
		exit (ERROR_RC);

	if (ttyn != NULL)
	{
		client_port = rc_map2id(rh, ttyn);
	}
	else
	{
		/* we take stdout here, because stdin is usually connected
	 	 *  to our input file
	 	 */
	 	if ((ttyn = ttyname(1)) != NULL)
	 	{
			client_port = rc_map2id(rh, ttyn);
		}
		else
		{
			client_port = 0;
		}
	}

	if ((send = rc_avpair_readin(rh, stdin))) {

		username = service = type = "(unknown)";
		fproto = NULL;

		if ((vp = rc_avpair_get(send, PW_ACCT_STATUS_TYPE, 0)) != NULL)
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					type = dval->name;
				}

		if ((vp = rc_avpair_get(send, PW_USER_NAME, 0)) != NULL)
				username = vp->strvalue;

		if ((vp = rc_avpair_get(send, PW_SERVICE_TYPE, 0)) != NULL)
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					service = dval->name;
				}

		if (vp && (vp->lvalue == PW_FRAMED) &&
			((vp = rc_avpair_get(send, PW_FRAMED_PROTOCOL, 0)) != NULL))
				if ((dval = rc_dict_getval(rh, vp->lvalue, vp->name)) != NULL) {
					fproto = dval->name;
				}

		result = rc_acct(rh, client_port, send);
		if (result == OK_RC)
		{
			fprintf(stderr, SC_ACCT_OK);
			rc_log(LOG_NOTICE, "accounting OK, type %s, username %s, service %s%s%s",
				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
		}
		else
		{
			fprintf(stderr, SC_ACCT_FAILED, result);
			rc_log(LOG_NOTICE, "accounting FAILED, type %s, username %s, service %s%s%s",
				   type, username, service,(fproto)?"/":"", (fproto)?fproto:"");
		}
		rc_avpair_free(send);
	}

	exit (result);
}