tor-android/app/src/main/java/org/torproject/android/ui/hiddenservices/backup/BackupUtils.java

337 lines
12 KiB
Java
Raw Normal View History

2016-11-24 02:56:11 +01:00
package org.torproject.android.ui.hiddenservices.backup;
2016-11-18 00:53:49 +01:00
2016-11-27 17:15:15 +01:00
import android.content.ContentResolver;
2016-11-27 18:50:20 +01:00
import android.content.ContentValues;
2016-11-18 00:53:49 +01:00
import android.content.Context;
2016-11-27 17:15:15 +01:00
import android.database.Cursor;
2016-11-27 20:57:47 +01:00
import android.net.Uri;
import android.os.ParcelFileDescriptor;
2016-11-24 02:22:41 +01:00
import android.widget.Toast;
2016-11-18 00:53:49 +01:00
2016-11-27 17:15:15 +01:00
import org.json.JSONException;
import org.json.JSONObject;
2016-11-27 18:50:20 +01:00
import org.torproject.android.R;
2016-11-18 00:53:49 +01:00
import org.torproject.android.service.TorServiceConstants;
import org.torproject.android.ui.hiddenservices.providers.CookieContentProvider;
2016-11-27 17:15:15 +01:00
import org.torproject.android.ui.hiddenservices.providers.HSContentProvider;
2016-11-24 02:56:11 +01:00
import org.torproject.android.ui.hiddenservices.storage.ExternalStorage;
2016-11-18 00:53:49 +01:00
import java.io.File;
2016-11-27 18:50:20 +01:00
import java.io.FileInputStream;
2016-11-27 20:57:47 +01:00
import java.io.FileOutputStream;
2016-11-27 17:15:15 +01:00
import java.io.FileWriter;
2016-11-24 02:22:41 +01:00
import java.io.IOException;
2016-11-27 20:57:47 +01:00
import java.io.InputStream;
import java.io.OutputStream;
2016-11-27 18:50:20 +01:00
import java.nio.MappedByteBuffer;
import java.nio.channels.FileChannel;
import java.nio.charset.Charset;
2016-11-18 00:53:49 +01:00
2016-11-22 22:37:34 +01:00
public class BackupUtils {
2016-11-27 18:50:20 +01:00
private final String configFileName = "config.json";
2016-11-24 02:22:41 +01:00
private Context mContext;
2016-11-27 17:15:15 +01:00
private ContentResolver mResolver;
2016-11-18 00:53:49 +01:00
2016-11-22 22:37:34 +01:00
public BackupUtils(Context context) {
2016-11-24 02:22:41 +01:00
mContext = context;
2016-11-27 17:15:15 +01:00
mResolver = mContext.getContentResolver();
2016-11-18 00:53:49 +01:00
}
2016-11-23 21:20:50 +01:00
public String createZipBackup(Integer port) {
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
2016-11-18 00:53:49 +01:00
2016-11-27 17:15:15 +01:00
String configFilePath = mHSBasePath + "/hs" + port + "/" + configFileName;
String hostnameFilePath = mHSBasePath + "/hs" + port + "/hostname";
String keyFilePath = mHSBasePath + "/hs" + port + "/private_key";
2016-11-24 02:22:41 +01:00
File storage_path = ExternalStorage.getOrCreateBackupDir();
if (storage_path == null)
2016-11-18 00:53:49 +01:00
return null;
2016-11-27 17:15:15 +01:00
Cursor portData = mResolver.query(
HSContentProvider.CONTENT_URI,
HSContentProvider.PROJECTION,
HSContentProvider.HiddenService.PORT + "=" + port,
null,
null
);
JSONObject config = new JSONObject();
try {
2016-11-27 20:07:49 +01:00
if (portData == null || portData.getCount() != 1)
2016-11-27 17:15:15 +01:00
return null;
portData.moveToNext();
config.put(
HSContentProvider.HiddenService.NAME,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.NAME))
);
config.put(
HSContentProvider.HiddenService.PORT,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.PORT))
);
config.put(
HSContentProvider.HiddenService.ONION_PORT,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.ONION_PORT))
);
config.put(
HSContentProvider.HiddenService.DOMAIN,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.DOMAIN))
);
config.put(
HSContentProvider.HiddenService.AUTH_COOKIE,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE))
);
config.put(
HSContentProvider.HiddenService.AUTH_COOKIE_VALUE,
portData.getString(portData.getColumnIndex(HSContentProvider.HiddenService.AUTH_COOKIE_VALUE))
);
2016-11-27 17:15:15 +01:00
config.put(
HSContentProvider.HiddenService.CREATED_BY_USER,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.CREATED_BY_USER))
);
config.put(
HSContentProvider.HiddenService.ENABLED,
portData.getInt(portData.getColumnIndex(HSContentProvider.HiddenService.ENABLED))
);
2016-11-27 17:15:15 +01:00
} catch (JSONException e) {
e.printStackTrace();
return null;
} catch (NullPointerException e) {
e.printStackTrace();
return null;
}
portData.close();
2016-11-27 17:15:15 +01:00
try {
FileWriter file = new FileWriter(configFilePath);
file.write(config.toString());
file.close();
} catch (IOException e) {
e.printStackTrace();
return null;
}
2016-11-24 02:22:41 +01:00
String zip_path = storage_path.getAbsolutePath() + "/hs" + port + ".zip";
2016-11-27 17:15:15 +01:00
String files[] = {hostnameFilePath, keyFilePath, configFilePath};
2016-11-18 00:53:49 +01:00
ZipIt zip = new ZipIt(files, zip_path);
2016-11-27 17:15:15 +01:00
if (!zip.zip())
2016-11-18 00:53:49 +01:00
return null;
return zip_path;
}
2016-11-27 18:50:20 +01:00
public void restoreZipBackup(File backup) {
2016-11-27 19:19:44 +01:00
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
2016-11-27 19:19:44 +01:00
int port;
Cursor service;
2016-11-27 18:50:20 +01:00
String backupName = backup.getName();
String hsDir = backupName.substring(0, backupName.lastIndexOf('.'));
String configFilePath = mHSBasePath + "/" + hsDir + "/" + configFileName;
String jString = null;
File hsPath = new File(mHSBasePath.getAbsolutePath(), hsDir);
if (!hsPath.isDirectory())
hsPath.mkdirs();
ZipIt zip = new ZipIt(null, backup.getAbsolutePath());
zip.unzip(hsPath.getAbsolutePath());
File config = new File(configFilePath);
FileInputStream stream;
2016-11-27 18:50:20 +01:00
2016-11-24 02:22:41 +01:00
try {
2016-11-27 18:50:20 +01:00
stream = new FileInputStream(config);
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
jString = Charset.defaultCharset().decode(bb).toString();
stream.close();
2016-11-24 02:22:41 +01:00
} catch (IOException e) {
e.printStackTrace();
}
2016-11-27 18:50:20 +01:00
if (jString == null)
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
try {
JSONObject savedValues = new JSONObject(jString);
ContentValues fields = new ContentValues();
fields.put(
HSContentProvider.HiddenService.NAME,
savedValues.getString(HSContentProvider.HiddenService.NAME)
);
fields.put(
HSContentProvider.HiddenService.ONION_PORT,
savedValues.getInt(HSContentProvider.HiddenService.ONION_PORT)
);
fields.put(
HSContentProvider.HiddenService.DOMAIN,
savedValues.getString(HSContentProvider.HiddenService.DOMAIN)
);
fields.put(
HSContentProvider.HiddenService.AUTH_COOKIE,
savedValues.getInt(HSContentProvider.HiddenService.AUTH_COOKIE)
);
2016-11-27 18:50:20 +01:00
fields.put(
HSContentProvider.HiddenService.CREATED_BY_USER,
savedValues.getInt(HSContentProvider.HiddenService.CREATED_BY_USER)
);
fields.put(
HSContentProvider.HiddenService.ENABLED,
savedValues.getInt(HSContentProvider.HiddenService.ENABLED)
);
2016-11-27 19:19:44 +01:00
port = savedValues.getInt(HSContentProvider.HiddenService.PORT);
fields.put(HSContentProvider.HiddenService.PORT, port);
service = mResolver.query(
2016-11-27 19:12:16 +01:00
HSContentProvider.CONTENT_URI,
HSContentProvider.PROJECTION,
HSContentProvider.HiddenService.PORT + "=" + port,
null,
null
);
2016-11-27 20:07:49 +01:00
if (service == null || service.getCount() == 0) {
2016-11-27 19:12:16 +01:00
mResolver.insert(HSContentProvider.CONTENT_URI, fields);
} else {
mResolver.update(
HSContentProvider.CONTENT_URI,
fields,
HSContentProvider.HiddenService.PORT + "=" + port,
null
);
2016-11-27 20:07:49 +01:00
service.close();
}
2016-11-27 19:12:16 +01:00
2016-11-27 18:50:20 +01:00
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
}
Toast.makeText(mContext, R.string.backup_restored, Toast.LENGTH_LONG).show();
2016-11-18 00:53:49 +01:00
}
2016-11-27 20:57:47 +01:00
public void restoreKeyBackup(int hsPort, Uri hsKeyPath) {
File mHSBasePath = new File(
mContext.getFilesDir().getAbsolutePath(),
TorServiceConstants.HIDDEN_SERVICES_DIR
);
2016-11-28 01:04:32 +01:00
File serviceDir = new File(mHSBasePath, "hs" + hsPort);
if (!serviceDir.isDirectory())
serviceDir.mkdirs();
2016-11-27 20:57:47 +01:00
try {
ParcelFileDescriptor mInputPFD = mContext.getContentResolver().openFileDescriptor(hsKeyPath, "r");
InputStream fileStream = new FileInputStream(mInputPFD.getFileDescriptor());
2016-11-28 01:04:32 +01:00
OutputStream file = new FileOutputStream(serviceDir.getAbsolutePath() + "/private_key");
2016-11-27 20:57:47 +01:00
byte[] buffer = new byte[1024];
int length;
while ((length = fileStream.read(buffer)) > 0) {
file.write(buffer, 0, length);
}
file.close();
} catch (IOException | NullPointerException e) {
e.printStackTrace();
}
}
public void restoreCookieBackup(File p) {
File config = new File(p.getAbsolutePath());
FileInputStream stream;
String jString = null;
try {
stream = new FileInputStream(config);
FileChannel fc = stream.getChannel();
MappedByteBuffer bb = fc.map(FileChannel.MapMode.READ_ONLY, 0, fc.size());
jString = Charset.defaultCharset().decode(bb).toString();
stream.close();
} catch (IOException e) {
e.printStackTrace();
}
if (jString == null)
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
try {
JSONObject savedValues = new JSONObject(jString);
ContentValues fields = new ContentValues();
fields.put(
CookieContentProvider.ClientCookie.DOMAIN,
savedValues.getString(CookieContentProvider.ClientCookie.DOMAIN)
);
fields.put(
CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE,
savedValues.getString(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE)
);
fields.put(
CookieContentProvider.ClientCookie.ENABLED,
savedValues.getInt(CookieContentProvider.ClientCookie.ENABLED)
);
mResolver.insert(CookieContentProvider.CONTENT_URI, fields);
} catch (JSONException e) {
e.printStackTrace();
Toast.makeText(mContext, R.string.error, Toast.LENGTH_LONG).show();
}
Toast.makeText(mContext, R.string.backup_restored, Toast.LENGTH_LONG).show();
}
public String createCookieBackup(String domain, String cookie, Integer enabled) {
File storage_path = ExternalStorage.getOrCreateBackupDir();
String backupFile = storage_path.getAbsolutePath() + '/' + domain.replace(".onion", ".json");
JSONObject backup = new JSONObject();
try {
backup.put(CookieContentProvider.ClientCookie.DOMAIN, domain);
backup.put(CookieContentProvider.ClientCookie.AUTH_COOKIE_VALUE, cookie);
backup.put(CookieContentProvider.ClientCookie.ENABLED, enabled);
FileWriter file = new FileWriter(backupFile);
file.write(backup.toString());
file.close();
} catch (JSONException | IOException e) {
e.printStackTrace();
return null;
}
return backupFile;
}
2016-11-18 00:53:49 +01:00
}