static void
infinoted_plugin_certificate_auth_connection_added(InfXmlConnection* conn,
                                                   gpointer plugin_info,
                                                   gpointer connection_info)
{
  InfinotedPluginCertificateAuth* plugin;
  InfXmppConnection* xmpp;
  gnutls_certificate_request_t cert_req;

  plugin = (InfinotedPluginCertificateAuth*)plugin_info;

  if(INF_IS_XMPP_CONNECTION(conn))
  {
    xmpp = INF_XMPP_CONNECTION(conn);

    if(plugin->accept_unauthenticated_clients == TRUE)
      cert_req = GNUTLS_CERT_REQUEST;
    else
      cert_req = GNUTLS_CERT_REQUIRE;

    inf_xmpp_connection_set_certificate_callback(
      xmpp,
      cert_req,
      infinoted_plugin_certificate_auth_certificate_func,
      plugin
    );
  }
}
Exemplo n.º 2
0
void Gobby::SelfHoster::directory_foreach_func_set_sasl_context_static(
	InfXmlConnection* connection,
	gpointer user_data)
{
	g_assert(INF_IS_XMPP_CONNECTION(connection));

	SelfHoster* hoster = static_cast<SelfHoster*>(user_data);

	inf_xmpp_connection_reset_sasl_authentication(
		INF_XMPP_CONNECTION(connection),
		hoster->m_sasl_context, hoster->get_sasl_mechanisms());
}
Exemplo n.º 3
0
void Gobby::AuthCommands::browser_error_callback(InfcBrowser* browser,
                                                 GError* error)
{
	// The Browser already displays errors inline, but we want
	// auth-related error messages to show up in the status bar.

	InfXmlConnection* connection = infc_browser_get_connection(browser);
	g_assert(INF_IS_XMPP_CONNECTION(connection));

	InfXmppConnection* xmpp = INF_XMPP_CONNECTION(connection);
	RetryMap::iterator iter = m_retries.find(xmpp);
	if(iter == m_retries.end())
		iter = insert_retry_info(xmpp);
	Glib::ustring& last_password(iter->second.last_password);
	Glib::ustring old_password;

	old_password.swap(last_password);

	if(error->domain ==
	     g_quark_from_static_string("INF_XMPP_CONNECTION_AUTH_ERROR"))
	{
		// Authentication failed for some reason, maybe because the
		// server aborted authentication. If we were querying a
		// password then close the dialog now.
		delete iter->second.password_dialog;
		iter->second.password_dialog = NULL;

		const GError* sasl_error =
			inf_xmpp_connection_get_sasl_error(xmpp);
		if(sasl_error != NULL &&
		   sasl_error->domain ==
		     inf_authentication_detail_error_quark())
		{
			handle_error_detail(xmpp, sasl_error,
			                    old_password,
			                    last_password);
		}
		else if(sasl_error != NULL)
		{
			show_error(sasl_error, m_statusbar, connection);
		}
		else
		{
			show_error(error, m_statusbar, connection);
		}
	}
	else if(error->domain == inf_gsasl_error_quark())
	{
		show_error(error, m_statusbar, connection);
	}
}
static void
infinoted_plugin_certificate_auth_connection_removed(InfXmlConnection* conn,
                                                     gpointer plugin_info,
                                                     gpointer session_info)
{
  InfinotedPluginCertificateAuth* plugin;
  InfXmppConnection* xmpp;

  plugin = (InfinotedPluginCertificateAuth*)plugin_info;

  if(INF_IS_XMPP_CONNECTION(conn))
  {
    xmpp = INF_XMPP_CONNECTION(conn);

    inf_xmpp_connection_set_certificate_callback(
      xmpp,
      GNUTLS_CERT_IGNORE,
      NULL,
      NULL
    );
  }
}
Exemplo n.º 5
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();
}