package io.scal.secureshareui.login;
import info.guardianproject.netcipher.proxy.OrbotHelper;
import info.guardianproject.netcipher.web.WebkitProxy;
import timber.log.Timber;
import io.scal.secureshareui.controller.SiteController;
import io.scal.secureshareui.lib.Util;
import io.scal.secureshareuilibrary.R;
import android.annotation.SuppressLint;
import android.app.Activity;
import android.app.AlertDialog;
import android.content.DialogInterface;
import android.content.Intent;
import android.content.SharedPreferences;
import android.os.Bundle;
import android.support.v7.app.ActionBarActivity;
import android.preference.PreferenceManager;
import android.util.Log;
import android.view.View;
import android.webkit.JavascriptInterface;
import android.webkit.WebView;
import android.webkit.WebViewClient;
public class ArchiveLoginActivity extends LockableActionBarActivity {
private static final String TAG = "ArchiveLoginActivity";
private final static String ARCHIVE_CREATE_ACCOUNT_URL = "https://archive.org/account/login.createaccount.php";
private final static String ARCHIVE_LOGIN_URL = "https://archive.org/account/login.php";
private final static String ARCHIVE_LOGGED_IN_URL = "https://archive.org/index.php";
private final static String ARCHIVE_CREDENTIALS_URL = "https://archive.org/account/s3.php";
private static boolean sIsLoginScren = false;
private int mAccessResult = Activity.RESULT_CANCELED;
private String mAccessKey = null;
private String mSecretKey = null;
// FIXME security: we need to override the webviews cache, cookies, formdata cache to store only in sqlcipher/iocipher, currently it hits disk and then we clear it
private WebView mWebview;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.activity_archive_login);
login(ARCHIVE_LOGIN_URL);
}
@SuppressLint({ "SetJavaScriptEnabled" })
private void login(String currentURL) {
// check for tor settings and set proxy
SharedPreferences settings = PreferenceManager.getDefaultSharedPreferences(getApplicationContext());
boolean useTor = settings.getBoolean("pusetor", false);
mWebview = (WebView) findViewById(R.id.webView);
if (useTor) {
Timber.d("user selected \"use tor\"");
if ((!OrbotHelper.isOrbotInstalled(getApplicationContext())) || (!OrbotHelper.isOrbotRunning(getApplicationContext()))) {
Timber.e("user selected \"use tor\" but orbot is not installed or not running");
return;
} else {
try {
WebkitProxy.setProxy("android.app.Application", getApplicationContext(), mWebview, Util.ORBOT_HOST, Util.ORBOT_HTTP_PORT);
} catch (Exception e) {
Timber.e("user selected \"use tor\" but an exception was thrown while setting the proxy: " + e.getLocalizedMessage());
return;
}
}
} else {
Timber.d("user selected \"don't use tor\"");
}
mWebview.getSettings().setJavaScriptEnabled(true);
mWebview.setVisibility(View.VISIBLE);
mWebview.addJavascriptInterface(new JSInterface(), "htmlout");
mWebview.setWebViewClient(new WebViewClient() {
@Override
public boolean shouldOverrideUrlLoading(WebView view, String url) {
//if logged in, hide and redirect to credentials
if (url.equals(ARCHIVE_LOGGED_IN_URL)) {
view.setVisibility(View.INVISIBLE);
view.loadUrl(ARCHIVE_CREDENTIALS_URL);
return true;
}
return false;
}
@Override
public void onPageFinished(WebView view, String url) {
super.onPageFinished(view, url);
//if credentials page, inject JS for scraping
if (url.equals(ARCHIVE_CREDENTIALS_URL)) {
sIsLoginScren = true;
String jsCheckBox= "javascript:(function(){document.getElementById('confirm').checked=true;})();";
String jsBtnClick = "javascript:(function(){$('[value=\"Generate New Keys\"]').click();})();";
String jsSourceDump = "javascript:window.htmlout.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');";
mWebview.loadUrl(jsCheckBox + jsBtnClick + jsSourceDump);
} else if(url.equals(ARCHIVE_CREATE_ACCOUNT_URL)) {
sIsLoginScren = false;
String jsSourceDump = "javascript:window.htmlout.processHTML('<html>'+document.getElementsByTagName('html')[0].innerHTML+'</html>');";
mWebview.loadUrl(jsSourceDump);
}
}
});
mWebview.loadUrl(currentURL);
}
private void parseArchiveCredentials(String rawHtml) {
//strip code sections
String startCode = "<code>";
String endCode = "</code>";
int iStartCode = rawHtml.indexOf(startCode);
int iEndCode = rawHtml.lastIndexOf(endCode);
//code tags not on page
if(iStartCode < 0 || iEndCode < 0) {
return;
}
String rawCodes = rawHtml.substring(iStartCode, iEndCode);
rawCodes = rawCodes.replaceAll("\\s", "");
//check to see codes are !present
if(rawCodes.contains("GenerateNewKeys")) {
return;
}
//strip codes
char colon = ':';
String brk = "<br";
int iFirstColon = rawCodes.indexOf(colon) + 1;
int iLastColon = rawCodes.lastIndexOf(colon) + 1;
int iFirstLt = rawCodes.indexOf(brk);
int iLastLt = rawCodes.lastIndexOf(brk);
mAccessKey = rawCodes.substring(iFirstColon, iFirstLt);
mSecretKey = rawCodes.substring(iLastColon, iLastLt);
if(null != mAccessKey && null != mSecretKey) {
mAccessResult = Activity.RESULT_OK;
}
finish();
}
class JSInterface {
@JavascriptInterface
public void processHTML(String html) {
if(null == html) {
return;
}
if(sIsLoginScren) {
parseArchiveCredentials(html);
} else if (html.contains("Verification Email Sent")) {
showAccountCreatedDialog(new DialogInterface.OnClickListener() {
@Override
public void onClick(DialogInterface dialog, int which) {
finish();
}
});
}
}
}
private void showAccountCreatedDialog(DialogInterface.OnClickListener positiveBtnClickListener) {
new AlertDialog.Builder(this)
.setTitle(getString(R.string.archive_title))
.setMessage(getString(R.string.archive_message))
.setPositiveButton(R.string.lbl_ok, positiveBtnClickListener).show();
}
@Override
public void finish() {
Timber.d("finish()");
Intent data = new Intent();
data.putExtra(SiteController.EXTRAS_KEY_USERNAME, mAccessKey);
data.putExtra(SiteController.EXTRAS_KEY_CREDENTIALS, mSecretKey);
setResult(mAccessResult, data);
super.finish();
Util.clearWebviewAndCookies(mWebview, this);
}
}