-rw-r--r-- | lib/openid_service_resolver.cc | 18 |
1 files changed, 11 insertions, 7 deletions
diff --git a/lib/openid_service_resolver.cc b/lib/openid_service_resolver.cc index 5f82955..505e5b2 100644 --- a/lib/openid_service_resolver.cc +++ b/lib/openid_service_resolver.cc @@ -199,96 +199,100 @@ namespace opkele { } } return curl_t::header(p,s,nm); } void openid_service_resolver_t::discover_service(const string& url,bool xri) { CURLcode r = easy_setopt(CURLOPT_URL,url.c_str()); if(r) throw opkele::exception_curl(OPKELE_CP_ "failed to set curly urlie",r); (*(expat_t*)this) = parser_create_ns(); set_user_data(); set_element_handler(); set_character_data_handler(); tree.clear(); state = state_parse; r = easy_perform(); if(r && r!=CURLE_WRITE_ERROR) throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); parse(0,0,true); while(!tree.empty()) pop_tag(); } const openid_auth_info_t& openid_service_resolver_t::resolve(const string& id) { auth_info = openid_auth_info_t(); html_SEP = openid_auth_SEP_t(); string::size_type fns = id.find_first_not_of(whitespace); if(fns==string::npos) throw opkele::bad_input(OPKELE_CP_ "whitespace-only identity"); string::size_type lns = id.find_last_not_of(whitespace); assert(lns!=string::npos); if(!strncasecmp( id.c_str()+fns,"xri://", sizeof("xri://")-1)) fns+=sizeof("xri://")-1; string nid(id,fns,lns-fns+1); if(nid.empty()) throw opkele::bad_input(OPKELE_CP_ "nothing significant in identity"); if(strchr("=@+$!(",*nid.c_str())) { discover_service( xri_proxy + util::url_encode(nid) + "?_xrd_t=" STURI_OPENID10 "&_xrd_r=application/xrd+xml;sep=true", true ); if(auth_info.canonical_id.empty() || auth_info.auth_SEP.xrd_Type.empty() ) throw opkele::failed_lookup(OPKELE_CP_ "no OpenID service for XRI found"); - return auth_info; }else{ const char *np = nid.c_str(); if( (strncasecmp(np,"http",4) || strncmp( tolower(*(np+4))=='s'? np+5 : np+4, "://", 3)) #ifndef NDEBUG && strncasecmp(np,"file:///",sizeof("file:///")-1) #endif /* XXX: or how do I let tests work? */ ) nid.insert(0,"http://"); string::size_type fp = nid.find('#'); if(fp!=string::npos) { string::size_type qp = nid.find('?'); if(qp==string::npos || qp<fp) { nid.erase(fp); }else if(qp>fp) nid.erase(fp,qp-fp); } discover_service(nid); const char *eu = 0; CURLcode r = easy_getinfo(CURLINFO_EFFECTIVE_URL,&eu); if(r) throw exception_curl(OPKELE_CP_ "failed to get CURLINFO_EFFECTIVE_URL",r); string canonicalized_id = util::rfc_3986_normalize_uri(eu); if(xrds_location.empty()) { if(auth_info.auth_SEP.xrd_Type.empty()) { if(html_SEP.xrd_URI.empty()) - throw opkele::failed_lookup(OPKELE_CP_ "no OpenID service discovered"); + throw opkele::failed_lookup(OPKELE_CP_ "no OpenID 1.0 service discovered"); auth_info.auth_SEP = html_SEP; auth_info.auth_SEP.xrd_Type.clear(); auth_info.auth_SEP.xrd_Type.insert( STURI_OPENID10 ); auth_info.canonical_id = canonicalized_id; }else{ if(auth_info.canonical_id.empty()) auth_info.canonical_id = canonicalized_id; } - return auth_info; }else{ discover_service(xrds_location); - if(auth_info.auth_SEP.xrd_Type.empty()) - throw opkele::failed_lookup(OPKELE_CP_ "no OpenID service found in Yadis document"); - if(auth_info.canonical_id.empty()) + if(auth_info.auth_SEP.xrd_Type.empty()) { + if(html_SEP.xrd_URI.empty()) + throw opkele::failed_lookup(OPKELE_CP_ "no OpenID 1.0 service discovered"); + auth_info.auth_SEP = html_SEP; + auth_info.auth_SEP.xrd_Type.clear(); auth_info.auth_SEP.xrd_Type.insert( STURI_OPENID10 ); auth_info.canonical_id = canonicalized_id; - return auth_info; + }else{ + if(auth_info.canonical_id.empty()) + auth_info.canonical_id = canonicalized_id; + } } } + return auth_info; } } |