summaryrefslogtreecommitdiffabout
Side-by-side diff
Diffstat (more/less context) (ignore whitespace changes)
-rw-r--r--lib/basic_op.cc6
1 files changed, 6 insertions, 0 deletions
diff --git a/lib/basic_op.cc b/lib/basic_op.cc
index fa659ac..511b51a 100644
--- a/lib/basic_op.cc
+++ b/lib/basic_op.cc
@@ -107,109 +107,115 @@ namespace opkele {
oum.set_field("ns",OIURI_OPENID20);
oum.set_field("assoc_type",a->assoc_type());
oum.set_field("assoc_handle",a->handle());
oum.set_field("expires_in",util::long_to_string(a->expires_in()));
secret_t secret = a->secret();
if(sts=="DH-SHA1" || sts=="DH-SHA256") {
if(d_len != secret.size())
throw bad_input(OPKELE_CP_ "Association secret and session MAC are not of the same size");
oum.set_field("session_type",sts);
oum.set_field("dh_server_public",util::bignum_to_base64(dh->pub_key));
string b64; secret.enxor_to_base64(key_digest,b64);
oum.set_field("enc_mac_key",b64);
}else /* TODO: support cleartext over encrypted connection */
throw unsupported(OPKELE_CP_ "Unsupported session type");
return oum;
} catch(unsupported& u) {
oum.reset_fields();
oum.set_field("ns",OIURI_OPENID20);
oum.set_field("error",u.what());
oum.set_field("error_code","unsupported-type");
oum.set_field("session_type","DH-SHA256");
oum.set_field("assoc_type","HMAC-SHA256");
return oum;
}
void basic_OP::checkid_(const basic_openid_message& inm,
extension_t *ext) {
reset_vars();
string modestr = inm.get_field("mode");
if(modestr=="checkid_setup")
mode = mode_checkid_setup;
else if(modestr=="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&) { }
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");
+ if(realm.empty())
+ throw failed_lookup(OPKELE_CP_ "Empty realm doesn't count");
}catch(failed_lookup&) {
try {
realm = inm.get_field("trust_root");
+ if(realm.empty())
+ throw failed_lookup(OPKELE_CP_ "Empty trust_root doesn't count");
}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");
+ if(realm.empty())
+ throw failed_lookup(OPKELE_CP_ "Empty trust_root doesn't count");
}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,
extension_t *ext) {
assert(!return_to.empty());
assert(!is_id_select());
if(!assoc) {
assoc = alloc_assoc("HMAC-SHA256",SHA256_DIGEST_LENGTH,true);
}
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";