Exemplo n.º 1
0
bool client_validate(RADCLIENT_LIST *clients, RADCLIENT *master, RADCLIENT *c)
{
	char buffer[128];

	/*
	 *	No virtual server defined.  Inherit the parent's
	 *	definition.
	 */
	if (master->server && !c->server) {
		c->server = talloc_typed_strdup(c, master->server);
	}

	/*
	 *	If the client network isn't global (not tied to a
	 *	virtual server), then ensure that this clients server
	 *	is the same as the enclosing networks virtual server.
	 */
	if (master->server &&
	     (strcmp(master->server, c->server) != 0)) {
		DEBUG("- Cannot add client %s: Virtual server %s is not the same as the virtual server for the network",
		      ip_ntoh(&c->ipaddr, buffer, sizeof(buffer)), c->server);

		goto error;
	}

	if (!client_add(clients, c)) {
		DEBUG("- Cannot add client %s: Internal error", ip_ntoh(&c->ipaddr, buffer, sizeof(buffer)));

		goto error;
	}

	/*
	 *	Initialize the remaining fields.
	 */
	c->dynamic = true;
	c->lifetime = master->lifetime;
	c->created = time(NULL);
	c->longname = talloc_typed_strdup(c, c->shortname);

	DEBUG("- Added client %s with shared secret %s",
	      ip_ntoh(&c->ipaddr, buffer, sizeof(buffer)),
	      c->secret);

	return true;

error:
	client_free(c);
	return false;
}
/*
 *	Find the client definition.
 */
static rlm_rcode_t mod_authorize(UNUSED void *instance,
				 REQUEST *request)
{
	size_t length;
	const char *value;
	CONF_PAIR *cp;
	RADCLIENT *c;
	char buffer[2048];

	/*
	 *	Ensure we're only being called from the main thread,
	 *	with fake packets.
	 */
	if ((request->packet->src_port != 0) || (request->packet->vps != NULL) ||
	    (request->parent != NULL)) {
		RDEBUG("Improper configuration");
		return RLM_MODULE_NOOP;
	}

	if (!request->client || !request->client->cs) {
		RDEBUG("Unknown client definition");
		return RLM_MODULE_NOOP;
	}

	cp = cf_pair_find(request->client->cs, "directory");
	if (!cp) {
		RDEBUG("No directory configuration in the client");
		return RLM_MODULE_NOOP;
	}

	value = cf_pair_value(cp);
	if (!value) {
		RDEBUG("No value given for the directory entry in the client.");
		return RLM_MODULE_NOOP;
	}

	length = strlen(value);
	if (length > (sizeof(buffer) - 256)) {
		RDEBUG("Directory name too long");
		return RLM_MODULE_NOOP;
	}

	memcpy(buffer, value, length + 1);
	ip_ntoh(&request->packet->src_ipaddr,
		buffer + length, sizeof(buffer) - length - 1);

	/*
	 *	Read the buffer and generate the client.
	 */
	c = client_read(buffer, (request->client->server != NULL), TRUE);
	if (!c) return RLM_MODULE_FAIL;

	/*
	 *	Replace the client.  This is more than a bit of a
	 *	hack.
	 */
	request->client = c;

	return RLM_MODULE_OK;
}
Exemplo n.º 3
0
/** Add a client from a result set (LDAP, SQL, et al)
 *
 * @param ctx Talloc context.
 * @param identifier Client IP Address / IPv4 subnet / IPv6 subnet / FQDN.
 * @param secret Client secret.
 * @param shortname Client friendly name.
 * @param type NAS-Type.
 * @param server Virtual-Server to associate clients with.
 * @param require_ma If true all packets from client must include a message-authenticator.
 * @return The new client, or NULL on error.
 */
RADCLIENT *client_from_query(TALLOC_CTX *ctx, char const *identifier, char const *secret, char const *shortname,
			     char const *type, char const *server, bool require_ma)
{
	RADCLIENT *c;
	char buffer[128];

	rad_assert(identifier);
	rad_assert(secret);

	c = talloc_zero(ctx, RADCLIENT);

	if (fr_pton(&c->ipaddr, identifier, 0, true) < 0) {
		ERROR("%s", fr_strerror());
		talloc_free(c);

		return NULL;
	}

#ifdef WITH_DYNAMIC_CLIENTS
	c->dynamic = true;
#endif
	ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
	c->longname = talloc_typed_strdup(c, buffer);

	/*
	 *	Other values (secret, shortname, nas_type, virtual_server)
	 */
	c->secret = talloc_typed_strdup(c, secret);
	if (shortname) c->shortname = talloc_typed_strdup(c, shortname);
	if (type) c->nas_type = talloc_typed_strdup(c, type);
	if (server) c->server = talloc_typed_strdup(c, server);
	c->message_authenticator = require_ma;

	return c;
}
Exemplo n.º 4
0
/*
 *	Recieve packets from a proxy socket.
 */
static int proxy_socket_tcp_recv(rad_listen_t *listener,
				 RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
{
	REQUEST		*request;
	RADIUS_PACKET	*packet;
	RAD_REQUEST_FUNP fun = NULL;
	char		buffer[128];

	packet = fr_tcp_recv(listener->fd, 0);
	if (!packet) {
		proxy_close_tcp_listener(listener);
		return 0;
	}

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch(packet->code) {
	case PW_AUTHENTICATION_ACK:
	case PW_ACCESS_CHALLENGE:
	case PW_AUTHENTICATION_REJECT:
		fun = rad_authenticate;
		break;

#ifdef WITH_ACCOUNTING
	case PW_ACCOUNTING_RESPONSE:
		fun = rad_accounting;
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	request = received_proxy_tcp_response(packet,
					      fr_listen2tcp(listener));
	if (!request) {
		return 0;
	}

	rad_assert(fun != NULL);
	*pfun = fun;
	*prequest = request;

	return 1;
}
Exemplo n.º 5
0
static void send_with_pcap(void)
{
	pcap = fr_pcap_init(NULL, iface, PCAP_INTERFACE_IN_OUT);

	if (!pcap) {
		fprintf(stderr, "Failed creating pcap \n");
		fr_exit_now(1);
	}

	if (fr_pcap_open(pcap) < 0) {
		fprintf(stderr, "Failed opening interface: %s", fr_strerror());
		fr_exit_now(1);
	}

	char ip[16];
	ip_ntoh(&request->src_ipaddr, ip, sizeof(ip));

	char pcap_filter[255];
	sprintf(pcap_filter, "udp and dst port %d", client_port);

	if (fr_pcap_apply_filter(pcap, pcap_filter) < 0) {
		fprintf(stderr, "Failed setting filter for interface: %s \n",
			fr_strerror());
		fr_exit_now(1);
	}

	if (fr_dhcp_send_pcap(pcap, eth_bcast, request) < 0) {
		fprintf(stderr, "dhcpclient: failed sending: %s\n",
			pcap_geterr(pcap->handle));
		fr_exit_now(1);
	}

	if (!reply_expected) return;

	reply = fr_dhcp_recv_raw_loop(pcap->fd,
#ifdef HAVE_LINUX_IF_PACKET_H
				      &ll,
#endif 
				      request);

	if (!reply) {
		fprintf(stderr, "dhcpclient: Error receiving reply\n");
		fr_exit_now(1);
	}
}
Exemplo n.º 6
0
/*
 *	Read a client definition from the given filename.
 */
RADCLIENT *client_read(char const *filename, int in_server, int flag)
{
	char const *p;
	RADCLIENT *c;
	CONF_SECTION *cs;
	char buffer[256];

	if (!filename) return NULL;

	cs = cf_file_read(filename);
	if (!cs) return NULL;

	cs = cf_section_sub_find(cs, "client");
	if (!cs) {
		ERROR("No \"client\" section found in client file");
		return NULL;
	}

	c = client_parse(cs, in_server);
	if (!c) return NULL;

	p = strrchr(filename, FR_DIR_SEP);
	if (p) {
		p++;
	} else {
		p = filename;
	}

	if (!flag) return c;

	/*
	 *	Additional validations
	 */
	ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
	if (strcmp(p, buffer) != 0) {
		DEBUG("Invalid client definition in %s: IP address %s does not match name %s", filename, buffer, p);
		client_free(c);
		return NULL;
	}

	return c;
}
Exemplo n.º 7
0
static int send_packet(RADIUS_PACKET *req, RADIUS_PACKET **rep)
{
	int i;
	struct timeval	tv;

	if (!req || !rep || !*rep) return -1;

	for (i = 0; i < retries; i++) {
		fd_set		rdfdesc;

		debug_packet(req, R_SENT);

		if (rad_send(req, NULL, secret) < 0) {
			fr_perror("radeapclient");
			exit(1);
		}

		/* And wait for reply, timing out as necessary */
		FD_ZERO(&rdfdesc);
		FD_SET(req->sockfd, &rdfdesc);

		tv.tv_sec = (int)timeout;
		tv.tv_usec = 1000000 * (timeout - (int) timeout);

		/* Something's wrong if we don't get exactly one fd. */
		if (select(req->sockfd + 1, &rdfdesc, NULL, NULL, &tv) != 1) {
			continue;
		}

		*rep = rad_recv(req->sockfd, 0);
		if (*rep != NULL) {
			/*
			 *	If we get a response from a machine
			 *	which we did NOT send a request to,
			 *	then complain.
			 */
			if (((*rep)->src_ipaddr.af != req->dst_ipaddr.af) ||
			    (memcmp(&(*rep)->src_ipaddr.ipaddr,
				    &req->dst_ipaddr.ipaddr,
				    ((req->dst_ipaddr.af == AF_INET ? /* AF_INET6? */
				      sizeof(req->dst_ipaddr.ipaddr.ip4addr) : /* FIXME: AF_INET6 */
				      sizeof(req->dst_ipaddr.ipaddr.ip6addr)))) != 0) ||
			    ((*rep)->src_port != req->dst_port)) {
				char src[128], dst[128];

				ip_ntoh(&(*rep)->src_ipaddr, src, sizeof(src));
				ip_ntoh(&req->dst_ipaddr, dst, sizeof(dst));
				fprintf(stderr, "radclient: ERROR: Sent request to host %s port %d, got response from host %s port %d\n!",
					dst, req->dst_port,
					src, (*rep)->src_port);
				exit(1);
			}
			break;
		} else {	/* NULL: couldn't receive the packet */
			fr_perror("radclient");
			exit(1);
		}
	}

	/* No response or no data read (?) */
	if (i == retries) {
		fprintf(stderr, "radclient: no response from server\n");
		exit(1);
	}

	/*
	 *	FIXME: Discard the packet & listen for another.
	 *
	 *	Hmm... we should really be using eapol_test, which does
	 *	a lot more than radeapclient.
	 */
	if (rad_verify(*rep, req, secret) != 0) {
		fr_perror("rad_verify");
		exit(1);
	}

	if (rad_decode(*rep, req, secret) != 0) {
		fr_perror("rad_decode");
		exit(1);
	}

	/* libradius debug already prints out the value pairs for us */
	if (!fr_debug_flag && do_output) {
		debug_packet(*rep, R_RECV);
	}
	if((*rep)->code == PW_CODE_AUTHENTICATION_ACK) {
		totalapp++;
	} else if ((*rep)->code == PW_CODE_AUTHENTICATION_REJECT) {
		totaldeny++;
	}

	return 0;
}
Exemplo n.º 8
0
/** Allocate a new client from a config section
 *
 * @param ctx to allocate new clients in.
 * @param cs to process as a client.
 * @param in_server Whether the client should belong to a specific virtual server.
 * @param with_coa If true and coa_server or coa_pool aren't specified automatically,
 *	create a coa home_server section and add it to the client CONF_SECTION.
 * @return new RADCLIENT struct.
 */
RADCLIENT *client_afrom_cs(TALLOC_CTX *ctx, CONF_SECTION *cs, bool in_server, bool with_coa)
{
	RADCLIENT	*c;
	char const	*name2;

	name2 = cf_section_name2(cs);
	if (!name2) {
		cf_log_err_cs(cs, "Missing client name");
		return NULL;
	}

	/*
	 *	The size is fine.. Let's create the buffer
	 */
	c = talloc_zero(ctx, RADCLIENT);
	c->cs = cs;

	memset(&cl_ipaddr, 0, sizeof(cl_ipaddr));
	if (cf_section_parse(cs, c, client_config) < 0) {
		cf_log_err_cs(cs, "Error parsing client section");
	error:
		client_free(c);
#ifdef WITH_TCP
		hs_proto = NULL;
		cl_srcipaddr = NULL;
#endif

		return NULL;
	}

	/*
	 *	Global clients can set servers to use, per-server clients cannot.
	 */
	if (in_server && c->server) {
		cf_log_err_cs(cs, "Clients inside of an server section cannot point to a server");
		goto error;
	}

	/*
	 *	Newer style client definitions with either ipaddr or ipaddr6
	 *	config items.
	 */
	if (cf_pair_find(cs, "ipaddr") || cf_pair_find(cs, "ipv4addr") || cf_pair_find(cs, "ipv6addr")) {
		char buffer[128];

		/*
		 *	Sets ipv4/ipv6 address and prefix.
		 */
		c->ipaddr = cl_ipaddr;

		/*
		 *	Set the long name to be the result of a reverse lookup on the IP address.
		 */
		ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
		c->longname = talloc_typed_strdup(c, buffer);

		/*
		 *	Set the short name to the name2.
		 */
		if (!c->shortname) c->shortname = talloc_typed_strdup(c, name2);
	/*
	 *	No "ipaddr" or "ipv6addr", use old-style "client <ipaddr> {" syntax.
	 */
	} else {
		cf_log_err_cs(cs, "No 'ipaddr' or 'ipv4addr' or 'ipv6addr' configuration "
			      "directive found in client %s", name2);
		goto error;
	}

	c->proto = IPPROTO_UDP;
	if (hs_proto) {
		if (strcmp(hs_proto, "udp") == 0) {
			hs_proto = NULL;

#ifdef WITH_TCP
		} else if (strcmp(hs_proto, "tcp") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
#  ifdef WITH_TLS
		} else if (strcmp(hs_proto, "tls") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
			c->tls_required = true;

		} else if (strcmp(hs_proto, "radsec") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
			c->tls_required = true;
#  endif
		} else if (strcmp(hs_proto, "*") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_IP; /* fake for dual */
#endif
		} else {
			cf_log_err_cs(cs, "Unknown proto \"%s\".", hs_proto);
			goto error;
		}
	}

	/*
	 *	If a src_ipaddr is specified, when we send the return packet
	 *	we will use this address instead of the src from the
	 *	request.
	 */
	if (cl_srcipaddr) {
#ifdef WITH_UDPFROMTO
		switch (c->ipaddr.af) {
		case AF_INET:
			if (fr_pton4(&c->src_ipaddr, cl_srcipaddr, -1, true, false) < 0) {
				cf_log_err_cs(cs, "Failed parsing src_ipaddr: %s", fr_strerror());
				goto error;
			}
			break;

		case AF_INET6:
			if (fr_pton6(&c->src_ipaddr, cl_srcipaddr, -1, true, false) < 0) {
				cf_log_err_cs(cs, "Failed parsing src_ipaddr: %s", fr_strerror());
				goto error;
			}
			break;
		default:
			rad_assert(0);
		}
#else
		WARN("Server not built with udpfromto, ignoring client src_ipaddr");
#endif
		cl_srcipaddr = NULL;
	}

	/*
	 *	A response_window of zero is OK, and means that it's
	 *	ignored by the rest of the server timers.
	 */
	if (timerisset(&c->response_window)) {
		FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, >=, 0, 1000);
		FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, <=, 60, 0);
		FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, <=, main_config.max_request_time, 0);
	}
Exemplo n.º 9
0
static int generate_sql_clients(rlm_sql_t *inst)
{
	rlm_sql_handle_t *handle;
	rlm_sql_row_t row;
	char querystr[MAX_QUERY_LEN];
	RADCLIENT *c;
	char *prefix_ptr = NULL;
	unsigned int i = 0;
	int numf = 0;

	DEBUG("rlm_sql (%s): Processing generate_sql_clients",
	      inst->config->xlat_name);

	/* NAS query isn't xlat'ed */
	strlcpy(querystr, inst->config->nas_query, sizeof(querystr));
	DEBUG("rlm_sql (%s) in generate_sql_clients: query is %s",
	      inst->config->xlat_name, querystr);

	handle = sql_get_socket(inst);
	if (handle == NULL)
		return -1;
	if (rlm_sql_select_query(&handle,inst,querystr)){
		return -1;
	}

	while(rlm_sql_fetch_row(&handle, inst) == 0) {
		i++;
		row = handle->row;
		if (row == NULL)
			break;
		/*
		 *  The return data for each row MUST be in the following order:
		 *
		 *  0. Row ID (currently unused)
		 *  1. Name (or IP address)
		 *  2. Shortname
		 *  3. Type
		 *  4. Secret
		 *  5. Virtual Server (optional)
		 */
		if (!row[0]){
			radlog(L_ERR, "rlm_sql (%s): No row id found on pass %d",inst->config->xlat_name,i);
			continue;
		}
		if (!row[1]){
			radlog(L_ERR, "rlm_sql (%s): No nasname found for row %s",inst->config->xlat_name,row[0]);
			continue;
		}
		if (!row[2]){
			radlog(L_ERR, "rlm_sql (%s): No short name found for row %s",inst->config->xlat_name,row[0]);
			continue;
		}
		if (!row[4]){
			radlog(L_ERR, "rlm_sql (%s): No secret found for row %s",inst->config->xlat_name,row[0]);
			continue;
		}

		DEBUG("rlm_sql (%s): Read entry nasname=%s,shortname=%s,secret=%s",inst->config->xlat_name,
			row[1],row[2],row[4]);

		c = talloc_zero(inst, RADCLIENT);

#ifdef WITH_DYNAMIC_CLIENTS
		c->dynamic = 1;
#endif

		/*
		 *	Look for prefixes
		 */
		c->prefix = -1;
		prefix_ptr = strchr(row[1], '/');
		if (prefix_ptr) {
			c->prefix = atoi(prefix_ptr + 1);
			if ((c->prefix < 0) || (c->prefix > 128)) {
				radlog(L_ERR, "rlm_sql (%s): Invalid Prefix value '%s' for IP.",
				       inst->config->xlat_name, prefix_ptr + 1);
				talloc_free(c);
				continue;
			}
			/* Replace '/' with '\0' */
			*prefix_ptr = '\0';
		}

		/*
		 *	Always get the numeric representation of IP
		 */
		if (ip_hton(row[1], AF_UNSPEC, &c->ipaddr) < 0) {
			radlog(L_ERR, "rlm_sql (%s): Failed to look up hostname %s: %s",
			       inst->config->xlat_name,
			       row[1], fr_strerror());
			talloc_free(c);
			continue;
		} else {
			char buffer[256];
			ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
			c->longname = talloc_strdup(c, buffer);
		}

		if (c->prefix < 0) switch (c->ipaddr.af) {
		case AF_INET:
			c->prefix = 32;
			break;
		case AF_INET6:
			c->prefix = 128;
			break;
		default:
			break;
		}

		/*
		 *	Other values (secret, shortname, nastype, virtual_server)
		 */
		c->secret = talloc_strdup(c, row[4]);
		c->shortname = talloc_strdup(c, row[2]);
		if(row[3] != NULL)
			c->nastype = strdup(row[3]);

		numf = (inst->module->sql_num_fields)(handle, inst->config);
		if ((numf > 5) && (row[5] != NULL) && *row[5]) c->server = strdup(row[5]);

		DEBUG("rlm_sql (%s): Adding client %s (%s, server=%s) to clients list",
		      inst->config->xlat_name,
		      c->longname,c->shortname, c->server ? c->server : "<none>");
		if (!client_add(NULL, c)) {
			sql_release_socket(inst, handle);
			DEBUG("rlm_sql (%s): Failed to add client %s (%s) to clients list.  Maybe there's a duplicate?",
			      inst->config->xlat_name,
			      c->longname,c->shortname);
			client_free(c);
			return -1;
		}
	}
	(inst->module->sql_finish_select_query)(handle, inst->config);
	sql_release_socket(inst, handle);

	return 0;
}
Exemplo n.º 10
0
/*
 *	member of the radius group?
 */
static rlm_rcode_t mod_authorize(UNUSED void *instance, REQUEST *request)
{
	struct passwd *userdata = NULL;
	struct group *groupdata = NULL;
	int ismember = 0;
	RADCLIENT *rad_client = NULL;
	uuid_t uuid;
	uuid_t guid_sacl;
	uuid_t guid_nasgroup;
	int err;
	char host_ipaddr[128] = {0};
	
	if (!request || !request->username) {
		RDEBUG("OpenDirectory requires a User-Name attribute.");
		return RLM_MODULE_NOOP;
	}
	
	/* resolve SACL */
	uuid_clear(guid_sacl);
	groupdata = getgrnam(kRadiusSACLName);
	if (groupdata != NULL) {
		err = mbr_gid_to_uuid(groupdata->gr_gid, guid_sacl);
		if (err != 0) {
			ERROR("rlm_opendirectory: The group \"%s\" does not have a GUID.", kRadiusSACLName);
			return RLM_MODULE_FAIL;
		}		
	}
	else {
		RDEBUG("The SACL group \"%s\" does not exist on this system.", kRadiusSACLName);
	}
	
	/* resolve client access list */
	uuid_clear(guid_nasgroup);

	rad_client = request->client;
#if 0
	if (rad_client->community[0] != '\0' )
	{
		/*
		 *	The "community" can be a GUID (Globally Unique ID) or
		 *	a group name
		 */
		if (uuid_parse(rad_client->community, guid_nasgroup) != 0) {
			/* attempt to resolve the name */
			groupdata = getgrnam(rad_client->community);
			if (!groupdata) {
				AUTH("rlm_opendirectory: The group \"%s\" does not exist on this system.", rad_client->community);
				return RLM_MODULE_FAIL;
			}
			err = mbr_gid_to_uuid(groupdata->gr_gid, guid_nasgroup);
			if (err != 0) {
				AUTH("rlm_opendirectory: The group \"%s\" does not have a GUID.", rad_client->community);
				return RLM_MODULE_FAIL;
			}
		}
	}
	else
#endif
	{
		if (!rad_client) {
			RDEBUG("The client record could not be found for host %s.",
					ip_ntoh(&request->packet->src_ipaddr,
						host_ipaddr, sizeof(host_ipaddr)));
		}
		else {
			RDEBUG("The host %s does not have an access group.",
					ip_ntoh(&request->packet->src_ipaddr,
						host_ipaddr, sizeof(host_ipaddr)));
		}
	}
	
	if (uuid_is_null(guid_sacl) && uuid_is_null(guid_nasgroup)) {
		RDEBUG("no access control groups, all users allowed.");
		if (pairfind(request->config_items, PW_AUTH_TYPE, 0, TAG_ANY) == NULL) {
			pairmake_config("Auth-Type", kAuthType, T_OP_EQ);
			RDEBUG("Setting Auth-Type = %s", kAuthType);
		}
		return RLM_MODULE_OK;
	}

	/* resolve user */
	uuid_clear(uuid);

	userdata = getpwnam(request->username->vp_strvalue);
	if (userdata != NULL) {
		err = mbr_uid_to_uuid(userdata->pw_uid, uuid);
		if (err != 0)
			uuid_clear(uuid);
	}
	
	if (uuid_is_null(uuid)) {
		REDEBUG("Could not get the user's uuid",
				   T_OP_EQ);
		return RLM_MODULE_NOTFOUND;
	}
	
	if (!uuid_is_null(guid_sacl)) {
		err = mbr_check_service_membership(uuid, kRadiusServiceName, &ismember);
		if (err != 0) {
			REDEBUG("Failed to check group membership", T_OP_EQ);
			return RLM_MODULE_FAIL;
		}
		
		if (ismember == 0) {
			REDEBUG("User is not authorized", T_OP_EQ);
			return RLM_MODULE_USERLOCK;
		}
	}
	
	if (!uuid_is_null(guid_nasgroup)) {
		err = mbr_check_membership_refresh(uuid, guid_nasgroup, &ismember);
		if (err != 0) {
			REDEBUG("Failed to check group membership", T_OP_EQ);
			return RLM_MODULE_FAIL;
		}
		
		if (ismember == 0) {
			REDEBUG("User is not authorized", T_OP_EQ);
			return RLM_MODULE_USERLOCK;
		}
	}
	
	if (pairfind(request->config_items, PW_AUTH_TYPE, 0, TAG_ANY) == NULL) {
		pairmake_config("Auth-Type", kAuthType, T_OP_EQ);
		RDEBUG("Setting Auth-Type = %s", kAuthType);
	}

	return RLM_MODULE_OK;
}
Exemplo n.º 11
0
/*
 *	Recieve packets from a proxy socket.
 */
static int proxy_socket_recv(rad_listen_t *listener,
			      RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
{
	REQUEST		*request;
	RADIUS_PACKET	*packet;
	char		buffer[128];
	RAD_REQUEST_FUNP fun = NULL;

	packet = rad_recv(listener->fd, 0);
	if (!packet) {
		radlog(L_ERR, "%s", fr_strerror());
		return 0;
	}

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch(packet->code) {
	case PW_AUTHENTICATION_ACK:
	case PW_ACCESS_CHALLENGE:
	case PW_AUTHENTICATION_REJECT:
#ifdef WITH_ACCOUNTING
	case PW_ACCOUNTING_RESPONSE:
#endif
		break;

#ifdef WITH_COA
	case PW_DISCONNECT_ACK:
	case PW_DISCONNECT_NAK:
	case PW_COA_ACK:
	case PW_COA_NAK:
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
 		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	request = received_proxy_response(packet);
	if (!request) {
		return 0;
	}

	rad_assert(request->process != NULL);

#ifdef WITH_COA
	/*
	 *	Distinguish proxied CoA requests from ones we
	 *	originate.  If we've proxied a DIFFERENT packet type
	 *	than the original, then it MUST be a CoA packet.  In
	 *	that case, we process it as a CoA reply packet, rather
	 *	than re-running the original method.
	 */
	if (request->packet->code != request->proxy->code) {
		rad_assert((request->proxy->code == PW_COA_REQUEST) ||
			   (request->proxy->code == PW_DISCONNECT_REQUEST));
		fun = rad_coa_reply; /* run NEW function */
	} else
#endif
	*pfun = request->process; /* re-run original function */
	*prequest = request;

	return 1;
}
Exemplo n.º 12
0
/*
 *	Recieve packets from a proxy socket.
 */
static int proxy_socket_recv(rad_listen_t *listener,
			      RAD_REQUEST_FUNP *pfun, REQUEST **prequest)
{
	REQUEST		*request;
	RADIUS_PACKET	*packet;
	char		buffer[128];
	RAD_REQUEST_FUNP fun = NULL;

	packet = rad_recv(listener->fd, 0);
	if (!packet) {
		radlog(L_ERR, "%s", fr_strerror());
		return 0;
	}

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch(packet->code) {
	case PW_AUTHENTICATION_ACK:
	case PW_ACCESS_CHALLENGE:
	case PW_AUTHENTICATION_REJECT:
#ifdef WITH_ACCOUNTING
	case PW_ACCOUNTING_RESPONSE:
#endif
		break;

#ifdef WITH_COA
	case PW_DISCONNECT_ACK:
	case PW_DISCONNECT_NAK:
	case PW_COA_ACK:
	case PW_COA_NAK:
		fun = rad_coa_reply; /* run NEW function */
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
 		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	request = received_proxy_response(packet);
	if (!request) {
		return 0;
	}

	rad_assert(request->process != NULL);

#ifdef WITH_COA
	if (!fun)
#endif
	  fun = request->process; /* re-run original function */
	*pfun = fun;
	*prequest = request;

	return 1;
}
Exemplo n.º 13
0
process	netin(void) {

	status	retval;			/* return value from function	*/
	recv_packets = 0;		/* initialize			*/
	
	netbufpool = mkbufpool(PACKLEN, UDP_SLOTS * UDP_QSIZ +
				ICMP_SLOTS * ICMP_QSIZ + ICMP_OQSIZ + 1);

	if (netbufpool == SYSERR) {
		kprintf("Cannot allocate network buffer pool");
		kill(getpid());
	}

	/* Copy Ethernet address to global variable */

	control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethaddr, 0);

	/* Indicate that IP address, mask, and router are not yet valid	*/

	NetData.ipvalid = FALSE;

	NetData.ipaddr = 0;
	NetData.addrmask = 0;
	NetData.routeraddr = 0;

	/* Initialize ARP cache */

	arp_init();

	/* Initialize UDP table */

	udp_init();

	currpkt = (struct netpacket *)getbuf(netbufpool);

	/* Do forever: read packets from the network and process */

//kprintf("[netin]: start to read packets\r\n");
	while(1) {
	    	retval = read(ETHER0, (char *)currpkt, PACKLEN);
	    	if (retval == SYSERR) {
			panic("Ethernet read error");
	    	}

		/* Convert Ethernet Type to host order */

		eth_ntoh(currpkt);

		/* Demultiplex on Ethernet type */

		switch (currpkt->net_ethtype) {

			case ETH_ARP:
				arp_in();	/* Handle an ARP packet	*/
				continue;

			case ETH_IP:

				/* Convert IP packet to host order */

				if (ipcksum(currpkt) != 0) {
					kprintf("checksum failed\n\r");
					continue;
				}

				if (currpkt->net_ipvh != 0x45) {
					kprintf("version failed\n\r");
					continue;
				}

                                /* Convert IP packet to host byte order */

                                ip_ntoh(currpkt);

				if ( (currpkt->net_ipdst != IP_BCAST) &&
				     (NetData.ipvalid) &&
				     (currpkt->net_ipdst != NetData.ipaddr) ) {
					continue;
				}

				/* Demultiplex UDP and ignore others */

				if (currpkt->net_ipproto == IP_UDP) {
//kprintf("[netin]: UDP# %d\r\n", ++recv_packets);	
					udp_in();/* Handle a UDP packet	*/
				}
				continue;

			default: /* Ignore all other Ethernet types */
				kprintf("\n");
				continue;		
		}
	}
}
Exemplo n.º 14
0
RADCLIENT *client_from_request(RADCLIENT_LIST *clients, REQUEST *request)
{
	int i, *pi;
	char **p;
	RADCLIENT *c;
	char buffer[128];

	if (!clients || !request) return NULL;

	c = talloc_zero(clients, RADCLIENT);
	c->cs = request->client->cs;
	c->ipaddr.af = AF_UNSPEC;
	c->src_ipaddr.af = AF_UNSPEC;

	for (i = 0; dynamic_config[i].name != NULL; i++) {
		DICT_ATTR const *da;
		VALUE_PAIR *vp;

		da = dict_attrbyname(dynamic_config[i].name);
		if (!da) {
			DEBUG("- Cannot add client %s: attribute \"%s\"is not in the dictionary",
			      ip_ntoh(&request->packet->src_ipaddr,
				      buffer, sizeof(buffer)),
			      dynamic_config[i].name);
		error:
			client_free(c);
			return NULL;
		}

		vp = pairfind(request->config_items, da->attr, da->vendor, TAG_ANY);
		if (!vp) {
			/*
			 *	Not required.  Skip it.
			 */
			if (!dynamic_config[i].dflt) continue;

			DEBUG("- Cannot add client %s: Required attribute \"%s\" is missing.",
			      ip_ntoh(&request->packet->src_ipaddr,
				      buffer, sizeof(buffer)),
			      dynamic_config[i].name);
			goto error;
		}

		switch (dynamic_config[i].type) {
		case PW_TYPE_IPV4_ADDR:
			if (da->attr == PW_FREERADIUS_CLIENT_IP_ADDRESS) {
				c->ipaddr.af = AF_INET;
				c->ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
				c->ipaddr.prefix = 32;
			} else if (da->attr == PW_FREERADIUS_CLIENT_SRC_IP_ADDRESS) {
#ifdef WITH_UDPFROMTO
				c->src_ipaddr.af = AF_INET;
				c->src_ipaddr.ipaddr.ip4addr.s_addr = vp->vp_ipaddr;
#else
				WARN("Server not built with udpfromto, ignoring FreeRADIUS-Client-Src-IP-Address");
#endif
			}

			break;

		case PW_TYPE_IPV6_ADDR:
			if (da->attr == PW_FREERADIUS_CLIENT_IPV6_ADDRESS) {
				c->ipaddr.af = AF_INET6;
				c->ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
				c->ipaddr.prefix = 128;
			} else if (da->attr == PW_FREERADIUS_CLIENT_SRC_IPV6_ADDRESS) {
#ifdef WITH_UDPFROMTO
				c->src_ipaddr.af = AF_INET6;
				c->src_ipaddr.ipaddr.ip6addr = vp->vp_ipv6addr;
#else
				WARN("Server not built with udpfromto, ignoring FreeRADIUS-Client-Src-IPv6-Address");
#endif
			}

			break;

		case PW_TYPE_IPV4_PREFIX:
			if (da->attr == PW_FREERADIUS_CLIENT_IP_PREFIX) {
				c->ipaddr.af = AF_INET;
				memcpy(&c->ipaddr.ipaddr.ip4addr.s_addr, &(vp->vp_ipv4prefix[2]), sizeof(c->ipaddr.ipaddr.ip4addr.s_addr));
				fr_ipaddr_mask(&c->ipaddr, (vp->vp_ipv4prefix[1] & 0x3f));
			}

			break;

		case PW_TYPE_IPV6_PREFIX:
			if (da->attr == PW_FREERADIUS_CLIENT_IPV6_PREFIX) {
				c->ipaddr.af = AF_INET6;
				memcpy(&c->ipaddr.ipaddr.ip6addr, &(vp->vp_ipv6prefix[2]), sizeof(c->ipaddr.ipaddr.ip6addr));
				fr_ipaddr_mask(&c->ipaddr, vp->vp_ipv6prefix[1]);
			}

			break;

		case PW_TYPE_STRING:
			p = (char **) ((char *) c + dynamic_config[i].offset);
			if (*p) talloc_free(*p);
			if (vp->vp_strvalue[0]) {
				*p = talloc_typed_strdup(c->cs, vp->vp_strvalue);
			} else {
				*p = NULL;
			}
			break;

		case PW_TYPE_BOOLEAN:
			pi = (int *) ((bool *) ((char *) c + dynamic_config[i].offset));
			*pi = vp->vp_integer;
			break;

		default:
			goto error;
		}
	}

	if (c->ipaddr.af == AF_UNSPEC) {
		DEBUG("- Cannot add client %s: No IP address was specified.",
		      ip_ntoh(&request->packet->src_ipaddr,
			      buffer, sizeof(buffer)));

		goto error;
	}

	{
		fr_ipaddr_t addr;

		/*
		 *	Need to apply the same mask as we set for the client
		 *	else clients created with FreeRADIUS-Client-IPv6-Prefix
		 *	or FreeRADIUS-Client-IPv4-Prefix will fail this check.
		 */
		addr = request->packet->src_ipaddr;
		fr_ipaddr_mask(&addr, c->ipaddr.prefix);
		if (fr_ipaddr_cmp(&addr, &c->ipaddr) != 0) {
			char buf2[128];

			DEBUG("- Cannot add client %s: IP address %s do not match",
			      ip_ntoh(&request->packet->src_ipaddr, buffer, sizeof(buffer)),
			      ip_ntoh(&c->ipaddr, buf2, sizeof(buf2)));
			goto error;
		}
	}

	if (!c->secret || !*c->secret) {
		DEBUG("- Cannot add client %s: No secret was specified.",
		      ip_ntoh(&request->packet->src_ipaddr,
			      buffer, sizeof(buffer)));
		goto error;
	}

	if (!client_validate(clients, request->client, c)) {
		return NULL;
	}

	if ((c->src_ipaddr.af != AF_UNSPEC) && (c->src_ipaddr.af != c->ipaddr.af)) {
		DEBUG("- Cannot add client %s: Client IP and src address are different IP version.",
		      ip_ntoh(&request->packet->src_ipaddr,
			      buffer, sizeof(buffer)));

		goto error;
	}

	return c;
}
Exemplo n.º 15
0
static RADCLIENT *client_parse(CONF_SECTION *cs, int in_server)
{
	RADCLIENT	*c;
	char const	*name2;

	name2 = cf_section_name2(cs);
	if (!name2) {
		cf_log_err_cs(cs, "Missing client name");
		return NULL;
	}

	/*
	 *	The size is fine.. Let's create the buffer
	 */
	c = talloc_zero(cs, RADCLIENT);
	c->cs = cs;

	memset(&cl_ipaddr, 0, sizeof(cl_ipaddr));
	if (cf_section_parse(cs, c, client_config) < 0) {
		cf_log_err_cs(cs, "Error parsing client section");
	error:
		client_free(c);
#ifdef WITH_TCP
		hs_proto = NULL;
		cl_srcipaddr = NULL;
#endif

		return NULL;
	}

	/*
	 *	Global clients can set servers to use per-server clients cannot.
	 */
	if (in_server && c->server) {
		cf_log_err_cs(cs, "Clients inside of an server section cannot point to a server");
		goto error;
	}

	/*
	 *	Newer style client definitions with either ipaddr or ipaddr6
	 *	config items.
	 */
	if (cf_pair_find(cs, "ipaddr") || cf_pair_find(cs, "ipv4addr") || cf_pair_find(cs, "ipv6addr")) {
		char buffer[128];

		/*
		 *	Sets ipv4/ipv6 address and prefix.
		 */
		c->ipaddr = cl_ipaddr;

		/*
		 *	Set the long name to be the result of a reverse lookup on the IP address.
		 */
		ip_ntoh(&c->ipaddr, buffer, sizeof(buffer));
		c->longname = talloc_typed_strdup(c, buffer);

		/*
		 *	Set the short name to the name2.
		 */
		if (!c->shortname) c->shortname = talloc_typed_strdup(c, name2);
	/*
	 *	No "ipaddr" or "ipv6addr", use old-style "client <ipaddr> {" syntax.
	 */
	} else {
		ERROR("No 'ipaddr' or 'ipv4addr' or 'ipv6addr' configuration directive found in client %s", name2);
		goto error;
	}

	c->proto = IPPROTO_UDP;
	if (hs_proto) {
		if (strcmp(hs_proto, "udp") == 0) {
			hs_proto = NULL;

#ifdef WITH_TCP
		} else if (strcmp(hs_proto, "tcp") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
#  ifdef WITH_TLS
		} else if (strcmp(hs_proto, "tls") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
			c->tls_required = true;

		} else if (strcmp(hs_proto, "radsec") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_TCP;
			c->tls_required = true;
#  endif
		} else if (strcmp(hs_proto, "*") == 0) {
			hs_proto = NULL;
			c->proto = IPPROTO_IP; /* fake for dual */
#endif
		} else {
			cf_log_err_cs(cs, "Unknown proto \"%s\".", hs_proto);
			goto error;
		}
	}

	/*
	 *	If a src_ipaddr is specified, when we send the return packet
	 *	we will use this address instead of the src from the
	 *	request.
	 */
	if (cl_srcipaddr) {
#ifdef WITH_UDPFROMTO
		switch (c->ipaddr.af) {
		case AF_INET:
			if (fr_pton4(&c->src_ipaddr, cl_srcipaddr, 0, true, false) < 0) {
				cf_log_err_cs(cs, "Failed parsing src_ipaddr: %s", fr_strerror());
				goto error;
			}
			break;

		case AF_INET6:
			if (fr_pton6(&c->src_ipaddr, cl_srcipaddr, 0, true, false) < 0) {
				cf_log_err_cs(cs, "Failed parsing src_ipaddr: %s", fr_strerror());
				goto error;
			}
			break;
		default:
			rad_assert(0);
		}
#else
		WARN("Server not built with udpfromto, ignoring client src_ipaddr");
#endif
		cl_srcipaddr = NULL;
	}

	FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, >=, 0, 1000);
	FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, <=, 60, 0);
	FR_TIMEVAL_BOUND_CHECK("response_window", &c->response_window, <=, main_config.max_request_time, 0);

#ifdef WITH_DYNAMIC_CLIENTS
	if (c->client_server) {
		c->secret = talloc_typed_strdup(c, "testing123");

		if (((c->ipaddr.af == AF_INET) && (c->ipaddr.prefix == 32)) ||
		    ((c->ipaddr.af == AF_INET6) && (c->ipaddr.prefix == 128))) {
			cf_log_err_cs(cs, "Dynamic clients MUST be a network, not a single IP address");
			goto error;
		}

		return c;
	}
#endif

	if (!c->secret || (c->secret[0] == '\0')) {
#ifdef WITH_DHCP
		char const *value = NULL;
		CONF_PAIR *cp = cf_pair_find(cs, "dhcp");

		if (cp) value = cf_pair_value(cp);

		/*
		 *	Secrets aren't needed for DHCP.
		 */
		if (value && (strcmp(value, "yes") == 0)) return c;
#endif

#ifdef WITH_TLS
		/*
		 *	If the client is TLS only, the secret can be
		 *	omitted.  When omitted, it's hard-coded to
		 *	"radsec".  See RFC 6614.
		 */
		if (c->tls_required) {
			c->secret = talloc_typed_strdup(cs, "radsec");
		} else
#endif

		{
			cf_log_err_cs(cs,
				      "secret must be at least 1 character long");
			goto error;
		}
	}

#ifdef WITH_COA
	/*
	 *	Point the client to the home server pool, OR to the
	 *	home server.  This gets around the problem of figuring
	 *	out which port to use.
	 */
	if (c->coa_name) {
		c->coa_pool = home_pool_byname(c->coa_name, HOME_TYPE_COA);
		if (!c->coa_pool) {
			c->coa_server = home_server_byname(c->coa_name,
							   HOME_TYPE_COA);
		}
		if (!c->coa_pool && !c->coa_server) {
			cf_log_err_cs(cs, "No such home_server or home_server_pool \"%s\"", c->coa_name);
			goto error;
		}
	}
#endif

#ifdef WITH_TCP
	if ((c->proto == IPPROTO_TCP) || (c->proto == IPPROTO_IP)) {
		if ((c->limit.idle_timeout > 0) && (c->limit.idle_timeout < 5))
			c->limit.idle_timeout = 5;
		if ((c->limit.lifetime > 0) && (c->limit.lifetime < 5))
			c->limit.lifetime = 5;
		if ((c->limit.lifetime > 0) && (c->limit.idle_timeout > c->limit.lifetime))
			c->limit.idle_timeout = 0;
	}
#endif

	return c;
}
Exemplo n.º 16
0
int proxy_tls_recv(rad_listen_t *listener)
{
	int rcode;
	size_t length;
	listen_socket_t *sock = listener->data;
	char buffer[256];
	RADIUS_PACKET *packet;
	RAD_REQUEST_FUNP fun = NULL;
	uint8_t *data;

	if (!sock->data) sock->data = rad_malloc(sock->ssn->offset);
	data = sock->data;

	DEBUG3("Proxy SSL socket has data to read");
	PTHREAD_MUTEX_LOCK(&sock->mutex);
redo:
	rcode = SSL_read(sock->ssn->ssl, data, 4);
	if (rcode <= 0) {
		int err = SSL_get_error(sock->ssn->ssl, rcode);
		switch (err) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			rcode = 0;
			goto redo;
		case SSL_ERROR_ZERO_RETURN:
			/* remote end sent close_notify, send one back */
			SSL_shutdown(sock->ssn->ssl);

		case SSL_ERROR_SYSCALL:
		do_close:
			PTHREAD_MUTEX_UNLOCK(&sock->mutex);
			tls_socket_close(listener);
			return 0;

		default:
			while ((err = ERR_get_error())) {
				DEBUG("proxy recv says %s",
				      ERR_error_string(err, NULL));
			}
			
			goto do_close;
		}
	}

	length = (data[2] << 8) | data[3];
	DEBUG3("Proxy received header saying we have a packet of %u bytes",
	       (unsigned int) length);

	if (length > sock->ssn->offset) {
		radlog(L_INFO,
		       "Received packet will be too large! Set \"fragment_size=%u\"",
		       (data[2] << 8) | data[3]);
		goto do_close;
	}
	
	rcode = SSL_read(sock->ssn->ssl, data + 4, length);
	if (rcode <= 0) {
		switch (SSL_get_error(sock->ssn->ssl, rcode)) {
		case SSL_ERROR_WANT_READ:
		case SSL_ERROR_WANT_WRITE:
			rcode = 0;
			break;

		case SSL_ERROR_ZERO_RETURN:
			/* remote end sent close_notify, send one back */
			SSL_shutdown(sock->ssn->ssl);
			goto do_close;
		default:
			goto do_close;
		}
	}
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	packet = rad_alloc(0);
	packet->sockfd = listener->fd;
	packet->src_ipaddr = sock->other_ipaddr;
	packet->src_port = sock->other_port;
	packet->dst_ipaddr = sock->my_ipaddr;
	packet->dst_port = sock->my_port;
	packet->code = data[0];
	packet->id = data[1];
	packet->data_len = length;
	packet->data = rad_malloc(packet->data_len);
	memcpy(packet->data, data, packet->data_len);
	memcpy(packet->vector, packet->data + 4, 16);

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch(packet->code) {
	case PW_AUTHENTICATION_ACK:
	case PW_ACCESS_CHALLENGE:
	case PW_AUTHENTICATION_REJECT:
		fun = rad_authenticate;
		break;

#ifdef WITH_ACCOUNTING
	case PW_ACCOUNTING_RESPONSE:
		fun = rad_accounting;
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		radlog(L_ERR, "Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	if (!request_proxy_reply(packet)) {
		rad_free(&packet);
		return 0;
	}

	return 1;
}
Exemplo n.º 17
0
int proxy_tls_recv(rad_listen_t *listener)
{
	listen_socket_t *sock = listener->data;
	char buffer[256];
	RADIUS_PACKET *packet;
	uint8_t *data;
	ssize_t data_len;

	if (listener->status != RAD_LISTEN_STATUS_KNOWN) return 0;

	DEBUG3("Proxy SSL socket has data to read");
	PTHREAD_MUTEX_LOCK(&sock->mutex);
	data_len = proxy_tls_read(listener);
	PTHREAD_MUTEX_UNLOCK(&sock->mutex);

	if (data_len < 0) {
		DEBUG("Closing TLS socket to home server");
		PTHREAD_MUTEX_LOCK(&sock->mutex);
		tls_socket_close(listener);
		PTHREAD_MUTEX_UNLOCK(&sock->mutex);
		return 0;
	}

	if (data_len == 0) return 0; /* not done yet */

	data = sock->data;

	packet = rad_alloc(sock, false);
	packet->sockfd = listener->fd;
	packet->src_ipaddr = sock->other_ipaddr;
	packet->src_port = sock->other_port;
	packet->dst_ipaddr = sock->my_ipaddr;
	packet->dst_port = sock->my_port;
	packet->code = data[0];
	packet->id = data[1];
	packet->data_len = data_len;
	packet->data = talloc_array(packet, uint8_t, packet->data_len);
	memcpy(packet->data, data, packet->data_len);
	memcpy(packet->vector, packet->data + 4, 16);

	/*
	 *	FIXME: Client MIB updates?
	 */
	switch (packet->code) {
	case PW_CODE_ACCESS_ACCEPT:
	case PW_CODE_ACCESS_CHALLENGE:
	case PW_CODE_ACCESS_REJECT:
		break;

#ifdef WITH_ACCOUNTING
	case PW_CODE_ACCOUNTING_RESPONSE:
		break;
#endif

	default:
		/*
		 *	FIXME: Update MIB for packet types?
		 */
		ERROR("Invalid packet code %d sent to a proxy port "
		       "from home server %s port %d - ID %d : IGNORED",
		       packet->code,
		       ip_ntoh(&packet->src_ipaddr, buffer, sizeof(buffer)),
		       packet->src_port, packet->id);
		rad_free(&packet);
		return 0;
	}

	if (!request_proxy_reply(packet)) {
		rad_free(&packet);
		return 0;
	}

	return 1;
}
Exemplo n.º 18
0
process	netin(void) {

	status	retval;			/* return value from function	*/
        int i=0;
        struct ipv4_packet* ippkt = NULL;

        /*
         * FIXME : This might now work
         */
	netbufpool = mkbufpool(PACKLEN, UDP_SLOTS * UDP_QSIZ +
				ICMP_SLOTS * ICMP_QSIZ + ICMP_OQSIZ + 1);

	if (netbufpool == SYSERR) {
		kprintf("Cannot allocate network buffer pool");
		kill(getpid());
	}

	/* Copy Ethernet address to global variable */

	control(ETHER0, ETH_CTRL_GET_MAC, (int32)NetData.ethaddr, 0);

	/* Indicate that IP address, mask, and router are not yet valid	*/

	NetData.ipvalid = FALSE;

	NetData.ipaddr = 0;
	NetData.addrmask = 0;
	NetData.routeraddr = 0;


        kprintf("My Mac is : %06x\r\n", *(NetData.ethaddr+4));

	/* Initialize ARP cache */

	arp_init();

	/* Initialize UDP table */

	udp_init();

        
	currpkt = (struct eth_packet *)getbuf(netbufpool);

	/* Do forever: read packets from the network and process */

	while(1) {
	    	retval = read(ETHER0, (char *)currpkt, PACKLEN);
	    	if (retval == SYSERR) {
			panic("Ethernet read error");
	    	}

		/* Convert Ethernet Type to host order */
		eth_ntoh(currpkt);
		/* Demultiplex on Ethernet type */

		switch (currpkt->net_ethtype) {

			case ETH_ARP:
				arp_in();	/* Handle an ARP packet	*/
				continue;

			case ETH_IP:
                                //kprintf("Ip packet received \r\n");
                                ippkt = (struct ipv4_packet *)(currpkt->net_ethdata);

				if (ipcksum(ippkt) != 0) {
					kprintf("checksum failed\n\r");
					continue;
				}

				if (ippkt->net_ipvh != 0x45) {
					kprintf("version failed\n\r");
					continue;
				}

				/* Convert IP packet to host order */
                                ip_ntoh(ippkt);

                                if ( (ippkt->net_ipdst != IP_BCAST) &&
				     (NetData.ipvalid) &&
				     (ippkt->net_ipdst != NetData.ipaddr) ) {
					continue;
				}

				/* Demultiplex UDP and ignore others */

				if (ippkt->net_ipproto == IP_UDP) {
					udp_in();/* Handle a UDP packet	*/
				}else if (ippkt->net_ipproto == IP_ICMP){
                                        kprintf("ICMP Packet \r\n");
					icmp_in();/* Handle ICMP packet */
				}
				continue;

                        case 0x1000:
#ifdef DEBUG
                                kprintf("Received a simulator packet\r\n");
#endif
                                wait(rpl_sim_write_sem);
                                memcpy((char *)&sim_queue[i], currpkt->net_ethdata, sizeof(struct rpl_sim_packet));
#ifdef DEBUG
                                kprintf("Netin working with iter [%d] message type : %d dest : %04x source : %04x\r\n",i, sim_queue[i].msg_type, *((uint32 *)(sim_queue[i].dest_node)), *((uint32 *)(sim_queue[i].src_node)));
#endif
                                signal(rpl_sim_read_sem);
                                i = (i+1)%RPL_SIM_RECV_QUEUE_LEN;
                                continue;

			default: /* Ignore all other Ethernet types */
				continue;		
		}
	}
}