-rw-r--r-- | lib/basic_op.cc | 35 |
1 files changed, 3 insertions, 32 deletions
diff --git a/lib/basic_op.cc b/lib/basic_op.cc index f7573aa..11ffb48 100644 --- a/lib/basic_op.cc +++ b/lib/basic_op.cc @@ -1,62 +1,59 @@ #include <time.h> #include <cassert> -#include <algorithm> #include <openssl/sha.h> #include <openssl/hmac.h> #include <opkele/data.h> #include <opkele/basic_op.h> #include <opkele/exception.h> #include <opkele/util.h> #include <opkele/uris.h> namespace opkele { - using std::pair; - using std::mismatch; void basic_op::reset_vars() { assoc.reset(); return_to.clear(); realm.clear(); claimed_id.clear(); identity.clear(); invalidate_handle.clear(); } bool basic_op::has_return_to() const { return !return_to.empty(); } const string& basic_op::get_return_to() const { if(return_to.empty()) throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); return return_to; } const string& basic_op::get_realm() const { assert(!realm.empty()); return realm; } bool basic_op::has_identity() const { return !identity.empty(); } const string& basic_op::get_claimed_id() const { if(claimed_id.empty()) throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); assert(!identity.empty()); return claimed_id; } const string& basic_op::get_identity() const { if(identity.empty()) throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); assert(!claimed_id.empty()); return identity; } bool basic_op::is_id_select() const { return identity==IDURI_SELECT20; } void basic_op::select_identity(const string& c,const string& i) { claimed_id = c; identity = i; } void basic_op::set_claimed_id(const string& c) { claimed_id = c; } @@ -276,81 +273,55 @@ namespace opkele { try { o2 = (inm.get_field("ns")==OIURI_OPENID20); }catch(failed_lookup&) { o2 = false; } string nonce; if(o2) { try { if(!check_nonce(nonce = inm.get_field("response_nonce"))) throw failed_check_authentication(OPKELE_CP_ "Invalid nonce"); }catch(failed_lookup&) { throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request"); } } try { assoc = retrieve_assoc(inm.get_field("assoc_handle")); if(!assoc->stateless()) throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle"); }catch(failed_lookup&) { throw failed_check_authentication(OPKELE_CP_ "No assoc_handle or invalid assoc_handle specified with check_authentication request"); } static const string idresmode = "id_res"; try { if(util::base64_signature(assoc,util::change_mode_message_proxy(inm,idresmode))!=inm.get_field("sig")) throw failed_check_authentication(OPKELE_CP_ "Signature mismatch"); }catch(failed_lookup&) { throw failed_check_authentication(OPKELE_CP_ "failed to calculate signature"); } oum.set_field("is_valid","true"); try { string h = inm.get_field("invalidate_handle"); try { assoc_t ih = retrieve_assoc(h); }catch(invalid_handle& ih) { oum.set_field("invalidate_handle",h); }catch(failed_lookup& ih) { oum.set_field("invalidate_handle",h); } }catch(failed_lookup&) { } if(o2) { assert(!nonce.empty()); invalidate_nonce(nonce); } return oum; }catch(failed_check_authentication& ) { oum.set_field("is_valid","false"); return oum; } void basic_op::verify_return_to() { - string nrealm = opkele::util::rfc_3986_normalize_uri(realm); - if(nrealm.find('#')!=string::npos) + if(realm.find('#')!=string::npos) throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment"); - string nrt = opkele::util::rfc_3986_normalize_uri(return_to); - string::size_type pr = nrealm.find("://"); - string::size_type prt = nrt.find("://"); - assert(!(pr==string::npos || prt==string::npos)); - pr += sizeof("://")-1; - prt += sizeof("://")-1; - if(!strncmp(nrealm.c_str()+pr,"*.",2)) { - pr = nrealm.find('.',pr); - prt = nrt.find('.',prt); - assert(pr!=string::npos); - if(prt==string::npos) - throw bad_return_to( - OPKELE_CP_ "return_to URL doesn't match realm"); - // TODO: check for overgeneralized realm - } - string::size_type lr = nrealm.length(); - string::size_type lrt = nrt.length(); - if( (lrt-prt) < (lr-pr) ) - throw bad_return_to( - OPKELE_CP_ "return_to URL doesn't match realm"); - pair<const char*,const char*> mp = mismatch( - nrealm.c_str()+pr,nrealm.c_str()+lr, - nrt.c_str()+prt); - if( (*(mp.first-1))!='/' - && !strchr("/?#",*mp.second) ) - throw bad_return_to( - OPKELE_CP_ "return_to URL doesn't match realm"); + if(!util::uri_matches_realm(return_to,realm)) + throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match realm"); } } |