summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/discovery.h3
-rw-r--r--include/opkele/prequeue_rp.h8
-rw-r--r--include/opkele/types.h3
-rw-r--r--lib/prequeue_rp.cc9
4 files changed, 19 insertions, 4 deletions
diff --git a/include/opkele/discovery.h b/include/opkele/discovery.h
index 4471597..f2721a6 100644
--- a/include/opkele/discovery.h
+++ b/include/opkele/discovery.h
@@ -1,115 +1,114 @@
#ifndef __OPKELE_DISCOVERY_H
#define __OPKELE_DISCOVERY_H
#include <string>
#include <opkele/types.h>
namespace opkele {
using std::string;
namespace xrd {
struct priority_compare {
inline bool operator()(long a,long b) const {
return (a<0) ? false : (b<0) ? true : (a<b);
}
};
template <typename _DT>
class priority_map : public multimap<long,_DT,priority_compare> {
typedef multimap<long,_DT,priority_compare> map_type;
public:
inline _DT& add(long priority,const _DT& d) {
return insert(typename map_type::value_type(priority,d))->second;
}
bool has_value(const _DT& d) const {
for(typename map_type::const_iterator i=this->begin();i!=this->end();++i)
if(i->second==d) return true;
return false;
}
};
typedef priority_map<string> canonical_ids_t;
typedef priority_map<string> local_ids_t;
typedef set<string> types_t;
struct uri_t {
string uri;
string append;
uri_t() { }
uri_t(const string& u) : uri(u) { }
uri_t(const string& u,const string& a) : uri(u), append(a) { }
};
typedef priority_map<uri_t> uris_t;
class service_t {
public:
types_t types;
uris_t uris;
local_ids_t local_ids;
string provider_id;
void clear() {
types.clear();
uris.clear(); local_ids.clear();
provider_id.clear();
}
};
typedef priority_map<service_t> services_t;
class XRD_t {
public:
time_t expires;
canonical_ids_t canonical_ids;
local_ids_t local_ids;
services_t services;
string provider_id;
void clear() {
expires = 0;
canonical_ids.clear(); local_ids.clear();
services.clear();
provider_id.clear();
}
bool empty() const {
return
canonical_ids.empty()
&& local_ids.empty()
&& services.empty();
}
};
}
- typedef util::output_iterator_proxy<openid_endpoint_t>
- endpoint_discovery_iterator;
+ typedef openid_endpoint_output_iterator endpoint_discovery_iterator;
string idiscover(
endpoint_discovery_iterator oi,
const string& identity);
void yadiscover(
endpoint_discovery_iterator oi,
const string& yurl,
const char **types, bool redirs=false);
struct idiscovery_t {
bool xri_identity;
string normalized_id;
string canonicalized_id;
xrd::XRD_t xrd;
idiscovery_t() { }
void clear() {
normalized_id.clear(); canonicalized_id.clear();
xrd.clear();
}
};
}
#endif /* __OPKELE_DISCOVERY_H */
diff --git a/include/opkele/prequeue_rp.h b/include/opkele/prequeue_rp.h
index 68fe03d..6f1fda9 100644
--- a/include/opkele/prequeue_rp.h
+++ b/include/opkele/prequeue_rp.h
@@ -1,88 +1,96 @@
#ifndef __OPKELE_RP_H
#define __OPKELE_RP_H
#include <string>
#include <set>
#include <iterator>
#include <opkele/basic_rp.h>
namespace opkele {
using std::string;
using std::set;
using std::iterator;
using std::output_iterator_tag;
/**
* discovery-enabled RP implementation, prequeueing discovered endpoints
*/
class prequeue_RP : public basic_RP {
public:
/**
* @name Session persistent store API
* @{
*/
/**
* Called before queueing discovered endpoints. Typically happens
* while initiating authentication session.
* @see queue_endpoint()
* @see end_queueing()
*/
virtual void begin_queueing() { }
/**
* Used to queue discovered endpoint. It is implementors
* responsibility to store the endpoint wherever he choses to store
* it.
* @param oep the endpoint to queue
* @see begin_queueing()
* @see end_queueing()
*/
virtual void queue_endpoint(const openid_endpoint_t& oep) = 0;
/**
* Called after all discovered endpoints were queued. Implementor
* may chose to use this virtual to commit endpoints queue to
* persistent store.
* @see begin_queueing()
* @see queue_endpoint()
*/
virtual void end_queueing() { }
/**
* Used to store normalized id when initiating request.
* The default implementation does nothing, because implementor
* doesn't have to care.
* @param nid normalized id
* @see get_normalzied_id()
*/
virtual void set_normalized_id(const string& nid);
/**
* Return the normalized id previously set by set_normalized_id().
* Provided for the sake of completeness because default
* implementation doesn't use it.
* @return the normalized identity
*/
virtual const string get_normalized_id() const;
/**
* @}
*/
/**
* @name Actions
* @{
*/
/**
* In addition to base class implementation it does endpoints
* discovery and queueing
* @param usi User-suppled identifier
*/
void initiate(const string& usi);
/**
* @}
*/
void verify_OP(const string& OP,
const string& claimed_id,const string& identity) const;
+
+ /**
+ * Perform full discovery on identity
+ * @param it iterator used for feeding discovered endpoints back to caller
+ * @param id user supplied identity
+ * @returns normalized identity (canonical identifier can be found in endpoints)
+ */
+ virtual const string discover(openid_endpoint_output_iterator it,const string& id) const;
};
}
#endif /* __OPKELE_RP_H */
diff --git a/include/opkele/types.h b/include/opkele/types.h
index 1f48362..1fab869 100644
--- a/include/opkele/types.h
+++ b/include/opkele/types.h
@@ -1,230 +1,233 @@
#ifndef __OPKELE_TYPES_H
#define __OPKELE_TYPES_H
/**
* @file
* @brief various types declarations
*/
#include <cstring>
#include <ostream>
#include <vector>
#include <string>
#include <map>
#include <set>
#include <list>
#include <opkele/iterator.h>
#include <opkele/tr1-mem.h>
namespace opkele {
using std::vector;
using std::string;
using std::map;
using std::ostream;
using std::multimap;
using std::set;
using std::list;
using std::iterator;
using std::forward_iterator_tag;
/**
* the OpenID operation mode
*/
typedef enum _mode_t {
mode_unknown = 0,
mode_associate,
mode_checkid_immediate,
mode_checkid_setup,
mode_check_association
} mode_t;
/**
* the association secret container
*/
class secret_t : public vector<unsigned char> {
public:
/**
* xor the secret and hmac together and encode, using base64
* @param key_d pointer to the message digest
* @param rv reference to the return value
*/
void enxor_to_base64(const unsigned char *key_d,string& rv) const;
/**
* decode base64-encoded secret and xor it with the message digest
* @param key_d pointer to the message digest
* @param b64 base64-encoded secret value
*/
void enxor_from_base64(const unsigned char *key_d,const string& b64);
/**
* plainly encode to base64 representation
* @param rv reference to the return value
*/
void to_base64(string& rv) const;
/**
* decode cleartext secret from base64
* @param b64 base64-encoded representation of the secret value
*/
void from_base64(const string& b64);
};
/**
* Interface to the association.
*/
class association_t {
public:
virtual ~association_t() { }
/**
* retrieve the server with which association was established.
* @return server name
*/
virtual string server() const = 0;
/**
* retrieve the association handle.
* @return handle
*/
virtual string handle() const = 0;
/**
* retrieve the association type.
* @return association type
*/
virtual string assoc_type() const = 0;
/**
* retrieve the association secret.
* @return association secret
*/
virtual secret_t secret() const = 0;
/**
* retrieve the number of seconds the association expires in.
* @return seconds till expiration
*/
virtual int expires_in() const = 0;
/**
* check whether the association is stateless.
* @return true if stateless
*/
virtual bool stateless() const = 0;
/**
* check whether the association is expired.
* @return true if expired
*/
virtual bool is_expired() const = 0;
};
/**
* the shared_ptr<> for association_t object type
*/
typedef tr1mem::shared_ptr<association_t> assoc_t;
class basic_openid_message {
public:
typedef list<string> fields_t;
typedef util::forward_iterator_proxy<
string,const string&,const string*
> fields_iterator;
basic_openid_message() { }
virtual ~basic_openid_message() { }
basic_openid_message(const basic_openid_message& x);
void copy_to(basic_openid_message& x) const;
virtual bool has_field(const string& n) const = 0;
virtual const string& get_field(const string& n) const = 0;
virtual bool has_ns(const string& uri) const;
virtual string get_ns(const string& uri) const;
virtual fields_iterator fields_begin() const = 0;
virtual fields_iterator fields_end() const = 0;
virtual string append_query(const string& url) const;
virtual string query_string() const;
virtual void reset_fields();
virtual void set_field(const string& n,const string& v);
virtual void reset_field(const string& n);
virtual void from_keyvalues(const string& kv);
virtual void to_keyvalues(ostream& o) const;
virtual void to_htmlhiddens(ostream& o,const char* pfx=0) const;
void add_to_signed(const string& fields);
string find_ns(const string& uri,const char *pfx) const;
string allocate_ns(const string& uri,const char *pfx);
};
class openid_message_t : public basic_openid_message, public map<string,string> {
public:
openid_message_t() { }
openid_message_t(const basic_openid_message& x)
: basic_openid_message(x) { }
void copy_to(basic_openid_message& x) const;
bool has_field(const string& n) const;
const string& get_field(const string& n) const;
virtual fields_iterator fields_begin() const;
virtual fields_iterator fields_end() const;
void reset_fields();
void set_field(const string& n,const string& v);
void reset_field(const string& n);
};
/**
* request/response parameters map
*/
class params_t : public openid_message_t {
public:
/**
* check whether the parameter is present.
* @param n the parameter name
* @return true if yes
*/
bool has_param(const string& n) const {
return has_field(n); }
/**
* retrieve the parameter (const version)
* @param n the parameter name
* @return the parameter value
* @throw failed_lookup if there is no such parameter
*/
const string& get_param(const string& n) const {
return get_field(n); }
/**
* parse the OpenID key/value data.
* @param kv the OpenID key/value data
*/
void parse_keyvalues(const string& kv) {
from_keyvalues(kv); }
string append_query(const string& url,const char *prefix="openid.") const;
};
struct openid_endpoint_t {
string uri;
string claimed_id;
string local_id;
openid_endpoint_t() { }
openid_endpoint_t(const string& u,const string& cid,const string& lid)
: uri(u), claimed_id(cid), local_id(lid) { }
bool operator==(const openid_endpoint_t& x) const {
return uri==x.uri && local_id==x.local_id; }
bool operator<(const openid_endpoint_t& x) const {
int c;
return (c=strcmp(uri.c_str(),x.uri.c_str()))
? (c<0) : (strcmp(local_id.c_str(),x.local_id.c_str())<0); }
};
+ typedef util::output_iterator_proxy<openid_endpoint_t>
+ openid_endpoint_output_iterator;
+
}
#endif /* __OPKELE_TYPES_H */
diff --git a/lib/prequeue_rp.cc b/lib/prequeue_rp.cc
index 3aa960f..ed1ddfe 100644
--- a/lib/prequeue_rp.cc
+++ b/lib/prequeue_rp.cc
@@ -1,81 +1,86 @@
#include <iostream>
#include <openssl/sha.h>
#include <openssl/hmac.h>
#include <opkele/exception.h>
#include <opkele/prequeue_rp.h>
#include <opkele/discovery.h>
#include <opkele/uris.h>
#include <opkele/data.h>
#include <opkele/util.h>
#include <opkele/curl.h>
#include <opkele/debug.h>
namespace opkele {
class __OP_verifier_good_input : public exception {
public:
__OP_verifier_good_input(OPKELE_E_PARS)
: exception(OPKELE_E_CONS) { }
};
class OP_verifier : public iterator<output_iterator_tag,openid_endpoint_t,void> {
public:
const string& OP;
const string& id;
OP_verifier(const string& o,const string& i)
: OP(o), id(i) { }
OP_verifier& operator*() { return *this; }
OP_verifier& operator=(const openid_endpoint_t& oep) {
if(oep.uri==OP) {
if(oep.claimed_id==IDURI_SELECT20
|| oep.local_id==IDURI_SELECT20 )
throw bad_input(OPKELE_CP_ "claimed_id is an OP-Id");
if(oep.local_id==id)
throw __OP_verifier_good_input(OPKELE_CP_ "Found corresponding endpoint");
}
return *this;
}
OP_verifier& operator++() { return *this; }
OP_verifier& operator++(int) { return *this; }
};
void prequeue_RP::verify_OP(const string& OP,const string& claimed_id,const string& identity) const {
try {
- idiscover(OP_verifier(OP,identity),claimed_id);
+ discover(OP_verifier(OP,identity),claimed_id);
throw id_res_unauthorized(OPKELE_CP_
"OP is not authorized to make an assertion regarding the identity");
}catch(__OP_verifier_good_input& ovgi) {
}
}
class endpoint_queuer : public iterator<output_iterator_tag,openid_endpoint_t,void> {
public:
prequeue_RP& rp;
endpoint_queuer(prequeue_RP& r) : rp(r) { }
endpoint_queuer& operator*() { return *this; }
endpoint_queuer& operator=(const openid_endpoint_t& oep) {
rp.queue_endpoint(oep); return *this; }
endpoint_queuer& operator++() { return *this; }
endpoint_queuer& operator++(int) { return *this; }
};
void prequeue_RP::initiate(const string& usi) {
begin_queueing();
- set_normalized_id( idiscover(endpoint_queuer(*this),usi) );
+ set_normalized_id( discover(endpoint_queuer(*this),usi) );
end_queueing();
}
void prequeue_RP::set_normalized_id(const string&) {
}
const string prequeue_RP::get_normalized_id() const {
throw not_implemented(OPKELE_CP_ "get_normalized_id() is not implemented");
}
+ const string prequeue_RP::discover(openid_endpoint_output_iterator it,
+ const string& id) const {
+ return idiscover(it,id);
+ }
+
}