Exemple #1
0
static int
_special_process(request *r, const char *mac, const char *redir_url)
{
	t_offline_client *o_client = NULL;

	LOCK_OFFLINE_CLIENT_LIST();
    o_client = offline_client_list_find_by_mac(mac);
    if(o_client == NULL) {
    	o_client = offline_client_list_add(r->clientAddr, mac);
    } else {
		o_client->last_login = time(NULL);
	}
    UNLOCK_OFFLINE_CLIENT_LIST();

	if(_is_apple_captive(r->request.host)) {
		unsigned int interval = time(NULL) - o_client->first_login;
		debug(LOG_INFO, "Into captive.apple.com hit_counts %d interval %d\n", o_client->hit_counts, interval);
		LOCK_OFFLINE_CLIENT_LIST();
    	o_client->hit_counts++;
		UNLOCK_OFFLINE_CLIENT_LIST();
		if(o_client->client_type == 1 ) {
			if(o_client->hit_counts < 5 && interval < 30 )
				http_send_js_redirect_ex(r, redir_url);
			else {
				http_send_apple_redirect(r, redir_url);
			}
		} else {	
			LOCK_OFFLINE_CLIENT_LIST();
			o_client->client_type = 1;
			UNLOCK_OFFLINE_CLIENT_LIST();
			http_send_js_redirect_ex(r, redir_url);
		}
		return 1;
	} 

	return 0;
}
Exemple #2
0
/** The 404 handler is also responsible for redirecting to the auth server */
void
http_callback_404(httpd * webserver, request * r, int error_code)
{
    char tmp_url[MAX_BUF], *url, *mac;
    s_config *config = config_get_config();
    t_auth_serv *auth_server = get_auth_server();
	
	
    memset(tmp_url, 0, sizeof(tmp_url));
    /* 
     * XXX Note the code below assumes that the client's request is a plain
     * http request to a standard port. At any rate, this handler is called only
     * if the internet/auth server is down so it's not a huge loss, but still.
     */
    snprintf(tmp_url, (sizeof(tmp_url) - 1), "http://%s%s%s%s",
             r->request.host, r->request.path, r->request.query[0] ? "?" : "", r->request.query);
    url = httpdUrlEncode(tmp_url);

    if (!is_online()) {
        /* The internet connection is down at the moment  - apologize and do not redirect anywhere */
        char *buf;
        safe_asprintf(&buf,
                      "<p>We apologize, but it seems that the internet connection that powers this hotspot is temporarily unavailable.</p>"
                      "<p>If at all possible, please notify the owners of this hotspot that the internet connection is out of service.</p>"
                      "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                      "<p>In a while please <a href='%s'>click here</a> to try your request again.</p>", tmp_url);

        send_http_page(r, "Internet access unavailable!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since I am not online - no point sending them to auth server",
              r->clientAddr);
    } else if (!is_auth_online()) {
        /* The auth server is down at the moment - apologize and do not redirect anywhere */
        char *buf;
        safe_asprintf(&buf,
                      "<p>We apologize, but it seems that we are currently unable to re-direct you to the login screen.</p>"
                      "<p>The maintainers of this network are aware of this disruption.  We hope that this situation will be resolved soon.</p>"
                      "<p>In a couple of minutes please <a href='%s'>click here</a> to try your request again.</p>",
                      tmp_url);

        send_http_page(r, "Auth server is not online!", buf);
        free(buf);
        debug(LOG_INFO, "Sent %s an apology since auth server not online - no point sending them to auth server",
              r->clientAddr);
    } else {
        /* Re-direct them to auth server */
        char *urlFragment;
			
        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_INFO, "Failed to retrieve MAC address for ip %s, so not putting in the login request",
                  r->clientAddr);
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&channel_path=%s&ssid=%s&ip=%s&url=%s",
                          auth_server->authserv_login_script_path_fragment, config->gw_address, config->gw_port,
                          config->gw_id, 
						  g_channel_path?g_channel_path:"null",
						  g_ssid?g_ssid:"null",
						  r->clientAddr, url);
        } else {
			t_client *clt = NULL;
            debug(LOG_INFO, "Got client MAC address for ip %s: %s", r->clientAddr, mac);
	
            safe_asprintf(&urlFragment, "%sgw_address=%s&gw_port=%d&gw_id=%s&channel_path=%s&ssid=%s&ip=%s&mac=%s&url=%s",
                          auth_server->authserv_login_script_path_fragment,
                          config->gw_address, config->gw_port, config->gw_id, 
						  g_channel_path?g_channel_path:"null",
						  g_ssid?g_ssid:"null",
						  r->clientAddr, mac, url);
			
			//>>> liudf 20160106 added
			if(_special_process(r, mac, urlFragment)) {
            	free(urlFragment);
				free(url);
				free(mac);
				return;
			}
	
			if(is_roaming(mac)) {
				fw_set_roam_mac(mac);
                http_send_redirect(r, tmp_url, "device roaming");
            	free(urlFragment);
                free(url);
				free(mac);
				return;
			}
			
			// if device has login; but after long time reconnected router, its ip changed
			LOCK_CLIENT_LIST();
			clt = client_list_find_by_mac(mac);
			if(clt && strcmp(clt->ip, r->clientAddr) != 0) {
				fw_deny(clt);
				free(clt->ip);
				clt->ip = safe_strdup(r->clientAddr);
				fw_allow(clt, clt->fw_connection_state);
				UNLOCK_CLIENT_LIST();
				http_send_redirect(r, tmp_url, "device has login");
            	free(urlFragment);
                free(url);
				free(mac);
				return;
			}
			UNLOCK_CLIENT_LIST();
			
			// if device is wired and wired device no need auth
			if(config->wired_passed == 1 && is_device_wired(mac)) {
        		debug(LOG_INFO, "wired_passed:  %s is wired device", mac);
				t_trusted_mac *pmac = add_trusted_mac(mac);
				fw_set_trusted_mac(mac);
				http_send_redirect(r, tmp_url, "device no need login");
				if(pmac != NULL)
					pmac->ip = safe_strdup(r->clientAddr);
            	free(urlFragment);
                free(url);
				free(mac);
				return;
			}
			//<<< liudf added end

           	free(mac);
        }
		
        // if host is not in whitelist, maybe not in conf or domain'IP changed, it will go to here.
        debug(LOG_INFO, "Check host %s is in whitelist or not", r->request.host);       // e.g. www.example.com
        t_firewall_rule *rule;
        //e.g. example.com is in whitelist
        // if request http://www.example.com/, it's not equal example.com.
        for (rule = get_ruleset("global"); config->js_filter != 1 && rule != NULL; rule = rule->next) {
            debug(LOG_INFO, "rule mask %s", rule->mask);
            if (strstr(r->request.host, rule->mask) == NULL) {
                debug(LOG_INFO, "host %s is not in %s, continue", r->request.host, rule->mask);
                continue;
            }
            int host_length = strlen(r->request.host);
            int mask_length = strlen(rule->mask);
            if (host_length != mask_length) {
                char prefix[1024] = {0};
                // must be *.example.com, if not have ".", maybe Phishing. e.g. phishingexample.com
                strncpy(prefix, r->request.host, host_length - mask_length - 1);        // e.g. www
                strcat(prefix, ".");    // www.
                strcat(prefix, rule->mask);     // www.example.com
                if (strcasecmp(r->request.host, prefix) == 0) {
                    debug(LOG_INFO, "allow subdomain");
                    fw_allow_host(r->request.host);
                    http_send_redirect(r, tmp_url, "allow subdomain");
                    free(url);
                    free(urlFragment);
                    return;
                }
            } else {
                // e.g. "example.com" is in conf, so it had been parse to IP and added into "iptables allow" when wifidog start. but then its' A record(IP) changed, it will go to here.
                debug(LOG_INFO, "allow domain again, because IP changed");
                fw_allow_host(r->request.host);
                http_send_redirect(r, tmp_url, "allow domain");
                free(url);
                free(urlFragment);
                return;
            }
        }
		
        debug(LOG_INFO, "Captured %s requesting [%s] and re-directing them to login page", r->clientAddr, url);
		if(config->js_filter)
			http_send_js_redirect_ex(r, urlFragment);
		else
			http_send_redirect_to_auth(r, urlFragment, "Redirect to login page");
        free(urlFragment);
    }
    free(url);
}