implementation 'org.bouncycastle:bcprov-jdk15on:1.67'
implementation 'net.sourceforge.argparse4j:argparse4j:0.8.1'
implementation 'com.github.hypfvieh:dbus-java:3.2.4'
- implementation 'org.slf4j:slf4j-nop:1.7.30'
+ implementation 'org.slf4j:slf4j-simple:1.7.30'
}
jar {
import org.bouncycastle.jce.provider.BouncyCastleProvider;
import org.freedesktop.dbus.connections.impl.DBusConnection;
import org.freedesktop.dbus.exceptions.DBusException;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.signalservice.api.push.exceptions.AuthorizationFailedException;
import org.whispersystems.signalservice.api.util.PhoneNumberFormatter;
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import java.security.Security;
import java.util.Map;
-import static org.whispersystems.signalservice.internal.util.Util.isEmpty;
-
public class Main {
+ final static Logger logger = LoggerFactory.getLogger(Main.class);
+
public static void main(String[] args) {
installSecurityProviderWorkaround();
System.exit(1);
}
- int res = handleCommands(ns);
+ int res = init(ns);
System.exit(res);
}
Security.addProvider(new BouncyCastleProvider());
}
- private static int handleCommands(Namespace ns) {
- final String username = ns.getString("username");
-
+ public static int init(Namespace ns) {
if (ns.getBoolean("dbus") || ns.getBoolean("dbus_system")) {
- try {
- DBusConnection.DBusBusType busType;
- if (ns.getBoolean("dbus_system")) {
- busType = DBusConnection.DBusBusType.SYSTEM;
- } else {
- busType = DBusConnection.DBusBusType.SESSION;
- }
- try (DBusConnection dBusConn = DBusConnection.getConnection(busType)) {
- Signal ts = dBusConn.getRemoteObject(DbusConfig.SIGNAL_BUSNAME,
- DbusConfig.SIGNAL_OBJECTPATH,
- Signal.class);
+ return initDbusClient(ns, ns.getBoolean("dbus_system"));
+ }
- return handleCommands(ns, ts, dBusConn);
- }
- } catch (UnsatisfiedLinkError e) {
- System.err.println("Missing native library dependency for dbus service: " + e.getMessage());
- return 1;
- } catch (DBusException | IOException e) {
- e.printStackTrace();
- return 3;
- }
+ final String username = ns.getString("username");
+
+ final File dataPath;
+ String config = ns.getString("config");
+ if (config != null) {
+ dataPath = new File(config);
} else {
- String dataPath = ns.getString("config");
- if (isEmpty(dataPath)) {
- dataPath = getDefaultDataPath();
- }
+ dataPath = getDefaultDataPath();
+ }
- final SignalServiceConfiguration serviceConfiguration = ServiceConfig.createDefaultServiceConfiguration(
- BaseConfig.USER_AGENT);
+ final SignalServiceConfiguration serviceConfiguration = ServiceConfig.createDefaultServiceConfiguration(
+ BaseConfig.USER_AGENT);
- if (!ServiceConfig.getCapabilities().isGv2()) {
- System.err.println("WARNING: Support for new group V2 is disabled,"
- + " because the required native library dependency is missing: libzkgroup");
- }
+ if (!ServiceConfig.getCapabilities().isGv2()) {
+ logger.warn("WARNING: Support for new group V2 is disabled,"
+ + " because the required native library dependency is missing: libzkgroup");
+ }
- if (username == null) {
- ProvisioningManager pm = new ProvisioningManager(dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
- return handleCommands(ns, pm);
- }
+ if (username == null) {
+ ProvisioningManager pm = new ProvisioningManager(dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
+ return handleCommands(ns, pm);
+ }
- Manager manager;
+ Manager manager;
+ try {
+ manager = Manager.init(username, dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
+ } catch (Throwable e) {
+ logger.error("Error loading state file: {}", e.getMessage());
+ return 2;
+ }
+
+ try (Manager m = manager) {
try {
- manager = Manager.init(username, dataPath, serviceConfiguration, BaseConfig.USER_AGENT);
- } catch (Throwable e) {
- System.err.println("Error loading state file: " + e.getMessage());
+ m.checkAccountState();
+ } catch (AuthorizationFailedException e) {
+ if (!"register".equals(ns.getString("command"))) {
+ // Register command should still be possible, if current authorization fails
+ System.err.println("Authorization failed, was the number registered elsewhere?");
+ return 2;
+ }
+ } catch (IOException e) {
+ logger.error("Error while checking account: {}", e.getMessage());
return 2;
}
- try (Manager m = manager) {
- try {
- m.checkAccountState();
- } catch (AuthorizationFailedException e) {
- if (!"register".equals(ns.getString("command"))) {
- // Register command should still be possible, if current authorization fails
- System.err.println("Authorization failed, was the number registered elsewhere?");
- return 2;
- }
- } catch (IOException e) {
- System.err.println("Error while checking account: " + e.getMessage());
- return 2;
- }
+ return handleCommands(ns, m);
+ } catch (IOException e) {
+ logger.error("Cleanup failed", e);
+ return 3;
+ }
+ }
- return handleCommands(ns, m);
- } catch (IOException e) {
- e.printStackTrace();
- return 3;
+ private static int initDbusClient(final Namespace ns, final boolean systemBus) {
+ try {
+ DBusConnection.DBusBusType busType;
+ if (systemBus) {
+ busType = DBusConnection.DBusBusType.SYSTEM;
+ } else {
+ busType = DBusConnection.DBusBusType.SESSION;
+ }
+ try (DBusConnection dBusConn = DBusConnection.getConnection(busType)) {
+ Signal ts = dBusConn.getRemoteObject(DbusConfig.SIGNAL_BUSNAME,
+ DbusConfig.SIGNAL_OBJECTPATH,
+ Signal.class);
+
+ return handleCommands(ns, ts, dBusConn);
}
+ } catch (DBusException | IOException e) {
+ logger.error("Dbus client failed", e);
+ return 3;
}
}
*
* @return the data directory to be used by signal-cli.
*/
- private static String getDefaultDataPath() {
- String dataPath = IOUtils.getDataHomeDir() + "/signal-cli";
- if (new File(dataPath).exists()) {
+ private static File getDefaultDataPath() {
+ File dataPath = new File(IOUtils.getDataHomeDir(), "/signal-cli");
+ if (dataPath.exists()) {
return dataPath;
}
- String legacySettingsPath = System.getProperty("user.home") + "/.config/signal";
- if (new File(legacySettingsPath).exists()) {
+ File legacySettingsPath = new File(System.getProperty("user.home"), "/.config/signal");
+ if (legacySettingsPath.exists()) {
return legacySettingsPath;
}
- legacySettingsPath = System.getProperty("user.home") + "/.config/textsecure";
- if (new File(legacySettingsPath).exists()) {
+ legacySettingsPath = new File(System.getProperty("user.home"), "/.config/textsecure");
+ if (legacySettingsPath.exists()) {
return legacySettingsPath;
}
}
private static Namespace parseArgs(String[] args) {
- ArgumentParser parser = ArgumentParsers.newFor("signal-cli")
- .build()
- .defaultHelp(true)
- .description("Commandline interface for Signal.")
- .version(BaseConfig.PROJECT_NAME + " " + BaseConfig.PROJECT_VERSION);
-
- parser.addArgument("-v", "--version").help("Show package version.").action(Arguments.version());
- parser.addArgument("--config")
- .help("Set the path, where to store the config (Default: $XDG_DATA_HOME/signal-cli , $HOME/.local/share/signal-cli).");
-
- MutuallyExclusiveGroup mut = parser.addMutuallyExclusiveGroup();
- mut.addArgument("-u", "--username").help("Specify your phone number, that will be used for verification.");
- mut.addArgument("--dbus").help("Make request via user dbus.").action(Arguments.storeTrue());
- mut.addArgument("--dbus-system").help("Make request via system dbus.").action(Arguments.storeTrue());
-
- Subparsers subparsers = parser.addSubparsers()
- .title("subcommands")
- .dest("command")
- .description("valid subcommands")
- .help("additional help");
-
- final Map<String, Command> commands = Commands.getCommands();
- for (Map.Entry<String, Command> entry : commands.entrySet()) {
- Subparser subparser = subparsers.addParser(entry.getKey());
- entry.getValue().attachToSubparser(subparser);
- }
+ ArgumentParser parser = buildArgumentParser();
Namespace ns;
try {
}
return ns;
}
+
+ private static ArgumentParser buildArgumentParser() {
+ ArgumentParser parser = ArgumentParsers.newFor("signal-cli")
+ .build()
+ .defaultHelp(true)
+ .description("Commandline interface for Signal.")
+ .version(BaseConfig.PROJECT_NAME + " " + BaseConfig.PROJECT_VERSION);
+
+ parser.addArgument("-v", "--version").help("Show package version.").action(Arguments.version());
+ parser.addArgument("--config")
+ .help("Set the path, where to store the config (Default: $XDG_DATA_HOME/signal-cli , $HOME/.local/share/signal-cli).");
+
+ MutuallyExclusiveGroup mut = parser.addMutuallyExclusiveGroup();
+ mut.addArgument("-u", "--username").help("Specify your phone number, that will be used for verification.");
+ mut.addArgument("--dbus").help("Make request via user dbus.").action(Arguments.storeTrue());
+ mut.addArgument("--dbus-system").help("Make request via system dbus.").action(Arguments.storeTrue());
+
+ Subparsers subparsers = parser.addSubparsers()
+ .title("subcommands")
+ .dest("command")
+ .description("valid subcommands")
+ .help("additional help");
+
+ final Map<String, Command> commands = Commands.getCommands();
+ for (Map.Entry<String, Command> entry : commands.entrySet()) {
+ Subparser subparser = subparsers.addParser(entry.getKey());
+ entry.getValue().attachToSubparser(subparser);
+ }
+ return parser;
+ }
}
import org.signal.zkgroup.profiles.ClientZkProfileOperations;
import org.signal.zkgroup.profiles.ProfileKey;
import org.signal.zkgroup.profiles.ProfileKeyCredential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.InvalidKeyException;
public class Manager implements Closeable {
+ final static Logger logger = LoggerFactory.getLogger(Manager.class);
+
private final SleepTimer timer = new UptimeSleepTimer();
private final SignalServiceConfiguration serviceConfiguration;
}
public static Manager init(
- String username, String settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent
+ String username, File settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent
) throws IOException {
PathConfig pathConfig = PathConfig.createDefault(settingsPath);
try {
profile = retrieveRecipientProfile(address, profileKey);
} catch (IOException e) {
- System.err.println("Failed to retrieve profile, ignoring: " + e.getMessage());
+ logger.warn("Failed to retrieve profile, ignoring: {}", e.getMessage());
profileEntry.setRequestPending(false);
return null;
}
profileAndCredential = profileHelper.retrieveProfileSync(address,
SignalServiceProfile.RequestType.PROFILE_AND_CREDENTIAL);
} catch (IOException e) {
- System.err.println("Failed to retrieve profile key credential, ignoring: " + e.getMessage());
+ logger.warn("Failed to retrieve profile key credential, ignoring: {}", e.getMessage());
return null;
}
? null
: retrieveProfileAvatar(address, encryptedProfile.getAvatar(), profileKey);
} catch (Throwable e) {
- System.err.println("Failed to retrieve profile avatar, ignoring: " + e.getMessage());
+ logger.warn("Failed to retrieve profile avatar, ignoring: {}", e.getMessage());
}
ProfileCipher profileCipher = new ProfileCipher(profileKey);
try {
certificate = accountManager.getSenderCertificate();
} catch (IOException e) {
- System.err.println("Failed to get sender certificate: " + e);
+ logger.warn("Failed to get sender certificate, ignoring: {}", e.getMessage());
return null;
}
// TODO cache for a day
missingUuids.stream().map(a -> a.getNumber().get()).collect(Collectors.toSet()),
CDS_MRENCLAVE);
} catch (IOException | Quote.InvalidQuoteFormatException | UnauthenticatedQuoteException | SignatureException | UnauthenticatedResponseException e) {
- System.err.println("Failed to resolve uuids from server: " + e.getMessage());
+ logger.warn("Failed to resolve uuids from server, ignoring: {}", e.getMessage());
registeredUsers = new HashMap<>();
}
try {
retrieveGroupAvatarAttachment(avatar.asPointer(), groupV1.getGroupId());
} catch (IOException | InvalidMessageException | MissingConfigurationException e) {
- System.err.println("Failed to retrieve group avatar (" + avatar.asPointer()
- .getRemoteId() + "): " + e.getMessage());
+ logger.warn("Failed to retrieve avatar for group {}, ignoring: {}",
+ groupId.toBase64(),
+ e.getMessage());
}
}
}
}
case DELIVER:
if (groupV1 == null && !isSync) {
- actions.add(new SendGroupInfoRequestAction(source, groupV1.getGroupId()));
+ actions.add(new SendGroupInfoRequestAction(source, groupId));
}
break;
case QUIT: {
try {
retrieveAttachment(attachment.asPointer());
} catch (IOException | InvalidMessageException | MissingConfigurationException e) {
- System.err.println("Failed to retrieve attachment ("
- + attachment.asPointer().getRemoteId()
- + "): "
- + e.getMessage());
+ logger.warn("Failed to retrieve attachment ({}), ignoring: {}",
+ attachment.asPointer().getRemoteId(),
+ e.getMessage());
}
}
}
try {
retrieveAttachment(attachment);
} catch (IOException | InvalidMessageException | MissingConfigurationException e) {
- System.err.println("Failed to retrieve attachment ("
- + attachment.getRemoteId()
- + "): "
- + e.getMessage());
+ logger.warn("Failed to retrieve preview image ({}), ignoring: {}",
+ attachment.getRemoteId(),
+ e.getMessage());
}
}
}
try {
retrieveAttachment(attachment.asPointer());
} catch (IOException | InvalidMessageException | MissingConfigurationException e) {
- System.err.println("Failed to retrieve attachment ("
- + attachment.asPointer().getRemoteId()
- + "): "
- + e.getMessage());
+ logger.warn("Failed to retrieve quote attachment thumbnail ({}), ignoring: {}",
+ attachment.asPointer().getRemoteId(),
+ e.getMessage());
}
}
}
// Received a v2 group message for a v1 group, we need to locally migrate the group
account.getGroupStore().deleteGroup(groupInfo.getGroupId());
groupInfoV2 = new GroupInfoV2(groupId, groupMasterKey);
- System.err.println("Locally migrated group "
- + groupInfo.getGroupId().toBase64()
- + " to group v2, id: "
- + groupInfoV2.getGroupId().toBase64()
- + " !!!");
+ logger.info("Locally migrated group {} to group v2, id: {}",
+ groupInfo.getGroupId().toBase64(),
+ groupInfoV2.getGroupId().toBase64());
} else if (groupInfo instanceof GroupInfoV2) {
groupInfoV2 = (GroupInfoV2) groupInfo;
} else {
}
if (group != null) {
storeProfileKeysFromMembers(group);
- try {
- retrieveGroupAvatar(groupId, groupSecretParams, group.getAvatar());
- } catch (IOException e) {
- System.err.println("Failed to download group avatar, ignoring ...");
+ final String avatar = group.getAvatar();
+ if (avatar != null && !avatar.isEmpty()) {
+ try {
+ retrieveGroupAvatar(groupId, groupSecretParams, avatar);
+ } catch (IOException e) {
+ logger.warn("Failed to download group avatar, ignoring: {}", e.getMessage());
+ }
}
}
groupInfoV2.setGroup(group);
try {
Files.delete(fileEntry.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete cached message file “" + fileEntry + "”: " + e.getMessage());
+ logger.warn("Failed to delete cached message file “{}”, ignoring: {}", fileEntry, e.getMessage());
}
return;
}
try {
Files.delete(fileEntry.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete cached message file “" + fileEntry + "”: " + e.getMessage());
+ logger.warn("Failed to delete cached message file “{}”, ignoring: {}", fileEntry, e.getMessage());
}
}
File cacheFile = getMessageCacheFile(source, now, envelope1.getTimestamp());
Utils.storeEnvelope(envelope1, cacheFile);
} catch (IOException e) {
- System.err.println("Failed to store encrypted message in disk cache, ignoring: "
- + e.getMessage());
+ logger.warn("Failed to store encrypted message in disk cache, ignoring: {}", e.getMessage());
}
});
if (result.isPresent()) {
if (returnOnTimeout) return;
continue;
} catch (InvalidVersionException e) {
- System.err.println("Ignoring error: " + e.getMessage());
+ logger.warn("Error while receiving messages, ignoring: {}", e.getMessage());
continue;
}
// Try to delete directory if empty
new File(getMessageCachePath()).delete();
} catch (IOException e) {
- System.err.println("Failed to delete cached message file “" + cacheFile + "”: " + e.getMessage());
+ logger.warn("Failed to delete cached message file “{}”, ignoring: {}", cacheFile, e.getMessage());
}
}
}
}
}
} catch (Exception e) {
+ logger.warn("Failed to handle received sync groups “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
e.printStackTrace();
} finally {
if (tmpFile != null) {
try {
Files.delete(tmpFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete received groups temp file “"
- + tmpFile
- + "”: "
- + e.getMessage());
+ logger.warn("Failed to delete received groups temp file “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
}
}
}
try {
setGroupBlocked(groupId, true);
} catch (GroupNotFoundException e) {
- System.err.println("BlockedListMessage contained groupID that was not found in GroupStore: "
- + groupId.toBase64());
+ logger.warn("BlockedListMessage contained groupID that was not found in GroupStore: {}",
+ groupId.toBase64());
}
}
}
try {
Files.delete(tmpFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete received contacts temp file “"
- + tmpFile
- + "”: "
- + e.getMessage());
+ logger.warn("Failed to delete received contacts temp file “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
}
}
}
try {
Files.delete(tmpFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete received avatar temp file “" + tmpFile + "”: " + e.getMessage());
+ logger.warn("Failed to delete received group avatar temp file “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
}
}
return outputFile;
try {
Files.delete(tmpFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete received avatar temp file “" + tmpFile + "”: " + e.getMessage());
+ logger.warn("Failed to delete received profile avatar temp file “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
}
}
return outputFile;
try {
Files.delete(tmpFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete received attachment temp file “"
- + tmpFile
- + "”: "
- + e.getMessage());
+ logger.warn("Failed to delete received attachment temp file “{}”, ignoring: {}",
+ tmpFile,
+ e.getMessage());
}
}
return outputFile;
try {
Files.delete(groupsFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete groups temp file “" + groupsFile + "”: " + e.getMessage());
+ logger.warn("Failed to delete groups temp file “{}”, ignoring: {}", groupsFile, e.getMessage());
}
}
}
try {
Files.delete(contactsFile.toPath());
} catch (IOException e) {
- System.err.println("Failed to delete contacts temp file “" + contactsFile + "”: " + e.getMessage());
+ logger.warn("Failed to delete contacts temp file “{}”, ignoring: {}", contactsFile, e.getMessage());
}
}
}
package org.asamk.signal.manager;
+import java.io.File;
+
public class PathConfig {
- private final String dataPath;
- private final String attachmentsPath;
- private final String avatarsPath;
+ private final File dataPath;
+ private final File attachmentsPath;
+ private final File avatarsPath;
- public static PathConfig createDefault(final String settingsPath) {
- return new PathConfig(settingsPath + "/data", settingsPath + "/attachments", settingsPath + "/avatars");
+ public static PathConfig createDefault(final File settingsPath) {
+ return new PathConfig(new File(settingsPath, "/data"),
+ new File(settingsPath, "/attachments"),
+ new File(settingsPath, "/avatars"));
}
- private PathConfig(final String dataPath, final String attachmentsPath, final String avatarsPath) {
+ private PathConfig(final File dataPath, final File attachmentsPath, final File avatarsPath) {
this.dataPath = dataPath;
this.attachmentsPath = attachmentsPath;
this.avatarsPath = avatarsPath;
}
public String getDataPath() {
- return dataPath;
+ return dataPath.getPath();
}
public String getAttachmentsPath() {
- return attachmentsPath;
+ return attachmentsPath.getPath();
}
public String getAvatarsPath() {
- return avatarsPath;
+ return avatarsPath.getPath();
}
}
import org.whispersystems.signalservice.internal.configuration.SignalServiceConfiguration;
import org.whispersystems.signalservice.internal.util.DynamicCredentialsProvider;
+import java.io.File;
import java.io.IOException;
import java.util.concurrent.TimeoutException;
private final int registrationId;
private final String password;
- public ProvisioningManager(String settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent) {
+ public ProvisioningManager(File settingsPath, SignalServiceConfiguration serviceConfiguration, String userAgent) {
this.pathConfig = PathConfig.createDefault(settingsPath);
this.serviceConfiguration = serviceConfiguration;
this.userAgent = userAgent;
import org.asamk.signal.manager.GroupLinkPassword;
import org.asamk.signal.manager.GroupUtils;
import org.asamk.signal.storage.groups.GroupInfoV2;
+import org.asamk.signal.storage.profiles.SignalProfile;
import org.asamk.signal.util.IOUtils;
import org.signal.storageservice.protos.groups.AccessControl;
import org.signal.storageservice.protos.groups.GroupChange;
import org.signal.zkgroup.groups.GroupSecretParams;
import org.signal.zkgroup.groups.UuidCiphertext;
import org.signal.zkgroup.profiles.ProfileKeyCredential;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.util.Pair;
import org.whispersystems.libsignal.util.guava.Optional;
import org.whispersystems.signalservice.api.groupsv2.DecryptedGroupUtil;
public class GroupHelper {
+ final static Logger logger = LoggerFactory.getLogger(GroupHelper.class);
+
private final ProfileKeyCredentialProvider profileKeyCredentialProvider;
private final ProfileProvider profileProvider;
groupSecretParams);
return groupsV2Api.getGroup(groupSecretParams, groupsV2AuthorizationString);
} catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
- System.err.println("Failed to retrieve Group V2 info, ignoring ...");
+ logger.warn("Failed to retrieve Group V2 info, ignoring: {}", e.getMessage());
return null;
}
}
groupsV2Api.putNewGroup(newGroup, groupAuthForToday);
decryptedGroup = groupsV2Api.getGroup(groupSecretParams, groupAuthForToday);
} catch (IOException | VerificationFailedException | InvalidGroupStateException e) {
- System.err.println("Failed to create V2 group: " + e.getMessage());
+ logger.warn("Failed to create V2 group: {}", e.getMessage());
return null;
}
if (decryptedGroup == null) {
- System.err.println("Failed to create V2 group!");
+ logger.warn("Failed to create V2 group, unknown error!");
return null;
}
final ProfileKeyCredential profileKeyCredential = profileKeyCredentialProvider.getProfileKeyCredential(
selfAddressProvider.getSelfAddress());
if (profileKeyCredential == null) {
- System.err.println("Cannot create a V2 group as self does not have a versioned profile");
+ logger.warn("Cannot create a V2 group as self does not have a versioned profile");
return null;
}
}
private boolean areMembersValid(final Collection<SignalServiceAddress> members) {
- final int noUuidCapability = members.stream()
+ final Set<String> noUuidCapability = members.stream()
.filter(address -> !address.getUuid().isPresent())
- .collect(Collectors.toUnmodifiableSet())
- .size();
- if (noUuidCapability > 0) {
- System.err.println("Cannot create a V2 group as " + noUuidCapability + " members don't have a UUID.");
+ .map(SignalServiceAddress::getLegacyIdentifier)
+ .collect(Collectors.toSet());
+ if (noUuidCapability.size() > 0) {
+ logger.warn("Cannot create a V2 group as some members don't have a UUID: {}",
+ String.join(", ", noUuidCapability));
return false;
}
- final int noGv2Capability = members.stream()
+ final Set<SignalProfile> noGv2Capability = members.stream()
.map(profileProvider::getProfile)
.filter(profile -> profile != null && !profile.getCapabilities().gv2)
- .collect(Collectors.toUnmodifiableSet())
- .size();
- if (noGv2Capability > 0) {
- System.err.println("Cannot create a V2 group as " + noGv2Capability + " members don't support Groups V2.");
+ .collect(Collectors.toSet());
+ if (noGv2Capability.size() > 0) {
+ logger.warn("Cannot create a V2 group as some members don't support Groups V2: {}",
+ noGv2Capability.stream().map(SignalProfile::getName).collect(Collectors.joining(", ")));
return false;
}
final GroupSecretParams groupSecretParams = GroupSecretParams.deriveFromMasterKey(groupInfoV2.getMasterKey());
GroupsV2Operations.GroupOperations groupOperations = groupsV2Operations.forGroup(groupSecretParams);
- if (!areMembersValid(newMembers)) return null;
+ if (!areMembersValid(newMembers)) {
+ throw new IOException("Failed to update group");
+ }
Set<GroupCandidate> candidates = newMembers.stream()
.map(member -> new GroupCandidate(member.getUuid().get(),
import org.asamk.signal.util.Util;
import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.profiles.ProfileKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
public class SignalAccount implements Closeable {
+ final static Logger logger = LoggerFactory.getLogger(SignalAccount.class);
+
private final ObjectMapper jsonProcessor = new ObjectMapper();
private final FileChannel fileChannel;
private final FileLock lock;
}
}
} catch (Exception e) {
- System.err.println(String.format("Error saving file: %s", e.getMessage()));
+ logger.error("Error saving file: {}", e.getMessage());
}
}
FileChannel fileChannel = new RandomAccessFile(new File(fileName), "rw").getChannel();
FileLock lock = fileChannel.tryLock();
if (lock == null) {
- System.err.println("Config file is in use by another instance, waiting…");
+ logger.info("Config file is in use by another instance, waiting…");
lock = fileChannel.lock();
- System.err.println("Config file lock acquired.");
+ logger.info("Config file lock acquired.");
}
return new Pair<>(fileChannel, lock);
}
import org.signal.storageservice.protos.groups.local.DecryptedGroup;
import org.signal.zkgroup.InvalidInputException;
import org.signal.zkgroup.groups.GroupMasterKey;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.util.Base64;
import java.io.File;
public class JsonGroupStore {
+ final static Logger logger = LoggerFactory.getLogger(JsonGroupStore.class);
+
private static final ObjectMapper jsonProcessor = new ObjectMapper();
public File groupCachePath;
groupFileLegacy.delete();
}
} catch (IOException e) {
- System.err.println("Failed to cache group, ignoring ...");
+ logger.warn("Failed to cache group, ignoring: {}", e.getMessage());
}
}
}
import org.asamk.signal.manager.TrustLevel;
import org.asamk.signal.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.IdentityKey;
import org.whispersystems.libsignal.IdentityKeyPair;
import org.whispersystems.libsignal.InvalidKeyException;
public class JsonIdentityKeyStore implements IdentityKeyStore {
+ final static Logger logger = LoggerFactory.getLogger(JsonIdentityKeyStore.class);
+
private final List<Identity> identities = new ArrayList<>();
private final IdentityKeyPair identityKeyPair;
.asLong()) : new Date();
keyStore.saveIdentity(serviceAddress, id, trustLevel, added);
} catch (InvalidKeyException | IOException e) {
- System.out.println(String.format("Error while decoding key for: %s", trustedKeyName));
+ logger.warn("Error while decoding key for {}: {}", trustedKeyName, e.getMessage());
}
}
}
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.PreKeyRecord;
import org.whispersystems.libsignal.state.PreKeyStore;
class JsonPreKeyStore implements PreKeyStore {
+ final static Logger logger = LoggerFactory.getLogger(JsonPreKeyStore.class);
+
private final Map<Integer, byte[]> store = new HashMap<>();
public JsonPreKeyStore() {
try {
preKeyMap.put(preKeyId, Base64.decode(preKey.get("record").asText()));
} catch (IOException e) {
- System.err.println(String.format("Error while decoding prekey for: %s", preKeyId));
+ logger.warn("Error while decoding prekey for {}: {}", preKeyId, e.getMessage());
}
}
}
import com.fasterxml.jackson.databind.SerializerProvider;
import org.asamk.signal.util.Util;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.SignalProtocolAddress;
import org.whispersystems.libsignal.state.SessionRecord;
import org.whispersystems.libsignal.state.SessionStore;
class JsonSessionStore implements SessionStore {
+ final static Logger logger = LoggerFactory.getLogger(JsonSessionStore.class);
+
private final List<SessionInfo> sessions = new ArrayList<>();
private SignalServiceAddressResolver resolver;
try {
return new SessionRecord(info.sessionRecord);
} catch (IOException e) {
- System.err.println("Failed to load session, resetting session: " + e);
+ logger.warn("Failed to load session, resetting session: {}", e.getMessage());
final SessionRecord sessionRecord = new SessionRecord();
info.sessionRecord = sessionRecord.serialize();
return sessionRecord;
SessionInfo sessionInfo = new SessionInfo(serviceAddress, deviceId, Base64.decode(record));
sessionStore.sessions.add(sessionInfo);
} catch (IOException e) {
- System.err.println(String.format("Error while decoding session for: %s", sessionName));
+ logger.warn("Error while decoding session for {}: {}", sessionName, e.getMessage());
}
}
}
import com.fasterxml.jackson.databind.JsonSerializer;
import com.fasterxml.jackson.databind.SerializerProvider;
+import org.slf4j.Logger;
+import org.slf4j.LoggerFactory;
import org.whispersystems.libsignal.InvalidKeyIdException;
import org.whispersystems.libsignal.state.SignedPreKeyRecord;
import org.whispersystems.libsignal.state.SignedPreKeyStore;
class JsonSignedPreKeyStore implements SignedPreKeyStore {
+ final static Logger logger = LoggerFactory.getLogger(JsonSignedPreKeyStore.class);
+
private final Map<Integer, byte[]> store = new HashMap<>();
public JsonSignedPreKeyStore() {
try {
preKeyMap.put(preKeyId, Base64.decode(preKey.get("record").asText()));
} catch (IOException e) {
- System.err.println(String.format("Error while decoding prekey for: %s", preKeyId));
+ logger.warn("Error while decoding prekey for {}: {}", preKeyId, e.getMessage());
}
}
}