summaryrefslogtreecommitdiffabout
path: root/include/opkele
authorMichael Krelin <hacker@klever.net>2008-01-20 21:08:05 (UTC)
committer Michael Krelin <hacker@klever.net>2008-01-20 21:08:05 (UTC)
commit9bfb6fadf71c46bf4cb5adabba0c96c32e84c1bc (patch) (unidiff)
tree702473142242e80538c4801cc379ec98fba199dd /include/opkele
parent395a126cbf59b7a50f44da3096b68bab412ab33d (diff)
downloadlibopkele-9bfb6fadf71c46bf4cb5adabba0c96c32e84c1bc.zip
libopkele-9bfb6fadf71c46bf4cb5adabba0c96c32e84c1bc.tar.gz
libopkele-9bfb6fadf71c46bf4cb5adabba0c96c32e84c1bc.tar.bz2
the whole library rewritten
Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (limited to 'include/opkele') (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/basic_rp.h218
-rw-r--r--include/opkele/discovery.h88
-rw-r--r--include/opkele/exception.h19
-rw-r--r--include/opkele/extension.h7
-rw-r--r--include/opkele/extension_chain.h6
-rw-r--r--include/opkele/prequeue_rp.h81
-rw-r--r--include/opkele/sreg.h8
-rw-r--r--include/opkele/types.h171
-rw-r--r--include/opkele/util.h8
9 files changed, 479 insertions, 127 deletions
diff --git a/include/opkele/basic_rp.h b/include/opkele/basic_rp.h
new file mode 100644
index 0000000..3f17fd9
--- a/dev/null
+++ b/include/opkele/basic_rp.h
@@ -0,0 +1,218 @@
1#ifndef __OPKELE_BASIC_RP_H
2#define __OPKELE_BASIC_RP_H
3
4#include <cstring>
5#include <string>
6#include <opkele/types.h>
7#include <opkele/extension.h>
8
9namespace opkele {
10 using std::string;
11
12 struct openid_endpoint_t {
13 string uri;
14 string claimed_id;
15 string local_id;
16
17 openid_endpoint_t() { }
18 openid_endpoint_t(const string& u,const string& cid,const string& lid)
19 : uri(u), claimed_id(cid), local_id(lid) { }
20
21 bool operator==(const openid_endpoint_t& x) const {
22 return uri==x.uri && local_id==x.local_id; }
23 bool operator<(const openid_endpoint_t& x) const {
24 int c;
25 return (c=strcmp(uri.c_str(),x.uri.c_str()))
26 ? (c<0) : (strcmp(local_id.c_str(),x.local_id.c_str())<0); }
27 };
28
29 class basic_RP {
30 public:
31
32 virtual ~basic_RP() { }
33
34 /**
35 * @name Global persistent store API
36 * These are functions related to the associations with OP storage
37 * and retrieval and nonce records. They provide an interface to
38 * the persistent storage which is shared by all sessions. If the
39 * implementor prefers the dumb mode instead, the function should
40 * throw dumb_RP exception instead.
41 * @see opkele::dumb_RP
42 * @{
43 */
44 /**
45 * Store association and return allocated association object.
46 * @param OP OP endpoint
47 * @param handle association handle
48 * @param type association type
49 * @param secret association secret
50 * @params expires_in the number of seconds association expires in
51 * @return the association object
52 * @throw dumb_RP for dumb RP
53 */
54 virtual assoc_t store_assoc(
55 const string& OP,const string& handle,
56 const string& type,const secret_t& secret,
57 int expires_in) = 0;
58 /**
59 * Find valid unexpired association with an OP.
60 * @param OP OP endpoint URL
61 * @return association found
62 * @throw failed_lookup if no association found
63 * @throw dumb_RP for dumb RP
64 */
65 virtual assoc_t find_assoc(
66 const string& OP) = 0;
67 /**
68 * Retrieve valid association handle for an OP by handle.
69 * @param OP OP endpoint URL
70 * @param handle association handle
71 * @return association found
72 * @throw failed_lookup if no association found
73 * @throw dumb_RP for dumb RP
74 */
75 virtual assoc_t retrieve_assoc(
76 const string& OP,const string& handle) = 0;
77 /**
78 * Invalidate association with OP
79 * @param OP OP endpoint URL
80 * @param handle association handle
81 * @throw dumb_RP for dumb RP
82 */
83 virtual void invalidate_assoc(const string& OP,const string& handle) = 0;
84
85 /**
86 * Check the nonce validity. That is, check that we haven't
87 * accepted request with this nonce from this OP, yet. May involve
88 * cutting off by the timestamp and checking the rest against the
89 * store of seen nonces.
90 * @param OP OP endpoint URL
91 * @param nonce nonce value
92 * @throw id_res_bad_nonce if the nonce is not to be accepted, i.e.
93 * either too old or seen.
94 */
95 virtual void check_nonce(const string& OP,const string& nonce) = 0;
96 /**
97 * @}
98 */
99
100 /**
101 * @name Session persistent store API
102 * @{
103 */
104 /**
105 * Retrieve OpenID endpoint being currently used for
106 * authentication. If there is no endpoint available, throw a
107 * no_endpoint exception.
108 * @return reference to the service endpoint object
109 * @see next_endpoint
110 * @throw no_endpoint if no endpoint available
111 */
112 virtual const openid_endpoint_t& get_endpoint() const = 0;
113 /**
114 * Advance to the next endpoint to try.
115 * @see get_endpoint()
116 * @throw no_endpoint if there are no more endpoints
117 */
118 virtual void next_endpoint() = 0;
119 /**
120 * @}
121 */
122
123 /**
124 * @name Site particulars API
125 * @{
126 */
127 /**
128 * Return an absolute URL of the page being processed, includining
129 * query parameters. It is used to validate return_to URL on
130 * positive assertions.
131 * @return fully qualified url of the page being processed.
132 */
133 virtual const string get_this_url() const = 0;
134 /**
135 * @}
136 */
137
138 /**
139 * @name OpenID actions
140 * @{
141 */
142 /**
143 * Initiates authentication session, doing discovery, normalization
144 * and whatever implementor wants to do at this point.
145 * @param usi User-supplied identity
146 */
147 virtual void initiate(const string& usi) = 0;
148 /**
149 * Prepare checkid_request.
150 * @param rv reference to the openid message to prepare
151 * @param mode checkid_setup or checkid_immediate
152 * @param return_to the URL OP should redirect to after completion
153 * @param realm authentication realm to pass to OP
154 * @param ext pointer to extension to use in request preparation
155 * @return reference to the openid message
156 */
157 basic_openid_message& checkid_(
158 basic_openid_message& rv,
159 mode_t mode,
160 const string& return_to,const string& realm,
161 extension_t *ext=0);
162 /**
163 * Verify assertion at the end of round-trip.
164 * @param om incoming openid message
165 * @param ext pointer to extention to use in parsing assertion
166 * @throw id_res_setup if checkid_immediate request could not be
167 * completed
168 * @throw id_res_cancel if authentication request was canceled
169 * @throw id_res_mismatch in case of signature mismatch
170 * @throw id_res_bad_return_to if return_to url seems to be
171 * tampered with
172 * @throw id_res_unauthorized if OP is not authorized to make
173 * assertions regarding the identity
174 */
175 void id_res(const basic_openid_message& om,extension_t *ext=0);
176
177 /**
178 * Establish association with OP
179 * @param OP OP to establish association with
180 * @throw dumb_RP if for a dumb RP
181 */
182 virtual assoc_t associate(const string& OP);
183 /**
184 * Check authentication with OP and invalidate handle if requested
185 * and confirmed
186 * @param OP OP to check with
187 * @param om message to check
188 * @throw failed_check_authentication if OP fails to confirm
189 * authenticity of the assertion
190 */
191 void check_authentication(const string& OP,const basic_openid_message& om);
192 /**
193 * @}
194 */
195
196 /**
197 * @name Miscellanea
198 * @{
199 */
200 /**
201 * Verify OP authority. Return normally if OP is authorized to make
202 * an assertion, throw an exception otherwise.
203 * @param OP OP endpoint
204 * @param claimed_id claimed identity
205 * @param identity OP-Local identifier
206 * @throw id_res_unauthorized if OP is not authorized to make
207 * assertion regarding this identity.
208 */
209 virtual void verify_OP(const string& OP,
210 const string& claimed_id,const string& identity) const = 0;
211 /**
212 * @}
213 */
214 };
215
216}
217
218#endif /* __OPKELE_BASIC_RP_H */
diff --git a/include/opkele/discovery.h b/include/opkele/discovery.h
index af4aa29..ab4b9d9 100644
--- a/include/opkele/discovery.h
+++ b/include/opkele/discovery.h
@@ -5,2 +5,3 @@
5#include <opkele/types.h> 5#include <opkele/types.h>
6#include <opkele/basic_rp.h>
6 7
@@ -9,5 +10,78 @@ namespace opkele {
9 10
10 struct idiscovery_t; 11 namespace xrd {
11 12
12 void idiscover(idiscovery_t& result,const string& identity); 13 struct priority_compare {
14 inline bool operator()(long a,long b) const {
15 return (a<0) ? false : (b<0) ? true : (a<b);
16 }
17 };
18
19 template <typename _DT>
20 class priority_map : public multimap<long,_DT,priority_compare> {
21 typedef multimap<long,_DT,priority_compare> map_type;
22 public:
23
24 inline _DT& add(long priority,const _DT& d) {
25 return insert(typename map_type::value_type(priority,d))->second;
26 }
27
28 bool has_value(const _DT& d) const {
29 for(typename map_type::const_iterator i=this->begin();i!=this->end();++i)
30 if(i->second==d) return true;
31 return false;
32 }
33 };
34
35 typedef priority_map<string> canonical_ids_t;
36 typedef priority_map<string> local_ids_t;
37 typedef set<string> types_t;
38 typedef priority_map<string> uris_t;
39
40 class service_t {
41 public:
42 types_t types;
43 uris_t uris;
44 local_ids_t local_ids;
45 string provider_id;
46
47 void clear() {
48 types.clear();
49 uris.clear(); local_ids.clear();
50 provider_id.clear();
51 }
52 };
53 typedef priority_map<service_t> services_t;
54
55 class XRD_t {
56 public:
57 time_t expires;
58
59 canonical_ids_t canonical_ids;
60 local_ids_t local_ids;
61 services_t services;
62 string provider_id;
63
64 void clear() {
65 expires = 0;
66 canonical_ids.clear(); local_ids.clear();
67 services.clear();
68 provider_id.clear();
69 }
70 bool empty() const {
71 return
72 canonical_ids.empty()
73 && local_ids.empty()
74 && services.empty();
75 }
76
77 };
78
79 }
80
81 typedef util::output_iterator_proxy<openid_endpoint_t>
82 endpoint_discovery_iterator;
83
84 string idiscover(
85 endpoint_discovery_iterator oi,
86 const string& identity);
13 87
@@ -20,8 +94,2 @@ namespace opkele {
20 idiscovery_t() { } 94 idiscovery_t() { }
21 idiscovery_t(const string& i) {
22 idiscover(*this,i);
23 }
24 idiscovery_t(const char *i) {
25 idiscover(*this,i);
26 }
27 95
@@ -32,6 +100,2 @@ namespace opkele {
32 100
33 idiscovery_t& operator=(const string& i) {
34 idiscover(*this,i); return *this; }
35 idiscovery_t& operator=(const char *i) {
36 idiscover(*this,i); return *this; }
37 }; 101 };
diff --git a/include/opkele/exception.h b/include/opkele/exception.h
index a8c3339..ccb39d9 100644
--- a/include/opkele/exception.h
+++ b/include/opkele/exception.h
@@ -313,2 +313,21 @@ namespace opkele {
313 313
314 /**
315 * thrown by associations store related functions in case of dumb RP.
316 */
317 class dumb_RP : public exception {
318 public:
319 dumb_RP(OPKELE_E_PARS)
320 : exception(OPKELE_E_CONS) { }
321 };
322
323 /**
324 * thrown by endpoint-queue related function if endpoint is being
325 * accessed but there's no endpoint available.
326 */
327 class no_endpoint : public exception {
328 public:
329 no_endpoint(OPKELE_E_PARS)
330 : exception(OPKELE_E_CONS) { }
331 };
332
314} 333}
diff --git a/include/opkele/extension.h b/include/opkele/extension.h
index 513672f..3ee25ee 100644
--- a/include/opkele/extension.h
+++ b/include/opkele/extension.h
@@ -19,2 +19,3 @@ namespace opkele {
19 virtual ~extension_t() { } 19 virtual ~extension_t() { }
20
20 /** 21 /**
@@ -29,3 +30,3 @@ namespace opkele {
29 */ 30 */
30 virtual void checkid_hook(params_t& p,const string& identity); 31 virtual void checkid_hook(basic_openid_message& om);
31 /** 32 /**
@@ -41,3 +42,3 @@ namespace opkele {
41 */ 42 */
42 virtual void id_res_hook(const params_t& p,const params_t& sp,const string& identity); 43 virtual void id_res_hook(const basic_openid_message& om,const basic_openid_message& sp);
43 44
@@ -53,3 +54,3 @@ namespace opkele {
53 */ 54 */
54 virtual void checkid_hook(const params_t& pin,params_t& pout); 55 virtual void checkid_hook(const basic_openid_message& inm,basic_openid_message& oum);
55 56
diff --git a/include/opkele/extension_chain.h b/include/opkele/extension_chain.h
index f0eea94..fb9bc84 100644
--- a/include/opkele/extension_chain.h
+++ b/include/opkele/extension_chain.h
@@ -30,5 +30,5 @@ namespace opkele {
30 30
31 virtual void checkid_hook(params_t& p,const string& identity); 31 virtual void checkid_hook(basic_openid_message& om);
32 virtual void id_res_hook(const params_t& p,const params_t& sp,const string& identity); 32 virtual void id_res_hook(const basic_openid_message& om,const basic_openid_message& sp);
33 virtual void checkid_hook(const params_t& pin,params_t& pout); 33 virtual void checkid_hook(const basic_openid_message& inm,basic_openid_message& oum);
34 }; 34 };
diff --git a/include/opkele/prequeue_rp.h b/include/opkele/prequeue_rp.h
new file mode 100644
index 0000000..b98dd5a
--- a/dev/null
+++ b/include/opkele/prequeue_rp.h
@@ -0,0 +1,81 @@
1#ifndef __OPKELE_RP_H
2#define __OPKELE_RP_H
3
4#include <string>
5#include <set>
6#include <iterator>
7#include <opkele/basic_rp.h>
8
9namespace opkele {
10 using std::string;
11 using std::set;
12 using std::iterator;
13 using std::output_iterator_tag;
14
15 class prequeue_RP : public basic_RP {
16 public:
17 /**
18 * @name Session persistent store API
19 * @{
20 */
21 /**
22 * Called before queueing discovered endpoints. Typically happens
23 * while initiating authentication session.
24 * @see queue_endpoint()
25 * @see end_queueing()
26 */
27 virtual void begin_queueing() { }
28 /**
29 * Used to queue discovered endpoint. It is implementors
30 * responsibility to store the endpoint wherever he choses to store
31 * it.
32 * @param oep the endpoint to queue
33 * @see begin_queueing()
34 * @see end_queueing()
35 */
36 virtual void queue_endpoint(const openid_endpoint_t& oep) = 0;
37 /**
38 * Called after all discovered endpoints were queued. Implementor
39 * may chose to use this virtual to commit endpoints queue to
40 * persistent store.
41 * @see begin_queueing()
42 * @see queue_endpoint()
43 */
44 virtual void end_queueing() { }
45
46 /**
47 * Used to store normalized id when initiating request.
48 * The default implementation does nothing, because implementor
49 * doesn't have to care.
50 * @param nid normalized id
51 * @see get_normalzied_id()
52 */
53 virtual void set_normalized_id(const string& nid);
54 /**
55 * Return the normalized id previously set by set_normalized_id().
56 * Provided for the sake of completeness because default
57 * implementation doesn't use it.
58 * @return the normalized identity
59 */
60 virtual const string get_normalized_id() const;
61 /**
62 * @}
63 */
64
65 /**
66 * @name Actions
67 * @{
68 */
69 void initiate(const string& usi);
70
71 /**
72 * @}
73 */
74
75 void verify_OP(const string& OP,
76 const string& claimed_id,const string& identity) const;
77 };
78
79}
80
81#endif /* __OPKELE_RP_H */
diff --git a/include/opkele/sreg.h b/include/opkele/sreg.h
index df37a86..24cb315 100644
--- a/include/opkele/sreg.h
+++ b/include/opkele/sreg.h
@@ -140,3 +140,3 @@ namespace opkele {
140 */ 140 */
141 virtual void checkid_hook(params_t& p,const string& identity); 141 virtual void checkid_hook(basic_openid_message& om);
142 /** 142 /**
@@ -144,3 +144,3 @@ namespace opkele {
144 */ 144 */
145 virtual void id_res_hook(const params_t& p,const params_t& sp,const string& identity); 145 virtual void id_res_hook(const basic_openid_message& om,const basic_openid_message& sp);
146 /** 146 /**
@@ -148,3 +148,3 @@ namespace opkele {
148 */ 148 */
149 virtual void checkid_hook(const params_t& pin,params_t& pout); 149 virtual void checkid_hook(const basic_openid_message& inm,basic_openid_message& oum);
150 150
@@ -197,3 +197,3 @@ namespace opkele {
197 */ 197 */
198 virtual void setup_response(const params_t& pin,params_t& pout); 198 virtual void setup_response(const basic_openid_message& inm,basic_openid_message& oum);
199 199
diff --git a/include/opkele/types.h b/include/opkele/types.h
index de44a5c..d5ad258 100644
--- a/include/opkele/types.h
+++ b/include/opkele/types.h
@@ -13,2 +13,4 @@
13#include <set> 13#include <set>
14#include <list>
15#include <opkele/iterator.h>
14#include <opkele/tr1-mem.h> 16#include <opkele/tr1-mem.h>
@@ -22,2 +24,5 @@ namespace opkele {
22 using std::set; 24 using std::set;
25 using std::list;
26 using std::iterator;
27 using std::forward_iterator_tag;
23 28
@@ -113,2 +118,55 @@ namespace opkele {
113 118
119 class basic_openid_message {
120 public:
121 typedef list<string> fields_t;
122 typedef util::forward_iterator_proxy<
123 string,const string&,const string*
124 > fields_iterator;
125
126 basic_openid_message() { }
127 basic_openid_message(const basic_openid_message& x);
128 void copy_to(basic_openid_message& x) const;
129
130 virtual bool has_field(const string& n) const = 0;
131 virtual const string& get_field(const string& n) const = 0;
132
133 virtual bool has_ns(const string& uri) const;
134 virtual string get_ns(const string& uri) const;
135
136 virtual fields_iterator fields_begin() const = 0;
137 virtual fields_iterator fields_end() const = 0;
138
139 virtual string append_query(const string& url) const;
140 virtual string query_string() const;
141
142
143 virtual void reset_fields();
144 virtual void set_field(const string& n,const string& v);
145 virtual void reset_field(const string& n);
146
147 virtual void from_keyvalues(const string& kv);
148
149 void add_to_signed(const string& fields);
150 string find_ns(const string& uri,const char *pfx) const;
151 string allocate_ns(const string& uri,const char *pfx);
152 };
153
154 class openid_message_t : public basic_openid_message, public map<string,string> {
155 public:
156 openid_message_t() { }
157 openid_message_t(const basic_openid_message& x)
158 : basic_openid_message(x) { }
159
160 void copy_to(basic_openid_message& x) const;
161
162 bool has_field(const string& n) const;
163 const string& get_field(const string& n) const;
164 virtual fields_iterator fields_begin() const;
165 virtual fields_iterator fields_end() const;
166
167 void reset_fields();
168 void set_field(const string& n,const string& v);
169 void reset_field(const string& n);
170 };
171
114 /** 172 /**
@@ -116,3 +174,3 @@ namespace opkele {
116 */ 174 */
117 class params_t : public map<string,string> { 175 class params_t : public openid_message_t {
118 public: 176 public:
@@ -124,3 +182,4 @@ namespace opkele {
124 */ 182 */
125 bool has_param(const string& n) const; 183 bool has_param(const string& n) const {
184 return has_field(n); }
126 /** 185 /**
@@ -131,10 +190,4 @@ namespace opkele {
131 */ 190 */
132 const string& get_param(const string& n) const; 191 const string& get_param(const string& n) const {
133 /** 192 return get_field(n); }
134 * retrieve the parameter.
135 * @param n the parameter name
136 * @return the parameter value
137 * @throw failed_lookup if there is no such parameter
138 */
139 string& get_param(const string& n);
140 193
@@ -144,101 +197,9 @@ namespace opkele {
144 */ 197 */
145 void parse_keyvalues(const string& kv); 198 void parse_keyvalues(const string& kv) {
146 /** 199 from_keyvalues(kv); }
147 * sign the fields.
148 * @param secret the secret used for signing
149 * @param sig reference to the string, containing base64-encoded
150 * result
151 * @param slist the comma-separated list of fields to sign
152 * @param prefix the string to prepend to parameter names
153 */
154 void sign(secret_t secret,string& sig,const string& slist,const char *prefix=0) const;
155 200
156 /** 201 string append_query(const string& url,const char *prefix="openid.") const;
157 * append parameters to the URL as a GET-request parameters.
158 * @param url the base URL
159 * @param prefix the string to prepend to parameter names
160 * @return the ready-to-use location
161 */
162 string append_query(const string& url,const char *prefix = "openid.") const;
163 202
164 /**
165 * make up a query string suitable for use in GET and POST
166 * requests.
167 * @param prefix string to prened to parameter names
168 * @return query string
169 */
170 string query_string(const char *prefix = "openid.") const;
171 }; 203 };
172 204
173 /**
174 * dump the key/value pairs for the parameters to the stream.
175 * @param o output stream
176 * @param p the parameters
177 */
178 ostream& operator << (ostream& o,const params_t& p);
179
180 namespace xrd {
181
182 struct priority_compare {
183 inline bool operator()(long a,long b) const {
184 return (a<0) ? false : (b<0) ? true : (a<b);
185 }
186 };
187
188 template <typename _DT>
189 class priority_map : public multimap<long,_DT,priority_compare> {
190 typedef multimap<long,_DT,priority_compare> map_type;
191 public:
192
193 inline _DT& add(long priority,const _DT& d) {
194 return insert(typename map_type::value_type(priority,d))->second;
195 }
196 };
197
198 typedef priority_map<string> canonical_ids_t;
199 typedef priority_map<string> local_ids_t;
200 typedef set<string> types_t;
201 typedef priority_map<string> uris_t;
202
203 class service_t {
204 public:
205 types_t types;
206 uris_t uris;
207 local_ids_t local_ids;
208 string provider_id;
209
210 void clear() {
211 types.clear();
212 uris.clear(); local_ids.clear();
213 provider_id.clear();
214 }
215 };
216 typedef priority_map<service_t> services_t;
217
218 class XRD_t {
219 public:
220 time_t expires;
221
222 canonical_ids_t canonical_ids;
223 local_ids_t local_ids;
224 services_t services;
225 string provider_id;
226
227 void clear() {
228 expires = 0;
229 canonical_ids.clear(); local_ids.clear();
230 services.clear();
231 provider_id.clear();
232 }
233 bool empty() const {
234 return
235 canonical_ids.empty()
236 && local_ids.empty()
237 && services.empty();
238 }
239
240 };
241
242 }
243
244} 205}
diff --git a/include/opkele/util.h b/include/opkele/util.h
index 085c9e6..e9176b0 100644
--- a/include/opkele/util.h
+++ b/include/opkele/util.h
@@ -8,2 +8,3 @@
8#include <openssl/dh.h> 8#include <openssl/dh.h>
9#include <opkele/types.h>
9 10
@@ -138,2 +139,9 @@ namespace opkele {
138 string rfc_3986_normalize_uri(const string& uri); 139 string rfc_3986_normalize_uri(const string& uri);
140
141 string& strip_uri_fragment_part(string& uri);
142
143 string abi_demangle(const char* mn);
144
145 string base64_signature(const assoc_t& assoc,const basic_openid_message& om);
146
139 } 147 }