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; } }
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 infinoted_startup_sasl_callback(InfSaslContextSession* session, Gsasl_property prop, gpointer session_data, gpointer user_data) { InfinotedStartup* startup; const char* username; const char* password; InfXmppConnection* xmpp; gchar cmp; gsize password_len; gsize i; #ifdef LIBINFINITY_HAVE_PAM const gchar* pam_service; GError* error; #endif gchar* remote_id; xmpp = INF_XMPP_CONNECTION(session_data); g_object_get(xmpp, "remote-id", &remote_id, NULL); switch(prop) { case GSASL_VALIDATE_SIMPLE: startup = (InfinotedStartup*)user_data; username = inf_sasl_context_session_get_property(session, GSASL_AUTHID); password = inf_sasl_context_session_get_property(session, GSASL_PASSWORD); #ifdef LIBINFINITY_HAVE_PAM pam_service = startup->options->pam_service; if(pam_service != NULL) { error = NULL; if(!infinoted_pam_authenticate(pam_service, username, password)) { infinoted_log_warning( startup->log, _("User %s failed to log in from %s: PAM authentication failed"), username, remote_id ); infinoted_startup_sasl_callback_set_error( xmpp, INF_AUTHENTICATION_DETAIL_ERROR_AUTHENTICATION_FAILED, NULL ); inf_sasl_context_session_continue( session, GSASL_AUTHENTICATION_ERROR ); } else if(!infinoted_pam_user_is_allowed(startup, username, &error)) { infinoted_log_warning( startup->log, _("User %s failed to log in from %s: PAM user not allowed"), username, remote_id ); infinoted_startup_sasl_callback_set_error( xmpp, INF_AUTHENTICATION_DETAIL_ERROR_USER_NOT_AUTHORIZED, error ); inf_sasl_context_session_continue( session, GSASL_AUTHENTICATION_ERROR ); } else { infinoted_log_info( startup->log, _("User %s logged in from %s via PAM"), username, remote_id ); inf_sasl_context_session_continue(session, GSASL_OK); } } else #endif /* LIBINFINITY_HAVE_PAM */ { g_assert(startup->options->password != NULL); /* length-independent string compare */ cmp = 0; password_len = strlen(password); for(i = 0; i < startup->options->password_len; ++i) { if(i < password_len) cmp |= (startup->options->password[i] ^ password[i]); else cmp |= (startup->options->password[i] ^ 0x00); } if(startup->options->password_len != password_len) cmp |= 0xFF; if(cmp == 0) { infinoted_log_info( startup->log, _("User %s logged in from %s via password"), username, remote_id ); inf_sasl_context_session_continue(session, GSASL_OK); } else { infinoted_log_warning( startup->log, _("User %s failed to log in from %s: wrong password"), username, remote_id ); infinoted_startup_sasl_callback_set_error( xmpp, INF_AUTHENTICATION_DETAIL_ERROR_AUTHENTICATION_FAILED, NULL ); inf_sasl_context_session_continue( session, GSASL_AUTHENTICATION_ERROR ); } } break; default: inf_sasl_context_session_continue(session, GSASL_AUTHENTICATION_ERROR); break; } g_free(remote_id); }
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; } }