Example #1
0
int
auth_client_untrust(const char *mac)
{
	int rc = -1;

	LOCK_CONFIG();

	if (!remove_from_trusted_mac_list(mac) && !iptables_untrust_mac(mac)) {
		rc = 0;
	}

	UNLOCK_CONFIG();

/*
	if (rc == 0) {
		LOCK_CLIENT_LIST();
		t_client * client = client_list_find_by_mac(mac);
		if (client) {
			rc = auth_change_state(client, FW_MARK_PREAUTHENTICATED, "manual_untrust");
			if (rc == 0) {
				client->session_start = 0;
				client->session_end = 0;
			}
		}
		UNLOCK_CLIENT_LIST();
	}
*/

	return rc;
}
Example #2
0
int
iptables_fw_deauthenticate(t_client *client)
{
	int download_limit, upload_limit, traffic_control;
	s_config *config;
	char upload_ifbname[16];
	int rc = 0;

	config = config_get_config();
	sprintf(upload_ifbname, "ifb%d", config->upload_ifb);

	LOCK_CONFIG();
	traffic_control = config->traffic_control;
	download_limit = config->download_limit;
	upload_limit = config->upload_limit;
	UNLOCK_CONFIG();

	if ((client->download_limit > 0) && (client->upload_limit > 0)) {
		download_limit = client->download_limit;
		upload_limit = client->upload_limit;
	}

	/* Remove the authentication rules. */
	debug(LOG_NOTICE, "Deauthenticating %s %s", client->ip, client->mac);
	rc |= iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x", client->ip, client->mac, markop, FW_MARK_AUTHENTICATED);
	rc |= iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j MARK %s 0x%x", client->ip, markop, FW_MARK_AUTHENTICATED);
	rc |= iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);

	if (traffic_control) {
		rc |= tc_detach_client(config->gw_interface, download_limit, upload_ifbname, upload_limit, client->id);
	}

	return rc;
}
Example #3
0
/** Insert or delete firewall mangle rules marking a client's packets.
 */
int
iptables_fw_authenticate(t_client *client)
{
	int rc = 0, download_limit, upload_limit, traffic_control;
	s_config *config;
	char upload_ifbname[16];

	config = config_get_config();
	sprintf(upload_ifbname, "ifb%d", config->upload_ifb);

	LOCK_CONFIG();
	traffic_control = config->traffic_control;
	download_limit = config->download_limit;
	upload_limit = config->upload_limit;
	UNLOCK_CONFIG();

	if ((client->download_limit > 0) && (client->upload_limit > 0)) {
		download_limit = client->download_limit;
		upload_limit = client->upload_limit;
	}

	debug(LOG_NOTICE, "Authenticating %s %s", client->ip, client->mac);
	/* This rule is for marking upload (outgoing) packets, and for upload byte counting */
	rc |= iptables_do_command("-t mangle -A " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x", client->ip, client->mac, markop, FW_MARK_AUTHENTICATED);
	rc |= iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j MARK %s 0x%x", client->ip, markop, FW_MARK_AUTHENTICATED);
	/* This rule is just for download (incoming) byte counting, see iptables_fw_counters_update() */
	rc |= iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);

	if (traffic_control) {
		rc |= tc_attach_client(config->gw_interface, download_limit, upload_ifbname, upload_limit, client->id, client->ip);
	}

	return rc;
}
Example #4
0
int connect_auth_server() {
	int sockfd;

	LOCK_CONFIG();
	sockfd = _connect_auth_server(0);
	UNLOCK_CONFIG();

	return (sockfd);
}
Example #5
0
/** Insert or delete firewall mangle rules marking a client's packets.
 */
int
iptables_fw_access(t_authaction action, t_client *client)
{
	int rc = 0, download_limit, upload_limit, traffic_control;
	s_config *config;
	char *download_imqname, *upload_imqname;

	fw_quiet = 0;

	config = config_get_config();
	safe_asprintf(&download_imqname,"imq%d",config->download_imq); /* must free */
	safe_asprintf(&upload_imqname,"imq%d",config->upload_imq);  /* must free */

	LOCK_CONFIG();
	traffic_control = config->traffic_control;
	download_limit = config->download_limit;
	upload_limit = config->upload_limit;
	UNLOCK_CONFIG();

	if ((client->download_limit > 0) && (client->upload_limit > 0)) {
		download_limit = client->download_limit;
		upload_limit = client->upload_limit;
	}

	switch(action) {
	case AUTH_MAKE_AUTHENTICATED:
		debug(LOG_NOTICE, "Authenticating %s %s", client->ip, client->mac);
		/* This rule is for marking upload (outgoing) packets, and for upload byte counting */
		rc |= iptables_do_command("-t mangle -A " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x%x", client->ip, client->mac, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
		rc |= iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j MARK %s 0x%x%x", client->ip, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
		/* This rule is just for download (incoming) byte counting, see iptables_fw_counters_update() */
		rc |= iptables_do_command("-t mangle -A " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);
		if (traffic_control) {
			rc |= tc_attach_client(download_imqname, download_limit, upload_imqname, upload_limit, client->idx, FW_MARK_AUTHENTICATED);
		}
		break;
	case AUTH_MAKE_DEAUTHENTICATED:
		/* Remove the authentication rules. */
		debug(LOG_NOTICE, "Deauthenticating %s %s", client->ip, client->mac);
		rc |= iptables_do_command("-t mangle -D " CHAIN_OUTGOING " -s %s -m mac --mac-source %s -j MARK %s 0x%x%x", client->ip, client->mac, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
		rc |= iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j MARK %s 0x%x%x", client->ip, markop, client->idx + 10, FW_MARK_AUTHENTICATED);
		rc |= iptables_do_command("-t mangle -D " CHAIN_INCOMING " -d %s -j ACCEPT", client->ip);
		if (traffic_control) {
			rc |= tc_detach_client(download_imqname, upload_imqname, client->idx);
		}
		break;
	default:
		rc = -1;
		break;
	}

	free(upload_imqname);
	free(download_imqname);
	return rc;
}
Example #6
0
int
auth_client_unblock(const char *mac)
{
	int rc = -1;

	LOCK_CONFIG();

	if (!remove_from_blocked_mac_list(mac) && !iptables_unblock_mac(mac)) {
		rc = 0;
	}

	UNLOCK_CONFIG();

	return rc;
}
Example #7
0
int
auth_client_block(const char *mac)
{
	int rc = -1;

	LOCK_CONFIG();

	if (!add_to_blocked_mac_list(mac) && !iptables_block_mac(mac)) {
		rc = 0;
	}

	UNLOCK_CONFIG();

	return rc;
}
Example #8
0
/* Tries really hard to connect to an auth server. Returns a file descriptor, -1 on error
 */
int connect_auth_server() {
	int sockfd;

	LOCK_CONFIG();
	sockfd = _connect_auth_server(0);
	UNLOCK_CONFIG();

	if (sockfd == -1) {
		debug(LOG_ERR, "Failed to connect to any of the auth servers");
		mark_auth_offline();
	}
	else {
		debug(LOG_DEBUG, "Connected to auth server");
		mark_auth_online();
	}
	return (sockfd);
}
static void
ndsctl_untrust(int fd, char *arg)
{
	debug(LOG_DEBUG, "Entering ndsctl_untrust...");

	LOCK_CONFIG();
	debug(LOG_DEBUG, "Argument: [%s]", arg);

	if (!remove_from_trusted_mac_list(arg) && !iptables_untrust_mac(arg)) {
		write(fd, "Yes", 3);
	} else {
		write(fd, "No", 2);
	}

	UNLOCK_CONFIG();

	debug(LOG_DEBUG, "Exiting ndsctl_untrust.");
}
Example #10
0
static void
ndsctl_allow(int fd, char *arg)
{
	debug(LOG_DEBUG, "Entering ndsctl_allow...");

	LOCK_CONFIG();
	debug(LOG_DEBUG, "Argument: [%s]", arg);

	if (!add_to_allowed_mac_list(arg) && !iptables_allow_mac(arg)) {
		write(fd, "Yes", 3);
	} else {
		write(fd, "No", 2);
	}

	UNLOCK_CONFIG();

	debug(LOG_DEBUG, "Exiting ndsctl_allow.");
}
Example #11
0
static char *
get_maclist_text(int which)
{
	pstr_t *pstr = NULL;
    s_config *config;
	t_trusted_mac *maclist = NULL;
	int line = 0;
    config = config_get_config();
    
	switch(which) {
	case TRUSTED_MAC:
		pstr = pstr_new();
		maclist = config->trustedmaclist; 
		pstr_cat(pstr, "\nTrusted mac list:\n");
		break;
	case UNTRUSTED_MAC:
		pstr = pstr_new();
		maclist = config->mac_blacklist;
		pstr_cat(pstr, "\nUntrusted mac list:\n");
		break;
	case ROAM_MAC:
		pstr = pstr_new();
		maclist = config->roam_maclist;
		pstr_cat(pstr, "\nRoam mac list:\n");
		break;
	default:
		return NULL;
	}
	
	LOCK_CONFIG();
	
	for (; maclist != NULL; maclist = maclist->next) {
        pstr_append_sprintf(pstr, " %s ", maclist->mac);
		line++;
		if(line == 4) {
			line = 0;
			pstr_append_sprintf(pstr, "\n");
		}
	}
	
	UNLOCK_CONFIG();
    
	return pstr_to_string(pstr);
}
Example #12
0
char *
get_serialize_maclist(int which)
{
	pstr_t *pstr = NULL;
    s_config *config;
	t_trusted_mac *maclist = NULL;
	int line = 0;
    config = config_get_config();
	
	switch(which) {
	case TRUSTED_MAC:
		maclist = config->trustedmaclist; 
		break;
	case UNTRUSTED_MAC:
		maclist = config->mac_blacklist;
		break;
	case ROAM_MAC:
		maclist = config->roam_maclist;
		break;
	default:
		return NULL;
	}
	
	if(maclist != NULL)
		pstr = pstr_new();
	else
		return NULL;

	LOCK_CONFIG();
	
	
	for (; maclist != NULL; maclist = maclist->next, line++) {
		if(line == 0)
        	pstr_append_sprintf(pstr, "%s", maclist->mac);
		else	
        	pstr_append_sprintf(pstr, ",%s", maclist->mac);
	}
	
	UNLOCK_CONFIG();
    
	return pstr_to_string(pstr);

}
Example #13
0
static void
ndsctl_username(int fd, char *arg)
{
	debug(LOG_DEBUG, "Entering ndsctl_username...");

	LOCK_CONFIG();
	debug(LOG_DEBUG, "Argument: [%s]", arg);


	if (!set_username(arg)) {
		write(fd, "Yes", 3);
		debug(LOG_NOTICE, "Set username to %s.", arg);
	} else {
		write(fd, "No", 2);
	}

	UNLOCK_CONFIG();

	debug(LOG_DEBUG, "Exiting ndsctl_username.");
}
/*
 * Given a well-known name structure, generate a binary-format SID.
 * It's a bit perverse that we must take a text-format SID and turn it into
 * a binary-format SID, only to have the caller probably turn it back into
 * text format, but SIDs are carried across LDAP in binary format.
 */
static
directory_error_t
sid_dav(directory_values_rpc *lvals, const wksids_table_t *wksid)
{
	char *text_sid;
	sid_t *sid;
	directory_error_t de;

	if (wksid->sidprefix == NULL) {
		RDLOCK_CONFIG();
		(void) asprintf(&text_sid, "%s-%d",
		    _idmapdstate.cfg->pgcfg.machine_sid,
		    wksid->rid);
		UNLOCK_CONFIG();
	} else {
		(void) asprintf(&text_sid, "%s-%d",
		    wksid->sidprefix, wksid->rid);
	}

	if (text_sid == NULL)
		goto nomem;

	sid = sid_fromstr(text_sid);
	free(text_sid);

	if (sid == NULL)
		goto nomem;

	sid_to_le(sid);

	de = bin_list_dav(lvals, sid, 1, sid_len(sid));

	sid_free(sid);

	return (de);

nomem:
	return (directory_error("ENOMEM.sid_dav",
	    "No memory allocating SID for user lookup", NULL));
}
Example #15
0
static void
ndsctl_loglevel(int fd, char *arg)
{
	int level = atoi(arg);

	debug(LOG_DEBUG, "Entering ndsctl_loglevel...");

	LOCK_CONFIG();
	debug(LOG_DEBUG, "Argument: [%s]", arg);


	if (!set_log_level(level)) {
		write(fd, "Yes", 3);
		debug(LOG_NOTICE, "Set debug loglevel to %d.", level);
	} else {
		write(fd, "No", 2);
	}

	UNLOCK_CONFIG();

	debug(LOG_DEBUG, "Exiting ndsctl_loglevel.");
}
/** in connect function emong added,for quickly find useable server

*/
int in_connect_auth_server(t_auth_serv *server) {
	int sockfd,level=0;
	s_config *config = config_get_config();
	t_auth_serv *tmp_server;
	for (tmp_server = config->auth_servers; tmp_server; tmp_server = tmp_server->next) {
		if(tmp_server == server)	//find it
			break;
		++level;
	}
	LOCK_CONFIG();
	sockfd = _connect_auth_server(level,0);
	UNLOCK_CONFIG();

	if (sockfd == -1) {
		debug(LOG_ERR, "Failed to connect to any of the auth servers");
		mark_auth_offline();
	}
	else {
		debug(LOG_DEBUG, "Connected to auth server");
		mark_auth_online();
	}
	return (sockfd);
}
/*
 * @return A string containing human-readable status text. MUST BE free()d by caller
 */
char * get_status_text() {
	char buffer[STATUS_BUF_SIZ];
	ssize_t len;
	s_config *config;
	t_auth_serv *auth_server;
	t_client	*first;
	int		count;
	unsigned long int uptime = 0;
	unsigned int days = 0, hours = 0, minutes = 0, seconds = 0;
     t_trusted_mac *p;
	
	len = 0;
	snprintf(buffer, (sizeof(buffer) - len), "WiFiDog status\n\n");
	len = strlen(buffer);

	uptime = time(NULL) - started_time;
	days    = uptime / (24 * 60 * 60);
	uptime -= days * (24 * 60 * 60);
	hours   = uptime / (60 * 60);
	uptime -= hours * (60 * 60);
	minutes = uptime / 60;
	uptime -= minutes * 60;
	seconds = uptime;

	snprintf((buffer + len), (sizeof(buffer) - len), "Version: " VERSION "\n");
	len = strlen(buffer);

	snprintf((buffer + len), (sizeof(buffer) - len), "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds);
	len = strlen(buffer);

	snprintf((buffer + len), (sizeof(buffer) - len), "Has been restarted: ");
	len = strlen(buffer);
	if (restart_orig_pid) {
		snprintf((buffer + len), (sizeof(buffer) - len), "yes (from PID %d)\n", restart_orig_pid);
		len = strlen(buffer);
	}
	else {
		snprintf((buffer + len), (sizeof(buffer) - len), "no\n");
		len = strlen(buffer);
	}
	
	snprintf((buffer + len), (sizeof(buffer) - len), "Internet Connectivity: %s\n", (is_online() ? "yes" : "no"));
	len = strlen(buffer);
	
	snprintf((buffer + len), (sizeof(buffer) - len), "Auth server reachable: %s\n", (is_auth_online() ? "yes" : "no"));
	len = strlen(buffer);

	snprintf((buffer + len), (sizeof(buffer) - len), "Clients served this session: %lu\n\n", served_this_session);
	len = strlen(buffer);

	LOCK_CLIENT_LIST();
	
	first = client_get_first_client();
	
	if (first == NULL) {
		count = 0;
	} else {
		count = 1;
		while (first->next != NULL) {
			first = first->next;
			count++;
		}
	}
	
	snprintf((buffer + len), (sizeof(buffer) - len), "%d clients "
			"connected.\n", count);
	len = strlen(buffer);

	first = client_get_first_client();

	count = 0;
	while (first != NULL) {
		snprintf((buffer + len), (sizeof(buffer) - len), "\nClient %d\n", count);
		len = strlen(buffer);

		snprintf((buffer + len), (sizeof(buffer) - len), "  IP: %s MAC: %s\n", first->ip, first->mac);
		len = strlen(buffer);

		snprintf((buffer + len), (sizeof(buffer) - len), "  Token: %s\n", first->token);
		len = strlen(buffer);

		snprintf((buffer + len), (sizeof(buffer) - len), "  Downloaded: %llu\n  Uploaded: %llu\n" , first->counters.incoming, first->counters.outgoing);
		len = strlen(buffer);

		count++;
		first = first->next;
	}

	UNLOCK_CLIENT_LIST();

    config = config_get_config();
    
    if (config->trustedmaclist != NULL) {
        snprintf((buffer + len), (sizeof(buffer) - len), "\nTrusted MAC addresses:\n");
        len = strlen(buffer);

        for (p = config->trustedmaclist; p != NULL; p = p->next) {
            snprintf((buffer + len), (sizeof(buffer) - len), "  %s\n", p->mac);
            len = strlen(buffer);
        }
    }

    snprintf((buffer + len), (sizeof(buffer) - len), "\nAuthentication servers:\n");
    len = strlen(buffer);

    LOCK_CONFIG();

    for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
        snprintf((buffer + len), (sizeof(buffer) - len), "  Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip);
        len = strlen(buffer);
    }

    UNLOCK_CONFIG();

	return safe_strdup(buffer);
}
Example #18
0
void
print_idmapdstate(void)
{
	int i, j;
	idmap_pg_config_t *pgcfg;
	idmap_trustedforest_t *tf;

	RDLOCK_CONFIG();

	if (_idmapdstate.cfg == NULL) {
		idmapdlog(LOG_INFO, "Null configuration");
		UNLOCK_CONFIG();
		return;
	}

	pgcfg = &_idmapdstate.cfg->pgcfg;

	idmapdlog(LOG_DEBUG, "list_size_limit=%llu", pgcfg->list_size_limit);
	idmapdlog(LOG_DEBUG, "default_domain=%s",
	    CHECK_NULL(pgcfg->default_domain));
	idmapdlog(LOG_DEBUG, "domain_name=%s", CHECK_NULL(pgcfg->domain_name));
	idmapdlog(LOG_DEBUG, "machine_sid=%s", CHECK_NULL(pgcfg->machine_sid));
	if (pgcfg->domain_controller == NULL ||
	    pgcfg->domain_controller[0].host[0] == '\0') {
		idmapdlog(LOG_DEBUG, "No domain controllers known");
	} else {
		for (i = 0; pgcfg->domain_controller[i].host[0] != '\0'; i++)
			idmapdlog(LOG_DEBUG, "domain_controller=%s port=%d",
			    pgcfg->domain_controller[i].host,
			    pgcfg->domain_controller[i].port);
	}
	idmapdlog(LOG_DEBUG, "forest_name=%s", CHECK_NULL(pgcfg->forest_name));
	idmapdlog(LOG_DEBUG, "site_name=%s", CHECK_NULL(pgcfg->site_name));
	if (pgcfg->global_catalog == NULL ||
	    pgcfg->global_catalog[0].host[0] == '\0') {
		idmapdlog(LOG_DEBUG, "No global catalog servers known");
	} else {
		for (i = 0; pgcfg->global_catalog[i].host[0] != '\0'; i++)
			idmapdlog(LOG_DEBUG, "global_catalog=%s port=%d",
			    pgcfg->global_catalog[i].host,
			    pgcfg->global_catalog[i].port);
	}
	if (pgcfg->domains_in_forest == NULL ||
	    pgcfg->domains_in_forest[0].domain[0] == '\0') {
		idmapdlog(LOG_DEBUG, "No domains in forest %s known",
		    CHECK_NULL(pgcfg->forest_name));
	} else {
		for (i = 0; pgcfg->domains_in_forest[i].domain[0] != '\0'; i++)
			idmapdlog(LOG_DEBUG, "domains in forest %s = %s",
			    CHECK_NULL(pgcfg->forest_name),
			    pgcfg->domains_in_forest[i].domain);
	}
	if (pgcfg->trusted_domains == NULL ||
	    pgcfg->trusted_domains[0].domain[0] == '\0') {
		idmapdlog(LOG_DEBUG, "No trusted domains known");
	} else {
		for (i = 0; pgcfg->trusted_domains[i].domain[0] != '\0'; i++)
			idmapdlog(LOG_DEBUG, "trusted domain = %s",
			    pgcfg->trusted_domains[i].domain);
	}

	for (i = 0; i < pgcfg->num_trusted_forests; i++) {
		tf = &pgcfg->trusted_forests[i];
		for (j = 0; tf->global_catalog[j].host[0] != '\0'; j++)
			idmapdlog(LOG_DEBUG,
			    "trusted forest %s global_catalog=%s port=%d",
			    tf->forest_name,
			    tf->global_catalog[j].host,
			    tf->global_catalog[j].port);
		for (j = 0; tf->domains_in_forest[j].domain[0] != '\0'; j++) {
			if (tf->domains_in_forest[j].trusted) {
				idmapdlog(LOG_DEBUG,
				    "trusted forest %s domain=%s",
				    tf->forest_name,
				    tf->domains_in_forest[j].domain);
			}
		}
	}

	idmapdlog(LOG_DEBUG, "directory_based_mapping=%s",
	    enum_lookup(pgcfg->directory_based_mapping, directory_mapping_map));
	idmapdlog(LOG_DEBUG, "ad_unixuser_attr=%s",
	    CHECK_NULL(pgcfg->ad_unixuser_attr));
	idmapdlog(LOG_DEBUG, "ad_unixgroup_attr=%s",
	    CHECK_NULL(pgcfg->ad_unixgroup_attr));
	idmapdlog(LOG_DEBUG, "nldap_winname_attr=%s",
	    CHECK_NULL(pgcfg->nldap_winname_attr));

	UNLOCK_CONFIG();
}
/*
 * Given a well-known name entry and a list of attributes that were
 * requested, populate the structure to return to the caller.
 */
static
directory_error_t
directory_provider_builtin_populate(
    directory_entry_rpc *pent,
    const wksids_table_t *wksid,
    idmap_utf8str_list *attrs)
{
	int j;
	directory_values_rpc *llvals;
	int nattrs;

	nattrs = attrs->idmap_utf8str_list_len;

	llvals = calloc(nattrs, sizeof (directory_values_rpc));
	if (llvals == NULL)
		goto nomem;

	pent->status = DIRECTORY_FOUND;
	pent->directory_entry_rpc_u.attrs.attrs_val = llvals;
	pent->directory_entry_rpc_u.attrs.attrs_len = nattrs;

	for (j = 0; j < nattrs; j++) {
		directory_values_rpc *val;
		char *a;
		directory_error_t de;

		/*
		 * We're going to refer to these a lot, so make a shorthand
		 * copy.
		 */
		a = attrs->idmap_utf8str_list_val[j];
		val = &llvals[j];

		/*
		 * Start by assuming no errors and that we don't have
		 * the information.
		 */
		val->found = FALSE;
		de = NULL;

		if (uu_strcaseeq(a, "uid")) {
			de = str_list_dav(val, &wksid->winname, 1);
		} else if (uu_strcaseeq(a, "uidNumber")) {
			if (wksid->pid != IDMAP_SENTINEL_PID &&
			    wksid->is_user) {
				de = uint_list_dav(val, &wksid->pid, 1);
			}
		} else if (uu_strcaseeq(a, "gidNumber")) {
			if (wksid->pid != IDMAP_SENTINEL_PID &&
			    !wksid->is_user) {
				de = uint_list_dav(val, &wksid->pid, 1);
			}
		} else if (uu_strcaseeq(a, "displayName") ||
		    uu_strcaseeq(a, "cn")) {
			de = str_list_dav(val, &wksid->winname, 1);
		} else if (uu_strcaseeq(a, "distinguishedName")) {
			char *container;
			if (wksid->domain == NULL) {
				container = "Users";
			} else {
				container = "Builtin";
			}
			RDLOCK_CONFIG();
			char *dn;
			(void) asprintf(&dn,
			    "CN=%s,CN=%s,DC=%s",
			    wksid->winname, container, _idmapdstate.hostname);
			UNLOCK_CONFIG();
			const char *cdn = dn;
			de = str_list_dav(val, &cdn, 1);
			free(dn);
		} else if (uu_strcaseeq(a, "objectClass")) {
			if (wksid->is_wuser) {
				static const char *objectClasses[] = {
					"top",
					"person",
					"organizationalPerson",
					"user",
				};
				de = str_list_dav(val, objectClasses,
				    UU_NELEM(objectClasses));
			} else {
				static const char *objectClasses[] = {
					"top",
					"group",
				};
				de = str_list_dav(val, objectClasses,
				    UU_NELEM(objectClasses));
			}
		} else if (uu_strcaseeq(a, "objectSid")) {
			de = sid_dav(val, wksid);
		} else if (uu_strcaseeq(a, "x-sun-canonicalName")) {
			char *canon;

			if (wksid->domain == NULL) {
				RDLOCK_CONFIG();
				(void) asprintf(&canon, "%s@%s",
				    wksid->winname, _idmapdstate.hostname);
				UNLOCK_CONFIG();
			} else if (uu_streq(wksid->domain, "")) {
				canon = strdup(wksid->winname);
			} else {
				(void) asprintf(&canon, "%s@%s",
				    wksid->winname, wksid->domain);
			}

			if (canon == NULL)
				goto nomem;
			const char *ccanon = canon;
			de = str_list_dav(val, &ccanon, 1);
			free(canon);
		} else if (uu_strcaseeq(a, "x-sun-provider")) {
			const char *provider = "Builtin";
			de = str_list_dav(val, &provider, 1);
		}
		if (de != NULL)
			return (de);
	}

	return (NULL);

nomem:
	return (directory_error("ENOMEM.users",
	    "No memory allocating return value for user lookup", NULL));
}
Example #20
0
        /*
         * @return A string containing human-readable status text. MUST BE free()d by caller
         */
char *
get_status_text()
{
    pstr_t *pstr = pstr_new();
    s_config *config;
    t_auth_serv *auth_server;
    t_client *sublist, *current;
    int count;
    time_t uptime = 0;
    unsigned int days = 0, hours = 0, minutes = 0, seconds = 0;
    t_trusted_mac *p;
	t_offline_client *oc_list;

    pstr_cat(pstr, "WiFiDog status\n\n");

    uptime = time(NULL) - started_time;
    days = (unsigned int)uptime / (24 * 60 * 60);
    uptime -= days * (24 * 60 * 60);
    hours = (unsigned int)uptime / (60 * 60);
    uptime -= hours * (60 * 60);
    minutes = (unsigned int)uptime / 60;
    uptime -= minutes * 60;
    seconds = (unsigned int)uptime;

    pstr_cat(pstr, "Version: " VERSION "\n");
    pstr_append_sprintf(pstr, "Uptime: %ud %uh %um %us\n", days, hours, minutes, seconds);
    pstr_cat(pstr, "Has been restarted: ");

    if (restart_orig_pid) {
        pstr_append_sprintf(pstr, "yes (from PID %d)\n", restart_orig_pid);
    } else {
        pstr_cat(pstr, "no\n");
    }

    pstr_append_sprintf(pstr, "Internet Connectivity: %s\n", (is_online()? "yes" : "no"));
    pstr_append_sprintf(pstr, "Auth server reachable: %s\n", (is_auth_online()? "yes" : "no"));
    pstr_append_sprintf(pstr, "Clients served this session: %lu\n\n", served_this_session);

    LOCK_CLIENT_LIST();

    count = client_list_dup(&sublist);

    UNLOCK_CLIENT_LIST();

    current = sublist;

    pstr_append_sprintf(pstr, "%d clients " "connected.\n", count);

    count = 1;
    while (current != NULL) {
        pstr_append_sprintf(pstr, "\nClient %d status [%d]\n", count, current->is_online);
        pstr_append_sprintf(pstr, "  IP: %s MAC: %s\n", current->ip, current->mac);
        pstr_append_sprintf(pstr, "  Token: %s\n", current->token);
        pstr_append_sprintf(pstr, "  First Login: %lld\n", (long long)current->first_login);
        pstr_append_sprintf(pstr, "  Name: %s\n", current->name != NULL?current->name:"null");
        pstr_append_sprintf(pstr, "  Downloaded: %llu\n  Uploaded: %llu\n", current->counters.incoming,
                            current->counters.outgoing);
        count++;
        current = current->next;
    }

    client_list_destroy(sublist);

	LOCK_OFFLINE_CLIENT_LIST();
    pstr_append_sprintf(pstr, "%d clients " "unconnected.\n", offline_client_number());
	oc_list = client_get_first_offline_client();
	while(oc_list != NULL) {	
        pstr_append_sprintf(pstr, "  IP: %s MAC: %s Last Login: %lld Hit Counts: %d Client Type: %d Temp Passed: %d\n", 
			oc_list->ip, oc_list->mac, (long long)oc_list->last_login, 
			oc_list->hit_counts, oc_list->client_type, oc_list->temp_passed);
		oc_list = oc_list->next;
	}
	UNLOCK_OFFLINE_CLIENT_LIST();

    config = config_get_config();

    LOCK_CONFIG();

    if (config->trustedmaclist != NULL) {
        pstr_cat(pstr, "\nTrusted MAC addresses:\n");

        for (p = config->trustedmaclist; p != NULL; p = p->next) {
            pstr_append_sprintf(pstr, "  %s\n", p->mac);
        }
    }

    pstr_cat(pstr, "\nAuthentication servers:\n");


    for (auth_server = config->auth_servers; auth_server != NULL; auth_server = auth_server->next) {
        pstr_append_sprintf(pstr, "  Host: %s (%s)\n", auth_server->authserv_hostname, auth_server->last_ip);
    }

    UNLOCK_CONFIG();

    return pstr_to_string(pstr);
}
Example #21
0
/** Initialize the firewall rules.
 */
int
iptables_fw_init(void)
{
	s_config *config;
	char * gw_interface = NULL;
	char * gw_address = NULL;
	char * gw_iprange = NULL;
	int gw_port = 0;
	int traffic_control;
	int set_mss, mss_value;
	t_MAC *pt;
	t_MAC *pb;
	t_MAC *pa;
	int rc = 0, mmask = 0, macmechanism;

	LOCK_CONFIG();
	config = config_get_config();
	gw_interface = safe_strdup(config->gw_interface); /* must free */
	gw_address = safe_strdup(config->gw_address);    /* must free */
	gw_iprange = safe_strdup(config->gw_iprange);    /* must free */
	gw_port = config->gw_port;
	pt = config->trustedmaclist;
	pb = config->blockedmaclist;
	pa = config->allowedmaclist;
	macmechanism = config->macmechanism;
	set_mss = config->set_mss;
	mss_value = config->mss_value;
	traffic_control = config->traffic_control;
	FW_MARK_BLOCKED = config->FW_MARK_BLOCKED;
	FW_MARK_TRUSTED = config->FW_MARK_TRUSTED;
	FW_MARK_AUTHENTICATED = config->FW_MARK_AUTHENTICATED;
	UNLOCK_CONFIG();


	/* Set up packet marking methods */
	rc |= _iptables_init_marks();
	rc |= _iptables_check_mark_masking();

	/*
	 *
	 **************************************
	 * Set up mangle table chains and rules
	 *
	 */

	/* Create new chains in the mangle table */
	rc |= iptables_do_command("-t mangle -N " CHAIN_TRUSTED); /* for marking trusted packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_BLOCKED); /* for marking blocked packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_INCOMING); /* for counting incoming packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_OUTGOING); /* for marking authenticated packets, and for counting outgoing packets */

	/* Assign jumps to these new chains */
	rc |= iptables_do_command("-t mangle -I PREROUTING 1 -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I PREROUTING 2 -i %s -s %s -j " CHAIN_BLOCKED, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I PREROUTING 3 -i %s -s %s -j " CHAIN_TRUSTED, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -d %s -j " CHAIN_INCOMING, gw_interface, gw_iprange);

	/* Rules to mark as trusted MAC address packets in mangle PREROUTING */
	for (; pt != NULL; pt = pt->next) {
		rc |= iptables_trust_mac(pt->mac);
	}

	/* Rules to mark as blocked MAC address packets in mangle PREROUTING */
	if(MAC_BLOCK == macmechanism) {
		/* with the MAC_BLOCK mechanism,
		 * MAC's on the block list are marked as blocked;
		 * everything else passes */
		for (; pb != NULL; pb = pb->next) {
			rc |= iptables_block_mac(pb->mac);
		}
	} else if(MAC_ALLOW == macmechanism) {
		/* with the MAC_ALLOW mechanism,
		 * MAC's on the allow list pass;
		 * everything else is to be marked as blocked */
		/* So, append at end of chain a rule to mark everything blocked */
		rc |= iptables_do_command("-t mangle -A " CHAIN_BLOCKED " -j MARK %s 0x%x", markop, FW_MARK_BLOCKED);
		/* But insert at beginning of chain rules to pass allowed MAC's */
		for (; pa != NULL; pa = pa->next) {
			rc |= iptables_allow_mac(pa->mac);
		}
	} else {
		debug(LOG_ERR, "Unknown MAC mechanism: %d",
			  macmechanism);
		rc = -1;
	}

	/* Set up for traffic control */
	if(traffic_control) {
		rc |= tc_init_tc();
	}

	/*
	 * End of mangle table chains and rules
	 **************************************
	 */

	/*
	 *
	 **************************************
	 * Set up nat table chains and rules
	 *
	 */

	/* Create new chains in nat table */
	rc |= iptables_do_command("-t nat -N " CHAIN_OUTGOING);

	/*
	 * nat PREROUTING chain
	 */

	/* packets coming in on gw_interface jump to CHAIN_OUTGOING */
	rc |= iptables_do_command("-t nat -A PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
	/* CHAIN_OUTGOING, packets marked TRUSTED  ACCEPT */
	rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j ACCEPT", FW_MARK_TRUSTED, markmask);
	/* CHAIN_OUTGOING, packets marked AUTHENTICATED  ACCEPT */
	rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j ACCEPT",FW_MARK_AUTHENTICATED, markmask);
	/* CHAIN_OUTGOING, append the "preauthenticated-users" ruleset */
	rc |= _iptables_append_ruleset("nat", "preauthenticated-users", CHAIN_OUTGOING);

	/* CHAIN_OUTGOING, packets for tcp port 80, redirect to gw_port on primary address for the iface */
	rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --dport 80 -j DNAT --to-destination %s:%d", gw_address, gw_port);
	/* CHAIN_OUTGOING, other packets  ACCEPT */
	rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -j ACCEPT");

	/*
	 * End of nat table chains and rules
	 **************************************
	 */

	/*
	 *
	 **************************************
	 * Set up filter table chains and rules
	 *
	 */

	/* Create new chains in the filter table */
	rc |= iptables_do_command("-t filter -N " CHAIN_TO_INTERNET);
	rc |= iptables_do_command("-t filter -N " CHAIN_TO_ROUTER);
	rc |= iptables_do_command("-t filter -N " CHAIN_AUTHENTICATED);
	rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED);
	rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED_TO_ROUTER);

	/*
	 * filter INPUT chain
	 */

	/* packets coming in on gw_interface jump to CHAIN_TO_ROUTER */
	rc |= iptables_do_command("-t filter -I INPUT -i %s -s %s -j " CHAIN_TO_ROUTER, gw_interface, gw_iprange);
	/* CHAIN_TO_ROUTER packets marked BLOCKED  DROP */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask);
	/* CHAIN_TO_ROUTER, invalid packets  DROP */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m state --state INVALID -j DROP");
	/* CHAIN_TO_ROUTER, related and established packets  ACCEPT */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m state --state RELATED,ESTABLISHED -j ACCEPT");
	/* CHAIN_TO_ROUTER, bogus SYN packets  DROP */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --tcp-flags SYN SYN \\! --tcp-option 2 -j  DROP");

	/* CHAIN_TO_ROUTER, packets to HTTP listening on gw_port on router ACCEPT */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", gw_port);

	/* CHAIN_TO_ROUTER, packets marked TRUSTED: */

	/* if trusted-users-to-router ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_TRUSTED_TO_ROUTER, and load and use users-to-router ruleset
	 */
	if(is_empty_ruleset("trusted-users-to-router")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users-to-router"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED_TO_ROUTER, FW_MARK_TRUSTED, markmask);
		/* CHAIN_TRUSTED_TO_ROUTER, related and established packets  ACCEPT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -m state --state RELATED,ESTABLISHED -j ACCEPT");
		/* CHAIN_TRUSTED_TO_ROUTER, append the "trusted-users-to-router" ruleset */
		rc |= _iptables_append_ruleset("filter", "trusted-users-to-router", CHAIN_TRUSTED_TO_ROUTER);
		/* CHAIN_TRUSTED_TO_ROUTER, any packets not matching that ruleset  REJECT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -j REJECT --reject-with icmp-port-unreachable");
	}

	/* CHAIN_TO_ROUTER, other packets: */

	/* if users-to-router ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    load and use users-to-router ruleset
	 */
	if(is_empty_ruleset("users-to-router")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j %s", get_empty_ruleset_policy("users-to-router"));
	} else {
		/* CHAIN_TO_ROUTER, append the "users-to-router" ruleset */
		rc |= _iptables_append_ruleset("filter", "users-to-router", CHAIN_TO_ROUTER);
		/* everything else, REJECT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j REJECT --reject-with icmp-port-unreachable");

	}

	/*
	 * filter FORWARD chain
	 */

	/* packets coming in on gw_interface jump to CHAIN_TO_INTERNET */
	rc |= iptables_do_command("-t filter -A FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange);
	/* CHAIN_TO_INTERNET packets marked BLOCKED  DROP */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask);
	/* CHAIN_TO_INTERNET, invalid packets  DROP */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m state --state INVALID -j DROP");
	/* CHAIN_TO_INTERNET, deal with MSS */
	if (set_mss) {
		/* XXX this mangles, so 'should' be done in the mangle POSTROUTING chain.
		 * However OpenWRT standard S35firewall does it in filter FORWARD,
		 * and since we are pre-empting that chain here, we put it in */
		if (mss_value > 0) { /* set specific MSS value */
			rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", mss_value);
		} else { /* allow MSS as large as possible */
			rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu");
		}
	}

	/* CHAIN_TO_INTERNET, packets marked TRUSTED: */

	/* if trusted-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_TRUSTED, and load and use trusted-users ruleset
	 */
	if(is_empty_ruleset("trusted-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED, FW_MARK_TRUSTED, markmask);
		/* CHAIN_TRUSTED, related and established packets  ACCEPT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -m state --state RELATED,ESTABLISHED -j ACCEPT");
		/* CHAIN_TRUSTED, append the "trusted-users" ruleset */
		rc |= _iptables_append_ruleset("filter", "trusted-users", CHAIN_TRUSTED);
		/* CHAIN_TRUSTED, any packets not matching that ruleset  REJECT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -j REJECT --reject-with icmp-port-unreachable");
	}


	/* CHAIN_TO_INTERNET, packets marked AUTHENTICATED: */

	/* if authenticated-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_AUTHENTICATED, and load and use authenticated-users ruleset
	 */
	if(is_empty_ruleset("authenticated-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_AUTHENTICATED, markmask, get_empty_ruleset_policy("authenticated-users"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_AUTHENTICATED, FW_MARK_AUTHENTICATED, markmask);
		/* CHAIN_AUTHENTICATED, related and established packets  ACCEPT */
		rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -m state --state RELATED,ESTABLISHED -j ACCEPT");
		/* CHAIN_AUTHENTICATED, append the "authenticated-users" ruleset */
		rc |= _iptables_append_ruleset("filter", "authenticated-users", CHAIN_AUTHENTICATED);
		/* CHAIN_AUTHENTICATED, any packets not matching that ruleset  REJECT */
		rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -j REJECT --reject-with icmp-port-unreachable");
	}

	/* CHAIN_TO_INTERNET, other packets: */

	/* if preauthenticated-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    load and use authenticated-users ruleset
	 */
	if(is_empty_ruleset("preauthenticated-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j %s ",  get_empty_ruleset_policy("preauthenticated-users"));
	} else {
		rc |= _iptables_append_ruleset("filter", "preauthenticated-users", CHAIN_TO_INTERNET);
	}
	/* CHAIN_TO_INTERNET, all other packets REJECT */
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j REJECT --reject-with icmp-port-unreachable");

	/*
	 * End of filter table chains and rules
	 **************************************
	 */

	free(gw_interface);
	free(gw_iprange);
	free(gw_address);

	return rc;
}
Example #22
0
	int
iptables_fw_init(void)
{
	const s_config *config;
	char * ext_interface = NULL;  // 获取WAN口名称
	int gw_port = 0;
	t_trusted_mac *p;

	fw_quiet = 0;

	LOCK_CONFIG();
	config = config_get_config();
	gw_port = config->gw_port;
	if (config->external_interface) {
		ext_interface = safe_strdup(config->external_interface);
	} else {
		ext_interface = get_ext_iface(); // 获取WAN口名称
	}

	if (ext_interface == NULL) {
		UNLOCK_CONFIG();
		debug(LOG_ERR, "FATAL: no external interface");
		return 0;
	}
	/*
	 *
	 * Everything in the MANGLE table
	 *
	 */

	/* Create new chains */// 创建自定义规则链
	// modified by lijg, 2013-05-17, 取消打标记
	//iptables_do_command("-t mangle -N " TABLE_WIFIDOG_TRUSTED);
	IPT_DO_CMMD("-t mangle -N " TABLE_WIFIDOG_OUTGOING);
	IPT_DO_CMMD("-t mangle -N " TABLE_WIFIDOG_INCOMING);

	/* Assign links and rules to these new chains */
	// modified by lijg, 2013-04-24, avoid confliting with QoS
	IPT_DO_CMMD("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface);
	//iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " TABLE_WIFIDOG_TRUSTED, config->gw_interface);//this rule will be inserted before the prior one


	IPT_DO_CMMD("-t mangle -I POSTROUTING 1 -o %s -j " TABLE_WIFIDOG_INCOMING, config->gw_interface);

    // modified by lijg, 2013-05-17, avoid confliting with QoS
    //for (p = config->trustedmaclist; p != NULL; p = p->next)
	//	iptables_do_command("-t mangle -A " TABLE_WIFIDOG_TRUSTED " -m mac --mac-source %s -j MARK --or-mark %d", p->mac, FW_MARK_KNOWN);

	/*
	 *
	 * Everything in the NAT table
	 *
	 */

	/* Create new chains */
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_OUTGOING);
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_WIFI_TO_ROUTER);
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_GLOBAL);
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_UNKNOWN);
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_AUTHSERVERS);

	// add by lijg, 2013-08-14, create chains for white list
	IPT_DO_CMMD("-t nat -N " TABLE_WIFIDOG_WLIST);

	/* Assign links and rules to these new chains */
	IPT_DO_CMMD("-t nat -A PREROUTING -i %s -j " TABLE_WIFIDOG_OUTGOING, config->gw_interface);

	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_OUTGOING " -d %s -j " TABLE_WIFIDOG_WIFI_TO_ROUTER, config->gw_address);
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_WIFI_TO_ROUTER " -j ACCEPT");

	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_OUTGOING " -j " TABLE_WIFIDOG_WIFI_TO_INTERNET);
	// modified by lijg, 2013-04-24, match mark mask = ff00
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%04x/0xff00 -j ACCEPT", FW_MARK_KNOWN);
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%04x/0xff00 -j ACCEPT", FW_MARK_PROBATION);

	// add by lijg, 2013-08-14, add a white list chain
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_WLIST);
	
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);

	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_AUTHSERVERS);
	// modified by lijg, 2013-05-17, 取消该规则
	//iptables_do_command("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -j " TABLE_WIFIDOG_GLOBAL);
	IPT_DO_CMMD("-t nat -A " TABLE_WIFIDOG_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);


	/*
	 *
	 * Everything in the FILTER table
	 *
	 */

	/* Create new chains */
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_WIFI_TO_INTERNET);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_AUTHSERVERS);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_LOCKED);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_GLOBAL);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_VALIDATE);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_KNOWN);
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_UNKNOWN);

	// add by lijg, 2013-08-14, create chains for white list
	IPT_DO_CMMD("-t filter -N " TABLE_WIFIDOG_WLIST);

	/* Assign links and rules to these new chains */

	/* Insert at the beginning */
	IPT_DO_CMMD("-t filter -I FORWARD -i %s -j " TABLE_WIFIDOG_WIFI_TO_INTERNET, config->gw_interface);


	//IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state INVALID -j DROP");

	/* XXX: Why this? it means that connections setup after authentication
	   stay open even after the connection is done...
	   iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT");*/

	//Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23
	//iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface);

	/* TCPMSS rule for PPPoE */
	// modified by lijg, 2013-05-28, cancel this fw rule , repeated in openwrt FW rules
	//iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface);

	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_AUTHSERVERS);
	iptables_fw_set_authservers();

	// modified by lijg, 2013-05-17, 取消匹配标记
	//iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%04x/0xff00 -j " TABLE_WIFIDOG_LOCKED, FW_MARK_LOCKED);
	//iptables_load_ruleset("filter", "locked-users", TABLE_WIFIDOG_LOCKED);

	//iptables_do_command("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_GLOBAL);
	//iptables_load_ruleset("filter", "global", TABLE_WIFIDOG_GLOBAL);
	//iptables_load_ruleset("nat", "global", TABLE_WIFIDOG_GLOBAL);

	// modified by lijg, 2013-05-17, 取消该规则
	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%04x/0xff00 -j " TABLE_WIFIDOG_VALIDATE, FW_MARK_PROBATION);
	iptables_load_ruleset("filter", "validating-users", TABLE_WIFIDOG_VALIDATE);

	// add by lijg, 2013-08-14, add a white list chain
	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_WLIST);

	// modified by lijg, 2013-05-17, 取消打标记
	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -m mark --mark 0x%04x/0xff00 -j " TABLE_WIFIDOG_KNOWN, FW_MARK_KNOWN);
	iptables_load_ruleset("filter", "known-users", TABLE_WIFIDOG_KNOWN);

	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_WIFI_TO_INTERNET " -j " TABLE_WIFIDOG_UNKNOWN);
	iptables_load_ruleset("filter", "unknown-users", TABLE_WIFIDOG_UNKNOWN);
	IPT_DO_CMMD("-t filter -A " TABLE_WIFIDOG_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");

	// add by lijg, 2013-08-14, Load wwlist config rule
	load_wwlist_conf("/etc/config/wwlist");

	UNLOCK_CONFIG();

	// add by lijg, 2013-05-17,
	free(ext_interface);
	return 1;
}
Example #23
0
/** Remove the firewall rules
 * This is used when we do a clean shutdown of nodogsplash,
 * and when it starts, to make sure there are no rules left over from a crash
 */
int
iptables_fw_destroy(void)
{
	fw_quiet = 1;
	s_config *config;
	int traffic_control;

	LOCK_CONFIG();
	config = config_get_config();
	traffic_control = config->traffic_control;
	UNLOCK_CONFIG();

	if (traffic_control) {
		debug(LOG_DEBUG, "Destroying our tc hooks");
		tc_destroy_tc();
	}

	debug(LOG_DEBUG, "Destroying our iptables entries");

	/* Everything in the mangle table */
	debug(LOG_DEBUG, "Destroying chains in the MANGLE table");
	iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_TRUSTED);
	iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_BLOCKED);
	iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_ALLOWED);
	iptables_fw_destroy_mention("mangle", "PREROUTING", CHAIN_OUTGOING);
	iptables_fw_destroy_mention("mangle", "POSTROUTING", CHAIN_INCOMING);
	iptables_do_command("-t mangle -F " CHAIN_TRUSTED);
	iptables_do_command("-t mangle -F " CHAIN_BLOCKED);
	iptables_do_command("-t mangle -F " CHAIN_ALLOWED);
	iptables_do_command("-t mangle -F " CHAIN_OUTGOING);
	iptables_do_command("-t mangle -F " CHAIN_INCOMING);
	iptables_do_command("-t mangle -X " CHAIN_TRUSTED);
	iptables_do_command("-t mangle -X " CHAIN_BLOCKED);
	iptables_do_command("-t mangle -X " CHAIN_ALLOWED);
	iptables_do_command("-t mangle -X " CHAIN_OUTGOING);
	iptables_do_command("-t mangle -X " CHAIN_INCOMING);

	/* Everything in the nat table (ip4 only) */
	if (!config->ip6) {
		debug(LOG_DEBUG, "Destroying chains in the NAT table");
		iptables_fw_destroy_mention("nat", "PREROUTING", CHAIN_OUTGOING);
		iptables_do_command("-t nat -F " CHAIN_OUTGOING);
		iptables_do_command("-t nat -X " CHAIN_OUTGOING);
	}

	/* Everything in the filter table */

	debug(LOG_DEBUG, "Destroying chains in the FILTER table");
	iptables_fw_destroy_mention("filter", "INPUT", CHAIN_TO_ROUTER);
	iptables_fw_destroy_mention("filter", "FORWARD", CHAIN_TO_INTERNET);
	iptables_do_command("-t filter -F " CHAIN_TO_ROUTER);
	iptables_do_command("-t filter -F " CHAIN_TO_INTERNET);
	iptables_do_command("-t filter -F " CHAIN_AUTHENTICATED);
	iptables_do_command("-t filter -F " CHAIN_TRUSTED);
	iptables_do_command("-t filter -F " CHAIN_TRUSTED_TO_ROUTER);
	iptables_do_command("-t filter -X " CHAIN_TO_ROUTER);
	iptables_do_command("-t filter -X " CHAIN_TO_INTERNET);
	iptables_do_command("-t filter -X " CHAIN_AUTHENTICATED);
	iptables_do_command("-t filter -X " CHAIN_TRUSTED);
	iptables_do_command("-t filter -X " CHAIN_TRUSTED_TO_ROUTER);

	fw_quiet = 0;

	return 0;
}
Example #24
0
/** Initialize the firewall rules.
 */
int
iptables_fw_init(void)
{
	s_config *config;
	int iptables_version;
	char *gw_interface = NULL;
	char *gw_ip = NULL;
	char *gw_address = NULL;
	char *gw_iprange = NULL;
	int gw_port = 0;
	char *fas_remoteip;
	int fas_port;
	int traffic_control;
	int set_mss, mss_value;
	t_MAC *pt;
	t_MAC *pb;
	t_MAC *pa;
	int rc = 0;
	int macmechanism;

	LOCK_CONFIG();
	config = config_get_config();
	gw_interface = safe_strdup(config->gw_interface); /* must free */
	
	/* ip4 vs ip6 differences */
	const char *ICMP_TYPE;
	if (config->ip6) {
		/* ip6 addresses must be in square brackets like [ffcc:e08::1] */
		safe_asprintf(&gw_ip, "[%s]", config->gw_ip); /* must free */
		ICMP_TYPE = "icmp6";
	} else {
		gw_ip = safe_strdup(config->gw_ip);    /* must free */
		ICMP_TYPE = "icmp";
	}
	
	gw_address = safe_strdup(config->gw_address);    /* must free */
	gw_iprange = safe_strdup(config->gw_iprange);    /* must free */
	gw_port = config->gw_port;
	fas_remoteip = safe_strdup(config->fas_remoteip);    /* must free */
	fas_port = config->fas_port;
	pt = config->trustedmaclist;
	pb = config->blockedmaclist;
	pa = config->allowedmaclist;
	macmechanism = config->macmechanism;
	set_mss = config->set_mss;
	mss_value = config->mss_value;
	traffic_control = config->traffic_control;
	FW_MARK_BLOCKED = config->fw_mark_blocked;
	FW_MARK_TRUSTED = config->fw_mark_trusted;
	FW_MARK_AUTHENTICATED = config->fw_mark_authenticated;
	UNLOCK_CONFIG();

	iptables_version = get_iptables_version();
	if (iptables_version < 0) {
		debug(LOG_ERR, "Cannot get iptables version.");
		return -1;
	}

	if (iptables_version < MIN_IPTABLES_VERSION) {
		debug(LOG_ERR, "Unsupported iptables version v%d.%d.%d, needs at least v%d.%d.%d.",
			(iptables_version / 10000),
			(iptables_version % 10000) / 100,
			(iptables_version % 100),
			(MIN_IPTABLES_VERSION / 10000),
			(MIN_IPTABLES_VERSION % 10000) / 100,
			(MIN_IPTABLES_VERSION % 100)
		);
		return -1;
	}

	/* Set up packet marking methods */
	rc |= _iptables_init_marks();
	rc |= _iptables_check_mark_masking();

	/*
	 *
	 **************************************
	 * Set up mangle table chains and rules
	 *
	 */

	/* Create new chains in the mangle table */
	rc |= iptables_do_command("-t mangle -N " CHAIN_TRUSTED); /* for marking trusted packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_BLOCKED); /* for marking blocked packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_ALLOWED); /* for marking allowed packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_INCOMING); /* for counting incoming packets */
	rc |= iptables_do_command("-t mangle -N " CHAIN_OUTGOING); /* for marking authenticated packets, and for counting outgoing packets */

	/* Assign jumps to these new chains */
	rc |= iptables_do_command("-t mangle -I PREROUTING 1 -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I PREROUTING 2 -i %s -s %s -j " CHAIN_BLOCKED, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I PREROUTING 3 -i %s -s %s -j " CHAIN_TRUSTED, gw_interface, gw_iprange);
	rc |= iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -d %s -j " CHAIN_INCOMING, gw_interface, gw_iprange);

	/* Rules to mark as trusted MAC address packets in mangle PREROUTING */
	for (; pt != NULL; pt = pt->next) {
		rc |= iptables_trust_mac(pt->mac);
	}

	/* Rules to mark as blocked MAC address packets in mangle PREROUTING */
	if (MAC_BLOCK == macmechanism) {
		/* with the MAC_BLOCK mechanism,
		 * MAC's on the block list are marked as blocked;
		 * everything else passes */
		for (; pb != NULL; pb = pb->next) {
			rc |= iptables_block_mac(pb->mac);
		}
	} else if (MAC_ALLOW == macmechanism) {
		/* with the MAC_ALLOW mechanism,
		 * MAC's on the allow list pass;
		 * everything else is to be marked as blocked */
		// So, append at end of chain a rule to mark everything blocked
		rc |= iptables_do_command("-t mangle -A " CHAIN_BLOCKED " -j MARK %s 0x%x", markop, FW_MARK_BLOCKED);
		// But insert at beginning of chain rules to pass allowed MAC's
		for (; pa != NULL; pa = pa->next) {
			rc |= iptables_allow_mac(pa->mac);
		}
	} else {
		debug(LOG_ERR, "Unknown MAC mechanism: %d", macmechanism);
		rc = -1;
	}

	/* Set up for traffic control */
	if (traffic_control) {
		rc |= tc_init_tc();
	}

	/*
	 * End of mangle table chains and rules
	 **************************************
	 */

	/*
	 *
	 **************************************
	 * Set up nat table chains and rules (ip4 only)
	 *
	 */
	 
	if (!config->ip6) {
		/* Create new chains in nat table */
		rc |= iptables_do_command("-t nat -N " CHAIN_OUTGOING);

		/*
		 * nat PREROUTING chain
		 */

		// packets coming in on gw_interface jump to CHAIN_OUTGOING
		rc |= iptables_do_command("-t nat -I PREROUTING -i %s -s %s -j " CHAIN_OUTGOING, gw_interface, gw_iprange);
		// CHAIN_OUTGOING, packets marked TRUSTED  ACCEPT
		rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j RETURN", FW_MARK_TRUSTED, markmask);
		// CHAIN_OUTGOING, packets marked AUTHENTICATED  ACCEPT
		rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -m mark --mark 0x%x%s -j RETURN", FW_MARK_AUTHENTICATED, markmask);
		// CHAIN_OUTGOING, append the "preauthenticated-users" ruleset
		rc |= _iptables_append_ruleset("nat", "preauthenticated-users", CHAIN_OUTGOING);

		// Allow access to remote FAS - CHAIN_OUTGOING and CHAIN_TO_INTERNET packets for remote FAS, ACCEPT
		if (fas_port && strcmp(fas_remoteip, gw_ip)) {
			rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --destination %s --dport %d -j ACCEPT", fas_remoteip, fas_port);
		}

		// CHAIN_OUTGOING, packets for tcp port 80, redirect to gw_port on primary address for the iface
		rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -p tcp --dport 80 -j DNAT --to-destination %s", gw_address);
		// CHAIN_OUTGOING, other packets ACCEPT
		rc |= iptables_do_command("-t nat -A " CHAIN_OUTGOING " -j ACCEPT");
	}
	/*
	 * End of nat table chains and rules (ip4 only)
	 **************************************
	 */

	/*
	 *
	 **************************************
	 * Set up filter table chains and rules
	 *
	 */

	// Create new chains in the filter table
	rc |= iptables_do_command("-t filter -N " CHAIN_TO_INTERNET);
	rc |= iptables_do_command("-t filter -N " CHAIN_TO_ROUTER);
	rc |= iptables_do_command("-t filter -N " CHAIN_AUTHENTICATED);
	rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED);
	rc |= iptables_do_command("-t filter -N " CHAIN_TRUSTED_TO_ROUTER);

	/*
	 * filter INPUT chain
	 */

	// packets coming in on gw_interface jump to CHAIN_TO_ROUTER
	rc |= iptables_do_command("-t filter -I INPUT -i %s -s %s -j " CHAIN_TO_ROUTER, gw_interface, gw_iprange);
	// CHAIN_TO_ROUTER packets marked BLOCKED DROP
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask);
	// CHAIN_TO_ROUTER, invalid packets DROP
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m conntrack --ctstate INVALID -j DROP");
	// CHAIN_TO_ROUTER, related and established packets ACCEPT
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
	// CHAIN_TO_ROUTER, bogus SYN packets DROP
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --tcp-flags SYN SYN \\! --tcp-option 2 -j DROP");

	// CHAIN_TO_ROUTER, packets to HTTP listening on gw_port on router ACCEPT
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", gw_port);

	// CHAIN_TO_ROUTER, packets to HTTP listening on fas_port on router ACCEPT
	if (fas_port && !strcmp(fas_remoteip, gw_ip)) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -p tcp --dport %d -j ACCEPT", fas_port);
	}

	// CHAIN_TO_ROUTER, packets marked TRUSTED:

	/* if trusted-users-to-router ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_TRUSTED_TO_ROUTER, and load and use users-to-router ruleset
	 */
	if (is_empty_ruleset("trusted-users-to-router")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users-to-router"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED_TO_ROUTER, FW_MARK_TRUSTED, markmask);
		// CHAIN_TRUSTED_TO_ROUTER, related and established packets ACCEPT
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
		// CHAIN_TRUSTED_TO_ROUTER, append the "trusted-users-to-router" ruleset
		rc |= _iptables_append_ruleset("filter", "trusted-users-to-router", CHAIN_TRUSTED_TO_ROUTER);
		// CHAIN_TRUSTED_TO_ROUTER, any packets not matching that ruleset REJECT
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED_TO_ROUTER " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE);
	}

	// CHAIN_TO_ROUTER, other packets:

	/* if users-to-router ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    load and use users-to-router ruleset
	 */
	if (is_empty_ruleset("users-to-router")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j %s", get_empty_ruleset_policy("users-to-router"));
	} else {
		/* CHAIN_TO_ROUTER, append the "users-to-router" ruleset */
		rc |= _iptables_append_ruleset("filter", "users-to-router", CHAIN_TO_ROUTER);
		/* everything else, REJECT */
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_ROUTER " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE);

	}

	/*
	 * filter FORWARD chain
	 */

	// packets coming in on gw_interface jump to CHAIN_TO_INTERNET
	rc |= iptables_do_command("-t filter -I FORWARD -i %s -s %s -j " CHAIN_TO_INTERNET, gw_interface, gw_iprange);
	// CHAIN_TO_INTERNET packets marked BLOCKED DROP
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j DROP", FW_MARK_BLOCKED, markmask);
	// CHAIN_TO_INTERNET, invalid packets DROP
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m conntrack --ctstate INVALID -j DROP");
	// CHAIN_TO_INTERNET, deal with MSS
	if (set_mss) {
		/* XXX this mangles, so 'should' be done in the mangle POSTROUTING chain.
		 * However OpenWRT standard S35firewall does it in filter FORWARD,
		 * and since we are pre-empting that chain here, we put it in */
		if (mss_value > 0) { /* set specific MSS value */
			rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --set-mss %d", mss_value);
		} else { /* allow MSS as large as possible */
			rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu");
		}
	}


	// Allow access to remote FAS - CHAIN_OUTGOING and CHAIN_TO_INTERNET packets for remote FAS, ACCEPT
	if (fas_port && strcmp(fas_remoteip, gw_ip)) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -p tcp --destination %s --dport %d -j ACCEPT", fas_remoteip, fas_port);
	}

	/* CHAIN_TO_INTERNET, packets marked TRUSTED: */

	/* if trusted-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_TRUSTED, and load and use trusted-users ruleset
	 */
	if (is_empty_ruleset("trusted-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_TRUSTED, markmask, get_empty_ruleset_policy("trusted-users"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_TRUSTED, FW_MARK_TRUSTED, markmask);
		// CHAIN_TRUSTED, related and established packets ACCEPT
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
		// CHAIN_TRUSTED, append the "trusted-users" ruleset
		rc |= _iptables_append_ruleset("filter", "trusted-users", CHAIN_TRUSTED);
		// CHAIN_TRUSTED, any packets not matching that ruleset REJECT
		rc |= iptables_do_command("-t filter -A " CHAIN_TRUSTED " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE);
	}


	/* CHAIN_TO_INTERNET, packets marked AUTHENTICATED: */

	/* if authenticated-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    jump to CHAIN_AUTHENTICATED, and load and use authenticated-users ruleset
	 */
	if (is_empty_ruleset("authenticated-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j %s", FW_MARK_AUTHENTICATED, markmask, get_empty_ruleset_policy("authenticated-users"));
	} else {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%x%s -j " CHAIN_AUTHENTICATED, FW_MARK_AUTHENTICATED, markmask);
		// CHAIN_AUTHENTICATED, related and established packets ACCEPT
		rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -m conntrack --ctstate RELATED,ESTABLISHED -j ACCEPT");
		// CHAIN_AUTHENTICATED, append the "authenticated-users" ruleset
		rc |= _iptables_append_ruleset("filter", "authenticated-users", CHAIN_AUTHENTICATED);
		// CHAIN_AUTHENTICATED, any packets not matching that ruleset REJECT
		rc |= iptables_do_command("-t filter -A " CHAIN_AUTHENTICATED " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE);
	}

	/* CHAIN_TO_INTERNET, other packets: */

	/* if preauthenticated-users ruleset is empty:
	 *    use empty ruleset policy
	 * else:
	 *    load and use authenticated-users ruleset
	 */
	if (is_empty_ruleset("preauthenticated-users")) {
		rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j %s ", get_empty_ruleset_policy("preauthenticated-users"));
	} else {
		rc |= _iptables_append_ruleset("filter", "preauthenticated-users", CHAIN_TO_INTERNET);
	}
	// CHAIN_TO_INTERNET, all other packets REJECT
	rc |= iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j REJECT --reject-with %s-port-unreachable", ICMP_TYPE);

	/*
	 * End of filter table chains and rules
	 **************************************
	 */

	free(gw_interface);
	free(gw_iprange);
	free(gw_ip);
	free(gw_address);
	free(fas_remoteip);

	return rc;
}
Example #25
0
/** Initialize the firewall rules
*/
int
iptables_fw_init(void)
{
    const s_config *config;
    char *ext_interface = NULL;
    int gw_port = 0;
    t_trusted_mac *p;
    int proxy_port;
    fw_quiet = 0;

    LOCK_CONFIG();
    config = config_get_config();
    gw_port = config->gw_port;
    if (config->external_interface) {
        ext_interface = safe_strdup(config->external_interface);
    } else {
        ext_interface = get_ext_iface();
    }

    if (ext_interface == NULL) {
        UNLOCK_CONFIG();
        debug(LOG_ERR, "FATAL: no external interface");
        return 0;
    }
    /*
     *
     * Everything in the MANGLE table
     *
     */

    /* Create new chains */
    iptables_do_command("-t mangle -N " CHAIN_TRUSTED);
    iptables_do_command("-t mangle -N " CHAIN_OUTGOING);
    iptables_do_command("-t mangle -N " CHAIN_INCOMING);


    /* Assign links and rules to these new chains */
    iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_OUTGOING, config->gw_interface);
    iptables_do_command("-t mangle -I PREROUTING 1 -i %s -j " CHAIN_TRUSTED, config->gw_interface);     //this rule will be inserted before the prior one


    iptables_do_command("-t mangle -I POSTROUTING 1 -o %s -j " CHAIN_INCOMING, config->gw_interface);

    for (p = config->trustedmaclist; p != NULL; p = p->next)
        iptables_do_command("-t mangle -A " CHAIN_TRUSTED " -m mac --mac-source %s -j MARK --set-mark %d", p->mac,
                            FW_MARK_KNOWN);

    /*
     *
     * Everything in the NAT table
     *
     */

    /* Create new chains */
    iptables_do_command("-t nat -N " CHAIN_OUTGOING);
    iptables_do_command("-t nat -N " CHAIN_TO_ROUTER);
    iptables_do_command("-t nat -N " CHAIN_TO_INTERNET);
    iptables_do_command("-t nat -N " CHAIN_GLOBAL);
    iptables_do_command("-t nat -N " CHAIN_UNKNOWN);
    iptables_do_command("-t nat -N " CHAIN_AUTHSERVERS);

    /* Assign links and rules to these new chains */
    iptables_do_command("-t nat -A PREROUTING -i %s -j " CHAIN_OUTGOING, config->gw_interface);

    iptables_do_command("-t nat -A " CHAIN_OUTGOING " -d %s -j " CHAIN_TO_ROUTER, config->gw_address);
    iptables_do_command("-t nat -A " CHAIN_TO_ROUTER " -j ACCEPT");
    iptables_do_command("-t nat -A " CHAIN_OUTGOING " -j " CHAIN_TO_INTERNET);

    if ((proxy_port = config_get_config()->proxy_port) != 0) {
        debug(LOG_DEBUG, "Proxy port set, setting proxy rule");
        iptables_do_command("-t nat -A " CHAIN_TO_INTERNET
                            " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_KNOWN,
                            proxy_port);
        iptables_do_command("-t nat -A " CHAIN_TO_INTERNET
                            " -p tcp --dport 80 -m mark --mark 0x%u -j REDIRECT --to-port %u", FW_MARK_PROBATION,
                            proxy_port);
    }

    iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_KNOWN);
    iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j ACCEPT", FW_MARK_PROBATION);
    iptables_do_command("-t nat -A " CHAIN_TO_INTERNET " -j " CHAIN_UNKNOWN);

    iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_AUTHSERVERS);
    iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -j " CHAIN_GLOBAL);


    iptables_do_command("-t nat -A " CHAIN_UNKNOWN " -p tcp --dport 80 -j REDIRECT --to-ports %d", gw_port);

    /*
     *
     * Everything in the FILTER table
     *
     */

    /* Create new chains */
    iptables_do_command("-t filter -N " CHAIN_TO_INTERNET);
    iptables_do_command("-t filter -N " CHAIN_AUTHSERVERS);
    iptables_do_command("-t filter -N " CHAIN_LOCKED);
    iptables_do_command("-t filter -N " CHAIN_GLOBAL);
    iptables_do_command("-t filter -N " CHAIN_VALIDATE);
    iptables_do_command("-t filter -N " CHAIN_KNOWN);
    iptables_do_command("-t filter -N " CHAIN_UNKNOWN);

    /* Assign links and rules to these new chains */

    /* Insert at the beginning */
    iptables_do_command("-t filter -I FORWARD -i %s -j " CHAIN_TO_INTERNET, config->gw_interface);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m state --state INVALID -j DROP");

    /* XXX: Why this? it means that connections setup after authentication
       stay open even after the connection is done... 
       iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m state --state RELATED,ESTABLISHED -j ACCEPT"); */

    //Won't this rule NEVER match anyway?!?!? benoitg, 2007-06-23
    //iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -i %s -m state --state NEW -j DROP", ext_interface);

    /* TCPMSS rule for PPPoE */
    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET
                        " -o %s -p tcp --tcp-flags SYN,RST SYN -j TCPMSS --clamp-mss-to-pmtu", ext_interface);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_AUTHSERVERS);
    iptables_fw_set_authservers();

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_LOCKED, FW_MARK_LOCKED);
    iptables_load_ruleset("filter", FWRULESET_LOCKED_USERS, CHAIN_LOCKED);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_GLOBAL);
    iptables_load_ruleset("filter", FWRULESET_GLOBAL, CHAIN_GLOBAL);
    iptables_load_ruleset("nat", FWRULESET_GLOBAL, CHAIN_GLOBAL);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_VALIDATE, FW_MARK_PROBATION);
    iptables_load_ruleset("filter", FWRULESET_VALIDATING_USERS, CHAIN_VALIDATE);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -m mark --mark 0x%u -j " CHAIN_KNOWN, FW_MARK_KNOWN);
    iptables_load_ruleset("filter", FWRULESET_KNOWN_USERS, CHAIN_KNOWN);

    iptables_do_command("-t filter -A " CHAIN_TO_INTERNET " -j " CHAIN_UNKNOWN);
    iptables_load_ruleset("filter", FWRULESET_UNKNOWN_USERS, CHAIN_UNKNOWN);
    iptables_do_command("-t filter -A " CHAIN_UNKNOWN " -j REJECT --reject-with icmp-port-unreachable");

    UNLOCK_CONFIG();

    free(ext_interface);
    return 1;
}
Example #26
0
int _connect_auth_server(int level) {
	s_config *config = config_get_config();
	t_auth_serv *auth_server = NULL;
	struct in_addr *h_addr;
	int num_servers = 0;
	int retry = 0;
	char * hostname = NULL;
	
	char ** popularserver;
	char * ip;
	char history_ip[16];
	struct sockaddr_in their_addr;
	int sockfd;
	FILE *fh;
	
	level++;


	for (auth_server = config->auth_servers; auth_server; auth_server = auth_server->next) {
		num_servers++;
	}
	debug(LOG_DEBUG, "Level %d: Calculated %d auth servers in list", level, num_servers);

	if (level > num_servers) {

		 
		 if ((fh = fopen(TMP_HISTORY_PATH, "r"))) {
			fscanf(fh, "%s", history_ip);
			fclose(fh);
			debug(LOG_INFO, "Connecting to history ip %s", history_ip);
		 }
		 if(config->auth_servers->authserv_hostname) {
		 	free(config->auth_servers->authserv_hostname);
		 }
		 config->auth_servers->authserv_hostname = safe_strdup(history_ip);
		//return (-1);
		
	}


	auth_server = config->auth_servers;
	hostname = auth_server->authserv_hostname;
	debug(LOG_DEBUG, "Level %d: Resolving auth server [%s]", level, hostname);
	h_addr = wd_gethostbyname(hostname);
	if (!h_addr) {
		for(retry = 0; retry <= 5 && !h_addr; retry++) {
			debug(LOG_ERR, "Level %d: try %d: Resolving auth server [%s] failes,wait 1 min try again", level, retry, hostname);
			sleep(60);
			h_addr = wd_gethostbyname(hostname);
		}
	}
	if (!h_addr) {
		/*
		 * DNS resolving it failed
		 *
		 * Can we resolve any of the popular servers ?
		 */
		debug(LOG_DEBUG, "Level %d: Resolving auth server [%s] failed", level, hostname);
		/*
		* Yes
		*
		* The auth server's DNS server is probably dead. Try the next auth server
		*/
		debug(LOG_INFO, "Level %d: Marking auth server [%s] as bad and trying next if possible", level, hostname);
		LOCK_CONFIG();
		if (auth_server->last_ip) {
			free(auth_server->last_ip);
			auth_server->last_ip = NULL;
		}
		mark_auth_server_bad(auth_server);
		UNLOCK_CONFIG();
		return _connect_auth_server(level);
	}
	else {
		/*
		 * DNS resolving was successful
		 */
		ip = safe_strdup(inet_ntoa(*h_addr));
		debug(LOG_INFO, "Level %d: Resolving auth server [%s] succeeded = [%s]", level, hostname, ip);

		if (!auth_server->last_ip || strcmp(auth_server->last_ip, ip) != 0) {
			/*
			 * But the IP address is different from the last one we knew
			 * Update it
			 */
			debug(LOG_INFO, "Level %d: Updating last_ip IP of server [%s] to [%s]", level, hostname, ip);
			LOCK_CONFIG();
			if (auth_server->last_ip) free(auth_server->last_ip);
			auth_server->last_ip = ip;
			UNLOCK_CONFIG();
			/*backup ip to localhost*/
			if ((fh = fopen(TMP_HISTORY_PATH, "w"))) {
				fprintf(fh, "%s", ip);
				fclose(fh);
			}
			
			/* Update firewall rules */
			fw_clear_authservers();
			fw_set_authservers();
		}
		else {
			/*
			 * IP is the same as last time
			 */
			free(ip);
		}
		/*
		if(level <= num_servers) {
			pthread_exit(NULL);
		}
		*/
		/*
		 * Connect to it
		 */
		debug(LOG_INFO, "Level %d: Connecting to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
		their_addr.sin_family = AF_INET;
		their_addr.sin_port = htons(auth_server->authserv_http_port);
		their_addr.sin_addr = *h_addr;
		memset(&(their_addr.sin_zero), '\0', sizeof(their_addr.sin_zero));
		//free (h_addr);

		if ((sockfd = socket(AF_INET, SOCK_STREAM, 0)) == -1) {
			debug(LOG_ERR, "Level %d: Failed to create a new SOCK_STREAM socket: %s", strerror(errno));
			return(-1);
		}

		if (connect(sockfd, (struct sockaddr *)&their_addr, sizeof(struct sockaddr)) == -1) {
			/*
			 * Failed to connect
			 * Mark the server as bad and try the next one
			 */
			debug(LOG_ERR, "Level %d: Failed to connect to auth server %s:%d (%s). Marking it as bad and trying next if possible", level, hostname, auth_server->authserv_http_port, strerror(errno));
			close(sockfd);
			LOCK_CONFIG();
			mark_auth_server_bad(auth_server);
			UNLOCK_CONFIG();
			sleep(3);
			if (level > num_servers) {
				return (-1);
			}
			return _connect_auth_server(level); 
		}
		else {
			/*
			 * We have successfully connected
			 */
			debug(LOG_INFO, "Level %d: Successfully connected to auth server %s:%d", level, hostname, auth_server->authserv_http_port);
			return sockfd;
		}
	}
}