using a proxy, in which case we'll send the non-proxy hostname in the
bootstrap data.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6530 542714f4-19e9-0310-aa3c-eee0fc999fb1
not whether they're old or new.
OLD -> NAME_WITH_BYTE_ENUM
NEW -> ORDINAL
NEW_WITH_BYTE_ENUM -> ORDINAL_WITH_BYTE_ENUM
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6523 542714f4-19e9-0310-aa3c-eee0fc999fb1
- Allow configuring of two new streaming policies for enums.
- Changed the alphabetical fields policy to be checked once on class init.
Let me elaborate on the first two changes:
1) The base Streamer class had grown to handle a variety of things.
There were two different ways to handle enums, a whole section of code
for arrays (two ways of handling those), and then custom reader/writer
methods were supported with fallback for regular old streaming classes.
A lot of this was checked by introspection every single time an object
was written/created/read. In addition, there were 6 different fields
in the base class, many of which would be unused by default. All
the BasicStreamers also inherited these fields and never did anything
with them.
So my change makes Streamer an abstract class with no non-static fields.
I pulled all the logic for different streaming strategies
into different classes and do the tests to determine which class
to use once when first setting up the streamer for a particular target class.
If our target class is an array with a final element type, why should
we be re-checking those two things each and every time an object is
written? Or if it's not an array and we've got field marshallers set up,
why are we wondering if it's an array or enum each time?
In addition, reading/writing would freak out if a field marshaller
was never found for a particular field. Let's fail faster and freak
out when the marshallers are first initialized, which is fine
now that (in a recentish commit) we don't initialize the marshallers
if there appears to be no reason to do so (if a Streamable class has
both a custom reader and a custom writer method, then the marshallers
are never used. The class could have non-transient fields that don't
stream, but it takes care of them itself in the custom methods.)
2) There are now three enum-streaming policies that can be configured.
- OLD, the default, will try to stream by byte if the enum is a ByteEnum,
and fall back to using the enum's name.
- NEW will always stream an enum by ordinal, using the smallest integer
type possible, given the enum's size. ByteEnum is ignored.
- NEW_WITH_BYTE_ENUM will do the ByteEnum thing for ByteEnums, and fall
back to the new ordinal thing for other enums.
The idea here is that narya streaming is designed specifically such that
the server and client are running the same code. There are some edge
cases, and some games persist streamed objects, but in general
streaming by ordinal should be fine.
But, it's opt-in for now. I can't go breaking everything.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6522 542714f4-19e9-0310-aa3c-eee0fc999fb1
as it's used for Collections, too.
Nixed my commented-out EnumSet/EnumMap explorations. A dead end.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6518 542714f4-19e9-0310-aa3c-eee0fc999fb1
This has a few benefits over the old system:
* We don't have to copy our Maven, Java, and Actionscript settings to every project
* Maven dependency fetching uses a cache in dist until clean is run instead of checking for
snapshots on every build
* Building aslibs no longer needs to generate a configuration file, which grows confusingly stale
* Nailgun can be used to run mxmlc. This cuts actionscript compile time in half. It can also
generate a script to call nailgun, which avoids the few seconds of Java startup required to run Ant.
This means we're using Flex 4 to compile naryalib.swc now, but we released a 1.7 recently. Any
projects wishing to stay out of Flex 4 land can pin to that.
If this goes off without too much turbulence, I'll migrate our other projects in a couple days.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6513 542714f4-19e9-0310-aa3c-eee0fc999fb1
on peer transfers of client connections), so have PresentsSession handle that in both starting
and resuming a session (and takes out a synchronized call in ClientManager).
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6495 542714f4-19e9-0310-aa3c-eee0fc999fb1
server). It can then be used to encrypt further data during the session.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6492 542714f4-19e9-0310-aa3c-eee0fc999fb1
(In Who, we need to stream com.threerings.geom.Vector2, so we need a custom Streamer for it)
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6487 542714f4-19e9-0310-aa3c-eee0fc999fb1
{Client.setRequireSecureAuth} then if the client fails to create a secure channel with the server,
an auth request with no credentials will be sent. The supplied Authenticator will need to handle
this situation to send the appropriate response back to the client (ie: tell it to download the
latest version).
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6480 542714f4-19e9-0310-aa3c-eee0fc999fb1
eventually change how the handshake works, we can maintain backwards compatability with the old
clients
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6479 542714f4-19e9-0310-aa3c-eee0fc999fb1
when sent to the server.
To implement a secure authentication channel:
- Create a key pair using the com.threerings.presents.tool.KeyPairGen tool. You will need to
distribute the public key with your client, and the private key with the server.
- On your server during initialization, use PresentsConnectionManager.setPrivateKey to set the
private key. It can take the key string gerenated by KeyPairGen. This will return true if the
key was sucessfully set and the server supports the encryption necessary.
- On your client before authenticating, use Client.setPublicKey to set the public key. As with
setPrivateKey, it will return true if the client supports the encryption necessary.
That's it! You should now be authenticating over a secure encrypted channel. The server can
still accept unsecured authentication attempts (for the purpose of telling the client it needs a
new version to get the server's public key). A failure to decrypt the client credientials on the
server will return a new "m.failed_to_secure" authentication code.
Handshake process:
- The client generates a random 128-bit key, and encodes it with the public key using a 32-bit
salt (PublicKeyCredentials). This is sent to the server as a SecureRequest.
- The server decrypts the i128-bit key using its private key and verifies it against the salt. If
verification fails, a failed secure response is returned and the client will authenticate over a
clear channel. If verification succeeds, the server generates a random 128-bit AES key and
encodes it with the 128-bit key sent from the client. This is sent back to the client as a
SecureResponse.
- The client will decode the AES key sent from the server (using the random key it generated at
the start of the handshake). Using the AES key, the client will encrypt their credentials using
an AESAuthRequest and send it to the server.
- The server can now decrypt the credentials from the client and pass the AESAuthRequest to the
configured authenticators to complete authentication. If the server fails to decrypt the
credentials a "m.failed_to_secure" authentication code is returned to the client.
git-svn-id: svn+ssh://src.earth.threerings.net/narya/trunk@6477 542714f4-19e9-0310-aa3c-eee0fc999fb1