aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2008-11-20 21:59:46 +0000
committerKenny Root <kenny@the-b.org>2008-11-20 21:59:46 +0000
commitfedb9892fcf2a5be87ecc4fc0a80584266f68b1b (patch)
tree53a8187d32e04b18dfb63d24e4cdc89c5635a60a /src
parent8c27256ce99583f97ede7994a5e722f1e1da52bb (diff)
downloadconnectbot-fedb9892fcf2a5be87ecc4fc0a80584266f68b1b.tar.gz
connectbot-fedb9892fcf2a5be87ecc4fc0a80584266f68b1b.tar.bz2
connectbot-fedb9892fcf2a5be87ecc4fc0a80584266f68b1b.zip
Convert Pubkey handling to PubkeyBean in preparation for backup/restore functionality
Diffstat (limited to 'src')
-rw-r--r--src/org/connectbot/PortForwardListActivity.java2
-rw-r--r--src/org/connectbot/PubkeyListActivity.java259
-rw-r--r--src/org/connectbot/TerminalView.java52
-rw-r--r--src/org/connectbot/bean/HostBean.java2
-rw-r--r--src/org/connectbot/bean/PubkeyBean.java160
-rw-r--r--src/org/connectbot/service/TerminalManager.java24
-rw-r--r--src/org/connectbot/util/HostDatabase.java2
-rw-r--r--src/org/connectbot/util/PubkeyDatabase.java134
-rw-r--r--src/org/connectbot/util/PubkeyUtils.java4
9 files changed, 425 insertions, 214 deletions
diff --git a/src/org/connectbot/PortForwardListActivity.java b/src/org/connectbot/PortForwardListActivity.java
index 26fe490..81cb2f3 100644
--- a/src/org/connectbot/PortForwardListActivity.java
+++ b/src/org/connectbot/PortForwardListActivity.java
@@ -362,7 +362,7 @@ public class PortForwardListActivity extends ListActivity {
this.portForwards = this.hostdb.getPortForwardsForHost(host);
}
- PortForwardAdapter adapter = new PortForwardAdapter(this, this.portForwards);
+ PortForwardAdapter adapter = new PortForwardAdapter(this, portForwards);
this.setListAdapter(adapter);
}
diff --git a/src/org/connectbot/PubkeyListActivity.java b/src/org/connectbot/PubkeyListActivity.java
index fb3df54..04c57c9 100644
--- a/src/org/connectbot/PubkeyListActivity.java
+++ b/src/org/connectbot/PubkeyListActivity.java
@@ -30,6 +30,7 @@ import java.util.EventListener;
import java.util.LinkedList;
import java.util.List;
+import org.connectbot.bean.PubkeyBean;
import org.connectbot.service.TerminalManager;
import org.connectbot.util.PubkeyDatabase;
import org.connectbot.util.PubkeyUtils;
@@ -42,7 +43,6 @@ import android.content.DialogInterface;
import android.content.Intent;
import android.content.ServiceConnection;
import android.content.DialogInterface.OnClickListener;
-import android.database.Cursor;
import android.os.Bundle;
import android.os.Environment;
import android.os.Handler;
@@ -55,16 +55,16 @@ import android.view.LayoutInflater;
import android.view.Menu;
import android.view.MenuItem;
import android.view.View;
+import android.view.ViewGroup;
import android.view.MenuItem.OnMenuItemClickListener;
import android.widget.AdapterView;
+import android.widget.ArrayAdapter;
import android.widget.EditText;
import android.widget.ImageView;
-import android.widget.SimpleCursorAdapter;
import android.widget.TableRow;
import android.widget.TextView;
import android.widget.Toast;
import android.widget.AdapterView.OnItemClickListener;
-import android.widget.SimpleCursorAdapter.ViewBinder;
import com.trilead.ssh2.crypto.PEMDecoder;
import com.trilead.ssh2.crypto.PEMStructure;
@@ -79,27 +79,27 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
public final static String TAG = PubkeyListActivity.class.toString();
protected PubkeyDatabase pubkeydb;
- private Cursor pubkeys;
+ private List<PubkeyBean> pubkeys;
- private int COL_ID, COL_NICKNAME, COL_TYPE, COL_PRIVATE, COL_PUBLIC, COL_ENCRYPTED, COL_STARTUP;
-
protected ClipboardManager clipboard;
protected LayoutInflater inflater = null;
protected TerminalManager bound = null;
+ private MenuItem onstartToggle = null;
+
private ServiceConnection connection = new ServiceConnection() {
public void onServiceConnected(ComponentName className, IBinder service) {
bound = ((TerminalManager.TerminalBinder) service).getService();
// update our listview binder to find the service
- PubkeyListActivity.this.updateCursor();
+ updateList();
}
public void onServiceDisconnected(ComponentName className) {
bound = null;
- PubkeyListActivity.this.updateCursor();
+ updateList();
}
};
@@ -107,21 +107,21 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
public void onStart() {
super.onStart();
- this.bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE);
+ bindService(new Intent(this, TerminalManager.class), connection, Context.BIND_AUTO_CREATE);
- if(this.pubkeydb == null)
- this.pubkeydb = new PubkeyDatabase(this);
+ if(pubkeydb == null)
+ pubkeydb = new PubkeyDatabase(this);
}
@Override
public void onStop() {
super.onStop();
- this.unbindService(connection);
+ unbindService(connection);
- if(this.pubkeydb != null) {
- this.pubkeydb.close();
- this.pubkeydb = null;
+ if(pubkeydb != null) {
+ pubkeydb.close();
+ pubkeydb = null;
}
}
@@ -135,40 +135,31 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
getResources().getText(R.string.title_pubkey_list)));
// connect with hosts database and populate list
- this.pubkeydb = new PubkeyDatabase(this);
+ pubkeydb = new PubkeyDatabase(this);
- this.updateCursor();
+ updateList();
- this.registerForContextMenu(this.getListView());
+ registerForContextMenu(getListView());
- this.COL_ID = pubkeys.getColumnIndexOrThrow("_id");
- this.COL_NICKNAME = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_NICKNAME);
- this.COL_TYPE = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_TYPE);
- this.COL_PRIVATE = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PRIVATE);
- this.COL_PUBLIC = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PUBLIC);
- this.COL_ENCRYPTED = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_ENCRYPTED);
- this.COL_STARTUP = pubkeys.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_STARTUP);
-
- this.getListView().setOnItemClickListener(new OnItemClickListener() {
+ getListView().setOnItemClickListener(new OnItemClickListener() {
public void onItemClick(AdapterView<?> adapter, View view, int position, long id) {
- Cursor cursor = (Cursor) getListView().getItemAtPosition(position);
- String nickname = cursor.getString(COL_NICKNAME);
- boolean loaded = bound.isKeyLoaded(nickname);
+ PubkeyBean pubkey = (PubkeyBean) getListView().getItemAtPosition(position);
+ boolean loaded = bound.isKeyLoaded(pubkey.getNickname());
// handle toggling key in-memory on/off
if(loaded) {
- bound.removeKey(nickname);
+ bound.removeKey(pubkey.getNickname());
updateHandler.sendEmptyMessage(-1);
} else {
- handleAddKey(cursor);
+ handleAddKey(pubkey);
}
}
});
- this.clipboard = (ClipboardManager)this.getSystemService(CLIPBOARD_SERVICE);
+ clipboard = (ClipboardManager)getSystemService(CLIPBOARD_SERVICE);
- this.inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
+ inflater = (LayoutInflater)getSystemService(Context.LAYOUT_INFLATER_SERVICE);
}
/**
@@ -269,10 +260,8 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
return true;
}
- protected void handleAddKey(final Cursor c) {
- int encrypted = c.getInt(COL_ENCRYPTED);
-
- if(encrypted != 0) {
+ protected void handleAddKey(final PubkeyBean pubkey) {
+ if(!pubkey.isEncrypted()) {
final View view = inflater.inflate(R.layout.dia_password, null);
final EditText passwordField = (EditText)view.findViewById(android.R.id.text1);
@@ -280,26 +269,23 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
.setView(view)
.setPositiveButton(R.string.pubkey_unlock, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
- handleAddKey(c, passwordField.getText().toString());
+ handleAddKey(pubkey, passwordField.getText().toString());
}
})
.setNegativeButton(android.R.string.cancel, null).create().show();
} else {
- handleAddKey(c, null);
+ handleAddKey(pubkey, null);
}
}
- protected void handleAddKey(Cursor c, String password) {
- String keyNickname = c.getString(COL_NICKNAME);
+ protected void handleAddKey(PubkeyBean pubkey, String password) {
Object trileadKey = null;
- String type = c.getString(COL_TYPE);
- if(PubkeyDatabase.KEY_TYPE_IMPORTED.equals(type)) {
+ if(PubkeyDatabase.KEY_TYPE_IMPORTED.equals(pubkey.getType())) {
// load specific key using pem format
- byte[] raw = c.getBlob(COL_PRIVATE);
try {
- trileadKey = PEMDecoder.decode(new String(raw).toCharArray(), password);
+ trileadKey = PEMDecoder.decode(new String(pubkey.getPrivateKey()).toCharArray(), password);
} catch(Exception e) {
- String message = getResources().getString(R.string.pubkey_failed_add, keyNickname);
+ String message = getResources().getString(R.string.pubkey_failed_add, pubkey.getNickname());
Log.e(TAG, message, e);
Toast.makeText(PubkeyListActivity.this, message, Toast.LENGTH_LONG);
}
@@ -309,10 +295,10 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
PrivateKey privKey = null;
PublicKey pubKey = null;
try {
- privKey = PubkeyUtils.decodePrivate(c.getBlob(COL_PRIVATE), c.getString(COL_TYPE), password);
- pubKey = PubkeyUtils.decodePublic(c.getBlob(COL_PUBLIC), c.getString(COL_TYPE));
+ privKey = PubkeyUtils.decodePrivate(pubkey.getPrivateKey(), pubkey.getType(), password);
+ pubKey = PubkeyUtils.decodePublic(pubkey.getPublicKey(), pubkey.getType());
} catch (Exception e) {
- String message = getResources().getString(R.string.pubkey_failed_add, keyNickname);
+ String message = getResources().getString(R.string.pubkey_failed_add, pubkey.getNickname());
Log.e(TAG, message, e);
Toast.makeText(PubkeyListActivity.this, message, Toast.LENGTH_LONG);
}
@@ -324,50 +310,39 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
if(trileadKey == null) return;
- Log.d(TAG, String.format("Unlocked key '%s'", keyNickname));
+ Log.d(TAG, String.format("Unlocked key '%s'", pubkey.getNickname()));
// save this key in-memory if option enabled
if(bound.isSavingKeys()) {
- bound.addKey(keyNickname, trileadKey);
+ bound.addKey(pubkey.getNickname(), trileadKey);
}
updateHandler.sendEmptyMessage(-1);
-
-
}
- private MenuItem onstartToggle = null;
-
@Override
public void onCreateContextMenu(ContextMenu menu, View v, ContextMenu.ContextMenuInfo menuInfo) {
// Create menu to handle deleting and editing pubkey
AdapterView.AdapterContextMenuInfo info = (AdapterView.AdapterContextMenuInfo) menuInfo;
- final Cursor cursor = (Cursor) this.getListView().getItemAtPosition(info.position);
+ final PubkeyBean pubkey = (PubkeyBean) getListView().getItemAtPosition(info.position);
- final String nickname = cursor.getString(COL_NICKNAME);
- menu.setHeaderTitle(nickname);
+ menu.setHeaderTitle(pubkey.getNickname());
// TODO: option load/unload key from in-memory list
// prompt for password as needed for passworded keys
- final long id = cursor.getLong(COL_ID);
- final byte[] pubkeyEncoded = cursor.getBlob(COL_PUBLIC);
- final String keyType = cursor.getString(COL_TYPE);
- final int encrypted = cursor.getInt(COL_ENCRYPTED);
-
// cant change password or clipboard imported keys
- boolean imported = PubkeyDatabase.KEY_TYPE_IMPORTED.equals(cursor.getString(COL_TYPE));
- final boolean loaded = bound.isKeyLoaded(nickname);
- final boolean onstart = (cursor.getInt(COL_STARTUP) == 1);
+ boolean imported = PubkeyDatabase.KEY_TYPE_IMPORTED.equals(pubkey.getType());
+ final boolean loaded = bound.isKeyLoaded(pubkey.getNickname());
MenuItem load = menu.add(loaded ? R.string.pubkey_memory_unload : R.string.pubkey_memory_load);
load.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
if(loaded) {
- bound.removeKey(nickname);
+ bound.removeKey(pubkey.getNickname());
updateHandler.sendEmptyMessage(-1);
} else {
- handleAddKey(cursor);
+ handleAddKey(pubkey);
//bound.addKey(nickname, trileadKey);
}
return true;
@@ -375,13 +350,14 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
});
onstartToggle = menu.add(R.string.pubkey_load_on_start);
- onstartToggle.setEnabled((encrypted == 0));
+ onstartToggle.setEnabled(!pubkey.isEncrypted());
onstartToggle.setCheckable(true);
- onstartToggle.setChecked(onstart);
+ onstartToggle.setChecked(pubkey.isStartup());
onstartToggle.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// toggle onstart status
- pubkeydb.setOnStart(id, !onstart);
+ pubkey.setStartup(!pubkey.isStartup());
+ pubkeydb.savePubkey(pubkey);
updateHandler.sendEmptyMessage(-1);
return true;
}
@@ -390,15 +366,15 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
MenuItem copyToClipboard = menu.add(R.string.pubkey_copy_clipboard);
copyToClipboard.setEnabled(!imported);
copyToClipboard.setOnMenuItemClickListener(new OnMenuItemClickListener() {
- public boolean onMenuItemClick(MenuItem item) {
- try {
- PublicKey pk = PubkeyUtils.decodePublic(pubkeyEncoded, keyType);
+ public boolean onMenuItemClick(MenuItem item) {
+ try {
+ PublicKey pk = PubkeyUtils.decodePublic(pubkey.getPublicKey(), pubkey.getType());
String openSSHPubkey = new String(PubkeyUtils.convertToOpenSSHFormat(pk));
clipboard.setText(openSSHPubkey);
} catch (Exception e) {
e.printStackTrace();
- }
+ }
return true;
}
});
@@ -409,7 +385,7 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
public boolean onMenuItemClick(MenuItem item) {
final View changePasswordView = inflater.inflate(R.layout.dia_changepassword, null, false);
((TableRow)changePasswordView.findViewById(R.id.old_password_prompt))
- .setVisibility(encrypted != 0 ? View.VISIBLE : View.GONE);
+ .setVisibility(pubkey.isEncrypted() ? View.VISIBLE : View.GONE);
new AlertDialog.Builder(PubkeyListActivity.this)
.setView(changePasswordView)
.setPositiveButton(R.string.button_change, new DialogInterface.OnClickListener() {
@@ -427,13 +403,15 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
}
try {
- if (!pubkeydb.changePassword(id, oldPassword, password1))
+ if (!pubkey.changePassword(oldPassword, password1))
new AlertDialog.Builder(PubkeyListActivity.this)
.setMessage(R.string.alert_wrong_password_msg)
.setPositiveButton(android.R.string.ok, null)
.create().show();
- else
+ else {
+ pubkeydb.savePubkey(pubkey);
updateHandler.sendEmptyMessage(-1);
+ }
} catch (Exception e) {
Log.e(TAG, "Could not change private key password", e);
new AlertDialog.Builder(PubkeyListActivity.this)
@@ -454,16 +432,16 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
public boolean onMenuItemClick(MenuItem item) {
// prompt user to make sure they really want this
new AlertDialog.Builder(PubkeyListActivity.this)
- .setMessage(getString(R.string.delete_message, nickname))
+ .setMessage(getString(R.string.delete_message, pubkey.getNickname()))
.setPositiveButton(R.string.delete_pos, new DialogInterface.OnClickListener() {
public void onClick(DialogInterface dialog, int which) {
// dont forget to remove from in-memory
if(loaded)
- bound.removeKey(nickname);
+ bound.removeKey(pubkey.getNickname());
// delete from backend database and update gui
- pubkeydb.deletePubkey(id);
+ pubkeydb.deletePubkey(pubkey);
updateHandler.sendEmptyMessage(-1);
}
})
@@ -479,86 +457,71 @@ public class PubkeyListActivity extends ListActivity implements EventListener {
protected Handler updateHandler = new Handler() {
@Override
public void handleMessage(Message msg) {
- PubkeyListActivity.this.updateCursor();
+ updateList();
}
};
- protected void updateCursor() {
- if (this.pubkeys != null)
- pubkeys.close();
- //pubkeys.requery();
-
- if (this.pubkeydb == null) return;
+ protected void updateList() {
+ if (pubkeydb == null) return;
- this.pubkeys = this.pubkeydb.allPubkeys();
+ pubkeys = pubkeydb.allPubkeys();
+ PubkeyAdapter adapter = new PubkeyAdapter(this, pubkeys);
- SimpleCursorAdapter adapter = new SimpleCursorAdapter(this, R.layout.item_pubkey, this.pubkeys,
- new String[] { PubkeyDatabase.FIELD_PUBKEY_NICKNAME, PubkeyDatabase.FIELD_PUBKEY_TYPE, PubkeyDatabase.FIELD_PUBKEY_ENCRYPTED },
- new int[] { android.R.id.text1, android.R.id.text2, android.R.id.icon1 });
- adapter.setViewBinder(new PubkeyBinder());
this.setListAdapter(adapter);
-
- //this.startManagingCursor(pubkeys);
}
- class PubkeyBinder implements ViewBinder {
- public boolean setViewValue(View view, Cursor cursor, int columnIndex) {
- switch (view.getId()) {
- case android.R.id.text2:
- int encrypted = cursor.getInt(cursor.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_ENCRYPTED));
- boolean imported = PubkeyDatabase.KEY_TYPE_IMPORTED.equals(cursor.getString(COL_TYPE));
- TextView caption = (TextView)view;
-
- if(imported) {
- // for imported keys, have trilead parse them to get stats
- try {
- byte[] raw = cursor.getBlob(cursor.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PRIVATE));
- PEMStructure struct = PEMDecoder.parsePEM(new String(raw).toCharArray());
- String type = (struct.pemType == PEMDecoder.PEM_RSA_PRIVATE_KEY) ? "RSA" : "DSA";
- caption.setText(String.format("%s unknown-bit", type));
- } catch (IOException e) {
- Log.e(TAG, "Error decoding IMPORTED public key at " + cursor.toString(), e);
- }
-
-
- } else {
-
- try {
- PublicKey pub = PubkeyUtils.decodePublic(cursor.getBlob(cursor.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PUBLIC)),
- cursor.getString(columnIndex));
- caption.setText(PubkeyUtils.describeKey(pub, encrypted));
- } catch (Exception e) {
- Log.e(TAG, "Error decoding public key at " + cursor.toString(), e);
- caption.setText(R.string.pubkey_unknown_format);
- }
+ class PubkeyAdapter extends ArrayAdapter<PubkeyBean> {
+ private List<PubkeyBean> pubkeys;
+
+ public PubkeyAdapter(Context context, List<PubkeyBean> pubkeys) {
+ super(context, R.layout.item_pubkey, pubkeys);
+
+ this.pubkeys = pubkeys;
+ }
+
+ public View getView(int position, View view, ViewGroup parent) {
+ if (view == null)
+ view = inflater.inflate(R.layout.item_portforward, null, false);
+
+ TextView nickname = (TextView)view.findViewById(android.R.id.text1);
+ TextView caption = (TextView)view.findViewById(android.R.id.text2);
+ ImageView icon = (ImageView)view.findViewById(android.R.id.icon1);
+
+ PubkeyBean pubkey = pubkeys.get(position);
+ nickname.setText(pubkey.getNickname());
+
+ boolean imported = PubkeyDatabase.KEY_TYPE_IMPORTED.equals(pubkey.getType());
+
+ if (imported) {
+ try {
+ PEMStructure struct = PEMDecoder.parsePEM(new String(pubkey.getPrivateKey()).toCharArray());
+ String type = (struct.pemType == PEMDecoder.PEM_RSA_PRIVATE_KEY) ? "RSA" : "DSA";
+ caption.setText(String.format("%s unknown-bit", type));
+ } catch (IOException e) {
+ Log.e(TAG, "Error decoding IMPORTED public key at " + pubkey.getId(), e);
}
-
- return true;
-
- case android.R.id.icon1:
-
- ImageView icon = (ImageView)view;
- if(bound == null) {
- icon.setVisibility(View.GONE);
- return true;
-
- } else {
- icon.setVisibility(View.VISIBLE);
-
+ } else {
+ try {
+ PublicKey pub = PubkeyUtils.decodePublic(pubkey.getPublicKey(), pubkey.getType());
+ caption.setText(PubkeyUtils.describeKey(pub, pubkey.isEncrypted()));
+ } catch (Exception e) {
+ Log.e(TAG, "Error decoding public key at " + pubkey.getId(), e);
+ caption.setText(R.string.pubkey_unknown_format);
}
-
- // read key in-memory status from backend terminalmanager
- String nickname = cursor.getString(COL_NICKNAME);
- boolean loaded = bound.isKeyLoaded(nickname);
-
- if(loaded)
+ }
+
+ if (bound == null) {
+ icon.setVisibility(View.GONE);
+ } else {
+ icon.setVisibility(View.VISIBLE);
+
+ if (bound.isKeyLoaded(pubkey.getNickname()))
icon.setImageState(new int[] { android.R.attr.state_checked }, true);
else
icon.setImageState(new int[] { }, true);
- return true;
}
- return false;
- }
+ return view;
+ }
}
}
diff --git a/src/org/connectbot/TerminalView.java b/src/org/connectbot/TerminalView.java
index ea8c229..dfcd6f8 100644
--- a/src/org/connectbot/TerminalView.java
+++ b/src/org/connectbot/TerminalView.java
@@ -49,10 +49,10 @@ public class TerminalView extends View {
protected int top = -1, bottom = -1, left = -1, right = -1;
public void resetSelected() {
- this.top = -1;
- this.bottom = -1;
- this.left = -1;
- this.right = -1;
+ top = -1;
+ bottom = -1;
+ left = -1;
+ right = -1;
}
public TerminalView(Context context, TerminalBridge bridge) {
@@ -60,56 +60,56 @@ public class TerminalView extends View {
this.context = context;
this.bridge = bridge;
- this.paint = new Paint();
+ paint = new Paint();
- this.setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
- this.setFocusable(true);
- this.setFocusableInTouchMode(true);
+ setLayoutParams(new LayoutParams(LayoutParams.FILL_PARENT, LayoutParams.FILL_PARENT));
+ setFocusable(true);
+ setFocusableInTouchMode(true);
- this.cursorPaint = new Paint();
- this.cursorPaint.setColor(bridge.color[TerminalBridge.COLOR_FG_STD]);
- this.cursorPaint.setXfermode(new PixelXorXfermode(bridge.color[TerminalBridge.COLOR_BG_STD]));
+ cursorPaint = new Paint();
+ cursorPaint.setColor(bridge.color[TerminalBridge.COLOR_FG_STD]);
+ cursorPaint.setXfermode(new PixelXorXfermode(bridge.color[TerminalBridge.COLOR_BG_STD]));
// connect our view up to the bridge
- this.setOnKeyListener(bridge);
+ setOnKeyListener(bridge);
}
public void destroy() {
// tell bridge to destroy its bitmap
- this.bridge.parentDestroyed();
+ bridge.parentDestroyed();
}
@Override
protected void onSizeChanged(int w, int h, int oldw, int oldh) {
super.onSizeChanged(w, h, oldw, oldh);
- this.bridge.parentChanged(this);
+ bridge.parentChanged(this);
}
@Override
public void onDraw(Canvas canvas) {
- if(this.bridge.bitmap != null) {
+ if(bridge.bitmap != null) {
// draw the bridge bitmap if it exists
- canvas.drawBitmap(this.bridge.bitmap, 0, 0, this.paint);
+ canvas.drawBitmap(bridge.bitmap, 0, 0, paint);
// also draw cursor if visible
- if(this.bridge.buffer.isCursorVisible()) {
- int x = this.bridge.buffer.getCursorColumn() * this.bridge.charWidth;
- int y = (this.bridge.buffer.getCursorRow()
- + this.bridge.buffer.screenBase - this.bridge.buffer.windowBase)
- * this.bridge.charHeight;
+ if(bridge.buffer.isCursorVisible()) {
+ int x = bridge.buffer.getCursorColumn() * bridge.charWidth;
+ int y = (bridge.buffer.getCursorRow()
+ + bridge.buffer.screenBase - bridge.buffer.windowBase)
+ * bridge.charHeight;
- canvas.drawRect(x, y, x + this.bridge.charWidth,
- y + this.bridge.charHeight, cursorPaint);
+ canvas.drawRect(x, y, x + bridge.charWidth,
+ y + bridge.charHeight, cursorPaint);
}
// draw any highlighted area
if(top >= 0 && bottom >= 0 && left >= 0 && right >= 0) {
- canvas.drawRect(left * this.bridge.charWidth, top * this.bridge.charHeight,
- right * this.bridge.charWidth, bottom * this.bridge.charHeight, cursorPaint);
+ canvas.drawRect(left * bridge.charWidth, top * bridge.charHeight,
+ right * bridge.charWidth, bottom * bridge.charHeight, cursorPaint);
}
}
@@ -138,6 +138,6 @@ public class TerminalView extends View {
* @param height
*/
public void forceSize(int width, int height) {
- this.bridge.resizeComputed(width, height, getWidth(), getHeight());
+ bridge.resizeComputed(width, height, getWidth(), getHeight());
}
}
diff --git a/src/org/connectbot/bean/HostBean.java b/src/org/connectbot/bean/HostBean.java
index 3ee48d5..7e6966b 100644
--- a/src/org/connectbot/bean/HostBean.java
+++ b/src/org/connectbot/bean/HostBean.java
@@ -22,7 +22,7 @@ import org.connectbot.util.HostDatabase;
import android.content.ContentValues;
/**
- * @author kenny
+ * @author Kenny Root
*
*/
public class HostBean extends AbstractBean {
diff --git a/src/org/connectbot/bean/PubkeyBean.java b/src/org/connectbot/bean/PubkeyBean.java
new file mode 100644
index 0000000..2e5606d
--- /dev/null
+++ b/src/org/connectbot/bean/PubkeyBean.java
@@ -0,0 +1,160 @@
+/*
+ ConnectBot: simple, powerful, open-source SSH client for Android
+ Copyright (C) 2007-2008 Kenny Root, Jeffrey Sharkey
+
+ This program is free software: you can redistribute it and/or modify
+ it under the terms of the GNU General Public License as published by
+ the Free Software Foundation, either version 3 of the License, or
+ (at your option) any later version.
+
+ This program is distributed in the hope that it will be useful,
+ but WITHOUT ANY WARRANTY; without even the implied warranty of
+ MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+ GNU General Public License for more details.
+
+ You should have received a copy of the GNU General Public License
+ along with this program. If not, see <http://www.gnu.org/licenses/>.
+*/
+package org.connectbot.bean;
+
+import java.security.InvalidKeyException;
+import java.security.NoSuchAlgorithmException;
+import java.security.PrivateKey;
+import java.security.spec.InvalidKeySpecException;
+
+import javax.crypto.BadPaddingException;
+import javax.crypto.IllegalBlockSizeException;
+import javax.crypto.NoSuchPaddingException;
+
+import org.connectbot.util.PubkeyDatabase;
+import org.connectbot.util.PubkeyUtils;
+
+import android.content.ContentValues;
+
+/**
+ * @author Kenny Root
+ *
+ */
+public class PubkeyBean extends AbstractBean {
+ /* Database fields */
+ private long id;
+ private String nickname;
+ private String type;
+ private byte[] privateKey;
+ private byte[] publicKey;
+ private boolean encrypted;
+ private boolean startup;
+
+ /* Transient values */
+ private boolean unlocked = false;
+ private Object unlockedPrivate = null;
+
+ public void setId(long id) {
+ this.id = id;
+ }
+
+ public long getId() {
+ return id;
+ }
+
+ public void setNickname(String nickname) {
+ this.nickname = nickname;
+ }
+
+ public String getNickname() {
+ return nickname;
+ }
+
+ public void setType(String type) {
+ this.type = type;
+ }
+
+ public String getType() {
+ return type;
+ }
+
+ public void setPrivateKey(byte[] privateKey) {
+ this.privateKey = privateKey;
+ }
+
+ public byte[] getPrivateKey() {
+ return privateKey;
+ }
+
+ public void setPublicKey(byte[] publicKey) {
+ this.publicKey = publicKey;
+ }
+
+ public byte[] getPublicKey() {
+ return publicKey;
+ }
+
+ public void setEncrypted(boolean encrypted) {
+ this.encrypted = encrypted;
+ }
+
+ public boolean isEncrypted() {
+ return encrypted;
+ }
+
+ public void setStartup(boolean startup) {
+ this.startup = startup;
+ }
+
+ public boolean isStartup() {
+ return startup;
+ }
+
+ public void setUnlocked(boolean unlocked) {
+ this.unlocked = unlocked;
+ }
+
+ public boolean isUnlocked() {
+ return unlocked;
+ }
+
+ public void setUnlockedPrivate(Object unlockedPrivate) {
+ this.unlockedPrivate = unlockedPrivate;
+ }
+
+ public Object getUnlockedPrivate() {
+ return unlockedPrivate;
+ }
+
+ /* (non-Javadoc)
+ * @see org.connectbot.bean.AbstractBean#getValues()
+ */
+ @Override
+ public ContentValues getValues() {
+ ContentValues values = new ContentValues();
+
+ values.put("_id", id);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_NICKNAME, nickname);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_TYPE, type);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_PRIVATE, privateKey);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_PUBLIC, publicKey);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_ENCRYPTED, encrypted ? 1 : 0);
+ values.put(PubkeyDatabase.FIELD_PUBKEY_STARTUP, startup ? 1 : 0);
+
+ return values;
+ }
+
+ public boolean changePassword(String oldPassword, String newPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException {
+ PrivateKey priv;
+
+ try {
+ priv = PubkeyUtils.decodePrivate(getPrivateKey(), getType(), oldPassword);
+ } catch (InvalidKeyException e) {
+ return false;
+ } catch (BadPaddingException e) {
+ return false;
+ } catch (InvalidKeySpecException e) {
+ return false;
+ }
+
+ setPrivateKey(PubkeyUtils.getEncodedPrivate(priv, newPassword));
+ setEncrypted(newPassword.length() > 0);
+
+ return true;
+ }
+}
diff --git a/src/org/connectbot/service/TerminalManager.java b/src/org/connectbot/service/TerminalManager.java
index a316936..bc2ecba 100644
--- a/src/org/connectbot/service/TerminalManager.java
+++ b/src/org/connectbot/service/TerminalManager.java
@@ -26,6 +26,7 @@ import java.util.List;
import org.connectbot.R;
import org.connectbot.bean.HostBean;
+import org.connectbot.bean.PubkeyBean;
import org.connectbot.util.HostDatabase;
import org.connectbot.util.PubkeyDatabase;
import org.connectbot.util.PubkeyUtils;
@@ -34,7 +35,6 @@ import android.app.Service;
import android.content.Intent;
import android.content.SharedPreferences;
import android.content.res.Resources;
-import android.database.Cursor;
import android.net.Uri;
import android.os.Binder;
import android.os.Handler;
@@ -84,28 +84,20 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
this.pubkeydb = new PubkeyDatabase(this);
// load all marked pubkeys into memory
- Cursor c = pubkeydb.getAllStartPubkeys();
- int COL_NICKNAME = c.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_NICKNAME),
- COL_TYPE = c.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_TYPE),
- COL_PRIVATE = c.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PRIVATE),
- COL_PUBLIC = c.getColumnIndexOrThrow(PubkeyDatabase.FIELD_PUBKEY_PUBLIC);
+ List<PubkeyBean> pubkeys = pubkeydb.getAllStartPubkeys();
- while(c.moveToNext()) {
- String keyNickname = c.getString(COL_NICKNAME);
+ for (PubkeyBean pubkey : pubkeys) {
try {
- PrivateKey privKey = PubkeyUtils.decodePrivate(c.getBlob(COL_PRIVATE), c.getString(COL_TYPE));
- PublicKey pubKey = PubkeyUtils.decodePublic(c.getBlob(COL_PUBLIC), c.getString(COL_TYPE));
+ PrivateKey privKey = PubkeyUtils.decodePrivate(pubkey.getPrivateKey(), pubkey.getType());
+ PublicKey pubKey = PubkeyUtils.decodePublic(pubkey.getPublicKey(), pubkey.getType());
Object trileadKey = PubkeyUtils.convertToTrilead(privKey, pubKey);
- this.loadedPubkeys.put(keyNickname, trileadKey);
- Log.d(TAG, String.format("Added key '%s' to in-memory cache", keyNickname));
+ this.loadedPubkeys.put(pubkey.getNickname(), trileadKey);
+ Log.d(TAG, String.format("Added key '%s' to in-memory cache", pubkey.getNickname()));
} catch (Exception e) {
- Log.d(TAG, String.format("Problem adding key '%s' to in-memory cache", keyNickname), e);
+ Log.d(TAG, String.format("Problem adding key '%s' to in-memory cache", pubkey.getNickname()), e);
}
}
- c.close();
-
-
}
@Override
diff --git a/src/org/connectbot/util/HostDatabase.java b/src/org/connectbot/util/HostDatabase.java
index 0ccf5c0..91472ea 100644
--- a/src/org/connectbot/util/HostDatabase.java
+++ b/src/org/connectbot/util/HostDatabase.java
@@ -205,7 +205,7 @@ public class HostDatabase extends SQLiteOpenHelper {
Cursor c = db.query(TABLE_HOSTS, null, null, null, null, null, sortField + " ASC");
- int COL_ID = c.getColumnIndexOrThrow("_id"),
+ final int COL_ID = c.getColumnIndexOrThrow("_id"),
COL_NICKNAME = c.getColumnIndexOrThrow(FIELD_HOST_NICKNAME),
COL_USERNAME = c.getColumnIndexOrThrow(FIELD_HOST_USERNAME),
COL_HOSTNAME = c.getColumnIndexOrThrow(FIELD_HOST_HOSTNAME),
diff --git a/src/org/connectbot/util/PubkeyDatabase.java b/src/org/connectbot/util/PubkeyDatabase.java
index f7228b2..685c960 100644
--- a/src/org/connectbot/util/PubkeyDatabase.java
+++ b/src/org/connectbot/util/PubkeyDatabase.java
@@ -18,16 +18,10 @@
package org.connectbot.util;
-import java.security.InvalidKeyException;
-import java.security.NoSuchAlgorithmException;
-import java.security.PrivateKey;
-import java.security.spec.InvalidKeySpecException;
import java.util.LinkedList;
import java.util.List;
-import javax.crypto.BadPaddingException;
-import javax.crypto.IllegalBlockSizeException;
-import javax.crypto.NoSuchPaddingException;
+import org.connectbot.bean.PubkeyBean;
import android.content.ContentValues;
import android.content.Context;
@@ -39,10 +33,9 @@ import android.database.sqlite.SQLiteOpenHelper;
* Public Key Encryption database. Contains private and public key pairs
* for public key authentication.
*
- * @author kroot
+ * @author Kenny Root
*/
-public class PubkeyDatabase extends SQLiteOpenHelper {
-
+public class PubkeyDatabase extends SQLiteOpenHelper {
public final static String TAG = PubkeyDatabase.class.toString();
public final static String DB_NAME = "pubkeys";
@@ -110,24 +103,69 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
/**
* Delete a specific host by its <code>_id</code> value.
*/
- public void deletePubkey(long id) {
- SQLiteDatabase db = this.getWritableDatabase();
- db.delete(TABLE_PUBKEYS, "_id = ?", new String[] { Long.toString(id) });
-
+ public void deletePubkey(PubkeyBean pubkey) {
HostDatabase hostdb = new HostDatabase(context);
- hostdb.stopUsingPubkey(id);
+ hostdb.stopUsingPubkey(pubkey.getId());
hostdb.close();
+
+ SQLiteDatabase db = getWritableDatabase();
+ db.delete(TABLE_PUBKEYS, "_id = ?", new String[] { Long.toString(pubkey.getId()) });
+ db.close();
}
/**
* Return a cursor that contains information about all known hosts.
*/
+ /*
public Cursor allPubkeys() {
SQLiteDatabase db = this.getReadableDatabase();
return db.query(TABLE_PUBKEYS, new String[] { "_id",
FIELD_PUBKEY_NICKNAME, FIELD_PUBKEY_TYPE, FIELD_PUBKEY_PRIVATE,
FIELD_PUBKEY_PUBLIC, FIELD_PUBKEY_ENCRYPTED, FIELD_PUBKEY_STARTUP },
null, null, null, null, null);
+ }*/
+
+ public List<PubkeyBean> allPubkeys() {
+ return getPubkeys(null, null);
+ }
+
+ public List<PubkeyBean> getAllStartPubkeys() {
+ return getPubkeys(FIELD_PUBKEY_STARTUP + " = 1 AND " + FIELD_PUBKEY_ENCRYPTED + " = 0", null);
+ }
+
+ private List<PubkeyBean> getPubkeys(String selection, String[] selectionArgs) {
+ SQLiteDatabase db = getReadableDatabase();
+
+ List<PubkeyBean> pubkeys = new LinkedList<PubkeyBean>();
+
+ Cursor c = db.query(TABLE_PUBKEYS, null, selection, selectionArgs, null, null, null);
+
+ final int COL_ID = c.getColumnIndexOrThrow("_id"),
+ COL_NICKNAME = c.getColumnIndexOrThrow(FIELD_PUBKEY_NICKNAME),
+ COL_TYPE = c.getColumnIndexOrThrow(FIELD_PUBKEY_TYPE),
+ COL_PRIVATE = c.getColumnIndexOrThrow(FIELD_PUBKEY_PRIVATE),
+ COL_PUBLIC = c.getColumnIndexOrThrow(FIELD_PUBKEY_PUBLIC),
+ COL_ENCRYPTED = c.getColumnIndexOrThrow(FIELD_PUBKEY_ENCRYPTED),
+ COL_STARTUP = c.getColumnIndexOrThrow(FIELD_PUBKEY_STARTUP);
+
+ while (c.moveToNext()) {
+ PubkeyBean pubkey = new PubkeyBean();
+
+ pubkey.setId(c.getLong(COL_ID));
+ pubkey.setNickname(c.getString(COL_NICKNAME));
+ pubkey.setType(c.getString(COL_TYPE));
+ pubkey.setPrivateKey(c.getBlob(COL_PRIVATE));
+ pubkey.setPublicKey(c.getBlob(COL_PUBLIC));
+ pubkey.setEncrypted(Boolean.valueOf(c.getString(COL_ENCRYPTED)));
+ pubkey.setStartup(Boolean.valueOf(c.getString(COL_STARTUP)));
+
+ pubkeys.add(pubkey);
+ }
+
+ c.close();
+ db.close();
+
+ return pubkeys;
}
public Cursor getPubkey(long id) {
@@ -139,14 +177,50 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
null, null, null);
}
- public Cursor getAllStartPubkeys() {
+ /*public Cursor getAllStartPubkeys() {
SQLiteDatabase db = this.getReadableDatabase();
return db.query(TABLE_PUBKEYS, new String[] { "_id",
FIELD_PUBKEY_NICKNAME, FIELD_PUBKEY_TYPE, FIELD_PUBKEY_PRIVATE,
FIELD_PUBKEY_PUBLIC, FIELD_PUBKEY_ENCRYPTED, FIELD_PUBKEY_STARTUP },
FIELD_PUBKEY_STARTUP + " = 1 AND " + FIELD_PUBKEY_ENCRYPTED + " = 0", null, null, null, null);
+ }*/
+
+ /**
+ * @param hostId
+ * @return
+ */
+ public PubkeyBean findPubkeyById(long pubkeyId) {
+ SQLiteDatabase db = getReadableDatabase();
+
+ Cursor c = db.query(TABLE_PUBKEYS, null,
+ "_id = ?", new String[] { String.valueOf(pubkeyId) },
+ null, null, null);
+
+ PubkeyBean pubkey = null;
+
+ if (c != null && c.moveToFirst()) {
+ pubkey = createPubkeyBean(c);
+ }
+
+ c.close();
+ db.close();
+
+ return pubkey;
}
+ private PubkeyBean createPubkeyBean(Cursor c) {
+ PubkeyBean pubkey = new PubkeyBean();
+
+ pubkey.setId(c.getLong(c.getColumnIndexOrThrow("_id")));
+ pubkey.setNickname(c.getString(c.getColumnIndexOrThrow(FIELD_PUBKEY_NICKNAME)));
+ pubkey.setType(c.getString(c.getColumnIndexOrThrow(FIELD_PUBKEY_TYPE)));
+ pubkey.setPrivateKey(c.getBlob(c.getColumnIndexOrThrow(FIELD_PUBKEY_PRIVATE)));
+ pubkey.setPublicKey(c.getBlob(c.getColumnIndexOrThrow(FIELD_PUBKEY_PUBLIC)));
+ pubkey.setEncrypted(Boolean.valueOf(c.getString(c.getColumnIndexOrThrow(FIELD_PUBKEY_ENCRYPTED))));
+ pubkey.setStartup(Boolean.valueOf(c.getString(c.getColumnIndexOrThrow(FIELD_PUBKEY_STARTUP))));
+
+ return pubkey;
+ }
/**
* Pull all values for a given column as a list of Strings, probably for use
@@ -167,7 +241,7 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
return list;
}
-
+
public String getNickname(long id) {
String nickname = null;
@@ -183,7 +257,7 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
return nickname;
}
-
+/*
public void setOnStart(long id, boolean onStart) {
SQLiteDatabase db = this.getWritableDatabase();
@@ -195,7 +269,6 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
}
-
public boolean changePassword(long id, String oldPassword, String newPassword) throws NoSuchAlgorithmException, NoSuchPaddingException, IllegalBlockSizeException, InvalidKeyException, BadPaddingException {
SQLiteDatabase db = this.getWritableDatabase();
@@ -229,5 +302,28 @@ public class PubkeyDatabase extends SQLiteOpenHelper {
return true;
}
+ */
+
+ /**
+ * @param pubkey
+ */
+ public PubkeyBean savePubkey(PubkeyBean pubkey) {
+ SQLiteDatabase db = this.getWritableDatabase();
+ boolean success = false;
+ ContentValues values = pubkey.getValues();
+ if (pubkey.getId() > 0) {
+ values.remove("_id");
+ if (db.update(TABLE_PUBKEYS, values, "_id = ?", new String[] { String.valueOf(pubkey.getId()) }) > 0)
+ success = true;
+ }
+
+ if (!success) {
+ long id = db.insert(TABLE_PUBKEYS, null, pubkey.getValues());
+ pubkey.setId(id);
+ }
+
+ db.close();
+ return pubkey;
+ }
}
diff --git a/src/org/connectbot/util/PubkeyUtils.java b/src/org/connectbot/util/PubkeyUtils.java
index 8702987..e13129e 100644
--- a/src/org/connectbot/util/PubkeyUtils.java
+++ b/src/org/connectbot/util/PubkeyUtils.java
@@ -54,7 +54,7 @@ public class PubkeyUtils {
", bytes=" + encoded.length + "]";
}
- public static String describeKey(Key key, int encrypted) {
+ public static String describeKey(Key key, boolean encrypted) {
String desc = null;
if (key instanceof RSAPublicKey) {
int bits = ((RSAPublicKey)key).getModulus().bitLength();
@@ -65,7 +65,7 @@ public class PubkeyUtils {
desc = "Unknown Key Type";
}
- if (encrypted != 0)
+ if (encrypted)
desc += " (encrypted)";
return desc;