<<>> <> <> <> <> <> <> <> DIRECTORY Commander USING [CommandProc, Handle, Register], CommanderBackdoor USING [AdamOrEve], EnvironmentVariables USING [Get], InstallationComforts USING [ProcName], IO, Rope USING [Concat, Length, ROPE], RuntimeError USING [UnboundProcedureFault, UNCAUGHT], SimpleFeedback USING [Append], SystemSite USING [Get, Names, Set], TypeScript USING [BackSpace, IsATypeScript], ViewerClasses USING [Viewer], ViewerIO USING [GetViewerFromStream], XNSAuth USING [AuthenticationError, CallError, GetIdentityDetails, Identity, MakeIdentity, Name], XNSCHName USING [Name, NameFromRope, RopeFromName], XNSCredentials; XNSCredentialsImpl: CEDAR MONITOR IMPORTS Commander, CommanderBackdoor, EnvironmentVariables, InstallationComforts, IO, Rope, RuntimeError, SimpleFeedback, SystemSite, TypeScript, ViewerIO, XNSAuth, XNSCHName EXPORTS XNSCredentials ~ { ROPE: TYPE ~ Rope.ROPE; XNSCredentialsChangeProc: TYPE ~ XNSCredentials.XNSCredentialsChangeProc; <> Identity: TYPE = XNSAuth.Identity; currentIdentity: Identity ¬ NIL; GetIdentity: PUBLIC ENTRY PROC RETURNS [Identity] ~ { RETURN[currentIdentity] }; SetIdentity: PUBLIC ENTRY PROC[id: XNSAuth.Identity] ~ { ENABLE UNWIND => NULL; InternalSetIdentity[id, XNSAuth.GetIdentityDetails[id].name]; }; XNSLoginFromNameAndPassword: PUBLIC ENTRY PROC[name, password: ROPE, strongCredentials: BOOL ¬ TRUE] RETURNS[identityWasSet: BOOL ¬ FALSE] ~ { ENABLE UNWIND => NULL; xnsName: XNSCHName.Name; { ENABLE { XNSAuth.AuthenticationError => GOTO notDone; XNSAuth.CallError => GOTO notDone; }; IF ( name # NIL ) AND ( password # NIL ) THEN { newId: XNSAuth.Identity; xnsName ¬ XNSCHName.NameFromRope[name]; newId ¬ XNSAuth.MakeIdentity[xnsName, password, IF strongCredentials THEN strong ELSE simple, TRUE]; InternalSetIdentity[newId, xnsName]; RETURN[TRUE]; }; EXITS notDone => RETURN[FALSE]; }; }; XNSLogin: Commander.CommandProc = { [] ¬ ReallyDoLogin[cmd: cmd, strongCredentials: TRUE, source: NARROW[cmd.procData.clientData]]; }; SimpleLogin: Commander.CommandProc = { [] ¬ ReallyDoLogin[cmd: cmd, strongCredentials: FALSE, source: NARROW[cmd.procData.clientData]]; }; DoLogin: PUBLIC PROC[cmd: Commander.Handle, strongCredentials: BOOL] RETURNS[identityWasSet: BOOL ¬ FALSE] = { RETURN[ReallyDoLogin[cmd, strongCredentials]]; }; ReallyDoLogin: ENTRY PROC[cmd: Commander.Handle, strongCredentials: BOOL, source: ATOM¬NIL] RETURNS[identityWasSet: BOOL ¬ FALSE] = { ENABLE UNWIND => NULL; name, passwd: Rope.ROPE; xnsName: XNSCHName.Name; <> IF source=$keyboard THEN cmd ¬ CommanderBackdoor.AdamOrEve[cmd]; -- Use original in/out streams BEGIN ENABLE BEGIN XNSAuth.AuthenticationError => { what: Rope.ROPE ¬ SELECT problem FROM credentialsInvalid => "credentialsInvalid", verifierInvalid => "verifierInvalid", verifierExpired => "verifierExpired", verifierReused => "verifierReused", credentialsExpired => "credentialsExpired", inappropriateCredentials => "inappropriateCredentials", ENDCASE => IO.PutFR1["\nUnknown error (%g)\n", [integer[ORD[problem]]] ]; cmd.out.PutF1["\nXNSAuth.AuthenticationError (%g)\n", [rope[what]] ]; GOTO notDone; }; XNSAuth.CallError => { IF ( problem = strongKeyDoesNotExist ) AND ( whichArg = initiator ) THEN cmd.out.PutF1["\nXNSAuth.CallError: %g is probably an invalid name\n", [rope[XNSCHName.RopeFromName[xnsName]]] ] ELSE { what: Rope.ROPE ¬ SELECT problem FROM tooBusy => "tooBusy", accessRightsInsufficient => "accessRightsInsufficient", keysUnavailable => "keysUnavailable", strongKeyDoesNotExist => "strongKeyDoesNotExist", simpleKeyDoesNotExist => "simpleKeyDoesNotExist", strongKeyAlreadyRegistered => "strongKeyAlreadyRegistered", simpleKeyAlreadyRegistered => "simpleKeyAlreadyRegistered", domainForNewKeyUnavailable => "domainForNewKeyUnavailable", domainForNewKeyUnknown => "domainForNewKeyUnknown", badKey => "badKey", badName => "badName", databaseFull => "databaseFull", other => "other catchall error", ENDCASE => IO.PutFR1["\nUnknown XNSAuth.CallError.problem (%g)\n", [integer[ORD[problem]]] ]; which: Rope.ROPE ¬ SELECT whichArg FROM notApplicable => "notApplicable", initiator => "initiator", recipient => "recipient", client => "client", ENDCASE => IO.PutFR1["\nUnknown XNSAuth.CallError.whichArg (%g)\n", [integer[ORD[whichArg]]] ]; cmd.out.PutF["\nXNSAuth.CallError: problem %g, whichArg: %g\n", [rope[what]], [rope[which]] ]; }; GOTO notDone; }; END; name ¬ PromptForLine[in: cmd.in, out: cmd.out, prompt: "user name", echo: TRUE]; IF name = NIL THEN RETURN; passwd ¬ PromptForLine[in: cmd.in, out: cmd.out, prompt: "password", echo: FALSE]; IF passwd = NIL THEN RETURN; IF ( name # NIL ) AND ( passwd # NIL ) THEN { newId: Identity; xnsName ¬ XNSCHName.NameFromRope[name]; newId ¬ XNSAuth.MakeIdentity[xnsName, passwd, IF strongCredentials THEN strong ELSE simple, TRUE]; InternalSetIdentity[newId, xnsName]; RETURN[TRUE]; }; EXITS notDone => NULL; END; }; PromptForLine: PROC [in, out: IO.STREAM, prompt: Rope.ROPE, echo: BOOL ¬ TRUE] RETURNS [line: Rope.ROPE ¬ NIL] ~ { lookHidden: IO.Value ~ IO.rope["h"]; lookShiftHidden: IO.Value ~ IO.rope["H"]; TypeScriptHackery: PROC ~ { ENABLE RuntimeError.UnboundProcedureFault => { GOTO NoViewers }; viewer: ViewerClasses.Viewer ~ ViewerIO.GetViewerFromStream[out]; out.PutF1["%l", lookShiftHidden]; IF TypeScript.IsATypeScript[viewer] THEN { TypeScript.BackSpace[viewer, line.Length[] + 1]; out.PutRope["****\n"]; in.Reset[]; }; EXITS NoViewers => { NULL }; }; IO.PutF1[out, " %g: ", [rope[prompt]]]; IF NOT echo THEN { IO.PutF1[out, "%l", lookHidden]; }; BEGIN ENABLE UNWIND => IF NOT echo THEN out.PutF1["%l", lookShiftHidden]; BEGIN ENABLE BEGIN IO.EndOfStream => CONTINUE; IO.Rubout => { IF NOT echo THEN out.PutF1["%l", lookShiftHidden]; out.PutRope[" \n"]; in.Reset[]; CONTINUE; }; END; line ¬ IO.GetLineRope[in]; END; IF line = NIL THEN { IF NOT echo THEN out.PutF1["%l", lookShiftHidden]; RETURN; }; IF NOT echo THEN TypeScriptHackery[]; END; }; RegisterForChange: PUBLIC ENTRY PROC [proc: XNSCredentialsChangeProc, clientData: REF ANY ¬ NIL] = { procList ¬ CONS[[proc, clientData], procList]; }; changeProc: TYPE = RECORD[proc: XNSCredentialsChangeProc, clientData: REF ANY]; procList: LIST OF changeProc ¬ NIL; InternalSetIdentity: INTERNAL PROC [this: Identity, xnsName: XNSCHName.Name] ~ { currentIdentity ¬ this; SystemSite.Set[ [ SystemSite.Get[].registry, xnsName.domain, xnsName.organization ] ]; FOR pL: LIST OF changeProc ¬ procList, pL.rest UNTIL pL = NIL DO pL.first.proc[this, pL.first.clientData ! RuntimeError.UNCAUGHT => { SimpleFeedback.Append[$XNSCredentials, $oneLiner, $info, Rope.Concat["\tUncaught error while executing XNSCredentialsChangeProc: ", InstallationComforts.ProcName[pL.first.proc]] ]; CONTINUE }]; ENDLOOP; }; GetIdentityName: Commander.CommandProc = { name: XNSAuth.Name ~ XNSAuth.GetIdentityDetails[GetIdentity[]].name; IO.PutRope[cmd.out, XNSCHName.RopeFromName[name]]; IO.PutRope[cmd.out, "\n"]; }; PrintSystemSiteValues: Commander.CommandProc = { names: SystemSite.Names ¬ SystemSite.Get[]; cmd.out.PutF["\nSystemSite [domain: %g, organization: %g]\n", [rope[names.domain]], [rope[names.organization]] ]; }; SetDefaults: PROC = { envDom, envOrg: ROPE; defaultNames: SystemSite.Names ¬ SystemSite.Get[]; envDom ¬ EnvironmentVariables.Get["XNSDOMAIN"]; envOrg ¬ EnvironmentVariables.Get["XNSORG"]; IF envDom # NIL THEN defaultNames.domain ¬ envDom; IF envOrg # NIL THEN defaultNames.organization ¬ envOrg; SystemSite.Set[defaultNames]; }; Commander.Register[ "GetIdentityName", GetIdentityName]; Commander.Register[ "PrintSystemSiteValues", PrintSystemSiteValues]; Commander.Register[ "XNSUser", GetIdentityName]; Commander.Register[ "XNSLogin", XNSLogin, "Allows one to set one's xns credentials"]; Commander.Register[ "SimpleLogin", SimpleLogin, "Allows one to set one's simple xns credentials"]; Commander.Register[ "XNSLoginFromKeyboard", XNSLogin, "Allows one to set one's xns credentials", $keyboard]; Commander.Register[ "SimpleLoginFromKeyboard", SimpleLogin, "Allows one to set one's simple xns credentials", $keyboard]; SetDefaults[]; }.