Beispiel #1
0
void file_free(OBJECT * filename, int is_recursive)
{
    file_info_t * ff;

    /* do nothing if cache is uninitialized */
    if ( !filecache_hash )
        return;

    ff = file_info( filename );
    hash_free( filecache_hash, (HASHDATA*)ff );

    /* freed directories must free all their files and subdirectories */
    if ( ff->is_dir )
    {
        printf( "dir_free: %s\n", filename );
        if ( !ff->files )
            printf( "directory without files: %s\n", filename );
        else
        {
            LIST * files = ff->files;
            for ( ; files; files = list_next( files ) )
                if ( is_recursive || file_is_file( files->value ) )
                    file_free( files->value, is_recursive );
        }
    }
    else
    {
        printf( "file_free: %s\n", filename );
    }
}
Beispiel #2
0
/** Print plain text file 
 @param path File path
 @todo unify with http_send_file
 */
void
odcgi_print_file (const char *path)
{
  openlog ("odcgi", LOG_PID, LOG_USER);

  char filename[1024];
  // Building the full path
  snprintf (filename, sizeof (filename), "%s%s", OD_CFG_ROOT_DIR, path);
  file_t fs;
  file_set_filename (&fs, filename);
  syslog (LOG_NOTICE, "%s\n", filename);
  printf ("Cache-Control: max-age=3600, must-revalidate\n");
  printf ("Content-Type: text/plain\n\n");
  if (file_is_file (&fs))
    {
      printf ("/* %s: */\n", filename);
      file_print (&fs);
    }
  else
    {
      printf ("/* File (%s) does not exist */\n\n", filename);
    }
}
Beispiel #3
0
/** Main execution routine
 @param argc Number of args (0)
 @param argv Args (always empty)
 */
int
main (int argc, char *argv[])
{


  /* ---------------------------------------------------------------------
   *  Alert! setuid program with root privileges
   * ---------------------------------------------------------------------*/

  /* syslog */
  openlog ("odcgi", LOG_PID, LOG_USER);

  script_env_t env;


  /* Agent address */
  //! @todo: what if eth0 don't exists?
  snprintf (env.agent_address, MAX_ENV_SIZE, "%s", getip ("eth0"));

  //! @todo: lots of static variables. Maybe some can be reused to save memory
  char http_gui[8];
  //char http_style[10];
  char http_logout[8];
  char http_user[256];
  char http_pass[256];
  char http_session[1024];
  char http_noheader[8];
  char http_newuser[256];
  char http_newpass1[256];
  char http_newpass2[256];
  char http_deluser[256];
  char http_moduser[256];
  char http_modpass1[256];
  char http_modpass2[256];
  char http_modoldpass[256];
  char http_getfile[256];
  char http_resource[50];
  char http_play_mjpg[100];
  char http_temp[100];

  /* Configuration vars */
  FILE *fh;
  read_config_file (fh, OD_APP_I18N_CONF, lang, "en");
  //read_config_file(fh,OD_APP_STYLE_CONF,style,"default");
  //read_config_file(fh,OD_APP_SKIN_CONF,skin,"silver");

  /* Get HTTP variables */
  cgi_t *cgi = cgi_alloc ();

  cgi_get_param_by_name (cgi, "GUI", http_gui, sizeof (http_gui));
  cgi_get_param_by_name (cgi, "LOGOUT", http_logout, sizeof (http_logout));
  cgi_get_param_by_name (cgi, "USER", http_user, sizeof (http_user));
  cgi_get_param_by_name (cgi, "PASS", http_pass, sizeof (http_pass));
  cgi_get_param_by_name (cgi, "HTSESSID", http_session,
			 sizeof (http_session));
  cgi_get_param_by_name (cgi, "NOHEADER", http_noheader,
			 sizeof (http_noheader));
  cgi_get_param_by_name (cgi, "NEWUSER", http_newuser, sizeof (http_newuser));
  cgi_get_param_by_name (cgi, "NEWPASS1", http_newpass1,
			 sizeof (http_newpass1));
  cgi_get_param_by_name (cgi, "NEWPASS2", http_newpass2,
			 sizeof (http_newpass2));
  cgi_get_param_by_name (cgi, "DELUSER", http_deluser, sizeof (http_deluser));
  cgi_get_param_by_name (cgi, "MODUSER", http_moduser, sizeof (http_moduser));
  cgi_get_param_by_name (cgi, "MODPASS1", http_modpass1,
			 sizeof (http_modpass1));
  cgi_get_param_by_name (cgi, "MODPASS2", http_modpass2,
			 sizeof (http_modpass2));
  cgi_get_param_by_name (cgi, "MODOLDPASS", http_modoldpass,
			 sizeof (http_modoldpass));
  cgi_get_param_by_name (cgi, "FILE", http_getfile, sizeof (http_getfile));
  cgi_get_param_by_name (cgi, "resource", http_resource,
			 sizeof (http_resource));
  cgi_get_param_by_name (cgi, "play_mjpg", http_play_mjpg,
			 sizeof (http_play_mjpg));



//      if (cgi_get_param_by_name(cgi,"style", http_style, sizeof(http_style))==1)
//      {
//              //cgi_get_cookie("HTSTYLE", http_style, sizeof(http_style));
//              strncpy(style, http_style, sizeof(http_style));
//              cgi_http_header_set_cookie("HTSTYLE", style);
//      }

  // Si se ha solicitado una hoja de estilo, la entregamos
  if (cgi_get_param_by_name (cgi, "css", http_temp, sizeof (http_temp)) == 1)
    {
      syslog (LOG_NOTICE, "printing style: %s\n", http_temp);
      odcgi_print_file (http_temp);
      cgi_free (cgi);
      return 0;
    }
/*	// Si se ha solicitado el javascript específico, lo entregamos
	if (cgi_get_param_by_name(cgi, "js", http_temp, sizeof(http_temp))==1) 
	{
		syslog(LOG_NOTICE, "printing script: %s\n", http_temp);
		odcgi_print_file(http_temp);
		return 0;
	} */


  if (strlen (http_session) == 0)
    {
      cgi_get_cookie ("HTSESSID", http_session, sizeof (http_session));
      syslog (LOG_NOTICE, "session from cookie: %s\n", http_session);
    }

  /* get gui type */
  if (strcmp (http_gui, "XML") == 0)
    gui = xml;
  if (strcmp (http_gui, "none") == 0)
    gui = none;


  /* login process */
  if (odcgi_login (&env, http_user, http_pass,
		   http_session, sizeof (http_session)) == -1)
    {
      syslog (LOG_NOTICE, "login failed: %s-%s\n", http_user, http_pass);
      cgi_free (cgi);
      return -1;
    }

//      syslog(LOG_NOTICE, "env.user: %s\n", env.user);
//      syslog(LOG_NOTICE, "http_user: %s\n", http_user);


  /* check logout */
  if (odcgi_logout (&env, http_logout))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK: odcgi is setuid root
   * --------------------------------------------------------------------- */
  //syslog(LOG_NOTICE, "[odcgi] userid: %d\n", getuid());

  /* root has not access */
  if (odcgi_check_root (http_user))
    {
      cgi_free (cgi);
      return -1;
    }


  /* ---------------------------------------------------------------------
   *  Login OK:
   *  + admin has root privileges
   *  + normal user has Linux privileges
   * --------------------------------------------------------------------- */
  syslog (LOG_NOTICE, "[odcgi] user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());

	/* NO USER MANAGEMENT FUNCTIONS IN
  // adds a new user 
  if (odcgi_add_user (http_newuser, http_newpass1, http_newpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // delete user 
  if (odcgi_del_user (http_deluser) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

  // modify user password 
  if (odcgi_mod_user (http_moduser, http_modoldpass,
		      http_modpass1, http_modpass2) == -1)
    {
      cgi_free (cgi);
      return -1;
    }

	*/

  /* set session */
  /* Privilege separation: drop root privileges */
//   syslog(LOG_NOTICE, "set session %s\n", http_session);
//   syslog(LOG_NOTICE, "[odcgi] session_set_ids user: %s\n", env.user);
  session_set_ids (env.user);
  syslog (LOG_NOTICE, "[odcgi] dropped privileges user: %s, uid: %d, guid: %d\n",
	  env.user, getuid (), getgid ());
  

  /* File reference with user permissions applied */
  if (strlen (http_getfile) > 5)
    {
      char buffer[1024] = "/media/";
      strcat (buffer, http_getfile);
      if (http_send_file (buffer))
	{
	  cgi_free (cgi);
	  return 0;
	}
      else
	{
	  //! @todo Mostrar error
	}
    }


  /* play mjpg file */
  if (strlen (http_play_mjpg) > 3)
	{
		syslog (LOG_NOTICE, "play: %s\n", http_play_mjpg);
		mjpg_play (http_play_mjpg);
		cgi_free (cgi);
		return 0;
	}

	switch (gui)
	{
		case xml:
			cgi_http_header_begin ("text/xml");
		break;
		case html:
			cgi_http_header_begin ("text/html");
		break;
		default:
			cgi_http_header_begin ("text/plain");
	}


  /* Resource reference */
  //TODO Verificar permisos de usuario
  if (strlen (http_resource) > 3)
	{
		syslog (LOG_NOTICE, "Serving resource %s\n", http_resource);
		if (mjpg_streaming_rsc (http_resource))
		{
			cgi_free (cgi);
			return 0;
		}
		else
		{
			//printf("<div id='connfail'><p class='error'>%s</p></div>\n",
			//              T(ODCGI_ERROR__CONNECTION_FAILURE));
			cgi_free (cgi);
			return 0;
		}
	}



	syslog (LOG_NOTICE, "1.session: %s\n", http_session);
	cgi_http_header_set_cookie ("HTSESSID", http_session);
	//   cgi_get_cookie("HTSTYLE", style, sizeof(style));
	//   cgi_http_header_set_cookie("HTSTYLE", style);
	cgi_http_header_end ();




	/* ---------------------------------------------------------------------
	*  User privileges
	* ---------------------------------------------------------------------*/

	size_t len = cgi->decoded_url->size;
	char path_info[256 + len];
	path_info[0] = 0;
	sstrncpy (path_info, cgi_get_path_info (cgi), sizeof (path_info));
	syslog (LOG_NOTICE, "path_info %s - %d\n", path_info, strlen (path_info));



	// If any POST/GET vars matches with submit_X.sh, X.sh is the target
	// then replace 'path_info'.
	char options[256 + len];
	int index = 0;
	char varname[256];
	char varvalue[256 + len];
	int has_option = 0;
	char scriptname[256] = "";
	char path[256 + len];
	path[0] = 0;

	while (cgi_get_param_by_index (cgi, index, varname, sizeof (varname),
				 varvalue, sizeof (varvalue)))
	{
		// Replace "+" for " "
		for (int i=0;i<sizeof(varvalue);i++) {
			if (varvalue[i]=='+') varvalue[i]=' ';
		}

		syslog (LOG_DEBUG, "CGIParam %d %s=%s\n", index, varname, varvalue);
		
		if (strcmp (varname, "GUI") == 0)
		{
		// Ignore               

		}
		else if (strcmp (varname, "odcgioptionsel") == 0)
		{
			sstrncat (options, varvalue, sizeof (options));
			sstrncat (options, " ", sizeof (options));
			has_option = 1;
		}

		else if (strncmp (varname, "submit_", 7) == 0)
		{
			syslog (LOG_NOTICE, "Submit redirection found at %s\n", varname);
			sstrncpy (scriptname, varname + 7, sizeof (scriptname));
			//sstrncpy(path_info, scriptname, sizeof(path_info));
			snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
			    scriptname);
			syslog (LOG_DEBUG, "debugging %s - %s [%s]\n", scriptname, path,
			  options);
			break;
		}
		index++;
	}


  /* Check PATH variable */
  if (strlen (path_info) == 0)
    strcpy (path_info, "/");

  /* filters */
  if (!match
      (path_info,
       "^/[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/]*\\.{0,1}[a-záéíóúàèäëïöüñçA-ZÁÉÍÓÚÀÈÄËÏÖÜÑÇ0-9_/+ =?:]*$"))
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
      	"Invalid character found in the command.");
      printf ("\n<!-- PATH_INFO: %s-->\n", path_info);
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  int err = 0;

  char *param_regex = "[$;'\\\"]";
  if (strstr (cgi_get_query_string (cgi), ".."))
    err = 1;
  else if (strstr (cgi_get_decoded_url (cgi), ".."))
    err = 2;
  else if (strlen (cgi_get_query_string (cgi)) > 0 &&
	   match (cgi_get_query_string (cgi), param_regex))
    err = 3;
  else if (strlen (cgi_get_decoded_url (cgi)) > 0 &&
	   match (cgi_get_decoded_url (cgi), param_regex))
    err = 4;

  if (err!=0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__INVALID_PATH);
      odcgi_msg_error (ODCGI_ERROR__INVALID_PATH,
		 "Invalid character found in the parameters.");
      printf ("\n<!-- PATH ERROR: %d (not allowed) \n\t%s \n\t %s -->\n", 
      	err,
      	cgi_get_query_string (cgi),
      	cgi_get_decoded_url (cgi));
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }

  // If PATH is not modified, use the default path in CONF_DIR.
  if (path[0] == 0)
    {
      snprintf (path, sizeof (path), "%s/%s", OD_CFG_ROOT_DIR, path_info);
    }

  /* root directory */
  if (chdir (OD_CFG_ROOT_DIR) != 0)
    {
      odcgi_print_header ("error", env.user);
      syslog (LOG_ERR, "%s\n", ODCGI_ERROR__ROOT_PATH_ACCESS);
      odcgi_msg_error (ODCGI_ERROR__ROOT_PATH_ACCESS,
		 "Cannot access the configuration directory. "
		 "Missing privileges or misconfiguration");
      odcgi_print_footer ("", 0, cgi);
      cgi_free (cgi);
      return -1;
    }


  char name[256 + len];
  char value[256 + len];
  char prename[256 + len];
  char *shname;
  string_t *cmd = string_alloc ("");

  file_t fs;
  strcpy (scriptname, basename (path));

  /* HTML-head begin */
  odcgi_print_header (scriptname, env.user);

  printf ("<!-- path: %s, path_info: %s-->\n", path, path_info);

  /* Check NOHEADER */
  if ((gui == html) && (atoi (http_noheader) != 1))
    {
      string_assign_str (cmd, "/usr/bin/categories.sh ");
      string_append (cmd, path_info);

      script_exec (cmd->str, "header", &env);
      if (strlen (path_info) < 2)
	{
	  printf
	    ("  <div class='applicationTitle'><h1>OpenDomo</h1></div>\n");
	}
      else
	{
	  printf ("  <div class='root'><a href='" OD_URI "/'> </a></div>\n");
	}
    }



  sstrncpy (prename, path, sizeof (prename));
  shname = strtok (prename, " ");
  file_set_filename (&fs, shname);
  strcpy (scriptname, basename (path));

  /* if dir: list contents */
  if (file_is_dir (&fs))
    {
      string_assign_str (cmd,  "/usr/bin/list.sh ");
      string_append (cmd, path_info);
      string_append (cmd, " contents");

      script_exec (cmd->str, "main", &env);
    }
  else
    {
      /* if file: execute */
      // The path might be a redirection (no actual link in ..opendomo/root/)
      if (!file_is_file (&fs))
	{
	  snprintf (path, sizeof (path), "/usr/local/opendomo/%s",
		    basename (scriptname));
	  printf ("\n<!-- debug paths: %s / %s [%s] -->\n", path, path_info,
		  scriptname);
	  file_set_filename (&fs, path);
	  if (!file_is_file (&fs))	// If it's still not a valid path, abort
	    {
	      odcgi_msg_error (ODCGI_ERROR__SCRIPT_NOT_FOUND,
			 "The script was not found. "
			 "Maybe the function you are requiring "
			 "is not installed in this system");
	      printf ("<!-- BASENAME: %s -->\n", basename (scriptname));
	      odcgi_print_footer ("", 0, cgi);
	      cgi_free (cgi);
	      return 1;
	    }
	}
      //printf("<!-- debug path: %s -->\n", path);
      //char *p = strrchr(path, '/');
      if (has_option /*&& p */ )
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	  string_append (cmd, options);
	}
      else
	{
	  string_assign_str (cmd, path);
	  string_append (cmd, " ");
	}
      printf ("\n<!-- decoded_url: %s \n\tquery_string: %s-->\n", 
      	cgi->decoded_url->str, cgi->query_string->str);
      int i = 0;
      while (cgi_get_param_by_index (cgi, i++,
				     name, sizeof (name), value,
				     sizeof (value)))
	{
		if (strcmp (name, ODCGI_SESSION_NAME) == 0)
		{
			// Ignoring session name var ...
		}
		else if (strncmp (name, "GUI", 3) == 0)
		{
			// Ignoring GUI param
		}
		else if (strncmp (name, "submit_", 7) == 0)
		{
			// Ignoring possible submit redirection ...
		}
		else
		{
			//for (i = 0; i < sizeof(value); i++){
			//	if (value[i]=='+') value[i]=' ';
			//}
			// Avoid overwritting a defined environment var
			if (getenv (name) == NULL)
				setenv (name, value, 1);
			string_append (cmd, " \"");
			string_append (cmd, value);
			string_append (cmd, "\" ");
		}
	}
	string_replace (cmd, "+", " ");
	string_replace (cmd, "'", "&apos;");

     printf ("<!-- cmd (file): %s -->\n", cmd->str);
      //fflush(stdout); // Force flush, otherwise an error will preceed stdout
      // Check the returned value of script_exec()


      int ret = script_exec (cmd->str, "main", &env);
      if (ret != 0)
	{
	  /* else: empty div */
	  printf ("<div id='main'><p class='error'>%s</p></div>",
		  ODCGI_ERROR__SCRIPT_NOT_FOUND);
	}
    }
  /* Print scripts */
  //odcgi_print_script(path); DEPRECATED

  /* HTML end */
  if (atoi (http_noheader) != 1)
    {
      odcgi_print_footer ("", BUTTON_LOGOUT + BUTTON_DEBUG, cgi);
    }

  string_free (cmd);
  cgi_free (cgi);
  closelog ();
  return 0;
}