Changeset 4ea88a5b849ba932b20b25f858d00acde49b65b5

Show
Ignore:
Timestamp:
12/25/10 20:44:00 (2 years ago)
Author:
Armin Burgmeier <armin@…>
Parents:
3b10ba674e94451d6b4b1c416cb0bf351a04f9bf
Children:
124c09a527b0d240598db4dbc383ed37e949c93e
git-committer:
Armin Burgmeier <armin@arbur.net> / 2010-12-25T20:44:00Z+0100
Message:

Show password dialog asynchronously

2010-12-25 Armin Burgmeier <armin@…>

  • code/core/browser.hpp:
  • code/core/browser.cpp:
  • code/commands/auth-commands.hpp:
  • code/commands/auth-commands.cpp: Adapt to latest API changes in libinfinity, show password dialog asynchronously.
Files:
5 modified

Legend:

Unmodified
Added
Removed
  • ChangeLog

    recfdae1 r4ea88a5  
     12010-12-25  Armin Burgmeier  <armin@arbur.net> 
     2 
     3        * code/core/browser.hpp: 
     4        * code/core/browser.cpp: 
     5        * code/commands/auth-commands.hpp: 
     6        * code/commands/auth-commands.cpp: Adapt to latest API changes in 
     7        libinfinity, show password dialog asynchronously. 
     8 
    192010-09-21  Armin Burgmeier  <armin@arbur.net> 
    210 
  • code/commands/auth-commands.cpp

    r61cce2c r4ea88a5  
    1818 
    1919#include "commands/auth-commands.hpp" 
    20 #include "dialogs/password-dialog.hpp" 
    2120#include "util/i18n.hpp" 
    2221 
     
    2827namespace 
    2928{ 
    30         Glib::ustring prompt_password(Gtk::Window& parent, 
    31                                       InfXmppConnection* xmpp, 
    32                                       unsigned int retry_counter) 
    33         { 
    34                 gchar* remote_id; 
    35                 g_object_get(G_OBJECT(xmpp), 
    36                         "remote-hostname", &remote_id, 
    37                         NULL); 
    38                 Glib::ustring remote_id_(remote_id); 
    39                 g_free(remote_id); 
    40                 Gobby::PasswordDialog dialog(parent, 
    41                                              remote_id_, 
    42                                              retry_counter); 
    43                 dialog.add_button(Gtk::Stock::CANCEL, Gtk::RESPONSE_CANCEL); 
    44  
    45                 dialog.add_button(Gtk::Stock::OK, Gtk::RESPONSE_ACCEPT); 
    46                 if(dialog.run() != Gtk::RESPONSE_ACCEPT) 
    47                         return ""; 
    48                 return dialog.get_password(); 
    49         } 
    50  
    5129        void show_error(const GError* error, 
    5230                        Gobby::StatusBar& statusbar, 
     
    8866        m_preferences(preferences) 
    8967{ 
    90         int gsasl_status = gsasl_init(&m_gsasl); 
    91         if(gsasl_status != GSASL_OK) 
    92                 throw std::runtime_error( 
    93                         std::string("gsasl error: ") + 
    94                         gsasl_strerror(gsasl_status)); 
    95         gsasl_callback_set(m_gsasl, &AuthCommands::gsasl_callback_static); 
    96         gsasl_callback_hook_set(m_gsasl, this); 
    97         g_object_set_data_full(G_OBJECT(m_browser.get_store()), 
    98                                "Gobby::AuthCommands::m_gsasl", 
    99                                m_gsasl, 
    100                                reinterpret_cast<GDestroyNotify>(gsasl_done)); 
    101         m_browser.set_gsasl_context(m_gsasl, "ANONYMOUS PLAIN"); 
     68        GError* error = NULL; 
     69        m_sasl_context = inf_sasl_context_new(&error); 
     70 
     71        if(!m_sasl_context) 
     72        { 
     73                std::string error_message = 
     74                        std::string("SASL initialization error: ") + 
     75                        error->message; 
     76                g_error_free(error); 
     77                throw std::runtime_error(error_message); 
     78        } 
     79 
     80        inf_sasl_context_set_callback( 
     81                m_sasl_context, &AuthCommands::sasl_callback_static, this); 
     82 
     83        m_browser.set_sasl_context(m_sasl_context, "ANONYMOUS PLAIN"); 
     84 
    10285        g_signal_connect( 
    10386                G_OBJECT(m_browser.get_store()), 
     
    10992Gobby::AuthCommands::~AuthCommands() 
    11093{ 
    111         m_browser.set_gsasl_context(NULL, NULL); 
     94        m_browser.set_sasl_context(NULL, NULL); 
     95        inf_sasl_context_unref(m_sasl_context); 
    11296 
    11397        for(RetryMap::iterator iter = m_retries.begin(); 
     
    118102} 
    119103 
    120 int Gobby::AuthCommands::gsasl_callback(Gsasl_session* session, 
     104void Gobby::AuthCommands::sasl_callback(InfSaslContextSession* session, 
     105                                        InfXmppConnection* xmpp, 
    121106                                        Gsasl_property prop) 
    122107{ 
     
    125110        { 
    126111        case GSASL_ANONYMOUS_TOKEN: 
    127                 gsasl_property_set(session, 
    128                                    GSASL_ANONYMOUS_TOKEN, 
    129                                    username.c_str()); 
    130                 return GSASL_OK; 
     112                inf_sasl_context_session_set_property( 
     113                        session, GSASL_ANONYMOUS_TOKEN, username.c_str()); 
     114                inf_sasl_context_session_continue(session, GSASL_OK); 
     115                break; 
    131116        case GSASL_AUTHID: 
    132                 gsasl_property_set(session, 
    133                                    GSASL_AUTHID, 
    134                                    username.c_str()); 
    135                 return GSASL_OK; 
     117                inf_sasl_context_session_set_property( 
     118                        session, GSASL_AUTHID, username.c_str()); 
     119                inf_sasl_context_session_continue(session, GSASL_OK); 
     120                break; 
    136121        case GSASL_PASSWORD: 
    137122                { 
    138                         InfXmppConnection* xmpp = 
    139                                 INF_XMPP_CONNECTION( 
    140                                         gsasl_session_hook_get(session)); 
    141123                        RetryMap::iterator i = m_retries.find(xmpp); 
    142124                        if(i == m_retries.end()) 
     
    144126                        RetryInfo& info(i->second); 
    145127 
    146                         if(info.last_password.empty()) 
     128                        if(!info.last_password.empty()) 
    147129                        { 
    148                                 info.last_password = 
    149                                         prompt_password(m_parent, xmpp, 
    150                                                         info.retries); 
    151                                 ++info.retries; 
    152  
    153                                 if(info.last_password.empty()) 
    154                                         return GSASL_NO_PASSWORD; 
     130                                inf_sasl_context_session_set_property( 
     131                                        session, GSASL_PASSWORD, 
     132                                        info.last_password.c_str()); 
     133 
     134                                inf_sasl_context_session_continue(session, 
     135                                                                  GSASL_OK); 
    155136                        } 
    156  
    157                         gsasl_property_set(session, 
    158                                            GSASL_PASSWORD, 
    159                                            info.last_password.c_str()); 
    160                         return GSASL_OK; 
    161                 } 
     137                        else 
     138                        { 
     139                                // Query user for password 
     140                                g_assert(info.password_dialog == NULL); 
     141 
     142                                gchar* remote_id; 
     143                                g_object_get(G_OBJECT(xmpp), 
     144                                             "remote-hostname", &remote_id, 
     145                                             NULL); 
     146                                Glib::ustring remote_id_(remote_id); 
     147                                g_free(remote_id); 
     148 
     149                                info.password_dialog = new PasswordDialog( 
     150                                        m_parent, remote_id_, info.retries); 
     151                                info.password_dialog->add_button( 
     152                                        Gtk::Stock::CANCEL, 
     153                                        Gtk::RESPONSE_CANCEL); 
     154                                info.password_dialog->add_button( 
     155                                        Gtk::Stock::OK, 
     156                                        Gtk::RESPONSE_ACCEPT); 
     157 
     158                                Gtk::Dialog& dialog = *info.password_dialog; 
     159                                dialog.signal_response().connect(sigc::bind( 
     160                                        sigc::mem_fun( 
     161                                                *this, 
     162                                                &AuthCommands::on_response), 
     163                                        session, xmpp)); 
     164 
     165                                info.password_dialog->present(); 
     166                        } 
     167                } 
     168 
     169                break; 
    162170        default: 
    163                 return GSASL_NO_CALLBACK; 
     171                inf_sasl_context_session_continue(session, GSASL_NO_CALLBACK); 
     172                break; 
     173        } 
     174} 
     175 
     176void Gobby::AuthCommands::on_response(int response_id, 
     177                                      InfSaslContextSession* session, 
     178                                      InfXmppConnection* xmpp) 
     179{ 
     180        RetryMap::iterator i = m_retries.find(xmpp); 
     181        g_assert(i != m_retries.end()); 
     182        RetryInfo& info(i->second); 
     183 
     184        if(response_id == Gtk::RESPONSE_ACCEPT) 
     185                info.last_password = info.password_dialog->get_password(); 
     186        else 
     187                info.last_password = ""; 
     188 
     189        delete info.password_dialog; 
     190        info.password_dialog = NULL; 
     191 
     192        ++info.retries; 
     193 
     194        if(info.last_password.empty()) 
     195        { 
     196                inf_sasl_context_session_continue(session, GSASL_NO_PASSWORD); 
     197        } 
     198        else 
     199        { 
     200                inf_sasl_context_session_set_property( 
     201                        session, GSASL_PASSWORD, info.last_password.c_str()); 
     202                inf_sasl_context_session_continue(session, GSASL_OK); 
    164203        } 
    165204} 
     
    195234             g_quark_from_static_string("INF_XMPP_CONNECTION_AUTH_ERROR")) 
    196235        { 
     236                // Authentication failed for some reason, maybe because the 
     237                // server aborted authentication. If we were querying a 
     238                // password then close the dialog now. 
     239                delete iter->second.password_dialog; 
     240                iter->second.password_dialog = NULL; 
     241 
    197242                const GError* sasl_error = 
    198243                        inf_xmpp_connection_get_sasl_error(xmpp); 
     
    262307                G_CALLBACK(on_notify_status_static), 
    263308                this); 
     309        iter->second.password_dialog = NULL; 
    264310 
    265311        return iter; 
     
    270316        InfXmlConnectionStatus status; 
    271317        g_object_get(G_OBJECT(connection), "status", &status, NULL); 
     318 
    272319        if(status != INF_XML_CONNECTION_OPENING) 
    273320        { 
    274321                RetryMap::iterator iter = m_retries.find(connection); 
    275322                g_signal_handler_disconnect(connection, iter->second.handle); 
     323                delete iter->second.password_dialog; 
    276324                m_retries.erase(iter); 
    277325        } 
  • code/commands/auth-commands.hpp

    r61cce2c r4ea88a5  
    2020#define _GOBBY_AUTH_COMMANDS_HPP_ 
    2121 
     22#include "dialogs/password-dialog.hpp" 
     23 
    2224#include "core/browser.hpp" 
    2325#include "core/statusbar.hpp" 
    2426#include "core/preferences.hpp" 
    25  
    26 #include <gsasl.h> 
    2727 
    2828#include <gtkmm/window.h> 
     
    4343 
    4444protected: 
    45         static int gsasl_callback_static(Gsasl* ctx, 
    46                                          Gsasl_session* session, 
    47                                          Gsasl_property prop) 
     45        static void sasl_callback_static(InfSaslContextSession* session, 
     46                                         Gsasl_property prop, 
     47                                         gpointer session_data, 
     48                                         gpointer user_data) 
    4849        { 
    49                 AuthCommands* auth = static_cast<AuthCommands*>( 
    50                         gsasl_callback_hook_get(ctx)); 
    51                 return auth->gsasl_callback(session, prop); 
     50                AuthCommands* auth = static_cast<AuthCommands*>(user_data); 
     51 
     52                auth->sasl_callback( 
     53                        session, INF_XMPP_CONNECTION(session_data), prop); 
    5254        } 
    5355 
     
    8082        } 
    8183 
    82         int gsasl_callback(Gsasl_session* session, 
     84        void sasl_callback(InfSaslContextSession* session, 
     85                           InfXmppConnection* xmpp, 
    8386                           Gsasl_property prop); 
    8487 
     
    9699                Glib::ustring last_password; 
    97100                gulong handle; 
     101                PasswordDialog* password_dialog; 
    98102        }; 
    99103 
     
    103107 
    104108        void on_notify_status(InfXmppConnection* connection); 
     109        void on_response(int response_id, InfSaslContextSession* session, 
     110                         InfXmppConnection* xmpp); 
    105111 
    106112        Gtk::Window& m_parent; 
     
    108114        StatusBar& m_statusbar; 
    109115        const Preferences& m_preferences; 
    110         Gsasl* m_gsasl; 
     116        InfSaslContext* m_sasl_context; 
    111117 
    112118        RetryMap m_retries; 
  • code/core/browser.cpp

    r61cce2c r4ea88a5  
    110110        m_status_bar(status_bar), 
    111111        m_preferences(preferences), 
    112         m_gsasl(NULL), 
     112        m_sasl_context(NULL), 
    113113        m_expander(_("_Direct Connection"), true), 
    114114        m_hbox(false, 6), 
     
    206206        } 
    207207 
     208        if(m_sasl_context) 
     209                inf_sasl_context_unref(m_sasl_context); 
     210 
    208211        g_object_unref(m_browser_store); 
    209212        g_object_unref(m_sort_model); 
     
    310313                                m_preferences.security.policy, 
    311314                                NULL, 
    312                                 m_gsasl, 
    313                                 m_gsasl_mechanisms.empty() 
     315                                m_sasl_context, 
     316                                m_sasl_mechanisms.empty() 
    314317                                        ? "" 
    315                                         : m_gsasl_mechanisms.c_str()); 
     318                                        : m_sasl_mechanisms.c_str()); 
    316319 
    317320                        inf_xmpp_manager_add_connection(m_xmpp_manager, xmpp); 
     
    468471} 
    469472 
    470 void Gobby::Browser::set_gsasl_context(Gsasl* gsasl, const char* mechanisms) 
    471 { 
    472         m_gsasl = gsasl; 
    473         m_gsasl_mechanisms = mechanisms ? mechanisms : ""; 
     473void Gobby::Browser::set_sasl_context(InfSaslContext* sasl_context, 
     474                                      const char* mechanisms) 
     475{ 
     476        if(m_sasl_context) inf_sasl_context_unref(m_sasl_context); 
     477        m_sasl_context = sasl_context; 
     478        if(m_sasl_context) inf_sasl_context_ref(m_sasl_context); 
     479        m_sasl_mechanisms = mechanisms ? mechanisms : ""; 
     480 
    474481#ifdef LIBINFINITY_HAVE_AVAHI 
    475482        g_object_set(G_OBJECT(m_discovery), 
    476                 "sasl-context", m_gsasl, 
     483                "sasl-context", m_sasl_context, 
    477484                "sasl-mechanisms", mechanisms, 
    478485                NULL); 
  • code/core/browser.hpp

    r61cce2c r4ea88a5  
    3535#include <libinfgtk/inf-gtk-browser-model.h> 
    3636#include <libinfgtk/inf-gtk-browser-model-sort.h> 
    37  
    38 #include <gsasl.h> 
    3937 
    4038#include <gtkmm/window.h> 
     
    8179        void connect_to_host(Glib::ustring str); 
    8280 
    83         void set_gsasl_context(Gsasl* gsasl, const char* mechanisms); 
     81        void set_sasl_context(InfSaslContext* sasl_context, 
     82                              const char* mechanisms); 
    8483 
    8584        SignalActivate signal_activate() const { return m_signal_activate; } 
     
    127126        Preferences& m_preferences; 
    128127 
    129         Gsasl* m_gsasl; 
    130         std::string m_gsasl_mechanisms; 
     128        InfSaslContext* m_sasl_context; 
     129        std::string m_sasl_mechanisms; 
    131130        InfXmppManager* m_xmpp_manager; 
    132131#ifdef LIBINFINITY_HAVE_AVAHI