summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-02-02 21:10:12 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-02 21:10:12 (UTC)
commit3658759966cbadb7b50457d446f3436b6f7987da (patch) (side-by-side diff)
treeb215da5b5212b60aa1ec965df28070b4bff587bc
parenta8f733c88d87abe422ecaa405df385bad562e60f (diff)
downloadlibopkele-3658759966cbadb7b50457d446f3436b6f7987da.zip
libopkele-3658759966cbadb7b50457d446f3436b6f7987da.tar.gz
libopkele-3658759966cbadb7b50457d446f3436b6f7987da.tar.bz2
moved uri matching into separate procedure
Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/util.h8
-rw-r--r--lib/basic_op.cc35
-rw-r--r--lib/util.cc30
3 files changed, 41 insertions, 32 deletions
diff --git a/include/opkele/util.h b/include/opkele/util.h
index 719f951..bc1a0ea 100644
--- a/include/opkele/util.h
+++ b/include/opkele/util.h
@@ -132,32 +132,40 @@ namespace opkele {
* Decode binary data from base64 representation.
* @param data base64-encoded data
* @param rv container for decoded binary
*/
void decode_base64(const string& data,vector<unsigned char>& rv);
/**
* Normalize http(s) URI according to RFC3986, section 6. URI is
* expected to have scheme: in front of it.
* @param uri URI
* @return normalized URI
* @throw not_implemented in case of non-httpi(s) URI
* @throw bad_input in case of malformed URI
*/
string rfc_3986_normalize_uri(const string& uri);
+ /**
+ * Match URI against realm
+ * @param uri URI to match
+ * @param realm realm to match against
+ * @return true if URI matches realm
+ */
+ bool uri_matches_realm(const string& uri,const string& realm);
+
string& strip_uri_fragment_part(string& uri);
string abi_demangle(const char* mn);
string base64_signature(const assoc_t& assoc,const basic_openid_message& om);
class change_mode_message_proxy : public basic_openid_message {
public:
const basic_openid_message& x;
const string& mode;
change_mode_message_proxy(const basic_openid_message& xx,const string& m) : x(xx), mode(m) { }
bool has_field(const string& n) const { return x.has_field(n); }
const string& get_field(const string& n) const {
return (n=="mode")?mode:x.get_field(n); }
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,30 +1,27 @@
#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;
}
@@ -308,49 +305,23 @@ namespace opkele {
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");
}
}
diff --git a/lib/util.cc b/lib/util.cc
index b7bc437..b85a377 100644
--- a/lib/util.cc
+++ b/lib/util.cc
@@ -1,23 +1,24 @@
#include <errno.h>
#include <cassert>
#include <cctype>
#include <cstring>
#include <vector>
#include <string>
#include <stack>
+#include <algorithm>
#include <openssl/bio.h>
#include <openssl/evp.h>
#include <openssl/hmac.h>
#include <curl/curl.h>
#include "opkele/util.h"
#include "opkele/exception.h"
#include <config.h>
#ifdef HAVE_DEMANGLE
# include <cxxabi.h>
#endif
namespace opkele {
using namespace std;
namespace util {
@@ -338,32 +339,61 @@ namespace opkele {
string& strip_uri_fragment_part(string& u) {
string::size_type q = u.find('?'), f = u.find('#');
if(q==string::npos) {
if(f!=string::npos)
u.erase(f);
}else{
if(f!=string::npos) {
if(f<q)
u.erase(f,q-f);
else
u.erase(f);
}
}
return u;
}
+ bool uri_matches_realm(const string& uri,const string& realm) {
+ string nrealm = opkele::util::rfc_3986_normalize_uri(realm);
+ string nu = opkele::util::rfc_3986_normalize_uri(uri);
+ string::size_type pr = nrealm.find("://");
+ string::size_type pu = nu.find("://");
+ assert(!(pr==string::npos || pu==string::npos));
+ pr += sizeof("://")-1;
+ pu += sizeof("://")-1;
+ if(!strncmp(nrealm.c_str()+pr,"*.",2)) {
+ pr = nrealm.find('.',pr);
+ pu = nu.find('.',pu);
+ assert(pr!=string::npos);
+ if(pu==string::npos)
+ return false;
+ // TODO: check for overgeneralized realm
+ }
+ string::size_type lr = nrealm.length();
+ string::size_type lu = nu.length();
+ if( (lu-pu) < (lr-pr) )
+ return false;
+ pair<const char*,const char*> mp = mismatch(
+ nrealm.c_str()+pr,nrealm.c_str()+lr,
+ nu.c_str()+pu);
+ if( (*(mp.first-1))!='/'
+ && !strchr("/?#",*mp.second) )
+ return false;
+ return true;
+ }
+
string abi_demangle(const char *mn) {
#ifndef HAVE_DEMANGLE
return mn;
#else /* !HAVE_DEMANGLE */
int dstat;
char *demangled = abi::__cxa_demangle(mn,0,0,&dstat);
if(dstat)
return mn;
string rv = demangled;
free(demangled);
return rv;
#endif /* !HAVE_DEMANGLE */
}
string base64_signature(const assoc_t& assoc,const basic_openid_message& om) {
const string& slist = om.get_field("signed");