Transport properties client. #229

This commit is contained in:
akwizgran
2016-01-22 11:32:39 +00:00
parent baa580c6f4
commit 88475bdd54
66 changed files with 748 additions and 436 deletions

View File

@@ -13,7 +13,7 @@
<item>org.briarproject.lifecycle.LifecycleModule</item> <item>org.briarproject.lifecycle.LifecycleModule</item>
<item>org.briarproject.messaging.MessagingModule</item> <item>org.briarproject.messaging.MessagingModule</item>
<item>org.briarproject.plugins.AndroidPluginsModule</item> <item>org.briarproject.plugins.AndroidPluginsModule</item>
<item>org.briarproject.property.PropertyModule</item> <item>org.briarproject.properties.PropertiesModule</item>
<item>org.briarproject.sync.SyncModule</item> <item>org.briarproject.sync.SyncModule</item>
<item>org.briarproject.system.AndroidSystemModule</item> <item>org.briarproject.system.AndroidSystemModule</item>
<item>org.briarproject.transport.TransportModule</item> <item>org.briarproject.transport.TransportModule</item>

View File

@@ -11,7 +11,6 @@ import android.support.v4.app.TaskStackBuilder;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.contact.ConversationActivity; import org.briarproject.android.contact.ConversationActivity;
import org.briarproject.android.forum.ForumActivity; import org.briarproject.android.forum.ForumActivity;
import org.briarproject.api.Settings;
import org.briarproject.api.android.AndroidExecutor; import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.android.AndroidNotificationManager; import org.briarproject.api.android.AndroidNotificationManager;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
@@ -24,6 +23,7 @@ import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.forum.ForumManager; import org.briarproject.api.forum.ForumManager;
import org.briarproject.api.lifecycle.Service; import org.briarproject.api.lifecycle.Service;
import org.briarproject.api.messaging.MessagingManager; import org.briarproject.api.messaging.MessagingManager;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;

View File

@@ -29,13 +29,13 @@ import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar; import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.android.AndroidExecutor; import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.plugins.Plugin; import org.briarproject.api.plugins.Plugin;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.property.TransportPropertyManager; import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.io.File; import java.io.File;

View File

@@ -25,12 +25,12 @@ import org.briarproject.android.util.FixedVerticalSpace;
import org.briarproject.android.util.HorizontalBorder; import org.briarproject.android.util.HorizontalBorder;
import org.briarproject.android.util.LayoutUtils; import org.briarproject.android.util.LayoutUtils;
import org.briarproject.android.util.ListLoadingProgressBar; import org.briarproject.android.util.ListLoadingProgressBar;
import org.briarproject.api.Settings;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.event.SettingsUpdatedEvent; import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.settings.SettingsManager;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;

View File

@@ -1,15 +1,11 @@
package org.briarproject.android.invitation; package org.briarproject.android.invitation;
import android.bluetooth.BluetoothAdapter;
import android.content.Intent; import android.content.Intent;
import android.os.Bundle; import android.os.Bundle;
import android.widget.Toast; import android.widget.Toast;
import org.briarproject.R; import org.briarproject.R;
import org.briarproject.android.BriarActivity; import org.briarproject.android.BriarActivity;
import org.briarproject.android.util.AndroidUtils;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId;
import org.briarproject.api.android.ReferenceManager; import org.briarproject.api.android.ReferenceManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
@@ -60,8 +56,6 @@ implements InvitationListener {
// Fields that are accessed from background threads must be volatile // Fields that are accessed from background threads must be volatile
@Inject private volatile DatabaseComponent db; @Inject private volatile DatabaseComponent db;
@Inject private volatile IdentityManager identityManager; @Inject private volatile IdentityManager identityManager;
private volatile boolean bluetoothWasEnabled = false;
private volatile boolean leaveBluetoothEnabled = false;
@Override @Override
public void onCreate(Bundle state) { public void onCreate(Bundle state) {
@@ -69,9 +63,6 @@ implements InvitationListener {
if (state == null) { if (state == null) {
// This is a new activity // This is a new activity
setView(new ChooseIdentityView(this)); setView(new ChooseIdentityView(this));
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) bluetoothWasEnabled = adapter.isEnabled();
} else { } else {
// Restore the activity's state // Restore the activity's state
byte[] b = state.getByteArray("briar.LOCAL_AUTHOR_ID"); byte[] b = state.getByteArray("briar.LOCAL_AUTHOR_ID");
@@ -79,8 +70,6 @@ implements InvitationListener {
taskHandle = state.getLong("briar.TASK_HANDLE", -1); taskHandle = state.getLong("briar.TASK_HANDLE", -1);
task = referenceManager.getReference(taskHandle, task = referenceManager.getReference(taskHandle,
InvitationTask.class); InvitationTask.class);
bluetoothWasEnabled =
state.getBoolean("briar.BLUETOOTH_WAS_ENABLED");
if (task == null) { if (task == null) {
// No background task - we must be in an initial or final state // No background task - we must be in an initial or final state
@@ -162,26 +151,6 @@ implements InvitationListener {
public void onResume() { public void onResume() {
super.onResume(); super.onResume();
view.populate(); view.populate();
loadBluetoothSetting();
}
private void loadBluetoothSetting() {
runOnDbThread(new Runnable() {
public void run() {
try {
long now = System.currentTimeMillis();
Settings s = db.getSettings("bt");
long duration = System.currentTimeMillis() - now;
if (LOG.isLoggable(INFO))
LOG.info("Loading setting took " + duration + " ms");
leaveBluetoothEnabled = bluetoothWasEnabled
|| s.getBoolean("enable", false);
} catch (DbException e) {
if (LOG.isLoggable(WARNING))
LOG.log(WARNING, e.toString(), e);
}
}
});
} }
@Override @Override
@@ -196,15 +165,12 @@ implements InvitationListener {
state.putBoolean("briar.FAILED", connectionFailed); state.putBoolean("briar.FAILED", connectionFailed);
state.putString("briar.CONTACT_NAME", contactName); state.putString("briar.CONTACT_NAME", contactName);
if (task != null) state.putLong("briar.TASK_HANDLE", taskHandle); if (task != null) state.putLong("briar.TASK_HANDLE", taskHandle);
state.putBoolean("briar.BLUETOOTH_WAS_ENABLED", bluetoothWasEnabled);
} }
@Override @Override
public void onDestroy() { public void onDestroy() {
super.onDestroy(); super.onDestroy();
if (task != null) task.removeListener(this); if (task != null) task.removeListener(this);
if (isFinishing()) disableBluetooth();
} }
@Override @Override
@@ -295,7 +261,7 @@ implements InvitationListener {
setView(new InvitationCodeView(this, true)); setView(new InvitationCodeView(this, true));
task = invitationTaskFactory.createTask(localAuthorId, task = invitationTaskFactory.createTask(localAuthorId,
localInvitationCode, code, leaveBluetoothEnabled); localInvitationCode, code);
taskHandle = referenceManager.putReference(task, InvitationTask.class); taskHandle = referenceManager.putReference(task, InvitationTask.class);
task.addListener(AddContactActivity.this); task.addListener(AddContactActivity.this);
// Add a second listener so we can remove the first in onDestroy(), // Add a second listener so we can remove the first in onDestroy(),
@@ -329,15 +295,6 @@ implements InvitationListener {
} }
} }
public void disableBluetooth() {
if (!leaveBluetoothEnabled) {
if (LOG.isLoggable(INFO)) LOG.info("Turning off Bluetooth again");
BluetoothAdapter adapter = BluetoothAdapter.getDefaultAdapter();
if (adapter != null) AndroidUtils.setBluetooth(adapter, false);
}
}
public void connectionSucceeded() { public void connectionSucceeded() {
runOnUiThread(new Runnable() { runOnUiThread(new Runnable() {
public void run() { public void run() {

View File

@@ -1,23 +1,19 @@
package org.briarproject.android.invitation; package org.briarproject.android.invitation;
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION;
import static android.view.Gravity.CENTER;
import static org.briarproject.android.invitation.AddContactActivity.REQUEST_BLUETOOTH;
import static org.briarproject.android.util.CommonLayoutParams.WRAP_WRAP;
import org.briarproject.R;
import android.content.Context; import android.content.Context;
import android.content.Intent; import android.content.Intent;
import android.view.LayoutInflater; import android.view.LayoutInflater;
import android.view.View; import android.view.View;
import android.view.View.OnClickListener; import android.view.View.OnClickListener;
import android.widget.Button; import android.widget.Button;
import android.widget.ImageView;
import android.widget.LinearLayout;
import android.widget.TextView; import android.widget.TextView;
import org.briarproject.R;
import static android.bluetooth.BluetoothAdapter.ACTION_REQUEST_DISCOVERABLE;
import static android.bluetooth.BluetoothAdapter.EXTRA_DISCOVERABLE_DURATION;
import static org.briarproject.android.invitation.AddContactActivity.REQUEST_BLUETOOTH;
class ErrorView extends AddContactView implements OnClickListener { class ErrorView extends AddContactView implements OnClickListener {
private final int error; private final int error;
@@ -39,8 +35,6 @@ class ErrorView extends AddContactView implements OnClickListener {
removeAllViews(); removeAllViews();
Context ctx = getContext(); Context ctx = getContext();
container.disableBluetooth();
LayoutInflater inflater = (LayoutInflater) ctx.getSystemService LayoutInflater inflater = (LayoutInflater) ctx.getSystemService
(Context.LAYOUT_INFLATER_SERVICE); (Context.LAYOUT_INFLATER_SERVICE);
View view = inflater.inflate(R.layout.invitation_error, this); View view = inflater.inflate(R.layout.invitation_error, this);

View File

@@ -10,13 +10,13 @@ import android.content.Intent;
import android.content.IntentFilter; import android.content.IntentFilter;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.android.AndroidExecutor; import org.briarproject.api.android.AndroidExecutor;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.util.LatchedReference; import org.briarproject.util.LatchedReference;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;

View File

@@ -13,9 +13,7 @@ import net.freehaven.tor.control.TorControlConnection;
import net.sourceforge.jsocks.socks.Socks5Proxy; import net.sourceforge.jsocks.socks.Socks5Proxy;
import net.sourceforge.jsocks.socks.SocksSocket; import net.sourceforge.jsocks.socks.SocksSocket;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.event.Event; import org.briarproject.api.event.Event;
@@ -24,6 +22,8 @@ import org.briarproject.api.event.SettingsUpdatedEvent;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.LocationUtils; import org.briarproject.api.system.LocationUtils;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;

View File

@@ -3,7 +3,7 @@ package org.briarproject.api;
import java.util.Hashtable; import java.util.Hashtable;
import java.util.Map; import java.util.Map;
abstract class StringMap extends Hashtable<String, String> { public abstract class StringMap extends Hashtable<String, String> {
private static final long serialVersionUID = 2497176435908100448L; private static final long serialVersionUID = 2497176435908100448L;

View File

@@ -1,12 +1,13 @@
package org.briarproject.api; package org.briarproject.api;
import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH;
/** /**
* Type-safe wrapper for a string that uniquely identifies a transport plugin. * Type-safe wrapper for a string that uniquely identifies a transport plugin.
*/ */
public class TransportId { public class TransportId {
/** The maximum length of transport identifier in UTF-8 bytes. */
public static int MAX_TRANSPORT_ID_LENGTH = 10;
private final String id; private final String id;
public TransportId(String id) { public TransportId(String id) {
@@ -21,8 +22,7 @@ public class TransportId {
@Override @Override
public boolean equals(Object o) { public boolean equals(Object o) {
if (o instanceof TransportId) return id.equals(((TransportId) o).id); return o instanceof TransportId && id.equals(((TransportId) o).id);
return false;
} }
@Override @Override

View File

@@ -1,12 +1,12 @@
package org.briarproject.api.db; package org.briarproject.api.db;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.Ack; import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;

View File

@@ -1,9 +0,0 @@
package org.briarproject.api.event;
/**
* An event that is broadcast when the local transport properties are
* updated.
*/
public class LocalTransportsUpdatedEvent extends Event {
}

View File

@@ -1,28 +0,0 @@
package org.briarproject.api.event;
import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId;
/**
* An event that is broadcast when a contact's remote transport properties
* are updated.
*/
public class RemoteTransportsUpdatedEvent extends Event {
private final ContactId contactId;
private final TransportId transportId;
public RemoteTransportsUpdatedEvent(ContactId contactId,
TransportId transportId) {
this.contactId = contactId;
this.transportId = transportId;
}
public ContactId getContactId() {
return contactId;
}
public TransportId getTransportId() {
return transportId;
}
}

View File

@@ -7,5 +7,5 @@ public interface InvitationTaskFactory {
/** Creates a task using the given pseudonym and invitation codes. */ /** Creates a task using the given pseudonym and invitation codes. */
InvitationTask createTask(AuthorId localAuthorId, int localCode, InvitationTask createTask(AuthorId localAuthorId, int localCode,
int remoteCode, boolean reuseConnection); int remoteCode);
} }

View File

@@ -1,8 +1,8 @@
package org.briarproject.api.plugins; package org.briarproject.api.plugins;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.Settings; import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import java.util.Map; import java.util.Map;

View File

@@ -1,4 +1,6 @@
package org.briarproject.api; package org.briarproject.api.properties;
import org.briarproject.api.StringMap;
import java.util.Map; import java.util.Map;

View File

@@ -1,13 +1,7 @@
package org.briarproject.api; package org.briarproject.api.properties;
public interface TransportPropertyConstants { public interface TransportPropertyConstants {
/**
* The maximum length of a string that uniquely identifies a transport
* plugin.
*/
int MAX_TRANSPORT_ID_LENGTH = 10;
/** The maximum number of properties per transport. */ /** The maximum number of properties per transport. */
int MAX_PROPERTIES_PER_TRANSPORT = 100; int MAX_PROPERTIES_PER_TRANSPORT = 100;

View File

@@ -1,7 +1,6 @@
package org.briarproject.api.property; package org.briarproject.api.properties;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
@@ -26,11 +25,4 @@ public interface TransportPropertyManager {
*/ */
void mergeLocalProperties(TransportId t, TransportProperties p) void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException; throws DbException;
/**
* Sets the remote transport properties for the given contact, replacing
* any existing properties.
*/
void setRemoteProperties(ContactId c,
Map<TransportId, TransportProperties> p) throws DbException;
} }

View File

@@ -1,4 +1,6 @@
package org.briarproject.api; package org.briarproject.api.settings;
import org.briarproject.api.StringMap;
public class Settings extends StringMap { public class Settings extends StringMap {

View File

@@ -1,6 +1,5 @@
package org.briarproject.api.settings; package org.briarproject.api.settings;
import org.briarproject.api.Settings;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
public interface SettingsManager { public interface SettingsManager {

View File

@@ -4,8 +4,6 @@ import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
import java.util.Collection;
/** /**
* Responsible for managing transport keys and recognising the pseudo-random * Responsible for managing transport keys and recognising the pseudo-random
* tags of incoming streams. * tags of incoming streams.
@@ -18,8 +16,8 @@ public interface KeyManager {
* {@link StreamContext StreamContexts} for the contact can be created * {@link StreamContext StreamContexts} for the contact can be created
* after this method has returned. * after this method has returned.
*/ */
void addContact(ContactId c, Collection<TransportId> transports, void addContact(ContactId c, SecretKey master, long timestamp,
SecretKey master, long timestamp, boolean alice); boolean alice);
/** /**
* Returns a {@link StreamContext} for sending a stream to the given * Returns a {@link StreamContext} for sending a stream to the given

View File

@@ -10,6 +10,7 @@ import org.briarproject.api.crypto.StreamDecrypterFactory;
import org.briarproject.api.crypto.StreamEncrypterFactory; import org.briarproject.api.crypto.StreamEncrypterFactory;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import java.security.SecureRandom;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import java.util.concurrent.ExecutorService; import java.util.concurrent.ExecutorService;
@@ -57,4 +58,9 @@ public class CryptoModule extends AbstractModule {
lifecycleManager.registerForShutdown(cryptoExecutor); lifecycleManager.registerForShutdown(cryptoExecutor);
return cryptoExecutor; return cryptoExecutor;
} }
@Provides
SecureRandom getSecureRandom(CryptoComponent crypto) {
return crypto.getSecureRandom();
}
} }

View File

@@ -1,6 +1,5 @@
package org.briarproject.db; package org.briarproject.db;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
@@ -10,6 +9,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;

View File

@@ -1,6 +1,5 @@
package org.briarproject.db; package org.briarproject.db;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
@@ -35,6 +34,7 @@ import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.lifecycle.ShutdownManager; import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.Ack; import org.briarproject.api.sync.Ack;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;

View File

@@ -1,5 +1,7 @@
package org.briarproject.db; package org.briarproject.db;
import org.briarproject.api.settings.Settings;
interface DatabaseConstants { interface DatabaseConstants {
/** /**
@@ -8,4 +10,34 @@ interface DatabaseConstants {
* limit is reached, additional offers will not be stored. * limit is reached, additional offers will not be stored.
*/ */
int MAX_OFFERED_MESSAGES = 1000; int MAX_OFFERED_MESSAGES = 1000;
/**
* The namespace of the {@link Settings Settings}
* where the database schema version is stored.
*/
String DB_SETTINGS_NAMESPACE = "db";
/**
* The {@link Settings Settings} key under which the
* database schema version is stored.
*/
String SCHEMA_VERSION_KEY = "schemaVersion";
/**
* The {@link Settings Settings} key under which the
* minimum supported database schema version is stored.
*/
String MIN_SCHEMA_VERSION_KEY = "minSchemaVersion";
/**
* The namespace of the {@link Settings Settings}
* where the unique device ID is stored.
*/
String DEVICE_SETTINGS_NAMESPACE = "device";
/**
* The {@link Settings Settings} key under which the
* unique device ID is stored.
*/
String DEVICE_ID_KEY = "deviceId";
} }

View File

@@ -9,8 +9,9 @@ import org.briarproject.api.db.DatabaseExecutor;
import org.briarproject.api.event.EventBus; import org.briarproject.api.event.EventBus;
import org.briarproject.api.lifecycle.LifecycleManager; import org.briarproject.api.lifecycle.LifecycleManager;
import org.briarproject.api.lifecycle.ShutdownManager; import org.briarproject.api.lifecycle.ShutdownManager;
import org.briarproject.system.SystemClock; import org.briarproject.api.system.Clock;
import java.security.SecureRandom;
import java.sql.Connection; import java.sql.Connection;
import java.util.concurrent.BlockingQueue; import java.util.concurrent.BlockingQueue;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
@@ -39,13 +40,12 @@ public class DatabaseModule extends AbstractModule {
} }
@Override @Override
protected void configure() { protected void configure() {}
// Nothing to bind
}
@Provides @Singleton @Provides @Singleton
Database<Connection> getDatabase(DatabaseConfig config) { Database<Connection> getDatabase(DatabaseConfig config,
return new H2Database(config, new SystemClock()); SecureRandom random, Clock clock) {
return new H2Database(config, random, clock);
} }
@Provides @Singleton @Provides @Singleton

View File

@@ -6,6 +6,7 @@ import org.briarproject.api.system.Clock;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.io.File; import java.io.File;
import java.security.SecureRandom;
import java.sql.Connection; import java.sql.Connection;
import java.sql.DriverManager; import java.sql.DriverManager;
import java.sql.SQLException; import java.sql.SQLException;
@@ -25,13 +26,13 @@ class H2Database extends JdbcDatabase {
private final String url; private final String url;
@Inject @Inject
H2Database(DatabaseConfig config, Clock clock) { H2Database(DatabaseConfig config, SecureRandom random, Clock clock) {
super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, clock); super(HASH_TYPE, BINARY_TYPE, COUNTER_TYPE, SECRET_TYPE, random, clock);
this.config = config; this.config = config;
File dir = config.getDatabaseDirectory(); File dir = config.getDatabaseDirectory();
String path = new File(dir, "db").getAbsolutePath(); String path = new File(dir, "db").getAbsolutePath();
url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1" url = "jdbc:h2:split:" + path + ";CIPHER=AES;MULTI_THREADED=1"
+ ";DB_CLOSE_ON_EXIT=false"; + ";WRITE_DELAY=0;DB_CLOSE_ON_EXIT=false";
} }
public boolean open() throws DbException { public boolean open() throws DbException {

View File

@@ -1,7 +1,7 @@
package org.briarproject.db; package org.briarproject.db;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.UniqueId;
import org.briarproject.api.contact.Contact; import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
@@ -12,6 +12,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
@@ -24,7 +25,9 @@ import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.IncomingKeys; import org.briarproject.api.transport.IncomingKeys;
import org.briarproject.api.transport.OutgoingKeys; import org.briarproject.api.transport.OutgoingKeys;
import org.briarproject.api.transport.TransportKeys; import org.briarproject.api.transport.TransportKeys;
import org.briarproject.util.StringUtils;
import java.security.SecureRandom;
import java.sql.Connection; import java.sql.Connection;
import java.sql.PreparedStatement; import java.sql.PreparedStatement;
import java.sql.ResultSet; import java.sql.ResultSet;
@@ -53,6 +56,11 @@ import static org.briarproject.api.sync.SyncConstants.MAX_SUBSCRIPTIONS;
import static org.briarproject.api.sync.ValidationManager.Status.INVALID; import static org.briarproject.api.sync.ValidationManager.Status.INVALID;
import static org.briarproject.api.sync.ValidationManager.Status.UNKNOWN; import static org.briarproject.api.sync.ValidationManager.Status.UNKNOWN;
import static org.briarproject.api.sync.ValidationManager.Status.VALID; import static org.briarproject.api.sync.ValidationManager.Status.VALID;
import static org.briarproject.db.DatabaseConstants.DB_SETTINGS_NAMESPACE;
import static org.briarproject.db.DatabaseConstants.DEVICE_ID_KEY;
import static org.briarproject.db.DatabaseConstants.DEVICE_SETTINGS_NAMESPACE;
import static org.briarproject.db.DatabaseConstants.MIN_SCHEMA_VERSION_KEY;
import static org.briarproject.db.DatabaseConstants.SCHEMA_VERSION_KEY;
import static org.briarproject.db.ExponentialBackoff.calculateExpiry; import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
/** /**
@@ -61,8 +69,8 @@ import static org.briarproject.db.ExponentialBackoff.calculateExpiry;
*/ */
abstract class JdbcDatabase implements Database<Connection> { abstract class JdbcDatabase implements Database<Connection> {
private static final int SCHEMA_VERSION = 17; private static final int SCHEMA_VERSION = 18;
private static final int MIN_SCHEMA_VERSION = 17; private static final int MIN_SCHEMA_VERSION = 18;
private static final String CREATE_SETTINGS = private static final String CREATE_SETTINGS =
"CREATE TABLE settings" "CREATE TABLE settings"
@@ -244,6 +252,7 @@ abstract class JdbcDatabase implements Database<Connection> {
// Different database libraries use different names for certain types // Different database libraries use different names for certain types
private final String hashType, binaryType, counterType, secretType; private final String hashType, binaryType, counterType, secretType;
private final SecureRandom random;
private final Clock clock; private final Clock clock;
private final LinkedList<Connection> connections = private final LinkedList<Connection> connections =
@@ -260,11 +269,12 @@ abstract class JdbcDatabase implements Database<Connection> {
private final Condition connectionsChanged = connectionsLock.newCondition(); private final Condition connectionsChanged = connectionsLock.newCondition();
JdbcDatabase(String hashType, String binaryType, String counterType, JdbcDatabase(String hashType, String binaryType, String counterType,
String secretType, Clock clock) { String secretType, SecureRandom random, Clock clock) {
this.hashType = hashType; this.hashType = hashType;
this.binaryType = binaryType; this.binaryType = binaryType;
this.counterType = counterType; this.counterType = counterType;
this.secretType = secretType; this.secretType = secretType;
this.random = random;
this.clock = clock; this.clock = clock;
} }
@@ -283,6 +293,7 @@ abstract class JdbcDatabase implements Database<Connection> {
} else { } else {
createTables(txn); createTables(txn);
storeSchemaVersion(txn); storeSchemaVersion(txn);
storeDeviceId(txn);
} }
commitTransaction(txn); commitTransaction(txn);
} catch (DbException e) { } catch (DbException e) {
@@ -292,19 +303,27 @@ abstract class JdbcDatabase implements Database<Connection> {
} }
private boolean checkSchemaVersion(Connection txn) throws DbException { private boolean checkSchemaVersion(Connection txn) throws DbException {
Settings s = getSettings(txn, "db"); Settings s = getSettings(txn, DB_SETTINGS_NAMESPACE);
int schemaVersion = s.getInt("schemaVersion", -1); int schemaVersion = s.getInt(SCHEMA_VERSION_KEY, -1);
if (schemaVersion == SCHEMA_VERSION) return true; if (schemaVersion == SCHEMA_VERSION) return true;
if (schemaVersion < MIN_SCHEMA_VERSION) return false; if (schemaVersion < MIN_SCHEMA_VERSION) return false;
int minSchemaVersion = s.getInt("minSchemaVersion", -1); int minSchemaVersion = s.getInt(MIN_SCHEMA_VERSION_KEY, -1);
return SCHEMA_VERSION >= minSchemaVersion; return SCHEMA_VERSION >= minSchemaVersion;
} }
private void storeSchemaVersion(Connection txn) throws DbException { private void storeSchemaVersion(Connection txn) throws DbException {
Settings s = new Settings(); Settings s = new Settings();
s.putInt("schemaVersion", SCHEMA_VERSION); s.putInt(SCHEMA_VERSION_KEY, SCHEMA_VERSION);
s.putInt("minSchemaVersion", MIN_SCHEMA_VERSION); s.putInt(MIN_SCHEMA_VERSION_KEY, MIN_SCHEMA_VERSION);
mergeSettings(txn, s, "db"); mergeSettings(txn, s, DB_SETTINGS_NAMESPACE);
}
private void storeDeviceId(Connection txn) throws DbException {
byte[] deviceId = new byte[UniqueId.LENGTH];
random.nextBytes(deviceId);
Settings s = new Settings();
s.put(DEVICE_ID_KEY, StringUtils.toHexString(deviceId));
mergeSettings(txn, s, DEVICE_SETTINGS_NAMESPACE);
} }
private void tryToClose(ResultSet rs) { private void tryToClose(ResultSet rs) {

View File

@@ -16,6 +16,8 @@ import org.briarproject.api.system.Clock;
import javax.inject.Singleton; import javax.inject.Singleton;
import static org.briarproject.forum.ForumManagerImpl.CLIENT_ID;
public class ForumModule extends AbstractModule { public class ForumModule extends AbstractModule {
@Override @Override
@@ -26,16 +28,14 @@ public class ForumModule extends AbstractModule {
@Provides @Singleton @Provides @Singleton
ForumPostValidator getValidator(ValidationManager validationManager, ForumPostValidator getValidator(ValidationManager validationManager,
ForumManager forumManager, CryptoComponent crypto, CryptoComponent crypto, BdfReaderFactory bdfReaderFactory,
BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, BdfWriterFactory bdfWriterFactory,
ObjectReader<Author> authorReader, MetadataEncoder metadataEncoder, ObjectReader<Author> authorReader, MetadataEncoder metadataEncoder,
Clock clock) { Clock clock) {
ForumPostValidator validator = new ForumPostValidator(crypto, ForumPostValidator validator = new ForumPostValidator(crypto,
bdfReaderFactory, bdfWriterFactory, authorReader, bdfReaderFactory, bdfWriterFactory, authorReader,
metadataEncoder, clock); metadataEncoder, clock);
validationManager.registerMessageValidator(forumManager.getClientId(), validationManager.registerMessageValidator(CLIENT_ID, validator);
validator);
return validator; return validator;
} }
} }

View File

@@ -1,7 +1,5 @@
package org.briarproject.invitation; package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
@@ -17,7 +15,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
@@ -47,17 +43,12 @@ class AliceConnector extends Connector {
StreamWriterFactory streamWriterFactory, StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory, AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager, KeyManager keyManager, ConnectionManager connectionManager,
ContactManager contactManager, ContactManager contactManager, Clock clock, ConnectorGroup group,
TransportPropertyManager transportPropertyManager, Clock clock, DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory, super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
streamWriterFactory, authorFactory, groupFactory, streamWriterFactory, authorFactory, groupFactory, keyManager,
keyManager, connectionManager, contactManager, connectionManager, contactManager, clock, group, plugin,
transportPropertyManager, clock, reuseConnection, group, localAuthor, random);
plugin, localAuthor, localProps, random);
} }
@Override @Override
@@ -152,20 +143,14 @@ class AliceConnector extends Connector {
// Derive the invitation nonces // Derive the invitation nonces
byte[] aliceNonce = crypto.deriveSignatureNonce(master, true); byte[] aliceNonce = crypto.deriveSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveSignatureNonce(master, false); byte[] bobNonce = crypto.deriveSignatureNonce(master, false);
// Exchange pseudonyms, signed nonces, timestamps and transports // Exchange pseudonyms, signed nonces, and timestamps
Author remoteAuthor; Author remoteAuthor;
long remoteTimestamp; long remoteTimestamp;
Map<TransportId, TransportProperties> remoteProps;
boolean remoteReuseConnection;
try { try {
sendPseudonym(w, aliceNonce); sendPseudonym(w, aliceNonce);
sendTimestamp(w, localTimestamp); sendTimestamp(w, localTimestamp);
sendTransportProperties(w);
sendConfirmation(w, reuseConnection);
remoteAuthor = receivePseudonym(r, bobNonce); remoteAuthor = receivePseudonym(r, bobNonce);
remoteTimestamp = receiveTimestamp(r); remoteTimestamp = receiveTimestamp(r);
remoteProps = receiveTransportProperties(r);
remoteReuseConnection = receiveConfirmation(r);
// Close the outgoing stream and expect EOF on the incoming stream // Close the outgoing stream and expect EOF on the incoming stream
w.close(); w.close();
if (!r.eof()) LOG.warning("Unexpected data at end of connection"); if (!r.eof()) LOG.warning("Unexpected data at end of connection");
@@ -182,18 +167,17 @@ class AliceConnector extends Connector {
} }
// The agreed timestamp is the minimum of the peers' timestamps // The agreed timestamp is the minimum of the peers' timestamps
long timestamp = Math.min(localTimestamp, remoteTimestamp); long timestamp = Math.min(localTimestamp, remoteTimestamp);
// Add the contact and store the transports // Add the contact
try { try {
addContact(remoteAuthor, remoteProps, master, timestamp, true); addContact(remoteAuthor, master, timestamp, true);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn, true); tryToClose(conn, true);
group.pseudonymExchangeFailed(); group.pseudonymExchangeFailed();
return; return;
} }
// Reuse the connection as a transport connection if both peers agree // Reuse the connection as a transport connection
if (reuseConnection && remoteReuseConnection) reuseConnection(conn); reuseConnection(conn);
else tryToClose(conn, false);
// Pseudonym exchange succeeded // Pseudonym exchange succeeded
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded"); LOG.info(pluginName + " pseudonym exchange succeeded");

View File

@@ -1,7 +1,5 @@
package org.briarproject.invitation; package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
@@ -17,7 +15,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import java.io.IOException;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Map;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
@@ -47,17 +43,12 @@ class BobConnector extends Connector {
StreamWriterFactory streamWriterFactory, StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory, AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager, KeyManager keyManager, ConnectionManager connectionManager,
ContactManager contactManager, ContactManager contactManager, Clock clock, ConnectorGroup group,
TransportPropertyManager transportPropertyManager, Clock clock, DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory, super(crypto, bdfReaderFactory, bdfWriterFactory, streamReaderFactory,
streamWriterFactory, authorFactory, groupFactory, streamWriterFactory, authorFactory, groupFactory, keyManager,
keyManager, connectionManager, contactManager, connectionManager, contactManager, clock, group, plugin,
transportPropertyManager, clock, reuseConnection, group, localAuthor, random);
plugin, localAuthor, localProps, random);
} }
@Override @Override
@@ -152,20 +143,14 @@ class BobConnector extends Connector {
// Derive the nonces // Derive the nonces
byte[] aliceNonce = crypto.deriveSignatureNonce(master, true); byte[] aliceNonce = crypto.deriveSignatureNonce(master, true);
byte[] bobNonce = crypto.deriveSignatureNonce(master, false); byte[] bobNonce = crypto.deriveSignatureNonce(master, false);
// Exchange pseudonyms, signed nonces, timestamps and transports // Exchange pseudonyms, signed nonces and timestamps
Author remoteAuthor; Author remoteAuthor;
long remoteTimestamp; long remoteTimestamp;
Map<TransportId, TransportProperties> remoteProps;
boolean remoteReuseConnection;
try { try {
remoteAuthor = receivePseudonym(r, aliceNonce); remoteAuthor = receivePseudonym(r, aliceNonce);
remoteTimestamp = receiveTimestamp(r); remoteTimestamp = receiveTimestamp(r);
remoteProps = receiveTransportProperties(r);
remoteReuseConnection = receiveConfirmation(r);
sendPseudonym(w, bobNonce); sendPseudonym(w, bobNonce);
sendTimestamp(w, localTimestamp); sendTimestamp(w, localTimestamp);
sendTransportProperties(w);
sendConfirmation(w, reuseConnection);
// Close the outgoing stream and expect EOF on the incoming stream // Close the outgoing stream and expect EOF on the incoming stream
w.close(); w.close();
if (!r.eof()) LOG.warning("Unexpected data at end of connection"); if (!r.eof()) LOG.warning("Unexpected data at end of connection");
@@ -182,18 +167,17 @@ class BobConnector extends Connector {
} }
// The agreed timestamp is the minimum of the peers' timestamps // The agreed timestamp is the minimum of the peers' timestamps
long timestamp = Math.min(localTimestamp, remoteTimestamp); long timestamp = Math.min(localTimestamp, remoteTimestamp);
// Add the contact and store the transports // Add the contact
try { try {
addContact(remoteAuthor, remoteProps, master, timestamp, false); addContact(remoteAuthor, master, timestamp, false);
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
tryToClose(conn, true); tryToClose(conn, true);
group.pseudonymExchangeFailed(); group.pseudonymExchangeFailed();
return; return;
} }
// Reuse the connection as a transport connection if both peers agree // Reuse the connection as a transport connection
if (reuseConnection && remoteReuseConnection) reuseConnection(conn); reuseConnection(conn);
else tryToClose(conn, false);
// Pseudonym exchange succeeded // Pseudonym exchange succeeded
if (LOG.isLoggable(INFO)) if (LOG.isLoggable(INFO))
LOG.info(pluginName + " pseudonym exchange succeeded"); LOG.info(pluginName + " pseudonym exchange succeeded");

View File

@@ -2,7 +2,6 @@ package org.briarproject.invitation;
import org.briarproject.api.FormatException; import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
@@ -23,7 +22,6 @@ import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
@@ -33,16 +31,10 @@ import org.briarproject.api.transport.StreamWriterFactory;
import java.io.IOException; import java.io.IOException;
import java.security.GeneralSecurityException; import java.security.GeneralSecurityException;
import java.util.Arrays; import java.util.Arrays;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.logging.Logger; import java.util.logging.Logger;
import static java.util.logging.Level.INFO; import static java.util.logging.Level.INFO;
import static java.util.logging.Level.WARNING; import static java.util.logging.Level.WARNING;
import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static org.briarproject.api.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.api.TransportPropertyConstants.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_AUTHOR_NAME_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_SIGNATURE_LENGTH;
@@ -64,13 +56,10 @@ abstract class Connector extends Thread {
protected final KeyManager keyManager; protected final KeyManager keyManager;
protected final ConnectionManager connectionManager; protected final ConnectionManager connectionManager;
protected final ContactManager contactManager; protected final ContactManager contactManager;
protected final TransportPropertyManager transportPropertyManager;
protected final Clock clock; protected final Clock clock;
protected final boolean reuseConnection;
protected final ConnectorGroup group; protected final ConnectorGroup group;
protected final DuplexPlugin plugin; protected final DuplexPlugin plugin;
protected final LocalAuthor localAuthor; protected final LocalAuthor localAuthor;
protected final Map<TransportId, TransportProperties> localProps;
protected final PseudoRandom random; protected final PseudoRandom random;
protected final String pluginName; protected final String pluginName;
@@ -87,12 +76,8 @@ abstract class Connector extends Thread {
StreamWriterFactory streamWriterFactory, StreamWriterFactory streamWriterFactory,
AuthorFactory authorFactory, GroupFactory groupFactory, AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager, KeyManager keyManager, ConnectionManager connectionManager,
ContactManager contactManager, ContactManager contactManager, Clock clock, ConnectorGroup group,
TransportPropertyManager transportPropertyManager, Clock clock, DuplexPlugin plugin, LocalAuthor localAuthor, PseudoRandom random) {
boolean reuseConnection, ConnectorGroup group, DuplexPlugin plugin,
LocalAuthor localAuthor,
Map<TransportId, TransportProperties> localProps,
PseudoRandom random) {
super("Connector"); super("Connector");
this.crypto = crypto; this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory; this.bdfReaderFactory = bdfReaderFactory;
@@ -104,13 +89,10 @@ abstract class Connector extends Thread {
this.keyManager = keyManager; this.keyManager = keyManager;
this.connectionManager = connectionManager; this.connectionManager = connectionManager;
this.contactManager = contactManager; this.contactManager = contactManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock; this.clock = clock;
this.reuseConnection = reuseConnection;
this.group = group; this.group = group;
this.plugin = plugin; this.plugin = plugin;
this.localAuthor = localAuthor; this.localAuthor = localAuthor;
this.localProps = localProps;
this.random = random; this.random = random;
pluginName = plugin.getClass().getName(); pluginName = plugin.getClass().getName();
keyPair = crypto.generateAgreementKeyPair(); keyPair = crypto.generateAgreementKeyPair();
@@ -233,57 +215,14 @@ abstract class Connector extends Thread {
return timestamp; return timestamp;
} }
protected void sendTransportProperties(BdfWriter w) throws IOException { protected ContactId addContact(Author remoteAuthor, SecretKey master,
w.writeListStart();
for (Entry<TransportId, TransportProperties> e :
localProps.entrySet()) {
w.writeString(e.getKey().getString());
w.writeDictionary(e.getValue());
}
w.writeListEnd();
w.flush();
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " sent transport properties");
}
protected Map<TransportId, TransportProperties> receiveTransportProperties(
BdfReader r) throws IOException {
Map<TransportId, TransportProperties> remoteProps =
new HashMap<TransportId, TransportProperties>();
r.readListStart();
while (!r.hasListEnd()) {
String idString = r.readString(MAX_TRANSPORT_ID_LENGTH);
if (idString.length() == 0) throw new FormatException();
TransportId id = new TransportId(idString);
Map<String, String> p = new HashMap<String, String>();
r.readDictionaryStart();
for (int i = 0; !r.hasDictionaryEnd(); i++) {
if (i == MAX_PROPERTIES_PER_TRANSPORT)
throw new FormatException();
String key = r.readString(MAX_PROPERTY_LENGTH);
String value = r.readString(MAX_PROPERTY_LENGTH);
p.put(key, value);
}
r.readDictionaryEnd();
remoteProps.put(id, new TransportProperties(p));
}
r.readListEnd();
if (LOG.isLoggable(INFO))
LOG.info(pluginName + " received transport properties");
return remoteProps;
}
protected void addContact(Author remoteAuthor,
Map<TransportId, TransportProperties> remoteProps, SecretKey master,
long timestamp, boolean alice) throws DbException { long timestamp, boolean alice) throws DbException {
// Add the contact to the database // Add the contact to the database
contactId = contactManager.addContact(remoteAuthor, contactId = contactManager.addContact(remoteAuthor,
localAuthor.getId()); localAuthor.getId());
// Store the remote transport properties // Derive transport keys
transportPropertyManager.setRemoteProperties(contactId, remoteProps); keyManager.addContact(contactId, master, timestamp, alice);
// Derive transport keys for each transport shared with the contact return contactId;
keyManager.addContact(contactId, remoteProps.keySet(), master,
timestamp, alice);
} }
protected void tryToClose(DuplexTransportConnection conn, protected void tryToClose(DuplexTransportConnection conn,

View File

@@ -1,7 +1,5 @@
package org.briarproject.invitation; package org.briarproject.invitation;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactManager; import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.crypto.CryptoComponent; import org.briarproject.api.crypto.CryptoComponent;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
@@ -19,7 +17,6 @@ import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
@@ -28,7 +25,6 @@ import org.briarproject.api.transport.StreamWriterFactory;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Collection; import java.util.Collection;
import java.util.Map;
import java.util.concurrent.CopyOnWriteArrayList; import java.util.concurrent.CopyOnWriteArrayList;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;
import java.util.concurrent.atomic.AtomicBoolean; import java.util.concurrent.atomic.AtomicBoolean;
@@ -57,12 +53,10 @@ class ConnectorGroup extends Thread implements InvitationTask {
private final ConnectionManager connectionManager; private final ConnectionManager connectionManager;
private final IdentityManager identityManager; private final IdentityManager identityManager;
private final ContactManager contactManager; private final ContactManager contactManager;
private final TransportPropertyManager transportPropertyManager;
private final Clock clock; private final Clock clock;
private final PluginManager pluginManager; private final PluginManager pluginManager;
private final AuthorId localAuthorId; private final AuthorId localAuthorId;
private final int localInvitationCode, remoteInvitationCode; private final int localInvitationCode, remoteInvitationCode;
private final boolean reuseConnection;
private final Collection<InvitationListener> listeners; private final Collection<InvitationListener> listeners;
private final AtomicBoolean connected; private final AtomicBoolean connected;
private final CountDownLatch localConfirmationLatch; private final CountDownLatch localConfirmationLatch;
@@ -83,10 +77,8 @@ class ConnectorGroup extends Thread implements InvitationTask {
AuthorFactory authorFactory, GroupFactory groupFactory, AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager, KeyManager keyManager, ConnectionManager connectionManager,
IdentityManager identityManager, ContactManager contactManager, IdentityManager identityManager, ContactManager contactManager,
TransportPropertyManager transportPropertyManager, Clock clock, Clock clock, PluginManager pluginManager, AuthorId localAuthorId,
PluginManager pluginManager, AuthorId localAuthorId, int localInvitationCode, int remoteInvitationCode) {
int localInvitationCode, int remoteInvitationCode,
boolean reuseConnection) {
super("ConnectorGroup"); super("ConnectorGroup");
this.crypto = crypto; this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory; this.bdfReaderFactory = bdfReaderFactory;
@@ -99,13 +91,11 @@ class ConnectorGroup extends Thread implements InvitationTask {
this.connectionManager = connectionManager; this.connectionManager = connectionManager;
this.identityManager = identityManager; this.identityManager = identityManager;
this.contactManager = contactManager; this.contactManager = contactManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock; this.clock = clock;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
this.localAuthorId = localAuthorId; this.localAuthorId = localAuthorId;
this.localInvitationCode = localInvitationCode; this.localInvitationCode = localInvitationCode;
this.remoteInvitationCode = remoteInvitationCode; this.remoteInvitationCode = remoteInvitationCode;
this.reuseConnection = reuseConnection;
listeners = new CopyOnWriteArrayList<InvitationListener>(); listeners = new CopyOnWriteArrayList<InvitationListener>();
connected = new AtomicBoolean(false); connected = new AtomicBoolean(false);
localConfirmationLatch = new CountDownLatch(1); localConfirmationLatch = new CountDownLatch(1);
@@ -136,11 +126,9 @@ class ConnectorGroup extends Thread implements InvitationTask {
@Override @Override
public void run() { public void run() {
LocalAuthor localAuthor; LocalAuthor localAuthor;
Map<TransportId, TransportProperties> localProps; // Load the local pseudonym
// Load the local pseudonym and transport properties
try { try {
localAuthor = identityManager.getLocalAuthor(localAuthorId); localAuthor = identityManager.getLocalAuthor(localAuthorId);
localProps = transportPropertyManager.getLocalProperties();
} catch (DbException e) { } catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
lock.lock(); lock.lock();
@@ -157,15 +145,13 @@ class ConnectorGroup extends Thread implements InvitationTask {
// Alice is the party with the smaller invitation code // Alice is the party with the smaller invitation code
if (localInvitationCode < remoteInvitationCode) { if (localInvitationCode < remoteInvitationCode) {
for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) { for (DuplexPlugin plugin : pluginManager.getInvitationPlugins()) {
Connector c = createAliceConnector(plugin, localAuthor, Connector c = createAliceConnector(plugin, localAuthor);
localProps);
connectors.add(c); connectors.add(c);
c.start(); c.start();
} }
} else { } else {
for (DuplexPlugin plugin: pluginManager.getInvitationPlugins()) { for (DuplexPlugin plugin: pluginManager.getInvitationPlugins()) {
Connector c = createBobConnector(plugin, localAuthor, Connector c = createBobConnector(plugin, localAuthor);
localProps);
connectors.add(c); connectors.add(c);
c.start(); c.start();
} }
@@ -190,27 +176,23 @@ class ConnectorGroup extends Thread implements InvitationTask {
} }
private Connector createAliceConnector(DuplexPlugin plugin, private Connector createAliceConnector(DuplexPlugin plugin,
LocalAuthor localAuthor, LocalAuthor localAuthor) {
Map<TransportId, TransportProperties> localProps) {
PseudoRandom random = crypto.getPseudoRandom(localInvitationCode, PseudoRandom random = crypto.getPseudoRandom(localInvitationCode,
remoteInvitationCode); remoteInvitationCode);
return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory, return new AliceConnector(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory, streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, contactManager, groupFactory, keyManager, connectionManager, contactManager,
transportPropertyManager, clock, reuseConnection, this, plugin, clock, this, plugin, localAuthor, random);
localAuthor, localProps, random);
} }
private Connector createBobConnector(DuplexPlugin plugin, private Connector createBobConnector(DuplexPlugin plugin,
LocalAuthor localAuthor, LocalAuthor localAuthor) {
Map<TransportId, TransportProperties> localProps) {
PseudoRandom random = crypto.getPseudoRandom(remoteInvitationCode, PseudoRandom random = crypto.getPseudoRandom(remoteInvitationCode,
localInvitationCode); localInvitationCode);
return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory, return new BobConnector(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory, streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, contactManager, groupFactory, keyManager, connectionManager, contactManager,
transportPropertyManager, clock, reuseConnection, this, plugin, clock, this, plugin, localAuthor, random);
localAuthor, localProps, random);
} }
public void localConfirmationSucceeded() { public void localConfirmationSucceeded() {

View File

@@ -11,7 +11,6 @@ import org.briarproject.api.invitation.InvitationTask;
import org.briarproject.api.invitation.InvitationTaskFactory; import org.briarproject.api.invitation.InvitationTaskFactory;
import org.briarproject.api.plugins.ConnectionManager; import org.briarproject.api.plugins.ConnectionManager;
import org.briarproject.api.plugins.PluginManager; import org.briarproject.api.plugins.PluginManager;
import org.briarproject.api.property.TransportPropertyManager;
import org.briarproject.api.sync.GroupFactory; import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
@@ -33,7 +32,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
private final ConnectionManager connectionManager; private final ConnectionManager connectionManager;
private final IdentityManager identityManager; private final IdentityManager identityManager;
private final ContactManager contactManager; private final ContactManager contactManager;
private final TransportPropertyManager transportPropertyManager;
private final Clock clock; private final Clock clock;
private final PluginManager pluginManager; private final PluginManager pluginManager;
@@ -45,7 +43,6 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
AuthorFactory authorFactory, GroupFactory groupFactory, AuthorFactory authorFactory, GroupFactory groupFactory,
KeyManager keyManager, ConnectionManager connectionManager, KeyManager keyManager, ConnectionManager connectionManager,
IdentityManager identityManager, ContactManager contactManager, IdentityManager identityManager, ContactManager contactManager,
TransportPropertyManager transportPropertyManager,
Clock clock, PluginManager pluginManager) { Clock clock, PluginManager pluginManager) {
this.crypto = crypto; this.crypto = crypto;
this.bdfReaderFactory = bdfReaderFactory; this.bdfReaderFactory = bdfReaderFactory;
@@ -58,17 +55,16 @@ class InvitationTaskFactoryImpl implements InvitationTaskFactory {
this.connectionManager = connectionManager; this.connectionManager = connectionManager;
this.identityManager = identityManager; this.identityManager = identityManager;
this.contactManager = contactManager; this.contactManager = contactManager;
this.transportPropertyManager = transportPropertyManager;
this.clock = clock; this.clock = clock;
this.pluginManager = pluginManager; this.pluginManager = pluginManager;
} }
public InvitationTask createTask(AuthorId localAuthorId, int localCode, public InvitationTask createTask(AuthorId localAuthorId, int localCode,
int remoteCode, boolean reuseConnection) { int remoteCode) {
return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory, return new ConnectorGroup(crypto, bdfReaderFactory, bdfWriterFactory,
streamReaderFactory, streamWriterFactory, authorFactory, streamReaderFactory, streamWriterFactory, authorFactory,
groupFactory, keyManager, connectionManager, identityManager, groupFactory, keyManager, connectionManager, identityManager,
contactManager, transportPropertyManager, clock, pluginManager, contactManager, clock, pluginManager, localAuthorId, localCode,
localAuthorId, localCode, remoteCode, reuseConnection); remoteCode);
} }
} }

View File

@@ -13,6 +13,8 @@ import org.briarproject.api.system.Clock;
import javax.inject.Singleton; import javax.inject.Singleton;
import static org.briarproject.messaging.MessagingManagerImpl.CLIENT_ID;
public class MessagingModule extends AbstractModule { public class MessagingModule extends AbstractModule {
@Override @Override
@@ -22,14 +24,11 @@ public class MessagingModule extends AbstractModule {
@Provides @Singleton @Provides @Singleton
PrivateMessageValidator getValidator(ValidationManager validationManager, PrivateMessageValidator getValidator(ValidationManager validationManager,
MessagingManager messagingManager,
BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder, BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
Clock clock) { Clock clock) {
PrivateMessageValidator validator = new PrivateMessageValidator( PrivateMessageValidator validator = new PrivateMessageValidator(
bdfReaderFactory, metadataEncoder, clock); bdfReaderFactory, metadataEncoder, clock);
validationManager.registerMessageValidator( validationManager.registerMessageValidator(CLIENT_ID, validator);
messagingManager.getClientId(),
validator);
return validator; return validator;
} }

View File

@@ -73,8 +73,7 @@ class ConnectionManagerImpl implements ConnectionManager {
ioExecutor.execute(new ManageOutgoingDuplexConnection(c, t, d)); ioExecutor.execute(new ManageOutgoingDuplexConnection(c, t, d));
} }
private byte[] readTag(TransportId t, TransportConnectionReader r) private byte[] readTag(TransportConnectionReader r) throws IOException {
throws IOException {
// Read the tag // Read the tag
byte[] tag = new byte[TAG_LENGTH]; byte[] tag = new byte[TAG_LENGTH];
InputStream in = r.getInputStream(); InputStream in = r.getInputStream();
@@ -128,7 +127,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag // Read and recognise the tag
StreamContext ctx; StreamContext ctx;
try { try {
byte[] tag = readTag(transportId, reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) { } catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -228,7 +227,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag // Read and recognise the tag
StreamContext ctx; StreamContext ctx;
try { try {
byte[] tag = readTag(transportId, reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) { } catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
@@ -353,7 +352,7 @@ class ConnectionManagerImpl implements ConnectionManager {
// Read and recognise the tag // Read and recognise the tag
StreamContext ctx; StreamContext ctx;
try { try {
byte[] tag = readTag(transportId, reader); byte[] tag = readTag(reader);
ctx = keyManager.getStreamContext(transportId, tag); ctx = keyManager.getStreamContext(transportId, tag);
} catch (IOException e) { } catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e); if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);

View File

@@ -1,8 +1,6 @@
package org.briarproject.plugins; package org.briarproject.plugins;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
@@ -26,7 +24,9 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback; import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig; import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory; import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.property.TransportPropertyManager; import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback; import org.briarproject.api.ui.UiCallback;

View File

@@ -1,5 +1,9 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.api.TransportId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.properties.TransportProperties;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@@ -8,10 +12,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
class LanTcpPlugin extends TcpPlugin { class LanTcpPlugin extends TcpPlugin {
static final TransportId ID = new TransportId("lan"); static final TransportId ID = new TransportId("lan");

View File

@@ -1,11 +1,11 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.io.IOException; import java.io.IOException;

View File

@@ -1,5 +1,9 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.api.TransportId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.properties.TransportProperties;
import java.net.Inet4Address; import java.net.Inet4Address;
import java.net.InetAddress; import java.net.InetAddress;
import java.net.InetSocketAddress; import java.net.InetSocketAddress;
@@ -8,10 +12,6 @@ import java.util.LinkedList;
import java.util.List; import java.util.List;
import java.util.concurrent.Executor; import java.util.concurrent.Executor;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
class WanTcpPlugin extends TcpPlugin { class WanTcpPlugin extends TcpPlugin {
static final TransportId ID = new TransportId("wan"); static final TransportId ID = new TransportId("wan");

View File

@@ -0,0 +1,40 @@
package org.briarproject.properties;
import com.google.inject.AbstractModule;
import com.google.inject.Provides;
import org.briarproject.api.contact.ContactManager;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ValidationManager;
import org.briarproject.api.system.Clock;
import javax.inject.Singleton;
import static org.briarproject.properties.TransportPropertyManagerImpl.CLIENT_ID;
public class PropertiesModule extends AbstractModule {
@Override
protected void configure() {}
@Provides @Singleton
TransportPropertyValidator getValidator(ValidationManager validationManager,
BdfReaderFactory bdfReaderFactory, MetadataEncoder metadataEncoder,
Clock clock) {
TransportPropertyValidator validator = new TransportPropertyValidator(
bdfReaderFactory, metadataEncoder, clock);
validationManager.registerMessageValidator(CLIENT_ID, validator);
return validator;
}
@Provides @Singleton
TransportPropertyManager getTransportPropertyManager(
ContactManager contactManager,
TransportPropertyManagerImpl transportPropertyManager) {
contactManager.registerAddContactHook(transportPropertyManager);
contactManager.registerRemoveContactHook(transportPropertyManager);
return transportPropertyManager;
}
}

View File

@@ -0,0 +1,339 @@
package org.briarproject.properties;
import com.google.inject.Inject;
import org.briarproject.api.FormatException;
import org.briarproject.api.TransportId;
import org.briarproject.api.UniqueId;
import org.briarproject.api.contact.Contact;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.contact.ContactManager.AddContactHook;
import org.briarproject.api.contact.ContactManager.RemoveContactHook;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfReader;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.BdfWriter;
import org.briarproject.api.data.BdfWriterFactory;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.data.MetadataParser;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.db.NoSuchSubscriptionException;
import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupFactory;
import org.briarproject.api.sync.GroupId;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageFactory;
import org.briarproject.api.sync.MessageId;
import org.briarproject.api.system.Clock;
import org.briarproject.util.StringUtils;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.IOException;
import java.util.Collections;
import java.util.HashMap;
import java.util.Map;
import java.util.Map.Entry;
import java.util.concurrent.locks.ReentrantReadWriteLock;
import java.util.logging.Logger;
import static java.util.logging.Level.WARNING;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
class TransportPropertyManagerImpl implements TransportPropertyManager,
AddContactHook, RemoveContactHook {
static final ClientId CLIENT_ID = new ClientId(StringUtils.fromHexString(
"673ea091673561e28f70122f6a8ea8f4"
+ "97c3624b86fa07f785bb15f09fb87b4b"));
private static final byte[] LOCAL_GROUP_DESCRIPTOR = new byte[0];
private static final Logger LOG =
Logger.getLogger(TransportPropertyManagerImpl.class.getName());
private final DatabaseComponent db;
private final GroupFactory groupFactory;
private final MessageFactory messageFactory;
private final BdfReaderFactory bdfReaderFactory;
private final BdfWriterFactory bdfWriterFactory;
private final MetadataEncoder metadataEncoder;
private final MetadataParser metadataParser;
private final Clock clock;
private final Group localGroup;
/** Ensures isolation between database reads and writes. */
private final ReentrantReadWriteLock lock = new ReentrantReadWriteLock();
@Inject
TransportPropertyManagerImpl(DatabaseComponent db, GroupFactory groupFactory,
MessageFactory messageFactory, BdfReaderFactory bdfReaderFactory,
BdfWriterFactory bdfWriterFactory, MetadataEncoder metadataEncoder,
MetadataParser metadataParser, Clock clock) {
this.db = db;
this.groupFactory = groupFactory;
this.messageFactory = messageFactory;
this.bdfReaderFactory = bdfReaderFactory;
this.bdfWriterFactory = bdfWriterFactory;
this.metadataEncoder = metadataEncoder;
this.metadataParser = metadataParser;
this.clock = clock;
localGroup = groupFactory.createGroup(CLIENT_ID,
LOCAL_GROUP_DESCRIPTOR);
}
@Override
public void addingContact(ContactId c) {
lock.writeLock().lock();
try {
// Create a group to share with the contact
Group g = getContactGroup(db.getContact(c));
// Subscribe to the group and share it with the contact
db.addGroup(g);
db.addContactGroup(c, g);
db.setVisibility(g.getId(), Collections.singletonList(c));
// Copy the latest local properties into the group
Map<TransportId, TransportProperties> local = getLocalProperties();
for (Entry<TransportId, TransportProperties> e : local.entrySet())
storeMessage(g.getId(), e.getKey(), e.getValue(), 0);
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} catch (FormatException e) {
throw new RuntimeException(e);
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally {
lock.writeLock().unlock();
}
}
private Group getContactGroup(Contact c) {
AuthorId local = c.getLocalAuthorId();
AuthorId remote = c.getAuthor().getId();
byte[] descriptor = encodeGroupDescriptor(local, remote);
return groupFactory.createGroup(CLIENT_ID, descriptor);
}
private byte[] encodeGroupDescriptor(AuthorId local, AuthorId remote) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BdfWriter w = bdfWriterFactory.createWriter(out);
try {
w.writeListStart();
if (UniqueId.IdComparator.INSTANCE.compare(local, remote) < 0) {
w.writeRaw(local.getBytes());
w.writeRaw(remote.getBytes());
} else {
w.writeRaw(remote.getBytes());
w.writeRaw(local.getBytes());
}
w.writeListEnd();
} catch (IOException e) {
// Shouldn't happen with ByteArrayOutputStream
throw new RuntimeException(e);
}
return out.toByteArray();
}
private void storeMessage(GroupId g, TransportId t, TransportProperties p,
long version) throws DbException, IOException {
byte[] body = encodeProperties(t, p, version);
long now = clock.currentTimeMillis();
Message m = messageFactory.createMessage(g, now, body);
BdfDictionary d = new BdfDictionary();
d.put("transportId", t.getString());
d.put("version", version);
d.put("local", true);
db.addLocalMessage(m, CLIENT_ID, metadataEncoder.encode(d));
}
private byte[] encodeProperties(TransportId t, TransportProperties p,
long version) {
ByteArrayOutputStream out = new ByteArrayOutputStream();
BdfWriter w = bdfWriterFactory.createWriter(out);
try {
// TODO: Device ID
w.writeListStart();
w.writeString(t.getString());
w.writeInteger(version);
w.writeDictionary(p);
w.writeListEnd();
} catch (IOException e) {
// Shouldn't happen with ByteArrayOutputStream
throw new RuntimeException(e);
}
return out.toByteArray();
}
@Override
public void removingContact(ContactId c) {
lock.writeLock().lock();
try {
db.removeGroup(getContactGroup(db.getContact(c)));
} catch (DbException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
} finally {
lock.writeLock().unlock();
}
}
@Override
public Map<TransportId, TransportProperties> getLocalProperties()
throws DbException {
lock.readLock().lock();
try {
// Find the latest local version for each transport
Map<TransportId, Latest> latest =
findLatest(localGroup.getId(), true);
// Retrieve and decode the latest local properties
Map<TransportId, TransportProperties> local =
new HashMap<TransportId, TransportProperties>();
for (Entry<TransportId, Latest> e : latest.entrySet()) {
byte[] raw = db.getRawMessage(e.getValue().messageId);
local.put(e.getKey(), decodeProperties(raw));
}
return Collections.unmodifiableMap(local);
} catch (NoSuchSubscriptionException e) {
// Local group doesn't exist - there are no local properties
return Collections.emptyMap();
} catch (IOException e) {
throw new DbException(e);
} finally {
lock.readLock().unlock();
}
}
private Map<TransportId, Latest> findLatest(GroupId g, boolean local)
throws DbException, FormatException {
// TODO: Use metadata queries
Map<TransportId, Latest> latest = new HashMap<TransportId, Latest>();
Map<MessageId, Metadata> metadata = db.getMessageMetadata(g);
for (Entry<MessageId, Metadata> e : metadata.entrySet()) {
BdfDictionary mm = metadataParser.parse(e.getValue());
if (mm.getBoolean("local") != local) continue;
TransportId t = new TransportId(mm.getString("transportId"));
long version = mm.getInteger("version");
Latest l = latest.get(t);
if (l == null || version > l.version)
latest.put(t, new Latest(e.getKey(), version));
}
return latest;
}
private TransportProperties decodeProperties(byte[] raw)
throws IOException {
TransportProperties p = new TransportProperties();
ByteArrayInputStream in = new ByteArrayInputStream(raw,
MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH);
BdfReader r = bdfReaderFactory.createReader(in);
// TODO: Device ID
r.readListStart();
r.skipString(); // Transport ID
r.skipInteger(); // Version
r.readDictionaryStart();
while (!r.hasDictionaryEnd()) {
String key = r.readString(MAX_PROPERTY_LENGTH);
String value = r.readString(MAX_PROPERTY_LENGTH);
p.put(key, value);
}
r.readDictionaryEnd();
r.readListEnd();
if (!r.eof()) throw new FormatException();
return p;
}
@Override
public TransportProperties getLocalProperties(TransportId t)
throws DbException {
lock.readLock().lock();
try {
// Find the latest local version
Latest latest = findLatest(localGroup.getId(), true).get(t);
if (latest == null) return null;
// Retrieve and decode the latest local properties
return decodeProperties(db.getRawMessage(latest.messageId));
} catch (NoSuchSubscriptionException e) {
// Local group doesn't exist - there are no local properties
return null;
} catch (IOException e) {
throw new DbException(e);
} finally {
lock.readLock().unlock();
}
}
@Override
public Map<ContactId, TransportProperties> getRemoteProperties(
TransportId t) throws DbException {
lock.readLock().lock();
try {
Map<ContactId, TransportProperties> remote =
new HashMap<ContactId, TransportProperties>();
for (Contact c : db.getContacts()) {
Group g = getContactGroup(c);
// Find the latest remote version
Latest latest = findLatest(g.getId(), false).get(t);
if (latest != null) {
// Retrieve and decode the latest remote properties
byte[] raw = db.getRawMessage(latest.messageId);
remote.put(c.getId(), decodeProperties(raw));
}
}
return Collections.unmodifiableMap(remote);
} catch (IOException e) {
throw new DbException(e);
} finally {
lock.readLock().unlock();
}
}
@Override
public void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException {
lock.writeLock().lock();
try {
// Create the local group if necessary
db.addGroup(localGroup);
// Merge the new properties with any existing properties
Latest latest = findLatest(localGroup.getId(), true).get(t);
if (latest != null) {
byte[] raw = db.getRawMessage(latest.messageId);
TransportProperties old = decodeProperties(raw);
if (old.equals(p)) return; // Unchanged
old.putAll(p);
p = old;
}
// Store the merged properties in the local group
long version = latest == null ? 0 : latest.version + 1;
storeMessage(localGroup.getId(), t, p, version);
// Store the merged properties in each contact's group
for (Contact c : db.getContacts()) {
Group g = getContactGroup(c);
latest = findLatest(g.getId(), true).get(t);
version = latest == null ? 0 : latest.version + 1;
storeMessage(g.getId(), t, p, version);
}
} catch (IOException e) {
throw new DbException(e);
} finally {
lock.writeLock().unlock();
}
}
private static class Latest {
private final MessageId messageId;
private final long version;
private Latest(MessageId messageId, long version) {
this.messageId = messageId;
this.version = version;
}
}
}

View File

@@ -0,0 +1,83 @@
package org.briarproject.properties;
import org.briarproject.api.FormatException;
import org.briarproject.api.data.BdfDictionary;
import org.briarproject.api.data.BdfReader;
import org.briarproject.api.data.BdfReaderFactory;
import org.briarproject.api.data.MetadataEncoder;
import org.briarproject.api.db.Metadata;
import org.briarproject.api.sync.Message;
import org.briarproject.api.sync.MessageValidator;
import org.briarproject.api.system.Clock;
import java.io.ByteArrayInputStream;
import java.io.IOException;
import java.util.logging.Logger;
import javax.inject.Inject;
import static org.briarproject.api.TransportId.MAX_TRANSPORT_ID_LENGTH;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTIES_PER_TRANSPORT;
import static org.briarproject.api.properties.TransportPropertyConstants.MAX_PROPERTY_LENGTH;
import static org.briarproject.api.sync.SyncConstants.MESSAGE_HEADER_LENGTH;
import static org.briarproject.api.transport.TransportConstants.MAX_CLOCK_DIFFERENCE;
class TransportPropertyValidator implements MessageValidator {
private static final Logger LOG =
Logger.getLogger(TransportPropertyValidator.class.getName());
private final BdfReaderFactory bdfReaderFactory;
private final MetadataEncoder metadataEncoder;
private final Clock clock;
@Inject
TransportPropertyValidator(BdfReaderFactory bdfReaderFactory,
MetadataEncoder metadataEncoder, Clock clock) {
this.bdfReaderFactory = bdfReaderFactory;
this.metadataEncoder = metadataEncoder;
this.clock = clock;
}
@Override
public Metadata validateMessage(Message m) {
// Reject the message if it's too far in the future
long now = clock.currentTimeMillis();
if (m.getTimestamp() - now > MAX_CLOCK_DIFFERENCE) {
LOG.info("Timestamp is too far in the future");
return null;
}
try {
// Parse the message body
byte[] raw = m.getRaw();
ByteArrayInputStream in = new ByteArrayInputStream(raw,
MESSAGE_HEADER_LENGTH, raw.length - MESSAGE_HEADER_LENGTH);
BdfReader r = bdfReaderFactory.createReader(in);
// TODO: Device ID
r.readListStart();
String id = r.readString(MAX_TRANSPORT_ID_LENGTH);
if (id.length() == 0) throw new FormatException();
long version = r.readInteger();
if (version < 0) throw new FormatException();
r.readDictionaryStart();
for (int i = 0; !r.hasDictionaryEnd(); i++) {
if (i == MAX_PROPERTIES_PER_TRANSPORT)
throw new FormatException();
r.readString(MAX_PROPERTY_LENGTH);
r.readString(MAX_PROPERTY_LENGTH);
}
r.readDictionaryEnd();
r.readListEnd();
if (!r.eof()) throw new FormatException();
// Return the metadata
BdfDictionary d = new BdfDictionary();
d.put("transportId", id);
d.put("version", version);
d.put("local", false);
return metadataEncoder.encode(d);
} catch (IOException e) {
LOG.info("Invalid transport update");
return null;
}
}
}

View File

@@ -1,14 +0,0 @@
package org.briarproject.property;
import com.google.inject.AbstractModule;
import org.briarproject.api.property.TransportPropertyManager;
public class PropertyModule extends AbstractModule {
@Override
protected void configure() {
bind(TransportPropertyManager.class).to(
TransportPropertyManagerImpl.class);
}
}

View File

@@ -1,57 +0,0 @@
package org.briarproject.property;
import com.google.inject.Inject;
import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId;
import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException;
import org.briarproject.api.property.TransportPropertyManager;
import java.util.Collections;
import java.util.Map;
// Temporary facade during sync protocol refactoring
class TransportPropertyManagerImpl implements TransportPropertyManager {
private final DatabaseComponent db;
@Inject
TransportPropertyManagerImpl(DatabaseComponent db) {
this.db = db;
}
@Override
public Map<TransportId, TransportProperties> getLocalProperties()
throws DbException {
// TODO
return Collections.emptyMap();
}
@Override
public TransportProperties getLocalProperties(TransportId t)
throws DbException {
// TODO
return new TransportProperties();
}
@Override
public Map<ContactId, TransportProperties> getRemoteProperties(
TransportId t) throws DbException {
// TODO
return Collections.emptyMap();
}
@Override
public void mergeLocalProperties(TransportId t, TransportProperties p)
throws DbException {
// TODO
}
@Override
public void setRemoteProperties(ContactId c,
Map<TransportId, TransportProperties> p) throws DbException {
// TODO
}
}

View File

@@ -2,9 +2,9 @@ package org.briarproject.settings;
import com.google.inject.Inject; import com.google.inject.Inject;
import org.briarproject.api.Settings;
import org.briarproject.api.db.DatabaseComponent; import org.briarproject.api.db.DatabaseComponent;
import org.briarproject.api.db.DbException; import org.briarproject.api.db.DbException;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.settings.SettingsManager; import org.briarproject.api.settings.SettingsManager;
class SettingsManagerImpl implements SettingsManager { class SettingsManagerImpl implements SettingsManager {

View File

@@ -18,7 +18,6 @@ import org.briarproject.api.system.Timer;
import org.briarproject.api.transport.KeyManager; import org.briarproject.api.transport.KeyManager;
import org.briarproject.api.transport.StreamContext; import org.briarproject.api.transport.StreamContext;
import java.util.Collection;
import java.util.Map; import java.util.Map;
import java.util.Map.Entry; import java.util.Map.Entry;
import java.util.concurrent.ConcurrentHashMap; import java.util.concurrent.ConcurrentHashMap;
@@ -71,12 +70,10 @@ class KeyManagerImpl implements KeyManager, Service, EventListener {
return true; return true;
} }
public void addContact(ContactId c, Collection<TransportId> transports, public void addContact(ContactId c, SecretKey master, long timestamp,
SecretKey master, long timestamp, boolean alice) { boolean alice) {
for (TransportId t : transports) { for (TransportKeyManager m : managers.values())
TransportKeyManager m = managers.get(t); m.addContact(c, master, timestamp, alice);
if (m != null) m.addContact(c, master, timestamp, alice);
}
} }
public StreamContext getStreamContext(ContactId c, TransportId t) { public StreamContext getStreamContext(ContactId c, TransportId t) {

View File

@@ -1,12 +1,12 @@
package org.briarproject.plugins.bluetooth; package org.briarproject.plugins.bluetooth;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.util.LatchedReference; import org.briarproject.util.LatchedReference;
import org.briarproject.util.OsUtils; import org.briarproject.util.OsUtils;

View File

@@ -1,7 +1,6 @@
package org.briarproject.plugins.modem; package org.briarproject.plugins.modem;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.TransportConnectionReader; import org.briarproject.api.plugins.TransportConnectionReader;
@@ -9,6 +8,7 @@ import org.briarproject.api.plugins.TransportConnectionWriter;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.util.StringUtils; import org.briarproject.util.StringUtils;
import java.io.IOException; import java.io.IOException;

View File

@@ -3,7 +3,6 @@ package org.briarproject.db;
import org.briarproject.BriarTestCase; import org.briarproject.BriarTestCase;
import org.briarproject.TestDatabaseConfig; import org.briarproject.TestDatabaseConfig;
import org.briarproject.TestUtils; import org.briarproject.TestUtils;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportId; import org.briarproject.api.TransportId;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.SecretKey; import org.briarproject.api.crypto.SecretKey;
@@ -13,6 +12,7 @@ import org.briarproject.api.db.StorageStatus;
import org.briarproject.api.identity.Author; import org.briarproject.api.identity.Author;
import org.briarproject.api.identity.AuthorId; import org.briarproject.api.identity.AuthorId;
import org.briarproject.api.identity.LocalAuthor; import org.briarproject.api.identity.LocalAuthor;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.sync.ClientId; import org.briarproject.api.sync.ClientId;
import org.briarproject.api.sync.Group; import org.briarproject.api.sync.Group;
import org.briarproject.api.sync.GroupId; import org.briarproject.api.sync.GroupId;
@@ -28,6 +28,7 @@ import org.junit.Before;
import org.junit.Test; import org.junit.Test;
import java.io.File; import java.io.File;
import java.security.SecureRandom;
import java.sql.Connection; import java.sql.Connection;
import java.util.ArrayList; import java.util.ArrayList;
import java.util.Arrays; import java.util.Arrays;
@@ -1121,7 +1122,7 @@ public class H2DatabaseTest extends BriarTestCase {
private Database<Connection> open(boolean resume) throws Exception { private Database<Connection> open(boolean resume) throws Exception {
Database<Connection> db = new H2Database(new TestDatabaseConfig(testDir, Database<Connection> db = new H2Database(new TestDatabaseConfig(testDir,
MAX_SIZE), new SystemClock()); MAX_SIZE), new SecureRandom(), new SystemClock());
if (!resume) TestUtils.deleteTestDirectory(testDir); if (!resume) TestUtils.deleteTestDirectory(testDir);
db.open(); db.open();
return db; return db;

View File

@@ -0,0 +1,14 @@
package org.briarproject.forum;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class ForumManagerImplTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.forum;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class ForumPostValidatorTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.messaging;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class MessagingManagerImplTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.messaging;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class PrivateMessageValidatorTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -1,11 +1,11 @@
package org.briarproject.plugins; package org.briarproject.plugins;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.crypto.PseudoRandom; import org.briarproject.api.crypto.PseudoRandom;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import java.io.IOException; import java.io.IOException;
import java.util.Map; import java.util.Map;

View File

@@ -1,10 +1,10 @@
package org.briarproject.plugins; package org.briarproject.plugins;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import java.util.Map; import java.util.Map;
import java.util.concurrent.CountDownLatch; import java.util.concurrent.CountDownLatch;

View File

@@ -13,7 +13,7 @@ import org.briarproject.api.plugins.simplex.SimplexPlugin;
import org.briarproject.api.plugins.simplex.SimplexPluginCallback; import org.briarproject.api.plugins.simplex.SimplexPluginCallback;
import org.briarproject.api.plugins.simplex.SimplexPluginConfig; import org.briarproject.api.plugins.simplex.SimplexPluginConfig;
import org.briarproject.api.plugins.simplex.SimplexPluginFactory; import org.briarproject.api.plugins.simplex.SimplexPluginFactory;
import org.briarproject.api.property.TransportPropertyManager; import org.briarproject.api.properties.TransportPropertyManager;
import org.briarproject.api.system.Clock; import org.briarproject.api.system.Clock;
import org.briarproject.api.ui.UiCallback; import org.briarproject.api.ui.UiCallback;
import org.briarproject.system.SystemClock; import org.briarproject.system.SystemClock;

View File

@@ -1,8 +1,8 @@
package org.briarproject.plugins.bluetooth; package org.briarproject.plugins.bluetooth;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexClientTest; import org.briarproject.plugins.DuplexClientTest;
import org.briarproject.system.SystemClock; import org.briarproject.system.SystemClock;

View File

@@ -1,7 +1,7 @@
package org.briarproject.plugins.bluetooth; package org.briarproject.plugins.bluetooth;
import org.briarproject.api.Settings; import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.TransportProperties; import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexServerTest; import org.briarproject.plugins.DuplexServerTest;
import org.briarproject.system.SystemClock; import org.briarproject.system.SystemClock;

View File

@@ -1,9 +1,9 @@
package org.briarproject.plugins.modem; package org.briarproject.plugins.modem;
import org.briarproject.BriarTestCase; import org.briarproject.BriarTestCase;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.properties.TransportProperties;
import org.jmock.Expectations; import org.jmock.Expectations;
import org.jmock.Mockery; import org.jmock.Mockery;
import org.junit.Test; import org.junit.Test;

View File

@@ -1,8 +1,8 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexClientTest; import org.briarproject.plugins.DuplexClientTest;
import java.util.Collections; import java.util.Collections;

View File

@@ -1,12 +1,12 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.BriarTestCase; import org.briarproject.BriarTestCase;
import org.briarproject.api.Settings;
import org.briarproject.api.TransportProperties;
import org.briarproject.api.contact.ContactId; import org.briarproject.api.contact.ContactId;
import org.briarproject.api.plugins.duplex.DuplexPlugin; import org.briarproject.api.plugins.duplex.DuplexPlugin;
import org.briarproject.api.plugins.duplex.DuplexPluginCallback; import org.briarproject.api.plugins.duplex.DuplexPluginCallback;
import org.briarproject.api.plugins.duplex.DuplexTransportConnection; import org.briarproject.api.plugins.duplex.DuplexTransportConnection;
import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.settings.Settings;
import org.junit.Test; import org.junit.Test;
import java.io.IOException; import java.io.IOException;

View File

@@ -1,7 +1,7 @@
package org.briarproject.plugins.tcp; package org.briarproject.plugins.tcp;
import org.briarproject.api.Settings; import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.TransportProperties; import org.briarproject.api.settings.Settings;
import org.briarproject.plugins.DuplexServerTest; import org.briarproject.plugins.DuplexServerTest;
import java.util.Collections; import java.util.Collections;

View File

@@ -0,0 +1,14 @@
package org.briarproject.properties;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class TransportPropertyManagerImplTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -0,0 +1,14 @@
package org.briarproject.properties;
import org.briarproject.BriarTestCase;
import org.junit.Test;
import static org.junit.Assert.fail;
public class TransportPropertyValidatorTest extends BriarTestCase {
@Test
public void testUnitTestsExist() {
fail(); // FIXME: Write tests
}
}

View File

@@ -54,7 +54,6 @@ import java.io.ByteArrayOutputStream;
import java.io.File; import java.io.File;
import java.io.InputStream; import java.io.InputStream;
import java.io.OutputStream; import java.io.OutputStream;
import java.util.Collections;
import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH; import static org.briarproject.api.identity.AuthorConstants.MAX_PUBLIC_KEY_LENGTH;
import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH; import static org.briarproject.api.transport.TransportConstants.TAG_LENGTH;
@@ -132,8 +131,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(bobAuthor, aliceId); ContactId contactId = contactManager.addContact(bobAuthor, aliceId);
// Derive and store the transport keys // Derive and store the transport keys
keyManager.addContact(contactId, Collections.singletonList(transportId), keyManager.addContact(contactId, master, timestamp, true);
master, timestamp, true);
// Send Bob a message // Send Bob a message
GroupId groupId = messagingManager.getConversationId(contactId); GroupId groupId = messagingManager.getConversationId(contactId);
@@ -198,8 +196,7 @@ public class SimplexMessagingIntegrationTest extends BriarTestCase {
new byte[MAX_PUBLIC_KEY_LENGTH]); new byte[MAX_PUBLIC_KEY_LENGTH]);
ContactId contactId = contactManager.addContact(aliceAuthor, bobId); ContactId contactId = contactManager.addContact(aliceAuthor, bobId);
// Derive and store the transport keys // Derive and store the transport keys
keyManager.addContact(contactId, Collections.singletonList(transportId), keyManager.addContact(contactId, master, timestamp, false);
master, timestamp, false);
// Set up an event listener // Set up an event listener
MessageListener listener = new MessageListener(); MessageListener listener = new MessageListener();