예제 #1
0
/**
 * @brief authenticated - called for all request from authenticated clients.
 * @param connection
 * @param ip_addr
 * @param mac
 * @param url
 * @param client
 * @return
 *
 * It's unsual to received request from clients which are already authed.
 * Happens when the user:
 * - clicked in multiple windows on "accept" -> redirect to origin - no checking
 * - when the user reloaded a splashpage -> redirect to origin
 * - when a user calls deny url -> deauth it
 */
static int authenticated(struct MHD_Connection *connection,
						 const char *ip_addr,
						 const char *mac,
						 const char *url,
						 t_client *client)
{
	s_config *config = config_get_config();
	const char *redirect_url;
	const char *host = NULL;
	char redirect_to_us[128];

	MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host);

	if (is_splashpage(host, url) ||
			check_authdir_match(url, config->authdir)) {
		redirect_url = get_redirect_url(connection);
		/* TODO: what should we do when we get such request? */
		if (redirect_url == NULL || strlen(redirect_url) == 0)
			return show_splashpage(connection, client);
		else
			return authenticate_client(connection, ip_addr, mac, redirect_url, client);
	} else if (check_authdir_match(url, config->denydir)) {
		auth_client_action(ip_addr, mac, AUTH_MAKE_DEAUTHENTICATED);
		snprintf(redirect_to_us, 128, "http://%s:%u/", config->gw_address, config->gw_port);
		return send_redirect_temp(connection, redirect_to_us);
	}

	/* user doesn't wants the splashpage or tried to auth itself */
	return serve_file(connection, client, url);
}
예제 #2
0
/**
 * @brief preauthenticated - called for all request of a client in this state.
 * @param connection
 * @param ip_addr
 * @param mac
 * @return
 */
static int preauthenticated(struct MHD_Connection *connection,
							const char *ip_addr,
							const char *mac,
							const char *url,
							t_client *client)
{
	char *host = NULL;
	const char *redirect_url;
	s_config *config = config_get_config();

	if (!client) {
		client = add_client(ip_addr);
		if (!client)
			return send_error(connection, 503);
	}

	MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host);

	/* check if this is a redirect querty with a foreign host as target */
	if(is_foreign_hosts(connection, host)) {
		return redirect_to_splashpage(connection, client, host, url);
	}

	/* request is directed to us */
	/* check if client wants to be authenticated */
	if(check_authdir_match(url, config->authdir)) {

		/* Only the first request will redirected to config->redirectURL.
		 * When the client reloads a page when it's authenticated, it should be redirected
		 * to their origin url
		 */
		if (config->redirectURL)
			redirect_url = config->redirectURL;
		else
			redirect_url = get_redirect_url(connection);

		if (try_to_authenticate(connection, client, host, url)) {
			return authenticate_client(connection, ip_addr, mac, redirect_url, client);
		} else {
			/* user used an invalid token, redirect to splashpage but hold query "redir" intact */
			return encode_and_redirect_to_splashpage(connection, redirect_url);
		}
	}

	if(is_splashpage(host, url)) {
		return show_splashpage(connection, client);
	}

	/* no special handling left - try to serve static content to the user */
	return serve_file(connection, client, url);
}
예제 #3
0
/**
 * @brief authenticated - called for all request from authenticated clients.
 * @param connection
 * @param ip_addr
 * @param mac
 * @param url
 * @param client
 * @return
 *
 * It's unsual to received request from clients which are already authed.
 * Happens when the user:
 * - clicked in multiple windows on "accept" -> redirect to origin - no checking
 * - when the user reloaded a splashpage -> redirect to origin
 * - when a user calls deny url -> deauth it
 */
static int authenticated(struct MHD_Connection *connection,
						 const char *ip_addr,
						 const char *mac,
						 const char *url,
						 t_client *client)
{
	s_config *config = config_get_config();
	const char *redirect_url;
	const char *host = NULL;
	char redirect_to_us[128];

	MHD_get_connection_values(connection, MHD_HEADER_KIND, get_host_value_callback, &host);

	if (is_splashpage(host, url) ||
			check_authdir_match(url, config->authdir)) {
		redirect_url = get_redirect_url(connection);
		/* TODO: what should we do when we get such request? */
		if (redirect_url == NULL || strlen(redirect_url) == 0)
			return show_splashpage(connection, client);
		else
			return authenticate_client(connection, ip_addr, mac, redirect_url, client);
	} else if (check_authdir_match(url, config->denydir)) {
		auth_client_action(ip_addr, mac, AUTH_MAKE_DEAUTHENTICATED);
		snprintf(redirect_to_us, 128, "http://%s:%u/", config->gw_address, config->gw_port);
		return send_redirect_temp(connection, redirect_to_us);
	}


	/* check if this is an late request meaning the user tries to get the internet, but ended up here,
	 * because the iptables rule came to late */
	if (is_foreign_hosts(connection, host)) {
		/* might happen if the firewall rule isn't yet installed */
		return send_refresh(connection);
	}

	/* user doesn't wants the splashpage or tried to auth itself */
	return serve_file(connection, client, url);
}
예제 #4
0
/**
 * @brief show_splashpage is called when the client clicked on Ok as well when the client doesn't know us yet.
 * @param connection
 * @param client
 * @return
 */
static int show_splashpage(struct MHD_Connection *connection, t_client *client)
{
	struct MHD_Response *response;
	struct templater templor;
	s_config *config = config_get_config();
	int ret = -1;
	char filename[PATH_MAX];
	const char *mimetype;
	int size = 0, bytes = 0;
	int splashpage_fd;
	char *splashpage_result;
	char *splashpage_tmpl;

	snprintf(filename, PATH_MAX, "%s/%s",config->webroot ,config->splashpage);

	splashpage_fd = open(filename, O_RDONLY);
	if (splashpage_fd < 0)
		return send_error(connection, 404);

	mimetype = lookup_mimetype(filename);

	/* input size */
	size = lseek(splashpage_fd, 0, SEEK_END);
	lseek(splashpage_fd, 0, SEEK_SET);

	/* we TMPLVAR_SIZE for template variables */
	splashpage_tmpl = calloc(1, size);
	splashpage_result = calloc(1, size + TMPLVAR_SIZE);

	while (bytes < size) {
		ret = read(splashpage_fd, splashpage_tmpl+bytes, size-bytes);
		if (ret < 0) {
			free(splashpage_result);
			free(splashpage_tmpl);
			close(splashpage_fd);
			return send_error(connection, 503);
		}
		bytes += ret;
	}

	char *uptime = get_uptime_string();
	char *nclients = NULL;
	char *maxclients = NULL;
	char *denyaction = NULL;
	char *authaction = NULL;
	char *authtarget = NULL;
	const char *redirect_url = NULL;
	char redirect_url_encoded[2048];
	char *imagesdir = NULL;
	char *pagesdir = NULL;

	memset(redirect_url_encoded, 0, sizeof(redirect_url_encoded));
	redirect_url = get_redirect_url(connection);
	if (redirect_url) {
		uh_urlencode(redirect_url_encoded, sizeof(redirect_url_encoded), redirect_url, strlen(redirect_url));
	}

	safe_asprintf(&nclients, "%d", get_client_list_length());
	safe_asprintf(&maxclients, "%d", config->maxclients);
	safe_asprintf(&denyaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->denydir);
	safe_asprintf(&authaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->authdir);
	safe_asprintf(&authtarget, "http://%s:%d/%s/?token=%s&redir=%s", config->gw_address, config->gw_port, config->authdir, client->token, redirect_url_encoded);
	safe_asprintf(&authaction, "http://%s:%d/%s/", config->gw_address, config->gw_port, config->authdir);
	safe_asprintf(&pagesdir, "/%s", config->pagesdir);
	safe_asprintf(&imagesdir, "/%s", config->imagesdir);

	tmpl_init_templor(&templor);
	tmpl_set_variable(&templor, "authaction", authaction);
	tmpl_set_variable(&templor, "authtarget", authtarget);
	tmpl_set_variable(&templor, "clientip", client->ip);
	tmpl_set_variable(&templor, "clientmac", client->mac);
	//	tmpl_set_variable(&templor, "content", VERSION);
	tmpl_set_variable(&templor, "denyaction", denyaction);
	tmpl_set_variable(&templor, "error_msg", "");

	tmpl_set_variable(&templor, "gatewaymac", config->gw_mac);
	tmpl_set_variable(&templor, "gatewayname", config->gw_name);

	tmpl_set_variable(&templor, "imagesdir", imagesdir);
	tmpl_set_variable(&templor, "pagesdir", pagesdir);

	tmpl_set_variable(&templor, "maxclients", maxclients);
	tmpl_set_variable(&templor, "nclients", nclients);

	tmpl_set_variable(&templor, "redir", redirect_url);
	tmpl_set_variable(&templor, "tok", client->token);
	tmpl_set_variable(&templor, "uptime", uptime);
	tmpl_set_variable(&templor, "version", VERSION);

	tmpl_parse(&templor, splashpage_result, size + TMPLVAR_SIZE, splashpage_tmpl, size);
	free(authaction);
	free(denyaction);
	free(maxclients);
	free(nclients);
	free(uptime);
	free(splashpage_tmpl);
	free(imagesdir);

	response = MHD_create_response_from_buffer(strlen(splashpage_result), (void *)splashpage_result, MHD_RESPMEM_MUST_FREE);
	if (!response) {
		close(splashpage_fd);
		return send_error(connection, 503);
	}

	MHD_add_response_header(response, "Content-Type", mimetype);
	ret = MHD_queue_response(connection, MHD_HTTP_OK, response);
	MHD_destroy_response(response);

	close(splashpage_fd);

	return ret;
}