# HG changeset patch # User Adam Chlipala # Date 1293982387 18000 # Node ID 6b2a44da71b093e06570a0228da5d49561fa5329 # Parent de04a3fc6b7289dc2566332a9dbd55c36b0c585d Change postify to satisfy more OPs; add untested invalidate_handle support diff -r de04a3fc6b72 -r 6b2a44da71b0 src/c/openid.c --- a/src/c/openid.c Sun Jan 02 10:11:38 2011 -0500 +++ b/src/c/openid.c Sun Jan 02 10:33:07 2011 -0500 @@ -1,3 +1,4 @@ +#include #include #include @@ -133,17 +134,29 @@ } static void postify(uw_OpenidFfi_inputs buf, uw_Basis_string s) { + char hex[4]; + for (; *s; ++s) { - switch (*s) { + if (isalnum(*s)) + uw_buffer_append(buf, s, 1); + else { + sprintf(hex, "%%%02X", (unsigned char)*s); + uw_buffer_append(buf, hex, 3); + } + + /*switch (*s) { case '=': uw_buffer_append(buf, "%3D", 3); break; case '&': uw_buffer_append(buf, "%26", 3); break; + case '%': + uw_buffer_append(buf, "%25", 3); + break; default: uw_buffer_append(buf, s, 1); - } + }*/ } } @@ -151,7 +164,7 @@ if (uw_buffer_used(buf) > 0) uw_buffer_append(buf, "&", 1); - postify(buf, key); + uw_buffer_append(buf, key, strlen(key)); uw_buffer_append(buf, "=", 1); postify(buf, value); diff -r de04a3fc6b72 -r 6b2a44da71b0 src/ur/openid.ur --- a/src/ur/openid.ur Sun Jan 02 10:11:38 2011 -0500 +++ b/src/ur/openid.ur Sun Jan 02 10:33:07 2011 -0500 @@ -217,14 +217,27 @@ else return (HandleOk {Endpoint = ep, Typ = assoc.Typ, Key = assoc.Key}) -fun verifyStateless os ep id = +fun verifyStateless os ep id expectInvalidation = os' <- OpenidFfi.direct ep (OpenidFfi.remode os "check_authentication"); case OpenidFfi.getOutput os' "error" of Some msg => return (Failure ("Failure confirming message contents with OP: " ^ msg)) | None => - case OpenidFfi.getOutput os' "is_valid" of - Some "true" => return (AuthenticatedAs id) - | _ => return (Failure "OP does not confirm message contents") + let + fun finish () = case OpenidFfi.getOutput os' "is_valid" of + Some "true" => return (AuthenticatedAs id) + | _ => return (Failure "OP does not confirm message contents") + in + case OpenidFfi.getOutput os' "invalidate_handle" of + None => + if expectInvalidation then + return (Failure "Claimed invalidate_handle is not confirmed") + else + finish () + | Some handle => + dml (DELETE FROM associations + WHERE Endpoint = {[ep]} AND Handle = {[handle]}); + finish () + end table nonces : { Endpoint : string, Nonce : string, Expires : time } PRIMARY KEY (Endpoint, Nonce) @@ -337,17 +350,22 @@ case errO of HandleError s => after (Failure s) | NoAssociation ep => - r <- verifyStateless os ep id; + r <- verifyStateless os ep id False; after r | HandleOk {Endpoint = ep, Typ = atype, Key = key} => - errO <- verifyNonce os ep; - case errO of - Some s => after (Failure s) + case OpenidFfi.getOutput os "openid.invalidate_handle" of + Some _ => + r <- verifyStateless os ep id True; + after r | None => - errO <- verifySig os atype key; + errO <- verifyNonce os ep; case errO of Some s => after (Failure s) - | None => after (AuthenticatedAs id)) + | None => + errO <- verifySig os atype key; + case errO of + Some s => after (Failure s) + | None => after (AuthenticatedAs id)) | _ => after (Failure ("Unexpected openid.mode: " ^ mode)) and verifyReturnTo os =