Merge mercury patchset in Smack

This commit is contained in:
Paul Schaub 2020-07-18 14:11:04 +02:00
parent 40266f8741
commit 3b66968ad5
Signed by: vanitasvitae
GPG Key ID: 62BEE9264BF17311
14 changed files with 100 additions and 92 deletions

View File

@ -5,6 +5,7 @@ import org.mercury_im.messenger.android.di.module.AndroidDatabaseModule;
import org.mercury_im.messenger.android.di.module.AndroidSchedulersModule;
import org.mercury_im.messenger.android.ui.account.detail.AndroidAccountDetailsViewModel;
import org.mercury_im.messenger.android.ui.roster.contacts.AndroidContactListViewModel;
import org.mercury_im.messenger.core.di.module.OpenPgpModule;
import org.mercury_im.messenger.core.di.module.RxMercuryMessageStoreFactoryModule;
import org.mercury_im.messenger.core.di.module.RxMercuryRosterStoreFactoryModule;
import org.mercury_im.messenger.core.di.module.XmppTcpConnectionFactoryModule;
@ -46,6 +47,7 @@ import dagger.Component;
ViewModelModule.class,
XmppTcpConnectionFactoryModule.class,
RxMercuryMessageStoreFactoryModule.class,
OpenPgpModule.class,
RxMercuryRosterStoreFactoryModule.class
})
public interface AppComponent {

View File

@ -7,7 +7,6 @@ import org.mercury_im.messenger.core.data.repository.GroupChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.data.mapping.AccountMapping;
import org.mercury_im.messenger.data.mapping.DirectChatMapping;
import org.mercury_im.messenger.data.mapping.EntityCapsMapping;
@ -92,18 +91,4 @@ public class RepositoryModule {
ReactiveEntityStore<Persistable> data, AccountRepository accountRepository) {
return new RxOpenPgpRepository(data, accountRepository);
}
@Provides
@Singleton
static Repositories provideRepositories(
AccountRepository accountRepository,
DirectChatRepository directChatRepository,
GroupChatRepository groupChatRepository,
MessageRepository messageRepository,
PeerRepository peerRepository,
EntityCapsRepository entityCapsRepository,
OpenPgpRepository openPgpRepository) {
return new Repositories(accountRepository, directChatRepository, groupChatRepository,
messageRepository, peerRepository, entityCapsRepository, openPgpRepository);
}
}

View File

@ -13,7 +13,6 @@ import org.jxmpp.jid.impl.JidCreate;
import org.jxmpp.stringprep.XmppStringprepException;
import org.mercury_im.messenger.core.connection.MercuryConnection;
import org.mercury_im.messenger.core.connection.MercuryConnectionManager;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.exception.ConnectionNotFoundException;
import org.mercury_im.messenger.core.exception.ContactAlreadyAddedException;
import org.mercury_im.messenger.entity.contact.Peer;
@ -35,14 +34,11 @@ public class Messenger {
private static final Logger LOGGER = Logger.getLogger(Messenger.class.getName());
private final MercuryConnectionManager connectionManager;
private final Repositories repositories;
private final SchedulersFacade schedulers;
@Inject
public Messenger(Repositories repositories,
MercuryConnectionManager connectionManager,
public Messenger(MercuryConnectionManager connectionManager,
SchedulersFacade schedulers) {
this.repositories = repositories;
this.connectionManager = connectionManager;
this.schedulers = schedulers;
}

View File

@ -7,7 +7,6 @@ import org.mercury_im.messenger.core.connection.state.ConnectionPoolState;
import org.mercury_im.messenger.core.connection.state.ConnectionState;
import org.mercury_im.messenger.core.crypto.MercuryOpenPgpManager;
import org.mercury_im.messenger.core.data.repository.AccountRepository;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.store.caps.MercuryEntityCapsStore;
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory;
@ -58,14 +57,14 @@ public class MercuryConnectionManager {
}
@Inject
public MercuryConnectionManager(Repositories repositories,
public MercuryConnectionManager(AccountRepository accountRepository,
RosterStoreBinder rosterStoreBinder,
MercuryEntityCapsStore entityCapsStore,
MercuryMessageStoreFactory messageStoreFactory,
XmppConnectionFactory connectionFactory,
MercuryOpenPgpManager cryptoManager,
SchedulersFacade schedulers) {
this.accountRepository = repositories.getAccountRepository();
this.accountRepository = accountRepository;
this.rosterStoreBinder = rosterStoreBinder;
this.connectionFactory = connectionFactory;
this.messageStoreFactory = messageStoreFactory;
@ -131,8 +130,8 @@ public class MercuryConnectionManager {
private BiPredicate<Optional<Account>, Optional<Account>> accountNotToggledNorRemoved = (first, second) ->
// Account not removed
first.isPresent() == second.isPresent()
// If account is not removed check if not toggled
&& (!first.isPresent() || first.getItem().isEnabled() == second.getItem().isEnabled());
// If account is not removed check if not toggled
&& (!first.isPresent() || first.getItem().isEnabled() == second.getItem().isEnabled());
private synchronized void putConnection(MercuryConnection connection) {
connectionsMap.put(connection.getAccountId(), connection);

View File

@ -14,7 +14,6 @@ import org.mercury_im.messenger.core.data.repository.AccountRepository;
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.listener.IncomingDirectMessageListener;
import org.mercury_im.messenger.entity.Account;
import org.mercury_im.messenger.entity.chat.DirectChat;
@ -44,13 +43,15 @@ public class XmppDirectMessageCenter
private Set<IncomingDirectMessageListener> messageListeners = new LinkedHashSet<>();
@Inject
public XmppDirectMessageCenter(Account account, Messenger messenger, Repositories repositories) {
public XmppDirectMessageCenter(Account account, Messenger messenger, PeerRepository peerRepository,
AccountRepository accountRepository, DirectChatRepository directChatRepository,
MessageRepository messageRepository) {
this.messenger = messenger;
this.account = account;
this.peerRepository = repositories.getPeerRepository();
this.accountRepository = repositories.getAccountRepository();
this.directChatRepository = repositories.getDirectChatRepository();
this.messageRepository = repositories.getMessageRepository();
this.peerRepository = peerRepository;
this.accountRepository = accountRepository;
this.directChatRepository = directChatRepository;
this.messageRepository = messageRepository;
XMPPConnection connection = getMessenger().getConnectionManager().getConnection(account).getConnection();

View File

@ -0,0 +1,16 @@
package org.mercury_im.messenger.core.crypto;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
/**
* For testing purposes we always use the same static passphrase for secret key backups.
* This obviously MUST NOT make it to production!
*/
public class InsecureStaticSecretKeyBackupPassphraseGenerator implements OpenPgpSecretKeyBackupPassphraseGenerator {
@Override
public OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase() {
return new OpenPgpSecretKeyBackupPassphrase("71ZA-Y416-UA7A-7NCE-3SNM-88EF");
}
}

View File

@ -3,18 +3,20 @@ package org.mercury_im.messenger.core.crypto;
import org.jivesoftware.smack.AbstractConnectionListener;
import org.jivesoftware.smack.XMPPConnection;
import org.jivesoftware.smackx.ox.OpenPgpManager;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
import org.jivesoftware.smackx.ox.crypto.OpenPgpProvider;
import org.jivesoftware.smackx.ox.crypto.PainlessOpenPgpProvider;
import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException;
import org.jivesoftware.smackx.ox.exception.NoBackupFoundException;
import org.jivesoftware.smackx.ox.store.definition.OpenPgpStore;
import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper;
import org.jivesoftware.smackx.ox_im.OXInstantMessagingManager;
import org.jivesoftware.smackx.pubsub.PubSubException;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.connection.MercuryConnection;
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
import org.mercury_im.messenger.core.data.repository.OpenPgpRepository;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.store.crypto.MercuryOpenPgpStore;
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
@ -27,17 +29,26 @@ public class MercuryOpenPgpManager {
private static final Logger LOGGER = Logger.getLogger(MercuryOpenPgpManager.class.getName());
private final Repositories repositories;
private final PeerRepository peerRepository;
private final DirectChatRepository directChatRepository;
private final MessageRepository messageRepository;
private final OpenPgpRepository openPgpRepository;
private final SchedulersFacade schedulers;
private final OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator;
@Inject
public MercuryOpenPgpManager(OpenPgpRepository openPgpRepository,
SchedulersFacade schedulers,
Repositories repositories) {
public MercuryOpenPgpManager(PeerRepository peerRepository,
DirectChatRepository directChatRepository,
MessageRepository messageRepository,
OpenPgpRepository openPgpRepository,
OpenPgpSecretKeyBackupPassphraseGenerator passphraseGenerator,
SchedulersFacade schedulers) {
this.peerRepository = peerRepository;
this.directChatRepository = directChatRepository;
this.messageRepository = messageRepository;
this.openPgpRepository = openPgpRepository;
this.schedulers = schedulers;
this.repositories = repositories;
this.passphraseGenerator = passphraseGenerator;
}
public void initialize(MercuryConnection connection) {
@ -56,14 +67,11 @@ public class MercuryOpenPgpManager {
}
private void setup(MercuryConnection connection) {
final String temporaryFixedTestingPassword = "71ZA-Y416-UA7A-7NCE-3SNM-88EF";
OpenPgpStore store = new MercuryOpenPgpStore(connection.getAccountId(), openPgpRepository, schedulers);
OpenPgpProvider provider = new PainlessOpenPgpProvider(store);
OpenPgpManager oxManager = OpenPgpManager.getInstanceFor(connection.getConnection());
oxManager.setOpenPgpProvider(provider);
SecretKeyBackupHelper.setBackupCodeGenerator(
// TODO: REMOVE IN PRODUCTION!!!
() -> temporaryFixedTestingPassword);
OpenPgpSecretKeyBackupPassphrase passphrase = passphraseGenerator.generateBackupPassphrase();
try {
boolean mustGenerate = false;
if (!oxManager.hasSecretKeysAvailable()) {
@ -71,7 +79,7 @@ public class MercuryOpenPgpManager {
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
try {
oxManager.restoreSecretKeyServerBackup(
() -> temporaryFixedTestingPassword);
() -> passphrase);
mustGenerate = false;
LOGGER.log(Level.INFO, "Successfully restored secret key backup!");
} catch (NoBackupFoundException | PubSubException.NotALeafNodeException | InvalidBackupCodeException e) {
@ -84,15 +92,14 @@ public class MercuryOpenPgpManager {
oxManager.generateAndImportKeyPair(connection.getAccount().getJid());
if (OpenPgpManager.serverSupportsSecretKeyBackups(connection.getConnection())) {
oxManager.backupSecretKeyToServer(
backupCode -> LOGGER.log(Level.INFO, "OpenPGP Backup Code: " + backupCode),
availableSecretKeys -> availableSecretKeys);
availableSecretKeys -> availableSecretKeys,
passphrase);
}
}
oxManager.announceSupportAndPublish();
OXInstantMessagingManager oximManager = OXInstantMessagingManager.getInstanceFor(connection.getConnection());
oximManager.addOxMessageListener(new MercuryMessageStore(connection.getAccount(),
repositories.getPeerRepository(), repositories.getDirectChatRepository(),
repositories.getMessageRepository(), schedulers));
peerRepository, directChatRepository, messageRepository, schedulers));
oximManager.announceSupportForOxInstantMessaging();
} catch (Exception e) {
e.printStackTrace();

View File

@ -0,0 +1,8 @@
package org.mercury_im.messenger.core.crypto;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
public interface OpenPgpSecretKeyBackupPassphraseGenerator {
OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase();
}

View File

@ -0,0 +1,13 @@
package org.mercury_im.messenger.core.crypto;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
import org.jivesoftware.smackx.ox.util.SecretKeyBackupHelper;
public class SecureRandomSecretKeyBackupPassphraseGenerator implements OpenPgpSecretKeyBackupPassphraseGenerator {
@Override
public OpenPgpSecretKeyBackupPassphrase generateBackupPassphrase() {
return SecretKeyBackupHelper.generateBackupPassword();
}
}

View File

@ -1,36 +0,0 @@
package org.mercury_im.messenger.core.data.repository;
import javax.inject.Inject;
import javax.inject.Singleton;
import lombok.Value;
@Singleton
@Value
public class Repositories {
AccountRepository accountRepository;
DirectChatRepository directChatRepository;
GroupChatRepository groupChatRepository;
MessageRepository messageRepository;
PeerRepository peerRepository;
EntityCapsRepository entityCapsRepository;
OpenPgpRepository openPgpRepository;
@Inject
public Repositories(AccountRepository accountRepository,
DirectChatRepository directChatRepository,
GroupChatRepository groupChatRepository,
MessageRepository messageRepository,
PeerRepository peerRepository,
EntityCapsRepository entityCapsRepository,
OpenPgpRepository openPgpRepository) {
this.accountRepository = accountRepository;
this.directChatRepository = directChatRepository;
this.groupChatRepository = groupChatRepository;
this.messageRepository = messageRepository;
this.peerRepository = peerRepository;
this.entityCapsRepository = entityCapsRepository;
this.openPgpRepository = openPgpRepository;
}
}

View File

@ -1,8 +1,21 @@
package org.mercury_im.messenger.core.di.module;
import org.mercury_im.messenger.core.crypto.InsecureStaticSecretKeyBackupPassphraseGenerator;
import org.mercury_im.messenger.core.crypto.OpenPgpSecretKeyBackupPassphraseGenerator;
import javax.inject.Singleton;
import dagger.Module;
import dagger.Provides;
@Module
public class OpenPgpModule {
@Singleton
@Provides
static OpenPgpSecretKeyBackupPassphraseGenerator provideSecretKeyBackupPassphraseGenerator() {
// TODO: THIS MUST NEVER MAKE IT TO PRODUCTION!!!
return new InsecureStaticSecretKeyBackupPassphraseGenerator();
}
}

View File

@ -1,7 +1,9 @@
package org.mercury_im.messenger.core.di.module;
import org.mercury_im.messenger.core.SchedulersFacade;
import org.mercury_im.messenger.core.data.repository.Repositories;
import org.mercury_im.messenger.core.data.repository.DirectChatRepository;
import org.mercury_im.messenger.core.data.repository.MessageRepository;
import org.mercury_im.messenger.core.data.repository.PeerRepository;
import org.mercury_im.messenger.core.store.message.MercuryMessageStore;
import org.mercury_im.messenger.core.store.message.MercuryMessageStoreFactory;
@ -15,12 +17,12 @@ public class RxMercuryMessageStoreFactoryModule {
@Provides
@Singleton
static MercuryMessageStoreFactory provideMessageStoreFactory(Repositories repositories, SchedulersFacade schedulers) {
static MercuryMessageStoreFactory provideMessageStoreFactory(PeerRepository peerRepository,
DirectChatRepository directChatRepository,
MessageRepository messageRepository,
SchedulersFacade schedulers) {
return account -> new MercuryMessageStore(account,
repositories.getPeerRepository(),
repositories.getDirectChatRepository(),
repositories.getMessageRepository(),
schedulers);
return account -> new MercuryMessageStore(account, peerRepository, directChatRepository,
messageRepository, schedulers);
}
}

View File

@ -4,6 +4,7 @@ import org.bouncycastle.openpgp.PGPException;
import org.jivesoftware.smack.SmackException;
import org.jivesoftware.smack.XMPPException;
import org.jivesoftware.smackx.ox.OpenPgpManager;
import org.jivesoftware.smackx.ox.OpenPgpSecretKeyBackupPassphrase;
import org.jivesoftware.smackx.ox.exception.InvalidBackupCodeException;
import org.jivesoftware.smackx.ox.exception.MissingUserIdOnKeyException;
import org.jivesoftware.smackx.ox.exception.NoBackupFoundException;
@ -41,7 +42,8 @@ public class OxSecretKeyBackupRestoreViewModel implements MercuryViewModel {
public void onRestoreCodeEntered(String code) {
try {
OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> code);
OpenPgpSecretKeyBackupPassphrase passphrase = new OpenPgpSecretKeyBackupPassphrase(code);
OpenPgpV4Fingerprint fingerprint = openPgpManager.restoreSecretKeyServerBackup(() -> passphrase);
LOGGER.log(Level.INFO, "Successfully restored OX secret key " + fingerprint + " for " + openPgpManager.getOpenPgpSelf().getJid());
finished.onNext(true);
} catch (InvalidBackupCodeException e) {

@ -1 +1 @@
Subproject commit f1f0a3d61ac9698bfbc627db4b6fdde5e478c4d8
Subproject commit 1267729430f2c53f966b98febf16ef7f262b94d7