Example #1
0
void Gobby::AuthCommands::on_response(int response_id,
                                      InfSaslContextSession* session,
                                      InfXmppConnection* xmpp)
{
	RetryMap::iterator i = m_retries.find(xmpp);
	g_assert(i != m_retries.end());
	RetryInfo& info(i->second);

	if(response_id == Gtk::RESPONSE_ACCEPT)
		info.last_password = info.password_dialog->get_password();
	else
		info.last_password = "";

	delete info.password_dialog;
	info.password_dialog = NULL;

	++info.retries;

	if(info.last_password.empty())
	{
		inf_sasl_context_session_continue(session, GSASL_NO_PASSWORD);
	}
	else
	{
		inf_sasl_context_session_set_property(
			session, GSASL_PASSWORD, info.last_password.c_str());
		inf_sasl_context_session_continue(session, GSASL_OK);
	}
}
static void
infd_xmpp_server_sasl_cb(InfSaslContextSession* session,
                         Gsasl_property property,
                         gpointer session_data,
                         gpointer user_data)
{
  InfdXmppServer* xmpp;
  InfdXmppServerPrivate* priv;

  xmpp = INFD_XMPP_SERVER(user_data);
  priv = INFD_XMPP_SERVER_PRIVATE(xmpp);

  switch(property)
  {
  case GSASL_ANONYMOUS_TOKEN:
    inf_sasl_context_session_set_property(
      session,
      GSASL_ANONYMOUS_TOKEN,
      priv->local_hostname
    );

    inf_sasl_context_session_continue(session, GSASL_OK);
    break;
  case GSASL_VALIDATE_ANONYMOUS:
    /* Authentaction always successful */
    inf_sasl_context_session_continue(session, GSASL_OK);
    break;
  default:
    /* This is only used when using built-in SASL context, and this one
     * only supports anonymous authentication. */
    g_assert_not_reached();
    inf_sasl_context_session_continue(session, GSASL_NO_CALLBACK);
    break;
  }
}
Example #3
0
void Gobby::AuthCommands::sasl_callback(InfSaslContextSession* session,
                                        InfXmppConnection* xmpp,
                                        Gsasl_property prop)
{
	const Glib::ustring username = m_preferences.user.name;
	const std::string correct_password = m_preferences.user.password;
	const char* password;
	gsize password_len;
	gchar cmp;

	switch(prop)
	{
	case GSASL_ANONYMOUS_TOKEN:
		inf_sasl_context_session_set_property(
			session, GSASL_ANONYMOUS_TOKEN, username.c_str());
		inf_sasl_context_session_continue(session, GSASL_OK);
		break;
	case GSASL_AUTHID:
		inf_sasl_context_session_set_property(
			session, GSASL_AUTHID, username.c_str());
		inf_sasl_context_session_continue(session, GSASL_OK);
		break;
	case GSASL_PASSWORD:
		{
			RetryMap::iterator i = m_retries.find(xmpp);
			if(i == m_retries.end())
				i = insert_retry_info(xmpp);
			RetryInfo& info(i->second);

			if(!info.last_password.empty())
			{
				inf_sasl_context_session_set_property(
					session, GSASL_PASSWORD,
					info.last_password.c_str());

				inf_sasl_context_session_continue(session,
				                                  GSASL_OK);
			}
			else
			{
				// Query user for password
				g_assert(info.password_dialog == NULL);

				gchar* remote_id;
				g_object_get(G_OBJECT(xmpp),
				             "remote-hostname", &remote_id,
					     NULL);
				Glib::ustring remote_id_(remote_id);
				g_free(remote_id);

				info.password_dialog = new PasswordDialog(
					m_parent, remote_id_, info.retries);
				info.password_dialog->add_button(
					_("_Cancel"), Gtk::RESPONSE_CANCEL);
				info.password_dialog->add_button(
					_("_Ok"), Gtk::RESPONSE_ACCEPT);

				Gtk::Dialog& dialog = *info.password_dialog;
				dialog.signal_response().connect(sigc::bind(
					sigc::mem_fun(
						*this,
						&AuthCommands::on_response),
					session, xmpp));

				info.password_dialog->present();
			}
		}

		break;
	case GSASL_VALIDATE_ANONYMOUS:
		if(m_preferences.user.require_password)
		{
			inf_sasl_context_session_continue(
				session,
				GSASL_AUTHENTICATION_ERROR
			);

			set_sasl_error(xmpp, _("Password required"));
		}
		else
		{
			inf_sasl_context_session_continue(session, GSASL_OK);
		}

		break;
	case GSASL_VALIDATE_SIMPLE:
		password = inf_sasl_context_session_get_property(
			session, GSASL_PASSWORD);

		/* length-independent string compare */
		cmp = 0;
		password_len = strlen(password);
		for(unsigned i = 0; i < correct_password.size(); ++i)
		{
			if(i < password_len)
				cmp |= (password[i] ^ correct_password[i]);
			else
				cmp |= (0x00 ^ correct_password[i]);
		}

		if(password_len != correct_password.size())
			cmp = 0xFF;

		if(cmp != 0)
		{
			inf_sasl_context_session_continue(
				session,
				GSASL_AUTHENTICATION_ERROR
			);

			set_sasl_error(xmpp, _("Incorrect password"));
		}
		else
		{
			inf_sasl_context_session_continue(session, GSASL_OK);
		}

		break;
	default:
		inf_sasl_context_session_continue(session, GSASL_NO_CALLBACK);
		break;
	}
}