aboutsummaryrefslogtreecommitdiffstats
path: root/src
diff options
context:
space:
mode:
authorKenny Root <kenny@the-b.org>2008-11-10 01:48:15 +0000
committerKenny Root <kenny@the-b.org>2008-11-10 01:48:15 +0000
commit91634b9e90b8b6581cf949026734b0bdf20a3026 (patch)
tree1a6548b59a0d526d3c954abab737c9de4c46054c /src
parent69accfe08fadf4712ec6e1d38a7f2c7410bcba44 (diff)
downloadconnectbot-91634b9e90b8b6581cf949026734b0bdf20a3026.tar.gz
connectbot-91634b9e90b8b6581cf949026734b0bdf20a3026.tar.bz2
connectbot-91634b9e90b8b6581cf949026734b0bdf20a3026.zip
* Allow user to have a port-forward-only connection to a host (similar to OpenSSH's -N option)
* Fixed bug with adding port forwards * Fixed bug where we crash if connection goes away while we're initializing the ConsoleActivity
Diffstat (limited to 'src')
-rw-r--r--src/org/connectbot/ConsoleActivity.java39
-rw-r--r--src/org/connectbot/PortForwardListActivity.java25
-rw-r--r--src/org/connectbot/service/TerminalBridge.java93
-rw-r--r--src/org/connectbot/service/TerminalManager.java4
-rw-r--r--src/org/connectbot/util/HostDatabase.java42
5 files changed, 162 insertions, 41 deletions
diff --git a/src/org/connectbot/ConsoleActivity.java b/src/org/connectbot/ConsoleActivity.java
index 98ff46c..1204669 100644
--- a/src/org/connectbot/ConsoleActivity.java
+++ b/src/org/connectbot/ConsoleActivity.java
@@ -133,9 +133,14 @@ public class ConsoleActivity extends Activity {
}
- // show the requested bridge if found, also fade out overlay
- flip.setDisplayedChild(requestedIndex);
- flip.getCurrentView().findViewById(R.id.terminal_overlay).startAnimation(fade_out);
+ try {
+ // show the requested bridge if found, also fade out overlay
+ flip.setDisplayedChild(requestedIndex);
+ flip.getCurrentView().findViewById(R.id.terminal_overlay).startAnimation(fade_out);
+ } catch (NullPointerException npe) {
+ Log.d(TAG, "View went away when we were about to display it", npe);
+ }
+
updatePromptVisible();
updateEmptyVisible();
@@ -608,8 +613,11 @@ public class ConsoleActivity extends Activity {
final View view = findCurrentView(R.id.console_flip);
boolean activeTerminal = (view instanceof TerminalView);
boolean authenticated = false;
- if(activeTerminal)
- authenticated = ((TerminalView)view).bridge.fullyConnected;
+ boolean sessionOpen = false;
+ if(activeTerminal) {
+ authenticated = ((TerminalView) view).bridge.isAuthenticated();
+ sessionOpen = ((TerminalView)view).bridge.isSessionOpen();
+ }
disconnect = menu.add(R.string.console_menu_disconnect);
disconnect.setEnabled(activeTerminal);
@@ -628,7 +636,7 @@ public class ConsoleActivity extends Activity {
copy = menu.add(R.string.console_menu_copy);
copy.setIcon(android.R.drawable.ic_menu_set_as);
- copy.setEnabled(activeTerminal && authenticated);
+ copy.setEnabled(activeTerminal);
copy.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
// mark as copying and reset any previous bounds
@@ -661,7 +669,7 @@ public class ConsoleActivity extends Activity {
portForward = menu.add(R.string.console_menu_portforwards);
portForward.setIcon(android.R.drawable.ic_menu_manage);
- portForward.setEnabled(activeTerminal && authenticated);
+ portForward.setEnabled(authenticated);
portForward.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
Intent intent = new Intent(ConsoleActivity.this, PortForwardListActivity.class);
@@ -673,7 +681,7 @@ public class ConsoleActivity extends Activity {
resize = menu.add(R.string.console_menu_resize);
resize.setIcon(android.R.drawable.ic_menu_crop);
- resize.setEnabled(activeTerminal && authenticated);
+ resize.setEnabled(activeTerminal && sessionOpen);
resize.setOnMenuItemClickListener(new OnMenuItemClickListener() {
public boolean onMenuItemClick(MenuItem item) {
final TerminalView terminal = (TerminalView)view;
@@ -724,14 +732,17 @@ public class ConsoleActivity extends Activity {
final View view = findCurrentView(R.id.console_flip);
boolean activeTerminal = (view instanceof TerminalView);
boolean authenticated = false;
- if(activeTerminal)
- authenticated = ((TerminalView)view).bridge.fullyConnected;
-
+ boolean sessionOpen = false;
+ if (activeTerminal) {
+ authenticated = ((TerminalView)view).bridge.isAuthenticated();
+ sessionOpen = ((TerminalView)view).bridge.isSessionOpen();
+ }
+
disconnect.setEnabled(activeTerminal);
- copy.setEnabled(activeTerminal && authenticated);
- paste.setEnabled(clipboard.hasText() && activeTerminal && authenticated);
+ copy.setEnabled(activeTerminal);
+ paste.setEnabled(clipboard.hasText() && activeTerminal && sessionOpen);
portForward.setEnabled(activeTerminal && authenticated);
- resize.setEnabled(activeTerminal && authenticated);
+ resize.setEnabled(activeTerminal && sessionOpen);
return true;
}
diff --git a/src/org/connectbot/PortForwardListActivity.java b/src/org/connectbot/PortForwardListActivity.java
index c5d4cb5..e2097fa 100644
--- a/src/org/connectbot/PortForwardListActivity.java
+++ b/src/org/connectbot/PortForwardListActivity.java
@@ -168,7 +168,18 @@ public class PortForwardListActivity extends ListActivity {
public boolean onMenuItemClick(MenuItem item) {
// build dialog to prompt user about updating
final View portForwardView = inflater.inflate(R.layout.dia_portforward, null, false);
+ final EditText destEdit = (EditText) portForwardView.findViewById(R.id.portforward_destination);
final Spinner typeSpinner = (Spinner)portForwardView.findViewById(R.id.portforward_type);
+
+ typeSpinner.setOnItemSelectedListener(new OnItemSelectedListener() {
+ public void onItemSelected(AdapterView<?> value, View view,
+ int position, long id) {
+ destEdit.setEnabled(position != 2);
+ }
+ public void onNothingSelected(AdapterView<?> arg0) {
+ }
+ });
+
new AlertDialog.Builder(PortForwardListActivity.this)
.setView(portForwardView)
.setPositiveButton(R.string.portforward_pos, new DialogInterface.OnClickListener() {
@@ -176,9 +187,19 @@ public class PortForwardListActivity extends ListActivity {
try {
final EditText nicknameEdit = (EditText) portForwardView.findViewById(R.id.nickname);
final EditText sourcePortEdit = (EditText) portForwardView.findViewById(R.id.portforward_source);
- final EditText destEdit = (EditText) portForwardView.findViewById(R.id.portforward_destination);
- String type = (String)typeSpinner.getSelectedItem();
+ String type = HostDatabase.PORTFORWARD_LOCAL;
+ switch (typeSpinner.getSelectedItemPosition()) {
+ case 0:
+ type = HostDatabase.PORTFORWARD_LOCAL;
+ break;
+ case 1:
+ type = HostDatabase.PORTFORWARD_REMOTE;
+ break;
+ case 2:
+ type = HostDatabase.PORTFORWARD_DYNAMIC5;
+ break;
+ }
PortForwardBean pfb = new PortForwardBean(hostId,
nicknameEdit.getText().toString(), type,
diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java
index 1762262..4cb1b2b 100644
--- a/src/org/connectbot/service/TerminalBridge.java
+++ b/src/org/connectbot/service/TerminalBridge.java
@@ -109,6 +109,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public final String nickname;
protected final String username;
public String postlogin = null;
+ private boolean wantSession = true;
public final Connection connection;
protected Session session;
@@ -145,6 +146,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// read in all known hosts from hostdb
KnownHosts hosts = manager.hostdb.getKnownHosts();
+ Boolean result;
switch(hosts.verifyHostkey(hostname, serverHostKeyAlgorithm, serverHostKey)) {
case KnownHosts.HOSTKEY_IS_OK:
@@ -154,9 +156,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
// prompt user
outputLine(String.format("The authenticity of host '%s' can't be established.", hostname));
outputLine(String.format("RSA key fingerprint is %s", KnownHosts.createHexFingerprint(serverHostKeyAlgorithm, serverHostKey)));
- //outputLine("[For now we'll assume you accept this key, but tap Menu and Disconnect if not.]");
- //outputLine("Are you sure you want to continue connecting (yes/no)? ");
- Boolean result = promptHelper.requestBooleanPrompt("Are you sure you want\nto continue connecting?");
+
+ result = promptHelper.requestBooleanPrompt("Are you sure you want\nto continue connecting?");
if(result == null) return false;
if(result.booleanValue()) {
// save this key in known database
@@ -172,9 +173,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
outputLine("Someone could be eavesdropping on you right now (man-in-the-middle attack)!");
outputLine("It is also possible that the RSA host key has just been changed.");
outputLine(String.format("RSA key fingerprint is %s", KnownHosts.createHexFingerprint(serverHostKeyAlgorithm, serverHostKey)));
- outputLine("Host key verification failed.");
- return false;
+ // Users have no way to delete keys, so we'll prompt them for now.
+ result = promptHelper.requestBooleanPrompt("Are you sure you want\nto continue connecting?");
+ if(result == null) return false;
+ if(result.booleanValue()) {
+ // save this key in known database
+ manager.hostdb.saveKnownHost(hostname, serverHostKeyAlgorithm, serverHostKey);
+ }
+ return result.booleanValue();
}
return false;
@@ -184,7 +191,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
public PromptHelper promptHelper;
-
+
/**
* Create new terminal bridge with following parameters. We will immediately
* launch thread to start SSH connection and handle any hostkey verification
@@ -199,6 +206,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
this.emulation = manager.getEmulation();
this.scrollback = manager.getScrollback();
this.postlogin = manager.getPostLogin(nickname);
+ this.wantSession = manager.getWantSession(nickname);
// create prompt helper to relay password and hostkey requests up to gui
this.promptHelper = new PromptHelper(this);
@@ -260,7 +268,12 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
public void run() {
try {
connection.connect(new HostKeyVerifier());
-
+ } catch (IOException e) {
+ Log.e(TAG, "Problem in SSH connection thread during authentication", e);
+ Log.d(TAG, String.format("Cause is: %s", e.getCause().toString()));
+ }
+
+ try {
// enter a loop to keep trying until authentication
int tries = 0;
while(!connection.isAuthenticationComplete() && tries++ < AUTH_TRIES && !disconnectFlag) {
@@ -270,7 +283,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
Thread.sleep(1000);
}
} catch(Exception e) {
- Log.e(TAG, "Problem in SSH connection thread", e);
+ Log.e(TAG, "Problem in SSH connection thread during authentication", e);
}
}
}).start();
@@ -466,13 +479,30 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}).start();
}
- public boolean fullyConnected = false;
+ private boolean authenticated = false;
+ private boolean sessionOpen = false;
/**
* Internal method to request actual PTY terminal once we've finished
* authentication. If called before authenticated, it will just fail.
*/
protected void finishConnection() {
+ setAuthenticated(true);
+
+ // Start up predefined port forwards
+ for (PortForwardBean pfb : portForwards) {
+ try {
+ enablePortForward(pfb);
+ outputLine(String.format("Enable port forward: %s", pfb.getDescription()));
+ } catch (Exception e) {
+ Log.e(TAG, "Error setting up port forward during connect", e);
+ }
+ }
+
+ if (!wantSession) {
+ outputLine("Session will not be started due to host preference.");
+ return;
+ }
try {
this.session = connection.openSession();
@@ -508,21 +538,15 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
}
});
- this.relay.start();
+ relay.start();
// force font-size to make sure we resizePTY as needed
- this.setFontSize(this.fontSize);
+ setFontSize(this.fontSize);
- this.fullyConnected = true;
-
- // Start up predefined port forwards
- for (PortForwardBean pfb : portForwards) {
- enablePortForward(pfb);
- Log.d(TAG, String.format("Enabling port formard %s (enabled? %b)", pfb.getDescription(), pfb.isEnabled()));
- }
+ setSessionOpen(true);
// finally send any post-login string, if requested
- this.injectString(postlogin);
+ injectString(postlogin);
} catch (IOException e1) {
Log.e(TAG, "Problem while trying to create PTY in finishConnection()", e1);
@@ -530,6 +554,20 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}
+ /**
+ * @param sessionOpen the sessionOpen to set
+ */
+ public void setSessionOpen(boolean sessionOpen) {
+ this.sessionOpen = sessionOpen;
+ }
+
+ /**
+ * @return the sessionOpen
+ */
+ public boolean isSessionOpen() {
+ return sessionOpen;
+ }
+
protected BridgeDisconnectedListener disconnectListener = null;
public void setOnDisconnectedListener(BridgeDisconnectedListener disconnectListener) {
@@ -553,7 +591,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
}).start();
this.disconnectFlag = true;
- this.fullyConnected = false;
+ this.authenticated = false;
+ this.sessionOpen = false;
// pass notification back up to terminal manager
// the manager will do any gui notification if applicable
@@ -1145,4 +1184,18 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener, InteractiveCal
return false;
}
}
+
+ /**
+ * @param authenticated the authenticated to set
+ */
+ public void setAuthenticated(boolean authenticated) {
+ this.authenticated = authenticated;
+ }
+
+ /**
+ * @return the authenticated
+ */
+ public boolean isAuthenticated() {
+ return authenticated;
+ }
}
diff --git a/src/org/connectbot/service/TerminalManager.java b/src/org/connectbot/service/TerminalManager.java
index 336d1fa..a0753df 100644
--- a/src/org/connectbot/service/TerminalManager.java
+++ b/src/org/connectbot/service/TerminalManager.java
@@ -167,6 +167,10 @@ public class TerminalManager extends Service implements BridgeDisconnectedListen
return hostdb.getPostLogin(nickname);
}
+ public boolean getWantSession(String nickname) {
+ return hostdb.getWantSession(nickname);
+ }
+
public String getKeyMode() {
return prefs.getString(this.pref_keymode, getString(R.string.list_keymode_right)); // "Use right-side keys"
}
diff --git a/src/org/connectbot/util/HostDatabase.java b/src/org/connectbot/util/HostDatabase.java
index dd003fe..c98fcce 100644
--- a/src/org/connectbot/util/HostDatabase.java
+++ b/src/org/connectbot/util/HostDatabase.java
@@ -43,7 +43,7 @@ public class HostDatabase extends SQLiteOpenHelper {
public final static String TAG = HostDatabase.class.toString();
public final static String DB_NAME = "hosts";
- public final static int DB_VERSION = 12;
+ public final static int DB_VERSION = 13;
public final static String TABLE_HOSTS = "hosts";
public final static String FIELD_HOST_NICKNAME = "nickname";
@@ -57,6 +57,7 @@ public class HostDatabase extends SQLiteOpenHelper {
public final static String FIELD_HOST_USEKEYS = "usekeys";
public final static String FIELD_HOST_POSTLOGIN = "postlogin";
public final static String FIELD_HOST_PUBKEYID = "pubkeyid";
+ public final static String FIELD_HOST_WANTSESSION = "wantsession";
public final static String TABLE_PORTFORWARDS = "portforwards";
public final static String FIELD_PORTFORWARD_HOSTID = "hostid";
@@ -97,7 +98,8 @@ public class HostDatabase extends SQLiteOpenHelper {
+ FIELD_HOST_COLOR + " TEXT, "
+ FIELD_HOST_USEKEYS + " TEXT, "
+ FIELD_HOST_POSTLOGIN + " TEXT, "
- + FIELD_HOST_PUBKEYID + " INTEGER DEFAULT " + PUBKEYID_ANY + ")");
+ + FIELD_HOST_PUBKEYID + " INTEGER DEFAULT " + PUBKEYID_ANY + ", "
+ + FIELD_HOST_WANTSESSION + " TEXT DEFAULT '" + Boolean.toString(true) + "')");
// insert a few sample hosts, none of which probably connect
//this.createHost(db, "connectbot@bravo", "connectbot", "192.168.254.230", 22, COLOR_GRAY);
@@ -136,7 +138,10 @@ public class HostDatabase extends SQLiteOpenHelper {
+ FIELD_PORTFORWARD_TYPE + " TEXT NOT NULL DEFAULT " + PORTFORWARD_LOCAL + ", "
+ FIELD_PORTFORWARD_SOURCEPORT + " INTEGER NOT NULL DEFAULT 8080, "
+ FIELD_PORTFORWARD_DESTADDR + " TEXT, "
- + FIELD_PORTFORWARD_DESTPORT + " INTEGER)");
+ + FIELD_PORTFORWARD_DESTPORT + " INTEGER)");
+ case 12:
+ db.execSQL("ALTER TABLE " + TABLE_HOSTS
+ + " ADD COLUMN " + FIELD_HOST_WANTSESSION + " TEXT DEFAULT '" + Boolean.toString(true) + "'");
}
}
@@ -219,6 +224,7 @@ public class HostDatabase extends SQLiteOpenHelper {
if(color != null)
values.put(FIELD_HOST_COLOR, color);
values.put(FIELD_HOST_PUBKEYID, pubkeyId);
+ values.put(FIELD_HOST_WANTSESSION, Boolean.toString(true));
return db.insert(TABLE_HOSTS, null, values);
@@ -254,19 +260,45 @@ public class HostDatabase extends SQLiteOpenHelper {
* Find the post-login command string for the given nickname.
*/
public String getPostLogin(String nickname) {
-
String result = null;
+
SQLiteDatabase db = this.getReadableDatabase();
Cursor c = db.query(TABLE_HOSTS, new String[] { FIELD_HOST_POSTLOGIN },
FIELD_HOST_NICKNAME + " = ?", new String[] { nickname }, null, null, null);
- if(c == null || !c.moveToFirst()) {
+
+ if (c == null || !c.moveToFirst()) {
result = null;
} else {
result = c.getString(c.getColumnIndexOrThrow(FIELD_HOST_POSTLOGIN));
}
+ c.close();
+ db.close();
+
return result;
+ }
+
+ /**
+ * Check whether a host should have a shell session started.
+ * @param nickname Nick name of host to check
+ * @return true if host should have a shell session started
+ */
+ public boolean getWantSession(String nickname) {
+ Boolean result = true;
+ SQLiteDatabase db = this.getReadableDatabase();
+ Cursor c = db.query(TABLE_HOSTS, new String[] { FIELD_HOST_WANTSESSION },
+ FIELD_HOST_NICKNAME + " = ?", new String[] { nickname }, null, null, null);
+ if(c == null || !c.moveToFirst()) {
+ result = true;
+ } else {
+ result = Boolean.valueOf(c.getString(c.getColumnIndexOrThrow(FIELD_HOST_WANTSESSION)));
+ }
+
+ c.close();
+ db.close();
+
+ return result;
}
/**