summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-02-02 19:57:52 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-02 19:57:52 (UTC)
commit529c53f0eb63040735b4cad7806cef6d5e65144b (patch) (unidiff)
tree711cd9e8d30a9f251de529cdfcfcd05ac0e871b3
parent4efb668baed49ede14846c3cdac31cc561451cd1 (diff)
downloadlibopkele-529c53f0eb63040735b4cad7806cef6d5e65144b.zip
libopkele-529c53f0eb63040735b4cad7806cef6d5e65144b.tar.gz
libopkele-529c53f0eb63040735b4cad7806cef6d5e65144b.tar.bz2
check if return_to matches realm
Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (show 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
@@ -348,15 +348,24 @@ namespace opkele {
348 : exception(OPKELE_E_CONS) { } 348 : exception(OPKELE_E_CONS) { }
349 }; 349 };
350 350
351 /** 351 /**
352 * thrown when querying identity of non-identity related request 352 * thrown when querying identity of non-identity related request
353 */ 353 */
354 class non_identity : public exception { 354 class non_identity : public exception {
355 public: 355 public:
356 non_identity(OPKELE_E_PARS) 356 non_identity(OPKELE_E_PARS)
357 : exception(OPKELE_E_CONS) { } 357 : exception(OPKELE_E_CONS) { }
358 }; 358 };
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}
361 370
362#endif /* __OPKELE_EXCEPTION_H */ 371#endif /* __OPKELE_EXCEPTION_H */
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
@@ -1,23 +1,26 @@
1#include <time.h> 1#include <time.h>
2#include <cassert> 2#include <cassert>
3#include <algorithm>
3#include <openssl/sha.h> 4#include <openssl/sha.h>
4#include <openssl/hmac.h> 5#include <openssl/hmac.h>
5#include <opkele/data.h> 6#include <opkele/data.h>
6#include <opkele/basic_op.h> 7#include <opkele/basic_op.h>
7#include <opkele/exception.h> 8#include <opkele/exception.h>
8#include <opkele/util.h> 9#include <opkele/util.h>
9#include <opkele/uris.h> 10#include <opkele/uris.h>
10 11
11namespace opkele { 12namespace opkele {
13 using std::pair;
14 using std::mismatch;
12 15
13 void basic_op::reset_vars() { 16 void basic_op::reset_vars() {
14 assoc.reset(); 17 assoc.reset();
15 return_to.clear(); realm.clear(); 18 return_to.clear(); realm.clear();
16 claimed_id.clear(); identity.clear(); 19 claimed_id.clear(); identity.clear();
17 invalidate_handle.clear(); 20 invalidate_handle.clear();
18 } 21 }
19 22
20 bool basic_op::has_return_to() const { 23 bool basic_op::has_return_to() const {
21 return !return_to.empty(); 24 return !return_to.empty();
22 } 25 }
23 const string& basic_op::get_return_to() const { 26 const string& basic_op::get_return_to() const {
@@ -308,13 +311,46 @@ namespace opkele {
308 } 311 }
309 }catch(failed_lookup&) { } 312 }catch(failed_lookup&) { }
310 if(o2) { 313 if(o2) {
311 assert(!nonce.empty()); 314 assert(!nonce.empty());
312 invalidate_nonce(nonce); 315 invalidate_nonce(nonce);
313 } 316 }
314 return oum; 317 return oum;
315 }catch(failed_check_authentication& ) { 318 }catch(failed_check_authentication& ) {
316 oum.set_field("is_valid","false"); 319 oum.set_field("is_valid","false");
317 return oum; 320 return oum;
318 } 321 }
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}