1
0
Fork 0
mirror of https://github.com/syncthing/syncthing-android.git synced 2024-12-23 03:11:30 +00:00

More refactoring

This commit is contained in:
Felix Ableitner 2017-10-02 15:40:10 +09:00
parent be1be9746e
commit e6c9960d0b
12 changed files with 98 additions and 73 deletions

View file

@ -334,7 +334,7 @@ public class SettingsActivity extends SyncthingActivity {
mUseRoot.setChecked(false);
new TestRootTask().execute();
} else {
new Thread(new ChownFilesRunnable()).start();
new Thread(() -> Util.fixAppDataPermissions(getActivity())).start();
mSyncthingService.getApi().showRestartDialog(getActivity());
}
return true;
@ -409,16 +409,5 @@ public class SettingsActivity extends SyncthingActivity {
}
}
}
/**
* Changes the owner of syncthing files so they can be accessed without root.
*/
private class ChownFilesRunnable implements Runnable {
@Override
public void run() {
Util.fixAppDataPermissions(getActivity());
}
}
}
}

View file

@ -24,6 +24,7 @@ import com.nutomic.syncthingandroid.service.RestApi;
import com.nutomic.syncthingandroid.service.SyncthingService;
import com.nutomic.syncthingandroid.util.Util;
import java.io.File;
import java.net.URL;
import java.text.NumberFormat;
import java.util.Locale;
@ -196,7 +197,7 @@ public class DrawerFragment extends Fragment implements View.OnClickListener {
private void showQrCode() {
//The QRCode request takes one paramteer called "text", which is the text to be converted to a QRCode.
String httpsCertPath = mActivity.getFilesDir() + "/" + SyncthingService.HTTPS_CERT_FILE;
File httpsCertPath = new File(mActivity.getFilesDir(), SyncthingService.HTTPS_CERT_FILE);
String apiKey = mActivity.getApi().getGui().apiKey;
String deviceId = mActivity.getApi().getLocalDevice().deviceID;
URL url = mActivity.getApi().getUrl();

View file

@ -19,6 +19,7 @@ import com.android.volley.toolbox.Volley;
import com.google.common.base.Optional;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
@ -78,10 +79,10 @@ public abstract class ApiRequest {
private final Context mContext;
private final URL mUrl;
private final String mPath;
private final String mHttpsCertPath;
private final File mHttpsCertPath;
private final String mApiKey;
public ApiRequest(Context context, URL url, String path, String httpsCertPath, String apiKey) {
public ApiRequest(Context context, URL url, String path, File httpsCertPath, String apiKey) {
mContext = context;
mUrl = url;
mPath = path;
@ -176,7 +177,7 @@ public abstract class ApiRequest {
private SSLSocketFactory getSslSocketFactory() {
try {
SSLContext sslContext = SSLContext.getInstance("TLS");
sslContext.init(null, new TrustManager[]{new SyncthingTrustManager()},
sslContext.init(null, new TrustManager[]{new SyncthingTrustManager(mHttpsCertPath)},
new SecureRandom());
return sslContext.getSocketFactory();
} catch (NoSuchAlgorithmException | KeyManagementException e) {
@ -184,51 +185,4 @@ public abstract class ApiRequest {
return null;
}
}
/*
* TrustManager checking against the local Syncthing instance's https public key.
*
* Based on http://stackoverflow.com/questions/16719959#16759793
*/
private class SyncthingTrustManager implements X509TrustManager {
private static final String TAG = "SyncthingTrustManager";
@Override
@SuppressLint("TrustAllX509TrustManager")
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/**
* Verifies certs against public key of the local syncthing instance
*/
@Override
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
InputStream is = null;
try {
is = new FileInputStream(mHttpsCertPath);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate ca = (X509Certificate) cf.generateCertificate(is);
for (X509Certificate cert : certs) {
cert.verify(ca.getPublicKey());
}
} catch (FileNotFoundException | NoSuchAlgorithmException | InvalidKeyException |
NoSuchProviderException | SignatureException e) {
throw new CertificateException("Untrusted Certificate!", e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
Log.w(TAG, e);
}
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}
}

View file

@ -7,6 +7,7 @@ import android.support.annotation.Nullable;
import com.android.volley.Request;
import com.google.common.base.Optional;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
@ -25,7 +26,7 @@ public class GetRequest extends ApiRequest {
public static final String URI_REPORT = "/rest/svc/report";
public static final String URI_EVENTS = "/rest/events";
public GetRequest(Context context, URL url, String path, String httpsCertPath, String apiKey,
public GetRequest(Context context, URL url, String path, File httpsCertPath, String apiKey,
@Nullable Map<String, String> params, OnSuccessListener listener) {
super(context, url, path, httpsCertPath, apiKey);
Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap());

View file

@ -6,6 +6,7 @@ import android.support.annotation.Nullable;
import com.google.common.base.Optional;
import java.io.File;
import java.net.URL;
import java.util.Collections;
import java.util.Map;
@ -14,7 +15,7 @@ public class ImageGetRequest extends ApiRequest {
public static final String QR_CODE_GENERATOR = "/qr/";
public ImageGetRequest(Context context, URL url, String path, String httpsCertPath, String apiKey,
public ImageGetRequest(Context context, URL url, String path, File httpsCertPath, String apiKey,
@Nullable Map<String, String> params, OnImageSuccessListener onSuccessListener, OnErrorListener onErrorListener) {
super(context, url, path, httpsCertPath, apiKey);
Map<String, String> safeParams = Optional.fromNullable(params).or(Collections.emptyMap());

View file

@ -8,6 +8,7 @@ import android.os.Handler;
import com.android.volley.Request;
import com.android.volley.VolleyError;
import java.io.File;
import java.net.URL;
import java.util.Collections;
@ -25,7 +26,7 @@ public class PollWebGuiAvailableTask extends ApiRequest {
private final OnSuccessListener mListener;
private final Handler mHandler = new Handler();
public PollWebGuiAvailableTask(Context context, URL url, String httpsCertPath, String apiKey,
public PollWebGuiAvailableTask(Context context, URL url, File httpsCertPath, String apiKey,
OnSuccessListener listener) {
super(context, url, "", httpsCertPath, apiKey);
mListener = listener;

View file

@ -5,6 +5,7 @@ import android.net.Uri;
import com.android.volley.Request;
import java.io.File;
import java.net.URL;
import java.util.Collections;
@ -12,7 +13,7 @@ public class PostConfigRequest extends ApiRequest {
private static final String URI_CONFIG = "/rest/system/config";
public PostConfigRequest(Context context, URL url, String httpsCertPath, String apiKey, String config,
public PostConfigRequest(Context context, URL url, File httpsCertPath, String apiKey, String config,
OnSuccessListener listener) {
super(context, url, URI_CONFIG, httpsCertPath, apiKey);
Uri uri = buildUri(Collections.emptyMap());

View file

@ -6,13 +6,14 @@ import android.net.Uri;
import com.android.volley.Request;
import com.google.common.collect.ImmutableMap;
import java.io.File;
import java.net.URL;
public class PostScanRequest extends ApiRequest {
private static final String URI_SCAN = "/rest/db/scan";
public PostScanRequest(Context context, URL url, String httpsCertPath, String apiKey,
public PostScanRequest(Context context, URL url, File httpsCertPath, String apiKey,
String folder, String sub) {
super(context, url, URI_SCAN, httpsCertPath, apiKey);
Uri uri = buildUri(ImmutableMap.of("folder", folder, "sub", sub));

View file

@ -0,0 +1,71 @@
package com.nutomic.syncthingandroid.http;
import android.annotation.SuppressLint;
import android.util.Log;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.io.InputStream;
import java.security.InvalidKeyException;
import java.security.NoSuchAlgorithmException;
import java.security.NoSuchProviderException;
import java.security.SignatureException;
import java.security.cert.CertificateException;
import java.security.cert.CertificateFactory;
import java.security.cert.X509Certificate;
import javax.net.ssl.X509TrustManager;
/*
* TrustManager checking against the local Syncthing instance's https public key.
*
* Based on http://stackoverflow.com/questions/16719959#16759793
*/
class SyncthingTrustManager implements X509TrustManager {
private static final String TAG = "SyncthingTrustManager";
private final File mHttpsCertPath;
SyncthingTrustManager(File httpsCertPath) {
mHttpsCertPath = httpsCertPath;
}
@Override
@SuppressLint("TrustAllX509TrustManager")
public void checkClientTrusted(X509Certificate[] chain, String authType)
throws CertificateException {
}
/**
* Verifies certs against public key of the local syncthing instance
*/
@Override
public void checkServerTrusted(X509Certificate[] certs,
String authType) throws CertificateException {
InputStream is = null;
try {
is = new FileInputStream(mHttpsCertPath);
CertificateFactory cf = CertificateFactory.getInstance("X.509");
X509Certificate ca = (X509Certificate) cf.generateCertificate(is);
for (X509Certificate cert : certs) {
cert.verify(ca.getPublicKey());
}
} catch (FileNotFoundException | NoSuchAlgorithmException | InvalidKeyException |
NoSuchProviderException | SignatureException e) {
throw new CertificateException("Untrusted Certificate!", e);
} finally {
try {
if (is != null)
is.close();
} catch (IOException e) {
Log.w(TAG, e);
}
}
}
public X509Certificate[] getAcceptedIssuers() {
return null;
}
}

View file

@ -32,6 +32,7 @@ import com.nutomic.syncthingandroid.model.SystemInfo;
import com.nutomic.syncthingandroid.model.SystemVersion;
import com.nutomic.syncthingandroid.util.FolderObserver;
import java.io.File;
import java.lang.reflect.Type;
import java.net.URL;
import java.util.Collections;
@ -75,7 +76,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
private final Context mContext;
private final URL mUrl;
private final String mApiKey;
private final String mHttpsCertPath;
private final File mHttpsCertPath;
private String mVersion;
private Config mConfig;
@ -104,7 +105,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
mContext = context;
mUrl = url;
mApiKey = apiKey;
mHttpsCertPath = mContext.getFilesDir() + "/" + SyncthingService.HTTPS_CERT_FILE;
mHttpsCertPath = new File(mContext.getFilesDir(), SyncthingService.HTTPS_CERT_FILE);
mOnApiAvailableListener = apiListener;
mOnConfigChangedListener = configListener;
}
@ -151,7 +152,7 @@ public class RestApi implements SyncthingService.OnWebGuiAvailableListener,
/**
* Increments mAvailableCount by one, and, if it reached TOTAL_STARTUP_CALLS,
* calls {@link SyncthingService#onApiChange()}.
* calls {@link SyncthingService#onApiChange}.
*/
private void tryIsAvailable() {
int value = mAvailableCount.incrementAndGet();

View file

@ -28,6 +28,7 @@ import java.io.IOException;
import java.io.InputStream;
import java.io.InputStreamReader;
import java.io.LineNumberReader;
import java.security.InvalidParameterException;
import java.util.HashMap;
import java.util.Map;
import java.util.concurrent.atomic.AtomicReference;
@ -85,7 +86,7 @@ public class SyncthingRunnable implements Runnable {
mCommand = new String[]{ mSyncthingBinary, "-home", mContext.getFilesDir().toString(), "-reset" };
break;
default:
Log.w(TAG, "Unknown command option");
throw new InvalidParameterException("Unknown command option");
}
}
@ -342,6 +343,9 @@ public class SyncthingRunnable implements Runnable {
* Only keep last {@link #LOG_FILE_MAX_LINES} lines in log file, to avoid bloat.
*/
private void trimLogFile() {
if (!mLogFile.exists())
return;
try {
LineNumberReader lnr = new LineNumberReader(new FileReader(mLogFile));
lnr.skip(Long.MAX_VALUE);

View file

@ -471,7 +471,7 @@ public class SyncthingService extends Service implements
* for SyncthingService.onDestroy for details.
*/
private void pollWebGui() {
new PollWebGuiAvailableTask(this, getWebGuiUrl(), getFilesDir() + "/" + HTTPS_CERT_FILE,
new PollWebGuiAvailableTask(this, getWebGuiUrl(), new File(getFilesDir(), HTTPS_CERT_FILE),
mConfig.getApiKey(), result -> {
synchronized (stateLock) {
if (mStopScheduled) {