Prevent possible UUID-only recipient creations.

This commit is contained in:
Greyson Parrelli 2019-12-04 23:54:56 -05:00
parent 911ca7c29d
commit f832a36a5e
3 changed files with 40 additions and 24 deletions

View file

@ -293,18 +293,7 @@ public class SignalServiceCipher {
} else if (e164Address != null && store.containsSession(e164Address)) { } else if (e164Address != null && store.containsSession(e164Address)) {
return e164Address; return e164Address;
} else { } else {
// TODO [greyson][uuid] We should switch to preferring the UUID once we allow UUID-only recipients return new SignalProtocolAddress(address.getLegacyIdentifier(), sourceDevice);
String preferred;
if (address.getNumber().isPresent()) {
preferred = address.getNumber().get();
} else if (address.getUuid().isPresent()) {
preferred = address.getUuid().get().toString();
} else {
throw new AssertionError("Given the constrains of creating a SignalServiceAddress, this should not be possible.");
}
return new SignalProtocolAddress(preferred, sourceDevice);
} }
} }

View file

@ -69,6 +69,16 @@ public class SignalServiceAddress {
} }
} }
public String getLegacyIdentifier() {
if (e164.isPresent()) {
return e164.get();
} else if (uuid.isPresent()) {
return uuid.get().toString();
} else {
throw new AssertionError("Given the checks in the constructor, this should not be possible.");
}
}
public Optional<String> getRelay() { public Optional<String> getRelay() {
return relay; return relay;
} }

View file

@ -15,6 +15,8 @@ import org.whispersystems.libsignal.state.SessionRecord;
import org.whispersystems.libsignal.state.SessionStore; import org.whispersystems.libsignal.state.SessionStore;
import org.whispersystems.signalservice.api.util.UuidUtil; import org.whispersystems.signalservice.api.util.UuidUtil;
import java.util.Collection;
import java.util.Collections;
import java.util.List; import java.util.List;
import java.util.logging.Logger; import java.util.logging.Logger;
@ -72,29 +74,41 @@ public class TextSecureSessionStore implements SessionStore {
@Override @Override
public void deleteSession(SignalProtocolAddress address) { public void deleteSession(SignalProtocolAddress address) {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
if (DatabaseFactory.getRecipientDatabase(context).containsPhoneOrUuid(address.getName())) {
RecipientId recipientId = Recipient.external(context, address.getName()).getId(); RecipientId recipientId = Recipient.external(context, address.getName()).getId();
DatabaseFactory.getSessionDatabase(context).delete(recipientId, address.getDeviceId()); DatabaseFactory.getSessionDatabase(context).delete(recipientId, address.getDeviceId());
} else {
Log.w(TAG, "Tried to delete session for " + address.toString() + ", but none existed!");
}
} }
} }
@Override @Override
public void deleteAllSessions(String name) { public void deleteAllSessions(String name) {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
if (DatabaseFactory.getRecipientDatabase(context).containsPhoneOrUuid(name)) {
RecipientId recipientId = Recipient.external(context, name).getId(); RecipientId recipientId = Recipient.external(context, name).getId();
DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipientId); DatabaseFactory.getSessionDatabase(context).deleteAllFor(recipientId);
} }
} }
}
@Override @Override
public List<Integer> getSubDeviceSessions(String name) { public List<Integer> getSubDeviceSessions(String name) {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
if (DatabaseFactory.getRecipientDatabase(context).containsPhoneOrUuid(name)) {
RecipientId recipientId = Recipient.external(context, name).getId(); RecipientId recipientId = Recipient.external(context, name).getId();
return DatabaseFactory.getSessionDatabase(context).getSubDevices(recipientId); return DatabaseFactory.getSessionDatabase(context).getSubDevices(recipientId);
} else {
Log.w(TAG, "Tried to get sub device sessions for " + name + ", but none existed!");
return Collections.emptyList();
}
} }
} }
public void archiveSiblingSessions(@NonNull SignalProtocolAddress address) { public void archiveSiblingSessions(@NonNull SignalProtocolAddress address) {
synchronized (FILE_LOCK) { synchronized (FILE_LOCK) {
if (DatabaseFactory.getRecipientDatabase(context).containsPhoneOrUuid(address.getName())) {
RecipientId recipientId = Recipient.external(context, address.getName()).getId(); RecipientId recipientId = Recipient.external(context, address.getName()).getId();
List<SessionDatabase.SessionRow> sessions = DatabaseFactory.getSessionDatabase(context).getAllFor(recipientId); List<SessionDatabase.SessionRow> sessions = DatabaseFactory.getSessionDatabase(context).getAllFor(recipientId);
@ -104,6 +118,9 @@ public class TextSecureSessionStore implements SessionStore {
storeSession(new SignalProtocolAddress(Recipient.resolved(row.getRecipientId()).requireServiceId(), row.getDeviceId()), row.getRecord()); storeSession(new SignalProtocolAddress(Recipient.resolved(row.getRecipientId()).requireServiceId(), row.getDeviceId()), row.getRecord());
} }
} }
} else {
Log.w(TAG, "Tried to archive sibling sessions for " + address.toString() + ", but none existed!");
}
} }
} }