diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/org/connectbot/HostList.java | 164 | ||||
-rw-r--r-- | src/org/connectbot/R.java | 148 | ||||
-rw-r--r-- | src/org/connectbot/WizardActivity.java | 108 | ||||
-rw-r--r-- | src/org/connectbot/service/TerminalBridge.java | 16 | ||||
-rw-r--r-- | src/org/theb/ssh/HostEditor.java | 2 | ||||
-rw-r--r-- | src/org/theb/ssh/HostsList.java | 11 | ||||
-rw-r--r-- | src/org/theb/ssh/Pubkey.java | 2 | ||||
-rw-r--r-- | src/org/theb/ssh/SecureShell.java | 2 |
8 files changed, 352 insertions, 101 deletions
diff --git a/src/org/connectbot/HostList.java b/src/org/connectbot/HostList.java index 90d8d32..e7677ff 100644 --- a/src/org/connectbot/HostList.java +++ b/src/org/connectbot/HostList.java @@ -1,5 +1,9 @@ package org.connectbot; +import java.io.ByteArrayOutputStream; +import java.io.InputStream; +import java.net.URL; +import java.net.URLConnection; import java.util.HashMap; import java.util.LinkedList; import java.util.List; @@ -11,6 +15,7 @@ import org.connectbot.service.TerminalManager; import org.connectbot.util.HostAdapter; import org.connectbot.util.HostBinder; import org.connectbot.util.HostDatabase; +import org.json.JSONObject; import org.theb.ssh.InteractiveHostKeyVerifier; import com.trilead.ssh2.Connection; @@ -22,10 +27,16 @@ import android.content.Context; import android.content.DialogInterface; import android.content.Intent; import android.content.ServiceConnection; +import android.content.SharedPreferences; +import android.content.Intent.ShortcutIconResource; +import android.content.SharedPreferences.Editor; import android.database.Cursor; import android.net.Uri; import android.os.Bundle; +import android.os.Handler; import android.os.IBinder; +import android.os.Message; +import android.util.Log; import android.view.ContextMenu; import android.view.KeyEvent; import android.view.LayoutInflater; @@ -43,6 +54,41 @@ import android.widget.TextView; import android.widget.AdapterView.OnItemClickListener; public class HostList extends Activity { + + public final static String UPDATE_URL = "http://connectbot.org/version"; + public final static double VERSION = 1.0; + + public Handler versionHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + + // handle version update message + if(!(msg.obj instanceof JSONObject)) return; + JSONObject json = (JSONObject)msg.obj; + + double version = json.optDouble("version"); + String features = json.optString("features"); + final String target = "market://" + json.optString("target"); + + if(version <= VERSION) return; + + new AlertDialog.Builder(HostList.this) + .setTitle("New version") + .setMessage(features) + .setPositiveButton("Yes, upgrade", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + Intent intent = new Intent(Intent.ACTION_VIEW, Uri.parse(target)); + HostList.this.startActivity(intent); + } + }) + .setNegativeButton("Not right now", new DialogInterface.OnClickListener() { + public void onClick(DialogInterface dialog, int which) { + } + }).create().show(); + + } + + }; public TerminalManager bound = null; @@ -83,12 +129,63 @@ public class HostList extends Activity { this.unbindService(connection); } + + + + public final static String EULA = "eula"; + protected SharedPreferences prefs = null; @Override + protected void onActivityResult(int requestCode, int resultCode, Intent data) { + + if(resultCode == Activity.RESULT_OK) { + // yay they agreed, so store that info + Editor edit = prefs.edit(); + edit.putBoolean(EULA, true); + edit.commit(); + } else { + // user didnt agree, so close + this.finish(); + } + + this.updateCursor(); + + } + + + protected boolean shortcut = false; + + @Override public void onCreate(Bundle icicle) { super.onCreate(icicle); setContentView(R.layout.act_hostlist); + + // check for eula agreement + this.prefs = this.getSharedPreferences(EULA, Context.MODE_PRIVATE); + + boolean agreed = prefs.getBoolean(EULA, false); + if(!agreed) { + this.startActivityForResult(new Intent(this, WizardActivity.class), 1); + } + + // start thread to check for new version + new Thread(new Runnable() { + public void run() { + try { + JSONObject json = new JSONObject(readUrl(UPDATE_URL)); + Message.obtain(versionHandler, -1, json).sendToTarget(); + } catch(Exception e) { + e.printStackTrace(); + } + } + }).start(); + + + + + this.shortcut = Intent.ACTION_CREATE_SHORTCUT.equals(getIntent().getAction()); + // connect with hosts database and populate list this.hostdb = new HostDatabase(this); this.list = (ListView) this.findViewById(R.id.front_hostlist); @@ -114,10 +211,30 @@ public class HostList extends Activity { int port = c.getInt(COL_PORT); String nickname = c.getString(COL_NICKNAME); - Intent intent = new Intent(HostList.this, Console.class); - intent.setData(Uri.parse(String.format("ssh://%s@%s:%s/#%s", username, hostname, port, nickname))); - HostList.this.startActivity(intent); + Uri uri = Uri.parse(String.format("ssh://%s@%s:%s/#%s", username, hostname, port, nickname)); + Intent contents = new Intent(Intent.ACTION_VIEW, uri); + contents.setFlags(Intent.FLAG_ACTIVITY_CLEAR_TOP); + + + if (shortcut) { + // create shortcut if requested + ShortcutIconResource icon = Intent.ShortcutIconResource.fromContext(HostList.this, R.drawable.icon); + + Intent intent = new Intent(); + intent.putExtra(Intent.EXTRA_SHORTCUT_INTENT, contents); + intent.putExtra(Intent.EXTRA_SHORTCUT_NAME, nickname); + intent.putExtra(Intent.EXTRA_SHORTCUT_ICON_RESOURCE, icon); + + setResult(RESULT_OK, intent); + finish(); + + } else { + HostList.this.startActivity(contents); + + + } + } }); @@ -242,30 +359,43 @@ public class HostList extends Activity { MenuItem settings = menu.add(0, 0, Menu.NONE, "Settings"); settings.setIcon(android.R.drawable.ic_menu_preferences); - settings.setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - HostList.this.startActivity(new Intent(HostList.this, SettingsActivity.class)); - return true; - } - }); + settings.setIntent(new Intent(HostList.this, SettingsActivity.class)); MenuItem about = menu.add(0, 0, Menu.NONE, "About"); about.setIcon(android.R.drawable.ic_menu_help); - about.setOnMenuItemClickListener(new OnMenuItemClickListener() { - public boolean onMenuItemClick(MenuItem item) { - HostList.this.startActivity(new Intent(HostList.this, AboutActivity.class)); - return true; - } - }); + about.setIntent(new Intent(HostList.this, WizardActivity.class)); return true; } - protected void onActivityResult(int requestCode, int resultCode, Intent data) { - this.updateCursor(); + + + public String readUrl(String fetchurl) throws Exception { + byte[] buffer = new byte[1024]; + + URL url = new URL(fetchurl); + URLConnection connection = url.openConnection(); + connection.setConnectTimeout(6000); + connection.setReadTimeout(6000); + connection.setRequestProperty("User-Agent", String.format("%s %f", this.getResources().getString(R.string.app_name), VERSION)); + connection.connect(); + InputStream is = connection.getInputStream(); + ByteArrayOutputStream os = new ByteArrayOutputStream(); + + int bytesRead; + while ((bytesRead = is.read(buffer)) != -1) { + os.write(buffer, 0, bytesRead); + } + + os.flush(); + os.close(); + is.close(); + + return new String(os.toByteArray()); } + public final static int REQUEST_EDIT = 1; @Override diff --git a/src/org/connectbot/R.java b/src/org/connectbot/R.java index d326023..0130e6b 100644 --- a/src/org/connectbot/R.java +++ b/src/org/connectbot/R.java @@ -28,86 +28,92 @@ public final class R { public static final int red=0x7f080002; } public static final class drawable { - public static final int blue=0x7f020003; + public static final int blue=0x7f020005; public static final int connected=0x7f020000; - public static final int even_stripe=0x7f020004; + public static final int even_stripe=0x7f020006; public static final int highlight_disabled_pressed=0x7f020001; - public static final int icon=0x7f020002; - public static final int odd_stripe=0x7f020005; + public static final int ic_btn_back=0x7f020002; + public static final int ic_btn_next=0x7f020003; + public static final int icon=0x7f020004; + public static final int odd_stripe=0x7f020007; } public static final class id { - public static final int add=0x7f090011; - public static final int cancel=0x7f090012; - public static final int console_flip=0x7f090002; - public static final int copyright=0x7f090001; - public static final int dismiss=0x7f090016; - public static final int edit_emulation=0x7f090007; - public static final int edit_hostname=0x7f090005; - public static final int edit_nickname=0x7f090003; - public static final int edit_port=0x7f090006; - public static final int edit_scrollback=0x7f090008; - public static final int edit_username=0x7f090004; - public static final int front_hostlist=0x7f090009; - public static final int front_quickconnect=0x7f09000a; - public static final int generate=0x7f09001a; - public static final int hostname=0x7f09000e; - public static final int hostnameLabel=0x7f09000d; - public static final int icon=0x7f090000; - public static final int keyName=0x7f09001b; - public static final int message=0x7f090015; - public static final int ok=0x7f090019; - public static final int password=0x7f090018; - public static final int passwordLabel=0x7f090017; - public static final int port=0x7f090010; - public static final int portLabel=0x7f09000f; - public static final int shell=0x7f090014; - public static final int terminal=0x7f09001c; - public static final int terminal_overlay=0x7f090013; - public static final int username=0x7f09000c; - public static final int usernameLabel=0x7f09000b; + public static final int action_next=0x7f09000c; + public static final int action_prev=0x7f09000b; + public static final int add=0x7f090013; + public static final int cancel=0x7f090014; + public static final int console_flip=0x7f090000; + public static final int dismiss=0x7f090018; + public static final int edit_emulation=0x7f090005; + public static final int edit_hostname=0x7f090003; + public static final int edit_nickname=0x7f090001; + public static final int edit_port=0x7f090004; + public static final int edit_scrollback=0x7f090006; + public static final int edit_username=0x7f090002; + public static final int front_hostlist=0x7f090007; + public static final int front_quickconnect=0x7f090008; + public static final int generate=0x7f09001c; + public static final int hostname=0x7f090010; + public static final int hostnameLabel=0x7f09000f; + public static final int keyName=0x7f09001d; + public static final int message=0x7f090017; + public static final int ok=0x7f09001b; + public static final int password=0x7f09001a; + public static final int passwordLabel=0x7f090019; + public static final int port=0x7f090012; + public static final int portLabel=0x7f090011; + public static final int shell=0x7f090016; + public static final int terminal=0x7f09001e; + public static final int terminal_overlay=0x7f090015; + public static final int username=0x7f09000e; + public static final int usernameLabel=0x7f09000d; + public static final int wizard_flipper=0x7f09000a; + public static final int wizard_scroll=0x7f090009; } public static final class layout { - public static final int about_dialog=0x7f030000; - public static final int act_about=0x7f030001; - public static final int act_console=0x7f030002; - public static final int act_hosteditor=0x7f030003; - public static final int act_hostlist=0x7f030004; - public static final int host_editor=0x7f030005; - public static final int item_host=0x7f030006; - public static final int item_terminal=0x7f030007; - public static final int main=0x7f030008; - public static final int message_dialog=0x7f030009; - public static final int password_dialog=0x7f03000a; - public static final int pubkey=0x7f03000b; - public static final int secure_shell=0x7f03000c; + public static final int act_console=0x7f030000; + public static final int act_hosteditor=0x7f030001; + public static final int act_hostlist=0x7f030002; + public static final int act_wizard=0x7f030003; + public static final int host_editor=0x7f030004; + public static final int item_host=0x7f030005; + public static final int item_terminal=0x7f030006; + public static final int main=0x7f030007; + public static final int message_dialog=0x7f030008; + public static final int password_dialog=0x7f030009; + public static final int pubkey=0x7f03000a; + public static final int secure_shell=0x7f03000b; + public static final int wiz_eula=0x7f03000c; + public static final int wiz_features=0x7f03000d; } public static final class string { - public static final int alert_disconnect_msg=0x7f070014; + public static final int alert_disconnect_msg=0x7f070015; + public static final int app_desc=0x7f070001; public static final int app_name=0x7f070000; - public static final int bind_days=0x7f070019; - public static final int bind_hours=0x7f070018; - public static final int bind_minutes=0x7f070017; - public static final int button_add=0x7f070010; - public static final int button_cancel=0x7f070011; - public static final int button_change=0x7f070012; - public static final int button_generate=0x7f070013; - public static final int button_ok=0x7f07000f; - public static final int menu_about=0x7f07000d; - public static final int menu_delete=0x7f07000a; - public static final int menu_insert=0x7f070009; - public static final int menu_preferences=0x7f07000b; - public static final int menu_pubkey=0x7f07000c; - public static final int msg_copyright=0x7f070015; - public static final int msg_version=0x7f070016; - public static final int prompt_touch=0x7f07000e; - public static final int resolve_connect=0x7f070008; - public static final int resolve_edit=0x7f070007; - public static final int title_entropy=0x7f070006; - public static final int title_host=0x7f070002; - public static final int title_hosts_list=0x7f070001; - public static final int title_password=0x7f070004; - public static final int title_pubkey=0x7f070005; - public static final int title_shell=0x7f070003; + public static final int bind_days=0x7f07001a; + public static final int bind_hours=0x7f070019; + public static final int bind_minutes=0x7f070018; + public static final int button_add=0x7f070011; + public static final int button_cancel=0x7f070012; + public static final int button_change=0x7f070013; + public static final int button_generate=0x7f070014; + public static final int button_ok=0x7f070010; + public static final int menu_about=0x7f07000e; + public static final int menu_delete=0x7f07000b; + public static final int menu_insert=0x7f07000a; + public static final int menu_preferences=0x7f07000c; + public static final int menu_pubkey=0x7f07000d; + public static final int msg_copyright=0x7f070016; + public static final int msg_version=0x7f070017; + public static final int prompt_touch=0x7f07000f; + public static final int resolve_connect=0x7f070009; + public static final int resolve_edit=0x7f070008; + public static final int title_entropy=0x7f070007; + public static final int title_host=0x7f070003; + public static final int title_hosts_list=0x7f070002; + public static final int title_password=0x7f070005; + public static final int title_pubkey=0x7f070006; + public static final int title_shell=0x7f070004; } public static final class xml { public static final int host_prefs=0x7f050000; diff --git a/src/org/connectbot/WizardActivity.java b/src/org/connectbot/WizardActivity.java new file mode 100644 index 0000000..0fce80f --- /dev/null +++ b/src/org/connectbot/WizardActivity.java @@ -0,0 +1,108 @@ +package org.connectbot; + +import android.app.Activity; +import android.content.Context; +import android.content.Intent; +import android.os.Bundle; +import android.os.Handler; +import android.os.Message; +import android.view.LayoutInflater; +import android.view.View; +import android.view.View.OnClickListener; +import android.view.animation.Animation; +import android.view.animation.AnimationUtils; +import android.widget.Button; +import android.widget.ImageView; +import android.widget.ScrollView; +import android.widget.ViewFlipper; + +public class WizardActivity extends Activity { + + public final static int ACTION_NEXT = +1, ACTION_PREV = -1; + + protected Handler actionHandler = new Handler() { + @Override + public void handleMessage(Message msg) { + + switch(msg.what) { + case ACTION_NEXT: + if(flipper.getDisplayedChild() == flipper.getChildCount() - 1) { + WizardActivity.this.setResult(Activity.RESULT_OK); + WizardActivity.this.finish(); + } else { + flipper.showNext(); + } + break; + case ACTION_PREV: + if(flipper.getDisplayedChild() == 0) { + WizardActivity.this.setResult(Activity.RESULT_CANCELED); + WizardActivity.this.finish(); + } else { + flipper.showPrevious(); + } + break; + + } + + // scroll to top and hide all views except current + scroll.scrollTo(0, 0); + + setButtons(); + + } + }; + + protected void setButtons() { + boolean eula = (flipper.getDisplayedChild() == 0); + + next.setText(eula ? "Agree" : "Next"); + prev.setText(eula ? "Cancel" : "Back"); + + } + + protected ScrollView scroll = null; + protected ViewFlipper flipper = null; + protected Button next, prev; + + protected ImageView finger = null, + cross = null; + + protected Animation animFinger = null, + animCross = null; + + @Override + public void onCreate(Bundle savedInstanceState) { + super.onCreate(savedInstanceState); + setContentView(R.layout.act_wizard); + + // let the user step through various parts of wizard + // inflate all views to walk through + + LayoutInflater inflater = (LayoutInflater)this.getSystemService(Context.LAYOUT_INFLATER_SERVICE); + + this.scroll = (ScrollView)this.findViewById(R.id.wizard_scroll); + this.flipper = (ViewFlipper)this.findViewById(R.id.wizard_flipper); + + this.flipper.addView(inflater.inflate(R.layout.wiz_eula, this.flipper, false)); + this.flipper.addView(inflater.inflate(R.layout.wiz_features, this.flipper, false)); + + next = (Button)this.findViewById(R.id.action_next); + next.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + actionHandler.sendEmptyMessage(ACTION_NEXT); + } + }); + + prev = (Button)this.findViewById(R.id.action_prev); + prev.setOnClickListener(new OnClickListener() { + public void onClick(View v) { + actionHandler.sendEmptyMessage(ACTION_PREV); + } + }); + + this.setButtons(); + + + } + +} diff --git a/src/org/connectbot/service/TerminalBridge.java b/src/org/connectbot/service/TerminalBridge.java index 79510b1..13b2870 100644 --- a/src/org/connectbot/service/TerminalBridge.java +++ b/src/org/connectbot/service/TerminalBridge.java @@ -89,7 +89,8 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { // prompt user outputLine(String.format("The authenticity of host '%s' can't be established.", hostname)); outputLine(String.format("RSA key fingerprint is %s", hosts.createHexFingerprint(serverHostKeyAlgorithm, serverHostKey))); - outputLine("Are you sure you want to continue connecting (yes/no)? "); + 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)? "); return true; case KnownHosts.HOSTKEY_HAS_CHANGED: @@ -236,9 +237,14 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { } public void dispose() { - if(this.session != null) - this.session.close(); - this.connection.close(); + // meh this is buggy if the host isnt alive, so just spawn to thread for now + new Thread(new Runnable() { + public void run() { + if(session != null) + session.close(); + connection.close(); + } + }).start(); } public KeyCharacterMap keymap = KeyCharacterMap.load(KeyCharacterMap.BUILT_IN_KEYBOARD); @@ -248,7 +254,7 @@ public class TerminalBridge implements VDUDisplay, OnKeyListener { public boolean onKey(View v, int keyCode, KeyEvent event) { // pass through any keystrokes to output stream - Log.d(this.getClass().toString(), "onKey() code="+keyCode); + //Log.d(this.getClass().toString(), "onKey() code="+keyCode); if(event.getAction() == KeyEvent.ACTION_UP) return false; try { diff --git a/src/org/theb/ssh/HostEditor.java b/src/org/theb/ssh/HostEditor.java index 2b31ccd..128d827 100644 --- a/src/org/theb/ssh/HostEditor.java +++ b/src/org/theb/ssh/HostEditor.java @@ -100,7 +100,7 @@ public class HostEditor extends Activity { } // Get a cursor to access the host data - this.mCursor = managedQuery(mURI, PROJECTION, null, null); + //this.mCursor = managedQuery(mURI, PROJECTION, null, null); } @Override diff --git a/src/org/theb/ssh/HostsList.java b/src/org/theb/ssh/HostsList.java index eb0bc53..888d629 100644 --- a/src/org/theb/ssh/HostsList.java +++ b/src/org/theb/ssh/HostsList.java @@ -149,7 +149,7 @@ public class HostsList extends ListActivity { //setupListStripes(); - mCursor = managedQuery(getIntent().getData(), PROJECTION, null, null); + //mCursor = managedQuery(getIntent().getData(), PROJECTION, null, null); ListAdapter adapter = new HostListCursorAdapter(this, android.R.layout.simple_list_item_1, mCursor, @@ -280,7 +280,7 @@ public class HostsList extends ListActivity { private void showAbout() { Dialog about = new Dialog(this); - about.setContentView(R.layout.about_dialog); + //about.setContentView(R.layout.about_dialog); about.setTitle(getResources().getString(R.string.app_name) + " " + getResources().getString(R.string.msg_version)); @@ -313,9 +313,10 @@ public class HostsList extends ListActivity { //startActivity(new Intent(Intent.ACTION_PICK, url)); // collect all connection details - Cursor cursor = managedQuery(url, new String[] { "nickname", - "username", "hostname", "port", "emulation", "scrollback", - "hostkey" }, null, null); + Cursor cursor = null; +// managedQuery(url, new String[] { "nickname", +// "username", "hostname", "port", "emulation", "scrollback", +// "hostkey" }, null, null); cursor.moveToFirst(); // try finding an already-open bridge for this connection diff --git a/src/org/theb/ssh/Pubkey.java b/src/org/theb/ssh/Pubkey.java index b39bcab..a8ccb7b 100644 --- a/src/org/theb/ssh/Pubkey.java +++ b/src/org/theb/ssh/Pubkey.java @@ -68,7 +68,7 @@ public class Pubkey extends Activity { final Runnable mKeyGen = new Runnable() { public void run() { // TODO Auto-generated method stub - Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); +// Security.addProvider(new org.bouncycastle.jce.provider.BouncyCastleProvider()); try { mSecRand = SecureRandom.getInstance("SHA1PRNG"); diff --git a/src/org/theb/ssh/SecureShell.java b/src/org/theb/ssh/SecureShell.java index 9c2d125..32a8b10 100644 --- a/src/org/theb/ssh/SecureShell.java +++ b/src/org/theb/ssh/SecureShell.java @@ -98,7 +98,7 @@ public class SecureShell extends Activity implements FeedbackUI, ConnectionMonit Log.d("SSH", "using URI " + getIntent().getData().toString()); - mCursor = managedQuery(getIntent().getData(), PROJECTION, null, null); +// mCursor = managedQuery(getIntent().getData(), PROJECTION, null, null); mCursor.moveToFirst(); mHostname = mCursor.getString(HOSTNAME_INDEX); |