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...");
}
Beispiel #2
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);
}
Beispiel #3
0
static void
ndsctl_auth(int fd, char *arg)
{
	t_client	*client;
	char *ip, *mac;
	debug(LOG_DEBUG, "Entering ndsctl_auth...");

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

	/* Add client to client list... */
	if ((client = client_list_add_client(arg)) == NULL) {
		debug(LOG_DEBUG, "Could not add client.");
		UNLOCK_CLIENT_LIST();
		write(fd, "No", 2);
		return;
	}

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

	auth_client_action(ip, mac, AUTH_MAKE_AUTHENTICATED);

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

	debug(LOG_DEBUG, "Exiting ndsctl_auth...");
}
Beispiel #4
0
/**
 * @brief authenticate the client and redirect them
 * @param connection
 * @param ip_addr - needs to be freed
 * @param mac - needs to be freed
 * @param redirect_url - redirect the client to this url
 * @return
 */
static int authenticate_client(struct MHD_Connection *connection,
							   const char *ip_addr,
							   const char *mac,
							   const char *redirect_url,
							   t_client *client)
{
	/* TODO: handle redirect_url == NULL */
	auth_client_action(ip_addr, mac, AUTH_MAKE_AUTHENTICATED);
	return send_redirect_temp(connection, redirect_url);
}
Beispiel #5
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);
}
Beispiel #6
0
/** The multipurpose authentication action handler
 */
void
http_nodogsplash_callback_action(request *r,
								 t_auth_target *authtarget,
								 t_authaction action)
{
	t_client	*client;
	char *mac;
	const char *ip;
	char *clienttoken = NULL;
	const char *requesttoken = authtarget->token;
	const char *redir = authtarget->redir;

	ip = r->clientAddr;

	if(!requesttoken) {
		debug(LOG_NOTICE, "No token in request from ip %s", ip);
		return;
	}
	if(!redir) {
		debug(LOG_NOTICE, "No redirect in request from ip %s", ip);
		return;
	}

	if (!(mac = arp_get(ip))) {
		/* We could not get their MAC address */
		debug(LOG_NOTICE, "Could not arp MAC address for %s action %d", ip, action);
		return;
	}

	/* We have their MAC address, find them on the client list */
	LOCK_CLIENT_LIST();
	client = client_list_find(ip,mac);
	if(client && client->token) {
		clienttoken = safe_strdup(client->token);
	}
	UNLOCK_CLIENT_LIST();

	if(!client) {
		debug(LOG_NOTICE, "Client %s %s action %d is not on client list",
			  ip, mac, action);
		http_nodogsplash_serve_info(r,
									"Nodogsplash Error",
									"You are not on the client list.");
		free(mac);
		return;
	}

	/* We have a client */

	/* Do we have a client token? */
	if(!clienttoken) {
		debug(LOG_NOTICE, "Client %s %s action %d does not have a token",
			  ip, mac, action);
		free(mac);
		return;
	}

	debug(LOG_DEBUG, "Action %d: %s %s tokens %s, %s",
		  action, ip, mac, clienttoken, requesttoken);
	debug(LOG_DEBUG, "Redirect:  %s", redir);

	/* Check token match */
	if (strcmp(clienttoken,requesttoken)) {
		/* tokens don't match, reject */
		debug(LOG_NOTICE, "Client %s %s tokens %s, %s do not match",
			  r->clientAddr, mac, clienttoken, requesttoken);
		http_nodogsplash_serve_info(r, "Nodogsplash Error",
									"Tokens do not match.");
		free(mac);
		free(clienttoken);
		return;
	}

	/* Log value of info string, if any */
	if(authtarget->info) {
		debug(LOG_NOTICE, "Client %s %s info: %s",
			  ip, mac, authtarget->info);
	}

	/* take action */
	switch(action) {
	case AUTH_MAKE_AUTHENTICATED:
		auth_client_action(ip,mac,action);
		http_nodogsplash_redirect(r, redir);
		break;
	case AUTH_MAKE_DEAUTHENTICATED:
		auth_client_action(ip,mac,action);
		http_nodogsplash_serve_info(r, "Nodogsplash Deny",
									"Authentication revoked.");
		break;
	default:
		debug(LOG_ERR, "Unknown auth action: %d", action);
	}

	free(mac);
	free(clienttoken);
	return;
}
Beispiel #7
0
static int check_token_is_valid(struct MHD_Connection *connection, t_client *client)
{
	/* token check */
	struct collect_query_key token_key = { .key = "token" };
	struct collect_query_key tok_key = { .key = "tok" };

	MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &collect_query_key, &token_key);
	MHD_get_connection_values(connection, MHD_GET_ARGUMENT_KIND, &collect_query_key, &tok_key);

	/* token not found in query string */
	if (!token_key.value && !tok_key.value)
		return 0;

	if (token_key.value && !strcmp(client->token, token_key.value))
		return 1;

	if (tok_key.value && !strcmp(client->token, tok_key.value))
		return 1;

	return 0;
}


/**
 * @brief try_to_authenticate
 * @param connection
 * @param client
 * @param host
 * @param url
 * @return
 */
static int try_to_authenticate(struct MHD_Connection *connection, t_client *client, const char *host, const char *url)
{
	/* a successful auth looks like
	 * http://192.168.42.1:2050/nodogsplash_auth/?redir=http%3A%2F%2Fberlin.freifunk.net%2F&tok=94c4cdd2
	 * when authaction -> http://192.168.42.1:2050/nodogsplash_auth/
	 */
	s_config *config = config_get_config();

	/* we are checking here for the second '/' of /denydir/ */
	if (check_authdir_match(url, config->authdir)) {
		/* matched to authdir */
		if (check_token_is_valid(connection, client)) {
			return 1; /* valid token */
		}
	} else if (check_authdir_match(url, config->denydir)) {
		/* matched to deauth */
		/* TODO: do we need denydir? */
		return 0;
	}

	return 0;
}

/**
 * @brief authenticate the client and redirect them
 * @param connection
 * @param ip_addr - needs to be freed
 * @param mac - needs to be freed
 * @param redirect_url - redirect the client to this url
 * @return
 */
static int authenticate_client(struct MHD_Connection *connection,
							   const char *ip_addr,
							   const char *mac,
							   const char *redirect_url,
							   t_client *client)
{
	/* TODO: handle redirect_url == NULL */
	auth_client_action(ip_addr, mac, AUTH_MAKE_AUTHENTICATED);
	if (redirect_url)
		return send_redirect_temp(connection, redirect_url);
	else
		return send_error(connection, 200);
}