mirror of
https://github.com/moparisthebest/SSLDroid
synced 2024-11-23 09:22:16 -05:00
Heavy refactoring, implemented proper GUI
Migrated settings to be sqlite-based and the GUI to be based on ListActivity Signed-off-by: Balint Kovacs <blint@blint.hu>
This commit is contained in:
parent
4d724fb37d
commit
422b11fdef
@ -9,6 +9,8 @@
|
||||
<category android:name="android.intent.category.LAUNCHER" />
|
||||
</intent-filter>
|
||||
</activity>
|
||||
<activity android:name=".SSLDroidTunnelDetails"
|
||||
android:windowSoftInputMode="stateVisible|adjustResize" />
|
||||
<service android:enabled="true" android:name="SSLDroid">
|
||||
<intent-filter>
|
||||
<action android:name="hu.blint.ssldroid.SSLDroid" />
|
||||
|
BIN
bin/SSLDroid.apk
BIN
bin/SSLDroid.apk
Binary file not shown.
BIN
bin/classes.dex
BIN
bin/classes.dex
Binary file not shown.
Binary file not shown.
@ -3,27 +3,28 @@
|
||||
android:orientation="vertical"
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent"
|
||||
android:gravity="center">
|
||||
<TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<TextView android:text="@string/local_port" android:gravity="left" android:layout_height="wrap_content" android:layout_width="wrap_content" android:textSize="15sp" android:id="@+id/localportlabel"></TextView>
|
||||
<EditText android:layout_width="70dip" android:text="@string/empty" android:id="@+id/localport" android:digits="0123456789" android:layout_height="35dip"></EditText>
|
||||
android:gravity="center"
|
||||
android:paddingLeft="10dip"
|
||||
android:paddingRight="10dip">
|
||||
<TableRow>
|
||||
<TextView android:gravity="left" android:layout_height="wrap_content" android:layout_width="wrap_content" android:textSize="15sp" android:id="@+id/localportlabel" android:text="@string/local_port"></TextView>
|
||||
<EditText android:layout_width="70dip" android:text="@string/empty" android:id="@+id/localport" android:inputType="number" android:digits="0123456789" android:layout_height="35dip"></EditText>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/remote_host" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15sp" android:id="@+id/remotehostlabel"></TextView>
|
||||
<EditText android:layout_width="wrap_content" android:id="@+id/remotehost" android:text="@string/empty" android:layout_height="35dip"></EditText>
|
||||
<TableRow android:id="@+id/tableRow3" android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<TextView android:text="@string/remote_port" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15sp" android:id="@+id/remoteportlabel"></TextView>
|
||||
<EditText android:text="@string/empty" android:layout_width="70dip" android:id="@+id/remoteport" android:digits="0123456789" android:layout_height="35dip"></EditText>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/remote_port" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15sp" android:id="@+id/remoteportlabel"></TextView>
|
||||
<EditText android:text="@string/empty" android:layout_width="70dip" android:id="@+id/remoteport" android:inputType="number" android:digits="0123456789" android:layout_height="35dip"></EditText>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/cert_file" android:gravity="center" android:layout_width="wrap_content" android:layout_height="wrap_content" android:textSize="15sp" android:id="@+id/certfilelabel"></TextView>
|
||||
<EditText android:text="@string/empty" android:layout_width="wrap_content" android:layout_height="35dip" android:id="@+id/pkcsfile"></EditText>
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:layout_width="wrap_content" android:id="@+id/pkcspasslabel" android:layout_height="wrap_content" android:text="@string/pkcspass"></TextView>
|
||||
<EditText android:layout_width="wrap_content" android:text="@string/empty" android:password="true" android:layout_height="35dip" android:id="@+id/pkcspass"></EditText>
|
||||
<Button android:id="@+id/buttonApply" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/apply"></Button>
|
||||
<TextView
|
||||
android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:gravity="center" android:textSize="20sp" android:padding="20dp" android:text="@string/service_control" android:id="@+id/servicecontrollabel"/>
|
||||
<TableRow android:id="@+id/tableRow2" android:layout_width="wrap_content" android:layout_height="wrap_content">
|
||||
<Button android:id="@+id/buttonStart" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Start"></Button>
|
||||
<Button android:id="@+id/buttonStop" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="Stop"></Button>
|
||||
</TableRow>
|
||||
<Button android:id="@+id/buttonApply" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/apply"></Button>
|
||||
</TableLayout>
|
68
res/layout/tunnel_details.xml
Normal file
68
res/layout/tunnel_details.xml
Normal file
@ -0,0 +1,68 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<ScrollView xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="fill_parent" android:layout_width="fill_parent"
|
||||
android:scrollbars="vertical">
|
||||
<TableLayout android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:paddingLeft="10dip"
|
||||
android:paddingRight="10dip">
|
||||
<TableRow>
|
||||
<TextView android:text="@string/connection_name"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/name" android:hint="Internal Webserver"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:singleLine="true" android:layout_weight="1" />
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/local_port"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/localport" android:hint="8080"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:inputType="number" />
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/remote_host"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/remotehost" android:hint="example.com"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:inputType="textEmailAddress" />
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/remote_port"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/remoteport" android:hint="443"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:inputType="number" />
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/cert_file"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/pkcsfile" android:hint="client.p12"
|
||||
android:layout_width="fill_parent" android:layout_height="wrap_content"
|
||||
android:layout_weight="1" android:inputType="textEmailAddress" />
|
||||
<Button android:text="..." android:layout_width="wrap_content" android:id="@+id/pickFile" android:layout_height="wrap_content"></Button>
|
||||
|
||||
</TableRow>
|
||||
<TableRow>
|
||||
<TextView android:text="@string/pkcspass"
|
||||
android:paddingRight="10dip" android:gravity="right|center_vertical"
|
||||
android:textAppearance="?android:attr/textAppearanceMedium" />
|
||||
|
||||
<EditText android:id="@+id/pkcspass" android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:layout_weight="1"
|
||||
android:password="true" android:hint="Not mandatory" />
|
||||
</TableRow>
|
||||
<TableRow android:gravity="center">
|
||||
<Button android:layout_width="fill_parent" android:layout_height="fill_parent" android:gravity="center" android:textAppearance="?android:attr/textAppearanceMedium" android:text="@string/apply" android:id="@+id/tunnel_apply_button"></Button>
|
||||
</TableRow>
|
||||
</TableLayout>
|
||||
</ScrollView>
|
9
res/layout/tunnel_list.xml
Normal file
9
res/layout/tunnel_list.xml
Normal file
@ -0,0 +1,9 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:orientation="vertical" android:layout_width="fill_parent"
|
||||
android:layout_height="fill_parent">
|
||||
<ListView android:id="@android:id/list" android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" ></ListView>
|
||||
<TextView android:id="@android:id/empty" android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge" android:text="@string/no_tunnels"/>
|
||||
</LinearLayout>
|
14
res/layout/tunnel_list_item.xml
Normal file
14
res/layout/tunnel_list_item.xml
Normal file
@ -0,0 +1,14 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
|
||||
android:layout_height="wrap_content" android:orientation="vertical"
|
||||
android:gravity="left|center_vertical" android:layout_width="fill_parent"
|
||||
android:padding="10dip">
|
||||
<TextView android:layout_width="fill_parent"
|
||||
android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceLarge"
|
||||
android:text="Tunnel Nickname" android:layout_alignParentTop="true"
|
||||
android:layout_alignParentLeft="true" android:id="@+id/text1"/>
|
||||
<!-- <TextView android:layout_width="wrap_content"
|
||||
android:layout_height="wrap_content" android:textAppearance="?android:attr/textAppearanceSmall"
|
||||
android:text="Local port 8080 to 192.168.1.1:80" android:layout_below="@+id/text1" android:id="@+id/text2"/> -->
|
||||
</RelativeLayout>
|
||||
|
7
res/menu/main.xml
Normal file
7
res/menu/main.xml
Normal file
@ -0,0 +1,7 @@
|
||||
<?xml version="1.0" encoding="utf-8"?>
|
||||
<menu
|
||||
xmlns:android="http://schemas.android.com/apk/res/android">
|
||||
<item android:enabled="true" android:title="@string/add_tunnel" android:id="@+id/addtunnel" android:icon="@android:drawable/ic_menu_add"></item>
|
||||
|
||||
<item android:enabled="true" android:id="@+id/startservice" android:title="@string/start_service" android:icon="@android:drawable/ic_menu_manage"></item><item android:title="@string/stop_service" android:enabled="true" android:id="@+id/stopservice" android:icon="@android:drawable/ic_menu_close_clear_cancel"></item>
|
||||
</menu>
|
@ -3,11 +3,17 @@
|
||||
<string name="hello">Hello World, SSLDroidGui!</string>
|
||||
<string name="app_name">SSLDroid</string>
|
||||
<string name="service_control">Service Control</string>
|
||||
<string name="local_port">Local port to listen on</string>
|
||||
<string name="remote_host">Remote host to connect to</string>
|
||||
<string name="remote_port">Remote port to connect to</string>
|
||||
<string name="cert_file">PKCS12 file to use for auth</string>
|
||||
<string name="local_port">Local port</string>
|
||||
<string name="remote_host">Remote host</string>
|
||||
<string name="remote_port">Remote port</string>
|
||||
<string name="cert_file">PKCS12 file</string>
|
||||
<string name="empty"></string>
|
||||
<string name="apply">Apply</string>
|
||||
<string name="pkcspass">PKCS12 password</string>
|
||||
<string name="pkcspass">PKCS12 pass</string>
|
||||
<string name="connection_name">Tunnel name</string>
|
||||
<string name="add_tunnel">Add tunnel</string>
|
||||
<string name="stop_service">Stop service</string>
|
||||
<string name="start_service">Start service</string>
|
||||
<string name="no_tunnels">No tunnels configured yet</string>
|
||||
<string name="menu_delete">Delete tunnel</string>
|
||||
</resources>
|
||||
|
@ -3,77 +3,61 @@ package hu.blint.ssldroid;
|
||||
import hu.blint.ssldroid.TcpProxy;
|
||||
import android.app.*;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.IBinder;
|
||||
import android.util.Log;
|
||||
import android.widget.Toast;
|
||||
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
|
||||
|
||||
public class SSLDroid extends Service {
|
||||
|
||||
final String TAG = "SSLDroid";
|
||||
public static final String PREFS_NAME = "MyPrefsFile";
|
||||
public static final String PREFS_NAME = "SSLDroid";
|
||||
TcpProxy tp[];
|
||||
private SSLDroidDbAdapter dbHelper;
|
||||
|
||||
@Override
|
||||
public void onCreate() {
|
||||
|
||||
// Restore preferences
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
int settingLocalport = settings.getInt("0.localPort", 0);
|
||||
String settingRemotehost = settings.getString("0.remoteHost", "");
|
||||
int settingRemoteport = settings.getInt("0.remotePort", 0);
|
||||
String settingPkcsfile = settings.getString("0.pkcsFile", "");
|
||||
String settingPkcspass = settings.getString("0.pkcsPass", "");
|
||||
dbHelper = new SSLDroidDbAdapter(this);
|
||||
dbHelper.open();
|
||||
Cursor cursor = dbHelper.fetchAllTunnels();
|
||||
|
||||
int listenPort;
|
||||
int targetPort;
|
||||
String targetHost;
|
||||
String keyFile;
|
||||
String keyPass;
|
||||
int tunnelcount = cursor.getCount();
|
||||
|
||||
if (settingLocalport!=0)
|
||||
listenPort = settingLocalport;
|
||||
else {
|
||||
Toast.makeText(this, "Please set up local port first", Toast.LENGTH_LONG).show();
|
||||
//skip start if the db is empty yet
|
||||
if (tunnelcount == 0)
|
||||
return;
|
||||
}
|
||||
if (settingRemotehost!="")
|
||||
targetHost = settingRemotehost;
|
||||
else {
|
||||
Toast.makeText(this, "Please set up remote host first", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
if (settingRemoteport!=0)
|
||||
targetPort = settingRemoteport;
|
||||
else {
|
||||
Toast.makeText(this, "Please set up remote port first", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
if (settingPkcsfile!="")
|
||||
keyFile = settingPkcsfile;
|
||||
else {
|
||||
Toast.makeText(this, "Please set up PKCS12 file first", Toast.LENGTH_LONG).show();
|
||||
return;
|
||||
}
|
||||
keyPass = settingPkcspass;
|
||||
|
||||
//Toast.makeText(this, "SSLDroid Service Started", Toast.LENGTH_LONG).show();
|
||||
createNotification(0, true, "SSLDroid is running", listenPort+"->"+targetHost+":"+targetPort);
|
||||
Log.d(TAG, "SSLDroid Service Started");
|
||||
tp = new TcpProxy[tunnelcount];
|
||||
|
||||
//createNotification("test", "This is a test of the emergency broadcast system");
|
||||
|
||||
tp = new TcpProxy[2];
|
||||
int i;
|
||||
for (i=0; i<tunnelcount; i++){
|
||||
cursor.moveToPosition(i);
|
||||
int listenPort = cursor.getInt(cursor
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT));
|
||||
int targetPort = cursor.getInt(cursor
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEPORT));
|
||||
String targetHost = cursor.getString(cursor
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEHOST));
|
||||
String keyFile = cursor.getString(cursor
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSFILE));
|
||||
String keyPass = cursor.getString(cursor
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS));
|
||||
try {
|
||||
tp[0] = new TcpProxy();
|
||||
tp[0].serve(listenPort, targetHost, targetPort, keyFile, keyPass);
|
||||
tp[1] = new TcpProxy();
|
||||
tp[1].serve(9998, "imaps.balabit.hu", 993, keyFile, keyPass);
|
||||
tp[i] = new TcpProxy();
|
||||
tp[i].serve(listenPort, targetHost, targetPort, keyFile, keyPass);
|
||||
Log.d(TAG, "Tunnel: "+listenPort+" "+targetHost+" "+targetPort+" "+keyFile);
|
||||
} catch (Exception e) {
|
||||
Log.d(TAG, "Error:" + e.toString());
|
||||
}
|
||||
}
|
||||
|
||||
cursor.deactivate();
|
||||
dbHelper.close();
|
||||
createNotification(0, true, "SSLDroid is running", "Started and serving "+tunnelcount+" tunnels");
|
||||
Log.d(TAG, "SSLDroid Service Started");
|
||||
}
|
||||
|
||||
@Override
|
||||
public int onStartCommand(Intent intent, int flags, int startId) {
|
||||
return START_STICKY;
|
||||
@ -106,9 +90,12 @@ public class SSLDroid extends Service {
|
||||
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
|
||||
Notification notification = new Notification(R.drawable.icon,
|
||||
"SSLDroid startup", System.currentTimeMillis());
|
||||
// Hide the notification after its selected
|
||||
// if requested, make the notification persistent, e.g. not clearable by the user at all,
|
||||
// automatically hide on displaying the main activity otherwise
|
||||
if (persistent == true)
|
||||
notification.flags |= Notification.FLAG_NO_CLEAR;
|
||||
else
|
||||
notification.flags |= Notification.FLAG_AUTO_CANCEL;
|
||||
|
||||
Intent intent = new Intent(this, SSLDroidGui.class);
|
||||
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
|
||||
|
@ -1,124 +1,143 @@
|
||||
package hu.blint.ssldroid;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.app.ListActivity;
|
||||
import android.content.Intent;
|
||||
import android.content.SharedPreferences;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.ContextMenu;
|
||||
import android.view.ContextMenu.ContextMenuInfo;
|
||||
import android.view.Menu;
|
||||
import android.view.MenuInflater;
|
||||
import android.view.MenuItem;
|
||||
import android.view.View;
|
||||
import android.view.View.OnClickListener;
|
||||
import android.widget.Button;
|
||||
import android.widget.TextView;
|
||||
import android.widget.Toast;
|
||||
import android.widget.AdapterView.AdapterContextMenuInfo;
|
||||
import android.widget.ListView;
|
||||
import android.widget.SimpleCursorAdapter;
|
||||
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
|
||||
|
||||
public class SSLDroidGui extends Activity implements OnClickListener {
|
||||
private static final String TAG = "SSLDroidGui";
|
||||
public static final String PREFS_NAME = "MyPrefsFile";
|
||||
Button buttonStart, buttonStop, buttonApply;
|
||||
|
||||
public boolean saveSettings(){
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
SharedPreferences.Editor editor = settings.edit();
|
||||
|
||||
TextView localport = (TextView) findViewById(R.id.localport);
|
||||
TextView remotehost = (TextView) findViewById(R.id.remotehost);
|
||||
TextView remoteport = (TextView) findViewById(R.id.remoteport);
|
||||
TextView pkcsfile = (TextView) findViewById(R.id.pkcsfile);
|
||||
TextView pkcspass = (TextView) findViewById(R.id.pkcspass);
|
||||
|
||||
String settingLocalport = localport.getText().toString();
|
||||
String settingRemotehost = remotehost.getText().toString();
|
||||
String settingRemoteport = remoteport.getText().toString();
|
||||
String settingPkcsfile = pkcsfile.getText().toString();
|
||||
String settingPkcspass = pkcspass.getText().toString();
|
||||
|
||||
if (settingLocalport.length() == 0) {
|
||||
Toast.makeText(this, "Required local port parameter not setup, skipping save", 5).show();
|
||||
return false;
|
||||
}
|
||||
if (settingRemotehost.length() == 0){
|
||||
Toast.makeText(this, "Required remote host parameter not setup, skipping save", 5).show();
|
||||
return false;
|
||||
}
|
||||
if (settingRemoteport.length() == 0){
|
||||
Toast.makeText(this, "Required remote port parameter not setup, skipping save", 5).show();
|
||||
return false;
|
||||
}
|
||||
if (settingPkcsfile.length() == 0){
|
||||
Toast.makeText(this, "Required PKCS12 file parameter not setup, skipping save", 5).show();
|
||||
return false;
|
||||
}
|
||||
editor.putInt("0.localPort", Integer.parseInt(settingLocalport));
|
||||
//Log.d(TAG, "settingSave: '"+ settingLocalport+"'");
|
||||
editor.putString("0.remoteHost", settingRemotehost);
|
||||
//Log.d(TAG, "settingSave: '"+ settingRemotehost+"'");
|
||||
editor.putInt("0.remotePort", Integer.parseInt(settingRemoteport));
|
||||
//Log.d(TAG, "settingSave: '"+ settingRemoteport+"'");
|
||||
editor.putString("0.pkcsFile", settingPkcsfile);
|
||||
//Log.d(TAG, "settingSave: '"+ settingPkcsfile+"'");
|
||||
editor.putString("0.pkcsPass", settingPkcspass);
|
||||
//Log.d(TAG, "settingSave: '"+ settingPkcspass+"'");
|
||||
editor.commit();
|
||||
return true;
|
||||
}
|
||||
public class SSLDroidGui extends ListActivity {
|
||||
private SSLDroidDbAdapter dbHelper;
|
||||
private static final int ACTIVITY_CREATE = 0;
|
||||
private static final int ACTIVITY_EDIT = 1;
|
||||
private static final int DELETE_ID = Menu.FIRST + 1;
|
||||
private Cursor cursor;
|
||||
|
||||
/** Called when the activity is first created. */
|
||||
@Override
|
||||
public void onCreate(Bundle savedInstanceState) {
|
||||
super.onCreate(savedInstanceState);
|
||||
setContentView(R.layout.main);
|
||||
|
||||
buttonStart = (Button) findViewById(R.id.buttonStart);
|
||||
buttonStop = (Button) findViewById(R.id.buttonStop);
|
||||
buttonApply = (Button) findViewById(R.id.buttonApply);
|
||||
|
||||
buttonStart.setOnClickListener(this);
|
||||
buttonStop.setOnClickListener(this);
|
||||
buttonApply.setOnClickListener(this);
|
||||
|
||||
TextView localport = (TextView) findViewById(R.id.localport);
|
||||
TextView remotehost = (TextView) findViewById(R.id.remotehost);
|
||||
TextView remoteport = (TextView) findViewById(R.id.remoteport);
|
||||
TextView pkcsfile = (TextView) findViewById(R.id.pkcsfile);
|
||||
TextView pkcspass = (TextView) findViewById(R.id.pkcspass);
|
||||
|
||||
// Restore preferences
|
||||
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0);
|
||||
int settingLocalport = settings.getInt("0.localPort", 0);
|
||||
String settingRemotehost = settings.getString("0.remoteHost", "");
|
||||
int settingRemoteport = settings.getInt("0.remotePort", 0);
|
||||
String settingPkcsfile = settings.getString("0.pkcsFile", "");
|
||||
String settingPkcspass = settings.getString("0.pkcsPass", "");
|
||||
|
||||
if (settingLocalport!=0)
|
||||
localport.setText(String.valueOf(settingLocalport));
|
||||
if (settingRemotehost!="")
|
||||
remotehost.setText(settingRemotehost);
|
||||
if (settingRemoteport!=0)
|
||||
remoteport.setText(String.valueOf(settingRemoteport));
|
||||
if (settingPkcsfile!="")
|
||||
pkcsfile.setText(settingPkcsfile);
|
||||
if (settingPkcspass!="")
|
||||
pkcspass.setText(settingPkcspass);
|
||||
setContentView(R.layout.tunnel_list);
|
||||
this.getListView().setDividerHeight(2);
|
||||
dbHelper = new SSLDroidDbAdapter(this);
|
||||
dbHelper.open();
|
||||
fillData();
|
||||
registerForContextMenu(getListView());
|
||||
}
|
||||
|
||||
public void onClick(View src) {
|
||||
switch (src.getId()) {
|
||||
case R.id.buttonStart:
|
||||
Log.d(TAG, "Starting service");
|
||||
startService(new Intent(this, SSLDroid.class));
|
||||
break;
|
||||
case R.id.buttonStop:
|
||||
Log.d(TAG, "Stopping service");
|
||||
stopService(new Intent(this, SSLDroid.class));
|
||||
break;
|
||||
case R.id.buttonApply:
|
||||
Log.d(TAG, "Saving settings...");
|
||||
if (saveSettings()){
|
||||
Log.d(TAG, "Restarting service after setting save");
|
||||
// Create the menu based on the XML defintion
|
||||
@Override
|
||||
public boolean onCreateOptionsMenu(Menu menu) {
|
||||
MenuInflater inflater = getMenuInflater();
|
||||
inflater.inflate(R.menu.main, menu);
|
||||
return true;
|
||||
}
|
||||
|
||||
// Reaction to the menu selection
|
||||
@Override
|
||||
public boolean onMenuItemSelected(int featureId, MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.addtunnel:
|
||||
createTunnel();
|
||||
return true;
|
||||
case R.id.stopservice:
|
||||
Log.d("SSLDroid", "Stopping service");
|
||||
stopService(new Intent(this, SSLDroid.class));
|
||||
return true;
|
||||
case R.id.startservice:
|
||||
Log.d("SSLDroid", "Starting service");
|
||||
startService(new Intent(this, SSLDroid.class));
|
||||
return true;
|
||||
}
|
||||
break;
|
||||
}
|
||||
return super.onMenuItemSelected(featureId, item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onOptionsItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case R.id.addtunnel:
|
||||
createTunnel();
|
||||
return true;
|
||||
case R.id.stopservice:
|
||||
Log.d("SSLDroid", "Stopping service");
|
||||
stopService(new Intent(this, SSLDroid.class));
|
||||
return true;
|
||||
case R.id.startservice:
|
||||
Log.d("SSLDroid", "Starting service");
|
||||
startService(new Intent(this, SSLDroid.class));
|
||||
return true;
|
||||
}
|
||||
return super.onOptionsItemSelected(item);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean onContextItemSelected(MenuItem item) {
|
||||
switch (item.getItemId()) {
|
||||
case DELETE_ID:
|
||||
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
|
||||
.getMenuInfo();
|
||||
dbHelper.deleteTunnel(info.id);
|
||||
fillData();
|
||||
return true;
|
||||
}
|
||||
return super.onContextItemSelected(item);
|
||||
}
|
||||
|
||||
private void createTunnel() {
|
||||
Intent i = new Intent(this, SSLDroidTunnelDetails.class);
|
||||
startActivityForResult(i, ACTIVITY_CREATE);
|
||||
}
|
||||
|
||||
// ListView and view (row) on which was clicked, position and
|
||||
@Override
|
||||
protected void onListItemClick(ListView l, View v, int position, long id) {
|
||||
super.onListItemClick(l, v, position, id);
|
||||
Intent i = new Intent(this, SSLDroidTunnelDetails.class);
|
||||
i.putExtra(SSLDroidDbAdapter.KEY_ROWID, id);
|
||||
// Activity returns an result if called with startActivityForResult
|
||||
|
||||
startActivityForResult(i, ACTIVITY_EDIT);
|
||||
}
|
||||
|
||||
// Called with the result of the other activity
|
||||
// requestCode was the origin request code send to the activity
|
||||
// resultCode is the return code, 0 is everything is ok
|
||||
// intend can be use to get some data from the caller
|
||||
@Override
|
||||
protected void onActivityResult(int requestCode, int resultCode,
|
||||
Intent intent) {
|
||||
super.onActivityResult(requestCode, resultCode, intent);
|
||||
fillData();
|
||||
|
||||
}
|
||||
|
||||
private void fillData() {
|
||||
cursor = dbHelper.fetchAllTunnels();
|
||||
startManagingCursor(cursor);
|
||||
|
||||
String[] from = new String[] { SSLDroidDbAdapter.KEY_NAME };
|
||||
int[] to = new int[] { R.id.text1 };
|
||||
|
||||
// Now create an array adapter and set it to display using our row
|
||||
SimpleCursorAdapter tunnels = new SimpleCursorAdapter(this,
|
||||
R.layout.tunnel_list_item, cursor, from, to);
|
||||
setListAdapter(tunnels);
|
||||
}
|
||||
|
||||
@Override
|
||||
public void onCreateContextMenu(ContextMenu menu, View v,
|
||||
ContextMenuInfo menuInfo) {
|
||||
super.onCreateContextMenu(menu, v, menuInfo);
|
||||
menu.add(0, DELETE_ID, 0, R.string.menu_delete);
|
||||
}
|
||||
}
|
166
src/hu/blint/ssldroid/SSLDroidTunnelDetails.java
Normal file
166
src/hu/blint/ssldroid/SSLDroidTunnelDetails.java
Normal file
@ -0,0 +1,166 @@
|
||||
package hu.blint.ssldroid;
|
||||
|
||||
import android.app.Activity;
|
||||
import android.content.Intent;
|
||||
import android.database.Cursor;
|
||||
import android.os.Bundle;
|
||||
import android.util.Log;
|
||||
import android.view.View;
|
||||
import android.widget.Button;
|
||||
import android.widget.EditText;
|
||||
import android.widget.Toast;
|
||||
import hu.blint.ssldroid.db.SSLDroidDbAdapter;
|
||||
|
||||
public class SSLDroidTunnelDetails extends Activity {
|
||||
private EditText name;
|
||||
private EditText localport;
|
||||
private EditText remotehost;
|
||||
private EditText remoteport;
|
||||
private EditText pkcsfile;
|
||||
private EditText pkcspass;
|
||||
private Long rowId;
|
||||
private SSLDroidDbAdapter dbHelper;
|
||||
|
||||
@Override
|
||||
protected void onCreate(Bundle bundle) {
|
||||
super.onCreate(bundle);
|
||||
dbHelper = new SSLDroidDbAdapter(this);
|
||||
dbHelper.open();
|
||||
setContentView(R.layout.tunnel_details);
|
||||
|
||||
Button confirmButton = (Button) findViewById(R.id.tunnel_apply_button);
|
||||
name = (EditText) findViewById(R.id.name);
|
||||
localport = (EditText) findViewById(R.id.localport);
|
||||
remotehost = (EditText) findViewById(R.id.remotehost);
|
||||
remoteport = (EditText) findViewById(R.id.remoteport);
|
||||
pkcsfile = (EditText) findViewById(R.id.pkcsfile);
|
||||
pkcspass = (EditText) findViewById(R.id.pkcspass);
|
||||
|
||||
rowId = null;
|
||||
Bundle extras = getIntent().getExtras();
|
||||
rowId = (bundle == null) ? null : (Long) bundle
|
||||
.getSerializable(SSLDroidDbAdapter.KEY_ROWID);
|
||||
if (extras != null) {
|
||||
rowId = extras.getLong(SSLDroidDbAdapter.KEY_ROWID);
|
||||
}
|
||||
populateFields();
|
||||
confirmButton.setOnClickListener(new View.OnClickListener() {
|
||||
public void onClick(View view) {
|
||||
//TODO: put input validation here
|
||||
//TODO: put local port collision check here
|
||||
if (name.getText().length() == 0) {
|
||||
Toast.makeText(getBaseContext(), "Required tunnel name parameter not setup, skipping save", 5).show();
|
||||
return;
|
||||
}
|
||||
if (localport.getText().length() == 0) {
|
||||
Toast.makeText(getBaseContext(), "Required local port parameter not setup, skipping save", 5).show();
|
||||
return;
|
||||
}
|
||||
if (remotehost.getText().length() == 0){
|
||||
Toast.makeText(getBaseContext(), "Required remote host parameter not setup, skipping save", 5).show();
|
||||
return;
|
||||
}
|
||||
if (remoteport.getText().length() == 0){
|
||||
Toast.makeText(getBaseContext(), "Required remote port parameter not setup, skipping save", 5).show();
|
||||
return;
|
||||
}
|
||||
if (pkcsfile.getText().length() == 0){
|
||||
Toast.makeText(getBaseContext(), "Required PKCS12 file parameter not setup, skipping save", 5).show();
|
||||
return;
|
||||
}
|
||||
setResult(RESULT_OK);
|
||||
finish();
|
||||
}
|
||||
|
||||
});
|
||||
}
|
||||
|
||||
private void populateFields() {
|
||||
if (rowId != null) {
|
||||
Cursor Tunnel = dbHelper.fetchTunnel(rowId);
|
||||
startManagingCursor(Tunnel);
|
||||
|
||||
name.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME)));
|
||||
localport.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT)));
|
||||
remotehost.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEHOST)));
|
||||
remoteport.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEPORT)));
|
||||
pkcsfile.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSFILE)));
|
||||
pkcspass.setText(Tunnel.getString(Tunnel
|
||||
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS)));
|
||||
}
|
||||
}
|
||||
|
||||
protected void onSaveInstanceState(Bundle outState) {
|
||||
super.onSaveInstanceState(outState);
|
||||
saveState();
|
||||
outState.putSerializable(SSLDroidDbAdapter.KEY_ROWID, rowId);
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onPause() {
|
||||
super.onPause();
|
||||
saveState();
|
||||
}
|
||||
|
||||
@Override
|
||||
protected void onResume() {
|
||||
super.onResume();
|
||||
populateFields();
|
||||
}
|
||||
|
||||
private void saveState() {
|
||||
String sName = name.getText().toString();
|
||||
int sLocalport = 0;
|
||||
try{
|
||||
sLocalport = Integer.parseInt(localport.getText().toString());
|
||||
} catch (NumberFormatException e){
|
||||
}
|
||||
String sRemotehost = remotehost.getText().toString();
|
||||
int sRemoteport = 0;
|
||||
try{
|
||||
sRemoteport = Integer.parseInt(remoteport.getText().toString());
|
||||
} catch (NumberFormatException e){
|
||||
}
|
||||
String sPkcsfile = pkcsfile.getText().toString();
|
||||
String sPkcspass = pkcspass.getText().toString();
|
||||
|
||||
//make sure that we have all of our values correctly set
|
||||
if (sName.length() == 0) {
|
||||
return;
|
||||
}
|
||||
if (sLocalport == 0) {
|
||||
return;
|
||||
}
|
||||
if (sRemotehost.length() == 0) {
|
||||
return;
|
||||
}
|
||||
if (sRemoteport == 0) {
|
||||
return;
|
||||
}
|
||||
if (sPkcsfile.length() == 0) {
|
||||
return;
|
||||
}
|
||||
|
||||
if (rowId == null) {
|
||||
long id = dbHelper.createTunnel(sName, sLocalport, sRemotehost, sRemoteport, sPkcsfile, sPkcspass);
|
||||
if (id > 0) {
|
||||
rowId = id;
|
||||
}
|
||||
} else {
|
||||
dbHelper.updateTunnel(rowId, sName, sLocalport, sRemotehost, sRemoteport, sPkcsfile, sPkcspass);
|
||||
}
|
||||
Log.d("SSLDroid", "Saving settings...");
|
||||
|
||||
//restart the service
|
||||
stopService(new Intent(this, SSLDroid.class));
|
||||
startService(new Intent(this, SSLDroid.class));
|
||||
Log.d("SSLDroid", "Restarting service after settings save...");
|
||||
|
||||
}
|
||||
}
|
||||
|
@ -68,5 +68,8 @@ public class TcpProxy {
|
||||
Log.d("SSLDroid", "Stopping service");
|
||||
}
|
||||
|
||||
public boolean isAlive(){
|
||||
return ss.isBound();
|
||||
}
|
||||
|
||||
}
|
||||
|
109
src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java
Normal file
109
src/hu/blint/ssldroid/db/SSLDroidDbAdapter.java
Normal file
@ -0,0 +1,109 @@
|
||||
package hu.blint.ssldroid.db;
|
||||
|
||||
import android.content.ContentValues;
|
||||
import android.content.Context;
|
||||
import android.database.Cursor;
|
||||
import android.database.SQLException;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
|
||||
public class SSLDroidDbAdapter {
|
||||
|
||||
// Database fields
|
||||
public static final String KEY_ROWID = "_id";
|
||||
public static final String KEY_NAME = "name";
|
||||
public static final String KEY_LOCALPORT = "localport";
|
||||
public static final String KEY_REMOTEHOST = "remotehost";
|
||||
public static final String KEY_REMOTEPORT = "remoteport";
|
||||
public static final String KEY_PKCSFILE = "pkcsfile";
|
||||
public static final String KEY_PKCSPASS = "pkcspass";
|
||||
private static final String DATABASE_TABLE = "tunnels";
|
||||
private Context context;
|
||||
private SQLiteDatabase database;
|
||||
private SSLDroidDbHelper dbHelper;
|
||||
|
||||
public SSLDroidDbAdapter(Context context) {
|
||||
this.context = context;
|
||||
}
|
||||
|
||||
public SSLDroidDbAdapter open() throws SQLException {
|
||||
dbHelper = new SSLDroidDbHelper(context);
|
||||
database = dbHelper.getWritableDatabase();
|
||||
return this;
|
||||
}
|
||||
|
||||
public void close() {
|
||||
dbHelper.close();
|
||||
database.close();
|
||||
}
|
||||
|
||||
/**
|
||||
* Create a new tunnel If the tunnel is successfully created return the new
|
||||
* rowId for that note, otherwise return a -1 to indicate failure.
|
||||
*/
|
||||
public long createTunnel(String name, int localport, String remotehost, int remoteport,
|
||||
String pkcsfile, String pkcspass) {
|
||||
ContentValues initialValues = createContentValues(name, localport, remotehost,
|
||||
remoteport, pkcsfile, pkcspass);
|
||||
|
||||
return database.insert(DATABASE_TABLE, null, initialValues);
|
||||
}
|
||||
|
||||
/**
|
||||
* Update the tunnel
|
||||
*/
|
||||
public boolean updateTunnel(long rowId, String name, int localport, String remotehost,
|
||||
int remoteport, String pkcsfile, String pkcspass) {
|
||||
ContentValues updateValues = createContentValues(name, localport, remotehost,
|
||||
remoteport, pkcsfile, pkcspass);
|
||||
|
||||
return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "="
|
||||
+ rowId, null) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Deletes tunnel
|
||||
*/
|
||||
public boolean deleteTunnel(long rowId) {
|
||||
return database.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Cursor over the list of all tunnel in the database
|
||||
*
|
||||
* @return Cursor over all notes
|
||||
*/
|
||||
public Cursor fetchAllTunnels() {
|
||||
return database.query(DATABASE_TABLE, new String[] { KEY_ROWID,
|
||||
KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT, KEY_PKCSFILE,
|
||||
KEY_PKCSPASS }, null, null, null, null, null);
|
||||
}
|
||||
|
||||
/**
|
||||
* Return a Cursor positioned at the defined tunnel
|
||||
*/
|
||||
public Cursor fetchTunnel(long rowId) throws SQLException {
|
||||
Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] {
|
||||
KEY_ROWID, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT,
|
||||
KEY_PKCSFILE, KEY_PKCSPASS },
|
||||
KEY_ROWID + "=" + rowId, null, null, null, null, null);
|
||||
if (mCursor != null) {
|
||||
mCursor.moveToFirst();
|
||||
}
|
||||
return mCursor;
|
||||
}
|
||||
|
||||
private ContentValues createContentValues(String name, int localport, String remotehost, int remoteport,
|
||||
String pkcsfile, String pkcspass) {
|
||||
ContentValues values = new ContentValues();
|
||||
values.put(KEY_NAME, name);
|
||||
values.put(KEY_LOCALPORT, localport);
|
||||
values.put(KEY_REMOTEHOST, remotehost);
|
||||
values.put(KEY_REMOTEPORT, remoteport);
|
||||
values.put(KEY_REMOTEPORT, remoteport);
|
||||
values.put(KEY_PKCSFILE, pkcsfile);
|
||||
values.put(KEY_PKCSPASS, pkcspass);
|
||||
return values;
|
||||
}
|
||||
}
|
||||
|
||||
|
39
src/hu/blint/ssldroid/db/SSLDroidDbHelper.java
Normal file
39
src/hu/blint/ssldroid/db/SSLDroidDbHelper.java
Normal file
@ -0,0 +1,39 @@
|
||||
package hu.blint.ssldroid.db;
|
||||
|
||||
import android.content.Context;
|
||||
import android.database.sqlite.SQLiteDatabase;
|
||||
import android.database.sqlite.SQLiteOpenHelper;
|
||||
|
||||
public class SSLDroidDbHelper extends SQLiteOpenHelper {
|
||||
private static final String DATABASE_NAME = "applicationdata";
|
||||
|
||||
private static final int DATABASE_VERSION = 1;
|
||||
|
||||
// Database creation sql statement
|
||||
private static final String DATABASE_CREATE = "create table tunnels (_id integer primary key autoincrement, "
|
||||
+ "name text not null, localport integer not null, remotehost text not null, "
|
||||
+ "remoteport integer not null, pkcsfile text not null, pkcspass text );";
|
||||
|
||||
public SSLDroidDbHelper(Context context) {
|
||||
super(context, DATABASE_NAME, null, DATABASE_VERSION);
|
||||
}
|
||||
|
||||
// Method is called during creation of the database
|
||||
@Override
|
||||
public void onCreate(SQLiteDatabase database) {
|
||||
database.execSQL(DATABASE_CREATE);
|
||||
}
|
||||
|
||||
// Method is called during an update of the database, e.g. if you increase
|
||||
// the database version
|
||||
@Override
|
||||
public void onUpgrade(SQLiteDatabase database, int oldVersion,
|
||||
int newVersion) {
|
||||
/* Log.w(SSLDroidDbHelper.class.getName(),
|
||||
"Upgrading database from version " + oldVersion + " to "
|
||||
+ newVersion + ", which will destroy all old data");
|
||||
database.execSQL("DROP TABLE IF EXISTS todo");
|
||||
onCreate(database); */
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user