summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorStef Walter <stef@memberwebs.com>2009-07-07 20:05:37 +0000
committerStef Walter <stef@memberwebs.com>2009-07-07 20:05:37 +0000
commite60cf88e22a8992c0d805450173dbe38d770618a (patch)
tree86cd637a3930c3a13ce1ad6ee12b2f412863b76e
parent30c217c0dca4c7a72ff4248fc4d4504fc1d85fc0 (diff)
Restart authentication if we think we've restarted since URL came back.
-rw-r--r--module/consumer.cc49
1 files 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 &params,
- 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 &params,
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 */