summaryrefslogtreecommitdiffabout
authorMichael Krelin <hacker@klever.net>2008-11-12 20:07:32 (UTC)
committer Michael Krelin <hacker@klever.net>2008-11-12 20:07:32 (UTC)
commit54f0c8a8f1a85669e623f04a209928daee5c59cc (patch) (unidiff)
tree9e6cde38964ef70b9130d46349e0aa97dc0acb60
parent4522de61114018633f66492e2e9977cdb3108098 (diff)
downloadlibopkele-54f0c8a8f1a85669e623f04a209928daee5c59cc.zip
libopkele-54f0c8a8f1a85669e623f04a209928daee5c59cc.tar.gz
libopkele-54f0c8a8f1a85669e623f04a209928daee5c59cc.tar.bz2
build fix: added missing include
Thanks to Jim Downing for spotting it! Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/basic_rp.cc1
1 files changed, 1 insertions, 0 deletions
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc
index 3357d0b..3cad71c 100644
--- a/lib/basic_rp.cc
+++ b/lib/basic_rp.cc
@@ -1,325 +1,326 @@
1#include <sys/types.h>
1#include <cassert> 2#include <cassert>
2#include <openssl/sha.h> 3#include <openssl/sha.h>
3#include <openssl/hmac.h> 4#include <openssl/hmac.h>
4#include <opkele/basic_rp.h> 5#include <opkele/basic_rp.h>
5#include <opkele/exception.h> 6#include <opkele/exception.h>
6#include <opkele/uris.h> 7#include <opkele/uris.h>
7#include <opkele/data.h> 8#include <opkele/data.h>
8#include <opkele/util.h> 9#include <opkele/util.h>
9#include <opkele/util-internal.h> 10#include <opkele/util-internal.h>
10#include <opkele/curl.h> 11#include <opkele/curl.h>
11#include <opkele/debug.h> 12#include <opkele/debug.h>
12 13
13namespace opkele { 14namespace opkele {
14 15
15 void basic_RP::reset_vars() { 16 void basic_RP::reset_vars() {
16 claimed_id.clear(); identity.clear(); 17 claimed_id.clear(); identity.clear();
17 } 18 }
18 19
19 const string& basic_RP::get_claimed_id() const { 20 const string& basic_RP::get_claimed_id() const {
20 if(claimed_id.empty()) 21 if(claimed_id.empty())
21 throw non_identity(OPKELE_CP_ "attempting to retreive claimed_id of non-identity assertion"); 22 throw non_identity(OPKELE_CP_ "attempting to retreive claimed_id of non-identity assertion");
22 assert(!identity.empty()); 23 assert(!identity.empty());
23 return claimed_id; 24 return claimed_id;
24 } 25 }
25 26
26 const string& basic_RP::get_identity() const { 27 const string& basic_RP::get_identity() const {
27 if(identity.empty()) 28 if(identity.empty())
28 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related assertion"); 29 throw non_identity(OPKELE_CP_ "attempting to retrieve identity of non-identity related assertion");
29 assert(!claimed_id.empty()); 30 assert(!claimed_id.empty());
30 return identity; 31 return identity;
31 } 32 }
32 33
33 static void dh_get_secret( 34 static void dh_get_secret(
34 secret_t& secret, const basic_openid_message& om, 35 secret_t& secret, const basic_openid_message& om,
35 const char *exp_assoc, const char *exp_sess, 36 const char *exp_assoc, const char *exp_sess,
36 util::dh_t& dh, 37 util::dh_t& dh,
37 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*), 38 size_t d_len, unsigned char *(*d_fun)(const unsigned char*,size_t,unsigned char*),
38 size_t exp_s_len) try { 39 size_t exp_s_len) try {
39 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess) 40 if(om.get_field("assoc_type")!=exp_assoc || om.get_field("session_type")!=exp_sess)
40 throw bad_input(OPKELE_CP_ "Unexpected associate response"); 41 throw bad_input(OPKELE_CP_ "Unexpected associate response");
41 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public")); 42 util::bignum_t s_pub = util::base64_to_bignum(om.get_field("dh_server_public"));
42 vector<unsigned char> ck(DH_size(dh)+1); 43 vector<unsigned char> ck(DH_size(dh)+1);
43 unsigned char *ckptr = &(ck.front())+1; 44 unsigned char *ckptr = &(ck.front())+1;
44 int cklen = DH_compute_key(ckptr,s_pub,dh); 45 int cklen = DH_compute_key(ckptr,s_pub,dh);
45 if(cklen<0) 46 if(cklen<0)
46 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()"); 47 throw exception_openssl(OPKELE_CP_ "failed to DH_compute_key()");
47 if(cklen && (*ckptr)&0x80) { 48 if(cklen && (*ckptr)&0x80) {
48 (*(--ckptr))=0; ++cklen; } 49 (*(--ckptr))=0; ++cklen; }
49 assert(d_len<=SHA256_DIGEST_LENGTH); 50 assert(d_len<=SHA256_DIGEST_LENGTH);
50 unsigned char key_digest[SHA256_DIGEST_LENGTH]; 51 unsigned char key_digest[SHA256_DIGEST_LENGTH];
51 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key")); 52 secret.enxor_from_base64((*d_fun)(ckptr,cklen,key_digest),om.get_field("enc_mac_key"));
52 if(secret.size()!=exp_s_len) 53 if(secret.size()!=exp_s_len)
53 throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type"); 54 throw bad_input(OPKELE_CP_ "Secret length isn't consistent with association type");
54 }catch(opkele::failed_lookup& ofl) { 55 }catch(opkele::failed_lookup& ofl) {
55 throw bad_input(OPKELE_CP_ "Incoherent response from OP"); 56 throw bad_input(OPKELE_CP_ "Incoherent response from OP");
56 } OPKELE_RETHROW 57 } OPKELE_RETHROW
57 58
58 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) { 59 static void direct_request(basic_openid_message& oum,const basic_openid_message& inm,const string& OP) {
59 util::curl_pick_t curl = util::curl_pick_t::easy_init(); 60 util::curl_pick_t curl = util::curl_pick_t::easy_init();
60 if(!curl) 61 if(!curl)
61 throw exception_curl(OPKELE_CP_ "failed to initialize curl"); 62 throw exception_curl(OPKELE_CP_ "failed to initialize curl");
62 string request = inm.query_string(); 63 string request = inm.query_string();
63 CURLcode r; 64 CURLcode r;
64 (r=curl.misc_sets()) 65 (r=curl.misc_sets())
65 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str())) 66 || (r=curl.easy_setopt(CURLOPT_URL,OP.c_str()))
66 || (r=curl.easy_setopt(CURLOPT_POST,1)) 67 || (r=curl.easy_setopt(CURLOPT_POST,1))
67 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data())) 68 || (r=curl.easy_setopt(CURLOPT_POSTFIELDS,request.data()))
68 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length())) 69 || (r=curl.easy_setopt(CURLOPT_POSTFIELDSIZE,request.length()))
69 || (r=curl.set_write()); 70 || (r=curl.set_write());
70 if(r) 71 if(r)
71 throw exception_curl(OPKELE_CP_ "failed to set curly options",r); 72 throw exception_curl(OPKELE_CP_ "failed to set curly options",r);
72 if( (r=curl.easy_perform()) ) 73 if( (r=curl.easy_perform()) )
73 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r); 74 throw exception_curl(OPKELE_CP_ "failed to perform curly request",r);
74 oum.from_keyvalues(curl.response); 75 oum.from_keyvalues(curl.response);
75 } 76 }
76 77
77 78
78 assoc_t basic_RP::associate(const string& OP) { 79 assoc_t basic_RP::associate(const string& OP) {
79 util::dh_t dh = DH_new(); 80 util::dh_t dh = DH_new();
80 if(!dh) 81 if(!dh)
81 throw exception_openssl(OPKELE_CP_ "failed to DH_new()"); 82 throw exception_openssl(OPKELE_CP_ "failed to DH_new()");
82 dh->p = util::dec_to_bignum(data::_default_p); 83 dh->p = util::dec_to_bignum(data::_default_p);
83 dh->g = util::dec_to_bignum(data::_default_g); 84 dh->g = util::dec_to_bignum(data::_default_g);
84 if(!DH_generate_key(dh)) 85 if(!DH_generate_key(dh))
85 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()"); 86 throw exception_openssl(OPKELE_CP_ "failed to DH_generate_key()");
86 openid_message_t req; 87 openid_message_t req;
87 req.set_field("ns",OIURI_OPENID20); 88 req.set_field("ns",OIURI_OPENID20);
88 req.set_field("mode","associate"); 89 req.set_field("mode","associate");
89 req.set_field("dh_modulus",util::bignum_to_base64(dh->p)); 90 req.set_field("dh_modulus",util::bignum_to_base64(dh->p));
90 req.set_field("dh_gen",util::bignum_to_base64(dh->g)); 91 req.set_field("dh_gen",util::bignum_to_base64(dh->g));
91 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key)); 92 req.set_field("dh_consumer_public",util::bignum_to_base64(dh->pub_key));
92 openid_message_t res; 93 openid_message_t res;
93 req.set_field("assoc_type","HMAC-SHA256"); 94 req.set_field("assoc_type","HMAC-SHA256");
94 req.set_field("session_type","DH-SHA256"); 95 req.set_field("session_type","DH-SHA256");
95 secret_t secret; 96 secret_t secret;
96 int expires_in; 97 int expires_in;
97 try { 98 try {
98 direct_request(res,req,OP); 99 direct_request(res,req,OP);
99 dh_get_secret( secret, res, 100 dh_get_secret( secret, res,
100 "HMAC-SHA256", "DH-SHA256", 101 "HMAC-SHA256", "DH-SHA256",
101 dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH ); 102 dh, SHA256_DIGEST_LENGTH, SHA256, SHA256_DIGEST_LENGTH );
102 expires_in = util::string_to_long(res.get_field("expires_in")); 103 expires_in = util::string_to_long(res.get_field("expires_in"));
103 }catch(exception&) { 104 }catch(exception&) {
104 try { 105 try {
105 req.set_field("assoc_type","HMAC-SHA1"); 106 req.set_field("assoc_type","HMAC-SHA1");
106 req.set_field("session_type","DH-SHA1"); 107 req.set_field("session_type","DH-SHA1");
107 direct_request(res,req,OP); 108 direct_request(res,req,OP);
108 dh_get_secret( secret, res, 109 dh_get_secret( secret, res,
109 "HMAC-SHA1", "DH-SHA1", 110 "HMAC-SHA1", "DH-SHA1",
110 dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); 111 dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH );
111 expires_in = util::string_to_long(res.get_field("expires_in")); 112 expires_in = util::string_to_long(res.get_field("expires_in"));
112 }catch(bad_input&) { 113 }catch(bad_input&) {
113 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); 114 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association");
114 } 115 }
115 } 116 }
116 return store_assoc( 117 return store_assoc(
117 OP, res.get_field("assoc_handle"), 118 OP, res.get_field("assoc_handle"),
118 res.get_field("assoc_type"), secret, 119 res.get_field("assoc_type"), secret,
119 expires_in ); 120 expires_in );
120 } 121 }
121 122
122 basic_openid_message& basic_RP::checkid_( 123 basic_openid_message& basic_RP::checkid_(
123 basic_openid_message& rv, 124 basic_openid_message& rv,
124 mode_t mode, 125 mode_t mode,
125 const string& return_to,const string& realm, 126 const string& return_to,const string& realm,
126 extension_t *ext) { 127 extension_t *ext) {
127 rv.reset_fields(); 128 rv.reset_fields();
128 rv.set_field("ns",OIURI_OPENID20); 129 rv.set_field("ns",OIURI_OPENID20);
129 if(mode==mode_checkid_immediate) 130 if(mode==mode_checkid_immediate)
130 rv.set_field("mode","checkid_immediate"); 131 rv.set_field("mode","checkid_immediate");
131 else if(mode==mode_checkid_setup) 132 else if(mode==mode_checkid_setup)
132 rv.set_field("mode","checkid_setup"); 133 rv.set_field("mode","checkid_setup");
133 else 134 else
134 throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); 135 throw bad_input(OPKELE_CP_ "unknown checkid_* mode");
135 if(realm.empty() && return_to.empty()) 136 if(realm.empty() && return_to.empty())
136 throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty"); 137 throw bad_input(OPKELE_CP_ "At least one of realm and return_to must be non-empty");
137 if(!realm.empty()) { 138 if(!realm.empty()) {
138 rv.set_field("realm",realm); 139 rv.set_field("realm",realm);
139 rv.set_field("trust_root",realm); 140 rv.set_field("trust_root",realm);
140 } 141 }
141 if(!return_to.empty()) 142 if(!return_to.empty())
142 rv.set_field("return_to",return_to); 143 rv.set_field("return_to",return_to);
143 const openid_endpoint_t& ep = get_endpoint(); 144 const openid_endpoint_t& ep = get_endpoint();
144 rv.set_field("claimed_id",ep.claimed_id); 145 rv.set_field("claimed_id",ep.claimed_id);
145 rv.set_field("identity",ep.local_id); 146 rv.set_field("identity",ep.local_id);
146 try { 147 try {
147 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle()); 148 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle());
148 }catch(dumb_RP& drp) { 149 }catch(dumb_RP& drp) {
149 }catch(failed_lookup& fl) { 150 }catch(failed_lookup& fl) {
150 try { 151 try {
151 rv.set_field("assoc_handle",associate(ep.uri)->handle()); 152 rv.set_field("assoc_handle",associate(ep.uri)->handle());
152 }catch(dumb_RP& drp) { } 153 }catch(dumb_RP& drp) { }
153 } OPKELE_RETHROW 154 } OPKELE_RETHROW
154 if(ext) ext->rp_checkid_hook(rv); 155 if(ext) ext->rp_checkid_hook(rv);
155 return rv; 156 return rv;
156 } 157 }
157 158
158 class signed_part_message_proxy : public basic_openid_message { 159 class signed_part_message_proxy : public basic_openid_message {
159 public: 160 public:
160 const basic_openid_message& x; 161 const basic_openid_message& x;
161 set<string> signeds; 162 set<string> signeds;
162 163
163 signed_part_message_proxy(const basic_openid_message& xx) : x(xx) { 164 signed_part_message_proxy(const basic_openid_message& xx) : x(xx) {
164 const string& slist = x.get_field("signed"); 165 const string& slist = x.get_field("signed");
165 string::size_type p = 0; 166 string::size_type p = 0;
166 while(true) { 167 while(true) {
167 string::size_type co = slist.find(',',p); 168 string::size_type co = slist.find(',',p);
168 string f = (co==string::npos) 169 string f = (co==string::npos)
169 ?slist.substr(p):slist.substr(p,co-p); 170 ?slist.substr(p):slist.substr(p,co-p);
170 signeds.insert(f); 171 signeds.insert(f);
171 if(co==string::npos) break; 172 if(co==string::npos) break;
172 p = co+1; 173 p = co+1;
173 } 174 }
174 } 175 }
175 176
176 bool has_field(const string& n) const { 177 bool has_field(const string& n) const {
177 return signeds.find(n)!=signeds.end() && x.has_field(n); } 178 return signeds.find(n)!=signeds.end() && x.has_field(n); }
178 const string& get_field(const string& n) const { 179 const string& get_field(const string& n) const {
179 if(signeds.find(n)==signeds.end()) 180 if(signeds.find(n)==signeds.end())
180 throw failed_lookup(OPKELE_CP_ "The field isn't known to be signed"); 181 throw failed_lookup(OPKELE_CP_ "The field isn't known to be signed");
181 return x.get_field(n); } 182 return x.get_field(n); }
182 183
183 fields_iterator fields_begin() const { 184 fields_iterator fields_begin() const {
184 return signeds.begin(); } 185 return signeds.begin(); }
185 fields_iterator fields_end() const { 186 fields_iterator fields_end() const {
186 return signeds.end(); } 187 return signeds.end(); }
187 }; 188 };
188 189
189 static void parse_query(const string& u,string::size_type q, 190 static void parse_query(const string& u,string::size_type q,
190 map<string,string>& p) { 191 map<string,string>& p) {
191 if(q==string::npos) 192 if(q==string::npos)
192 return; 193 return;
193 assert(u[q]=='?'); 194 assert(u[q]=='?');
194 ++q; 195 ++q;
195 string::size_type l = u.size(); 196 string::size_type l = u.size();
196 while(q<l) { 197 while(q<l) {
197 string::size_type eq = u.find('=',q); 198 string::size_type eq = u.find('=',q);
198 string::size_type am = u.find('&',q); 199 string::size_type am = u.find('&',q);
199 if(am==string::npos) { 200 if(am==string::npos) {
200 if(eq==string::npos) { 201 if(eq==string::npos) {
201 p[""] = u.substr(q); 202 p[""] = u.substr(q);
202 }else{ 203 }else{
203 p[u.substr(q,eq-q)] = u.substr(eq+1); 204 p[u.substr(q,eq-q)] = u.substr(eq+1);
204 } 205 }
205 break; 206 break;
206 }else{ 207 }else{
207 if(eq==string::npos || eq>am) { 208 if(eq==string::npos || eq>am) {
208 p[""] = u.substr(q,eq-q); 209 p[""] = u.substr(q,eq-q);
209 }else{ 210 }else{
210 p[u.substr(q,eq-q)] = u.substr(eq+1,am-eq-1); 211 p[u.substr(q,eq-q)] = u.substr(eq+1,am-eq-1);
211 } 212 }
212 q = ++am; 213 q = ++am;
213 } 214 }
214 } 215 }
215 } 216 }
216 217
217 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) { 218 void basic_RP::id_res(const basic_openid_message& om,extension_t *ext) {
218 reset_vars(); 219 reset_vars();
219 bool o2 = om.has_field("ns") 220 bool o2 = om.has_field("ns")
220 && om.get_field("ns")==OIURI_OPENID20; 221 && om.get_field("ns")==OIURI_OPENID20;
221 if( (!o2) && om.has_field("user_setup_url")) 222 if( (!o2) && om.has_field("user_setup_url"))
222 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided", 223 throw id_res_setup(OPKELE_CP_ "assertion failed, setup url provided",
223 om.get_field("user_setup_url")); 224 om.get_field("user_setup_url"));
224 string m = om.get_field("mode"); 225 string m = om.get_field("mode");
225 if(o2 && m=="setup_needed") 226 if(o2 && m=="setup_needed")
226 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided"); 227 throw id_res_setup(OPKELE_CP_ "setup needed, no setup url provided");
227 if(m=="cancel") 228 if(m=="cancel")
228 throw id_res_cancel(OPKELE_CP_ "authentication cancelled"); 229 throw id_res_cancel(OPKELE_CP_ "authentication cancelled");
229 bool go_dumb=false; 230 bool go_dumb=false;
230 try { 231 try {
231 string OP = o2 232 string OP = o2
232 ?om.get_field("op_endpoint") 233 ?om.get_field("op_endpoint")
233 :get_endpoint().uri; 234 :get_endpoint().uri;
234 assoc_t assoc = retrieve_assoc( 235 assoc_t assoc = retrieve_assoc(
235 OP,om.get_field("assoc_handle")); 236 OP,om.get_field("assoc_handle"));
236 if(om.get_field("sig")!=util::base64_signature(assoc,om)) 237 if(om.get_field("sig")!=util::base64_signature(assoc,om))
237 throw id_res_mismatch(OPKELE_CP_ "signature mismatch"); 238 throw id_res_mismatch(OPKELE_CP_ "signature mismatch");
238 }catch(dumb_RP& drp) { 239 }catch(dumb_RP& drp) {
239 go_dumb=true; 240 go_dumb=true;
240 }catch(failed_lookup& e) { 241 }catch(failed_lookup& e) {
241 go_dumb=true; 242 go_dumb=true;
242 } OPKELE_RETHROW 243 } OPKELE_RETHROW
243 if(go_dumb) { 244 if(go_dumb) {
244 try { 245 try {
245 string OP = o2 246 string OP = o2
246 ?om.get_field("op_endpoint") 247 ?om.get_field("op_endpoint")
247 :get_endpoint().uri; 248 :get_endpoint().uri;
248 check_authentication(OP,om); 249 check_authentication(OP,om);
249 }catch(failed_check_authentication& fca) { 250 }catch(failed_check_authentication& fca) {
250 throw id_res_failed(OPKELE_CP_ "failed to check_authentication()"); 251 throw id_res_failed(OPKELE_CP_ "failed to check_authentication()");
251 } OPKELE_RETHROW 252 } OPKELE_RETHROW
252 } 253 }
253 signed_part_message_proxy signeds(om); 254 signed_part_message_proxy signeds(om);
254 if(o2) { 255 if(o2) {
255 check_nonce(om.get_field("op_endpoint"), 256 check_nonce(om.get_field("op_endpoint"),
256 om.get_field("response_nonce")); 257 om.get_field("response_nonce"));
257 static const char *mustsign[] = { 258 static const char *mustsign[] = {
258 "op_endpoint", "return_to", "response_nonce", "assoc_handle", 259 "op_endpoint", "return_to", "response_nonce", "assoc_handle",
259 "claimed_id", "identity" }; 260 "claimed_id", "identity" };
260 for(size_t ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) { 261 for(size_t ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) {
261 if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms])) 262 if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms]))
262 throw bad_input(OPKELE_CP_ string("Field '")+mustsign[ms]+"' is not signed against the specs"); 263 throw bad_input(OPKELE_CP_ string("Field '")+mustsign[ms]+"' is not signed against the specs");
263 } 264 }
264 if( ( 265 if( (
265 (om.has_field("claimed_id")?1:0) 266 (om.has_field("claimed_id")?1:0)
266 ^ 267 ^
267 (om.has_field("identity")?1:0) 268 (om.has_field("identity")?1:0)
268 )&1 ) 269 )&1 )
269 throw bad_input(OPKELE_CP_ "claimed_id and identity must be either both present or both absent"); 270 throw bad_input(OPKELE_CP_ "claimed_id and identity must be either both present or both absent");
270 271
271 string turl = util::rfc_3986_normalize_uri(get_this_url()); 272 string turl = util::rfc_3986_normalize_uri(get_this_url());
272 util::strip_uri_fragment_part(turl); 273 util::strip_uri_fragment_part(turl);
273 string rurl = util::rfc_3986_normalize_uri(om.get_field("return_to")); 274 string rurl = util::rfc_3986_normalize_uri(om.get_field("return_to"));
274 util::strip_uri_fragment_part(rurl); 275 util::strip_uri_fragment_part(rurl);
275 string::size_type 276 string::size_type
276 tq = turl.find('?'), rq = rurl.find('?'); 277 tq = turl.find('?'), rq = rurl.find('?');
277 if( 278 if(
278 ((tq==string::npos)?turl:turl.substr(0,tq)) 279 ((tq==string::npos)?turl:turl.substr(0,tq))
279 != 280 !=
280 ((rq==string::npos)?rurl:rurl.substr(0,rq)) 281 ((rq==string::npos)?rurl:rurl.substr(0,rq))
281 ) 282 )
282 throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url"); 283 throw id_res_bad_return_to(OPKELE_CP_ "return_to url doesn't match request url");
283 map<string,string> tp; parse_query(turl,tq,tp); 284 map<string,string> tp; parse_query(turl,tq,tp);
284 map<string,string> rp; parse_query(rurl,rq,rp); 285 map<string,string> rp; parse_query(rurl,rq,rp);
285 for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) { 286 for(map<string,string>::const_iterator rpi=rp.begin();rpi!=rp.end();++rpi) {
286 map<string,string>::const_iterator tpi = tp.find(rpi->first); 287 map<string,string>::const_iterator tpi = tp.find(rpi->first);
287 if(tpi==tp.end()) 288 if(tpi==tp.end())
288 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request"); 289 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to is missing from the request");
289 if(tpi->second!=rpi->second) 290 if(tpi->second!=rpi->second)
290 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request"); 291 throw id_res_bad_return_to(OPKELE_CP_ string("Parameter '")+rpi->first+"' from return_to doesn't matche the request");
291 } 292 }
292 293
293 if(om.has_field("claimed_id")) { 294 if(om.has_field("claimed_id")) {
294 claimed_id = om.get_field("claimed_id"); 295 claimed_id = om.get_field("claimed_id");
295 identity = om.get_field("identity"); 296 identity = om.get_field("identity");
296 verify_OP( 297 verify_OP(
297 om.get_field("op_endpoint"), 298 om.get_field("op_endpoint"),
298 claimed_id, identity ); 299 claimed_id, identity );
299 } 300 }
300 301
301 }else{ 302 }else{
302 claimed_id = get_endpoint().claimed_id; 303 claimed_id = get_endpoint().claimed_id;
303 /* TODO: check if this is the identity we asked for */ 304 /* TODO: check if this is the identity we asked for */
304 identity = om.get_field("identity"); 305 identity = om.get_field("identity");
305 } 306 }
306 if(ext) ext->rp_id_res_hook(om,signeds); 307 if(ext) ext->rp_id_res_hook(om,signeds);
307 } 308 }
308 309
309 void basic_RP::check_authentication(const string& OP, 310 void basic_RP::check_authentication(const string& OP,
310 const basic_openid_message& om){ 311 const basic_openid_message& om){
311 openid_message_t res; 312 openid_message_t res;
312 static const string checkauthmode = "check_authentication"; 313 static const string checkauthmode = "check_authentication";
313 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP); 314 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP);
314 if(res.has_field("is_valid")) { 315 if(res.has_field("is_valid")) {
315 if(res.get_field("is_valid")=="true") { 316 if(res.get_field("is_valid")=="true") {
316 if(res.has_field("invalidate_handle")) 317 if(res.has_field("invalidate_handle"))
317 invalidate_assoc(OP,res.get_field("invalidate_handle")); 318 invalidate_assoc(OP,res.get_field("invalidate_handle"));
318 return; 319 return;
319 } 320 }
320 } 321 }
321 throw failed_check_authentication( 322 throw failed_check_authentication(
322 OPKELE_CP_ "failed to verify response"); 323 OPKELE_CP_ "failed to verify response");
323 } 324 }
324 325
325} 326}