summaryrefslogtreecommitdiffabout
Unidiff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--include/opkele/basic_rp.h36
-rw-r--r--lib/basic_rp.cc29
2 files changed, 63 insertions, 2 deletions
diff --git a/include/opkele/basic_rp.h b/include/opkele/basic_rp.h
index d5356aa..d096e0a 100644
--- a/include/opkele/basic_rp.h
+++ b/include/opkele/basic_rp.h
@@ -1,27 +1,63 @@
1#ifndef __OPKELE_BASIC_RP_H 1#ifndef __OPKELE_BASIC_RP_H
2#define __OPKELE_BASIC_RP_H 2#define __OPKELE_BASIC_RP_H
3 3
4#include <string> 4#include <string>
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_RP { 11 class basic_RP {
12 public: 12 public:
13 /**
14 * Claimed identifier from a parsed id_res message.
15 */
16 string claimed_id;
17 /**
18 * OP-Local identifier from a parsed id_res message.
19 */
20 string identity;
13 21
14 virtual ~basic_RP() { } 22 virtual ~basic_RP() { }
15 23
24 void reset_vars();
25
26 /**
27 * @name Assertion information retrieval
28 * Retrieval of the information passed with openid message
29 * @{
30 */
31 /**
32 * Find out if the assertion is about identity
33 * @return true if so
34 */
35 bool has_identity() const;
36 /**
37 * Get claimed identifier supplied with the request
38 * @return claimed identifier
39 * @throw non_identity if request is not about identity
40 */
41 const string& get_claimed_id() const;
42 /**
43 * Get the identity (OP-Local identifier) confirmed
44 * @return identity
45 * @throw non_identity if request is not about identity
46 */
47 const string& get_identity() const;
48 /**
49 * @}
50 */
51
16 /** 52 /**
17 * @name Global persistent store API 53 * @name Global persistent store API
18 * These are functions related to the associations with OP storage 54 * These are functions related to the associations with OP storage
19 * and retrieval and nonce records. They provide an interface to 55 * and retrieval and nonce records. They provide an interface to
20 * the persistent storage which is shared by all sessions. If the 56 * the persistent storage which is shared by all sessions. If the
21 * implementor prefers the dumb mode instead, the function should 57 * implementor prefers the dumb mode instead, the function should
22 * throw dumb_RP exception instead. 58 * throw dumb_RP exception instead.
23 * @see opkele::dumb_RP 59 * @see opkele::dumb_RP
24 * @{ 60 * @{
25 */ 61 */
26 /** 62 /**
27 * Store association and return allocated association object. 63 * Store association and return allocated association object.
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc
index e65d9fb..3357d0b 100644
--- a/lib/basic_rp.cc
+++ b/lib/basic_rp.cc
@@ -1,25 +1,44 @@
1#include <cassert> 1#include <cassert>
2#include <openssl/sha.h> 2#include <openssl/sha.h>
3#include <openssl/hmac.h> 3#include <openssl/hmac.h>
4#include <opkele/basic_rp.h> 4#include <opkele/basic_rp.h>
5#include <opkele/exception.h> 5#include <opkele/exception.h>
6#include <opkele/uris.h> 6#include <opkele/uris.h>
7#include <opkele/data.h> 7#include <opkele/data.h>
8#include <opkele/util.h> 8#include <opkele/util.h>
9#include <opkele/util-internal.h> 9#include <opkele/util-internal.h>
10#include <opkele/curl.h> 10#include <opkele/curl.h>
11#include <opkele/debug.h>
11 12
12namespace opkele { 13namespace opkele {
13 14
15 void basic_RP::reset_vars() {
16 claimed_id.clear(); identity.clear();
17 }
18
19 const string& basic_RP::get_claimed_id() const {
20 if(claimed_id.empty())
21 throw non_identity(OPKELE_CP_ "attempting to retreive claimed_id of non-identity assertion");
22 assert(!identity.empty());
23 return claimed_id;
24 }
25
26 const string& basic_RP::get_identity() const {
27 if(identity.empty())
28 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related assertion");
29 assert(!claimed_id.empty());
30 return identity;
31 }
32
14 static void dh_get_secret( 33 static void dh_get_secret(
15 secret_t& secret, const basic_openid_message& om, 34 secret_t& secret, const basic_openid_message& om,
16 const char *exp_assoc, const char *exp_sess, 35 const char *exp_assoc, const char *exp_sess,
17 util::dh_t& dh, 36 util::dh_t& dh,
18 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), 37 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*),
19 size_t exp_s_len) try { 38 size_t exp_s_len) try {
20 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) 39 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess)
21 throw bad_input(OPKELE_CP_ "Unexpected associate response"); 40 throw bad_input(OPKELE_CP_ "Unexpected associate response");
22 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); 41 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public"));
23 vector<unsigned char> ck(DH_size(dh)+1); 42 vector<unsigned char> ck(DH_size(dh)+1);
24 unsigned char *ckptr = &(ck.front())+1; 43 unsigned char *ckptr = &(ck.front())+1;
25 int cklen = DH_compute_key(ckptr,s_pub,dh); 44 int cklen = DH_compute_key(ckptr,s_pub,dh);
@@ -187,24 +206,25 @@ namespace opkele {
187 }else{ 206 }else{
188 if(eq==string::npos || eq>am) { 207 if(eq==string::npos || eq>am) {
189 p[""] = u.substr(q,eq-q); 208 p[""] = u.substr(q,eq-q);
190 }else{ 209 }else{
191 p[u.substr(q,eq-q)] = u.substr(eq+1,am-eq-1); 210 p[u.substr(q,eq-q)] = u.substr(eq+1,am-eq-1);
192 } 211 }
193 q = ++am; 212 q = ++am;
194 } 213 }
195 } 214 }
196 } 215 }
197 216
198 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) { 217 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) {
218 reset_vars();
199 bool o2 = om.has_field("ns") 219 bool o2 = om.has_field("ns")
200 && om.get_field("ns")==OIURI_OPENID20; 220 && om.get_field("ns")==OIURI_OPENID20;
201 if( (!o2) && om.has_field("user_setup_url")) 221 if( (!o2) && om.has_field("user_setup_url"))
202 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided", 222 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided",
203 om.get_field("user_setup_url")); 223 om.get_field("user_setup_url"));
204 string m = om.get_field("mode"); 224 string m = om.get_field("mode");
205 if(o2 && m=="setup_needed") 225 if(o2 && m=="setup_needed")
206 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided"); 226 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided");
207 if(m=="cancel") 227 if(m=="cancel")
208 throw id_res_cancel(OPKELE_CP_ "authentication cancelled"); 228 throw id_res_cancel(OPKELE_CP_ "authentication cancelled");
209 bool go_dumb=false; 229 bool go_dumb=false;
210 try { 230 try {
@@ -262,30 +282,35 @@ namespace opkele {
262 throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url"); 282 throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url");
263 map<string,string> tp; parse_query(turl,tq,tp); 283 map<string,string> tp; parse_query(turl,tq,tp);
264 map<string,string> rp; parse_query(rurl,rq,rp); 284 map<string,string> rp; parse_query(rurl,rq,rp);
265 for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) { 285 for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) {
266 map<string,string>::const_iterator tpi = tp.find(rpi->first); 286 map<string,string>::const_iterator tpi = tp.find(rpi->first);
267 if(tpi==tp.end()) 287 if(tpi==tp.end())
268 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request"); 288 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request");
269 if(tpi->second!=rpi->second) 289 if(tpi->second!=rpi->second)
270 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request"); 290 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request");
271 } 291 }
272 292
273 if(om.has_field("claimed_id")) { 293 if(om.has_field("claimed_id")) {
294 claimed_id = om.get_field("claimed_id");
295 identity = om.get_field("identity");
274 verify_OP( 296 verify_OP(
275 om.get_field("op_endpoint"), 297 om.get_field("op_endpoint"),
276 om.get_field("claimed_id"), 298 claimed_id, identity );
277 om.get_field("identity") );
278 } 299 }
279 300
301 }else{
302 claimed_id = get_endpoint().claimed_id;
303 /* TODO: check if this is the identity we asked for */
304 identity = om.get_field("identity");
280 } 305 }
281 if(ext) ext->rp_id_res_hook(om,signeds); 306 if(ext) ext->rp_id_res_hook(om,signeds);
282 } 307 }
283 308
284 void basic_RP::check_authentication(const string& OP, 309 void basic_RP::check_authentication(const string& OP,
285 const basic_openid_message& om){ 310 const basic_openid_message& om){
286 openid_message_t res; 311 openid_message_t res;
287 static const string checkauthmode = "check_authentication"; 312 static const string checkauthmode = "check_authentication";
288 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP); 313 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP);
289 if(res.has_field("is_valid")) { 314 if(res.has_field("is_valid")) {
290 if(res.get_field("is_valid")=="true") { 315 if(res.get_field("is_valid")=="true") {
291 if(res.has_field("invalidate_handle")) 316 if(res.has_field("invalidate_handle"))