author | Michael Krelin <hacker@klever.net> | 2007-12-09 17:22:06 (UTC) |
---|---|---|
committer | Michael Krelin <hacker@klever.net> | 2007-12-09 22:08:24 (UTC) |
commit | c34adc6e274c3dbb63af99ca566000e7d218244c (patch) (side-by-side diff) | |
tree | 705624c208deb4eaf8d07c119a883e6f4f35236e /include | |
parent | 60fdaff7888b455b4d07eadc905cefd20f1ddd3c (diff) | |
download | libopkele-c34adc6e274c3dbb63af99ca566000e7d218244c.zip libopkele-c34adc6e274c3dbb63af99ca566000e7d218244c.tar.gz libopkele-c34adc6e274c3dbb63af99ca566000e7d218244c.tar.bz2 |
reworked identity resolution and service discovery
The discovery, which does both XRDS-based (Yadis, XRI, for XRI, using proxy)
and HTML-based search, now returns results in opkele:idiscovery_t structure.
It uses expat-based parser idigger_t, which itself is not exposed via any
header files, but hidden in lib/discovery.cc, the discovery testing program is
renamed from openid_resolve to idiscover.
Signed-off-by: Michael Krelin <hacker@klever.net>
-rw-r--r-- | include/Makefile.am | 2 | ||||
-rw-r--r-- | include/opkele/discovery.h | 33 | ||||
-rw-r--r-- | include/opkele/exception.h | 19 | ||||
-rw-r--r-- | include/opkele/openid_service_resolver.h | 118 | ||||
-rw-r--r-- | include/opkele/types.h | 63 | ||||
-rw-r--r-- | include/opkele/uris.h | 13 |
6 files changed, 125 insertions, 123 deletions
diff --git a/include/Makefile.am b/include/Makefile.am index 23c7e0d..0c2928d 100644 --- a/include/Makefile.am +++ b/include/Makefile.am @@ -1,19 +1,19 @@ nobase_include_HEADERS = \ opkele/acconfig.h \ opkele/opkele-config.h \ opkele/types.h \ opkele/association.h \ opkele/exception.h \ opkele/server.h \ opkele/consumer.h \ opkele/extension.h \ opkele/sreg.h \ opkele/extension_chain.h \ opkele/xconsumer.h \ opkele/xserver.h \ opkele/curl.h opkele/expat.h \ - opkele/openid_service_resolver.h \ + opkele/discovery.h \ opkele/uris.h EXTRA_DIST = \ opkele/data.h \ opkele/util.h diff --git a/include/opkele/discovery.h b/include/opkele/discovery.h new file mode 100644 index 0000000..5d7129b --- a/dev/null +++ b/include/opkele/discovery.h @@ -0,0 +1,33 @@ +#ifndef __OPKELE_DISCOVERY_H +#define __OPKELE_DISCOVERY_H + +#include <string> +#include <opkele/types.h> + +namespace opkele { + using std::string; + + struct idiscovery_t; + + void idiscover(idiscovery_t& result,const string& identity); + + struct idiscovery_t { + string normalized_id; + string canonicalized_id; + xrd::XRD_t xrd; + + idiscovery_t(const string& i) { + idiscover(*this,i); + } + idiscovery_t(const char *i) { + idiscover(*this,i); + } + + void clear() { + normalized_id.clear(); canonicalized_id.clear(); + xrd.clear(); + } + }; +} + +#endif /* __OPKELE_DISCOVERY_H */ diff --git a/include/opkele/exception.h b/include/opkele/exception.h index 753a818..a654d59 100644 --- a/include/opkele/exception.h +++ b/include/opkele/exception.h @@ -158,69 +158,88 @@ namespace opkele { string setup_url; id_res_setup(OPKELE_E_PARS,const string& su) : id_res_failed(OPKELE_E_CONS), setup_url(su) { } ~id_res_setup() throw() { } }; /** * thrown in case of signature mismatch */ class id_res_mismatch : public id_res_failed { public: id_res_mismatch(OPKELE_E_PARS) : id_res_failed(OPKELE_E_CONS) { } }; /** * openssl malfunction occured */ class exception_openssl : public exception { public: unsigned long _error; string _ssl_string; exception_openssl(OPKELE_E_PARS); ~exception_openssl() throw() { } }; /** * network operation related error occured */ class exception_network : public exception { public: exception_network(OPKELE_E_PARS) : exception(OPKELE_E_CONS) { } }; /** * network operation related error occured, specifically, related to * libcurl */ class exception_curl : public exception_network { public: CURLcode _error; string _curl_string; exception_curl(OPKELE_E_PARS); exception_curl(OPKELE_E_PARS,CURLcode e); ~exception_curl() throw() { } }; /** + * exception thrown in case of failed discovery + */ + class failed_discovery : public exception { + public: + failed_discovery(OPKELE_E_PARS) + : exception(OPKELE_E_CONS) { } + }; + + /** + * unsuccessfull xri resolution + */ + class failed_xri_resolution : public failed_discovery { + public: + long _code; + failed_xri_resolution(OPKELE_E_PARS,long _c=-1) + : failed_discovery(OPKELE_E_CONS), _code(_c) { } + }; + + /** * not implemented (think pure virtual) member function executed, signfies * programmer error */ class not_implemented : public exception { public: not_implemented(OPKELE_E_PARS) : exception(OPKELE_E_CONS) { } }; /** * internal error, indicates internal libopkele problem */ class internal_error : public exception { public: internal_error(OPKELE_E_PARS) : exception(OPKELE_E_CONS) { } }; } #endif /* __OPKELE_EXCEPTION_H */ diff --git a/include/opkele/openid_service_resolver.h b/include/opkele/openid_service_resolver.h deleted file mode 100644 index 64edd28..0000000 --- a/include/opkele/openid_service_resolver.h +++ b/dev/null @@ -1,118 +0,0 @@ -#ifndef __OPKELE_OPENID_SERVICE_RESOLVER_H -#define __OPKELE_OPENID_SERVICE_RESOLVER_H - -#include <climits> -#include <string> -#include <list> -#include <set> -#include <map> -#include <opkele/curl.h> -#include <opkele/expat.h> - -namespace opkele { - using std::list; - using std::string; - using std::set; - using std::map; - - struct openid_auth_SEP_t { - long priority; - set<string> xrd_Type; - string xrd_URI; - string openid_Delegate; - - openid_auth_SEP_t() : priority(LONG_MAX) { } - }; - - struct openid_auth_info_t { - string canonical_id; - openid_auth_SEP_t auth_SEP; - }; - - - class openid_service_resolver_t : public util::curl_t, public util::expat_t { - public: - string xri_proxy; - - openid_service_resolver_t(const string& xp=""); - ~openid_service_resolver_t() throw() { } - - const openid_auth_info_t& resolve(const string& id); - - enum state_t { - state_parse = 0, - state_stopping_head, state_stopping_body, - state_stopping_size - }; - state_t state; - - struct parser_node_t { - string element; - string content; - typedef map<string,string> attrs_t; - attrs_t attrs; - bool skip_text, skip_tags; - openid_auth_info_t auth_info; - - parser_node_t(const XML_Char *n,const XML_Char **a) - : skip_text(true), skip_tags(true) - { - element = n; - for(;*a;a+=2) - attrs[a[0]] = a[1]; - } - - }; - - class parser_tree_t : public list<parser_node_t> { - public: - const_reference top() const { return back(); } - reference top() { return back(); } - - const_reference parent() const { - const_reverse_iterator rv = rbegin(); - return *(++rv); } - reference parent() { - reverse_iterator rv = rbegin(); - return *(++rv); } - - inline void pop() { pop_back(); } - inline void push(const_reference e) { push_back(e); } - - void push(const XML_Char *n,const XML_Char **a) { - parser_node_t nn(n,a); - if(empty()) - nn.skip_text = nn.skip_tags = true; - else{ - const_reference t = top(); - nn.skip_text = t.skip_text; nn.skip_tags = t.skip_tags; - } - push(nn); - } - }; - parser_tree_t tree; - - void start_element(const XML_Char *n,const XML_Char **a); - void end_element(const XML_Char *n); - void character_data(const XML_Char *s,int l); - - string xrds_location; - openid_auth_SEP_t html_SEP; - openid_auth_info_t auth_info; - - void pop_tag(); - - size_t write(void *p,size_t s,size_t nm); - - string http_content_type; - - size_t header(void *p,size_t s,size_t nm); - - bool xri_mode; - - void discover_service(const string& url,bool xri=false); - }; - -} - -#endif /* __OPKELE_OPENID_SERVICE_RESOLVER_H */ diff --git a/include/opkele/types.h b/include/opkele/types.h index f732a1e..520618d 100644 --- a/include/opkele/types.h +++ b/include/opkele/types.h @@ -1,68 +1,71 @@ #ifndef __OPKELE_TYPES_H #define __OPKELE_TYPES_H /** * @file * @brief various types declarations */ #include <ostream> #include <vector> #include <string> #include <map> #include <memory> +#include <set> namespace opkele { using std::vector; using std::string; using std::map; using std::ostream; using std::auto_ptr; + using std::multimap; + using std::set; /** * the OpenID operation mode */ typedef enum _mode_t { 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_sha1 pointer to the sha1 digest * @param rv reference to the return value */ void enxor_to_base64(const unsigned char *key_sha1,string& rv) const; /** * decode base64-encoded secret and xor it with the sha1 digest * @param key_sha1 pointer to the message digest * @param b64 base64-encoded secret value */ void enxor_from_base64(const unsigned char *key_sha1,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() { } @@ -122,51 +125,111 @@ namespace opkele { */ bool has_param(const string& n) const; /** * 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; /** * retrieve the parameter. * @param n the parameter name * @return the parameter value * @throw failed_lookup if there is no such parameter */ string& get_param(const string& n); /** * parse the OpenID key/value data. * @param kv the OpenID key/value data */ void parse_keyvalues(const string& kv); /** * sign the fields. * @param secret the secret used for signing * @param sig reference to the string, containing base64-encoded * result * @param slist the comma-separated list of fields to sign * @param prefix the string to prepend to parameter names */ void sign(secret_t secret,string& sig,const string& slist,const char *prefix=0) const; /** * append parameters to the URL as a GET-request parameters. * @param url the base URL * @param prefix the string to prepend to parameter names * @return the ready-to-use location */ string append_query(const string& url,const char *prefix = "openid.") const; }; /** * dump the key/value pairs for the parameters to the stream. * @param o output stream * @param p the parameters */ ostream& operator << (ostream& o,const params_t& p); + namespace xrd { + + struct priority_compare { + inline bool operator()(long a,long b) const { + return (a<0) ? false : (b<0) ? false : (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; + } + }; + + typedef priority_map<string> canonical_ids_t; + typedef priority_map<string> local_ids_t; + typedef set<string> types_t; + typedef priority_map<string> uris_t; + + class service_t { + public: + types_t types; + uris_t uris; + local_ids_t local_ids; + + void clear() { + types.clear(); + uris.clear(); local_ids.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; + + void clear() { + expires = 0; + canonical_ids.clear(); local_ids.clear(); + services.clear(); + } + bool empty() const { + return + canonical_ids.empty() + && local_ids.empty() + && services.empty(); + } + + }; + + } + } #endif /* __OPKELE_TYPES_H */ diff --git a/include/opkele/uris.h b/include/opkele/uris.h index 9a6a3cd..a432b13 100644 --- a/include/opkele/uris.h +++ b/include/opkele/uris.h @@ -1,10 +1,15 @@ #ifndef __OPKELE_URIS_H #define __OPKELE_URIS_H -#define NSURI_XRDS "xri://$xrds" -#define NSURI_XRD "xri://$xrd*($v*2.0)" -#define NSURI_OPENID10 "http://openid.net/xmlns/1.0" +#define NSURI_XRDS "xri://$xrds" +#define NSURI_XRD "xri://$xrd*($v*2.0)" +#define NSURI_OPENID10 "http://openid.net/xmlns/1.0" -#define STURI_OPENID10 "http://openid.net/signon/1.0" +#define STURI_OPENID10 "http://openid.net/signon/1.0" +#define STURI_OPENID11 "http://openid.net/signon/1.1" +#define STURI_OPENID20 "http://specs.openid.net/auth/2.0/signon" +#define STURI_OPENID20_OP "http://specs.openid.net/auth/2.0/server" + +#define IDURI_SELECT20 "http://specs.openid.net/auth/2.0/identifier_select" #endif /* __OPKELE_URIS_H */ |