From 69451c568218f70fc5c3ba4c0d95ae8008b18d94 Mon Sep 17 00:00:00 2001 From: Jamie Doornbos Date: Mon, 2 Jun 2008 04:38:01 +0000 Subject: [PATCH] Implemented bureau authentication * Token member for bureaus * Exception type for failed authentication * Authenticate function * Bureau id to credentials * Fixed bad constructor and toString git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@5149 542714f4-19e9-0310-aa3c-eee0fc999fb1 --- .../threerings/bureau/client/BureauClient.as | 3 -- .../bureau/data/BureauCredentials.as | 16 +++++-- .../bureau/client/BureauClient.java | 3 -- .../bureau/data/BureauCredentials.java | 24 +++++++--- .../bureau/server/BureauRegistry.java | 47 ++++++++++++++++++- 5 files changed, 74 insertions(+), 19 deletions(-) diff --git a/src/as/com/threerings/bureau/client/BureauClient.as b/src/as/com/threerings/bureau/client/BureauClient.as index 9ec2d56d9..29191897b 100644 --- a/src/as/com/threerings/bureau/client/BureauClient.as +++ b/src/as/com/threerings/bureau/client/BureauClient.as @@ -39,13 +39,10 @@ public class BureauClient extends Client public function BureauClient (token :String, bureauId :String) { super(null); - _bureauId = bureauId; - var creds :BureauCredentials = new BureauCredentials(_bureauId); creds.sessionToken = token; _creds = creds; - _ctx = createContext(); _director = createDirector(); } diff --git a/src/as/com/threerings/bureau/data/BureauCredentials.as b/src/as/com/threerings/bureau/data/BureauCredentials.as index 97c70d95a..f32f3f1ce 100644 --- a/src/as/com/threerings/bureau/data/BureauCredentials.as +++ b/src/as/com/threerings/bureau/data/BureauCredentials.as @@ -38,20 +38,26 @@ public class BureauCredentials extends Credentials */ public var sessionToken :String; + /** + * The id of the bureau logging in. + */ + public var bureauId :String; + /** * Creates new credentials for a specific bureau. */ - public function BureauCredentials (token :String) + public function BureauCredentials (bureauId :String) { - super(new Name("@@bureau:" + token + "@@")); - sessionToken = token; + super(new Name("@@bureau:" + bureauId + "@@")); + this.bureauId = bureauId; } /** @inheritDoc */ override protected function toStringBuf (buf :StringBuilder) :void { super.toStringBuf(buf); - buf.append(" token=").append(sessionToken); + buf.append(" bureauId=").append(bureauId). + append(" token=").append(sessionToken); } // from interface Streamable @@ -59,6 +65,7 @@ public class BureauCredentials extends Credentials { super.readObject(ins); sessionToken = (ins.readField(String) as String); + bureauId = (ins.readField(String) as String); } // from interface Streamable @@ -66,6 +73,7 @@ public class BureauCredentials extends Credentials { super.writeObject(out); out.writeField(sessionToken); + out.writeField(bureauId); } } } diff --git a/src/java/com/threerings/bureau/client/BureauClient.java b/src/java/com/threerings/bureau/client/BureauClient.java index 03e552ce1..961e02ecb 100644 --- a/src/java/com/threerings/bureau/client/BureauClient.java +++ b/src/java/com/threerings/bureau/client/BureauClient.java @@ -41,13 +41,10 @@ public abstract class BureauClient extends Client public BureauClient (String token, String bureauId, RunQueue runQueue) { super(null, runQueue); - _bureauId = bureauId; - BureauCredentials creds = new BureauCredentials(_bureauId); creds.sessionToken = token; _creds = creds; - _ctx = createContext(); _director = createDirector(); } diff --git a/src/java/com/threerings/bureau/data/BureauCredentials.java b/src/java/com/threerings/bureau/data/BureauCredentials.java index a9bc5efa8..5391c8b60 100644 --- a/src/java/com/threerings/bureau/data/BureauCredentials.java +++ b/src/java/com/threerings/bureau/data/BureauCredentials.java @@ -35,6 +35,20 @@ public class BureauCredentials extends Credentials */ public String sessionToken; + /** + * The id of the bureau logging in. + */ + public String bureauId; + + /** + * Test if a given name object matches the name that we generate. + */ + public static boolean isBureau (Name name) + { + String normal = name.getNormal(); + return normal.startsWith("@@bureau:") && normal.endsWith("@@"); + } + /** * Creates an empty credentials for streaming. Should not be used directly. */ @@ -48,18 +62,14 @@ public class BureauCredentials extends Credentials public BureauCredentials (String bureauId) { super(new Name("@@bureau:" + bureauId + "@@")); + this.bureauId = bureauId; } @Override // inherit documentation protected void toString (StringBuilder buf) { super.toString(buf); - buf.append(" token=").append(sessionToken); - } - - // inherit documentation - from Object - public String toString () - { - return super.toString() + ", token=" + sessionToken; + buf.append(" id=").append(bureauId). + append(" token=").append(sessionToken); } } diff --git a/src/java/com/threerings/bureau/server/BureauRegistry.java b/src/java/com/threerings/bureau/server/BureauRegistry.java index 6c17b2c91..62f0386b2 100644 --- a/src/java/com/threerings/bureau/server/BureauRegistry.java +++ b/src/java/com/threerings/bureau/server/BureauRegistry.java @@ -25,6 +25,7 @@ import java.util.Map; import java.util.Set; import com.threerings.bureau.data.AgentObject; import com.threerings.bureau.data.BureauCodes; +import com.threerings.bureau.data.BureauCredentials; import com.threerings.presents.data.ClientObject; import com.threerings.presents.dobj.RootDObjectManager; import com.threerings.presents.dobj.ObjectDeathListener; @@ -67,6 +68,21 @@ public class BureauRegistry String token); } + /** + * Thrown when a bureau could not be authenticated. + */ + public static class AuthenticationException extends Exception + { + /** + * Creates a new authentication exception with a message explaining why the client could + * not be authenticated as a bureau. + */ + public AuthenticationException (String message) + { + super(message); + } + } + /** * Creates a new registry, prepared to provide bureau services. */ @@ -101,6 +117,30 @@ public class BureauRegistry BureauCodes.BUREAU_GROUP); } + /** + * Check the credentials to make sure this is one of our bureaus. + */ + public void authenticate (BureauCredentials creds) + throws AuthenticationException + { + Bureau bureau = _bureaus.get(creds.bureauId); + if (bureau == null) { + throw new AuthenticationException( + "Bureau " + creds.bureauId + " not found"); + } + + if (bureau.clientObj != null) { + throw new AuthenticationException( + "Bureau " + creds.bureauId + " already logged in"); + } + + if (!bureau.token.equals(creds.sessionToken)) { + throw new AuthenticationException( + "Bureau " + creds.bureauId + + " does not match credentials token"); + } + } + /** * Registers a command generator for a given type. When an agent is started and no bureaus are * running, the bureauType is used to determine the CommandGenerator @@ -155,12 +195,12 @@ public class BureauRegistry bureau = new Bureau(); bureau.bureauId = agent.bureauId; + bureau.token = generateToken(); // schedule the bureau to be kicked off - String token = generateToken(); bureau.builder = new ProcessBuilder( generator.createCommand( - _serverNameAndPort, agent.bureauId, token)); + _serverNameAndPort, agent.bureauId, bureau.token)); bureau.builder.redirectErrorStream(true); @@ -514,6 +554,9 @@ public class BureauRegistry // non-null once the bureau is scheduled but not yet kicked off ProcessBuilder builder; + // The token given to this bureau for authentication + String token; + // The bureau's key in the map of bureaus. All requests for this bureau // with this id should be associated with one instance String bureauId;