summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2007-01-09 20:04:29 (UTC)
committer Michael Krelin <hacker@klever.net>2007-01-09 20:04:29 (UTC)
commit46fa1790c6d5e990030d8b2b7ae07cb150a49730 (patch) (unidiff)
tree115419ff78232cfec478222b372d8c60e15dd0fc
parentadc2d682fa4f0aa83b4359bb212eda616cbe39dd (diff)
downloadlibopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.zip
libopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.tar.gz
libopkele-46fa1790c6d5e990030d8b2b7ae07cb150a49730.tar.bz2
canonicalization bug - do not add '/' after '?', add it right after hostname if needed.
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/consumer.cc11
1 files changed, 9 insertions, 2 deletions
diff --git a/lib/consumer.cc b/lib/consumer.cc
index cbe0769..bb6358c 100644
--- a/lib/consumer.cc
+++ b/lib/consumer.cc
@@ -240,102 +240,109 @@ namespace opkele {
240 || (r=curl_easy_setopt(curl,CURLOPT_URL,server.c_str())) 240 || (r=curl_easy_setopt(curl,CURLOPT_URL,server.c_str()))
241 || (r=curl_easy_setopt(curl,CURLOPT_POST,1)) 241 || (r=curl_easy_setopt(curl,CURLOPT_POST,1))
242 || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDS,request.data())) 242 || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDS,request.data()))
243 || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,request.length())) 243 || (r=curl_easy_setopt(curl,CURLOPT_POSTFIELDSIZE,request.length()))
244 || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring)) 244 || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring))
245 || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response)) 245 || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&response))
246 ; 246 ;
247 if(r) 247 if(r)
248 throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r); 248 throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r);
249 if(r=curl_easy_perform(curl)) 249 if(r=curl_easy_perform(curl))
250 throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); 250 throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r);
251 params_t pp; pp.parse_keyvalues(response); 251 params_t pp; pp.parse_keyvalues(response);
252 if(pp.has_param("invalidate_handle")) 252 if(pp.has_param("invalidate_handle"))
253 invalidate_assoc(server,pp.get_param("invalidate_handle")); 253 invalidate_assoc(server,pp.get_param("invalidate_handle"));
254 if(pp.has_param("is_valid")) { 254 if(pp.has_param("is_valid")) {
255 if(pp.get_param("is_valid")=="true") 255 if(pp.get_param("is_valid")=="true")
256 return; 256 return;
257 }else if(pp.has_param("lifetime")) { 257 }else if(pp.has_param("lifetime")) {
258 if(util::string_to_long(pp.get_param("lifetime"))) 258 if(util::string_to_long(pp.get_param("lifetime")))
259 return; 259 return;
260 } 260 }
261 throw failed_check_authentication(OPKELE_CP_ "failed to verify response"); 261 throw failed_check_authentication(OPKELE_CP_ "failed to verify response");
262 } 262 }
263 263
264 void consumer_t::retrieve_links(const string& url,string& server,string& delegate) { 264 void consumer_t::retrieve_links(const string& url,string& server,string& delegate) {
265 server.erase(); 265 server.erase();
266 delegate.erase(); 266 delegate.erase();
267 curl_t curl = curl_easy_init(); 267 curl_t curl = curl_easy_init();
268 if(!curl) 268 if(!curl)
269 throw exception_curl(OPKELE_CP_ "failed to curl_easy_init()"); 269 throw exception_curl(OPKELE_CP_ "failed to curl_easy_init()");
270 string html; 270 string html;
271 CURLcode r; 271 CURLcode r;
272 (r=curl_misc_sets(curl)) 272 (r=curl_misc_sets(curl))
273 || (r=curl_easy_setopt(curl,CURLOPT_URL,url.c_str())) 273 || (r=curl_easy_setopt(curl,CURLOPT_URL,url.c_str()))
274 || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring)) 274 || (r=curl_easy_setopt(curl,CURLOPT_WRITEFUNCTION,_curl_tostring))
275 || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&html)) 275 || (r=curl_easy_setopt(curl,CURLOPT_WRITEDATA,&html))
276 ; 276 ;
277 if(r) 277 if(r)
278 throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r); 278 throw exception_curl(OPKELE_CP_ "failed to curl_easy_setopt()",r);
279 r = curl_easy_perform(curl); 279 r = curl_easy_perform(curl);
280 if(r && r!=CURLE_WRITE_ERROR) 280 if(r && r!=CURLE_WRITE_ERROR)
281 throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r); 281 throw exception_curl(OPKELE_CP_ "failed to curl_easy_perform()",r);
282 pcrepp::Pcre bre("<body\\b",PCRE_CASELESS); 282 pcrepp::Pcre bre("<body\\b",PCRE_CASELESS);
283 // strip out everything past body 283 // strip out everything past body
284 if(bre.search(html)) 284 if(bre.search(html))
285 html.erase(bre.get_match_start()); 285 html.erase(bre.get_match_start());
286 pcrepp::Pcre hdre("<head[^>]*>",PCRE_CASELESS); 286 pcrepp::Pcre hdre("<head[^>]*>",PCRE_CASELESS);
287 if(!hdre.search(html)) 287 if(!hdre.search(html))
288 throw bad_input(OPKELE_CP_ "failed to find head"); 288 throw bad_input(OPKELE_CP_ "failed to find head");
289 html.erase(0,hdre.get_match_end()+1); 289 html.erase(0,hdre.get_match_end()+1);
290 pcrepp::Pcre lre("<link\\b([^>]+)>",PCRE_CASELESS), 290 pcrepp::Pcre lre("<link\\b([^>]+)>",PCRE_CASELESS),
291 rre("\\brel=['\"]([^'\"]+)['\"]",PCRE_CASELESS), 291 rre("\\brel=['\"]([^'\"]+)['\"]",PCRE_CASELESS),
292 hre("\\bhref=['\"]([^'\"]+)['\"]",PCRE_CASELESS); 292 hre("\\bhref=['\"]([^'\"]+)['\"]",PCRE_CASELESS);
293 while(lre.search(html)) { 293 while(lre.search(html)) {
294 string attrs = lre[0]; 294 string attrs = lre[0];
295 html.erase(0,lre.get_match_end()+1); 295 html.erase(0,lre.get_match_end()+1);
296 if(!(rre.search(attrs)&&hre.search(attrs))) 296 if(!(rre.search(attrs)&&hre.search(attrs)))
297 continue; 297 continue;
298 if(rre[0]=="openid.server") { 298 if(rre[0]=="openid.server") {
299 server = hre[0]; 299 server = hre[0];
300 if(!delegate.empty()) 300 if(!delegate.empty())
301 break; 301 break;
302 }else if(rre[0]=="openid.delegate") { 302 }else if(rre[0]=="openid.delegate") {
303 delegate = hre[0]; 303 delegate = hre[0];
304 if(!server.empty()) 304 if(!server.empty())
305 break; 305 break;
306 } 306 }
307 } 307 }
308 if(server.empty()) 308 if(server.empty())
309 throw failed_assertion(OPKELE_CP_ "The location has no openid.server declaration"); 309 throw failed_assertion(OPKELE_CP_ "The location has no openid.server declaration");
310 } 310 }
311 311
312 assoc_t consumer_t::find_assoc(const string& server) { 312 assoc_t consumer_t::find_assoc(const string& server) {
313 throw failed_lookup(OPKELE_CP_ "no find_assoc() provided"); 313 throw failed_lookup(OPKELE_CP_ "no find_assoc() provided");
314 } 314 }
315 315
316 string consumer_t::canonicalize(const string& url) { 316 string consumer_t::canonicalize(const string& url) {
317 string rv = url; 317 string rv = url;
318 // strip leading and trailing spaces 318 // strip leading and trailing spaces
319 string::size_type i = rv.find_first_not_of(" \t\r\n"); 319 string::size_type i = rv.find_first_not_of(" \t\r\n");
320 if(i==string::npos) 320 if(i==string::npos)
321 throw bad_input(OPKELE_CP_ "empty URL"); 321 throw bad_input(OPKELE_CP_ "empty URL");
322 if(i) 322 if(i)
323 rv.erase(0,i); 323 rv.erase(0,i);
324 i = rv.find_last_not_of(" \t\r\n"); 324 i = rv.find_last_not_of(" \t\r\n");
325 assert(i!=string::npos); 325 assert(i!=string::npos);
326 if(i<(rv.length()-1)) 326 if(i<(rv.length()-1))
327 rv.erase(i+1); 327 rv.erase(i+1);
328 // add missing http:// 328 // add missing http://
329 i = rv.find("://"); 329 i = rv.find("://");
330 if(i==string::npos) { // primitive. but do we need more? 330 if(i==string::npos) { // primitive. but do we need more?
331 rv.insert(0,"http://"); 331 rv.insert(0,"http://");
332 i = sizeof("http://")-1; 332 i = sizeof("http://")-1;
333 }else{ 333 }else{
334 i += sizeof("://")-1; 334 i += sizeof("://")-1;
335 } 335 }
336 if(rv.find('/',i)==string::npos) 336 string::size_type qm = rv.find('?',i);
337 rv += '/'; 337 string::size_type sl = rv.find('/',i);
338 if(qm!=string::npos) {
339 if(sl==string::npos || sl>qm)
340 rv.insert(qm,1,'/');
341 }else{
342 if(sl==string::npos)
343 rv += '/';
344 }
338 return rv; 345 return rv;
339 } 346 }
340 347
341} 348}