mirror of
https://github.com/AsamK/signal-cli
synced 2025-08-29 18:40:39 +00:00
Retrieve profile to get latest identity key
This commit is contained in:
parent
2ef59d692a
commit
deb4ecd04f
2 changed files with 88 additions and 21 deletions
|
@ -157,3 +157,32 @@ class SendGroupInfoAction implements HandleAction {
|
||||||
return result;
|
return result;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class RetrieveProfileAction implements HandleAction {
|
||||||
|
|
||||||
|
private final SignalServiceAddress address;
|
||||||
|
|
||||||
|
public RetrieveProfileAction(final SignalServiceAddress address) {
|
||||||
|
this.address = address;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void execute(Manager m) throws Throwable {
|
||||||
|
m.getRecipientProfile(address, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public boolean equals(final Object o) {
|
||||||
|
if (this == o) return true;
|
||||||
|
if (o == null || getClass() != o.getClass()) return false;
|
||||||
|
|
||||||
|
final RetrieveProfileAction that = (RetrieveProfileAction) o;
|
||||||
|
|
||||||
|
return address.equals(that.address);
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public int hashCode() {
|
||||||
|
return address.hashCode();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
|
@ -146,6 +146,7 @@ import java.nio.file.Files;
|
||||||
import java.security.SignatureException;
|
import java.security.SignatureException;
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
|
import java.util.Base64;
|
||||||
import java.util.Collection;
|
import java.util.Collection;
|
||||||
import java.util.Date;
|
import java.util.Date;
|
||||||
import java.util.HashSet;
|
import java.util.HashSet;
|
||||||
|
@ -532,11 +533,13 @@ public class Manager implements Closeable {
|
||||||
return getRecipientProfile(address, false);
|
return getRecipientProfile(address, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
private SignalProfile getRecipientProfile(
|
SignalProfile getRecipientProfile(
|
||||||
SignalServiceAddress address, boolean force
|
SignalServiceAddress address, boolean force
|
||||||
) {
|
) {
|
||||||
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
||||||
if (profileEntry == null) {
|
if (profileEntry == null) {
|
||||||
|
// retrieve profile to get identity key
|
||||||
|
retrieveEncryptedProfile(address);
|
||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
var now = new Date().getTime();
|
var now = new Date().getTime();
|
||||||
|
@ -549,14 +552,13 @@ public class Manager implements Closeable {
|
||||||
profileEntry.setRequestPending(true);
|
profileEntry.setRequestPending(true);
|
||||||
final SignalServiceProfile encryptedProfile;
|
final SignalServiceProfile encryptedProfile;
|
||||||
try {
|
try {
|
||||||
encryptedProfile = profileHelper.retrieveProfileSync(address, SignalServiceProfile.RequestType.PROFILE)
|
encryptedProfile = retrieveEncryptedProfile(address);
|
||||||
.getProfile();
|
|
||||||
} catch (IOException e) {
|
|
||||||
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
|
||||||
return null;
|
|
||||||
} finally {
|
} finally {
|
||||||
profileEntry.setRequestPending(false);
|
profileEntry.setRequestPending(false);
|
||||||
}
|
}
|
||||||
|
if (encryptedProfile == null) {
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
final var profileKey = profileEntry.getProfileKey();
|
final var profileKey = profileEntry.getProfileKey();
|
||||||
final var profile = decryptProfileAndDownloadAvatar(address, profileKey, encryptedProfile);
|
final var profile = decryptProfileAndDownloadAvatar(address, profileKey, encryptedProfile);
|
||||||
|
@ -567,6 +569,25 @@ public class Manager implements Closeable {
|
||||||
return profileEntry.getProfile();
|
return profileEntry.getProfile();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private SignalServiceProfile retrieveEncryptedProfile(SignalServiceAddress address) {
|
||||||
|
try {
|
||||||
|
final var profile = profileHelper.retrieveProfileSync(address, SignalServiceProfile.RequestType.PROFILE)
|
||||||
|
.getProfile();
|
||||||
|
try {
|
||||||
|
account.getIdentityKeyStore()
|
||||||
|
.saveIdentity(resolveRecipient(address),
|
||||||
|
new IdentityKey(Base64.getDecoder().decode(profile.getIdentityKey())),
|
||||||
|
new Date());
|
||||||
|
} catch (InvalidKeyException ignored) {
|
||||||
|
logger.warn("Got invalid identity key in profile for {}", address.getLegacyIdentifier());
|
||||||
|
}
|
||||||
|
return profile;
|
||||||
|
} catch (IOException e) {
|
||||||
|
logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private ProfileKeyCredential getRecipientProfileKeyCredential(SignalServiceAddress address) {
|
private ProfileKeyCredential getRecipientProfileKeyCredential(SignalServiceAddress address) {
|
||||||
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
var profileEntry = account.getProfileStore().getProfileEntry(address);
|
||||||
if (profileEntry == null) {
|
if (profileEntry == null) {
|
||||||
|
@ -1292,6 +1313,16 @@ public class Manager implements Closeable {
|
||||||
unidentifiedAccessHelper.getAccessFor(recipients),
|
unidentifiedAccessHelper.getAccessFor(recipients),
|
||||||
isRecipientUpdate,
|
isRecipientUpdate,
|
||||||
message);
|
message);
|
||||||
|
|
||||||
|
for (var r : result) {
|
||||||
|
if (r.getIdentityFailure() != null) {
|
||||||
|
account.getIdentityKeyStore().
|
||||||
|
saveIdentity(resolveRecipient(r.getAddress()),
|
||||||
|
r.getIdentityFailure().getIdentityKey(),
|
||||||
|
new Date());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
return new Pair<>(timestamp, result);
|
return new Pair<>(timestamp, result);
|
||||||
} catch (UntrustedIdentityException e) {
|
} catch (UntrustedIdentityException e) {
|
||||||
return new Pair<>(timestamp, List.of());
|
return new Pair<>(timestamp, List.of());
|
||||||
|
@ -1612,19 +1643,31 @@ public class Manager implements Closeable {
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retryFailedReceivedMessages(ReceiveMessageHandler handler, boolean ignoreAttachments) {
|
private void retryFailedReceivedMessages(ReceiveMessageHandler handler, boolean ignoreAttachments) {
|
||||||
|
Set<HandleAction> queuedActions = new HashSet<>();
|
||||||
for (var cachedMessage : account.getMessageCache().getCachedMessages()) {
|
for (var cachedMessage : account.getMessageCache().getCachedMessages()) {
|
||||||
retryFailedReceivedMessage(handler, ignoreAttachments, cachedMessage);
|
var actions = retryFailedReceivedMessage(handler, ignoreAttachments, cachedMessage);
|
||||||
|
if (actions != null) {
|
||||||
|
queuedActions.addAll(actions);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
for (var action : queuedActions) {
|
||||||
|
try {
|
||||||
|
action.execute(this);
|
||||||
|
} catch (Throwable e) {
|
||||||
|
logger.warn("Message action failed.", e);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retryFailedReceivedMessage(
|
private List<HandleAction> retryFailedReceivedMessage(
|
||||||
final ReceiveMessageHandler handler, final boolean ignoreAttachments, final CachedMessage cachedMessage
|
final ReceiveMessageHandler handler, final boolean ignoreAttachments, final CachedMessage cachedMessage
|
||||||
) {
|
) {
|
||||||
var envelope = cachedMessage.loadEnvelope();
|
var envelope = cachedMessage.loadEnvelope();
|
||||||
if (envelope == null) {
|
if (envelope == null) {
|
||||||
return;
|
return null;
|
||||||
}
|
}
|
||||||
SignalServiceContent content = null;
|
SignalServiceContent content = null;
|
||||||
|
List<HandleAction> actions = null;
|
||||||
if (!envelope.isReceipt()) {
|
if (!envelope.isReceipt()) {
|
||||||
try {
|
try {
|
||||||
content = decryptMessage(envelope);
|
content = decryptMessage(envelope);
|
||||||
|
@ -1638,24 +1681,18 @@ public class Manager implements Closeable {
|
||||||
logger.warn("Failed to move cached message to recipient folder: {}", ioException.getMessage());
|
logger.warn("Failed to move cached message to recipient folder: {}", ioException.getMessage());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return;
|
return null;
|
||||||
} catch (Exception er) {
|
} catch (Exception er) {
|
||||||
// All other errors are not recoverable, so delete the cached message
|
// All other errors are not recoverable, so delete the cached message
|
||||||
cachedMessage.delete();
|
cachedMessage.delete();
|
||||||
return;
|
return null;
|
||||||
}
|
|
||||||
var actions = handleMessage(envelope, content, ignoreAttachments);
|
|
||||||
for (var action : actions) {
|
|
||||||
try {
|
|
||||||
action.execute(this);
|
|
||||||
} catch (Throwable e) {
|
|
||||||
logger.warn("Message action failed.", e);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
actions = handleMessage(envelope, content, ignoreAttachments);
|
||||||
}
|
}
|
||||||
account.save();
|
account.save();
|
||||||
handler.handleMessage(envelope, content, null);
|
handler.handleMessage(envelope, content, null);
|
||||||
cachedMessage.delete();
|
cachedMessage.delete();
|
||||||
|
return actions;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void receiveMessages(
|
public void receiveMessages(
|
||||||
|
@ -1749,9 +1786,10 @@ public class Manager implements Closeable {
|
||||||
}
|
}
|
||||||
if (cachedMessage[0] != null) {
|
if (cachedMessage[0] != null) {
|
||||||
if (exception instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
|
if (exception instanceof org.whispersystems.libsignal.UntrustedIdentityException) {
|
||||||
if (!envelope.hasSource()) {
|
|
||||||
final var recipientId = resolveRecipient(((org.whispersystems.libsignal.UntrustedIdentityException) exception)
|
final var recipientId = resolveRecipient(((org.whispersystems.libsignal.UntrustedIdentityException) exception)
|
||||||
.getName());
|
.getName());
|
||||||
|
queuedActions.add(new RetrieveProfileAction(resolveSignalServiceAddress(recipientId)));
|
||||||
|
if (!envelope.hasSource()) {
|
||||||
try {
|
try {
|
||||||
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
|
cachedMessage[0] = account.getMessageCache().replaceSender(cachedMessage[0], recipientId);
|
||||||
} catch (IOException ioException) {
|
} catch (IOException ioException) {
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue