Ejemplo n.º 1
0
void Gobby::SelfHoster::on_require_password_changed()
{
	// Update SASL context and mechanisms for new connections:
	m_server.set_sasl_context(m_sasl_context, get_sasl_mechanisms());

	// Also update the SASL context for all existing connections. This is
	// important, so that the new password requirement setting also
	// affects already connected but not yet authorized clients.
	infd_directory_foreach_connection(
		m_directory, directory_foreach_func_set_sasl_context_static,
		this);
}
static void
infinoted_plugin_manager_unload_plugin(InfinotedPluginManager* manager,
                                       InfinotedPluginInstance* instance)
{
  InfinotedPluginManagerPrivate* priv;
  InfinotedPluginManagerForeachConnectionData data;
  InfBrowserIter root;

  priv = INFINOTED_PLUGIN_MANAGER_PRIVATE(manager);
  priv->plugins = g_slist_remove(priv->plugins, instance);

  /* Unregister all sessions with the plugin */
  inf_browser_get_root(INF_BROWSER(priv->directory), &root);
  infinoted_plugin_manager_walk_directory(
    manager,
    &root,
    instance,
    infinoted_plugin_manager_remove_session
  );

  /* Unregister all connections with the plugin */
  data.manager = manager;
  data.instance = instance;
  infd_directory_foreach_connection(
    priv->directory,
    infinoted_plugin_manager_unload_plugin_foreach_connection_func,
    &data
  );

  if(instance->plugin->on_deinitialize != NULL)
    instance->plugin->on_deinitialize(instance+1);

  infinoted_log_info(
    priv->log,
    _("Unloaded plugin \"%s\" from \"%s\""),
    instance->plugin->name,
    g_module_name(instance->module)
  );

  g_module_close(instance->module);
  g_free(instance);
}
static gboolean
infinoted_plugin_manager_load_plugin(InfinotedPluginManager* manager,
                                     const gchar* plugin_path,
                                     const gchar* plugin_name,
                                     GKeyFile* key_file,
                                     GError** error)
{
  gchar* plugin_basename;
  gchar* plugin_filename;

  GModule* module;
  const InfinotedPlugin* plugin;
  InfinotedPluginInstance* instance;

  gboolean result;
  GError* local_error;

  InfBrowserIter root;
  InfinotedPluginManagerForeachConnectionData data;

  plugin_basename = g_strdup_printf(
    "libinfinoted-plugin-%s.%s",
    plugin_name,
    G_MODULE_SUFFIX
  );

  plugin_filename = g_build_filename(plugin_path, plugin_basename, NULL);
  g_free(plugin_basename);

  module = g_module_open(plugin_filename, G_MODULE_BIND_LOCAL);
  g_free(plugin_filename);

  if(module == NULL)
  {
    g_set_error(
      error,
      infinoted_plugin_manager_error_quark(),
      INFINOTED_PLUGIN_MANAGER_ERROR_OPEN_FAILED,
      "%s",
      g_module_error()
    );

    
    return FALSE;
  }

  if(g_module_symbol(module, "INFINOTED_PLUGIN", (gpointer*)&plugin) == FALSE)
  {
    g_set_error(
      error,
      infinoted_plugin_manager_error_quark(),
      INFINOTED_PLUGIN_MANAGER_ERROR_NO_ENTRY_POINT,
      "%s",
      g_module_error()
    );
    
    g_module_close(module);
    return FALSE;
  }

  instance = g_malloc(sizeof(InfinotedPluginInstance) + plugin->info_size);
  instance->module = module;
  instance->plugin = plugin;

  /* Call on_info_initialize, allowing the plugin to set default values */
  if(plugin->on_info_initialize != NULL)
    plugin->on_info_initialize(instance+1);

  /* Next, parse options from keyfile */
  if(plugin->options != NULL)
  {
    local_error = NULL;

    result = infinoted_parameter_load_from_key_file(
      plugin->options,
      key_file,
      plugin->name,
      instance+1,
      &local_error
    );
    
    if(result == FALSE)
    {
      g_free(instance);
      g_module_close(module);

      g_propagate_prefixed_error(
        error,
        local_error,
        "Failed to initialize plugin \"%s\": ",
        plugin_name
      );

      return FALSE;
    }
  }

  /* Finally, call on_initialize, which allows the plugin to initialize
   * itself with the plugin options. */
  if(plugin->on_initialize != NULL)
  {
    local_error = NULL;

    result = plugin->on_initialize(manager, instance+1, &local_error);

    if(local_error != NULL)
    {
      if(instance->plugin->on_deinitialize != NULL)
        instance->plugin->on_deinitialize(instance+1);

      g_free(instance);
      g_module_close(module);

      g_propagate_prefixed_error(
        error,
        local_error,
        "Failed to initialize plugin \"%s\": ",
        plugin_name
      );

      return FALSE;
    }
  }

  /* Register initial connections with plugin */
  data.manager = manager;
  data.instance = instance;
  infd_directory_foreach_connection(
    manager->directory,
    infinoted_plugin_manager_load_plugin_foreach_connection_func,
    &data
  );

  /* Register initial sessions with plugin */
  inf_browser_get_root(INF_BROWSER(manager->directory), &root);
  infinoted_plugin_manager_walk_directory(
    manager,
    &root,
    instance,
    infinoted_plugin_manager_add_session
  );

  infinoted_log_info(
    manager->log,
    _("Loaded plugin \"%s\" from \"%s\""),
    plugin_name,
    g_module_name(module)
  );

  manager->plugins = g_slist_prepend(manager->plugins, instance);

  return TRUE;
}
Ejemplo n.º 4
0
void Gobby::SelfHoster::apply_preferences()
{
	// Update directory storage
	if(m_preferences.user.keep_local_documents)
	{
		InfdStorage* storage =
			infd_directory_get_storage(m_directory);
		g_assert(storage == NULL ||
		         INFD_IS_FILESYSTEM_STORAGE(storage));
		InfdFilesystemStorage* fs_storage =
			INFD_FILESYSTEM_STORAGE(storage);

		const std::string new_directory =
			m_preferences.user.host_directory;

		bool set_new_storage = true;
		if(fs_storage != NULL)
		{
			gchar* root_directory;
			g_object_get(
				G_OBJECT(fs_storage),
				"root-directory", &root_directory, NULL);

			if(strcmp(root_directory, new_directory.c_str()) == 0)
				set_new_storage = false;

			g_free(root_directory);
		}

		if(set_new_storage)
		{
			fs_storage = infd_filesystem_storage_new(
				new_directory.c_str());
			g_object_set(
				G_OBJECT(m_directory),
				"storage", fs_storage, NULL);
			g_object_unref(fs_storage);
		}
	}
	else
	{
		if(infd_directory_get_storage(m_directory) != NULL)
		{
			g_object_set(
				G_OBJECT(m_directory), "storage", NULL, NULL);
		}
	}

	// Remove old statusbar message, if any
	if(m_info_handle != m_status_bar.invalid_handle())
	{
		m_status_bar.remove_message(m_info_handle);
		m_info_handle = m_status_bar.invalid_handle();
	}

	// Close server and all connections if no access is required
	if(!m_preferences.user.allow_remote_access)
	{
		infd_directory_foreach_connection(
			m_directory, directory_foreach_func_close_static,
			this);
		if(m_server.is_open())
			m_server.close();
		return;
	}

	// Okay, we want to share our documents, so let's try to start a
	// server for it.

	// Make sure TLS credentials are available.
	if(m_preferences.security.policy !=
	   INF_XMPP_CONNECTION_SECURITY_ONLY_UNSECURED &&
	   (m_preferences.security.authentication_enabled != true ||
            m_cert_manager.get_private_key() == NULL ||
	    m_cert_manager.get_certificates() == NULL))
	{
		m_info_handle = m_status_bar.add_info_message(
			_("In order to start sharing your documents, "
			  "choose a private key and certificate or "
			  "create a new pair in the preferences"));
		return;
	}

	// Make sure we have DH parameters
	if(!ensure_dh_params()) return;

	// Okay, go and open a server. If the server is already open the
	// command below will only change the port and/or security policy.
	try
	{
		const InfKeepalive& keepalive =
			m_preferences.network.keepalive;
		m_server.open(m_preferences.user.port, &keepalive,
		              m_preferences.security.policy,
		              m_cert_manager.get_credentials(),
		              m_sasl_context, get_sasl_mechanisms());
	}
	catch(const std::exception& ex)
	{
		m_status_bar.add_error_message(_("Failed to share documents"),
		                               ex.what());

		return;
	}
}