From c5eea01a23dfa56d953eba6440c3a9fa2ad4b89f Mon Sep 17 00:00:00 2001 From: David Dworken Date: Sun, 3 Apr 2022 21:00:46 -0700 Subject: [PATCH] device ID is now a random uuid generated by the client --- clients/local/client.go | 2 +- server/server_test.go | 27 ++++++++++++++------------- shared/client.go | 8 ++++---- shared/client_test.go | 8 ++++---- shared/data.go | 10 +--------- shared/data_test.go | 4 ++-- 6 files changed, 26 insertions(+), 33 deletions(-) diff --git a/clients/local/client.go b/clients/local/client.go index 2090cb6..2397703 100644 --- a/clients/local/client.go +++ b/clients/local/client.go @@ -24,7 +24,7 @@ func main() { case "export": export() case "init": - shared.CheckFatalError(shared.Setup(0, os.Args)) + shared.CheckFatalError(shared.Setup( os.Args)) // TODO: Call ebootstrap here case "install": shared.CheckFatalError(shared.Install()) diff --git a/server/server_test.go b/server/server_test.go index c2cc136..d754d69 100644 --- a/server/server_test.go +++ b/server/server_test.go @@ -8,6 +8,7 @@ import ( "net/http/httptest" "testing" + "github.com/google/uuid" "github.com/ddworken/hishtory/shared" ) @@ -15,7 +16,7 @@ func TestSubmitThenQuery(t *testing.T) { // Set up defer shared.BackupAndRestore(t)() InitDB() - shared.Check(t, shared.Setup(0, []string{})) + shared.Check(t, shared.Setup([]string{})) // Submit an entry entry, err := shared.BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "120", " 123 ls / ", "1641774958326745663"}) @@ -62,7 +63,7 @@ func TestNoUserSecretGivesNoResults(t *testing.T) { // Set up defer shared.BackupAndRestore(t)() InitDB() - shared.Check(t, shared.Setup(0, []string{})) + shared.Check(t, shared.Setup([]string{})) // Submit an entry entry, err := shared.BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "120", " 123 ls / ", "1641774958326745663"}) @@ -91,7 +92,7 @@ func TestSearchQuery(t *testing.T) { // Set up defer shared.BackupAndRestore(t)() InitDB() - shared.Check(t, shared.Setup(0, []string{})) + shared.Check(t, shared.Setup([]string{})) // Submit an entry that we'll match entry, err := shared.BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "120", " 123 ls /bar ", "1641774958326745663"}) @@ -133,14 +134,14 @@ func TestESubmitThenQuery(t *testing.T) { // Set up defer shared.BackupAndRestore(t)() InitDB() - shared.Check(t, shared.Setup(0, []string{})) + shared.Check(t, shared.Setup([]string{})) // Register a few devices userId := shared.UserId("key") - devId1 := shared.DeviceId("key", 1) - devId2 := shared.DeviceId("key", 2) + devId1 := uuid.Must(uuid.NewRandom()).String() + devId2 := uuid.Must(uuid.NewRandom()).String() otherUser := shared.UserId("otherkey") - otherDev := shared.DeviceId("otherkey", 1) + otherDev := uuid.Must(uuid.NewRandom()).String() deviceReq := httptest.NewRequest(http.MethodGet, "/?device_id="+devId1+"&user_id="+userId, nil) apiERegisterHandler(nil, deviceReq) deviceReq = httptest.NewRequest(http.MethodGet, "/?device_id="+devId2+"&user_id="+userId, nil) @@ -160,7 +161,7 @@ func TestESubmitThenQuery(t *testing.T) { // Query for device id 1 w := httptest.NewRecorder() - searchReq := httptest.NewRequest(http.MethodGet, "/?device_id="+shared.DeviceId("key", 1), nil) + searchReq := httptest.NewRequest(http.MethodGet, "/?device_id="+devId1, nil) apiEQueryHandler(w, searchReq) res := w.Result() defer res.Body.Close() @@ -172,7 +173,7 @@ func TestESubmitThenQuery(t *testing.T) { t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries)) } dbEntry := retrievedEntries[0] - if dbEntry.DeviceId != shared.DeviceId("key", 1) { + if dbEntry.DeviceId != devId1 { t.Fatalf("Response contains an incorrect device ID: %#v", *dbEntry) } if dbEntry.UserId != shared.UserId("key") { @@ -181,7 +182,7 @@ func TestESubmitThenQuery(t *testing.T) { if dbEntry.ReadCount != 1 { t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount) } - decEntry, err := shared.DecryptHistoryEntry("key", 1, *dbEntry) + decEntry, err := shared.DecryptHistoryEntry("key", *dbEntry) shared.Check(t, err) if !shared.EntryEquals(decEntry, *entry) { t.Fatalf("DB data is different than input! \ndb =%#v\ninput=%#v", *dbEntry, *entry) @@ -189,7 +190,7 @@ func TestESubmitThenQuery(t *testing.T) { // Same for device id 2 w = httptest.NewRecorder() - searchReq = httptest.NewRequest(http.MethodGet, "/?device_id="+shared.DeviceId("key", 2), nil) + searchReq = httptest.NewRequest(http.MethodGet, "/?device_id="+devId2, nil) apiEQueryHandler(w, searchReq) res = w.Result() defer res.Body.Close() @@ -200,7 +201,7 @@ func TestESubmitThenQuery(t *testing.T) { t.Fatalf("Expected to retrieve 1 entry, found %d", len(retrievedEntries)) } dbEntry = retrievedEntries[0] - if dbEntry.DeviceId != shared.DeviceId("key", 2) { + if dbEntry.DeviceId != devId2 { t.Fatalf("Response contains an incorrect device ID: %#v", *dbEntry) } if dbEntry.UserId != shared.UserId("key") { @@ -209,7 +210,7 @@ func TestESubmitThenQuery(t *testing.T) { if dbEntry.ReadCount != 1 { t.Fatalf("db.ReadCount should have been 1, was %v", dbEntry.ReadCount) } - decEntry, err = shared.DecryptHistoryEntry("key", 2, *dbEntry) + decEntry, err = shared.DecryptHistoryEntry("key", *dbEntry) shared.Check(t, err) if !shared.EntryEquals(decEntry, *entry) { t.Fatalf("DB data is different than input! \ndb =%#v\ninput=%#v", *dbEntry, *entry) diff --git a/shared/client.go b/shared/client.go index 6eff080..e57b9ae 100644 --- a/shared/client.go +++ b/shared/client.go @@ -120,7 +120,7 @@ func GetUserSecret() (string, error) { return config.UserSecret, nil } -func Setup(deviceId int, args []string) error { +func Setup(args []string) error { userSecret := uuid.Must(uuid.NewRandom()).String() if len(args) > 2 && args[2] != "" { userSecret = args[2] @@ -130,7 +130,7 @@ func Setup(deviceId int, args []string) error { var config ClientConfig config.UserSecret = userSecret config.IsEnabled = true - config.DeviceId = deviceId + config.DeviceId = uuid.Must(uuid.NewRandom()).String() return SetConfig(config) } @@ -158,7 +158,7 @@ func DisplayResults(results []*HistoryEntry, displayHostname bool) { type ClientConfig struct { UserSecret string `json:"user_secret"` IsEnabled bool `json:"is_enabled"` - DeviceId int `json:"device_id"` + DeviceId string `json:"device_id"` } func GetConfig() (ClientConfig, error) { @@ -253,7 +253,7 @@ func Install() error { if err != nil { // No config, so set up a new installation // TODO: GO THROUGH THE REGISTRATION FLOW - return Setup(0, os.Args) + return Setup(os.Args) } return nil } diff --git a/shared/client_test.go b/shared/client_test.go index 64b6684..ce41f53 100644 --- a/shared/client_test.go +++ b/shared/client_test.go @@ -15,7 +15,7 @@ func TestSetup(t *testing.T) { if _, err := os.Stat(path.Join(homedir, HISHTORY_PATH, CONFIG_PATH)); err == nil { t.Fatalf("hishtory secret file already exists!") } - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) if _, err := os.Stat(path.Join(homedir, HISHTORY_PATH, CONFIG_PATH)); err != nil { t.Fatalf("hishtory secret file does not exist after Setup()!") } @@ -28,7 +28,7 @@ func TestSetup(t *testing.T) { func TestBuildHistoryEntry(t *testing.T) { defer BackupAndRestore(t)() - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) entry, err := BuildHistoryEntry([]string{"unused", "saveHistoryEntry", "120", " 123 ls / ", "1641774958326745663"}) Check(t, err) if entry.UserSecret == "" || len(entry.UserSecret) < 10 || strings.TrimSpace(entry.UserSecret) != entry.UserSecret { @@ -53,14 +53,14 @@ func TestBuildHistoryEntry(t *testing.T) { func TestGetUserSecret(t *testing.T) { defer BackupAndRestore(t)() - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) secret1, err := GetUserSecret() Check(t, err) if len(secret1) < 10 || strings.Contains(secret1, " ") || strings.Contains(secret1, "\n") { t.Fatalf("unexpected secret: %v", secret1) } - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) secret2, err := GetUserSecret() Check(t, err) diff --git a/shared/data.go b/shared/data.go index f03b3e4..a1ce586 100644 --- a/shared/data.go +++ b/shared/data.go @@ -5,7 +5,6 @@ import ( "io" "os" "path" - "strconv" "strings" "time" @@ -74,10 +73,6 @@ func UserId(key string) string { return Hmac(key, KDF_USER_ID) } -func DeviceId(key string, id int) string { - return Hmac(key, KDF_DEVICE_ID+strconv.Itoa(id)) -} - func EncryptionKey(userSecret string) ([]byte, error) { encryptionKey, err := base64.URLEncoding.DecodeString(Hmac(userSecret, KDF_ENCRYPTION_KEY)) if err != nil { @@ -150,13 +145,10 @@ func EncryptHistoryEntry(userSecret string, entry HistoryEntry) (EncHistoryEntry }, nil } -func DecryptHistoryEntry(userSecret string, deviceId int, entry EncHistoryEntry) (HistoryEntry, error) { +func DecryptHistoryEntry(userSecret string, entry EncHistoryEntry) (HistoryEntry, error) { if entry.UserId != UserId(userSecret) { return HistoryEntry{}, fmt.Errorf("Refusing to decrypt history entry with mismatching UserId") } - if entry.DeviceId != DeviceId(userSecret, deviceId) { - return HistoryEntry{}, fmt.Errorf("Refusing to decrypt history entry with mismatching DeviceId") - } plaintext, err := Decrypt(userSecret, entry.EncryptedData, []byte(UserId(userSecret)), entry.Nonce) if err != nil { return HistoryEntry{}, nil diff --git a/shared/data_test.go b/shared/data_test.go index b30c058..b11f262 100644 --- a/shared/data_test.go +++ b/shared/data_test.go @@ -6,7 +6,7 @@ import ( func TestPersist(t *testing.T) { defer BackupAndRestore(t)() - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) db, err := OpenLocalSqliteDb() Check(t, err) @@ -27,7 +27,7 @@ func TestPersist(t *testing.T) { func TestSearch(t *testing.T) { defer BackupAndRestore(t)() - Check(t, Setup(0, []string{})) + Check(t, Setup([]string{})) db, err := OpenLocalSqliteDb() Check(t, err)