mirror of
https://github.com/syncthing/syncthing-android.git
synced 2024-11-22 20:31:16 +00:00
More refactoring
This commit is contained in:
parent
be1be9746e
commit
e6c9960d0b
12 changed files with 98 additions and 73 deletions
|
@ -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());
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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();
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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());
|
||||
|
|
|
@ -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));
|
||||
|
|
|
@ -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;
|
||||
}
|
||||
}
|
|
@ -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();
|
||||
|
|
|
@ -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);
|
||||
|
|
|
@ -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) {
|
||||
|
|
Loading…
Reference in a new issue