summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-02-08 21:02:26 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-08 21:02:26 (UTC)
commit9e902e373ba72fd8725c5a1ffdfdc0447b664369 (patch) (unidiff)
tree5006b406209f13f684fbce235e470252386da818
parenta62ccf212acb27a092a48d3af8ee0bfb3efdb666 (diff)
downloadlibopkele-9e902e373ba72fd8725c5a1ffdfdc0447b664369.zip
libopkele-9e902e373ba72fd8725c5a1ffdfdc0447b664369.tar.gz
libopkele-9e902e373ba72fd8725c5a1ffdfdc0447b664369.tar.bz2
renamed basic_op class to basic_OP
and doxygenated basic_OP a bit. Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/basic_op.h119
-rw-r--r--include/opkele/verify_op.h2
-rw-r--r--lib/basic_op.cc38
-rw-r--r--lib/verify_op.cc2
-rw-r--r--test/OP.cc2
5 files changed, 134 insertions, 29 deletions
diff --git a/include/opkele/basic_op.h b/include/opkele/basic_op.h
index 5bba1bf..4daed02 100644
--- a/include/opkele/basic_op.h
+++ b/include/opkele/basic_op.h
@@ -5,13 +5,13 @@
5#include <opkele/types.h> 5#include <opkele/types.h>
6#include <opkele/extension.h> 6#include <opkele/extension.h>
7 7
8namespace opkele { 8namespace opkele {
9 using std::string; 9 using std::string;
10 10
11 class basic_op { 11 class basic_OP {
12 public: 12 public:
13 mode_t mode; 13 mode_t mode;
14 assoc_t assoc; 14 assoc_t assoc;
15 bool openid2; 15 bool openid2;
16 string return_to; 16 string return_to;
17 string realm; 17 string realm;
@@ -32,38 +32,143 @@ namespace opkele {
32 32
33 bool is_id_select() const; 33 bool is_id_select() const;
34 34
35 void select_identity(const string& c,const string& i); 35 void select_identity(const string& c,const string& i);
36 void set_claimed_id(const string& c); 36 void set_claimed_id(const string& c);
37 37
38 /** @name OpenID operations
39 * @{
40 */
41 /**
42 * Establish association with RP
43 * @param oum reply message
44 * @param inm request message
45 */
38 basic_openid_message& associate( 46 basic_openid_message& associate(
39 basic_openid_message& oum, 47 basic_openid_message& oum,
40 const basic_openid_message& inm); 48 const basic_openid_message& inm);
41 49
50 /**
51 * Parse the checkid_* request. The function parses input message,
52 * retrieves the information needed for further processing,
53 * verifies what can be verified at this stage.
54 * @param inm incoming OpenID message
55 * @param ext extension/chain of extensions supported
56 */
42 void checkid_(const basic_openid_message& inm,extension_t *ext=0); 57 void checkid_(const basic_openid_message& inm,extension_t *ext=0);
58 /**
59 * Build and sign a positive assertion message
60 * @param om outpu OpenID message
61 * @param ext extension/chain of extensions supported
62 * @return reference to om
63 */
43 basic_openid_message& id_res(basic_openid_message& om, 64 basic_openid_message& id_res(basic_openid_message& om,
44 extension_t *ext=0); 65 extension_t *ext=0);
66 /**
67 * Build a 'cancel' negative assertion
68 * @param om output OpenID message
69 * @return reference to om
70 */
45 basic_openid_message& cancel(basic_openid_message& om); 71 basic_openid_message& cancel(basic_openid_message& om);
72 /**
73 * Build an 'error' reply
74 * @param om output OpenID message
75 * @param error a human-readable message indicating the cause
76 * @param contact contact address for the server administrator (can be empty)
77 * @param reference a reference token (can be empty)
78 * @return reference to om
79 */
46 basic_openid_message& error(basic_openid_message& om, 80 basic_openid_message& error(basic_openid_message& om,
47 const string& error,const string& contact, 81 const string& error,const string& contact,
48 const string& reference ); 82 const string& reference );
83 /**
84 * Build a setup_needed reply to checkid_immediate request
85 * @param oum output OpenID message
86 * @param inm incoming OpenID request being processed
87 * @return reference to oum
88 */
49 basic_openid_message& setup_needed( 89 basic_openid_message& setup_needed(
50 basic_openid_message& oum,const basic_openid_message& inm); 90 basic_openid_message& oum,const basic_openid_message& inm);
51 91
92 /**
93 * Process check_authentication request
94 * @param oum output OpenID message
95 * @param inm incoming request
96 * @return reference to oum
97 */
52 basic_openid_message& check_authentication( 98 basic_openid_message& check_authentication(
53 basic_openid_message& oum,const basic_openid_message& inm); 99 basic_openid_message& oum,const basic_openid_message& inm);
54 100 /**
101 * @}
102 */
103
104 /**
105 * Verify return_to url. The default implementation checks whether
106 * return_to URI matches the realm
107 * @throw bad_realm in case of invalid realm
108 * @throw bad_return_to if return_to doesn't match the realm
109 * @see verify_op::verify_return_to()
110 */
55 virtual void verify_return_to(); 111 virtual void verify_return_to();
56 112
57 virtual assoc_t alloc_assoc(const string& t,size_t kl,bool sl) = 0; 113 /**
58 virtual assoc_t retrieve_assoc(const string& h) = 0; 114 * @name Global persistent store API
59 115 * These functions are related to the associations with RPs storage
60 virtual string& alloc_nonce(string& nonce,bool sl) = 0; 116 * and retrieval and nonce management.
117 * @{
118 */
119 /**
120 * Allocate association.
121 * @param type association type
122 * @param kl association key length
123 * @param sl true if the association is stateless
124 * @return association object
125 */
126 virtual assoc_t alloc_assoc(const string& type,size_t kl,bool sl) = 0;
127 /**
128 * Retrieve valid unexpired association
129 * @param handle association handle
130 * @return association object
131 */
132 virtual assoc_t retrieve_assoc(const string& handle) = 0;
133 /**
134 * Allocate nonce.
135 * @param nonce input-output parameter containing timestamp part of
136 * the nonce on input
137 * @param sl true if the nonce is
138 * @return reference to nonce
139 * @throw failed_lookup if no such valid unexpired association
140 * could be retrieved
141 */
142 virtual string& alloc_nonce(string& nonce) = 0;
143 /**
144 * Check nonce validity
145 * @param nonce nonce to check
146 * @return true if nonce found and isn't yet invalidated
147 */
61 virtual bool check_nonce(const string& nonce) = 0; 148 virtual bool check_nonce(const string& nonce) = 0;
149 /**
150 * Invalidate nonce
151 * @param nonce nonce to check
152 */
62 virtual void invalidate_nonce(const string& nonce) = 0; 153 virtual void invalidate_nonce(const string& nonce) = 0;
63 154 /**
155 * @}
156 */
157
158 /**
159 * @name Site particulars API
160 * @{
161 */
162 /**
163 * Query the absolute URL of the op endpoint
164 * @return fully qualified url of the OP endpoint
165 */
64 virtual const string get_op_endpoint() const = 0; 166 virtual const string get_op_endpoint() const = 0;
167 /**
168 * @}
169 */
65 170
66 }; 171 };
67} 172}
68 173
69#endif /* __OPKELE_BASIC_OP_H */ 174#endif /* __OPKELE_BASIC_OP_H */
diff --git a/include/opkele/verify_op.h b/include/opkele/verify_op.h
index f5c97b2..6c3c386 100644
--- a/include/opkele/verify_op.h
+++ b/include/opkele/verify_op.h
@@ -2,13 +2,13 @@
2#define __OPKELE_VERIFY_OP_H 2#define __OPKELE_VERIFY_OP_H
3 3
4#include <opkele/basic_op.h> 4#include <opkele/basic_op.h>
5 5
6namespace opkele { 6namespace opkele {
7 7
8 class verify_op : public basic_op { 8 class verify_op : public basic_OP {
9 public: 9 public:
10 10
11 void verify_return_to(); 11 void verify_return_to();
12 }; 12 };
13 13
14} 14}
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index 7a2dbd2..18446dc 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -7,61 +7,61 @@
7#include <opkele/exception.h> 7#include <opkele/exception.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/uris.h> 9#include <opkele/uris.h>
10 10
11namespace opkele { 11namespace opkele {
12 12
13 void basic_op::reset_vars() { 13 void basic_OP::reset_vars() {
14 assoc.reset(); 14 assoc.reset();
15 return_to.clear(); realm.clear(); 15 return_to.clear(); realm.clear();
16 claimed_id.clear(); identity.clear(); 16 claimed_id.clear(); identity.clear();
17 invalidate_handle.clear(); 17 invalidate_handle.clear();
18 } 18 }
19 19
20 bool basic_op::has_return_to() const { 20 bool basic_OP::has_return_to() const {
21 return !return_to.empty(); 21 return !return_to.empty();
22 } 22 }
23 const string& basic_op::get_return_to() const { 23 const string& basic_OP::get_return_to() const {
24 if(return_to.empty()) 24 if(return_to.empty())
25 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request"); 25 throw no_return_to(OPKELE_CP_ "No return_to URL provided with request");
26 return return_to; 26 return return_to;
27 } 27 }
28 28
29 const string& basic_op::get_realm() const { 29 const string& basic_OP::get_realm() const {
30 assert(!realm.empty()); 30 assert(!realm.empty());
31 return realm; 31 return realm;
32 } 32 }
33 33
34 bool basic_op::has_identity() const { 34 bool basic_OP::has_identity() const {
35 return !identity.empty(); 35 return !identity.empty();
36 } 36 }
37 const string& basic_op::get_claimed_id() const { 37 const string& basic_OP::get_claimed_id() const {
38 if(claimed_id.empty()) 38 if(claimed_id.empty())
39 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request"); 39 throw non_identity(OPKELE_CP_ "attempting to retrieve claimed_id of non-identity related request");
40 assert(!identity.empty()); 40 assert(!identity.empty());
41 return claimed_id; 41 return claimed_id;
42 } 42 }
43 const string& basic_op::get_identity() const { 43 const string& basic_OP::get_identity() const {
44 if(identity.empty()) 44 if(identity.empty())
45 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request"); 45 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related request");
46 assert(!claimed_id.empty()); 46 assert(!claimed_id.empty());
47 return identity; 47 return identity;
48 } 48 }
49 49
50 bool basic_op::is_id_select() const { 50 bool basic_OP::is_id_select() const {
51 return identity==IDURI_SELECT20; 51 return identity==IDURI_SELECT20;
52 } 52 }
53 53
54 void basic_op::select_identity(const string& c,const string& i) { 54 void basic_OP::select_identity(const string& c,const string& i) {
55 claimed_id = c; identity = i; 55 claimed_id = c; identity = i;
56 } 56 }
57 void basic_op::set_claimed_id(const string& c) { 57 void basic_OP::set_claimed_id(const string& c) {
58 claimed_id = c; 58 claimed_id = c;
59 } 59 }
60 60
61 basic_openid_message& basic_op::associate( 61 basic_openid_message& basic_OP::associate(
62 basic_openid_message& oum, 62 basic_openid_message& oum,
63 const basic_openid_message& inm) try { 63 const basic_openid_message& inm) try {
64 assert(inm.get_field("mode")=="associate"); 64 assert(inm.get_field("mode")=="associate");
65 util::dh_t dh; 65 util::dh_t dh;
66 util::bignum_t c_pub; 66 util::bignum_t c_pub;
67 unsigned char key_digest[SHA256_DIGEST_LENGTH]; 67 unsigned char key_digest[SHA256_DIGEST_LENGTH];
@@ -128,13 +128,13 @@ namespace opkele {
128 oum.set_field("error_code","unsupported-type"); 128 oum.set_field("error_code","unsupported-type");
129 oum.set_field("session_type","DH-SHA256"); 129 oum.set_field("session_type","DH-SHA256");
130 oum.set_field("assoc_type","HMAC-SHA256"); 130 oum.set_field("assoc_type","HMAC-SHA256");
131 return oum; 131 return oum;
132 } 132 }
133 133
134 void basic_op::checkid_(const basic_openid_message& inm, 134 void basic_OP::checkid_(const basic_openid_message& inm,
135 extension_t *ext) { 135 extension_t *ext) {
136 reset_vars(); 136 reset_vars();
137 string mode = inm.get_field("mode"); 137 string mode = inm.get_field("mode");
138 if(mode=="checkid_setup") 138 if(mode=="checkid_setup")
139 mode = mode_checkid_setup; 139 mode = mode_checkid_setup;
140 else if(mode=="checkid_immediate") 140 else if(mode=="checkid_immediate")
@@ -190,13 +190,13 @@ namespace opkele {
190 "claimed_id and identity must be either both present or both absent"); 190 "claimed_id and identity must be either both present or both absent");
191 } 191 }
192 verify_return_to(); 192 verify_return_to();
193 if(ext) ext->op_checkid_hook(inm); 193 if(ext) ext->op_checkid_hook(inm);
194 } 194 }
195 195
196 basic_openid_message& basic_op::id_res(basic_openid_message& om, 196 basic_openid_message& basic_OP::id_res(basic_openid_message& om,
197 extension_t *ext) { 197 extension_t *ext) {
198 assert(!return_to.empty()); 198 assert(!return_to.empty());
199 assert(!is_id_select()); 199 assert(!is_id_select());
200 if(!assoc) { 200 if(!assoc) {
201 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true); 201 assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true);
202 } 202 }
@@ -215,44 +215,44 @@ namespace opkele {
215 om.set_field("identity",identity); 215 om.set_field("identity",identity);
216 om.set_field("claimed_id",claimed_id); 216 om.set_field("claimed_id",claimed_id);
217 ats += ",identity,claimed_id"; 217 ats += ",identity,claimed_id";
218 } 218 }
219 om.set_field("return_to",return_to); 219 om.set_field("return_to",return_to);
220 string nonce = w3timestr; 220 string nonce = w3timestr;
221 om.set_field("response_nonce",alloc_nonce(nonce,assoc->stateless())); 221 om.set_field("response_nonce",alloc_nonce(nonce));
222 if(!invalidate_handle.empty()) { 222 if(!invalidate_handle.empty()) {
223 om.set_field("invalidate_handle",invalidate_handle); 223 om.set_field("invalidate_handle",invalidate_handle);
224 ats += ",invalidate_handle"; 224 ats += ",invalidate_handle";
225 } 225 }
226 om.set_field("assoc_handle",assoc->handle()); 226 om.set_field("assoc_handle",assoc->handle());
227 om.add_to_signed(ats); 227 om.add_to_signed(ats);
228 if(ext) ext->op_id_res_hook(om); 228 if(ext) ext->op_id_res_hook(om);
229 om.set_field("sig",util::base64_signature(assoc,om)); 229 om.set_field("sig",util::base64_signature(assoc,om));
230 return om; 230 return om;
231 } 231 }
232 232
233 basic_openid_message& basic_op::cancel(basic_openid_message& om) { 233 basic_openid_message& basic_OP::cancel(basic_openid_message& om) {
234 assert(!return_to.empty()); 234 assert(!return_to.empty());
235 om.set_field("ns",OIURI_OPENID20); 235 om.set_field("ns",OIURI_OPENID20);
236 om.set_field("mode","cancel"); 236 om.set_field("mode","cancel");
237 return om; 237 return om;
238 } 238 }
239 239
240 basic_openid_message& basic_op::error(basic_openid_message& om, 240 basic_openid_message& basic_OP::error(basic_openid_message& om,
241 const string& error,const string& contact, 241 const string& error,const string& contact,
242 const string& reference ) { 242 const string& reference ) {
243 assert(!return_to.empty()); 243 assert(!return_to.empty());
244 om.set_field("ns",OIURI_OPENID20); 244 om.set_field("ns",OIURI_OPENID20);
245 om.set_field("mode","error"); 245 om.set_field("mode","error");
246 om.set_field("error",error); 246 om.set_field("error",error);
247 om.set_field("contact",contact); 247 om.set_field("contact",contact);
248 om.set_field("reference",reference); 248 om.set_field("reference",reference);
249 return om; 249 return om;
250 } 250 }
251 251
252 basic_openid_message& basic_op::setup_needed( 252 basic_openid_message& basic_OP::setup_needed(
253 basic_openid_message& oum,const basic_openid_message& inm) { 253 basic_openid_message& oum,const basic_openid_message& inm) {
254 assert(mode==mode_checkid_immediate); 254 assert(mode==mode_checkid_immediate);
255 assert(!return_to.empty()); 255 assert(!return_to.empty());
256 if(openid2) { 256 if(openid2) {
257 oum.set_field("ns",OIURI_OPENID20); 257 oum.set_field("ns",OIURI_OPENID20);
258 oum.set_field("mode","setup_needed"); 258 oum.set_field("mode","setup_needed");
@@ -263,13 +263,13 @@ namespace opkele {
263 util::change_mode_message_proxy(inm,setupmode) 263 util::change_mode_message_proxy(inm,setupmode)
264 .append_query(get_op_endpoint())); 264 .append_query(get_op_endpoint()));
265 } 265 }
266 return oum; 266 return oum;
267 } 267 }
268 268
269 basic_openid_message& basic_op::check_authentication( 269 basic_openid_message& basic_OP::check_authentication(
270 basic_openid_message& oum, 270 basic_openid_message& oum,
271 const basic_openid_message& inm) try { 271 const basic_openid_message& inm) try {
272 assert(inm.get_field("mode")=="check_authentication"); 272 assert(inm.get_field("mode")=="check_authentication");
273 oum.reset_fields(); 273 oum.reset_fields();
274 oum.set_field("ns",OIURI_OPENID20); 274 oum.set_field("ns",OIURI_OPENID20);
275 bool o2; 275 bool o2;
@@ -317,13 +317,13 @@ namespace opkele {
317 return oum; 317 return oum;
318 }catch(failed_check_authentication& ) { 318 }catch(failed_check_authentication& ) {
319 oum.set_field("is_valid","false"); 319 oum.set_field("is_valid","false");
320 return oum; 320 return oum;
321 } 321 }
322 322
323 void basic_op::verify_return_to() { 323 void basic_OP::verify_return_to() {
324 if(realm.find('#')!=string::npos) 324 if(realm.find('#')!=string::npos)
325 throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment"); 325 throw opkele::bad_realm(OPKELE_CP_ "authentication realm contains URI fragment");
326 if(!util::uri_matches_realm(return_to,realm)) 326 if(!util::uri_matches_realm(return_to,realm))
327 throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match realm"); 327 throw bad_return_to(OPKELE_CP_ "return_to URL doesn't match realm");
328 } 328 }
329 329
diff --git a/lib/verify_op.cc b/lib/verify_op.cc
index e7c26b5..0beca2d 100644
--- a/lib/verify_op.cc
+++ b/lib/verify_op.cc
@@ -30,13 +30,13 @@ namespace opkele {
30 30
31 RP_verifier& operator++() { ++seen; return *this; } 31 RP_verifier& operator++() { ++seen; return *this; }
32 RP_verifier& operator++(int) { +seen; return *this; } 32 RP_verifier& operator++(int) { +seen; return *this; }
33 }; 33 };
34 34
35 void verify_op::verify_return_to() { 35 void verify_op::verify_return_to() {
36 basic_op::verify_return_to(); 36 basic_OP::verify_return_to();
37 try { 37 try {
38 RP_verifier rpv(return_to); 38 RP_verifier rpv(return_to);
39 string drealm = realm; 39 string drealm = realm;
40 string::size_type csss = drealm.find("://*."); 40 string::size_type csss = drealm.find("://*.");
41 if(csss==4 || csss==5) 41 if(csss==4 || csss==5)
42 drealm.replace(csss+3,1,"www"); 42 drealm.replace(csss+3,1,"www");
diff --git a/test/OP.cc b/test/OP.cc
index c919d7f..ce54d92 100644
--- a/test/OP.cc
+++ b/test/OP.cc
@@ -158,13 +158,13 @@ class example_op_t : public opkele::verify_op {
158 return opkele::assoc_t(new opkele::association( 158 return opkele::assoc_t(new opkele::association(
159 "", h, T.get(1,1,nc), secret, 159 "", h, T.get(1,1,nc), secret,
160 strtol(T.get(1,4,nc),0,0), 160 strtol(T.get(1,4,nc),0,0),
161 strtol(T.get(1,3,nc),0,0) )); 161 strtol(T.get(1,3,nc),0,0) ));
162 } 162 }
163 163
164 string& alloc_nonce(string& nonce,bool stateless) { 164 string& alloc_nonce(string& nonce) {
165 uuid_t uuid; uuid_generate(uuid); 165 uuid_t uuid; uuid_generate(uuid);
166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid)); 166 nonce += opkele::util::encode_base64(uuid,sizeof(uuid));
167 sqlite3_mem_t<char*> 167 sqlite3_mem_t<char*>
168 S = sqlite3_mprintf( 168 S = sqlite3_mprintf(
169 "INSERT INTO nonces" 169 "INSERT INTO nonces"
170 " (n_once) VALUES (%Q)", 170 " (n_once) VALUES (%Q)",