SunRPCAuthShortImpl.mesa
Demers, September 4, 1987 7:25:58 pm PDT
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
~ {
Types
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;
Parameters
myHostId: CARDLOOPHOLE[ArpaExtras.MyAddress[]];
tableSize: CARDINAL ~ 31;
initialTtl: CARDINAL ← 120;
Table Management
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
];
The following must be LOOPHOLE compatible with TEXT[BYTES[KeyValue]]:
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;
};
Client Interface
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]];
};
};
Registration
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];
};
}...