Пример #1
0
/** Ping clients to see if they are still active,
 *  refresh their traffic counters,
 *  remove and deny them if timed out
 */
void
fw_refresh_client_list(void)
{
	t_client *cp1, *cp2;
	time_t now, added_time, last_updated;
	s_config *config = config_get_config();

	/* Update all the counters */
	if (-1 == iptables_fw_counters_update()) {
		debug(LOG_ERR, "Could not get counters from firewall!");
		return;
	}

	LOCK_CLIENT_LIST();

	for (cp1 = cp2 = client_get_first_client(); NULL != cp1; cp1 = cp2) {
		cp2 = cp1->next;

		if (!(cp1 = client_list_find(cp1->ip, cp1->mac))) {
			debug(LOG_ERR, "Node %s was freed while being re-validated!", cp1->ip);
		} else {
			now = time(NULL);
			last_updated = cp1->counters.last_updated;
			added_time = cp1->added_time;
			if (last_updated +  (config->checkinterval * config->clienttimeout) <= now) {
				/* Timing out inactive user */
				debug(LOG_NOTICE, "%s %s inactive %d secs. kB in: %llu  kB out: %llu",
					cp1->ip, cp1->mac, config->checkinterval * config->clienttimeout,
					cp1->counters.incoming/1000, cp1->counters.outgoing/1000);
				if (cp1->fw_connection_state == FW_MARK_AUTHENTICATED) {
					iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1);
				}
				client_list_delete(cp1);
			} else if (added_time +  (config->checkinterval * config->clientforceout) <= now) {
				/* Forcing out user */
				debug(LOG_NOTICE, "%s %s connected %d secs. kB in: %llu kB out: %llu",
					cp1->ip, cp1->mac, config->checkinterval * config->clientforceout,
					cp1->counters.incoming/1000, cp1->counters.outgoing/1000);
				if (cp1->fw_connection_state == FW_MARK_AUTHENTICATED) {
					iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, cp1);
				}
				client_list_delete(cp1);
			}
		}
	}
	UNLOCK_CLIENT_LIST();
}
Пример #2
0
/** Take action on a client.
 * Alter the firewall rules and client list accordingly.
*/
void
auth_client_action(const char ip[], const char mac[], t_authaction action)
{
	t_client *client;

	LOCK_CLIENT_LIST();

	client = client_list_find(ip,mac);

	/* Client should already have hit the server and be on the client list */
	if (client == NULL) {
		debug(LOG_ERR, "Client %s %s action %d is not on client list",
			  ip, mac, action);
		UNLOCK_CLIENT_LIST();
		return;
	}

	switch(action) {

	case AUTH_MAKE_AUTHENTICATED:
		if(client->fw_connection_state != FW_MARK_AUTHENTICATED) {
			client->fw_connection_state = FW_MARK_AUTHENTICATED;
			iptables_fw_access(AUTH_MAKE_AUTHENTICATED, client);
			authenticated_since_start++;
		} else {
			debug(LOG_INFO, "Nothing to do, %s %s already authenticated", client->ip, client->mac);
		}
		break;

	case AUTH_MAKE_DEAUTHENTICATED:
		if(client->fw_connection_state == FW_MARK_AUTHENTICATED) {
			iptables_fw_access(AUTH_MAKE_DEAUTHENTICATED, client);
		}
		client_list_delete(client);
		break;

	default:
		debug(LOG_ERR, "Unknown auth action: %d",action);
	}
	UNLOCK_CLIENT_LIST();
	return;
}
Пример #3
0
/**
 * Allow a client access through the firewall by adding a rule in the firewall to MARK the user's packets with the proper
 * rule by providing his IP and MAC address
 * @param ip IP address to allow
 * @param mac MAC address to allow
 * @param fw_connection_state fw_connection_state Tag
 * @return Return code of the command
 */
int
fw_allow(t_client * client, int new_fw_connection_state)
{
    int result;
    int old_state = client->fw_connection_state;

    debug(LOG_DEBUG, "Allowing %s %s with fw_connection_state %d", client->ip, client->mac, new_fw_connection_state);
    client->fw_connection_state = new_fw_connection_state;

    /* Grant first */
    result = iptables_fw_access(FW_ACCESS_ALLOW, client->ip, client->mac, new_fw_connection_state);

    /* Deny after if needed. */
    if (old_state != FW_MARK_NONE) {
        debug(LOG_DEBUG, "Clearing previous fw_connection_state %d", old_state);
        _fw_deny_raw(client->ip, client->mac, old_state);
    }

    return result;
}
Пример #4
0
/** @internal
 * Actually does the clearing, so fw_allow can call it to clear previous mark.
 * @param ip IP address to deny
 * @param mac MAC address to deny
 * @param mark fw_connection_state Tag
 * @return Return code of the command
 */
static int
_fw_deny_raw(const char *ip, const char *mac, const int mark)
{
    return iptables_fw_access(FW_ACCESS_DENY, ip, mac, mark);
}
Пример #5
0
void notify_client_disconnect(char *mac, char *ifname)
{
    t_client *client;
    t_redir_node *node;
    FILE *output;
    char *script, ip[16], rc;
    unsigned long long int counter;
    struct in_addr tempaddr;
    int ifIndex = get_ifIndex(ifname);
    //     printf("Client Disconnected\n");
    LOCK_REDIR();

    node = redir_list_find(mac);
    if (node && node->redir_pending) {
        UNLOCK_REDIR();
        safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_OUTGOING);
        iptables_insert_gateway_id(&script);
        output = popen(script, "r");
        free(script);
        if (!output) {
            debug(LOG_ERR, "popen(): %s", strerror(errno));
            return -1;
        }

        /* skip the first two lines */
        while (('\n' != fgetc(output)) && !feof(output)) ;
        while (('\n' != fgetc(output)) && !feof(output)) ;
        while (output && !(feof(output))) {
            rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %17[0-9a-fA-F:] %*s %*s 0x%*u", &counter, ip, mac);
            if (3 == rc && EOF != rc) {
                /* Sanity */
                if (!inet_aton(ip, &tempaddr)) {
                    debug(LOG_WARNING, "I was supposed to read an IP address but instead got [%s] - ignoring it", ip);
                    continue;
                }
                debug(LOG_DEBUG, "Read outgoing traffic for %s(%s): Bytes=%llu", ip, mac, counter);
                LOCK_CLIENT_LIST();
                if ((client = client_list_find_by_ip(ip))) {
                    client->counters.outgoing = client->counters.outgoing_history + counter;
                    client->counters.last_updated = time(NULL);
                    UNLOCK_CLIENT_LIST();
                    pclose(output);
                    return;
                }
            }
        }
        UNLOCK_CLIENT_LIST();
        pclose(output);
    }

    if(node)
        if(node->ifindex != ifIndex)
            debug(LOG_NOTICE,"%s: %s connected to idx %d, recv'd disconnect evt from idx %d\n",__func__, mac, node->ifindex, ifIndex);

    if (node && (node->ifindex == ifIndex)) {
        if (node->redir_pending) {
            char command[100];
            char fmac[13];
            formatmacaddr(mac, &fmac);
            node->redir_pending = 0;
            debug(LOG_NOTICE,"%s: recv'd disconnect evt for %s from idx %d\n",__func__, mac, node->ifindex);
            snprintf(command,100,"echo %s > /proc/sys/net/bridge/bridge-http-redirect-del-mac",fmac);
            //      printf("%s",command);
            execute(command,0);
            if (node->route_added) {
                memset(command, 0, sizeof(command));
                sprintf(command, "/bin/ip route del %s/32 src %s dev %s", node->host_ip, node->dev_ip, node->dev);
                //printf("\nexecuting %s\n", command);
                execute(command, 0);
            }
            fw_mark_mangle(mac,0);
        }
        debug(LOG_NOTICE,"%s: removing node list for %s from idx %d\n",__func__, mac, node->ifindex);
        redir_list_delete(node);
    }

    UNLOCK_REDIR();

    LOCK_CLIENT_LIST();
    client = client_list_find_by_mac(mac);
    if (client) {
        /*fw_deny_raw(client->ip, client->mac, client->fw_connection_state);*/
        iptables_fw_access(FW_ACCESS_DENY, client->ip, client->mac, client->fw_connection_state);
        client_list_delete(client);
    }
    UNLOCK_CLIENT_LIST();
}
Пример #6
0
void notify_client_connect(char *mac, char *ifname)
{
    t_client *client;
    t_redir_node *node;
    s_config *config = config_get_config();
    int ifIndex = get_ifIndex(ifname);

    if( !config->status[ifIndex] ) {
        debug(LOG_NOTICE, "Captive Portal is not enabled for %s", ifname);
        return;
    }
    LOCK_REDIR();
    //  config_cp_auth_status(ifname, mac, 1); /* Updating the cpAuthStatus to 1 */
    node = redir_list_find(mac);
    if (!node) {
        node = redir_list_append(mac);
    }
    if (!node) {
        UNLOCK_REDIR();
        return;
    }
    debug(LOG_NOTICE,"%s recv'd association req from mac %s  %p\n",__func__,mac, node);
    
    /*post_event(ifname, mac, 1 << 0); *//* BIT0 is set which is a session query notification */
    node->ifindex = ifIndex;
    node->wlindex = config->profile[ifIndex];
    if (ifname) strncpy(node->dev, ifname, sizeof(node->dev));
    node->cpAuthstatus = 1;
    node->expiry = time(NULL);

    if (!node->redir_pending) {
        char command[100];
        char fmac[13];
        formatmacaddr(mac, &fmac);
        node->redir_pending = 1;
        snprintf(command,100,"echo %s > /proc/sys/net/bridge/bridge-http-redirect-add-mac",fmac);
        //      printf("%s",command);
        execute(command,0);
        fw_mark_mangle(mac,1);
    }
    if(config->operate_mode){
        if((time(NULL) - timekeeper[0].timestamp) > MAX_HOSTNAME_RESOLVE_TIMEOUT){
            make_proc_entry_for_url(config->portal[0], 0);
            timekeeper[0].timestamp = time(NULL);
        }
    }else{
        if((time(NULL) - timekeeper[ifIndex].timestamp) > MAX_HOSTNAME_RESOLVE_TIMEOUT){
            make_proc_entry_for_url(config->portal[ifIndex], ifIndex);
            timekeeper[ifIndex].timestamp = time(NULL);
        }
    }
    timekeeper[ifIndex].timestamp = time(NULL);

    UNLOCK_REDIR();

    LOCK_CLIENT_LIST();

    client = client_list_find_by_mac(mac);
    if (client) {
        /*fw_deny_raw(client->ip, client->mac, client->fw_connection_state);      *//*PRATIK: Commented so that it doesn't invoke the firewall*/
    iptables_fw_access(FW_ACCESS_DENY, client->ip, client->mac, client->fw_connection_state);    
    client_list_delete(client);
    }

    UNLOCK_CLIENT_LIST();
}