Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

UserImpl[...] has public keys! Either there is a userRepoKeyRing or there are public keys! #25

Open
nlmarco opened this issue Oct 17, 2016 · 3 comments
Assignees
Labels
bug

Comments

@nlmarco
Copy link
Contributor

@nlmarco nlmarco commented Oct 17, 2016

java.lang.IllegalStateException: UserImpl[ababababa, Aaaa, Bbbb, [aaa@bbb.org], [cdcdcdcd, dededede]] has public keys! Either there is a userRepoKeyRing or there are public keys! There cannot be both!
    at sun.reflect.NativeConstructorAccessorImpl.newInstance0(Native Method)
    at sun.reflect.NativeConstructorAccessorImpl.newInstance(NativeConstructorAccessorImpl.java:62)
    at sun.reflect.DelegatingConstructorAccessorImpl.newInstance(DelegatingConstructorAccessorImpl.java:45)
    at java.lang.reflect.Constructor.newInstance(Constructor.java:423)
    at co.codewizards.cloudstore.core.dto.RemoteExceptionUtil.getObjectOrNull(RemoteExceptionUtil.java:89)
    at co.codewizards.cloudstore.core.dto.RemoteExceptionUtil.throwOriginalExceptionIfPossible(RemoteExceptionUtil.java:29)
    at co.codewizards.cloudstore.ls.rest.client.LocalServerRestClient.handleAndRethrowException(LocalServerRestClient.java:368)
    at co.codewizards.cloudstore.ls.rest.client.LocalServerRestClient.execute(LocalServerRestClient.java:191)
    at co.codewizards.cloudstore.ls.client.LocalServerClient.invoke(LocalServerClient.java:252)
    at co.codewizards.cloudstore.ls.client.LocalServerClient.invoke(LocalServerClient.java:212)
    at co.codewizards.cloudstore.ls.client.LocalServerClient.invoke(LocalServerClient.java:199)
    at co.codewizards.cloudstore.ls.core.invoke.RemoteObjectProxyInvocationHandler.invoke(RemoteObjectProxyInvocationHandler.java:54)
    at com.sun.proxy.$Proxy44.getPlainHistoCryptoRepoFileDtos(Unknown Source)
    at org.subshare.gui.histo.HistoFramePane$3$1.call(HistoFramePane.java:205)
    at org.subshare.gui.histo.HistoFramePane$3$1.call(HistoFramePane.java:200)
    at javafx.concurrent.Task$TaskCallable.call(Task.java:1423)
    at java.util.concurrent.FutureTask.run(FutureTask.java:266)
    at javafx.concurrent.Service.lambda$null$73(Service.java:725)
    at java.security.AccessController.doPrivileged(Native Method)
    at javafx.concurrent.Service.lambda$executeTask$74(Service.java:724)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
Caused by: co.codewizards.cloudstore.core.dto.RemoteException<java.lang.IllegalStateException>: UserImpl[ababababa, Aaaa, Bbbb, [aaa@bbb.org], [cdcdcdcd, dededede]] has public keys! Either there is a userRepoKeyRing or there are public keys! There cannot be both!
    at org.subshare.core.user.UserImpl.getUserRepoKeyRingOrCreate(UserImpl.java:167)
    at org.subshare.core.user.UserRepoKeyRingLookupImpl.getUserRepoKeyRing(UserRepoKeyRingLookupImpl.java:35)
    at org.subshare.core.user.UserRepoKeyRingLookupImpl.getUserRepoKeyRing(UserRepoKeyRingLookupImpl.java:24)
    at org.subshare.local.SsLocalRepoMetaDataImpl.getCryptree(SsLocalRepoMetaDataImpl.java:280)
    at org.subshare.local.SsLocalRepoMetaDataImpl.getPlainHistoCryptoRepoFileDtos(SsLocalRepoMetaDataImpl.java:396)
    at sun.reflect.NativeMethodAccessorImpl.invoke0(Native Method)
    at sun.reflect.NativeMethodAccessorImpl.invoke(NativeMethodAccessorImpl.java:62)
    at sun.reflect.DelegatingMethodAccessorImpl.invoke(DelegatingMethodAccessorImpl.java:43)
    at java.lang.reflect.Method.invoke(Method.java:498)
    at co.codewizards.cloudstore.core.util.ReflectionUtil.invoke(ReflectionUtil.java:153)
    at co.codewizards.cloudstore.core.util.ReflectionUtil.invoke(ReflectionUtil.java:131)
    at co.codewizards.cloudstore.ls.core.invoke.InvokeMethodExecutor$InvocationRunnable.run(InvokeMethodExecutor.java:201)
    at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142)
    at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617)
    at java.lang.Thread.run(Thread.java:745)
    at co.codewizards.cloudstore.core.dto.RemoteExceptionUtil.throwOriginalExceptionIfPossible(RemoteExceptionUtil.java:23)
    ... 17 more

(note: data anonymized)

@nlmarco nlmarco added the bug label Oct 17, 2016
@nlmarco nlmarco added this to the 0.9.8 milestone Oct 17, 2016
@nlmarco nlmarco self-assigned this Oct 17, 2016
@nlmarco

This comment has been minimized.

Copy link
Contributor Author

@nlmarco nlmarco commented Oct 17, 2016

The above exception happened too late. The user actually already had a UserRepoKeyRing assigned.

I fixed this error by adding a check that prevents adding an element to User.userRepoKeyPublicKeys, if there already is a UserRepoKeyRing. After this, the following exception was thrown:

java.lang.IllegalStateException: UserImpl[U3_W4jLY9cK-DsZCZ99mlw, Adam, Smith, [adam@smith.name], [123456a45b7380c2, 6564a5f6df511111]] already has a userRepoKeyRing! Cannot add public keys! Either there is a userRepoKeyRing or there are public keys! There cannot be both! userRepoKeyRing=UserRepoKeyRingImpl[[UserRepoKeyImpl[userRepoKeyId=dh8o_uh-7D-8uN4IsHmguQ, invitation=false]]], userRepoKeyPublicKeys=[], event.changeCollection=[PublicKeyWithSignatureImpl[userRepoKeyId=X8FXjVE-y9cw-bXjhhO6Jg, invitation=false, validTo=null]]
        at org.subshare.core.user.UserImpl$PreventUserRepoKeyRingAndPublicKeysCollisionListener.modificationOccurring(UserImpl.java:88) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.core.observable.standard.StandardModificationHandler.firePreEvent(StandardModificationHandler.java:436) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.core.observable.standard.StandardModificationHandler.preEvent(StandardModificationHandler.java:406) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.core.observable.ModificationHandler.preAdd(ModificationHandler.java:292) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.core.observable.ObservableCollection.add(ObservableCollection.java:214) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.local.UserRepoKeyPublicKeyHelper.updateUserRepoKeyRingFromUserIdentities(UserRepoKeyPublicKeyHelper.java:422) ~[org.subshare.local-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.local.CryptreeImpl.putCryptoChangeSetDto(CryptreeImpl.java:536) ~[org.subshare.local-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.rest.client.transport.CryptreeRestRepoTransportImpl.syncCryptoKeysFromRemoteRepo(CryptreeRestRepoTransportImpl.java:209) ~[org.subshare.rest.client-0.9.8-SNAPSHOT.jar:na]
        at org.subshare.rest.client.transport.CryptreeRestRepoTransportImpl.getChangeSetDto(CryptreeRestRepoTransportImpl.java:160) ~[org.subshare.rest.client-0.9.8-SNAPSHOT.jar:na]
        at co.codewizards.cloudstore.core.repo.sync.RepoToRepoSync.sync(RepoToRepoSync.java:217) ~[co.codewizards.cloudstore.core-0.9.11.jar:na]
        at co.codewizards.cloudstore.core.repo.sync.RepoToRepoSync.syncDown(RepoToRepoSync.java:168) ~[co.codewizards.cloudstore.core-0.9.11.jar:na]
        at co.codewizards.cloudstore.core.repo.sync.RepoToRepoSync.sync(RepoToRepoSync.java:131) ~[co.codewizards.cloudstore.core-0.9.11.jar:na]
        at org.subshare.core.repo.sync.SsRepoToRepoSync.sync(SsRepoToRepoSync.java:65) ~[org.subshare.core-0.9.8-SNAPSHOT.jar:na]
        at co.codewizards.cloudstore.core.repo.sync.RepoSyncRunner.run(RepoSyncRunner.java:51) ~[co.codewizards.cloudstore.core-0.9.11.jar:na]
        at co.codewizards.cloudstore.core.repo.sync.RepoSyncDaemonImpl$WrapperRunnable.run(RepoSyncDaemonImpl.java:123) ~[co.codewizards.cloudstore.core-0.9.11.jar:na]
        at java.util.concurrent.Executors$RunnableAdapter.call(Executors.java:511) [na:1.8.0_91]
        at java.util.concurrent.FutureTask.run(FutureTask.java:266) [na:1.8.0_91]
        at java.util.concurrent.ThreadPoolExecutor.runWorker(ThreadPoolExecutor.java:1142) [na:1.8.0_91]
        at java.util.concurrent.ThreadPoolExecutor$Worker.run(ThreadPoolExecutor.java:617) [na:1.8.0_91]
        at java.lang.Thread.run(Thread.java:745) [na:1.8.0_91]

(note: data anonymized)

@nlmarco

This comment has been minimized.

Copy link
Contributor Author

@nlmarco nlmarco commented Oct 17, 2016

Further investigation -- with the help of the new exception -- revealed that the error was actually produced by a manual modification a while ago: The user deleted his userRegistry.subshare file locally and the admin deleted it on the server, when the data was screwed up completely (at the beginning of the alpha testing).

Hence, the User with userId=U3_W4jLY9cK-DsZCZ99mlw had only his new UserRepoKey with userRepoKeyId=dh8o_uh-7D-8uN4IsHmguQ in his UserRepoKeyRing (holding public and private keys). The old UserRepoKey with userRepoKeyId=X8FXjVE-y9cw-bXjhhO6Jg was missing.

Therefore, Subshare tried to copy the public key with userRepoKeyId=X8FXjVE-y9cw-bXjhhO6Jg from the repository-database into the UserRegistry leading to the above exception.

It is not possible to properly solve this situation programmatically, because the private key is not available and therefore a key-pair cannot be enlisted in the user's UserRepoKeyRing (holding key-pairs). We could only do the following to solve this issue:

  1. Allow a User to have both a UserRepoKeyRing (with public+private-key-pairs) and a collection of public keys (without any private key).

  2. Somehow introduce a "repair" mode that replaces all signatures done with the old key by new signatures done with the new key. After this is done, the old UserRepoKeyPublicKey can be deleted everywhere.

The option (2) is not always possible! At least not for the actual user: The user might have permissions on only a sub-set of what he originally signed (e.g. before he had write-access to the root-directory, but now, he's only allowed to write into a certain sub-directory).

Hence, we cannot go for option (2) -- only the owner (or another admin with sufficient permissions) might do this, but it's definitely a very complex process and it changes the history, as someone else signed the stuff after the process.

So we probably have to go for option (1): Extend Subshare to allow a User to contain both - a UserRepoKeyRing (= private+public-key-pairs) and a UserRepoKeyPublicKey-collection (= public keys only).

@nlmarco nlmarco removed this from the 0.9.8 milestone Oct 17, 2016
@nlmarco

This comment has been minimized.

Copy link
Contributor Author

@nlmarco nlmarco commented Oct 17, 2016

Since this bug was caused by a manual modification and should thus normally never happen, I removed the assignment to milestone 0.9.8. We have more urgent things to do now.

Btw. we solved the problem for the affected user by restoring the missing <userRepoKeyDtos> entry in the UserRegistryDto.xml (inside ~/.subshare/userRegistry.subshare) from a backup.

nlmarco pushed a commit that referenced this issue Nov 7, 2016
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Projects
None yet
1 participant
You can’t perform that action at this time.