<> <> DIRECTORY ArpaExtras USING [MyAddress], BasicTime USING [earliestGMT, GMT, Now, Period], RefText USING [New], Rope USING [ROPE], SunRPCAuth USING [AuthenticateProc, Conversation, Error, Flavor, InitiateProc, nullFlavor, OpaqueValue, Register, shortFlavor, SweepProc] ; SunRPCAuthShortImpl: CEDAR MONITOR IMPORTS ArpaExtras, BasicTime, RefText, SunRPCAuth EXPORTS SunRPCAuth ~ { <> ROPE: TYPE ~ Rope.ROPE; Flavor: TYPE ~ SunRPCAuth.Flavor; shortFlavor: Flavor ~ SunRPCAuth.shortFlavor; nullFlavor: Flavor ~ SunRPCAuth.nullFlavor; OpaqueValue: TYPE ~ SunRPCAuth.OpaqueValue; nullOpaqueValue: OpaqueValue _ RefText.New[0]; ClientConversation: TYPE ~ SunRPCAuth.Conversation; ServerConversation: TYPE ~ SunRPCAuth.Conversation; <> myHostId: CARD _ LOOPHOLE[ArpaExtras.MyAddress[]]; tableSize: CARDINAL ~ 31; initialTtl: CARDINAL _ 120; <> Headers: TYPE ~ REF HeadersObject; HeadersObject: TYPE ~ ARRAY [0 .. tableSize) OF Handle; headers: Headers _ NEW[HeadersObject]; Handle: TYPE ~ REF Object; Object: TYPE ~ RECORD [ next: Handle, keyValue: KeyValue, ttl: CARDINAL _ initialTtl, c: ServerConversation ]; <> Key: TYPE ~ REF KeyObject; KeyObject: TYPE ~ RECORD [ dummy1, dummy2: CARDINAL, value: KeyValue ]; KeyValue: TYPE ~ RECORD [ hostId: CARD32, timestamp: CARD32 ]; Insert: ENTRY PROC [hdrs: Headers, h: Handle] ~ { i: CARDINAL ~ h.keyValue.timestamp MOD tableSize; h.next _ hdrs[i]; hdrs[i] _ h; }; Lookup: ENTRY PROC [hdrs: Headers, k: Key] RETURNS [h: Handle] ~ { i: CARDINAL ~ k.value.timestamp MOD tableSize; FOR h _ hdrs[i], h.next WHILE h # NIL DO IF h.keyValue = k.value THEN RETURN; ENDLOOP; }; Delete: ENTRY PROC [hdrs: Headers, k: Key] ~ { i: CARDINAL ~ k.value.timestamp MOD tableSize; prev, p: Handle; p _ hdrs[i]; DO IF p = NIL THEN RETURN; IF p.keyValue = k.value THEN EXIT; prev _ p; p _ p.next; ENDLOOP; IF prev = NIL THEN hdrs[i] _ p.next ELSE prev.next _ p.next; }; Sweep: SunRPCAuth.SweepProc ~ { FOR i: CARDINAL IN [0 .. tableSize) DO SweepInner[NARROW[registrationData], i, secondsSinceLastSweep]; ENDLOOP; }; SweepInner: ENTRY PROC [hdrs: Headers, i: CARDINAL, secs: CARD] ~ { prev, p: Handle; prev _ NIL; p _ hdrs[i]; WHILE p # NIL DO IF p.ttl > secs THEN { p.ttl _ p.ttl - secs; prev _ p; p _ p.next; } ELSE { IF prev = NIL THEN hdrs[i] _ p.next ELSE prev.next _ p.next; p _ p.next; }; ENDLOOP; }; <> lastTimestamp: CARD32 _ 0; GetNewTimestamp: ENTRY PROC RETURNS [timestamp: CARD] ~ { timestamp _ BasicTime.Period[from~BasicTime.earliestGMT, to~BasicTime.Now[]]; IF timestamp <= lastTimestamp THEN timestamp _ lastTimestamp+1; lastTimestamp _ timestamp; }; CreateShort: PUBLIC PROC [c: ServerConversation] RETURNS [replyVerifier: OpaqueValue] ~ { key: Key; h: Handle; replyVerifier _ RefText.New[BYTES[KeyValue]]; replyVerifier.length _ BYTES[KeyValue]; TRUSTED { key _ LOOPHOLE[replyVerifier] }; key.value.hostId _ myHostId; key.value.timestamp _ GetNewTimestamp[]; h _ NEW[Object _ [keyValue~key.value, c~c]]; Insert[headers, h]; }; DestroyShort: PUBLIC PROC [verifier: OpaqueValue] ~ { IF verifier.length >= BYTES[KeyValue] THEN TRUSTED { Delete[headers, LOOPHOLE[verifier, Key]]; }; }; <> ShortInitiate: SunRPCAuth.InitiateProc ~ { ERROR SunRPCAuth.Error[$shortInitiateIsIllegal]; }; ShortAuthenticate: SunRPCAuth.AuthenticateProc ~ { h: Handle; IF credentials.length >= BYTES[KeyValue] THEN { TRUSTED { h _ Lookup[NARROW[registrationData], LOOPHOLE[credentials]] }; IF h # NIL THEN RETURN [result~ok, replyFlavor~nullFlavor, replyVerifier~nullOpaqueValue, c~h.c]; }; RETURN [result~badCredentials, replyFlavor~nullFlavor, replyVerifier~NIL, c~NIL]; }; RegisterShort: PROC ~ { SunRPCAuth.Register[shortFlavor, ShortInitiate, ShortAuthenticate, Sweep, headers]; }; }...