Merge branch '573-hidden-service-for-crash-reports-and-feedback' into 'master'

Server-side code for accepting crash reports and feedback

* Moved some shared code for copying InputStreams to OutputStreams into a utility class
* Modified the  dev report sender to send one report per connection
  * Easier to handle on the server side
  * If the connection fails after sending any reports, they don't need to be resent
  * Tor will reuse the circuit, so it's cheap
* Added server-side code for accepting dev reports
  * We need to protect the server's resources from DoS attacks
  * Reports can't be larger than 1 MB
  * Connections are limited to an average rate of one per minute
  * The rate limiter uses a token bucket to allow bursts of up to 1,000 connections
  * If the rate limit is exceeded, connection attempts will fail - clients will retry next time they sign in
  * The limits can be raised when we move to a bigger server (and when we have some users)


See merge request !288
This commit is contained in:
akwizgran
2016-08-22 20:09:46 +00:00
10 changed files with 269 additions and 91 deletions

View File

@@ -34,8 +34,10 @@ import org.briarproject.api.properties.TransportProperties;
import org.briarproject.api.reporting.DevReporter;
import org.briarproject.api.settings.Settings;
import org.briarproject.api.system.LocationUtils;
import org.briarproject.util.IoUtils;
import org.briarproject.util.StringUtils;
import java.io.Closeable;
import java.io.EOFException;
import java.io.File;
import java.io.FileInputStream;
@@ -243,17 +245,17 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
// Unzip the Tor binary to the filesystem
in = getTorInputStream();
out = new FileOutputStream(torFile);
copy(in, out);
IoUtils.copy(in, out);
// Make the Tor binary executable
if (!torFile.setExecutable(true, true)) throw new IOException();
// Unzip the GeoIP database to the filesystem
in = getGeoIpInputStream();
out = new FileOutputStream(geoIpFile);
copy(in, out);
IoUtils.copy(in, out);
// Copy the config file to the filesystem
in = getConfigInputStream();
out = new FileOutputStream(configFile);
copy(in, out);
IoUtils.copy(in, out);
doneFile.createNewFile();
} catch (IOException e) {
tryToClose(in);
@@ -284,28 +286,9 @@ class TorPlugin implements DuplexPlugin, EventHandler, EventListener {
return appContext.getResources().getAssets().open("torrc");
}
private void copy(InputStream in, OutputStream out) throws IOException {
byte[] buf = new byte[4096];
while (true) {
int read = in.read(buf);
if (read == -1) break;
out.write(buf, 0, read);
}
in.close();
out.close();
}
private void tryToClose(InputStream in) {
private void tryToClose(Closeable c) {
try {
if (in != null) in.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}
}
private void tryToClose(OutputStream out) {
try {
if (out != null) out.close();
if (c != null) c.close();
} catch (IOException e) {
if (LOG.isLoggable(WARNING)) LOG.log(WARNING, e.toString(), e);
}