1
0
mirror of https://github.com/moparisthebest/SSLDroid synced 2025-02-19 20:41:49 -05:00

Indentation fixes

Signed-off-by: Balint Kovacs <blint@blint.hu>
This commit is contained in:
Balint Kovacs 2011-05-04 21:31:26 +02:00
parent 69c521c91e
commit aad79a8e5a
10 changed files with 963 additions and 960 deletions

View File

@ -5,12 +5,12 @@ import android.content.Context;
import android.content.Intent; import android.content.Intent;
public class BootStartupReceiver extends BroadcastReceiver { public class BootStartupReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) { if (intent.getAction().equals(Intent.ACTION_BOOT_COMPLETED)) {
Intent i = new Intent(); Intent i = new Intent();
i.setAction("hu.blint.ssldroid.SSLDroid"); i.setAction("hu.blint.ssldroid.SSLDroid");
context.startService(i); context.startService(i);
} }
} }
} }

View File

@ -7,25 +7,25 @@ import android.net.ConnectivityManager;
import android.net.NetworkInfo; import android.net.NetworkInfo;
import android.util.Log; import android.util.Log;
public class NetworkChangeReceiver extends BroadcastReceiver{ public class NetworkChangeReceiver extends BroadcastReceiver {
@Override @Override
public void onReceive(Context context, Intent intent) { public void onReceive(Context context, Intent intent) {
ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE ); ConnectivityManager connectivityManager = (ConnectivityManager) context.getSystemService( Context.CONNECTIVITY_SERVICE );
NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo(); NetworkInfo activeNetInfo = connectivityManager.getActiveNetworkInfo();
if ( activeNetInfo == null ) { if ( activeNetInfo == null ) {
Intent i = new Intent(); Intent i = new Intent();
i.setAction("hu.blint.ssldroid.SSLDroid"); i.setAction("hu.blint.ssldroid.SSLDroid");
context.stopService(i); context.stopService(i);
return; return;
} }
Log.d("SSLDroid", activeNetInfo.toString()); Log.d("SSLDroid", activeNetInfo.toString());
if (activeNetInfo.isAvailable()) { if (activeNetInfo.isAvailable()) {
Intent i = new Intent(); Intent i = new Intent();
i.setAction("hu.blint.ssldroid.SSLDroid"); i.setAction("hu.blint.ssldroid.SSLDroid");
context.stopService(i); context.stopService(i);
context.startService(i); context.startService(i);
} }
} }
} }

View File

@ -10,107 +10,107 @@ import hu.blint.ssldroid.db.SSLDroidDbAdapter;
public class SSLDroid extends Service { public class SSLDroid extends Service {
final String TAG = "SSLDroid"; final String TAG = "SSLDroid";
TcpProxy tp[]; TcpProxy tp[];
private SSLDroidDbAdapter dbHelper; private SSLDroidDbAdapter dbHelper;
@Override @Override
public void onCreate() { public void onCreate() {
dbHelper = new SSLDroidDbAdapter(this); dbHelper = new SSLDroidDbAdapter(this);
dbHelper.open(); dbHelper.open();
Cursor cursor = dbHelper.fetchAllTunnels(); Cursor cursor = dbHelper.fetchAllTunnels();
int tunnelcount = cursor.getCount(); int tunnelcount = cursor.getCount();
//skip start if the db is empty yet //skip start if the db is empty yet
if (tunnelcount == 0) if (tunnelcount == 0)
return; return;
tp = new TcpProxy[tunnelcount]; tp = new TcpProxy[tunnelcount];
int i; int i;
for (i=0; i<tunnelcount; i++){ for (i=0; i<tunnelcount; i++) {
cursor.moveToPosition(i); cursor.moveToPosition(i);
String tunnelName = cursor.getString(cursor String tunnelName = cursor.getString(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME));
int listenPort = cursor.getInt(cursor int listenPort = cursor.getInt(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT));
int targetPort = cursor.getInt(cursor int targetPort = cursor.getInt(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEPORT)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEPORT));
String targetHost = cursor.getString(cursor String targetHost = cursor.getString(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEHOST)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_REMOTEHOST));
String keyFile = cursor.getString(cursor String keyFile = cursor.getString(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSFILE)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSFILE));
String keyPass = cursor.getString(cursor String keyPass = cursor.getString(cursor
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS)); .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_PKCSPASS));
try { try {
tp[i] = new TcpProxy(tunnelName, listenPort, targetHost, targetPort, keyFile, keyPass); tp[i] = new TcpProxy(tunnelName, listenPort, targetHost, targetPort, keyFile, keyPass);
tp[i].serve(); tp[i].serve();
Log.d(TAG, "Tunnel: "+tunnelName+" "+listenPort+" "+targetHost+" "+targetPort+" "+keyFile); Log.d(TAG, "Tunnel: "+tunnelName+" "+listenPort+" "+targetHost+" "+targetPort+" "+keyFile);
} catch (Exception e) { } catch (Exception e) {
Log.d(TAG, "Error:" + e.toString()); Log.d(TAG, "Error:" + e.toString());
new AlertDialog.Builder(SSLDroid.this) new AlertDialog.Builder(SSLDroid.this)
.setTitle("SSLDroid encountered a fatal error: "+e.getMessage()) .setTitle("SSLDroid encountered a fatal error: "+e.getMessage())
.setPositiveButton(android.R.string.ok, null) .setPositiveButton(android.R.string.ok, null)
.create(); .create();
} }
} }
cursor.deactivate();
cursor.close();
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;
}
@Override cursor.deactivate();
public IBinder onBind(Intent intent) { cursor.close();
return null; dbHelper.close();
} createNotification(0, true, "SSLDroid is running", "Started and serving "+tunnelcount+" tunnels");
Log.d(TAG, "SSLDroid Service Started");
}
@Override @Override
public void onDestroy() { public int onStartCommand(Intent intent, int flags, int startId) {
super.onDestroy(); return START_STICKY;
dbHelper.close(); }
try {
for (TcpProxy proxy : tp) {
proxy.stop();
}
} catch (Exception e) {
Log.d("SSLDroid", "Error stopping service: " + e.toString());
}
removeNotification(0);
Log.d(TAG, "SSLDroid Service Stopped");
}
public void removeNotification(int id){ @Override
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE); public IBinder onBind(Intent intent) {
notificationManager.cancel(id); return null;
} }
public void createNotification(int id, boolean persistent, String title, String text) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon,
"SSLDroid startup", System.currentTimeMillis());
// 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;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.tickerText = null;
Intent intent = new Intent(this, SSLDroidGui.class); @Override
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0); public void onDestroy() {
notification.setLatestEventInfo(this, title, text, activity); super.onDestroy();
notificationManager.notify(id, notification); dbHelper.close();
} try {
for (TcpProxy proxy : tp) {
proxy.stop();
}
} catch (Exception e) {
Log.d("SSLDroid", "Error stopping service: " + e.toString());
}
removeNotification(0);
Log.d(TAG, "SSLDroid Service Stopped");
}
public void removeNotification(int id) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
notificationManager.cancel(id);
}
public void createNotification(int id, boolean persistent, String title, String text) {
NotificationManager notificationManager = (NotificationManager) getSystemService(NOTIFICATION_SERVICE);
Notification notification = new Notification(R.drawable.icon,
"SSLDroid startup", System.currentTimeMillis());
// 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;
notification.flags |= Notification.FLAG_ONGOING_EVENT;
notification.tickerText = null;
Intent intent = new Intent(this, SSLDroidGui.class);
PendingIntent activity = PendingIntent.getActivity(this, 0, intent, 0);
notification.setLatestEventInfo(this, title, text, activity);
notificationManager.notify(id, notification);
}
} }

View File

@ -17,138 +17,138 @@ import android.widget.SimpleCursorAdapter;
import hu.blint.ssldroid.db.SSLDroidDbAdapter; import hu.blint.ssldroid.db.SSLDroidDbAdapter;
public class SSLDroidGui extends ListActivity { public class SSLDroidGui extends ListActivity {
private SSLDroidDbAdapter dbHelper; private SSLDroidDbAdapter dbHelper;
private static final int ACTIVITY_CREATE = 0; private static final int ACTIVITY_CREATE = 0;
private static final int ACTIVITY_EDIT = 1; private static final int ACTIVITY_EDIT = 1;
private static final int DELETE_ID = Menu.FIRST + 1; private static final int DELETE_ID = Menu.FIRST + 1;
private Cursor cursor; private Cursor cursor;
/** Called when the activity is first created. */ /** Called when the activity is first created. */
@Override @Override
public void onCreate(Bundle savedInstanceState) { public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState); super.onCreate(savedInstanceState);
setContentView(R.layout.tunnel_list); setContentView(R.layout.tunnel_list);
this.getListView().setDividerHeight(2); this.getListView().setDividerHeight(2);
dbHelper = new SSLDroidDbAdapter(this); dbHelper = new SSLDroidDbAdapter(this);
dbHelper.open(); dbHelper.open();
fillData(); fillData();
registerForContextMenu(getListView()); registerForContextMenu(getListView());
} }
// Create the menu based on the XML defintion // Create the menu based on the XML defintion
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuInflater inflater = getMenuInflater(); MenuInflater inflater = getMenuInflater();
inflater.inflate(R.menu.main, menu); inflater.inflate(R.menu.main, menu);
return true; return true;
} }
// Reaction to the menu selection // Reaction to the menu selection
@Override @Override
public boolean onMenuItemSelected(int featureId, MenuItem item) { public boolean onMenuItemSelected(int featureId, MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.addtunnel: case R.id.addtunnel:
createTunnel(); createTunnel();
return true; return true;
case R.id.stopservice: case R.id.stopservice:
Log.d("SSLDroid", "Stopping service"); Log.d("SSLDroid", "Stopping service");
stopService(new Intent(this, SSLDroid.class)); stopService(new Intent(this, SSLDroid.class));
return true; return true;
case R.id.startservice: case R.id.startservice:
Log.d("SSLDroid", "Starting service"); Log.d("SSLDroid", "Starting service");
startService(new Intent(this, SSLDroid.class)); startService(new Intent(this, SSLDroid.class));
return true; return true;
case R.id.readlogs: case R.id.readlogs:
readLogs(); readLogs();
return true; return true;
} }
return super.onMenuItemSelected(featureId, item); return super.onMenuItemSelected(featureId, item);
} }
@Override @Override
public boolean onOptionsItemSelected(MenuItem item) { public boolean onOptionsItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case R.id.addtunnel: case R.id.addtunnel:
createTunnel(); createTunnel();
return true; return true;
case R.id.stopservice: case R.id.stopservice:
Log.d("SSLDroid", "Stopping service"); Log.d("SSLDroid", "Stopping service");
stopService(new Intent(this, SSLDroid.class)); stopService(new Intent(this, SSLDroid.class));
return true; return true;
case R.id.startservice: case R.id.startservice:
Log.d("SSLDroid", "Starting service"); Log.d("SSLDroid", "Starting service");
startService(new Intent(this, SSLDroid.class)); startService(new Intent(this, SSLDroid.class));
return true; return true;
case R.id.readlogs: case R.id.readlogs:
readLogs(); readLogs();
return true; return true;
} }
return super.onOptionsItemSelected(item); return super.onOptionsItemSelected(item);
} }
@Override @Override
public boolean onContextItemSelected(MenuItem item) { public boolean onContextItemSelected(MenuItem item) {
switch (item.getItemId()) { switch (item.getItemId()) {
case DELETE_ID: case DELETE_ID:
AdapterContextMenuInfo info = (AdapterContextMenuInfo) item AdapterContextMenuInfo info = (AdapterContextMenuInfo) item
.getMenuInfo(); .getMenuInfo();
dbHelper.deleteTunnel(info.id); dbHelper.deleteTunnel(info.id);
fillData(); fillData();
return true; return true;
} }
return super.onContextItemSelected(item); return super.onContextItemSelected(item);
} }
private void createTunnel() { private void createTunnel() {
Intent i = new Intent(this, SSLDroidTunnelDetails.class); Intent i = new Intent(this, SSLDroidTunnelDetails.class);
startActivityForResult(i, ACTIVITY_CREATE); startActivityForResult(i, ACTIVITY_CREATE);
} }
private void readLogs() { private void readLogs() {
Intent i = new Intent(this, SSLDroidReadLogs.class); Intent i = new Intent(this, SSLDroidReadLogs.class);
startActivity(i); startActivity(i);
} }
// 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 // ListView and view (row) on which was clicked, position and
// requestCode was the origin request code send to the activity @Override
// resultCode is the return code, 0 is everything is ok protected void onListItemClick(ListView l, View v, int position, long id) {
// intend can be use to get some data from the caller super.onListItemClick(l, v, position, id);
@Override Intent i = new Intent(this, SSLDroidTunnelDetails.class);
protected void onActivityResult(int requestCode, int resultCode, i.putExtra(SSLDroidDbAdapter.KEY_ROWID, id);
Intent intent) { // Activity returns an result if called with startActivityForResult
super.onActivityResult(requestCode, resultCode, intent);
fillData();
} startActivityForResult(i, ACTIVITY_EDIT);
}
private void fillData() { // Called with the result of the other activity
cursor = dbHelper.fetchAllTunnels(); // requestCode was the origin request code send to the activity
startManagingCursor(cursor); // 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();
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 private void fillData() {
SimpleCursorAdapter tunnels = new SimpleCursorAdapter(this, cursor = dbHelper.fetchAllTunnels();
R.layout.tunnel_list_item, cursor, from, to); startManagingCursor(cursor);
setListAdapter(tunnels);
}
@Override String[] from = new String[] { SSLDroidDbAdapter.KEY_NAME };
public void onCreateContextMenu(ContextMenu menu, View v, int[] to = new int[] { R.id.text1 };
ContextMenuInfo menuInfo) {
super.onCreateContextMenu(menu, v, menuInfo); // Now create an array adapter and set it to display using our row
menu.add(0, DELETE_ID, 0, R.string.menu_delete); 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

@ -11,56 +11,56 @@ import android.view.Menu;
import android.view.MenuItem; import android.view.MenuItem;
import android.widget.TextView; import android.widget.TextView;
public class SSLDroidReadLogs extends Activity{ public class SSLDroidReadLogs extends Activity {
@Override @Override
public boolean onCreateOptionsMenu(Menu menu) { public boolean onCreateOptionsMenu(Menu menu) {
MenuItem refresh = menu.add(R.string.refresh); MenuItem refresh = menu.add(R.string.refresh);
refresh.setIcon(android.R.drawable.ic_menu_rotate); refresh.setIcon(android.R.drawable.ic_menu_rotate);
return true; return true;
} }
@Override
public boolean onOptionsItemSelected(MenuItem item) {
refreshLogs();
return true;
}
@Override
public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.read_logs);
refreshLogs();
}
public void refreshLogs(){ @Override
TextView logcontainer = (TextView) findViewById(R.id.logTextView); public boolean onOptionsItemSelected(MenuItem item) {
logcontainer.setText(""); refreshLogs();
Process mLogcatProc = null; return true;
BufferedReader reader = null; }
try {
mLogcatProc = Runtime.getRuntime().exec(new String[] @Override
{"logcat", "-d", "-v", "time", "-b", "main", "SSLDroid:D SSLDroidGui:D *:S" }); public void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.read_logs);
refreshLogs();
}
public void refreshLogs() {
TextView logcontainer = (TextView) findViewById(R.id.logTextView);
logcontainer.setText("");
Process mLogcatProc = null;
BufferedReader reader = null;
try {
mLogcatProc = Runtime.getRuntime().exec(new String[]
{"logcat", "-d", "-v", "time", "-b", "main", "SSLDroid:D SSLDroidGui:D *:S" });
reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream())); reader = new BufferedReader(new InputStreamReader(mLogcatProc.getInputStream()));
String line; String line;
String separator = System.getProperty("line.separator"); String separator = System.getProperty("line.separator");
while ((line = reader.readLine()) != null){ while ((line = reader.readLine()) != null) {
logcontainer.append(line+separator); logcontainer.append(line+separator);
} }
} catch (IOException e) { } catch (IOException e) {
Log.d("SSLDroid", "Logcat problem: "+e.toString()); Log.d("SSLDroid", "Logcat problem: "+e.toString());
} }
finally { finally {
if (reader != null) if (reader != null)
try { try {
reader.close(); reader.close();
} catch (IOException e) { } catch (IOException e) {
Log.d("SSLDroid", "Logcat problem: "+e.toString()); Log.d("SSLDroid", "Logcat problem: "+e.toString());
} }
} }
} }
} }

View File

@ -37,359 +37,359 @@ import hu.blint.ssldroid.db.SSLDroidDbAdapter;
//TODO: test connection button //TODO: test connection button
public class SSLDroidTunnelDetails extends Activity { public class SSLDroidTunnelDetails extends Activity {
private EditText name; private EditText name;
private EditText localport; private EditText localport;
private EditText remotehost; private EditText remotehost;
private EditText remoteport; private EditText remoteport;
private EditText pkcsfile; private EditText pkcsfile;
private EditText pkcspass; private EditText pkcspass;
private Long rowId; private Long rowId;
private SSLDroidDbAdapter dbHelper; private SSLDroidDbAdapter dbHelper;
@Override @Override
protected void onCreate(Bundle bundle) { protected void onCreate(Bundle bundle) {
super.onCreate(bundle); super.onCreate(bundle);
dbHelper = new SSLDroidDbAdapter(this); dbHelper = new SSLDroidDbAdapter(this);
dbHelper.open(); dbHelper.open();
setContentView(R.layout.tunnel_details); setContentView(R.layout.tunnel_details);
Button confirmButton = (Button) findViewById(R.id.tunnel_apply_button); Button confirmButton = (Button) findViewById(R.id.tunnel_apply_button);
name = (EditText) findViewById(R.id.name); name = (EditText) findViewById(R.id.name);
localport = (EditText) findViewById(R.id.localport); localport = (EditText) findViewById(R.id.localport);
remotehost = (EditText) findViewById(R.id.remotehost); remotehost = (EditText) findViewById(R.id.remotehost);
remoteport = (EditText) findViewById(R.id.remoteport); remoteport = (EditText) findViewById(R.id.remoteport);
pkcsfile = (EditText) findViewById(R.id.pkcsfile); pkcsfile = (EditText) findViewById(R.id.pkcsfile);
pkcspass = (EditText) findViewById(R.id.pkcspass); pkcspass = (EditText) findViewById(R.id.pkcspass);
Button pickFile = (Button) findViewById(R.id.pickFile); Button pickFile = (Button) findViewById(R.id.pickFile);
pickFile.setOnClickListener(new View.OnClickListener() { pickFile.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { public void onClick(View view) {
pickFileSimple(); pickFileSimple();
} }
}); });
rowId = null; rowId = null;
Bundle extras = getIntent().getExtras(); Bundle extras = getIntent().getExtras();
rowId = (bundle == null) ? null : (Long) bundle rowId = (bundle == null) ? null : (Long) bundle
.getSerializable(SSLDroidDbAdapter.KEY_ROWID); .getSerializable(SSLDroidDbAdapter.KEY_ROWID);
if (extras != null) { if (extras != null) {
rowId = extras.getLong(SSLDroidDbAdapter.KEY_ROWID); rowId = extras.getLong(SSLDroidDbAdapter.KEY_ROWID);
} }
populateFields(); populateFields();
confirmButton.setOnClickListener(new View.OnClickListener() { confirmButton.setOnClickListener(new View.OnClickListener() {
public void onClick(View view) { public void onClick(View view) {
if (name.getText().length() == 0) { if (name.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required tunnel name parameter not setup, skipping save", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Required tunnel name parameter not setup, skipping save", Toast.LENGTH_LONG).show();
return; return;
} }
//local port validation //local port validation
if (localport.getText().length() == 0) { if (localport.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required local port parameter not setup, skipping save", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Required local port parameter not setup, skipping save", Toast.LENGTH_LONG).show();
return; return;
} }
else { else {
//local port should be between 1025-65535 //local port should be between 1025-65535
int cPort = 0; int cPort = 0;
try { try {
cPort = Integer.parseInt(localport.getText().toString()); cPort = Integer.parseInt(localport.getText().toString());
} catch (NumberFormatException e){ } catch (NumberFormatException e) {
Toast.makeText(getBaseContext(), "Local port parameter has invalid number format", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Local port parameter has invalid number format", Toast.LENGTH_LONG).show();
return; return;
} }
if (cPort < 1025 || cPort > 65535) { if (cPort < 1025 || cPort > 65535) {
Toast.makeText(getBaseContext(), "Local port parameter not in valid range (1025-65535)", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Local port parameter not in valid range (1025-65535)", Toast.LENGTH_LONG).show();
return; return;
} }
//check if the requested port is colliding with a port already configured for another tunnel //check if the requested port is colliding with a port already configured for another tunnel
SSLDroidDbAdapter dbHelper = new SSLDroidDbAdapter(getBaseContext()); SSLDroidDbAdapter dbHelper = new SSLDroidDbAdapter(getBaseContext());
dbHelper.open(); dbHelper.open();
Cursor cursor = dbHelper.fetchAllLocalPorts(); Cursor cursor = dbHelper.fetchAllLocalPorts();
startManagingCursor(cursor); startManagingCursor(cursor);
while (cursor.moveToNext()){ while (cursor.moveToNext()) {
String cDbName = cursor.getString(cursor.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME)); String cDbName = cursor.getString(cursor.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME));
int cDbPort = cursor.getInt(cursor.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT)); int cDbPort = cursor.getInt(cursor.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_LOCALPORT));
if (cPort == cDbPort){ if (cPort == cDbPort) {
Toast.makeText(getBaseContext(), "Local port already configured in tunnel '"+cDbName+"', please change...", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Local port already configured in tunnel '"+cDbName+"', please change...", Toast.LENGTH_LONG).show();
return; return;
} }
} }
} }
//remote host validation //remote host validation
if (remotehost.getText().length() == 0){ if (remotehost.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required remote host parameter not setup, skipping save", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Required remote host parameter not setup, skipping save", Toast.LENGTH_LONG).show();
return; return;
} }
else { else {
//if we have interwebs access, the remote host should exist //if we have interwebs access, the remote host should exist
ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE); ConnectivityManager conMgr = (ConnectivityManager)getSystemService(Context.CONNECTIVITY_SERVICE);
if ( conMgr.getActiveNetworkInfo() != null || conMgr.getActiveNetworkInfo().isAvailable()) { if ( conMgr.getActiveNetworkInfo() != null || conMgr.getActiveNetworkInfo().isAvailable()) {
try { try {
InetAddress.getByName(remotehost.getText().toString()); InetAddress.getByName(remotehost.getText().toString());
} catch (UnknownHostException e){ } catch (UnknownHostException e) {
Toast.makeText(getBaseContext(), "Remote host not found, please recheck...", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Remote host not found, please recheck...", Toast.LENGTH_LONG).show();
} }
} }
} }
//remote port validation //remote port validation
if (remoteport.getText().length() == 0){ if (remoteport.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required remote port parameter not setup, skipping save", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Required remote port parameter not setup, skipping save", Toast.LENGTH_LONG).show();
return; return;
} }
else { else {
//remote port should be between 1025-65535 //remote port should be between 1025-65535
int cPort = 0; int cPort = 0;
try { try {
cPort = Integer.parseInt(remoteport.getText().toString()); cPort = Integer.parseInt(remoteport.getText().toString());
} catch (NumberFormatException e){ } catch (NumberFormatException e) {
Toast.makeText(getBaseContext(), "Remote port parameter has invalid number format", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Remote port parameter has invalid number format", Toast.LENGTH_LONG).show();
return; return;
} }
if (cPort < 1 || cPort > 65535) { if (cPort < 1 || cPort > 65535) {
Toast.makeText(getBaseContext(), "Remote port parameter not in valid range (1-65535)", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Remote port parameter not in valid range (1-65535)", Toast.LENGTH_LONG).show();
return; return;
} }
} }
if (pkcsfile.getText().length() == 0){ if (pkcsfile.getText().length() == 0) {
Toast.makeText(getBaseContext(), "Required PKCS12 file parameter not setup, skipping save", Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "Required PKCS12 file parameter not setup, skipping save", Toast.LENGTH_LONG).show();
return; return;
} }
else { else {
// try to open pkcs12 file with password // try to open pkcs12 file with password
String cPkcsFile = pkcsfile.getText().toString(); String cPkcsFile = pkcsfile.getText().toString();
String cPkcsPass = pkcspass.getText().toString(); String cPkcsPass = pkcspass.getText().toString();
try { try {
if (checkKeys(cPkcsFile, cPkcsPass) == false){ if (checkKeys(cPkcsFile, cPkcsPass) == false) {
return; return;
} }
} catch (Exception e) { } catch (Exception e) {
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show(); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
return; return;
} }
} }
saveState(); saveState();
setResult(RESULT_OK); setResult(RESULT_OK);
finish(); finish();
} }
}); });
} }
final List<File> getFileNames(File url, File baseurl) final List<File> getFileNames(File url, File baseurl)
{ {
final List<File> names = new LinkedList<File>(); final List<File> names = new LinkedList<File>();
File[] files = url.listFiles(); File[] files = url.listFiles();
if (files != null && files.length > 0) { if (files != null && files.length > 0) {
for(File file : url.listFiles()) { for (File file : url.listFiles()) {
if (file.getName().startsWith(".")) if (file.getName().startsWith("."))
continue; continue;
names.add(file); names.add(file);
} }
} }
return names; return names;
} }
private void showFiles(final List<File> names, final File baseurl){ private void showFiles(final List<File> names, final File baseurl) {
final String[] namesList = new String[names.size()]; // = names.toArray(new String[] {}); final String[] namesList = new String[names.size()]; // = names.toArray(new String[] {});
ListIterator<File> filelist = names.listIterator(); ListIterator<File> filelist = names.listIterator();
int i = 0; int i = 0;
while (filelist.hasNext()){ while (filelist.hasNext()) {
File file = filelist.next(); File file = filelist.next();
if (file.isDirectory()) if (file.isDirectory())
namesList[i] = file.getAbsolutePath().replaceFirst(baseurl+"/", "")+" (...)"; namesList[i] = file.getAbsolutePath().replaceFirst(baseurl+"/", "")+" (...)";
else else
namesList[i] = file.getAbsolutePath().replaceFirst(baseurl+"/", ""); namesList[i] = file.getAbsolutePath().replaceFirst(baseurl+"/", "");
i++; i++;
} }
//Log.d("SSLDroid", "Gathered file names: "+namesList.toString()); //Log.d("SSLDroid", "Gathered file names: "+namesList.toString());
// prompt user to select any file from the sdcard root
new AlertDialog.Builder(SSLDroidTunnelDetails.this)
.setTitle(R.string.pkcsfile_pick)
.setItems(namesList, new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
File name = names.get(arg1);
if (name.isDirectory()){
List<File> names_ = getFileNames(name, baseurl);
Collections.sort(names_);
if (names_.size() > 0) {
showFiles(names_, baseurl);
}
else
Toast.makeText(getBaseContext(), "Empty directory", Toast.LENGTH_LONG).show();
}
if (name.isFile()) {
pkcsfile.setText(name.getAbsolutePath());
pkcspass.requestFocus();
}
}
})
//create a Back button (shouldn't go above base URL)
.setNeutralButton(R.string.back, new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
if (names.size() == 0)
return;
File name = names.get(0);
if (!name.getParentFile().equals(baseurl)) {
List<File> names_ = getFileNames(name.getParentFile().getParentFile(), baseurl);
Collections.sort(names_);
if (names_.size() > 0) {
showFiles(names_, baseurl);
}
else
return;
}
}
})
.setNegativeButton(android.R.string.cancel, null).create().show();
}
//pick a file from /sdcard, courtesy of ConnectBot
private void pickFileSimple() {
// build list of all files in sdcard root
final File sdcard = Environment.getExternalStorageDirectory();
Log.d("SSLDroid", "SD Card location: "+sdcard.toString());
// Don't show a dialog if the SD card is completely absent. // prompt user to select any file from the sdcard root
final String state = Environment.getExternalStorageState(); new AlertDialog.Builder(SSLDroidTunnelDetails.this)
if (!Environment.MEDIA_MOUNTED_READ_ONLY.equals(state) .setTitle(R.string.pkcsfile_pick)
&& !Environment.MEDIA_MOUNTED.equals(state)) { .setItems(namesList, new OnClickListener() {
new AlertDialog.Builder(SSLDroidTunnelDetails.this) public void onClick(DialogInterface arg0, int arg1) {
.setMessage(R.string.alert_sdcard_absent) File name = names.get(arg1);
.setNegativeButton(android.R.string.cancel, null).create().show(); if (name.isDirectory()) {
return; List<File> names_ = getFileNames(name, baseurl);
} Collections.sort(names_);
if (names_.size() > 0) {
showFiles(names_, baseurl);
}
else
Toast.makeText(getBaseContext(), "Empty directory", Toast.LENGTH_LONG).show();
}
if (name.isFile()) {
pkcsfile.setText(name.getAbsolutePath());
pkcspass.requestFocus();
}
}
})
//create a Back button (shouldn't go above base URL)
.setNeutralButton(R.string.back, new OnClickListener() {
public void onClick(DialogInterface arg0, int arg1) {
if (names.size() == 0)
return;
File name = names.get(0);
if (!name.getParentFile().equals(baseurl)) {
List<File> names_ = getFileNames(name.getParentFile().getParentFile(), baseurl);
Collections.sort(names_);
if (names_.size() > 0) {
showFiles(names_, baseurl);
}
else
return;
}
}
})
.setNegativeButton(android.R.string.cancel, null).create().show();
}
List<File> names = new LinkedList<File>(); //pick a file from /sdcard, courtesy of ConnectBot
names = getFileNames(sdcard, sdcard); private void pickFileSimple() {
Collections.sort(names); // build list of all files in sdcard root
showFiles(names, sdcard); final File sdcard = Environment.getExternalStorageDirectory();
} Log.d("SSLDroid", "SD Card location: "+sdcard.toString());
private void populateFields() { // Don't show a dialog if the SD card is completely absent.
if (rowId != null) { final String state = Environment.getExternalStorageState();
Cursor Tunnel = dbHelper.fetchTunnel(rowId); if (!Environment.MEDIA_MOUNTED_READ_ONLY.equals(state)
startManagingCursor(Tunnel); && !Environment.MEDIA_MOUNTED.equals(state)) {
new AlertDialog.Builder(SSLDroidTunnelDetails.this)
name.setText(Tunnel.getString(Tunnel .setMessage(R.string.alert_sdcard_absent)
.getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME))); .setNegativeButton(android.R.string.cancel, null).create().show();
localport.setText(Tunnel.getString(Tunnel return;
.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)));
}
}
public boolean checkKeys(String inCertPath, String passw) throws Exception {
try {
FileInputStream in_cert = new FileInputStream(inCertPath);
KeyStore myStore = KeyStore.getInstance("PKCS12");
myStore.load(in_cert, passw.toCharArray());
Enumeration<String> eAliases = myStore.aliases();
while (eAliases.hasMoreElements()) {
String strAlias = (String) eAliases.nextElement();
if (myStore.isKeyEntry(strAlias)) {
// try to retrieve the private key part from PKCS12 certificate
myStore.getKey(strAlias, passw.toCharArray());
// try to retrieve the certificate part from PKCS12 certificate
myStore.getCertificate(strAlias);
}
}
} catch (KeyStoreException e) { List<File> names = new LinkedList<File>();
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show(); names = getFileNames(sdcard, sdcard);
return false; Collections.sort(names);
} catch (NoSuchAlgorithmException e) { showFiles(names, sdcard);
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show(); }
return false;
} catch (CertificateException e) {
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
return false;
} catch (IOException e) {
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
return false;
} catch (UnrecoverableKeyException e) {
Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
return false;
}
return true;
}
protected void onSaveInstanceState(Bundle outState) { private void populateFields() {
super.onSaveInstanceState(outState); if (rowId != null) {
saveState(); Cursor Tunnel = dbHelper.fetchTunnel(rowId);
outState.putSerializable(SSLDroidDbAdapter.KEY_ROWID, rowId); startManagingCursor(Tunnel);
}
@Override name.setText(Tunnel.getString(Tunnel
protected void onPause() { .getColumnIndexOrThrow(SSLDroidDbAdapter.KEY_NAME)));
super.onPause(); localport.setText(Tunnel.getString(Tunnel
//saveState(); .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)));
}
}
@Override public boolean checkKeys(String inCertPath, String passw) throws Exception {
protected void onResume() { try {
super.onResume(); FileInputStream in_cert = new FileInputStream(inCertPath);
populateFields(); KeyStore myStore = KeyStore.getInstance("PKCS12");
} myStore.load(in_cert, passw.toCharArray());
Enumeration<String> eAliases = myStore.aliases();
while (eAliases.hasMoreElements()) {
String strAlias = (String) eAliases.nextElement();
if (myStore.isKeyEntry(strAlias)) {
// try to retrieve the private key part from PKCS12 certificate
myStore.getKey(strAlias, passw.toCharArray());
// try to retrieve the certificate part from PKCS12 certificate
myStore.getCertificate(strAlias);
}
}
private void saveState() { } catch (KeyStoreException e) {
String sName = name.getText().toString(); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
int sLocalport = 0; return false;
try{ } catch (NoSuchAlgorithmException e) {
sLocalport = Integer.parseInt(localport.getText().toString()); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
} catch (NumberFormatException e){ return false;
} } catch (CertificateException e) {
String sRemotehost = remotehost.getText().toString(); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
int sRemoteport = 0; return false;
try{ } catch (IOException e) {
sRemoteport = Integer.parseInt(remoteport.getText().toString()); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
} catch (NumberFormatException e){ return false;
} } catch (UnrecoverableKeyException e) {
String sPkcsfile = pkcsfile.getText().toString(); Toast.makeText(getBaseContext(), "PKCS12 problem: "+e.getMessage(), Toast.LENGTH_LONG).show();
String sPkcspass = pkcspass.getText().toString(); return false;
}
//make sure that we have all of our values correctly set return true;
if (sName.length() == 0) { }
return;
}
if (sLocalport == 0) { protected void onSaveInstanceState(Bundle outState) {
return; super.onSaveInstanceState(outState);
} saveState();
if (sRemotehost.length() == 0) { outState.putSerializable(SSLDroidDbAdapter.KEY_ROWID, rowId);
return; }
}
if (sRemoteport == 0) { @Override
return; protected void onPause() {
} super.onPause();
if (sPkcsfile.length() == 0) { //saveState();
return; }
}
@Override
if (rowId == null) { protected void onResume() {
long id = dbHelper.createTunnel(sName, sLocalport, sRemotehost, super.onResume();
sRemoteport, sPkcsfile, sPkcspass); populateFields();
if (id > 0) { }
rowId = id;
} private void saveState() {
} else { String sName = name.getText().toString();
dbHelper.updateTunnel(rowId, sName, sLocalport, sRemotehost, sRemoteport, int sLocalport = 0;
sPkcsfile, sPkcspass); try {
} sLocalport = Integer.parseInt(localport.getText().toString());
Log.d("SSLDroid", "Saving settings..."); } catch (NumberFormatException e) {
}
//restart the service String sRemotehost = remotehost.getText().toString();
stopService(new Intent(this, SSLDroid.class)); int sRemoteport = 0;
startService(new Intent(this, SSLDroid.class)); try {
Log.d("SSLDroid", "Restarting service after settings save..."); 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

@ -11,53 +11,53 @@ import android.util.Log;
* xml.apache.org project. * xml.apache.org project.
*/ */
public class TcpProxy { public class TcpProxy {
String tunnelName; String tunnelName;
int listenPort; int listenPort;
String tunnelHost; String tunnelHost;
int tunnelPort; int tunnelPort;
String keyFile, keyPass; String keyFile, keyPass;
Thread server = null; Thread server = null;
ServerSocket ss = null; ServerSocket ss = null;
public TcpProxy(String tunnelName, int listenPort, String targetHost, int targetPort, String keyFile, String keyPass) { public TcpProxy(String tunnelName, int listenPort, String targetHost, int targetPort, String keyFile, String keyPass) {
this.tunnelName = tunnelName; this.tunnelName = tunnelName;
this.listenPort = listenPort; this.listenPort = listenPort;
this.tunnelHost = targetHost; this.tunnelHost = targetHost;
this.tunnelPort = targetPort; this.tunnelPort = targetPort;
this.keyFile = keyFile; this.keyFile = keyFile;
this.keyPass = keyPass; this.keyPass = keyPass;
} }
public void serve() throws IOException { public void serve() throws IOException {
try { try {
ss = new ServerSocket(listenPort, 50, InetAddress.getLocalHost()); ss = new ServerSocket(listenPort, 50, InetAddress.getLocalHost());
Log.d("SSLDroid", "Listening for connections on port " Log.d("SSLDroid", "Listening for connections on port "
+ this.listenPort + " ..."); + this.listenPort + " ...");
} catch (Exception e) { } catch (Exception e) {
Log.d("SSLDroid", "Error setting up listening socket: " + e.toString()); Log.d("SSLDroid", "Error setting up listening socket: " + e.toString());
return; return;
} }
server = new TcpProxyServerThread(this.ss, this.tunnelName, this.listenPort, this.tunnelHost, server = new TcpProxyServerThread(this.ss, this.tunnelName, this.listenPort, this.tunnelHost,
this.tunnelPort, this.keyFile, this.keyPass); this.tunnelPort, this.keyFile, this.keyPass);
server.start(); server.start();
} }
public void stop() { public void stop() {
if (server != null){ if (server != null) {
try { try {
//close the server socket and interrupt the server thread //close the server socket and interrupt the server thread
ss.close(); ss.close();
server.interrupt(); server.interrupt();
} catch (Exception e) { } catch (Exception e) {
Log.d("SSLDroid", "Interrupt failure: " + e.toString()); Log.d("SSLDroid", "Interrupt failure: " + e.toString());
} }
} }
Log.d("SSLDroid", "Stopping tunnel "+this.listenPort+":"+this.tunnelHost+":"+this.tunnelPort); Log.d("SSLDroid", "Stopping tunnel "+this.listenPort+":"+this.tunnelHost+":"+this.tunnelPort);
} }
//if the listening socket is still active, we're alive //if the listening socket is still active, we're alive
public boolean isAlive(){ public boolean isAlive() {
return ss.isBound(); return ss.isBound();
} }
} }

View File

@ -25,192 +25,192 @@ import javax.net.ssl.X509TrustManager;
import android.util.Log; import android.util.Log;
public class TcpProxyServerThread extends Thread { public class TcpProxyServerThread extends Thread {
String tunnelName;
int listenPort;
String tunnelHost;
int tunnelPort;
String keyFile, keyPass;
Relay inRelay, outRelay;
ServerSocket ss = null;
int sessionid = 0;
public TcpProxyServerThread(ServerSocket ss,String tunnelName, int listenPort, String tunnelHost, int tunnelPort, String keyFile, String keyPass) { String tunnelName;
this.tunnelName = tunnelName; int listenPort;
this.listenPort = listenPort; String tunnelHost;
this.tunnelHost = tunnelHost; int tunnelPort;
this.tunnelPort = tunnelPort; String keyFile, keyPass;
this.keyFile = keyFile; Relay inRelay, outRelay;
this.keyPass = keyPass; ServerSocket ss = null;
this.ss = ss; int sessionid = 0;
}
// Create a trust manager that does not validate certificate chains
// TODO: handle this somehow properly (popup if cert is untrusted?)
// TODO: cacert + crl should be configurable
TrustManager[] trustAllCerts = new TrustManager[]{
new X509TrustManager() {
public java.security.cert.X509Certificate[] getAcceptedIssuers() {
return null;
}
public void checkClientTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
public void checkServerTrusted(
java.security.cert.X509Certificate[] certs, String authType) {
}
}
};
private static SSLSocketFactory sslSocketFactory;
public final SSLSocketFactory getSocketFactory(String pkcsFile, public TcpProxyServerThread(ServerSocket ss,String tunnelName, int listenPort, String tunnelHost, int tunnelPort, String keyFile, String keyPass) {
String pwd, int sessionid) { this.tunnelName = tunnelName;
if (sslSocketFactory == null) { this.listenPort = listenPort;
try { this.tunnelHost = tunnelHost;
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509"); this.tunnelPort = tunnelPort;
KeyStore keyStore = KeyStore.getInstance("PKCS12"); this.keyFile = keyFile;
keyStore.load(new FileInputStream(pkcsFile), pwd.toCharArray()); this.keyPass = keyPass;
keyManagerFactory.init(keyStore, pwd.toCharArray()); this.ss = ss;
SSLContext context = SSLContext.getInstance("TLS"); }
context.init(keyManagerFactory.getKeyManagers(), trustAllCerts,
new SecureRandom());
sslSocketFactory = (SSLSocketFactory) context.getSocketFactory();
} catch (FileNotFoundException e) { // Create a trust manager that does not validate certificate chains
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate file:" // TODO: handle this somehow properly (popup if cert is untrusted?)
+ e.toString()); // TODO: cacert + crl should be configurable
} catch (KeyManagementException e) { TrustManager[] trustAllCerts = new TrustManager[] {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": No SSL algorithm support: " + e.toString()); new X509TrustManager() {
} catch (NoSuchAlgorithmException e) { public java.security.cert.X509Certificate[] getAcceptedIssuers() {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": No common SSL algorithm found: " + e.toString()); return null;
} catch (KeyStoreException e) { }
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error setting up keystore:" + e.toString()); public void checkClientTrusted(
} catch (java.security.cert.CertificateException e) { java.security.cert.X509Certificate[] certs, String authType) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate:" + e.toString()); }
} catch (IOException e) { public void checkServerTrusted(
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate file:" + e.toString()); java.security.cert.X509Certificate[] certs, String authType) {
} catch (UnrecoverableKeyException e) { }
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate:" + e.toString()); }
} };
}
return sslSocketFactory;
}
public class Relay extends Thread {
private InputStream in;
private OutputStream out;
private String side;
private int sessionid;
private final static int BUFSIZ = 4096;
private byte buf[] = new byte[BUFSIZ];
public Relay(InputStream in, OutputStream out, String side, int sessionid) { private static SSLSocketFactory sslSocketFactory;
this.in = in;
this.out = out;
this.side = side;
this.sessionid = sessionid;
}
public void run() { public final SSLSocketFactory getSocketFactory(String pkcsFile,
int n = 0; String pwd, int sessionid) {
if (sslSocketFactory == null) {
try {
KeyManagerFactory keyManagerFactory = KeyManagerFactory.getInstance("X509");
KeyStore keyStore = KeyStore.getInstance("PKCS12");
keyStore.load(new FileInputStream(pkcsFile), pwd.toCharArray());
keyManagerFactory.init(keyStore, pwd.toCharArray());
SSLContext context = SSLContext.getInstance("TLS");
context.init(keyManagerFactory.getKeyManagers(), trustAllCerts,
new SecureRandom());
sslSocketFactory = (SSLSocketFactory) context.getSocketFactory();
try { } catch (FileNotFoundException e) {
while ((n = in.read(buf)) > 0) { Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate file:"
if (Thread.interrupted()) { + e.toString());
// We've been interrupted: no more relaying } catch (KeyManagementException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Interrupted "+side+" thread"); Log.d("SSLDroid", tunnelName+"/"+sessionid+": No SSL algorithm support: " + e.toString());
try { } catch (NoSuchAlgorithmException e) {
in.close(); Log.d("SSLDroid", tunnelName+"/"+sessionid+": No common SSL algorithm found: " + e.toString());
out.close(); } catch (KeyStoreException e) {
} catch (IOException e) { Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error setting up keystore:" + e.toString());
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString()); } catch (java.security.cert.CertificateException e) {
} Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate:" + e.toString());
return; } catch (IOException e) {
} Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate file:" + e.toString());
out.write(buf, 0, n); } catch (UnrecoverableKeyException e) {
out.flush(); Log.d("SSLDroid", tunnelName+"/"+sessionid+": Error loading the client certificate:" + e.toString());
}
}
return sslSocketFactory;
}
for (int i = 0; i < n; i++) { public class Relay extends Thread {
if (buf[i] == 7) private InputStream in;
buf[i] = '#'; private OutputStream out;
} private String side;
} private int sessionid;
} catch (SocketException e) { private final static int BUFSIZ = 4096;
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString()); private byte buf[] = new byte[BUFSIZ];
} catch (IOException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
}
}
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Quitting "+side+"-side stream proxy...");
}
}
public void run() {
while (true) {
try {
Thread fromBrowserToServer = null;
Thread fromServerToBrowser = null;
if (isInterrupted()){
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Interrupted server thread, closing sockets...");
ss.close();
if (fromBrowserToServer != null)
fromBrowserToServer.notify();
if (fromServerToBrowser != null)
fromServerToBrowser.notify();
return;
}
// accept the connection from my client
Socket sc = null;
try {
sc = ss.accept();
sessionid++;
} catch (SocketException e){
Log.d("SSLDroid", "Accept failure: " + e.toString());
}
Socket st = null;
try {
st = (SSLSocket) getSocketFactory(this.keyFile, this.keyPass, this.sessionid).createSocket(this.tunnelHost, this.tunnelPort);
((SSLSocket) st).startHandshake();
} catch (IOException e){
}
catch (Exception e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": SSL failure: " + e.toString());
sc.close();
return;
}
if (sc == null || st == null){ public Relay(InputStream in, OutputStream out, String side, int sessionid) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Trying socket operation on a null socket, returning"); this.in = in;
return; this.out = out;
} this.side = side;
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Tunnelling port " this.sessionid = sessionid;
+ listenPort + " to port " }
+ tunnelPort + " on host "
+ tunnelHost + " ...");
// relay the stuff through
fromBrowserToServer = new Relay(
sc.getInputStream(), st.getOutputStream(), "client", sessionid);
fromServerToBrowser = new Relay(
st.getInputStream(), sc.getOutputStream(), "server", sessionid);
fromBrowserToServer.start(); public void run() {
fromServerToBrowser.start(); int n = 0;
} catch (IOException ee) { try {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Ouch: " + ee.toString()); while ((n = in.read(buf)) > 0) {
} if (Thread.interrupted()) {
} // We've been interrupted: no more relaying
} Log.d("SSLDroid", tunnelName+"/"+sessionid+": Interrupted "+side+" thread");
try {
in.close();
out.close();
} catch (IOException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
}
return;
}
out.write(buf, 0, n);
out.flush();
for (int i = 0; i < n; i++) {
if (buf[i] == 7)
buf[i] = '#';
}
}
} catch (SocketException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
} catch (IOException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
} finally {
try {
in.close();
out.close();
} catch (IOException e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": "+e.toString());
}
}
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Quitting "+side+"-side stream proxy...");
}
}
public void run() {
while (true) {
try {
Thread fromBrowserToServer = null;
Thread fromServerToBrowser = null;
if (isInterrupted()) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Interrupted server thread, closing sockets...");
ss.close();
if (fromBrowserToServer != null)
fromBrowserToServer.notify();
if (fromServerToBrowser != null)
fromServerToBrowser.notify();
return;
}
// accept the connection from my client
Socket sc = null;
try {
sc = ss.accept();
sessionid++;
} catch (SocketException e) {
Log.d("SSLDroid", "Accept failure: " + e.toString());
}
Socket st = null;
try {
st = (SSLSocket) getSocketFactory(this.keyFile, this.keyPass, this.sessionid).createSocket(this.tunnelHost, this.tunnelPort);
((SSLSocket) st).startHandshake();
} catch (IOException e) {
}
catch (Exception e) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": SSL failure: " + e.toString());
sc.close();
return;
}
if (sc == null || st == null) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Trying socket operation on a null socket, returning");
return;
}
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Tunnelling port "
+ listenPort + " to port "
+ tunnelPort + " on host "
+ tunnelHost + " ...");
// relay the stuff through
fromBrowserToServer = new Relay(
sc.getInputStream(), st.getOutputStream(), "client", sessionid);
fromServerToBrowser = new Relay(
st.getInputStream(), sc.getOutputStream(), "server", sessionid);
fromBrowserToServer.start();
fromServerToBrowser.start();
} catch (IOException ee) {
Log.d("SSLDroid", tunnelName+"/"+sessionid+": Ouch: " + ee.toString());
}
}
}
}; };

View File

@ -8,112 +8,115 @@ import android.database.sqlite.SQLiteDatabase;
public class SSLDroidDbAdapter { public class SSLDroidDbAdapter {
// Database fields // Database fields
public static final String KEY_ROWID = "_id"; public static final String KEY_ROWID = "_id";
public static final String KEY_NAME = "name"; public static final String KEY_NAME = "name";
public static final String KEY_LOCALPORT = "localport"; public static final String KEY_LOCALPORT = "localport";
public static final String KEY_REMOTEHOST = "remotehost"; public static final String KEY_REMOTEHOST = "remotehost";
public static final String KEY_REMOTEPORT = "remoteport"; public static final String KEY_REMOTEPORT = "remoteport";
public static final String KEY_PKCSFILE = "pkcsfile"; public static final String KEY_PKCSFILE = "pkcsfile";
public static final String KEY_PKCSPASS = "pkcspass"; public static final String KEY_PKCSPASS = "pkcspass";
private static final String DATABASE_TABLE = "tunnels"; private static final String DATABASE_TABLE = "tunnels";
private Context context; private Context context;
private SQLiteDatabase database; private SQLiteDatabase database;
private SSLDroidDbHelper dbHelper; private SSLDroidDbHelper dbHelper;
public SSLDroidDbAdapter(Context context) { public SSLDroidDbAdapter(Context context) {
this.context = context; this.context = context;
} }
public SSLDroidDbAdapter open() throws SQLException { public SSLDroidDbAdapter open() throws SQLException {
dbHelper = new SSLDroidDbHelper(context); dbHelper = new SSLDroidDbHelper(context);
database = dbHelper.getWritableDatabase(); database = dbHelper.getWritableDatabase();
return this; return this;
} }
public void close() { public void close() {
dbHelper.close(); dbHelper.close();
database.close(); database.close();
} }
/** /**
* Create a new tunnel If the tunnel is successfully created return the new * Create a new tunnel If the tunnel is successfully created return the new
* rowId for that note, otherwise return a -1 to indicate failure. * rowId for that note, otherwise return a -1 to indicate failure.
*/ */
public long createTunnel(String name, int localport, String remotehost, int remoteport, public long createTunnel(String name, int localport, String remotehost, int remoteport,
String pkcsfile, String pkcspass) { String pkcsfile, String pkcspass) {
ContentValues initialValues = createContentValues(name, localport, remotehost, ContentValues initialValues = createContentValues(name, localport, remotehost,
remoteport, pkcsfile, pkcspass); remoteport, pkcsfile, pkcspass);
return database.insert(DATABASE_TABLE, null, initialValues); return database.insert(DATABASE_TABLE, null, initialValues);
} }
/** /**
* Update the tunnel * Update the tunnel
*/ */
public boolean updateTunnel(long rowId, String name, int localport, String remotehost, public boolean updateTunnel(long rowId, String name, int localport, String remotehost,
int remoteport, String pkcsfile, String pkcspass) { int remoteport, String pkcsfile, String pkcspass) {
ContentValues updateValues = createContentValues(name, localport, remotehost, ContentValues updateValues = createContentValues(name, localport, remotehost,
remoteport, pkcsfile, pkcspass); remoteport, pkcsfile, pkcspass);
return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "=" return database.update(DATABASE_TABLE, updateValues, KEY_ROWID + "="
+ rowId, null) > 0; + rowId, null) > 0;
} }
/** /**
* Deletes tunnel * Deletes tunnel
*/ */
public boolean deleteTunnel(long rowId) { public boolean deleteTunnel(long rowId) {
return database.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0; return database.delete(DATABASE_TABLE, KEY_ROWID + "=" + rowId, null) > 0;
} }
/** /**
* Return a Cursor over the list of all tunnels in the database * Return a Cursor over the list of all tunnels in the database
* *
* @return Cursor over all notes * @return Cursor over all notes
*/ */
public Cursor fetchAllTunnels() { public Cursor fetchAllTunnels() {
return database.query(DATABASE_TABLE, new String[] { KEY_ROWID, return database.query(DATABASE_TABLE, new String[] { KEY_ROWID,
KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT, KEY_PKCSFILE, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT, KEY_PKCSFILE,
KEY_PKCSPASS }, null, null, null, null, null); KEY_PKCSPASS
} }, null, null, null, null, null);
}
/** /**
* Return a Cursor over the list of all tunnels in the database * Return a Cursor over the list of all tunnels in the database
* *
* @return Cursor over all notes * @return Cursor over all notes
*/ */
public Cursor fetchAllLocalPorts() { public Cursor fetchAllLocalPorts() {
return database.query(DATABASE_TABLE, new String[] { KEY_NAME, return database.query(DATABASE_TABLE, new String[] { KEY_NAME,
KEY_LOCALPORT }, null, null, null, null, null); KEY_LOCALPORT
} }, 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) { * Return a Cursor positioned at the defined tunnel
ContentValues values = new ContentValues(); */
values.put(KEY_NAME, name); public Cursor fetchTunnel(long rowId) throws SQLException {
values.put(KEY_LOCALPORT, localport); Cursor mCursor = database.query(true, DATABASE_TABLE, new String[] {
values.put(KEY_REMOTEHOST, remotehost); KEY_ROWID, KEY_NAME, KEY_LOCALPORT, KEY_REMOTEHOST, KEY_REMOTEPORT,
values.put(KEY_REMOTEPORT, remoteport); KEY_PKCSFILE, KEY_PKCSPASS
values.put(KEY_REMOTEPORT, remoteport); },
values.put(KEY_PKCSFILE, pkcsfile); KEY_ROWID + "=" + rowId, null, null, null, null, null);
values.put(KEY_PKCSPASS, pkcspass); if (mCursor != null) {
return values; 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

@ -5,35 +5,35 @@ import android.database.sqlite.SQLiteDatabase;
import android.database.sqlite.SQLiteOpenHelper; import android.database.sqlite.SQLiteOpenHelper;
public class SSLDroidDbHelper extends SQLiteOpenHelper { public class SSLDroidDbHelper extends SQLiteOpenHelper {
private static final String DATABASE_NAME = "applicationdata"; private static final String DATABASE_NAME = "applicationdata";
private static final int DATABASE_VERSION = 1; private static final int DATABASE_VERSION = 1;
// Database creation sql statement // Database creation sql statement
private static final String DATABASE_CREATE = "create table tunnels (_id integer primary key autoincrement, " 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, " + "name text not null, localport integer not null, remotehost text not null, "
+ "remoteport integer not null, pkcsfile text not null, pkcspass text );"; + "remoteport integer not null, pkcsfile text not null, pkcspass text );";
public SSLDroidDbHelper(Context context) { public SSLDroidDbHelper(Context context) {
super(context, DATABASE_NAME, null, DATABASE_VERSION); super(context, DATABASE_NAME, null, DATABASE_VERSION);
} }
// Method is called during creation of the database // Method is called during creation of the database
@Override @Override
public void onCreate(SQLiteDatabase database) { public void onCreate(SQLiteDatabase database) {
database.execSQL(DATABASE_CREATE); database.execSQL(DATABASE_CREATE);
} }
// Method is called during an update of the database, e.g. if you increase // Method is called during an update of the database, e.g. if you increase
// the database version // the database version
@Override @Override
public void onUpgrade(SQLiteDatabase database, int oldVersion, public void onUpgrade(SQLiteDatabase database, int oldVersion,
int newVersion) { int newVersion) {
/* Log.w(SSLDroidDbHelper.class.getName(), /* Log.w(SSLDroidDbHelper.class.getName(),
"Upgrading database from version " + oldVersion + " to " "Upgrading database from version " + oldVersion + " to "
+ newVersion + ", which will destroy all old data"); + newVersion + ", which will destroy all old data");
database.execSQL("DROP TABLE IF EXISTS todo"); database.execSQL("DROP TABLE IF EXISTS todo");
onCreate(database); */ onCreate(database); */
} }
} }