Beispiel #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);
}
Beispiel #2
0
void 
http_callback_auth(httpd *webserver, request *r)
{
	t_client	*client;
	httpVar * token;
	char	*mac;
	if ((token = httpdGetVariableByName(r, "token"))) {
		/* They supplied variable "token" */
		if (!(mac = arp_get(r->clientAddr))) {
			/* We could not get their MAC address */
			debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
			send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
		} else {
			/* We have their MAC address */

			LOCK_CLIENT_LIST();
			
			if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
				debug(LOG_DEBUG, "New client for %s", r->clientAddr);
				client_list_append(r->clientAddr, mac, token->value);
			} else {
				debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
			}
			UNLOCK_CLIENT_LIST();
			authenticate_client(r);
			free(mac);
		}
	} else {
		/* They did not supply variable "token" */
		send_http_page(r, "WiFiDog error", "Invalid token");
	}
}
static int write_connection_cb(server_generic_client_t *client)
{
        assert(!(client->state & SERVER_GENERIC_CLIENT_STATE_CLOSING));

        if ( client->state & SERVER_GENERIC_CLIENT_STATE_ACCEPTED )
                return client->server->write(client);
        else {
                server_generic_notify_write_disable(client);
                return authenticate_client(client->server, client);
        }
}
/*
 * callback called by server-logic when data is available for reading.
 * We direct the message either to the authentication process either
 * to the real data handling function.
 *
 * If the authentication function return -1 (error), this will cause
 * server-logic to call the close_connection_cb callback.
 */
static int read_connection_cb(server_generic_client_t *client)
{
        int ret = 0;

        assert(!(client->state & SERVER_GENERIC_CLIENT_STATE_CLOSING));

        if ( client->state & SERVER_GENERIC_CLIENT_STATE_ACCEPTED )
                ret = client->server->read(client);
        else
                ret = authenticate_client(client->server, client);

        return ret;
}
Beispiel #5
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);
}
Beispiel #6
0
void
http_callback_auth(httpd * webserver, request * r)
{
    t_client *client;
    httpVar *token;
    char *mac;
    httpVar *logout = httpdGetVariableByName(r, "logout");
    const s_config *config = config_get_config();

    if ((token = httpdGetVariableByName(r, "token"))) {
        /* They supplied variable "token" */
        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
            send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
        } else {
	    t_redir_node *node;
	    int index = 0;
	    LOCK_REDIR();
	    node = redir_list_find(mac);
	    if (node) {
		index = node->wlindex;
	    }
	    UNLOCK_REDIR();
            /* We have their MAC address */
            LOCK_CLIENT_LIST();

            if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
                debug(LOG_DEBUG, "New client for %s", r->clientAddr);
                client = client_list_add(r->clientAddr, mac, token->value);
		client->fw_connection_state = FW_MARK_REDIR;
		client->counters.active_duration = config->sessiontimeout[index-1];
            } else if (logout) {
                logout_client(client);
            } else {
                debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
            }

            UNLOCK_CLIENT_LIST();
            if (!logout) { /* applies for case 1 and 3 from above if */
                authenticate_client(r);
            }
            free(mac);
        }
    } else {
        /* They did not supply variable "token" */
        send_http_page(r, "WiFiDog error", "Invalid token");
    }
}
Beispiel #7
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 #8
0
    void
http_callback_auth(httpd *webserver, request *r)
{
    t_client	*client;
    httpVar * token;
    char	*mac;
    httpVar *logout = httpdGetVariableByName(r, "logout");
    if ((token = httpdGetVariableByName(r, "token"))) {
        /* They supplied variable "token" */
        if (!(mac = arp_get(r->clientAddr))) {
            /* We could not get their MAC address */
            debug(LOG_ERR, "Failed to retrieve MAC address for ip %s", r->clientAddr);
            send_http_page(r, "WiFiDog Error", "Failed to retrieve your MAC address");
        } else {
            /* We have their MAC address */

            LOCK_CLIENT_LIST();

            if ((client = client_list_find(r->clientAddr, mac)) == NULL) {
                debug(LOG_DEBUG, "New client for %s", r->clientAddr);
                client_list_append(r->clientAddr, mac, token->value);
            } else if (logout) {
                t_authresponse  authresponse;
                s_config *config = config_get_config();
                unsigned long long incoming = client->counters.incoming;
                unsigned long long outgoing = client->counters.outgoing;
                char *ip = safe_strdup(client->ip);
                char *urlFragment = NULL;
                t_auth_serv	*auth_server = get_auth_server();

                fw_deny(client->ip, client->mac, client->fw_connection_state);
                client_list_delete(client);
                debug(LOG_DEBUG, "Got logout from %s", client->ip);

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

                    /* Re-direct them to auth server */
                    debug(LOG_INFO, "Got manual logout from client ip %s, mac %s, token %s"
                            "- redirecting them to logout message", client->ip, client->mac, client->token);
                    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);
                }
                free(ip);
            }
            else {
                debug(LOG_DEBUG, "Client for %s is already in the client list", client->ip);
            }
            UNLOCK_CLIENT_LIST();
            if (!logout) {
                authenticate_client(r);
            }
            free(mac);
        }
    } else {
        /* They did not supply variable "token" */
        send_http_page(r, "WiFiDog error", "Invalid token");
    }
}
Beispiel #9
0
void
check_config(void)
{
  char buf[BUFSIZ];
  char aclfile[MAXPATHLEN];
  char *tools_dir=NULL;
  char *tree_owner=NULL;
  char *map_file=NULL;
  char *cmd;
  char *p;
  char *q=(char *)"";
  FILE *fp;
  int cmdfound;
  char *uniq_str_arg;
  struct stat st;
  struct passwd *pw;
  char * bufptr;
  BOOLEAN matched;
  int i;
  char * dummy;

  if (debug)
      diag("checking config");
  if ( !batch ) {
    tree_base = *arglist++;
    tree_owner = *arglist++;
  } /* if */
  cmd = *arglist;
  if (debug)
      diag("command: %s", cmd );
  if ( strcmp ( cmd, "odexm_begin") == 0 ) {
     start_batch = 1;
     return;
  } /* if */
  if ( strcmp ( cmd, "odexm_end") == 0 ) {
     end_batch = 1;
     return;
  } /* if */
  if ( first ) {
    first = FALSE;
    if ((fp = fopen( conf_file, "r")) == NULL)
      efatal("fopen %s", conf_file);
    matched = FALSE;
    while ( fgets( buf, sizeof(buf), fp ) != NULL) {
      rm_newline ( buf );
      bufptr = (char *) buf;
      uniq_str_arg = strdup ( nxtarg ( &bufptr, " \t" ) );
      if ( strcmp ( uniq_str_arg, uniq_str ) != 0 )
        continue;
      /* if */
      matched = TRUE;
      if ( batch )
        tree_base = strdup ( nxtarg ( &bufptr, " \t" ) );
      else
	/* Skip over argument */
        dummy = nxtarg ( &bufptr, " \t" );
      /* if */
      tools_dir = strdup ( nxtarg ( &bufptr, " \t" ) );
      if ( batch )
        tree_owner = strdup ( nxtarg ( &bufptr, " \t" ) );
      else
	/* Skip over argument */
        dummy = nxtarg ( &bufptr, " \t" );
      /* if */
      map_file = strdup ( nxtarg ( &bufptr, " \t" ) );
      break;
    } /* while */
    fclose ( fp );
    if ( ! matched ) {
      sprintf (buf, "No match for unique string %s\nin configuration file %s.\n", uniq_str, conf_file );
      fatal (buf);
    }
    if (debug)
      diag("map file %s", map_file );
    if (lstat(map_file, &st) < 0 || (st.st_mode&S_IFMT) != S_IFREG) {
      sprintf(buf, "Invalid odexm map file: %s\n", map_file);
      fatal(buf);
    }
    if (debug)
      diag("map file mode ok");
    if ((pw = getpwnam(tree_owner)) == NULL)
      fatal("Owner of directory not found");
    if (pw -> pw_uid == 0)
      fatal("Cannot run as root");
    if (setgid(pw->pw_gid) < 0)
      efatal("setgid");
    if (setuid(pw->pw_uid) < 0)
      efatal("setuid");
    if (chdir(tree_base) < 0)
      efatal("chdir");
    if (debug)
      diag("setuid/chdir ok");
    (void) concat ( exec_path, sizeof (exec_path), tools_dir,
                    ":/bin:/usr/bin:/usr/ucb", NULL );
    if ((fp = fopen(map_file, "r")) == NULL)
        efatal("map file fopen");
    i = 0;
    while ((p = fgets(buf, sizeof(buf), fp)) != NULL) {
      if ((q  = strrchr (p, '\n')) != NULL)
          *q = '\0';
      q = nxtarg(&p, " \t");
      strcpy ( map_data [i].cmd, q );
      q = nxtarg(&p, " \t");
      strcpy ( map_data [i].bin, q );
      q = nxtarg(&p, " \t");
      strcpy ( map_data [i].acl, q );
      i++;
    }
    map_entries = i;
    (void) fclose(fp);
  } /* if */
  if ( tempslot != 0 && !made_temp_dir ) {
    made_temp_dir = TRUE;
    concat ( tempdir, sizeof(tempdir), tree_base, "/#odexmXXXXXX", NULL);
    if ( opentemp(tempdir, tempdir ) < 0) {
    	efatal("opentemp %s failed", tree_base); 
    }
  } /* if */
  cmdfound = FALSE;
  if ( strcmp ( cmd, "odexm_cp" ) != 0 ) {
    for ( i = 0; i < map_entries; i++ ) {
      if (strcmp( map_data [i].cmd, cmd) == 0) {
        cmdfound = TRUE;
        (void) strcpy(aclfile, q);
        strcpy ( cmdbuf, map_data [i].bin );
      } /* if */
    } /* for */
    if (!cmdfound) {
      sprintf (buf, "No match for command %s in map file %s.\n", cmd, map_file );
      fatal("%s", buf);
    }
    if (debug)
      diag("command %s acl %s temp %s", cmdbuf, aclfile, tempdir);
    /* if */
  } /* if */
  if ( !batch )
    authenticate_client ();
  /* if */
}
Beispiel #10
0
/*ARGSUSED*/
void
main( int argc, char **argv)
{
    errdesc = 1;
    debug = 0;

  if ( argc == 2 ) {
    conf_file = *(argv+1);
  } /* if */
    /*
     * setup network connections
     */
    setup_connections();

    if ( batch ) {
      /*
       * check authentication
       */

      authenticate_client();

      read_config_info ();

    } else {
      strcpy ( uniq_str, "kxct-compatible" );
    } /* if */
    for (;;) {
      /*
       * read argument list for command
       */
      read_arglist();
      /*
       * check configuration
       */
      check_config();

      if ( start_batch ) {
        start_batch = 0;
        continue;
      } /* if */
      if ( end_batch ) {
        break;
      } /* if */
      /*
       * receive data file
       */
      if (tempslot != 0)
          receive_data();

    /*
     * execute command
     */
    run_command();
    /*
     * transmit data file
     */
    if (tempslot != 0)
        transmit_data();

    /*
     * transmit the exit status
     */
    transmit_status();
    if ( ! batch ) {
      break;
    } /* if */
}
    /*
     * that is all
     */
    if ( made_temp_dir )
      (void) rmdir(tempdir);
    /* if */
    exit(0);
}