示例#1
0
static void
wdctl_reset(int fd, char *arg)
{
	t_client	*node;

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

	LOCK_CLIENT_LIST();
	debug(LOG_DEBUG, "Argument: %s (@%x)", arg, arg);

	/* We get the node or return... */
	if ((node = client_list_find_by_ip(arg)) != NULL);
	else if ((node = client_list_find_by_mac(arg)) != NULL);
	else {
		debug(LOG_DEBUG, "Client not found.");
		UNLOCK_CLIENT_LIST();
		write(fd, "No", 2);
		return;
	}

	debug(LOG_DEBUG, "Got node %x.", node);

	/* deny.... */
	/* TODO: maybe just deleting the connection is not best... But this
	 * is a manual command, I don't anticipate it'll be that useful. */
	fw_deny(node->ip, node->mac, node->fw_connection_state);
	client_list_delete(node);

	UNLOCK_CLIENT_LIST();

	write(fd, "Yes", 3);

	debug(LOG_DEBUG, "Exiting wdctl_reset...");
}
示例#2
0
static void
ndsctl_deauth(int fd, char *arg)
{
	t_client	*client;
	char *ip, *mac;
	debug(LOG_DEBUG, "Entering ndsctl_deauth...");

	LOCK_CLIENT_LIST();
	/* arg can be IP or MAC address of client */
	debug(LOG_DEBUG, "Argument: %s (@%x)", arg, arg);

	/* We get the client or return... */
	if ((client = client_list_find_by_ip(arg)) != NULL);
	else if ((client = client_list_find_by_mac(arg)) != NULL);
	else if ((client = client_list_find_by_token(arg)) != NULL);
	else {
		debug(LOG_DEBUG, "Client not found.");
		UNLOCK_CLIENT_LIST();
		write(fd, "No", 2);
		return;
	}

	/* We have the client.  Get both ip and mac address and deauthenticate */
	ip = safe_strdup(client->ip);
	mac = safe_strdup(client->mac);
	UNLOCK_CLIENT_LIST();

	auth_client_action(ip, mac, AUTH_MAKE_DEAUTHENTICATED);

	free(ip);
	free(mac);
	write(fd, "Yes", 3);

	debug(LOG_DEBUG, "Exiting ndsctl_deauth...");
}
示例#3
0
void http_callback_logout(httpd *webserver, request *r)
{
	t_client *client;
	s_config *config = config_get_config();

	LOCK_CLIENT_LIST();
	client = client_list_find_by_ip(r->clientAddr);

	/* Send logout to auth server if client is logged in */
	if (client != NULL) {
		t_authresponse authresponse;
		char *ip = strdup(client->ip);
		char *mac = strdup(client->mac);
		char *token = strdup(client->token);
		unsigned long long incoming = client->counters.incoming;
		unsigned long long outgoing = client->counters.outgoing;

		debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s",
			client->ip, client->mac, client->token);

		fw_deny(client->ip, client->mac, client->fw_connection_state);
		client_list_delete(client);

		/* Unlock client list here since auth_server_request may take a while */
		UNLOCK_CLIENT_LIST();

		/* Advertise the logout if we have an auth server */
		if (config->auth_servers != NULL) {
			auth_server_request(&authresponse, REQUEST_TYPE_LOGOUT, ip,
								mac, token, incoming, outgoing);
		}

		free(ip);
		free(mac);
		free(token);
	} else {
		/* Do nothing if the client is not in the client list (i.e. not logged in) */
		debug(LOG_INFO, "Got manual logout from client %s, but client not in list", r->clientAddr);
		UNLOCK_CLIENT_LIST();
	}

	if (config->auth_servers != NULL) {
		/* Re-direct them to auth server */
		char *urlFragment = NULL;
		t_auth_serv	*auth_server = get_auth_server();

		safe_asprintf(&urlFragment, "%smessage=%s",
			auth_server->authserv_msg_script_path_fragment,
			GATEWAY_MESSAGE_ACCOUNT_LOGGED_OUT
		);
		http_send_redirect_to_auth(r, urlFragment, "Redirect to logout message");
		free(urlFragment);
	}
}
示例#4
0
void load_fwrule_conf(void)
{
	FILE *fp = NULL;
	char buff[128];
	int cnum = 0;
	char *ptr = NULL;
	char *ip = NULL; 
	char *mac = NULL;
	char *token = NULL;
	t_client	*client;

	if (NULL == (fp = fopen(WCLIENT_CONF, "r"))) {
		return ;
	}

	while (cnum < 256 && fgets(buff, sizeof(buff), fp) != NULL) {
		unsigned int len = strlen(buff);
		if (buff[len-1] == '\r' || buff[len-1] == '\n') {
			buff[len-1] = '\0';
		}

		ip = strtok_r(buff, " ", &ptr);
		if (!ip) continue;
		mac = strtok_r(NULL, " ", &ptr);
		if (!mac) continue;
		token = strtok_r(NULL, " ", &ptr);
		if (!token) continue;

		// alloc a client and append it to client list 
		if ((client = client_list_find_by_ip(ip)) == NULL) {
			client = client_list_append(ip, mac, token);
			client->fw_connection_state = FW_MARK_KNOWN;
			fw_allow(ip, mac, FW_MARK_KNOWN); 
			debug(LOG_DEBUG, "load client %s %s %s", ip, mac, token);
		}
		
		cnum ++;
	}

	fclose(fp);
}
示例#5
0
/** Update the counters of all the clients in the client list */
	int
iptables_fw_counters_update(void)
{
	FILE *output;
	char *script,
	     ip[16],
	     rc;
	unsigned long long int counter;
	t_client *p1;
	struct in_addr tempaddr;

	debug(LOG_DEBUG, "begin iptables_fw_counters_update");

	/* Look for outgoing traffic */
	// modified by lijg , 2013-05-18, 修改获取上行流量
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_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 %*s %*s %*s %*s", &counter, ip);
		//rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
		//debug(LOG_DEBUG, "outgoing >> %s -- %llu  (%u)", ip, counter, rc);
		if (2 == 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: Bytes=%llu", ip, counter);
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
					p1->counters.outgoing = p1->counters.outgoing_history + counter;
					p1->counters.last_updated = time(NULL);
					debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes.  Updated last_updated to %d", ip, counter, p1->counters.last_updated);
				}
			} else {
				debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip);

				debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING);
				iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip);
				debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING);
				iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	/* Look for incoming traffic */
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING);
	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 %*s %15[0-9.]", &counter, ip);
		if (2 == 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 incoming traffic for %s: Bytes=%llu", ip, counter);
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
					p1->counters.incoming = p1->counters.incoming_history + counter;
					debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
				}
			} else {
				debug(LOG_ERR, "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed", ip);

				debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_OUTGOING);
				iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_OUTGOING, ip);
				debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, TABLE_WIFIDOG_INCOMING);
				iptables_fw_destroy_mention("mangle", TABLE_WIFIDOG_INCOMING, ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	debug(LOG_DEBUG, "end iptables_fw_counters_update\n\n");

	return 1;
}
示例#6
0
文件: auth.c 项目: zombie9080/wifi
/** Authenticates a single client against the central server and returns when done
 * Alters the firewall rules depending on what the auth server says
@param r httpd request struct
*/
void
authenticate_client(request * r)
{
    t_client *client, *tmp;
    t_authresponse auth_response;
    char *token;
    httpVar *var;
    char *urlFragment = NULL;
    s_config *config = NULL;
    t_auth_serv *auth_server = NULL;

    LOCK_CLIENT_LIST();

    client = client_dup(client_list_find_by_ip(r->clientAddr));

    UNLOCK_CLIENT_LIST();

    if (client == NULL) {
        debug(LOG_ERR, "authenticate_client(): Could not find client for %s", r->clientAddr);
        return;
    }

    /* Users could try to log in(so there is a valid token in
     * request) even after they have logged in, try to deal with
     * this */
    if ((var = httpdGetVariableByName(r, "token")) != NULL) {
        token = safe_strdup(var->value);
    } else {
        token = safe_strdup(client->token);
    }

    /* 
     * At this point we've released the lock while we do an HTTP request since it could
     * take multiple seconds to do and the gateway would effectively be frozen if we
     * kept the lock.
     */
    auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, client->ip, client->mac, token, 0, 0);

    LOCK_CLIENT_LIST();

    /* can't trust the client to still exist after n seconds have passed */
    tmp = client_list_find_by_client(client);

    if (NULL == tmp) {
        debug(LOG_ERR, "authenticate_client(): Could not find client node for %s (%s)", client->ip, client->mac);
        UNLOCK_CLIENT_LIST();
        client_list_destroy(client);    /* Free the cloned client */
        free(token);
        return;
    }

    client_list_destroy(client);        /* Free the cloned client */
    client = tmp;

    if (strcmp(token, client->token) != 0) {
        /* If token changed, save it. */
        free(client->token);
        client->token = token;
    } else {
        free(token);
    }

    /* Prepare some variables we'll need below */
    config = config_get_config();
    auth_server = get_auth_server();

    switch (auth_response.authcode) {

    case AUTH_ERROR:
        /* Error talking to central server */
        debug(LOG_ERR, "Got ERROR from central server authenticating token %s from %s at %s", client->token, client->ip,
              client->mac);
        send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server");
        break;

    case AUTH_DENIED:
        /* Central server said invalid token */
        debug(LOG_INFO,
              "Got DENIED from central server authenticating token %s from %s at %s - deleting from firewall and redirecting them to denied message",
              client->token, client->ip, client->mac);
        fw_deny(client);
        safe_asprintf(&urlFragment, "%smessage=%s",
                      auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_DENIED);
        http_send_redirect_to_auth(r, urlFragment, "Redirect to denied message");
        free(urlFragment);
        break;

    case AUTH_VALIDATION:
        /* They just got validated for X minutes to check their email */
        debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
              "- adding to firewall and redirecting them to activate message", client->token, client->ip, client->mac);
        fw_allow(client, FW_MARK_PROBATION);
        safe_asprintf(&urlFragment, "%smessage=%s",
                      auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_ACTIVATE_ACCOUNT);
        http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message");
        free(urlFragment);
        break;

    case AUTH_ALLOWED:
        /* Logged in successfully as a regular account */
        debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
              "adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
        fw_allow(client, FW_MARK_KNOWN);
        // add by zp 
        debug(LOG_INFO,"goto fw_allow()...");
        served_this_session++;
        safe_asprintf(&urlFragment, "%sgw_id=%s", auth_server->authserv_portal_script_path_fragment, config->gw_id);
        // modify by zp 
        http_send_redirect_to_auth(r, urlFragment, "Redirect to portal");
        //char * text = "advertisement";
        //http_send_redirect_to_advertisement(r, urlFragment, text);
        free(urlFragment);
        break;

    case AUTH_VALIDATION_FAILED:
        /* Client had X minutes to validate account by email and didn't = too late */
        debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
              "- redirecting them to failed_validation message", client->token, client->ip, client->mac);
        safe_asprintf(&urlFragment, "%smessage=%s",
                      auth_server->authserv_msg_script_path_fragment, GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED);
        http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message");
        free(urlFragment);
        break;

    default:
        debug(LOG_WARNING,
              "I don't know what the validation code %d means for token %s from %s at %s - sending error message",
              auth_response.authcode, client->token, client->ip, client->mac);
        send_http_page(r, "Internal Error", "We can not validate your request at this time");
        break;

    }

    UNLOCK_CLIENT_LIST();
    return;
}
示例#7
0
/** Update the counters of all the clients in the client list */
	int
iptables_fw_counters_update(void)
{
	FILE *output;
	char *script,
	     ip[16],
	     rc;
	unsigned long long int counter;
	t_client *p1;
	struct in_addr tempaddr;
	int fd;

	/* Look for outgoing traffic */
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_OUTGOING);
	iptables_insert_gateway_id(&script);
	output = popen(script, "r");
	free(script);
	if (!output) {
		debug(LOG_ERR, "popen(): %s", strerror(errno));
		return -1;
	}
fprintf(stderr,"popen:");
	/* skip the first two lines */
	while (('\n' != fgetc(output)) && !feof(output))
		;
	while (('\n' != fgetc(output)) && !feof(output))
		;

/*set nonblocking -> would need to change fscanf against read and buffer and other parsing logic
fd = fileno(output);
fcntl(fd, F_SETFL, O_NONBLOCK);
*/
	while (output && !(feof(output))) {
fprintf(stderr,"#");
		rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip);
		//rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
fprintf(stderr,"!");
		if (2 == 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: Bytes=%llu", ip, counter);
//here we deadlock sometimes,...
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
					p1->counters.outgoing = p1->counters.outgoing_history + counter;
					p1->counters.last_updated = time(NULL);
					debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes.  Updated last_updated to %d", ip, counter, p1->counters.last_updated);
				}
			} else {
				debug(LOG_ERR, "Could not find %s in client list", ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	/* Look for incoming traffic */
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " TABLE_WIFIDOG_INCOMING);
	iptables_insert_gateway_id(&script);
	output = popen(script, "r");
	free(script);
	if (!output) {
		debug(LOG_ERR, "popen(): %s", strerror(errno));
		return -1;
	}
fprintf(stderr,"popen:");
	/* skip the first two lines */
	while (('\n' != fgetc(output)) && !feof(output))
		;
	while (('\n' != fgetc(output)) && !feof(output))
		;
	while (output && !(feof(output))) {
fprintf(stderr,"#");
		rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %*s %15[0-9.]", &counter, ip);
fprintf(stderr,"!");
		if (2 == 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 incoming traffic for %s: Bytes=%llu", ip, counter);
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
					p1->counters.incoming = p1->counters.incoming_history + counter;
					debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
				}
			} else {
				debug(LOG_ERR, "Could not find %s in client list", ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	return 1;
}
示例#8
0
/** Update the counters of all the clients in the client list */
int
iptables_fw_counters_update(void)
{
	FILE *output;
	char *script,
		 ip[16],
		 target[MAX_BUF];
	int rc;
	unsigned long long int counter;
	t_client *p1;
	struct in_addr tempaddr;

	/* Look for outgoing traffic */
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_OUTGOING);
	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 ( !(feof(output) )) {
		rc = fscanf(output, "%*s %llu %s %*s %*s %*s %*s %15[0-9.]", &counter,target,ip);
		/* eat rest of line */
		while (('\n' != fgetc(output)) && !feof(output)) {}
		if (3 == rc && !strcmp(target,"MARK")) {
			/* 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: Bytes=%llu", ip, counter);
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
					p1->counters.outgoing = p1->counters.outgoing_history + counter;
					p1->counters.last_updated = time(NULL);
					debug(LOG_DEBUG, "%s - Updated counter.outgoing to %llu bytes.  Updated last_updated to %d", ip, counter, p1->counters.last_updated);
				}
			} else {
				debug(LOG_WARNING, "Could not find %s in client list", ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	/* Look for incoming traffic */
	safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_INCOMING);
	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 ( !(feof(output) )) {
		rc = fscanf(output, "%*s %llu %s %*s %*s %*s %*s %*s %15[0-9.]", &counter,target,ip);
		/* eat rest of line */
		while (('\n' != fgetc(output)) && !feof(output)) {}
		if (3 == rc && !strcmp(target,"ACCEPT")) {
			/* 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 incoming traffic for %s: Bytes=%llu", ip, counter);
			LOCK_CLIENT_LIST();
			if ((p1 = client_list_find_by_ip(ip))) {
				if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
					p1->counters.incoming = p1->counters.incoming_history + counter;
					debug(LOG_DEBUG, "%s - Updated counter.incoming to %llu bytes", ip, counter);
				}
			} else {
				debug(LOG_WARNING, "Could not find %s in client list", ip);
			}
			UNLOCK_CLIENT_LIST();
		}
	}
	pclose(output);

	return 0;
}
/** Initiates a transaction with the auth server, either to authenticate or to
 * update the traffic counters at the server
@param authresponse Returns the information given by the central server 
@param request_type Use the REQUEST_TYPE_* defines in centralserver.h
@param ip IP adress of the client this request is related to
@param mac MAC adress of the client this request is related to
@param token Authentification token of the client
@param incoming Current counter of the client's total incoming traffic, in bytes 
@param outgoing Current counter of the client's total outgoing traffic, in bytes 
*/
t_authcode
auth_server_request(t_authresponse *authresponse, const char *request_type, const char *ip, const char *mac, const char *token, unsigned long long int incoming, unsigned long long int outgoing)
{
	int sockfd;
	t_client *client;
	ssize_t	numbytes;
	size_t totalbytes;
	char buf[MAX_BUF];
	char *tmp;
        char *safe_token;
	int done, nfds;
	fd_set			readfds;
	struct timeval		timeout;
	t_auth_serv	*auth_server = NULL;
	auth_server = get_auth_server();
	
	/* Blanket default is error. */
	authresponse->authcode = AUTH_ERROR;
	
	sockfd = in_connect_auth_server(auth_server);
	if (sockfd == -1) {
		/* Could not connect to any auth server */
		return (AUTH_ERROR);
	}

	/**
	 * TODO: XXX change the PHP so we can harmonize stage as request_type
	 * everywhere.
	 */
	memset(buf, 0, sizeof(buf));
        safe_token=httpdUrlEncode(token);
	snprintf(buf, (sizeof(buf) - 1),
		"GET %s%sstage=%s&ip=%s&mac=%s&token=%s&incoming=%llu&outgoing=%llu&gw_id=%s HTTP/1.0\r\n"
		"User-Agent: WiFiDog %s\r\n"
		"Host: %s\r\n"
		"\r\n",
		auth_server->authserv_path,
		auth_server->authserv_auth_script_path_fragment,
		request_type,
		ip,
		mac,
		safe_token,
		incoming,
		outgoing,
                config_get_config()->gw_id,
		VERSION,
		auth_server->authserv_hostname
	);

        free(safe_token);

	debug(LOG_DEBUG, "Sending HTTP request to auth server: [%s]\n", buf);
	send(sockfd, buf, strlen(buf), 0);

	debug(LOG_DEBUG, "Reading response");
	numbytes = totalbytes = 0;
	done = 0;
	do {
		FD_ZERO(&readfds);
		FD_SET(sockfd, &readfds);
		timeout.tv_sec = 30; /* XXX magic... 30 second is as good a timeout as any */
		timeout.tv_usec = 0;
		nfds = sockfd + 1;

		nfds = select(nfds, &readfds, NULL, NULL, &timeout);

		if (nfds > 0) {
			/** We don't have to use FD_ISSET() because there
			 *  was only one fd. */
			numbytes = read(sockfd, buf + totalbytes, MAX_BUF - (totalbytes + 1));
			if (numbytes < 0) {
				debug(LOG_ERR, "An error occurred while reading from auth server: %s", strerror(errno));
				/* FIXME */
				close(sockfd);
				return (AUTH_ERROR);
			}
			else if (numbytes == 0) {
				done = 1;
			}
			else {
				totalbytes += numbytes;
				debug(LOG_DEBUG, "Read %d bytes, total now %d", numbytes, totalbytes);
			}
		}
		else if (nfds == 0) {
			debug(LOG_ERR, "Timed out reading data via select() from auth server");
			/* FIXME */
			close(sockfd);
			return (AUTH_ERROR);
		}
		else if (nfds < 0) {
			debug(LOG_ERR, "Error reading data via select() from auth server: %s", strerror(errno));
			/* FIXME */
			close(sockfd);
			return (AUTH_ERROR);
		}
	} while (!done);

	close(sockfd);

	buf[totalbytes] = '\0';
	debug(LOG_DEBUG, "HTTP Response from Server: [%s]", buf);
	
	if ((tmp = strstr(buf, "Auth: "))) {
		if (sscanf(tmp, "Auth: %d", (int *)&authresponse->authcode) == 1) {
			debug(LOG_INFO, "Auth server returned authentication code %d", authresponse->authcode);
			if(authresponse->authcode == 1) {
				debug(LOG_INFO, "Auth server returned 1,then check bandwidth.");
				int bwdn=0,bwup=0;
				if ((tmp = strstr(buf, "Bwdn: "))) {
					if (sscanf(tmp, "Bwdn: %d", &bwdn) == 1) {
						debug(LOG_INFO, "Auth server returned user download bandwidth %d", bwdn);		
					}
				}
				if ((tmp = strstr(buf, "Bwup: "))) {
					if (sscanf(tmp, "Bwup: %d", &bwup) == 1) {
						debug(LOG_INFO, "Auth server returned user upload bandwidth %d", bwup);
					}
				}
				if(bwdn==0 || bwup==0){
					bwdn=config_get_config()->clientbandwidthdown;
					bwup=config_get_config()->clientbandwidthup;
				}

				LOCK_CLIENT_LIST();
				client = client_list_find_by_ip(ip);
				if (client != NULL) {
					debug(LOG_DEBUG, "get bandwidth %d %d", bwdn,bwup);
					client->bwdn = bwdn;
					client->bwup = bwup;
				}
				UNLOCK_CLIENT_LIST();
			}
			return(authresponse->authcode);
		} else {
			debug(LOG_WARNING, "Auth server did not return expected authentication code");
			return(AUTH_ERROR);
		}
	}
	else {
		return(AUTH_ERROR);
	}

	/* XXX Never reached because of the above if()/else pair. */
	return(AUTH_ERROR);
}
示例#10
0
/** Update the counters of all the clients in the client list */
int
iptables_fw_counters_update(void)
{
    FILE *output;
    char *script, ip[16], rc, mac[18];
    unsigned long long int counter;
    t_client *p1;
    struct in_addr tempaddr;
    const s_config *config = config_get_config();

    /* Look for outgoing traffic */
    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))) {
//3554   390634 MARK       all  --  *      *       0.0.0.0/0            0.0.0.0/0            MAC C0:38:96:96:74:7D MARK set 0x3
        /*rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s %*s", &counter, ip);*/
        //rc = fscanf(output, "%*s %llu %*s %*s %*s %*s %*s %15[0-9.] %*s %*s %*s %*s %*s 0x%*u", &counter, ip);
        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 ((p1 = client_list_find_by_ip(ip))) {
		p1->counters.active_duration--;
                if ((p1->counters.outgoing - p1->counters.outgoing_history) < counter) {
                    p1->counters.outgoing_delta = p1->counters.outgoing_history + counter - p1->counters.outgoing;
                    p1->counters.outgoing = p1->counters.outgoing_history + counter;
                    p1->counters.last_updated = time(NULL);
                    debug(LOG_DEBUG, "%s(%s) - Outgoing traffic %llu bytes, updated counter.outgoing to %llu bytes.  Updated last_updated to %d", ip, mac,
                          counter, p1->counters.outgoing, p1->counters.last_updated);
                }
            } else {
                debug(LOG_ERR,
                      "iptables_fw_counters_update(): Could not find %s(%s) in client list, this should not happen unless if the gateway crashed",
                      ip, mac);
                debug(LOG_ERR, "Preventively deleting firewall rules for %s(%s) in table %s", ip, mac, CHAIN_OUTGOING);
                iptables_fw_destroy_mention("mangle", CHAIN_OUTGOING, ip);
                debug(LOG_ERR, "Preventively deleting firewall rules for %s(%s) in table %s", ip, mac, CHAIN_INCOMING);
                iptables_fw_destroy_mention("mangle", CHAIN_INCOMING, ip);
            }
            UNLOCK_CLIENT_LIST();
        }
    }
    pclose(output);

    /* Look for incoming traffic */
    safe_asprintf(&script, "%s %s", "iptables", "-v -n -x -t mangle -L " CHAIN_INCOMING);
    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 %*s %15[0-9.]", &counter, ip);
        if (2 == 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 incoming traffic for %s: Bytes=%llu", ip, counter);
            LOCK_CLIENT_LIST();
            if ((p1 = client_list_find_by_ip(ip))) {
                if ((p1->counters.incoming - p1->counters.incoming_history) < counter) {
                    p1->counters.incoming_delta = p1->counters.incoming_history + counter - p1->counters.incoming;
                    p1->counters.incoming = p1->counters.incoming_history + counter;
                    debug(LOG_DEBUG, "%s - Incoming traffic %llu bytes, Updated counter.incoming to %llu bytes", ip, counter, p1->counters.incoming);
                }
            } else {
                debug(LOG_ERR,
                      "iptables_fw_counters_update(): Could not find %s in client list, this should not happen unless if the gateway crashed",
                      ip);
                debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, CHAIN_OUTGOING);
                iptables_fw_destroy_mention("mangle", CHAIN_OUTGOING, ip);
                debug(LOG_ERR, "Preventively deleting firewall rules for %s in table %s", ip, CHAIN_INCOMING);
                iptables_fw_destroy_mention("mangle", CHAIN_INCOMING, ip);
            }
            UNLOCK_CLIENT_LIST();
        }
    }
    pclose(output);

    return 1;
}
示例#11
0
文件: auth.c 项目: kissthink/multidog
/** Authenticates a single client against the central server and returns when done
 * Alters the firewall rules depending on what the auth server says
@param r httpd request struct
*/
void
authenticate_client(request *r, char *gw_id)
{
	t_client	*client;
	t_authresponse	auth_response;
	char	*mac,
		*token;
	char *urlFragment = NULL;
	s_config	*config = NULL;
	t_auth_serv	*auth_server = NULL;

	LOCK_CLIENT_LIST();

	client = client_list_find_by_ip(r->clientAddr);

	if (client == NULL) {
		debug(LOG_ERR, "Could not find client for %s", r->clientAddr);
		UNLOCK_CLIENT_LIST();
		return;
	}
	
	mac = safe_strdup(client->mac);
	token = safe_strdup(client->token);
	
	UNLOCK_CLIENT_LIST();
	
	/* 
	 * At this point we've released the lock while we do an HTTP request since it could
	 * take multiple seconds to do and the gateway would effectively be frozen if we
	 * kept the lock.
	 */
	auth_server_request(&auth_response, REQUEST_TYPE_LOGIN, r->clientAddr, mac, token, 0, 0, gw_id);
	
	LOCK_CLIENT_LIST();
	
	/* can't trust the client to still exist after n seconds have passed */
	client = client_list_find(r->clientAddr, mac);
	
	if (client == NULL) {
		debug(LOG_ERR, "Could not find client node for %s (%s)", r->clientAddr, mac);
		UNLOCK_CLIENT_LIST();
		free(token);
		free(mac);
		return;
	}
	
	free(token);
	free(mac);

	/* Prepare some variables we'll need below */
	config = config_get_config();
	auth_server = get_auth_server();

	switch(auth_response.authcode) {

	case AUTH_ERROR:
		/* Error talking to central server */
		debug(LOG_ERR, "Got %d from central server authenticating token %s from %s at %s", auth_response, client->token, client->ip, client->mac);
		send_http_page(r, "Error!", "Error: We did not get a valid answer from the central server");
		break;

	case AUTH_DENIED:
		/* Central server said invalid token */
		debug(LOG_INFO, "Got DENIED from central server authenticating token %s from %s at %s - redirecting them to denied message", client->token, client->ip, client->mac);
		safe_asprintf(&urlFragment, "%smessage=%s",
			auth_server->authserv_msg_script_path_fragment,
			GATEWAY_MESSAGE_DENIED
		);
		http_send_redirect_to_auth(r, urlFragment, "Redirect to portal", gw_id);
		//set connection logged out (xperimental)
		//snprintf(,client->token, client->ip, client->mac)	
		/*{
			char mysqlCmd[256];
			sprintf(mysqlCmd,"echo \"DELETE FROM connections WHERE token='%s';\"|mysql -uauthpuppy -pauthpuppydev authpuppy > /tmp/wifidog_deauth_mysql_result",client->token);
			debug(LOG_WARNING,"issuing this would help: %s",mysqlCmd);
			//system(mysqlCmd);//kills wifidog somehow *g
		}*/
		free(urlFragment);
		
		//for race conditions, remove from firewall
		fw_deny(client->ip, client->mac, client->fw_connection_state);
		//experimental delete client from list
                client_list_delete(client);

		break;

    case AUTH_VALIDATION:
		/* They just got validated for X minutes to check their email */
		debug(LOG_INFO, "Got VALIDATION from central server authenticating token %s from %s at %s"
				"- adding to firewall and redirecting them to activate message", client->token,
				client->ip, client->mac);
		client->fw_connection_state = FW_MARK_PROBATION;
		fw_allow(client->ip, client->mac, FW_MARK_PROBATION);
		safe_asprintf(&urlFragment, "%smessage=%s",
			auth_server->authserv_msg_script_path_fragment,
			GATEWAY_MESSAGE_ACTIVATE_ACCOUNT
		);
		http_send_redirect_to_auth(r, urlFragment, "Redirect to activate message", gw_id);
		free(urlFragment);
	    break;

    case AUTH_ALLOWED:
		/* Logged in successfully as a regular account */
		debug(LOG_INFO, "Got ALLOWED from central server authenticating token %s from %s at %s - "
				"adding to firewall and redirecting them to portal", client->token, client->ip, client->mac);
		client->fw_connection_state = FW_MARK_KNOWN;
		fw_allow(client->ip, client->mac, FW_MARK_KNOWN);
        served_this_session++;
		safe_asprintf(&urlFragment, "%sgw_id=%s",
			auth_server->authserv_portal_script_path_fragment,
			gw_id
		);
		http_send_redirect_to_auth(r, urlFragment, "Redirect to portal", gw_id);
		free(urlFragment);
	    break;

    case AUTH_VALIDATION_FAILED:
		 /* Client had X minutes to validate account by email and didn't = too late */
		debug(LOG_INFO, "Got VALIDATION_FAILED from central server authenticating token %s from %s at %s "
				"- redirecting them to failed_validation message", client->token, client->ip, client->mac);
		safe_asprintf(&urlFragment, "%smessage=%s",
			auth_server->authserv_msg_script_path_fragment,
			GATEWAY_MESSAGE_ACCOUNT_VALIDATION_FAILED
		);
		http_send_redirect_to_auth(r, urlFragment, "Redirect to failed validation message", gw_id);
		free(urlFragment);
	    break;

    default:
		debug(LOG_WARNING, "I don't know what the validation code %d means for token %s from %s at %s - sending error message", auth_response.authcode, client->token, client->ip, client->mac);
		send_http_page(r, "Internal Error", "We can not validate your request at this time");
	    break;

	}

	UNLOCK_CLIENT_LIST();
	return;
}
示例#12
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();
}