From fd9947b87dcfcdbaf680c254685a6c5fe08eae13 Mon Sep 17 00:00:00 2001 From: Erik Johnston Date: Fri, 6 Oct 2017 13:47:40 +0100 Subject: [PATCH] Generate smaller device IDs --- .../dendrite/clientapi/auth/auth.go | 5 ++- .../clientapi/auth/storage/devices/storage.go | 43 ++++++++++++++----- .../dendrite/clientapi/readers/login.go | 9 +--- .../dendrite/clientapi/writers/register.go | 2 +- .../dendrite/cmd/create-account/main.go | 2 +- 5 files changed, 41 insertions(+), 20 deletions(-) diff --git a/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go b/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go index 668bab5f3..3959addde 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go +++ b/src/github.com/matrix-org/dendrite/clientapi/auth/auth.go @@ -40,6 +40,9 @@ var UnknownDeviceID = "unknown-device" // 32 bytes => 256 bits var tokenByteLength = 32 +// The length of generated device IDs +var deviceIDByteLength = 8 + // DeviceDatabase represents a device database. type DeviceDatabase interface { // Look up the device matching the given access token. @@ -89,7 +92,7 @@ func GenerateAccessToken() (string, error) { // GenerateDeviceID creates a new device id. Returns an error if failed to generate // random bytes. func GenerateDeviceID() (string, error) { - b := make([]byte, tokenByteLength) + b := make([]byte, deviceIDByteLength) _, err := rand.Read(b) if err != nil { return "", err diff --git a/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go b/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go index df8bf4f3f..ea7d87383 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go +++ b/src/github.com/matrix-org/dendrite/clientapi/auth/storage/devices/storage.go @@ -18,6 +18,7 @@ import ( "context" "database/sql" + "github.com/matrix-org/dendrite/clientapi/auth" "github.com/matrix-org/dendrite/clientapi/auth/authtypes" "github.com/matrix-org/dendrite/common" "github.com/matrix-org/gomatrixserverlib" @@ -55,20 +56,42 @@ func (d *Database) GetDeviceByAccessToken( // If there is already a device with the same device ID for this user, that access token will be revoked // and replaced with the given accessToken. If the given accessToken is already in use for another device, // an error will be returned. +// If no device ID is given one is generated. // Returns the device on success. func (d *Database) CreateDevice( - ctx context.Context, localpart, deviceID, accessToken string, + ctx context.Context, localpart string, deviceID *string, accessToken string, ) (dev *authtypes.Device, returnErr error) { - returnErr = common.WithTransaction(d.db, func(txn *sql.Tx) error { - var err error - // Revoke existing token for this device - if err = d.devices.deleteDevice(ctx, txn, deviceID, localpart); err != nil { - return err - } + if deviceID != nil { + returnErr = common.WithTransaction(d.db, func(txn *sql.Tx) error { + var err error + // Revoke existing token for this device + if err = d.devices.deleteDevice(ctx, txn, *deviceID, localpart); err != nil { + return err + } - dev, err = d.devices.insertDevice(ctx, txn, deviceID, localpart, accessToken) - return err - }) + dev, err = d.devices.insertDevice(ctx, txn, *deviceID, localpart, accessToken) + return err + }) + } else { + // We generate device IDs in a loop in case its already taken. + // We cap this at going round 5 times to ensure we don't spin forever + var newDeviceID string + for i := 1; i <= 5; i++ { + newDeviceID, returnErr = auth.GenerateDeviceID() + if returnErr != nil { + return + } + + returnErr = common.WithTransaction(d.db, func(txn *sql.Tx) error { + var err error + dev, err = d.devices.insertDevice(ctx, txn, newDeviceID, localpart, accessToken) + return err + }) + if returnErr == nil { + return + } + } + } return } diff --git a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go index 196b827fa..ddbac12ce 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/readers/login.go +++ b/src/github.com/matrix-org/dendrite/clientapi/readers/login.go @@ -117,14 +117,9 @@ func Login( httputil.LogThenError(req, err) } - deviceID, err := auth.GenerateDeviceID() - if err != nil { - httputil.LogThenError(req, err) - } - // TODO: Use the device ID in the request dev, err := deviceDB.CreateDevice( - req.Context(), acc.Localpart, deviceID, token, + req.Context(), acc.Localpart, nil, token, ) if err != nil { return util.JSONResponse{ @@ -139,7 +134,7 @@ func Login( UserID: dev.UserID, AccessToken: dev.AccessToken, HomeServer: cfg.Matrix.ServerName, - DeviceID: deviceID, + DeviceID: dev.ID, }, } } diff --git a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go index 8519c9a1f..a317a249a 100644 --- a/src/github.com/matrix-org/dendrite/clientapi/writers/register.go +++ b/src/github.com/matrix-org/dendrite/clientapi/writers/register.go @@ -290,7 +290,7 @@ func completeRegistration( } // // TODO: Use the device ID in the request. - dev, err := deviceDB.CreateDevice(ctx, username, auth.UnknownDeviceID, token) + dev, err := deviceDB.CreateDevice(ctx, username, nil, token) if err != nil { return util.JSONResponse{ Code: 500, diff --git a/src/github.com/matrix-org/dendrite/cmd/create-account/main.go b/src/github.com/matrix-org/dendrite/cmd/create-account/main.go index d031afc26..3d5c35878 100644 --- a/src/github.com/matrix-org/dendrite/cmd/create-account/main.go +++ b/src/github.com/matrix-org/dendrite/cmd/create-account/main.go @@ -87,7 +87,7 @@ func main() { } device, err := deviceDB.CreateDevice( - context.Background(), *username, "create-account-script", *accessToken, + context.Background(), *username, nil, *accessToken, ) if err != nil { fmt.Println(err.Error())