Changeset 4ea88a5b849ba932b20b25f858d00acde49b65b5
- 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:
-
Legend:
- Unmodified
- Added
- Removed
-
|
recfdae1
|
r4ea88a5
|
|
| | 1 | 2010-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 | |
| 1 | 9 | 2010-09-21 Armin Burgmeier <armin@arbur.net> |
| 2 | 10 | |
-
|
r61cce2c
|
r4ea88a5
|
|
| 18 | 18 | |
| 19 | 19 | #include "commands/auth-commands.hpp" |
| 20 | | #include "dialogs/password-dialog.hpp" |
| 21 | 20 | #include "util/i18n.hpp" |
| 22 | 21 | |
| … |
… |
|
| 28 | 27 | namespace |
| 29 | 28 | { |
| 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 | | |
| 51 | 29 | void show_error(const GError* error, |
| 52 | 30 | Gobby::StatusBar& statusbar, |
| … |
… |
|
| 88 | 66 | m_preferences(preferences) |
| 89 | 67 | { |
| 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 | |
| 102 | 85 | g_signal_connect( |
| 103 | 86 | G_OBJECT(m_browser.get_store()), |
| … |
… |
|
| 109 | 92 | Gobby::AuthCommands::~AuthCommands() |
| 110 | 93 | { |
| 111 | | m_browser.set_gsasl_context(NULL, NULL); |
| | 94 | m_browser.set_sasl_context(NULL, NULL); |
| | 95 | inf_sasl_context_unref(m_sasl_context); |
| 112 | 96 | |
| 113 | 97 | for(RetryMap::iterator iter = m_retries.begin(); |
| … |
… |
|
| 118 | 102 | } |
| 119 | 103 | |
| 120 | | int Gobby::AuthCommands::gsasl_callback(Gsasl_session* session, |
| | 104 | void Gobby::AuthCommands::sasl_callback(InfSaslContextSession* session, |
| | 105 | InfXmppConnection* xmpp, |
| 121 | 106 | Gsasl_property prop) |
| 122 | 107 | { |
| … |
… |
|
| 125 | 110 | { |
| 126 | 111 | 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; |
| 131 | 116 | 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; |
| 136 | 121 | case GSASL_PASSWORD: |
| 137 | 122 | { |
| 138 | | InfXmppConnection* xmpp = |
| 139 | | INF_XMPP_CONNECTION( |
| 140 | | gsasl_session_hook_get(session)); |
| 141 | 123 | RetryMap::iterator i = m_retries.find(xmpp); |
| 142 | 124 | if(i == m_retries.end()) |
| … |
… |
|
| 144 | 126 | RetryInfo& info(i->second); |
| 145 | 127 | |
| 146 | | if(info.last_password.empty()) |
| | 128 | if(!info.last_password.empty()) |
| 147 | 129 | { |
| 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); |
| 155 | 136 | } |
| 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; |
| 162 | 170 | default: |
| 163 | | return GSASL_NO_CALLBACK; |
| | 171 | inf_sasl_context_session_continue(session, GSASL_NO_CALLBACK); |
| | 172 | break; |
| | 173 | } |
| | 174 | } |
| | 175 | |
| | 176 | void 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); |
| 164 | 203 | } |
| 165 | 204 | } |
| … |
… |
|
| 195 | 234 | g_quark_from_static_string("INF_XMPP_CONNECTION_AUTH_ERROR")) |
| 196 | 235 | { |
| | 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 | |
| 197 | 242 | const GError* sasl_error = |
| 198 | 243 | inf_xmpp_connection_get_sasl_error(xmpp); |
| … |
… |
|
| 262 | 307 | G_CALLBACK(on_notify_status_static), |
| 263 | 308 | this); |
| | 309 | iter->second.password_dialog = NULL; |
| 264 | 310 | |
| 265 | 311 | return iter; |
| … |
… |
|
| 270 | 316 | InfXmlConnectionStatus status; |
| 271 | 317 | g_object_get(G_OBJECT(connection), "status", &status, NULL); |
| | 318 | |
| 272 | 319 | if(status != INF_XML_CONNECTION_OPENING) |
| 273 | 320 | { |
| 274 | 321 | RetryMap::iterator iter = m_retries.find(connection); |
| 275 | 322 | g_signal_handler_disconnect(connection, iter->second.handle); |
| | 323 | delete iter->second.password_dialog; |
| 276 | 324 | m_retries.erase(iter); |
| 277 | 325 | } |
-
|
r61cce2c
|
r4ea88a5
|
|
| 20 | 20 | #define _GOBBY_AUTH_COMMANDS_HPP_ |
| 21 | 21 | |
| | 22 | #include "dialogs/password-dialog.hpp" |
| | 23 | |
| 22 | 24 | #include "core/browser.hpp" |
| 23 | 25 | #include "core/statusbar.hpp" |
| 24 | 26 | #include "core/preferences.hpp" |
| 25 | | |
| 26 | | #include <gsasl.h> |
| 27 | 27 | |
| 28 | 28 | #include <gtkmm/window.h> |
| … |
… |
|
| 43 | 43 | |
| 44 | 44 | protected: |
| 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) |
| 48 | 49 | { |
| 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); |
| 52 | 54 | } |
| 53 | 55 | |
| … |
… |
|
| 80 | 82 | } |
| 81 | 83 | |
| 82 | | int gsasl_callback(Gsasl_session* session, |
| | 84 | void sasl_callback(InfSaslContextSession* session, |
| | 85 | InfXmppConnection* xmpp, |
| 83 | 86 | Gsasl_property prop); |
| 84 | 87 | |
| … |
… |
|
| 96 | 99 | Glib::ustring last_password; |
| 97 | 100 | gulong handle; |
| | 101 | PasswordDialog* password_dialog; |
| 98 | 102 | }; |
| 99 | 103 | |
| … |
… |
|
| 103 | 107 | |
| 104 | 108 | void on_notify_status(InfXmppConnection* connection); |
| | 109 | void on_response(int response_id, InfSaslContextSession* session, |
| | 110 | InfXmppConnection* xmpp); |
| 105 | 111 | |
| 106 | 112 | Gtk::Window& m_parent; |
| … |
… |
|
| 108 | 114 | StatusBar& m_statusbar; |
| 109 | 115 | const Preferences& m_preferences; |
| 110 | | Gsasl* m_gsasl; |
| | 116 | InfSaslContext* m_sasl_context; |
| 111 | 117 | |
| 112 | 118 | RetryMap m_retries; |
-
|
r61cce2c
|
r4ea88a5
|
|
| 110 | 110 | m_status_bar(status_bar), |
| 111 | 111 | m_preferences(preferences), |
| 112 | | m_gsasl(NULL), |
| | 112 | m_sasl_context(NULL), |
| 113 | 113 | m_expander(_("_Direct Connection"), true), |
| 114 | 114 | m_hbox(false, 6), |
| … |
… |
|
| 206 | 206 | } |
| 207 | 207 | |
| | 208 | if(m_sasl_context) |
| | 209 | inf_sasl_context_unref(m_sasl_context); |
| | 210 | |
| 208 | 211 | g_object_unref(m_browser_store); |
| 209 | 212 | g_object_unref(m_sort_model); |
| … |
… |
|
| 310 | 313 | m_preferences.security.policy, |
| 311 | 314 | NULL, |
| 312 | | m_gsasl, |
| 313 | | m_gsasl_mechanisms.empty() |
| | 315 | m_sasl_context, |
| | 316 | m_sasl_mechanisms.empty() |
| 314 | 317 | ? "" |
| 315 | | : m_gsasl_mechanisms.c_str()); |
| | 318 | : m_sasl_mechanisms.c_str()); |
| 316 | 319 | |
| 317 | 320 | inf_xmpp_manager_add_connection(m_xmpp_manager, xmpp); |
| … |
… |
|
| 468 | 471 | } |
| 469 | 472 | |
| 470 | | void Gobby::Browser::set_gsasl_context(Gsasl* gsasl, const char* mechanisms) |
| 471 | | { |
| 472 | | m_gsasl = gsasl; |
| 473 | | m_gsasl_mechanisms = mechanisms ? mechanisms : ""; |
| | 473 | void 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 | |
| 474 | 481 | #ifdef LIBINFINITY_HAVE_AVAHI |
| 475 | 482 | g_object_set(G_OBJECT(m_discovery), |
| 476 | | "sasl-context", m_gsasl, |
| | 483 | "sasl-context", m_sasl_context, |
| 477 | 484 | "sasl-mechanisms", mechanisms, |
| 478 | 485 | NULL); |
-
|
r61cce2c
|
r4ea88a5
|
|
| 35 | 35 | #include <libinfgtk/inf-gtk-browser-model.h> |
| 36 | 36 | #include <libinfgtk/inf-gtk-browser-model-sort.h> |
| 37 | | |
| 38 | | #include <gsasl.h> |
| 39 | 37 | |
| 40 | 38 | #include <gtkmm/window.h> |
| … |
… |
|
| 81 | 79 | void connect_to_host(Glib::ustring str); |
| 82 | 80 | |
| 83 | | void set_gsasl_context(Gsasl* gsasl, const char* mechanisms); |
| | 81 | void set_sasl_context(InfSaslContext* sasl_context, |
| | 82 | const char* mechanisms); |
| 84 | 83 | |
| 85 | 84 | SignalActivate signal_activate() const { return m_signal_activate; } |
| … |
… |
|
| 127 | 126 | Preferences& m_preferences; |
| 128 | 127 | |
| 129 | | Gsasl* m_gsasl; |
| 130 | | std::string m_gsasl_mechanisms; |
| | 128 | InfSaslContext* m_sasl_context; |
| | 129 | std::string m_sasl_mechanisms; |
| 131 | 130 | InfXmppManager* m_xmpp_manager; |
| 132 | 131 | #ifdef LIBINFINITY_HAVE_AVAHI |