1
0
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:
Balint Kovacs 2011-04-20 18:10:34 +02:00
parent 4d724fb37d
commit 422b11fdef
16 changed files with 614 additions and 184 deletions

View File

@ -9,6 +9,8 @@
<category android:name="android.intent.category.LAUNCHER" /> <category android:name="android.intent.category.LAUNCHER" />
</intent-filter> </intent-filter>
</activity> </activity>
<activity android:name=".SSLDroidTunnelDetails"
android:windowSoftInputMode="stateVisible|adjustResize" />
<service android:enabled="true" android:name="SSLDroid"> <service android:enabled="true" android:name="SSLDroid">
<intent-filter> <intent-filter>
<action android:name="hu.blint.ssldroid.SSLDroid" /> <action android:name="hu.blint.ssldroid.SSLDroid" />

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@ -3,27 +3,28 @@
android:orientation="vertical" android:orientation="vertical"
android:layout_width="fill_parent" android:layout_width="fill_parent"
android:layout_height="fill_parent" android:layout_height="fill_parent"
android:gravity="center"> android:gravity="center"
<TableRow android:id="@+id/tableRow1" android:layout_width="wrap_content" android:layout_height="wrap_content"> android:paddingLeft="10dip"
<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> android:paddingRight="10dip">
<EditText android:layout_width="70dip" android:text="@string/empty" android:id="@+id/localport" android:digits="0123456789" android:layout_height="35dip"></EditText> <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>
<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> <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> <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>
<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> <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> <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> <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> <EditText android:layout_width="wrap_content" android:text="@string/empty" android:password="true" android:layout_height="35dip" android:id="@+id/pkcspass"></EditText>
</TableRow>
<Button android:id="@+id/buttonApply" android:layout_width="wrap_content" android:layout_height="wrap_content" android:text="@string/apply"></Button> <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>
</TableLayout> </TableLayout>

View 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>

View 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>

View 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
View 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>

View File

@ -3,11 +3,17 @@
<string name="hello">Hello World, SSLDroidGui!</string> <string name="hello">Hello World, SSLDroidGui!</string>
<string name="app_name">SSLDroid</string> <string name="app_name">SSLDroid</string>
<string name="service_control">Service Control</string> <string name="service_control">Service Control</string>
<string name="local_port">Local port to listen on</string> <string name="local_port">Local port</string>
<string name="remote_host">Remote host to connect to</string> <string name="remote_host">Remote host</string>
<string name="remote_port">Remote port to connect to</string> <string name="remote_port">Remote port</string>
<string name="cert_file">PKCS12 file to use for auth</string> <string name="cert_file">PKCS12 file</string>
<string name="empty"></string> <string name="empty"></string>
<string name="apply">Apply</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> </resources>

View File

@ -3,75 +3,59 @@ package hu.blint.ssldroid;
import hu.blint.ssldroid.TcpProxy; import hu.blint.ssldroid.TcpProxy;
import android.app.*; import android.app.*;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.database.Cursor;
import android.os.IBinder; import android.os.IBinder;
import android.util.Log; import android.util.Log;
import android.widget.Toast; import hu.blint.ssldroid.db.SSLDroidDbAdapter;
public class SSLDroid extends Service { public class SSLDroid extends Service {
final String TAG = "SSLDroid"; final String TAG = "SSLDroid";
public static final String PREFS_NAME = "MyPrefsFile"; public static final String PREFS_NAME = "SSLDroid";
TcpProxy tp[]; TcpProxy tp[];
private SSLDroidDbAdapter dbHelper;
@Override @Override
public void onCreate() { public void onCreate() {
// Restore preferences dbHelper = new SSLDroidDbAdapter(this);
SharedPreferences settings = getSharedPreferences(PREFS_NAME, 0); dbHelper.open();
int settingLocalport = settings.getInt("0.localPort", 0); Cursor cursor = dbHelper.fetchAllTunnels();
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", "");
int listenPort;
int targetPort;
String targetHost;
String keyFile;
String keyPass;
if (settingLocalport!=0)
listenPort = settingLocalport;
else {
Toast.makeText(this, "Please set up local port first", Toast.LENGTH_LONG).show();
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(); int tunnelcount = cursor.getCount();
createNotification(0, true, "SSLDroid is running", listenPort+"->"+targetHost+":"+targetPort);
Log.d(TAG, "SSLDroid Service Started"); //skip start if the db is empty yet
if (tunnelcount == 0)
//createNotification("test", "This is a test of the emergency broadcast system"); return;
tp = new TcpProxy[2]; tp = new TcpProxy[tunnelcount];
try {
tp[0] = new TcpProxy(); int i;
tp[0].serve(listenPort, targetHost, targetPort, keyFile, keyPass); for (i=0; i<tunnelcount; i++){
tp[1] = new TcpProxy(); cursor.moveToPosition(i);
tp[1].serve(9998, "imaps.balabit.hu", 993, keyFile, keyPass); int listenPort = cursor.getInt(cursor
} catch (Exception e) { .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT));
Log.d(TAG, "Error:" + e.toString()); 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[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 @Override
@ -106,9 +90,12 @@ public class SSLDroid extends Service {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon, Notification notification = new Notification(R.drawable.icon,
"SSLDroid startup", System.currentTimeMillis()); "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) if (persistent == true)
notification.flags |= Notification.FLAG_NO_CLEAR; notification.flags |= Notification.FLAG_NO_CLEAR;
else
notification.flags |= Notification.FLAG_AUTO_CANCEL;
Intent intent = new Intent(this, SSLDroidGui.class); Intent intent = new Intent(this, SSLDroidGui.class);
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0); PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);

View File

@ -1,124 +1,143 @@
package hu.blint.ssldroid; package hu.blint.ssldroid;
import android.app.Activity; import android.app.ListActivity;
import android.content.Intent; import android.content.Intent;
import android.content.SharedPreferences; import android.database.Cursor;
import android.os.Bundle; import android.os.Bundle;
import android.util.Log; 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;
import android.view.View.OnClickListener; import android.widget.AdapterView.AdapterContextMenuInfo;
import android.widget.Button; import android.widget.ListView;
import android.widget.TextView; import android.widget.SimpleCursorAdapter;
import android.widget.Toast; import hu.blint.ssldroid.db.SSLDroidDbAdapter;
public class SSLDroidGui extends Activity implements OnClickListener { public class SSLDroidGui extends ListActivity {
private static final String TAG = "SSLDroidGui"; private SSLDroidDbAdapter dbHelper;
public static final String PREFS_NAME = "MyPrefsFile"; private static final int ACTIVITY_CREATE = 0;
Button buttonStart, buttonStop, buttonApply; private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1;
private Cursor cursor;
public boolean saveSettings(){ /** Called when the activity is first created. */
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;
}
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.main); setContentView(R.layout.tunnel_list);
this.getListView().setDividerHeight(2);
buttonStart = (Button) findViewById(R.id.buttonStart); dbHelper = new SSLDroidDbAdapter(this);
buttonStop = (Button) findViewById(R.id.buttonStop); dbHelper.open();
buttonApply = (Button) findViewById(R.id.buttonApply); fillData();
registerForContextMenu(getListView());
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);
} }
public void onClick(View src) { // Create the menu based on the XML defintion
switch (src.getId()) { @Override
case R.id.buttonStart: public boolean onCreateOptionsMenu(Menu menu) {
Log.d(TAG, "Starting service"); MenuInflater inflater = getMenuInflater();
startService(new Intent(this, SSLDroid.class)); inflater.inflate(R.menu.main, menu);
break; return true;
case R.id.buttonStop: }
Log.d(TAG, "Stopping service");
// 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)); stopService(new Intent(this, SSLDroid.class));
break; return true;
case R.id.buttonApply: case R.id.startservice:
Log.d(TAG, "Saving settings..."); Log.d("SSLDroid", "Starting service");
if (saveSettings()){ startService(new Intent(this, SSLDroid.class));
Log.d(TAG, "Restarting service after setting save"); return true;
stopService(new Intent(this, SSLDroid.class));
startService(new Intent(this, SSLDroid.class));
}
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);
}
}

View 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...");
}
}

View File

@ -68,5 +68,8 @@ public class TcpProxy {
Log.d("SSLDroid", "Stopping service"); Log.d("SSLDroid", "Stopping service");
} }
public boolean isAlive(){
return ss.isBound();
}
} }

View 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;
}
}

View 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); */
}
}