コード例 #1
0
static void
infinoted_plugin_dbus_query_acl(InfinotedPluginDbus* plugin,
                                InfinotedPluginDbusInvocation* invocation,
                                InfBrowser* browser,
                                const InfBrowserIter* iter)
{
  const InfAclSheetSet* sheet_set;
  const InfAclSheet* sheet;
  const gchar* account;
  InfAclAccountId id;
  GVariantBuilder builder;

  /* TODO: Actually query the ACL if not available */
  sheet_set = inf_browser_get_acl(browser, iter);
  g_variant_get_child(invocation->parameters, 1, "&s", &account);

  if(*account == '\0')
  {
    g_dbus_method_invocation_return_value(
      invocation->invocation,
      g_variant_new(
        "(@a{sa{sb}})",
        infinoted_builder_dbus_sheet_set_to_variant(sheet_set)
      )
    );
  }
  else
  {
    id = inf_acl_account_id_from_string(account);
    if(sheet_set != NULL)
      sheet = inf_acl_sheet_set_find_const_sheet(sheet_set, id);
    else
      sheet = NULL;

    g_variant_builder_init(&builder, G_VARIANT_TYPE("a{sa{sb}}"));
    if(sheet != NULL)
    {
      g_variant_builder_add(
        &builder,
        "{s@a{sb}}",
        account,
        infinoted_plugin_dbus_perms_to_variant(&sheet->mask, &sheet->perms)
      );
    }

    g_dbus_method_invocation_return_value(
      invocation->invocation,
      g_variant_new("(@a{sa{sb}})", g_variant_builder_end(&builder))
    );
  }

  infinoted_plugin_dbus_invocation_free(plugin, invocation);
}
コード例 #2
0
static void
infinoted_plugin_dbus_check_acl(InfinotedPluginDbus* plugin,
                                InfinotedPluginDbusInvocation* invocation,
                                InfBrowser* browser,
                                const InfBrowserIter* iter)
{
  const gchar* account;
  GVariant* mask_variant;
  InfAclMask mask;
  InfAclMask out;
  GError* error;

  g_variant_get_child(invocation->parameters, 1, "&s", &account);
  g_variant_get_child(invocation->parameters, 2, "@as", &mask_variant);

  error = NULL;
  infinoted_plugin_dbus_mask_from_variant(&mask, mask_variant, &error);
  g_variant_unref(mask_variant);

  if(error != NULL)
  {
    g_dbus_method_invocation_return_gerror(invocation->invocation, error);
    g_error_free(error);
  }
  else
  {
    inf_browser_check_acl(
      browser,
      iter,
      inf_acl_account_id_from_string(account),
      &mask,
      &out
    );

    g_dbus_method_invocation_return_value(
      invocation->invocation,
      g_variant_new(
        "(@a{sb})",
        infinoted_plugin_dbus_perms_to_variant(&mask, &out)
      )
    );
  }

  infinoted_plugin_dbus_invocation_free(plugin, invocation);
}
コード例 #3
0
static InfAclSheetSet*
infinoted_plugin_dbus_sheet_set_from_variant(GVariant* variant,
                                             GError** error)
{
  InfAclSheetSet* sheet_set;
  GVariantIter iter;
  const gchar* account;
  GVariant* sub_variant;
  InfAclSheet* sheet;
  gboolean success;

  sheet_set = inf_acl_sheet_set_new();
  g_variant_iter_init(&iter, variant);
  while(g_variant_iter_loop(&iter, "{&s@a{sb}}", &account, &sub_variant))
  {
    sheet = inf_acl_sheet_set_add_sheet(
      sheet_set,
      inf_acl_account_id_from_string(account)
    );

    success = infinoted_plugin_dbus_perms_from_variant(
      &sheet->mask,
      &sheet->perms,
      sub_variant,
      error
    );

    if(success != TRUE)
    {
      inf_acl_sheet_set_free(sheet_set);
      g_variant_unref(sub_variant);
      return NULL;
    }
  }

  return sheet_set;
}
コード例 #4
0
void Gobby::BrowserContextCommands::on_account_created(
	gnutls_x509_privkey_t key,
	InfCertificateChain* certificate,
	const InfAclAccount* account)
{
	InfBrowser* browser;
	g_object_get(G_OBJECT(m_dialog->gobj()), "browser", &browser, NULL);
	const InfAclAccount* own_account =
		inf_browser_get_acl_local_account(browser);
	const InfAclAccountId default_id =
		inf_acl_account_id_from_string("default");
	const bool is_default_account = (own_account->id == default_id);
	g_object_unref(browser);

	gnutls_x509_crt_t cert =
		inf_certificate_chain_get_own_certificate(certificate);
	gchar* name = inf_cert_util_get_dn_by_oid(
		cert, GNUTLS_OID_X520_COMMON_NAME, 0);
	const std::string cn = name;
	g_free(name);

	std::string host;
	if(INFC_IS_BROWSER(browser))
	{
		InfXmlConnection* xml =
			infc_browser_get_connection(INFC_BROWSER(browser));
		if(INF_IS_XMPP_CONNECTION(xml))
		{
			gchar* hostname;
			g_object_get(G_OBJECT(xml), "remote-hostname",
			             &hostname, NULL);
			host = hostname;
			g_free(hostname);
		}
	}

	if(host.empty())
		host = "local";

	gnutls_x509_crt_t* certs = inf_certificate_chain_get_raw(certificate);
	const unsigned int n_certs =
		inf_certificate_chain_get_n_certificates(certificate);

	std::auto_ptr<Gtk::MessageDialog> dlg;

	try
	{
		const std::string filename = make_certificate_filename(cn, host);

		GError* error = NULL;
		inf_cert_util_write_certificate_with_key(
			key, certs, n_certs, filename.c_str(), &error);

		if(error != NULL)
		{
			const std::string message = error->message;
			g_error_free(error);
			throw std::runtime_error(message);
		}

		if(is_default_account &&
		   (m_cert_manager.get_private_key() == NULL ||
		    m_cert_manager.get_certificates() == NULL))
		{
			m_preferences.security.key_file = filename;
			m_preferences.security.certificate_file = filename;

			dlg.reset(new Gtk::MessageDialog(
				m_parent, _("Account successfully created"),
				false, Gtk::MESSAGE_INFO,
				Gtk::BUTTONS_CLOSE));
			dlg->set_secondary_text(
				_("When re-connecting to the server, the "
				  "new account will be used."));
		}
		else
		{
			// TODO: Gobby should support multiple certificates
			dlg.reset(new Gtk::MessageDialog(
				m_parent, _("Account successfully created"),
				false, Gtk::MESSAGE_INFO,
				Gtk::BUTTONS_CLOSE));
			dlg->set_secondary_text(Glib::ustring::compose(
				_("The certificate has been stored at %1.\n\n"
				  "To login to this account, set the "
				  "certificate in Gobby's preferences "
				  "and re-connect to the server."),
				filename));
		}
	}
	catch(const std::exception& ex)
	{
		// This is actually a bit unfortunate, because the
		// account was actually created and we have a valid
		// certificate for it, but we cannot keep it...
		dlg.reset(new Gtk::MessageDialog(
			m_parent, _("Failed to create account"),
			false, Gtk::MESSAGE_ERROR, Gtk::BUTTONS_CLOSE));
		dlg->set_secondary_text(Glib::ustring::compose(
			_("Could not save the certificate for the "
			  "account: %1"), ex.what()));
	}

	m_dialog = dlg;
	m_dialog->signal_response().connect(
		sigc::mem_fun(
			*this,
			&BrowserContextCommands::
				on_account_created_response));
	m_dialog->present();
}