summaryrefslogtreecommitdiffabout
path: root/lib/basic_op.cc
Side-by-side diff
Diffstat (limited to 'lib/basic_op.cc') (more/less context) (ignore whitespace changes)
-rw-r--r--lib/basic_op.cc5
1 files changed, 4 insertions, 1 deletions
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index c89d1d7..9e2ea5a 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -132,159 +132,162 @@ namespace opkele {
}
void basic_op::checkid_(const basic_openid_message& inm,
extension_t *ext) {
reset_vars();
string mode = inm.get_field("mode");
if(mode=="checkid_setup")
mode = mode_checkid_setup;
else if(mode=="checkid_immediate")
mode = mode_checkid_immediate;
else
throw bad_input(OPKELE_CP_ "Invalid checkid_* mode");
try {
assoc = retrieve_assoc(invalidate_handle=inm.get_field("assoc_handle"));
invalidate_handle.clear();
}catch(failed_lookup&) {
// no handle specified or no valid assoc found, go dumb
assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true);
}
try {
openid2 = (inm.get_field("ns")==OIURI_OPENID20);
}catch(failed_lookup&) { openid2 = false; }
try {
return_to = inm.get_field("return_to");
}catch(failed_lookup&) { }
if(openid2) {
try {
realm = inm.get_field("realm");
}catch(failed_lookup&) {
try {
realm = inm.get_field("trust_root");
}catch(failed_lookup&) {
if(return_to.empty())
throw bad_input(OPKELE_CP_
"Both realm and return_to are unset");
realm = return_to;
}
}
}else{
try {
realm = inm.get_field("trust_root");
}catch(failed_lookup&) {
if(return_to.empty())
throw bad_input(OPKELE_CP_
"Both realm and return_to are unset");
realm = return_to;
}
}
try {
identity = inm.get_field("identity");
try {
claimed_id = inm.get_field("claimed_id");
}catch(failed_lookup&) {
if(openid2)
throw bad_input(OPKELE_CP_
"claimed_id and identity must be either both present or both absent");
claimed_id = identity;
}
}catch(failed_lookup&) {
if(openid2 && inm.has_field("claimed_id"))
throw bad_input(OPKELE_CP_
"claimed_id and identity must be either both present or both absent");
}
verify_return_to();
+ if(ext) ext->op_checkid_hook(inm);
}
- basic_openid_message& basic_op::id_res(basic_openid_message& om) {
+ basic_openid_message& basic_op::id_res(basic_openid_message& om,
+ extension_t *ext) {
assert(assoc);
assert(!return_to.empty());
assert(!is_id_select());
time_t now = time(0);
struct tm gmt; gmtime_r(&now,&gmt);
char w3timestr[24];
if(!strftime(w3timestr,sizeof(w3timestr),"%Y-%m-%dT%H:%M:%SZ",&gmt))
throw failed_conversion(OPKELE_CP_
"Failed to build time string for nonce" );
om.set_field("ns",OIURI_OPENID20);
om.set_field("mode","id_res");
om.set_field("op_endpoint",get_op_endpoint());
string ats = "ns,mode,op_endpoint,return_to,response_nonce,"
"assoc_handle,signed";
if(!identity.empty()) {
om.set_field("identity",identity);
om.set_field("claimed_id",claimed_id);
ats += ",identity,claimed_id";
}
om.set_field("return_to",return_to);
string nonce = w3timestr;
om.set_field("response_nonce",alloc_nonce(nonce,assoc->stateless()));
if(!invalidate_handle.empty()) {
om.set_field("invalidate_handle",invalidate_handle);
ats += ",invalidate_handle";
}
om.set_field("assoc_handle",assoc->handle());
om.add_to_signed(ats);
+ if(ext) ext->op_id_res_hook(om);
om.set_field("sig",util::base64_signature(assoc,om));
return om;
}
basic_openid_message& basic_op::cancel(basic_openid_message& om) {
assert(!return_to.empty());
om.set_field("ns",OIURI_OPENID20);
om.set_field("mode","cancel");
return om;
}
basic_openid_message& basic_op::error(basic_openid_message& om,
const string& error,const string& contact,
const string& reference ) {
assert(!return_to.empty());
om.set_field("ns",OIURI_OPENID20);
om.set_field("mode","error");
om.set_field("error",error);
om.set_field("contact",contact);
om.set_field("reference",reference);
return om;
}
basic_openid_message& basic_op::setup_needed(
basic_openid_message& oum,const basic_openid_message& inm) {
assert(mode==mode_checkid_immediate);
assert(!return_to.empty());
if(openid2) {
oum.set_field("ns",OIURI_OPENID20);
oum.set_field("mode","setup_needed");
}else{
oum.set_field("mode","id_res");
static const string setupmode = "checkid_setup";
oum.set_field("user_setup_url",
util::change_mode_message_proxy(inm,setupmode)
.append_query(get_op_endpoint()));
}
return oum;
}
basic_openid_message& basic_op::check_authentication(
basic_openid_message& oum,
const basic_openid_message& inm) try {
assert(inm.get_field("mode")=="check_authentication");
oum.reset_fields();
oum.set_field("ns",OIURI_OPENID20);
bool o2;
try {
o2 = (inm.get_field("ns")==OIURI_OPENID20);
}catch(failed_lookup&) { o2 = false; }
string nonce;
if(o2) {
try {
if(!check_nonce(nonce = inm.get_field("response_nonce")))
throw failed_check_authentication(OPKELE_CP_ "Invalid nonce");
}catch(failed_lookup&) {
throw failed_check_authentication(OPKELE_CP_ "No nonce provided with check_authentication request");
}
}
try {
assoc = retrieve_assoc(inm.get_field("assoc_handle"));
if(!assoc->stateless())
throw failed_check_authentication(OPKELE_CP_ "Will not do check_authentication on a stateful handle");
}catch(failed_lookup&) {