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