Skip to content

Commit

Permalink
Merge pull request #527 from guardianproject/fix_523_onionbackup
Browse files Browse the repository at this point in the history
Fixes #523 Onion Site Backup Bugs
  • Loading branch information
n8fr8 authored Oct 12, 2021
2 parents d3fba52 + 5465fff commit e815bc0
Show file tree
Hide file tree
Showing 9 changed files with 33 additions and 23 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,8 @@ public class HiddenServicesActivity extends AppCompatActivity {
BUNDLE_KEY_PORT = "port",
BUNDLE_KEY_ONION = "onion",
BUNDLE_KEY_AUTH_COOKIE = "auth_cookie",
BUNDLE_KEY_AUTH_COOKIE_VALUE = "auth_cookie_value";
BUNDLE_KEY_AUTH_COOKIE_VALUE = "auth_cookie_value",
BUNDLE_KEY_PATH = "path";
private static final int REQUEST_CODE_READ_ZIP_BACKUP = 125;
private static final String BUNDLE_KEY_SHOW_USER_SERVICES = "show_user_services";
private ContentResolver mResolver;
Expand Down Expand Up @@ -83,6 +84,7 @@ protected void onCreate(Bundle savedInstanceState) {
arguments.putString(BUNDLE_KEY_ONION, item.getString(item.getColumnIndex(HSContentProvider.HiddenService.DOMAIN)));
arguments.putInt(BUNDLE_KEY_AUTH_COOKIE, item.getInt(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE)));
arguments.putString(BUNDLE_KEY_AUTH_COOKIE_VALUE, item.getString(item.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE)));
arguments.putString(BUNDLE_KEY_PATH, item.getString(item.getColumnIndex(HSContentProvider.HiddenService.PATH)));

HSActionsDialog dialog = new HSActionsDialog();
dialog.setArguments(arguments);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,8 +40,8 @@ public BackupUtils(Context context) {
mResolver = mContext.getContentResolver();
}

public String createV3ZipBackup(String port, Uri zipFile) {
String[] files = createFilesForZippingV3(port);
public String createV3ZipBackup(String port, String relativePath, Uri zipFile) {
String[] files = createFilesForZippingV3(relativePath);
ZipUtilities zip = new ZipUtilities(files, zipFile, mResolver);
if (!zip.zip()) return null;
return zipFile.getPath();
Expand All @@ -61,8 +61,8 @@ public String createV3AuthBackup(String domain, String keyHash, Uri backupFile)
return backupFile.getPath();
}

public String createV2ZipBackup(int port, Uri zipFile) {
String[] files = createFilesForZippingV2(port);
public String createV2ZipBackup(int port, String relativePath, Uri zipFile) {
String[] files = createFilesForZippingV2(relativePath);
ZipUtilities zip = new ZipUtilities(files, zipFile, mResolver);

if (!zip.zip())
Expand All @@ -72,15 +72,15 @@ public String createV2ZipBackup(int port, Uri zipFile) {
}

// todo this doesn't export data for onions that orbot hosts which have authentication (not supported yet...)
private String[] createFilesForZippingV3(String port) {
final String v3BasePath = getV3BasePath() + "/v3" + port + "/";
private String[] createFilesForZippingV3(String relativePath) {
final String v3BasePath = getV3BasePath() + "/" + relativePath + "/";
final String hostnamePath = v3BasePath + "hostname",
configFilePath = v3BasePath + configFileName,
privKeyPath = v3BasePath + "hs_ed25519_secret_key",
pubKeyPath = v3BasePath + "hs_ed25519_public_key";

Cursor portData = mResolver.query(OnionServiceContentProvider.CONTENT_URI, OnionServiceContentProvider.PROJECTION,
OnionServiceContentProvider.OnionService.PORT + "=" + port, null, null);
OnionServiceContentProvider.OnionService.PATH + "=\"" + relativePath + "\"", null, null);

JSONObject config = new JSONObject();
try {
Expand Down Expand Up @@ -109,16 +109,16 @@ private String[] createFilesForZippingV3(String port) {
return new String[]{hostnamePath, configFilePath, privKeyPath, pubKeyPath};
}

private String[] createFilesForZippingV2(int port) {
File hsBasePath = getHSBasePath();
String configFilePath = hsBasePath + "/hs" + port + "/" + configFileName;
String hostnameFilePath = hsBasePath + "/hs" + port + "/hostname";
String keyFilePath = hsBasePath + "/hs" + port + "/private_key";
private String[] createFilesForZippingV2(String relativePath) {
final String hsBasePath = getHSBasePath() + "/" + relativePath + "/";
String configFilePath = hsBasePath + configFileName;
String hostnameFilePath = hsBasePath + "hostname";
String keyFilePath = hsBasePath + "private_key";

Cursor portData = mResolver.query(
HSContentProvider.CONTENT_URI,
HSContentProvider.PROJECTION,
HSContentProvider.HiddenService.PORT + "=" + port,
HSContentProvider.HiddenService.PATH + "=\"" + relativePath + "\"",
null,
null
);
Expand Down Expand Up @@ -193,7 +193,7 @@ private void extractConfigFromUnzippedBackupV3(String backupName) {
Toast.makeText(mContext, R.string.backup_restored, Toast.LENGTH_LONG).show();
} else {
// collision, clean up files
for (File file: v3Path.listFiles())
for (File file : v3Path.listFiles())
file.delete();
v3Path.delete();
Toast.makeText(mContext, mContext.getString(R.string.backup_port_exist, port), Toast.LENGTH_LONG).show();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -107,8 +107,9 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}

private void attemptToWriteBackup(Uri outputFile) {
String path = getArguments().getString(HiddenServicesActivity.BUNDLE_KEY_PATH);
BackupUtils backupUtils = new BackupUtils(getContext());
String backup = backupUtils.createV2ZipBackup(port, outputFile);
String backup = backupUtils.createV2ZipBackup(port, path, outputFile);
Toast.makeText(getContext(), backup != null ? R.string.backup_saved_at_external_storage : R.string.error, Toast.LENGTH_LONG).show();
dismiss();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -33,7 +33,7 @@ private void doDelete(Bundle arguments, Context context) {

// Delete from internal storage
String base = context.getFilesDir().getAbsolutePath() + "/" + TorServiceConstants.HIDDEN_SERVICES_DIR;
File dir = new File(base, "hs" + arguments.getString(HiddenServicesActivity.BUNDLE_KEY_PORT));
File dir = new File(base, arguments.getString(HiddenServicesActivity.BUNDLE_KEY_PATH));

if (dir.isDirectory()) {
String[] children = dir.list();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,8 @@ public class HSContentProvider extends ContentProvider {
HiddenService.AUTH_COOKIE,
HiddenService.AUTH_COOKIE_VALUE,
HiddenService.CREATED_BY_USER,
HiddenService.ENABLED
HiddenService.ENABLED,
HiddenService.PATH
};
private static final String AUTH = "org.torproject.android.ui.hiddenservices.providers";
public static final Uri CONTENT_URI = Uri.parse("content://" + AUTH + "/hs");
Expand Down Expand Up @@ -134,6 +135,7 @@ public static final class HiddenService implements BaseColumns {
public static final String AUTH_COOKIE_VALUE = "auth_cookie_value";
public static final String CREATED_BY_USER = "created_by_user";
public static final String ENABLED = "enabled";
public static final String PATH = "filepath";

private HiddenService() {
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -63,6 +63,7 @@ private void doCopy(Bundle arguments, Context context) {

private void doBackup(Bundle arguments, Context context) {
String filename = "onion_service" + arguments.getString(OnionServiceActivity.BUNDLE_KEY_PORT) + ".zip";
String relativePath = arguments.getString(OnionServiceActivity.BUNDLE_KEY_PATH);
if (arguments.getString(OnionServiceActivity.BUNDLE_KEY_DOMAIN) == null) {
Toast.makeText(context, R.string.please_restart_Orbot_to_enable_the_changes, Toast.LENGTH_LONG).show();
return;
Expand All @@ -85,8 +86,10 @@ public void onActivityResult(int requestCode, int resultCode, Intent data) {
}

private void attemptToWriteBackup(Uri outputFile) {
String port = getArguments().getString(OnionServiceActivity.BUNDLE_KEY_PORT);
String relativePath = getArguments().getString(OnionServiceActivity.BUNDLE_KEY_PATH);
BackupUtils backupUtils = new BackupUtils(getContext());
String backup = backupUtils.createV3ZipBackup(getArguments().getString(OnionServiceActivity.BUNDLE_KEY_PORT), outputFile);
String backup = backupUtils.createV3ZipBackup(port, relativePath, outputFile);
Toast.makeText(getContext(), backup != null ? R.string.backup_saved_at_external_storage : R.string.error, Toast.LENGTH_LONG).show();
dismiss();
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -32,7 +32,7 @@

public class OnionServiceActivity extends AppCompatActivity {

static final String BUNDLE_KEY_ID = "id", BUNDLE_KEY_PORT = "port", BUNDLE_KEY_DOMAIN = "domain";
static final String BUNDLE_KEY_ID = "id", BUNDLE_KEY_PORT = "port", BUNDLE_KEY_DOMAIN = "domain", BUNDLE_KEY_PATH = "path";
private static final String BASE_WHERE_SELECTION_CLAUSE = OnionServiceContentProvider.OnionService.CREATED_BY_USER + "=";
private static final String BUNDLE_KEY_SHOW_USER_SERVICES = "show_user_key";
private static final int REQUEST_CODE_READ_ZIP_BACKUP = 347;
Expand Down Expand Up @@ -72,6 +72,7 @@ public void onCreate(Bundle bundle) {
arguments.putInt(BUNDLE_KEY_ID, item.getInt(item.getColumnIndex(OnionServiceContentProvider.OnionService._ID)));
arguments.putString(BUNDLE_KEY_PORT, item.getString(item.getColumnIndex(OnionServiceContentProvider.OnionService.PORT)));
arguments.putString(BUNDLE_KEY_DOMAIN, item.getString(item.getColumnIndex(OnionServiceContentProvider.OnionService.DOMAIN)));
arguments.putString(BUNDLE_KEY_PATH, item.getString(item.getColumnIndex(OnionServiceContentProvider.OnionService.PATH)));
OnionServiceActionsDialogFragment dialog = new OnionServiceActionsDialogFragment(arguments);
dialog.show(getSupportFragmentManager(), OnionServiceActionsDialogFragment.class.getSimpleName());
});
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,7 +21,8 @@ public class OnionServiceContentProvider extends ContentProvider {
OnionService.DOMAIN,
OnionService.ONION_PORT,
OnionService.CREATED_BY_USER,
OnionService.ENABLED
OnionService.ENABLED,
OnionService.PATH
};

private static final int ONIONS = 1, ONION_ID = 2;
Expand Down Expand Up @@ -102,7 +103,7 @@ public static final class OnionService implements BaseColumns {
public static final String DOMAIN = "domain";
public static final String CREATED_BY_USER = "created_by_user";
public static final String ENABLED = "enabled";

public static final String PATH = "filepath";
private OnionService() { // no-op
}
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,7 +34,7 @@ public Dialog onCreateDialog(@Nullable Bundle savedInstanceState) {
private void doDelete(Bundle arguments, Context context) {
context.getContentResolver().delete(OnionServiceContentProvider.CONTENT_URI, OnionServiceContentProvider.OnionService._ID + '=' + arguments.getInt(OnionServiceActivity.BUNDLE_KEY_ID), null);
String base = context.getFilesDir().getAbsolutePath() + "/" + TorServiceConstants.ONION_SERVICES_DIR;
DiskUtils.recursivelyDeleteDirectory(new File(base, "v3" + arguments.getString(OnionServiceActivity.BUNDLE_KEY_PORT)));
DiskUtils.recursivelyDeleteDirectory(new File(base, arguments.getString(OnionServiceActivity.BUNDLE_KEY_PATH)));
}

}

0 comments on commit e815bc0

Please sign in to comment.