From e60cf88e22a8992c0d805450173dbe38d770618a Mon Sep 17 00:00:00 2001 From: Stef Walter Date: Tue, 7 Jul 2009 20:05:37 +0000 Subject: Restart authentication if we think we've restarted since URL came back. --- module/consumer.cc | 49 ++++++++++++++++++++++++++++++++++++++----------- 1 file changed, 38 insertions(+), 11 deletions(-) diff --git a/module/consumer.cc b/module/consumer.cc index 9c5da89..bc248ad 100644 --- a/module/consumer.cc +++ b/module/consumer.cc @@ -151,6 +151,10 @@ public: // interface : _store(store), _url(url), _index(0) { } + bool is_dumb() const + { return _store ? false : true; } + bool has_assoc(const string& handle) const; + public: // overrides virtual void begin_queueing() @@ -230,6 +234,23 @@ Consumer::store_assoc(const string& server, const string& handle, return assoc_t(new association(server, handle, type, secret, expires_in, false)); } +bool +Consumer::has_assoc(const string& handle) const +{ + sid_assoc_t data = { 0, }; + int res; + + if (!_store) + return false; + + { + LockShared lock; + res = sid_storage_find_assoc (_store, NULL, handle.c_str(), &data); + } + + return res ? true : false; +} + assoc_t Consumer::find_assoc(const string& server) { @@ -274,13 +295,8 @@ Consumer::retrieve_assoc(const string& server, const string& handle) } } - /* - * Yes, we return this when not found, it helps the user experience, if - * apache restarted. - */ - if (!assoc) - throw dumb_RP("could not retrieve association for server: " + server); + throw failed_lookup("could not retrieve association for server: " + server); return assoc_t(assoc); } @@ -484,9 +500,10 @@ begin_auth (sid_request_t *req, Consumer &consumer, const string& trust_root, static void complete_auth (sid_request_t *req, Consumer &consumer, params_t ¶ms, - sid_attribute_t *attributes) + sid_attribute_t *attributes, bool &finished) { try { + finished = true; consumer.id_res(params); string identity = consumer.get_claimed_id(); sid_request_authenticated (req, identity.c_str()); @@ -501,8 +518,14 @@ complete_auth (sid_request_t *req, Consumer &consumer, params_t ¶ms, sid_request_respond (req, 403, "Bad authenticated address", NULL); sid_request_log_error (req, "bad return to", ex.what()); } catch (id_res_failed &ex) { - sid_request_respond (req, 503, "Service error, try again", NULL); - sid_request_log_error (req, "checking response failed", ex.what()); + /* If we don't have this association, then try again */ + if (params.has_param("assoc_handle") && !consumer.has_assoc(params.get_param("assoc_handle"))) { + sid_request_log_error (req, "response from invalid association, retrying authentication", NULL); + finished = false; + } else { + sid_request_respond (req, 503, "Service error, try again", NULL); + sid_request_log_error (req, "checking response failed", ex.what()); + } } catch (exception &ex) { sid_request_respond (req, 500, NULL, NULL); sid_request_log_error (req, "error while completing authentication", ex.what()); @@ -536,10 +559,14 @@ sid_consumer_authenticate(sid_request_t *req, sid_storage_t *store, /* Returning (hopefully successful) authentication */ if (openid.has_param("assoc_handle")) { - complete_auth (req, consumer, openid, attributes); + bool finished = true; + complete_auth (req, consumer, openid, attributes, finished); + if (finished) + return; + } /* Returning cancelled authentication */ - } else if (openid.has_param("mode") && openid.get_param("mode") == "cancel") { + if (openid.has_param("mode") && openid.get_param("mode") == "cancel") { cancelled_auth (req, consumer, openid); /* Begin a new authentication */ -- cgit v1.2.3