summaryrefslogtreecommitdiffabout
path: root/lib/basic_rp.cc
authorMichael Krelin <hacker@klever.net>2008-02-04 22:39:59 (UTC)
committer Michael Krelin <hacker@klever.net>2008-02-04 22:39:59 (UTC)
commit9163a26ec8839a31df888920418280a62ebc5595 (patch) (unidiff)
tree55339b4ecf0a3f24817eb5cc1b0b24f831ac895b /lib/basic_rp.cc
parentc0eeee1cfd41d0f5f6ff6ac3d6fe021421376a69 (diff)
downloadlibopkele-9163a26ec8839a31df888920418280a62ebc5595.zip
libopkele-9163a26ec8839a31df888920418280a62ebc5595.tar.gz
libopkele-9163a26ec8839a31df888920418280a62ebc5595.tar.bz2
reworked extensions framework
* changed {checkid,id_res}_hook to {rp,op}_{checkid,id_res}_hook * deprecated older hooks, although implemented it in sreg and chain extensions * added extension processing to basic_op * added sreg to test OP Signed-off-by: Michael Krelin <hacker@klever.net>
Diffstat (limited to 'lib/basic_rp.cc') (more/less context) (show whitespace changes)
-rw-r--r--lib/basic_rp.cc4
1 files changed, 2 insertions, 2 deletions
diff --git a/lib/basic_rp.cc b/lib/basic_rp.cc
index a884583..bd45d99 100644
--- a/lib/basic_rp.cc
+++ b/lib/basic_rp.cc
@@ -84,97 +84,97 @@ namespace opkele {
84 req.set_field("session_type","DH-SHA1"); 84 req.set_field("session_type","DH-SHA1");
85 direct_request(res,req,OP); 85 direct_request(res,req,OP);
86 dh_get_secret( secret, res, 86 dh_get_secret( secret, res,
87 "HMAC-SHA1", "DH-SHA1", 87 "HMAC-SHA1", "DH-SHA1",
88 dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH ); 88 dh, SHA_DIGEST_LENGTH, SHA1, SHA_DIGEST_LENGTH );
89 expires_in = util::string_to_long(res.get_field("expires_in")); 89 expires_in = util::string_to_long(res.get_field("expires_in"));
90 }catch(bad_input& e) { 90 }catch(bad_input& e) {
91 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association"); 91 throw dumb_RP(OPKELE_CP_ "OP failed to supply an association");
92 } 92 }
93 } 93 }
94 return store_assoc( 94 return store_assoc(
95 OP, res.get_field("assoc_handle"), 95 OP, res.get_field("assoc_handle"),
96 res.get_field("assoc_type"), secret, 96 res.get_field("assoc_type"), secret,
97 expires_in ); 97 expires_in );
98 } 98 }
99 99
100 basic_openid_message& basic_RP::checkid_( 100 basic_openid_message& basic_RP::checkid_(
101 basic_openid_message& rv, 101 basic_openid_message& rv,
102 mode_t mode, 102 mode_t mode,
103 const string& return_to,const string& realm, 103 const string& return_to,const string& realm,
104 extension_t *ext) { 104 extension_t *ext) {
105 rv.reset_fields(); 105 rv.reset_fields();
106 rv.set_field("ns",OIURI_OPENID20); 106 rv.set_field("ns",OIURI_OPENID20);
107 if(mode==mode_checkid_immediate) 107 if(mode==mode_checkid_immediate)
108 rv.set_field("mode","checkid_immediate"); 108 rv.set_field("mode","checkid_immediate");
109 else if(mode==mode_checkid_setup) 109 else if(mode==mode_checkid_setup)
110 rv.set_field("mode","checkid_setup"); 110 rv.set_field("mode","checkid_setup");
111 else 111 else
112 throw bad_input(OPKELE_CP_ "unknown checkid_* mode"); 112 throw bad_input(OPKELE_CP_ "unknown checkid_* mode");
113 if(realm.empty() && return_to.empty()) 113 if(realm.empty() && return_to.empty())
114 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");
115 if(!realm.empty()) { 115 if(!realm.empty()) {
116 rv.set_field("realm",realm); 116 rv.set_field("realm",realm);
117 rv.set_field("trust_root",realm); 117 rv.set_field("trust_root",realm);
118 } 118 }
119 if(!return_to.empty()) 119 if(!return_to.empty())
120 rv.set_field("return_to",return_to); 120 rv.set_field("return_to",return_to);
121 const openid_endpoint_t& ep = get_endpoint(); 121 const openid_endpoint_t& ep = get_endpoint();
122 rv.set_field("claimed_id",ep.claimed_id); 122 rv.set_field("claimed_id",ep.claimed_id);
123 rv.set_field("identity",ep.local_id); 123 rv.set_field("identity",ep.local_id);
124 try { 124 try {
125 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle()); 125 rv.set_field("assoc_handle",find_assoc(ep.uri)->handle());
126 }catch(dumb_RP& drp) { 126 }catch(dumb_RP& drp) {
127 }catch(failed_lookup& fl) { 127 }catch(failed_lookup& fl) {
128 try { 128 try {
129 rv.set_field("assoc_handle",associate(ep.uri)->handle()); 129 rv.set_field("assoc_handle",associate(ep.uri)->handle());
130 }catch(dumb_RP& drp) { } 130 }catch(dumb_RP& drp) { }
131 } OPKELE_RETHROW 131 } OPKELE_RETHROW
132 if(ext) ext->checkid_hook(rv); 132 if(ext) ext->rp_checkid_hook(rv);
133 return rv; 133 return rv;
134 } 134 }
135 135
136 class signed_part_message_proxy : public basic_openid_message { 136 class signed_part_message_proxy : public basic_openid_message {
137 public: 137 public:
138 const basic_openid_message& x; 138 const basic_openid_message& x;
139 set<string> signeds; 139 set<string> signeds;
140 140
141 signed_part_message_proxy(const basic_openid_message& xx) : x(xx) { 141 signed_part_message_proxy(const basic_openid_message& xx) : x(xx) {
142 const string& slist = x.get_field("signed"); 142 const string& slist = x.get_field("signed");
143 string::size_type p = 0; 143 string::size_type p = 0;
144 while(true) { 144 while(true) {
145 string::size_type co = slist.find(',',p); 145 string::size_type co = slist.find(',',p);
146 string f = (co==string::npos) 146 string f = (co==string::npos)
147 ?slist.substr(p):slist.substr(p,co-p); 147 ?slist.substr(p):slist.substr(p,co-p);
148 signeds.insert(f); 148 signeds.insert(f);
149 if(co==string::npos) break; 149 if(co==string::npos) break;
150 p = co+1; 150 p = co+1;
151 } 151 }
152 } 152 }
153 153
154 bool has_field(const string& n) const { 154 bool has_field(const string& n) const {
155 return signeds.find(n)!=signeds.end() && x.has_field(n); } 155 return signeds.find(n)!=signeds.end() && x.has_field(n); }
156 const string& get_field(const string& n) const { 156 const string& get_field(const string& n) const {
157 if(signeds.find(n)==signeds.end()) 157 if(signeds.find(n)==signeds.end())
158 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");
159 return x.get_field(n); } 159 return x.get_field(n); }
160 160
161 fields_iterator fields_begin() const { 161 fields_iterator fields_begin() const {
162 return signeds.begin(); } 162 return signeds.begin(); }
163 fields_iterator fields_end() const { 163 fields_iterator fields_end() const {
164 return signeds.end(); } 164 return signeds.end(); }
165 }; 165 };
166 166
167 static void parse_query(const string& u,string::size_type q, 167 static void parse_query(const string& u,string::size_type q,
168 map<string,string>& p) { 168 map<string,string>& p) {
169 if(q==string::npos) 169 if(q==string::npos)
170 return; 170 return;
171 assert(u[q]=='?'); 171 assert(u[q]=='?');
172 ++q; 172 ++q;
173 string::size_type l = u.size(); 173 string::size_type l = u.size();
174 while(q<l) { 174 while(q<l) {
175 string::size_type eq = u.find('=',q); 175 string::size_type eq = u.find('=',q);
176 string::size_type am = u.find('&',q); 176 string::size_type am = u.find('&',q);
177 if(am==string::npos) { 177 if(am==string::npos) {
178 if(eq==string::npos) { 178 if(eq==string::npos) {
179 p[""] = u.substr(q); 179 p[""] = u.substr(q);
180 }else{ 180 }else{
@@ -230,68 +230,68 @@ namespace opkele {
230 signed_part_message_proxy signeds(om); 230 signed_part_message_proxy signeds(om);
231 if(o2) { 231 if(o2) {
232 check_nonce(om.get_field("op_endpoint"), 232 check_nonce(om.get_field("op_endpoint"),
233 om.get_field("response_nonce")); 233 om.get_field("response_nonce"));
234 static const char *mustsign[] = { 234 static const char *mustsign[] = {
235 "op_endpoint", "return_to", "response_nonce", "assoc_handle", 235 "op_endpoint", "return_to", "response_nonce", "assoc_handle",
236 "claimed_id", "identity" }; 236 "claimed_id", "identity" };
237 for(int ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) { 237 for(int ms=0;ms<(sizeof(mustsign)/sizeof(*mustsign));++ms) {
238 if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms])) 238 if(om.has_field(mustsign[ms]) && !signeds.has_field(mustsign[ms]))
239 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");
240 } 240 }
241 if( ( 241 if( (
242 (om.has_field("claimed_id")?1:0) 242 (om.has_field("claimed_id")?1:0)
243 ^ 243 ^
244 (om.has_field("identity")?1:0) 244 (om.has_field("identity")?1:0)
245 )&1 ) 245 )&1 )
246 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");
247 247
248 string turl = util::rfc_3986_normalize_uri(get_this_url()); 248 string turl = util::rfc_3986_normalize_uri(get_this_url());
249 util::strip_uri_fragment_part(turl); 249 util::strip_uri_fragment_part(turl);
250 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"));
251 util::strip_uri_fragment_part(rurl); 251 util::strip_uri_fragment_part(rurl);
252 string::size_type 252 string::size_type
253 tq = turl.find('?'), rq = rurl.find('?'); 253 tq = turl.find('?'), rq = rurl.find('?');
254 if( 254 if(
255 ((tq==string::npos)?turl:turl.substr(0,tq)) 255 ((tq==string::npos)?turl:turl.substr(0,tq))
256 != 256 !=
257 ((rq==string::npos)?rurl:rurl.substr(0,rq)) 257 ((rq==string::npos)?rurl:rurl.substr(0,rq))
258 ) 258 )
259 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");
260 map<string,string> tp; parse_query(turl,tq,tp); 260 map<string,string> tp; parse_query(turl,tq,tp);
261 map<string,string> rp; parse_query(rurl,rq,rp); 261 map<string,string> rp; parse_query(rurl,rq,rp);
262 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) {
263 map<string,string>::const_iterator tpi = tp.find(rpi->first); 263 map<string,string>::const_iterator tpi = tp.find(rpi->first);
264 if(tpi==tp.end()) 264 if(tpi==tp.end())
265 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");
266 if(tpi->second!=rpi->second) 266 if(tpi->second!=rpi->second)
267 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");
268 } 268 }
269 269
270 if(om.has_field("claimed_id")) { 270 if(om.has_field("claimed_id")) {
271 verify_OP( 271 verify_OP(
272 om.get_field("op_endpoint"), 272 om.get_field("op_endpoint"),
273 om.get_field("claimed_id"), 273 om.get_field("claimed_id"),
274 om.get_field("identity") ); 274 om.get_field("identity") );
275 } 275 }
276 276
277 } 277 }
278 if(ext) ext->id_res_hook(om,signeds); 278 if(ext) ext->rp_id_res_hook(om,signeds);
279 } 279 }
280 280
281 void basic_RP::check_authentication(const string& OP, 281 void basic_RP::check_authentication(const string& OP,
282 const basic_openid_message& om){ 282 const basic_openid_message& om){
283 openid_message_t res; 283 openid_message_t res;
284 static const string checkauthmode = "check_authentication"; 284 static const string checkauthmode = "check_authentication";
285 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP); 285 direct_request(res,util::change_mode_message_proxy(om,checkauthmode),OP);
286 if(res.has_field("is_valid")) { 286 if(res.has_field("is_valid")) {
287 if(res.get_field("is_valid")=="true") { 287 if(res.get_field("is_valid")=="true") {
288 if(res.has_field("invalidate_handle")) 288 if(res.has_field("invalidate_handle"))
289 invalidate_assoc(OP,res.get_field("invalidate_handle")); 289 invalidate_assoc(OP,res.get_field("invalidate_handle"));
290 return; 290 return;
291 } 291 }
292 } 292 }
293 throw failed_check_authentication( 293 throw failed_check_authentication(
294 OPKELE_CP_ "failed to verify response"); 294 OPKELE_CP_ "failed to verify response");
295 } 295 }
296 296
297} 297}