summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/exception.h9
-rw-r--r--lib/basic_op.cc36
2 files changed, 45 insertions, 0 deletions
diff --git a/include/opkele/exception.h b/include/opkele/exception.h
index 5c8418e..33f89cc 100644
--- a/include/opkele/exception.h
+++ b/include/opkele/exception.h
@@ -359,2 +359,11 @@ namespace opkele {
359 359
360 /**
361 * thrown if return_to URL doesn't match realm
362 */
363 class bad_return_to : public exception {
364 public:
365 bad_return_to(OPKELE_E_PARS)
366 : exception(OPKELE_E_CONS) { }
367 };
368
360} 369}
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index 22012bc..f7573aa 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -2,2 +2,3 @@
2#include <cassert> 2#include <cassert>
3#include <algorithm>
3#include <openssl/sha.h> 4#include <openssl/sha.h>
@@ -11,2 +12,4 @@
11namespace opkele { 12namespace opkele {
13 using std::pair;
14 using std::mismatch;
12 15
@@ -319,2 +322,35 @@ namespace opkele {
319 322
323 void basic_op::verify_return_to() {
324 string nrealm = opkele::util::rfc_3986_normalize_uri(realm);
325 if(nrealm.find('#')!=string::npos)
326 throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment");
327 string nrt = opkele::util::rfc_3986_normalize_uri(return_to);
328 string::size_type pr = nrealm.find("://");
329 string::size_type prt = nrt.find("://");
330 assert(!(pr==string::npos || prt==string::npos));
331 pr += sizeof("://")-1;
332 prt += sizeof("://")-1;
333 if(!strncmp(nrealm.c_str()+pr,"*.",2)) {
334 pr = nrealm.find('.',pr);
335 prt = nrt.find('.',prt);
336 assert(pr!=string::npos);
337 if(prt==string::npos)
338 throw bad_return_to(
339 OPKELE_CP_ "return_to URL doesn't match realm");
340 // TODO: check for overgeneralized realm
341 }
342 string::size_type lr = nrealm.length();
343 string::size_type lrt = nrt.length();
344 if( (lrt-prt) < (lr-pr) )
345 throw bad_return_to(
346 OPKELE_CP_ "return_to URL doesn't match realm");
347 pair<const char*,const char*> mp = mismatch(
348 nrealm.c_str()+pr,nrealm.c_str()+lr,
349 nrt.c_str()+prt);
350 if( (*(mp.first-1))!='/'
351 && !strchr("/?#",*mp.second) )
352 throw bad_return_to(
353 OPKELE_CP_ "return_to URL doesn't match realm");
354 }
355
320} 356}