]> hydra-www.ietfng.org Git - android-vcpass-oisafe/commitdiff
OI Safe: moved almost all access of the database to a new class Passwords.
authorrmceoin <rmceoin@72b678ce-9140-0410-bee8-679b907dd61a>
Thu, 5 Mar 2009 13:56:00 +0000 (13:56 +0000)
committerrmceoin <rmceoin@72b678ce-9140-0410-bee8-679b907dd61a>
Thu, 5 Mar 2009 13:56:00 +0000 (13:56 +0000)
This new class in turn interacts with DBHelper.   It retains all
PassEntry and CategoryEntry data in memory.  Encrypted data is only
decrypted as needed.   Decrypted data is kept in memory.  This serves
as a cache and results in a dramatic increase in speed on the
CategoryList and PassList activities upon repeat use.

All references to DBHelper for passwords or categories have been
removed from all activities and centralized inside of Passwords.  The
only remaining DBHelper calls are for the Salt and MasterPassword.

With this new class we should be able to more easily implement a
search activity.

Fixed an assortment of minor flaws surround orientation changes.
Possibly fixed I210.  Fixed I206 and I209.

This is a major overhaul.  Please help test for new bugs.

git-svn-id: http://openintents.googlecode.com/svn/trunk/Safe@1967 72b678ce-9140-0410-bee8-679b907dd61a

17 files changed:
AndroidManifest.xml
res/values/strings.xml
src/org/openintents/safe/AskPassword.java
src/org/openintents/safe/Backup.java
src/org/openintents/safe/CategoryEdit.java
src/org/openintents/safe/CategoryEntry.java
src/org/openintents/safe/CategoryList.java
src/org/openintents/safe/CryptoHelper.java
src/org/openintents/safe/DBHelper.java
src/org/openintents/safe/IntentHandler.java
src/org/openintents/safe/PackageAccessEntry.java [new file with mode: 0644]
src/org/openintents/safe/PassEdit.java
src/org/openintents/safe/PassEntry.java
src/org/openintents/safe/PassList.java
src/org/openintents/safe/PassView.java
src/org/openintents/safe/Passwords.java [new file with mode: 0644]
src/org/openintents/safe/Restore.java

index 763f6c30cea636b805b4db4435dfcc4a3972f967..f04e4e9a8674de277f81b379f68f4b2bda304b07 100644 (file)
@@ -1,8 +1,7 @@
 <?xml version="1.0" encoding="utf-8"?>
 <manifest xmlns:android="http://schemas.android.com/apk/res/android"
     package="org.openintents.safe" \r
-    android:versionCode="4" \r
-    android:versionName="1.0.0">
+    android:versionName="1.1.0" android:versionCode="5">
     <application android:icon="@drawable/icon_safe" android:allowClearUserData="true" android:debuggable="true" android:label="@string/app_name">\r
        \r
         <!-- aTrackDog metadata -->\r
@@ -65,7 +64,7 @@
         <activity class=".PassList" android:name="PassList" android:label="@string/app_name" />
         <activity class=".PassEdit" android:name="PassEdit" android:label="@string/app_name" />
         <activity class=".CategoryList" android:name="CategoryList" android:label="@string/app_name" />
-        <activity class=".AskPassword" android:name="AskPassword" android:label="@string/app_name" />\r
+        <activity class=".AskPassword" android:name="AskPassword" android:label="@string/app_name"/>\r
         <activity class=".Help" android:name="Help" android:label="@string/app_name" />
         <activity class=".ChangePass" android:name="ChangePass" android:label="@string/app_name" />
         <activity class=".Restore" android:name="Restore" android:label="@string/app_name" />
index 8ee2f61551627523c9cd631f214a137a2294219a..da253e0c8833017b67a8aa0ff94c11ef3e37e10e 100644 (file)
        <string name="dialog_title_first_time_warning">New master key</string>\r
        <string name="dialog_summary_first_time_warning">A new random master key has been created. Use menu > backup and store this key in a safe place. Without this key you may lose encrypted data.</string>\r
        <string name="switch_mode">Switch mode</string>\r
+       <string name="decrypt_progress">Decrypting...</string>\r
        \r
        \r
        <!-- ***************************\r
index 6a436ea1c4c543b52d25cffc25d07c4d43d206d9..003499761d422514759c6b0286670430cdc1bc2b 100644 (file)
@@ -143,6 +143,7 @@ public class AskPassword extends Activity {
                boolean isLocal = thisIntent.getBooleanExtra (EXTRA_IS_LOCAL, false);
 
                pbeKey = (EditText) findViewById(R.id.password);
+               pbeKey.requestFocus();
                introText = (TextView) findViewById(R.id.first_time);
                remoteAsk = (TextView) findViewById(R.id.remote);
                confirmPass = (EditText) findViewById(R.id.pass_confirm);
@@ -295,6 +296,12 @@ public class AskPassword extends Activity {
                if (dbHelper == null) {
                        dbHelper = new DBHelper(this);
                }
+               if (viewMode==VIEW_NORMAL) {
+                       // clear pbeKey in case user had typed it, strayed
+                       // to something else, then another person opened
+                       // the app.   Wouldn't want the password already typed
+                       pbeKey.setText("");
+               }
 
        }
 
@@ -381,7 +388,6 @@ public class AskPassword extends Activity {
                        masterKey=decryptedMasterKey;
                        return true;
                }
-               masterKey=null;
                return false;
        }
        
index febfb0a21a42f8fe5b5207b8076dae53a5d287cc..c9d7d6b86737534778e54867b4f14200fb5bc329 100644 (file)
@@ -21,7 +21,7 @@ import java.io.IOException;
 import java.text.DateFormat;
 import java.util.ArrayList;
 import java.util.Date;
-import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import android.content.Context;
 import android.util.Log;
@@ -66,21 +66,18 @@ public class Backup {
 
             serializer.attribute(null, "date", dateOut);
             
-                       DBHelper dbHelper=new DBHelper(myCtx);
-                       
-                       String masterKeyEncrypted = dbHelper.fetchMasterKey();
+                       String masterKeyEncrypted = Passwords.fetchMasterKeyEncrypted();
                        serializer.startTag(null, "MasterKey");
                        serializer.text(masterKeyEncrypted);
                        serializer.endTag(null, "MasterKey");
 
-                       String salt = dbHelper.fetchSalt();
+                       String salt = Passwords.fetchSalt();
                        serializer.startTag(null, "Salt");
                        serializer.text(salt);
                        serializer.endTag(null, "Salt");
 
                        List<CategoryEntry> crows;
-                       crows = dbHelper.fetchAllCategoryRows();
-                       HashMap<Long, ArrayList<String>> packageAccess=dbHelper.fetchPackageAccessAll();
+                       crows = Passwords.getCategoryEntries();
                        
                        int totalPasswords=0;
 
@@ -90,7 +87,7 @@ public class Backup {
                                serializer.attribute(null, "name", crow.name);
 
                                List<PassEntry> rows;
-                               rows = dbHelper.fetchAllRows(crow.id);
+                               rows = Passwords.getPassEntries(crow.id, false, false);
        
                                for (PassEntry row : rows) {
                                        totalPasswords++;
@@ -127,9 +124,19 @@ public class Backup {
                                                serializer.endTag(null, "UniqueName");
                                        }
                                        
-                                       if(packageAccess.containsKey(row.id)) {
+                                       ArrayList<PackageAccessEntry> packageAccess=Passwords.getPackageAccessEntries(row.id);
+                                       if(packageAccess!=null) {
                                                serializer.startTag(null, "PackageAccess");
-                                               serializer.text(packageAccess.get(row.id).toString());
+                                               String entry="";
+                                               Iterator<PackageAccessEntry> packIter=packageAccess.iterator();
+                                               while (packIter.hasNext()) {
+                                                       if (entry.length()!=0) {
+                                                               entry += ",";
+                                                       }
+                                                       entry += packIter.next().packageAccess;
+                                               }
+                                               entry = "[" + entry + "]";
+                                               serializer.text(entry);
                                                serializer.endTag(null, "PackageAccess");
                                        }
 
@@ -141,8 +148,6 @@ public class Backup {
                        serializer.endTag(null, "OISafe");
                        serializer.endDocument();
 
-                       dbHelper.close();
-
                        result=myCtx.getString(R.string.backup_complete)+" "+
                                Integer.toString(totalPasswords);
                } catch (IOException e) {
index 9bb38af8ab68115cf14c7a4fea4dc456db80cbcc..1295441bc6525e20895ab421f8dbd35edbdf1e6b 100644 (file)
@@ -37,28 +37,11 @@ public class CategoryEdit extends Activity {
 
     private EditText nameText;
     private Long RowId;
-    private DBHelper dbHelper=null;
-    private CryptoHelper ch;
-
 
     public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
                if (debug) Log.d(TAG, "onCreate");
                
-               ch = new CryptoHelper();
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium,PassList.getSalt());
-                       ch.setPassword(PassList.getMasterKey());
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e1.getMessage(), Toast.LENGTH_SHORT).show();
-               }
-
-               if (dbHelper == null){
-                       dbHelper = new DBHelper(this);
-               }
-               
                String title = getResources().getString(R.string.app_name) + " - " +
                getResources().getString(R.string.edit_entry);
                setTitle(title);
@@ -108,17 +91,12 @@ public class CategoryEdit extends Activity {
     protected void onPause() {
                super.onPause();
                if (debug) Log.d(TAG, "onPause");
-               dbHelper.close();
-               dbHelper = null;
     }
 
     @Override
     protected void onResume() {
                super.onResume();
                if (debug) Log.d(TAG, "onResume");
-               if (dbHelper == null) {
-                   dbHelper = new DBHelper(this);
-               }
                if (!CategoryList.isSignedIn()) {
                        Intent frontdoor = new Intent(this, FrontDoor.class);
                        startActivity(frontdoor);               
@@ -133,22 +111,15 @@ public class CategoryEdit extends Activity {
        
                String namePlain = nameText.getText().toString();
                if (debug) Log.d(TAG, "name: " + namePlain);
+               entry.plainName=namePlain;
                
-               try {
-                   entry.name = ch.encrypt(namePlain);
-               } catch(CryptoHelperException e) {
-                   Log.e(TAG,e.toString());
-               }
-       
-       
                if(RowId == null || RowId == -1) {
-                       if (debug) Log.d(TAG, "addCategory");
-                   dbHelper.addCategory(entry);
+                       entry.id=-1;
                } else {
-                       if (debug) Log.d(TAG, "updateCategory");
-                       if (debug) Log.d(TAG, "RowId: " + String.valueOf(RowId));
-                   dbHelper.updateCategory(RowId, entry);
+                       entry.id=RowId;
                }
+               if (debug) Log.d(TAG, "addCategory");
+           RowId=Passwords.putCategoryEntry(entry);
     }
 
     /**
@@ -157,15 +128,8 @@ public class CategoryEdit extends Activity {
     private void populateFields() {
        if (debug) Log.d(TAG, "populateFields");
                if (RowId != null) {
-                   CategoryEntry row = dbHelper.fetchCategory(RowId);
-                   if (row.id > -1) {
-                               String cryptName = row.name;
-                               try {
-                                   nameText.setText(ch.decrypt(cryptName));
-                               } catch (CryptoHelperException e) {
-                                   Log.e(TAG,e.toString());
-                               }
-                   }            
+                   CategoryEntry catEntry = Passwords.getCategoryEntry(RowId);
+                   nameText.setText(catEntry.plainName);
                }
     }
 }
index 5a9d69c7236faaedec7a75aae036f4eae6a15b9c..0202113821d2fa0688ace78be196a6ddde72236c 100644 (file)
@@ -20,7 +20,9 @@ package org.openintents.safe;
  * @author Randy McEoin
  */
 public class CategoryEntry extends Object {
-    public long id;
+    public long id=-1;
     public String name;
+    public boolean nameNeedsDecrypt;
     public String plainName;
+    public boolean plainNameNeedsEncrypt=true;
 }
index 03b5e2a9f17b1f4a0c8adc9d8a870c76edfcb07c..ffbecdabe89d8167ddeefe2dc3b283385afe1054 100644 (file)
@@ -20,9 +20,6 @@ import java.io.File;
 import java.io.FileReader;
 import java.io.FileWriter;
 import java.io.IOException;
-import java.util.ArrayList;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
 import java.util.Iterator;
 import java.util.List;
@@ -110,9 +107,6 @@ public class CategoryList extends ListActivity {
     
     public static final String KEY_ID = "id";  // Intent keys
 
-    private CryptoHelper ch=null;
-    private DBHelper dbHelper=null;
-       
        private String importMessage="";
        private int importedEntries=0;
        private Thread importThread=null;
@@ -126,6 +120,7 @@ public class CategoryList extends ListActivity {
 
     private List<CategoryEntry> rows;
     private Intent restartTimerIntent;
+    private int lastPosition=0;
     
     BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
         public void onReceive(Context context, Intent intent) {
@@ -205,18 +200,23 @@ public class CategoryList extends ListActivity {
                        finish();
        }
                
+               try {
+                       Passwords.InitCrypto(CryptoHelper.EncryptionMedium, salt, masterKey);
+               } catch (Exception e) {
+                       e.printStackTrace();
+            Toast.makeText(CategoryList.this, "CategoryList: " + getString(R.string.crypto_error),
+                    Toast.LENGTH_SHORT).show();
+               }
+               
                setContentView(R.layout.cat_list);
                String title = getResources().getString(R.string.app_name) + " - " +
                        getResources().getString(R.string.categories);
                setTitle(title);
 
-               if (dbHelper==null) {
-                       dbHelper = new DBHelper(this);
-                       if (dbHelper.getPrePopulate()==true)
-                       {
-                               prePopulate();
-                               dbHelper.clearPrePopulate();
-                       }
+               if (Passwords.getPrePopulate()==true)
+               {
+                       prePopulate();
+                       Passwords.clearPrePopulate();
                }
                
         IntentFilter filter = new IntentFilter();
@@ -237,9 +237,6 @@ public class CategoryList extends ListActivity {
                super.onResume();
 
                if (debug) Log.d(TAG,"onResume()");
-               if (dbHelper == null) {
-                   dbHelper = new DBHelper(this);
-               }
 
                if (!isSignedIn()) {
                        Intent frontdoor = new Intent(this, FrontDoor.class);
@@ -286,8 +283,6 @@ public class CategoryList extends ListActivity {
                        try { backupThread.join(maxWaitToDie); } 
                        catch(InterruptedException e){} //  ignore 
                }
-               dbHelper.close();
-               dbHelper = null;
     }
 
     @Override
@@ -358,7 +353,7 @@ public class CategoryList extends ListActivity {
      * @return True if signed in
      */
     public static boolean isSignedIn() {
-       if (masterKey != null) {
+       if ((salt != null) && (masterKey != null)) {
                return true;
        }
        return false;
@@ -379,47 +374,13 @@ public class CategoryList extends ListActivity {
      */
     private void fillData() {
        if (debug) Log.d(TAG,"fillData()");
-               // initialize crypto so that we can display readable descriptions in
-               // the list view
-               ch = new CryptoHelper();
-               if(masterKey == null) {
-                   masterKey = "";
-               }
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium,salt);
-                       ch.setPassword(masterKey);
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e1.getMessage(), Toast.LENGTH_SHORT).show();
-                       return;
-               }
-       
-               List<String> items = new ArrayList<String>();
-               if (dbHelper==null) {
-                       return;
-               }
-               rows = dbHelper.fetchAllCategoryRows();
-
-               for (CategoryEntry row : rows) {
-                   String cryptDesc = row.name;
-                   row.plainName = "";
-                   try {
-                               row.plainName = ch.decrypt(cryptDesc);
-                   } catch (CryptoHelperException e) {
-                               Log.e(TAG,e.toString());
-                   }
-               }
-               Collections.sort(rows, new Comparator<CategoryEntry>() {
-                   public int compare(CategoryEntry o1, CategoryEntry o2) {
-                       return o1.plainName.compareToIgnoreCase(o2.plainName);
-                   }});
-               for (CategoryEntry row : rows) {
-                       items.add(row.plainName);
-               }
-
+               List<String> categoryNames=Passwords.getCategoryNames();
+               
+               rows=Passwords.getCategoryEntries();
+               
                ArrayAdapter<String> entries = 
-                   new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
+                   new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1,
+                               categoryNames);
                setListAdapter(entries);
                
     }
@@ -507,12 +468,12 @@ public class CategoryList extends ListActivity {
     }
 
     private void delCategory(long Id) {
-       if (dbHelper.countPasswords(Id)>0) {
+       if (Passwords.countPasswords(Id)>0) {
             Toast.makeText(CategoryList.this, R.string.category_not_empty,
                     Toast.LENGTH_SHORT).show();
                return;
        }
-               dbHelper.deleteCategory(Id);
+       Passwords.deleteCategoryEntry(Id);
                fillData();
     }
 
@@ -535,10 +496,12 @@ public class CategoryList extends ListActivity {
                        launchPassList(rows.get(info.position).id);
                        break;
                case EDIT_CATEGORY_INDEX:
-                       Intent i = new Intent(this, CategoryEdit.class);
                        if (position > -1) {
+                               Intent i = new Intent(this, CategoryEdit.class);
                                i.putExtra(KEY_ID, rows.get(position).id);
                                startActivityForResult(i,REQUEST_EDIT_CATEGORY);
+                               
+                               lastPosition=position;
                        }
                    break;
                case ADD_CATEGORY_INDEX:
@@ -548,6 +511,9 @@ public class CategoryList extends ListActivity {
                    try {
                                if (position > -1) {
                                        delCategory(rows.get(position).id);
+                                       if (position>2) {
+                                               setSelection(position-1);
+                                       }
                                }
                    } catch (IndexOutOfBoundsException e) {
                                // This should only happen when there are no
@@ -658,12 +624,11 @@ public class CategoryList extends ListActivity {
     protected void onActivityResult(int requestCode, int resultCode, Intent i) {
        super.onActivityResult(requestCode, resultCode, i);
 
-       if (dbHelper == null) {
-                   dbHelper = new DBHelper(this);
-               }
-
        if (resultCode == RESULT_OK) {
                fillData();
+               if (requestCode==REQUEST_EDIT_CATEGORY) {
+                       setSelection(lastPosition);
+               }
        }
     }
 
@@ -676,28 +641,13 @@ public class CategoryList extends ListActivity {
        if (debug) Log.d(TAG,"addCategory("+name+")");
        if ((name==null) || (name=="")) return -1;
                CategoryEntry entry =  new CategoryEntry();
+               entry.plainName=name;
 
-               sendBroadcast (restartTimerIntent);
-               String namePlain = name;
-
-               try {
-                       ch = new CryptoHelper();
-                       if(masterKey == null) {
-                           masterKey = "";
-                       }
-                       ch.init(CryptoHelper.EncryptionMedium,salt);
-                       ch.setPassword(masterKey);
-
-                   entry.name = ch.encrypt(namePlain);
-               } catch(CryptoHelperException e) {
-                   Log.e(TAG,e.toString());
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e.getMessage(), Toast.LENGTH_SHORT).show();
-               }
-           return dbHelper.addCategory(entry);
+           return Passwords.putCategoryEntry(entry);
     }
     
        public boolean exportDatabase(){
+               sendBroadcast (restartTimerIntent);
                String filename=EXPORT_FILENAME;
                try {
                        CSVWriter writer = new CSVWriter(new FileWriter(filename), ',');
@@ -711,65 +661,12 @@ public class CategoryList extends ListActivity {
                        };
                        writer.writeNext(header);
                        
-                       ch = new CryptoHelper();
-                       if(masterKey == null) {
-                           masterKey = "";
-                       }
-                       try {
-                               ch.init(CryptoHelper.EncryptionMedium,salt);
-                               ch.setPassword(masterKey);
-                       } catch (CryptoHelperException e1) {
-                               e1.printStackTrace();
-                               Toast.makeText(this,getString(R.string.crypto_error)
-                                       + e1.getMessage(), Toast.LENGTH_SHORT).show();
-                               return false;
-                       }
-               
-                       HashMap<Long, String> categories = new HashMap<Long, String>();
+                       HashMap<Long, String> categories = Passwords.getCategoryIdToName();
                        
-                       List<CategoryEntry> crows;
-                       crows = dbHelper.fetchAllCategoryRows();
-               
-                       for (CategoryEntry row : crows) {
-                           String cryptDesc = row.name;
-                           row.plainName = "";
-                           try {
-                                       row.plainName = ch.decrypt(cryptDesc);
-                                       categories.put(row.id, row.plainName);
-                           } catch (CryptoHelperException e) {
-                                       Log.e(TAG,e.toString());
-                           Toast.makeText(CategoryList.this, R.string.cannot_decrypt_category,
-                                   Toast.LENGTH_SHORT).show();
-                           return false;
-                           }
-                       }
-               
                        List<PassEntry> rows;
-                       rows = dbHelper.fetchAllRows(new Long(0));
+                       rows = Passwords.getPassEntries(new Long(0), true, false);
                
                        for (PassEntry row : rows) {
-                           String cryptDesc = row.description;
-                           String cryptWebsite = row.website;
-                           String cryptUsername = row.username;
-                           String cryptPassword = row.password;
-                           String cryptNote = row.note;
-                           row.plainDescription = "";
-                           row.plainWebsite = "";
-                           row.plainUsername = "";
-                           row.plainPassword = "";
-                           row.plainNote = "";
-                           try {
-                                       row.plainDescription = ch.decrypt(cryptDesc);
-                                       row.plainWebsite     = ch.decrypt(cryptWebsite);
-                                       row.plainUsername    = ch.decrypt(cryptUsername);
-                                       row.plainPassword    = ch.decrypt(cryptPassword);
-                                       row.plainNote        = ch.decrypt(cryptNote);
-                           } catch (CryptoHelperException e) {
-                                       Log.e(TAG,e.toString());
-                           Toast.makeText(CategoryList.this, R.string.cannot_decrypt_password,
-                                   Toast.LENGTH_SHORT).show();
-                           return false;
-                           }
                            String[] rowEntries = { categories.get(row.category),
                                        row.plainDescription,
                                        row.plainWebsite,
@@ -793,7 +690,7 @@ public class CategoryList extends ListActivity {
        }
 
        private void deleteDatabaseNow(){
-               dbHelper.deleteDatabase();
+               Passwords.deleteAll();
        }
 
        public void deleteDatabase4Import(final String filename){
@@ -860,6 +757,7 @@ public class CategoryList extends ListActivity {
         */
        private void importDatabaseThreadStart(final String filename){
                showDialog(IMPORT_PROGRESS_KEY);
+
                importThread = new Thread(new Runnable() {
                        public void run() {
                                importDatabaseFromCSV(filename);
@@ -880,6 +778,7 @@ public class CategoryList extends ListActivity {
         * into the database.
         */
        private void importDatabaseFromCSV(String filename){
+               sendBroadcast (restartTimerIntent);
                try {
                        importMessage="";
                        importedEntries=0;
@@ -908,7 +807,7 @@ public class CategoryList extends ListActivity {
                    }
 //                 Log.i(TAG,"first line is valid");
                    
-                   HashMap<String, Long> categoryToId=getCategoryToId(dbHelper);
+                   HashMap<String, Long> categoryToId=Passwords.getCategoryNameToId();
                    //
                    // take a pass through the CSV and collect any new Categories
                    //
@@ -953,7 +852,8 @@ public class CategoryList extends ListActivity {
                    }
                    reader.close();
 
-                   categoryToId=getCategoryToId(dbHelper);     // re-read the categories to get id's of new categories
+                   // re-read the categories to get id's of new categories
+                   categoryToId=Passwords.getCategoryNameToId();
                    //
                    // read the whole file again to import the actual fields
                    //
@@ -1012,21 +912,16 @@ public class CategoryList extends ListActivity {
                                }
                                continue;
                        }
-                       
+
                        PassEntry entry=new PassEntry();
-                               try {
-                                       entry.category = categoryToId.get(nextLine[0]);
-                                   entry.description = ch.encrypt(description);
-                                   entry.website = ch.encrypt(nextLine[2]);
-                                   entry.username = ch.encrypt(nextLine[3]);
-                                   entry.password = ch.encrypt(nextLine[4]);
-                                   entry.note = ch.encrypt(nextLine[5]);
-                               } catch(CryptoHelperException e) {
-                                   Log.e(TAG,e.toString());
-                                   continue;
-                               }
+                               entry.category = categoryToId.get(nextLine[0]);
+                           entry.plainDescription = description;
+                           entry.plainWebsite = nextLine[2];
+                           entry.plainUsername = nextLine[3];
+                           entry.plainPassword = nextLine[4];
+                           entry.plainNote = nextLine[5];
                                entry.id=0;
-                           dbHelper.addPassword(entry);
+                           Passwords.putPassEntry(entry);
                        newEntries++;
                    }
                        reader.close();
@@ -1049,39 +944,4 @@ public class CategoryList extends ListActivity {
                        importMessage=getString(R.string.import_file_error);
                }
        }
-
-       public static HashMap<String, Long> getCategoryToId(DBHelper dbHelper)
-       {
-               CryptoHelper ch = new CryptoHelper();
-               if(masterKey == null) {
-                   masterKey = "";
-               }
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium,salt);
-                       ch.setPassword(masterKey);
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       return null;
-               }
-       
-               HashMap<String,Long> categories = new HashMap<String,Long>();
-               List<CategoryEntry> rows;
-               if (dbHelper==null) {
-                       if (debug) Log.d(TAG, "getCategoryToId: dbHelper is null");
-                       return categories;
-               }
-               rows = dbHelper.fetchAllCategoryRows();
-
-               for (CategoryEntry row : rows) {
-                   String cryptDesc = row.name;
-                   row.plainName = "";
-                   try {
-                               row.plainName = ch.decrypt(cryptDesc);
-                               categories.put(row.plainName, row.id);
-                   } catch (CryptoHelperException e) {
-                               Log.e(TAG,e.toString());
-                   }
-               }
-               return categories;
-       }
 }
\ No newline at end of file
index 1d75651348ac8415476b21e8722afd071e1ebfa2..e5fcb601f34e4044eb0edeb7cc0dc50d885b5133 100644 (file)
@@ -292,6 +292,9 @@ public class CryptoHelper {
                    throw new CryptoHelperException(msg);\r
                }\r
                byte[] ciphertext = {};\r
+               if (plaintext==null) {\r
+                       return "";\r
+               }\r
        \r
                try {\r
                    pbeCipher.init(Cipher.ENCRYPT_MODE, pbeKey, pbeParamSpec);\r
@@ -329,7 +332,7 @@ public class CryptoHelper {
                    throw new CryptoHelperException(msg);\r
                }\r
        \r
-               if ((ciphertext==null) || (ciphertext=="")) {\r
+               if ((ciphertext==null) || (ciphertext.length()==0)) {\r
                        return "";\r
                }\r
                byte[] byteCiphertext=hexStringToBytes(ciphertext);\r
index 3ead13a1952cadf367bad11bf1267b96a4a4c689..40f575f76523d0628a65462a08625eab8042c019 100644 (file)
@@ -102,8 +102,8 @@ public class DBHelper {
                        + "expires integer not null, "
                        + "dateadded text not null);";
 
-    private static final String CIPHER_ACCESS_DROP =
-       "drop table " + TABLE_CIPHER_ACCESS + ";";
+//    private static final String CIPHER_ACCESS_DROP =
+//     "drop table " + TABLE_CIPHER_ACCESS + ";";
 
     private SQLiteDatabase db;
     private static boolean needsPrePopulation=false;
index efd1e73509b4c9a67d6eae943cfbedb7c3de2e54..529e2307caa9107e98c3b8a89d9e5e57f9d4b0ac 100644 (file)
@@ -54,8 +54,6 @@ public class IntentHandler extends Activity {
        private static final int REQUEST_CODE_ASK_PASSWORD = 1;\r
        private static final int REQUEST_CODE_ALLOW_EXTERNAL_ACCESS = 2;\r
        \r
-\r
-       private DBHelper dbHelper;\r
        private String salt;\r
        private String masterKey;\r
        private CryptoHelper ch;\r
@@ -74,7 +72,9 @@ public class IntentHandler extends Activity {
                super.onCreate(icicle);\r
                mServiceIntent = null;\r
                mPreferences = PreferenceManager.getDefaultSharedPreferences(this);\r
-               \r
+\r
+               Passwords.Initialize(this);\r
+\r
                // The service is launched in onResume()\r
        }\r
 \r
@@ -181,6 +181,9 @@ public class IntentHandler extends Activity {
         CategoryList.setSalt(salt);\r
                PassList.setMasterKey(masterKey);\r
         CategoryList.setMasterKey(masterKey);\r
+        if ((salt==null) || (salt=="")) {\r
+               return;\r
+        }\r
         if (ch == null) {\r
                ch = new CryptoHelper();\r
         }\r
@@ -328,21 +331,14 @@ public class IntentHandler extends Activity {
 \r
         if (clearUniqueName == null) throw new Exception ("EXTRA_UNIQUE_NAME not set.");\r
         \r
-               if (dbHelper == null) {\r
-               // Need to open DBHelper here, because\r
-                       // onResume() is called after onActivityResult()\r
-                       dbHelper = new DBHelper(this);\r
-               }\r
-\r
-        String uniqueName = ch.encrypt(clearUniqueName);\r
-       PassEntry row = dbHelper.fetchPassword(uniqueName);\r
-       boolean passExists = row.id > 1;\r
+       PassEntry row = Passwords.findPassWithUniqueName(clearUniqueName);\r
+       boolean passExists = (row!=null);\r
 \r
-        String clearCallingPackage = getCallingPackage();\r
-        String callingPackage = ch.encrypt (clearCallingPackage);\r
+        String callingPackage = getCallingPackage();\r
        if (passExists) { // check for permission to access this password.\r
-               ArrayList<String> packageAccess = dbHelper.fetchPackageAccess(row.id);\r
-               if (! PassEntry.checkPackageAccess(packageAccess, callingPackage)) {\r
+               ArrayList<String> packageAccess = Passwords.getPackageAccess(row.id);\r
+               if ((packageAccess==null) ||\r
+                       (! PassEntry.checkPackageAccess(packageAccess, callingPackage))) {\r
                        throw new Exception ("It is currently not permissible for this application to request this password.");\r
                }\r
             /*TODO: check if this package is in the package_access table corresponding to this password:\r
@@ -353,12 +349,14 @@ public class IntentHandler extends Activity {
                                [ ] Always grant access to all passwords in org.syntaxpolice.ServiceTest category?\r
                                [ ] Don't grant access"\r
              */\r
+       } else {\r
+               row = new PassEntry();\r
        }\r
        \r
         if (action.equals (CryptoIntents.ACTION_GET_PASSWORD)) {\r
                if (passExists) {\r
-                       username = ch.decrypt(row.username);\r
-                       password = ch.decrypt(row.password);\r
+                       username = row.plainUsername;\r
+                       password = row.plainPassword;\r
                } else throw new Exception ("Could not find password with the unique name: " + clearUniqueName);\r
 \r
                // stashing the return values:\r
@@ -370,34 +368,39 @@ public class IntentHandler extends Activity {
             if (clearPassword == null) {\r
                        throw new Exception ("PASSWORD extra must be set.");\r
             }  \r
-            row.username = ch.encrypt(clearUsername == null ? "" : clearUsername);\r
-            row.password = ch.encrypt(clearPassword);\r
+            row.plainUsername = clearUsername == null ? "" : clearUsername;\r
+            row.plainPassword = clearPassword;\r
             // since this package is setting the password, it automatically gets access to it:\r
                if (passExists) { //exists already \r
                        if (clearUsername.equals("") && clearPassword.equals("")) {\r
-                               dbHelper.deletePassword(row.id);\r
+                               Passwords.deletePassEntry(row.id);\r
                        } else {\r
-                               dbHelper.updatePassword(row.id, row);\r
+                               Passwords.putPassEntry(row);\r
                        }\r
                } else {// add a new one\r
-                row.uniqueName = uniqueName;\r
-                   row.description=uniqueName; //for display purposes\r
+                row.plainUniqueName = clearUniqueName;\r
+                   row.plainDescription=clearUniqueName; //for display purposes\r
                 // TODO: Should we send these fields in extras also?  If so, probably not using \r
                 // the openintents namespace?  If another application were to implement a keystore\r
                 // they might not want to use these.\r
-                   row.website = ""; \r
-                   row.note = "";\r
-\r
-                   String category = ch.encrypt("Application Data");\r
-                   CategoryEntry c = new CategoryEntry();\r
-                   c.name = category;\r
-                   row.category = dbHelper.addCategory(c); //doesn't add category if it already exists\r
+                   row.plainWebsite = ""; \r
+                   row.plainNote = "";\r
+\r
+                   String category="Application Data";\r
+                   CategoryEntry c = Passwords.getCategoryEntryByName(category);\r
+                   if (c==null) {\r
+                       c = new CategoryEntry();\r
+                           c.plainName = "Application Data";\r
+                           c.id = Passwords.putCategoryEntry(c); //doesn't add category if it already exists\r
+                   }\r
+                   row.category = c.id;\r
                    row.id = 0; // entry is truly new\r
-                   row.id = dbHelper.addPassword(row);\r
+                   row.id = Passwords.putPassEntry(row);\r
                }  \r
-               ArrayList<String> packageAccess = dbHelper.fetchPackageAccess(row.id);\r
-               if (! PassEntry.checkPackageAccess(packageAccess, callingPackage)) {\r
-               dbHelper.addPackageAccess(row.id, callingPackage);\r
+               ArrayList<String> packageAccess = Passwords.getPackageAccess(row.id);\r
+               if ((packageAccess==null) ||\r
+                       (! PassEntry.checkPackageAccess(packageAccess, callingPackage))) {\r
+               Passwords.addPackageAccess(row.id, callingPackage);\r
                }\r
     \r
         }\r
@@ -412,8 +415,6 @@ public class IntentHandler extends Activity {
                        Log.d(TAG, "onPause()");\r
 \r
                releaseService();\r
-               dbHelper.close();\r
-               dbHelper = null;\r
        }\r
 \r
        @Override\r
@@ -422,9 +423,6 @@ public class IntentHandler extends Activity {
 \r
                if (debug)\r
                        Log.d(TAG, "onResume()");\r
-               if (dbHelper == null) {\r
-                       dbHelper = new DBHelper(this);\r
-               }\r
                \r
                initService(); // start up the PWS service so other applications can query.\r
        }\r
diff --git a/src/org/openintents/safe/PackageAccessEntry.java b/src/org/openintents/safe/PackageAccessEntry.java
new file mode 100644 (file)
index 0000000..ca523e2
--- /dev/null
@@ -0,0 +1,24 @@
+/* $Id$
+ * 
+ * Copyright (C) 2009 OpenIntents.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+package org.openintents.safe;
+
+public class PackageAccessEntry extends Object {
+    public boolean needsDecrypt;
+    public boolean needsEncrypt=true;
+    public String packageAccess;
+    public String plainPackageAccess;
+}
index 1f180e0d57fcd9a755157fc0d730dcb37f87ff40..cdec050d2a0529a526d815c1bc524ec2dffb96e1 100644 (file)
 package org.openintents.safe;
 
 
+import org.openintents.intents.CryptoIntents;
+
 import android.app.Activity;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.content.ActivityNotFoundException;
+import android.content.BroadcastReceiver;
+import android.content.Context;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.net.Uri;
@@ -53,40 +57,49 @@ public class PassEdit extends Activity {
        public static final int GEN_PASSWORD_INDEX = Menu.FIRST + 3;
 
        public static final int RESULT_DELETED = RESULT_FIRST_USER;
-       
+
+    private Intent restartTimerIntent;
+
        private EditText descriptionText;
        private EditText passwordText;
        private EditText usernameText;
        private EditText websiteText;
        private EditText noteText;
        private Long RowId;
-       private DBHelper dbHelper = null;
-       private CryptoHelper ch;
        private boolean pass_gen_ret = false;
        private boolean discardEntry = false;
        public static boolean entryEdited = false;
+       boolean populated = false;
+       Intent frontdoor;
+
+    BroadcastReceiver mIntentReceiver = new BroadcastReceiver() {
+        public void onReceive(Context context, Intent intent) {
+            if (intent.getAction().equals(CryptoIntents.ACTION_CRYPTO_LOGGED_OUT)) {
+                if (debug) Log.d(TAG,"caught ACTION_CRYPTO_LOGGED_OUT");
+                frontdoor.setAction(Intent.ACTION_MAIN);
+                startActivity(frontdoor);
+            }
+        }
+    };
 
        public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
 
                if (debug) Log.d(TAG,"onCreate()");
+               
+               frontdoor = new Intent(this, FrontDoor.class);
+               if (!CategoryList.isSignedIn()) {
+                       startActivity(frontdoor);
+                       // normally we'd do a finish() here, but
+                       // by starting frontdoor from here the user could
+                       // potentially find this activity and continue editing
+       }
+               restartTimerIntent = new Intent (CryptoIntents.ACTION_RESTART_TIMER);
+
                String title = getResources().getString(R.string.app_name) + " - "
                                + getResources().getString(R.string.edit_entry);
                setTitle(title);
 
-               ch = new CryptoHelper();
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium,PassList.getSalt());
-                       ch.setPassword(PassList.getMasterKey());
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e1.getMessage(), Toast.LENGTH_SHORT).show();
-               }
-
-               if (dbHelper == null) {
-                       dbHelper = new DBHelper(this);
-               }
 
                setContentView(R.layout.pass_edit);
 
@@ -134,7 +147,9 @@ public class PassEdit extends Activity {
                                }
                        }
                });
+               restoreMe();
 
+               sendBroadcast (restartTimerIntent);
        }
 
        @Override
@@ -153,8 +168,6 @@ public class PassEdit extends Activity {
                if (isFinishing() && discardEntry==false) {
                        savePassword();
                }
-               dbHelper.close();
-               dbHelper = null;
        }
 
        @Override
@@ -163,9 +176,6 @@ public class PassEdit extends Activity {
 
                if (debug) Log.d(TAG,"onResume()");
 
-               if (dbHelper == null) {
-                       dbHelper = new DBHelper(this);
-               }
                if (CategoryList.isSignedIn() == false) {
                        saveState();
                        finish();
@@ -176,33 +186,24 @@ public class PassEdit extends Activity {
        private void saveState() {
                PassEntry entry = new PassEntry();
 
-               String passwordPlain = passwordText.getText().toString();
-               String notePlain = noteText.getText().toString();
-               String usernamePlain = usernameText.getText().toString();
-               String websitePlain = websiteText.getText().toString();
-               String descPlain = descriptionText.getText().toString();
-
-               try {
-                       entry.category = PassList.getCategoryId();
-                       entry.description = ch.encrypt(descPlain);
-                       entry.username = ch.encrypt(usernamePlain);
-                       entry.password = ch.encrypt(passwordPlain);
-                       entry.note = ch.encrypt(notePlain);
-                       entry.website = ch.encrypt(websitePlain);
-               } catch (CryptoHelperException e) {
-                       Log.e(TAG, e.toString());
-               }
+               entry.category = PassList.getCategoryId();
+               entry.plainDescription = descriptionText.getText().toString();
+               entry.plainWebsite = websiteText.getText().toString();
+               entry.plainUsername = usernameText.getText().toString();
+               entry.plainPassword = passwordText.getText().toString();
+               entry.plainNote = noteText.getText().toString();
 
                entryEdited = true;
 
                if (RowId == null || RowId == -1) {
                        entry.id = 0;   // brand new entry
-                       RowId = dbHelper.addPassword(entry);
+                       RowId = Passwords.putPassEntry(entry);
                } else {
-                       PassEntry storedEntry = dbHelper.fetchPassword (RowId);
+                       entry.id=RowId;
+                       PassEntry storedEntry = Passwords.getPassEntry(RowId, true, false);
                        //update fields that aren't set in the UI:
                        entry.uniqueName = storedEntry.uniqueName;
-                       dbHelper.updatePassword(RowId, entry);
+                       Passwords.putPassEntry(entry);
                }
        }
 
@@ -275,7 +276,7 @@ public class PassEdit extends Activity {
         * @param Id
         */
        private void delPassword(long Id) {
-               dbHelper.deletePassword(Id);
+               Passwords.deletePassEntry(Id);
                discardEntry=true;
                setResult(RESULT_DELETED);
                finish();
@@ -330,24 +331,40 @@ public class PassEdit extends Activity {
                        pass_gen_ret = false;
                        return;
                }
-               if (RowId != null) {
-                       PassEntry row = dbHelper.fetchPassword(RowId);
-                       if (row.id > -1) {
-                               String cryptDesc = row.description;
-                               String cryptWebsite = row.website;
-                               String cryptUsername = row.username;
-                               String cryptPass = row.password;
-                               String cryptNote = row.note;
-                               try {
-                                       descriptionText.setText(ch.decrypt(cryptDesc));
-                                       websiteText.setText(ch.decrypt(cryptWebsite));
-                                       usernameText.setText(ch.decrypt(cryptUsername));
-                                       passwordText.setText(ch.decrypt(cryptPass));
-                                       noteText.setText(ch.decrypt(cryptNote));
-                               } catch (CryptoHelperException e) {
-                                       Log.e(TAG, e.toString());
-                               }
-                       }
+               if (debug) Log.d(TAG,"populateFields: populated="+populated);
+               if (populated) {
+                       return;
+               }
+               if ((RowId != null) && (RowId != -1)) {
+                       PassEntry passEntry = Passwords.getPassEntry(RowId, true, false);
+                       descriptionText.setText(passEntry.plainDescription);
+                       websiteText.setText(passEntry.plainWebsite);
+                       usernameText.setText(passEntry.plainUsername);
+                       passwordText.setText(passEntry.plainPassword);
+                       noteText.setText(passEntry.plainNote);
                }
+               populated=true;
        }
+       
+       @Override  
+       public Object onRetainNonConfigurationInstance() {  
+               String nonConfig;
+               if (populated==true) {
+                       nonConfig="true";
+               }else {
+                       nonConfig="false";
+               }
+               return(nonConfig);  
+       }  
+       
+       private void restoreMe() {  
+               String nonConfig;
+       
+               if (getLastNonConfigurationInstance()!=null) {  
+                       nonConfig=(String) getLastNonConfigurationInstance();
+                       if (nonConfig.compareTo("true")==0) {
+                               populated=true;
+                       }
+               }  
+       }  
 }
index 6a7112a1d09230e0d1c0d7aeab1643469066113d..71f8d8981515efb0d6e20cc73735d349202cc4b5 100644 (file)
@@ -23,8 +23,11 @@ import java.util.ArrayList;
  * @author Steven Osborn - http://steven.bitsetters.com\r
  */\r
 public class PassEntry extends Object {\r
+    public long id=-1;\r
+    public boolean needsDecryptDescription;\r
+    public boolean needsDecrypt;\r
+    public boolean needsEncrypt=true;\r
     public String password;\r
-    public long id;\r
     public long category;\r
     public String categoryName;\r
     public String description;\r
@@ -38,6 +41,7 @@ public class PassEntry extends Object {
     public String plainUsername;\r
     public String plainWebsite;\r
     public String plainNote;\r
+    public String plainUniqueName;\r
     public String lastEdited;\r
     \r
     public static boolean checkPackageAccess (ArrayList<String> packageAccess, String packageName) {\r
index 49d60f24b850fe1cf68ab2d594feab3ab2a9405b..287428f53aa455f32b1f4deaae35ff43e1e23008 100644 (file)
@@ -18,9 +18,8 @@ package org.openintents.safe;
 
 import java.util.ArrayList;
 import java.util.Arrays;
-import java.util.Collections;
-import java.util.Comparator;
 import java.util.HashMap;
+import java.util.Iterator;
 import java.util.List;
 import java.util.Set;
 
@@ -29,9 +28,12 @@ import org.openintents.intents.CryptoIntents;
 import android.app.AlertDialog;
 import android.app.Dialog;
 import android.app.ListActivity;
+import android.app.ProgressDialog;
 import android.content.DialogInterface;
 import android.content.Intent;
 import android.os.Bundle;
+import android.os.Handler;
+import android.os.Message;
 import android.util.Log;
 import android.view.ContextMenu;
 import android.view.Menu;
@@ -55,7 +57,7 @@ import android.widget.AdapterView.AdapterContextMenuInfo;
  */
 public class PassList extends ListActivity {
 
-       private static final boolean debug= false;
+       private static final boolean debug = false;
     private static final String TAG = "PassList";
 
     // Menu Item order
@@ -69,20 +71,47 @@ public class PassList extends ListActivity {
     public static final int REQUEST_EDIT_PASSWORD = 2;
     public static final int REQUEST_ADD_PASSWORD = 3;
     public static final int REQUEST_MOVE_PASSWORD = 4;
+
+    protected static final int MSG_UPDATE_LIST = 0x101; 
+
+    private static final int DECRYPT_PROGRESS_KEY = 0;
     
     public static final String KEY_ID = "id";  // Intent keys
     public static final String KEY_CATEGORY_ID = "categoryId";  // Intent keys
 
-    private CryptoHelper ch;
-    private DBHelper dbHelper=null;
     private static Long CategoryId=null;
     private Intent restartTimerIntent;
 
     private static String salt;
-    private static String masterKey;                   
+    private static String masterKey;
+    
+       private Thread fillerThread=null;
 
     private List<PassEntry> rows;
-    
+    private int lastPosition=0;
+       List<String> passDescriptions=new ArrayList<String>();
+
+       public Handler myViewUpdateHandler = new Handler(){
+               // @Override
+               public void handleMessage(Message msg) {
+                       switch (msg.what) {
+                               case PassList.MSG_UPDATE_LIST:
+                                       ArrayAdapter<String> entries = 
+                                           new ArrayAdapter<String>(PassList.this, android.R.layout.simple_list_item_1,
+                                                       passDescriptions);
+                                       setListAdapter(entries);
+
+                                       if (debug) Log.d(TAG,"lastPosition="+lastPosition);
+                                       if (lastPosition>2) {
+                                               setSelection(lastPosition-1);
+                                               lastPosition=0;
+                                       }
+                                       break;
+                       }
+                       super.handleMessage(msg);
+               }
+       }; 
+
     /** 
      * Called when the activity is first created. 
      */
@@ -91,12 +120,13 @@ public class PassList extends ListActivity {
                super.onCreate(icicle);
                
                if (debug) Log.d(TAG,"onCreate()");
+               if (!CategoryList.isSignedIn()) {
+                       finish();
+       }
                restartTimerIntent = new Intent (CryptoIntents.ACTION_RESTART_TIMER);
+
                setContentView(R.layout.pass_list);
                
-               if (dbHelper==null) {
-                       dbHelper = new DBHelper(this);
-               }
                CategoryId = icicle != null ? icicle.getLong(CategoryList.KEY_ID) : null;
                if (CategoryId == null) {
                    Bundle extras = getIntent().getExtras();            
@@ -106,7 +136,7 @@ public class PassList extends ListActivity {
                        finish();       // no valid category less than one
                }
                
-               String categoryName=getCategoryName(CategoryId);
+               String categoryName=Passwords.getCategoryEntry(CategoryId).plainName;
                String title = getResources().getString(R.string.app_name) + " - " +
                        getResources().getString(R.string.passwords) + " -" +
                        categoryName;
@@ -118,6 +148,8 @@ public class PassList extends ListActivity {
                list.setFocusable(true);
                list.setOnCreateContextMenuListener(this);
                registerForContextMenu(list);
+               
+               sendBroadcast (restartTimerIntent);
     }
     
        @Override
@@ -137,9 +169,11 @@ public class PassList extends ListActivity {
                super.onPause();
                
                if (debug) Log.d(TAG,"onPause()");
-               if (dbHelper != null) {
-                       dbHelper.close();
-                       dbHelper = null;
+               if ((fillerThread != null) && (fillerThread.isAlive())) {
+                       if (debug) Log.d(TAG,"wait for thread");
+                       int maxWaitToDie=500000;
+                       try { fillerThread.join(maxWaitToDie); } 
+                       catch(InterruptedException e){} //  ignore 
                }
     }
 
@@ -152,9 +186,6 @@ public class PassList extends ListActivity {
                if (CategoryList.isSignedIn()==false) {
                        finish();
                }
-               if (dbHelper == null) {
-                   dbHelper = new DBHelper(this);
-               }
     }
     
     @Override
@@ -162,10 +193,6 @@ public class PassList extends ListActivity {
                super.onStop();
                
                if (debug) Log.d(TAG,"onStop()");
-               if (dbHelper != null) {
-                       dbHelper.close();
-                       dbHelper=null;
-               }
     }
     @Override
     public void onCreateContextMenu(ContextMenu menu, View view,
@@ -194,54 +221,53 @@ public class PassList extends ListActivity {
                return true;
     }
 
+    @Override
+    protected Dialog onCreateDialog(int id) {
+        switch (id) {
+               case DECRYPT_PROGRESS_KEY: {
+                   ProgressDialog dialog = new ProgressDialog(this);
+                   dialog.setMessage(getString(R.string.decrypt_progress));
+                   dialog.setIndeterminate(false);
+                   dialog.setCancelable(true);
+                   return dialog;
+               }
+        }
+        return null;
+    }
+
     /**
      * Populates the password ListView
      */
-    private void fillData() {
-               // initialize crypto so that we can display readable descriptions in
-               // the list view
-               ch = new CryptoHelper();
-               if(masterKey == null) {
-                   masterKey = "";
-               }
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium, salt);
-                       ch.setPassword(masterKey);
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                                       + e1.getMessage(), Toast.LENGTH_SHORT).show();
-                       return;
-               }
-       
-               List<String> items = new ArrayList<String>();
-               rows = dbHelper.fetchAllRows(CategoryId);
-
-               for (PassEntry row : rows) {
-                   String cryptDesc = row.description;
-                   row.plainDescription = "";
-                   try {
-                               row.plainDescription = ch.decrypt(cryptDesc);
-                   } catch (CryptoHelperException e) {
-                               Log.e(TAG,e.toString());
-                   }
-               }
-               Collections.sort(rows, new Comparator<PassEntry>() {
-                   public int compare(PassEntry o1, PassEntry o2) {
-                       return o1.plainDescription.compareToIgnoreCase(o2.plainDescription);
-                   }});
-               for (PassEntry row : rows) {
-                       items.add(row.plainDescription);
-               }
-
-               ArrayAdapter<String> entries = 
-                   new ArrayAdapter<String>(this, android.R.layout.simple_list_item_1, items);
-               setListAdapter(entries);
-               
-    }
+       private void fillData() {
+               showDialog(DECRYPT_PROGRESS_KEY);
+
+               fillerThread = new Thread(new Runnable() {
+                       public void run(){
+                               rows=Passwords.getPassEntries(CategoryId, true, true);
+                               passDescriptions.clear();
+                               Iterator<PassEntry> passIter=rows.iterator();
+                               while (passIter.hasNext()) {
+                                       PassEntry passEntry=passIter.next();
+                                       passDescriptions.add(passEntry.plainDescription);
+                               }
+//                             dismissDialog(DECRYPT_PROGRESS_KEY);
+                               // forced to removeDialog(), without it
+                               // after an orientation change dismissDialog()
+                               // would crash
+                               removeDialog(DECRYPT_PROGRESS_KEY);
+
+                               Message mu = new Message();
+                               mu.what = PassList.MSG_UPDATE_LIST;
+                               PassList.this.myViewUpdateHandler.sendMessage(mu); 
+                       }
+               });
+               fillerThread.start();
+       }
 
     @Override
     public boolean onMenuOpened(int featureId, Menu menu) {
+               sendBroadcast (restartTimerIntent);
+
        if (menu == null) {
                return super.onMenuOpened(featureId, menu);
        }
@@ -328,6 +354,7 @@ public class PassList extends ListActivity {
         */
        public void deletePassword2(int position){
            try {
+               lastPosition=position;
                delPassword(rows.get(position).id);
            } catch (IndexOutOfBoundsException e) {
                        // This should only happen when there are no
@@ -337,7 +364,7 @@ public class PassList extends ListActivity {
        }
 
     private void delPassword(long Id) {
-               dbHelper.deletePassword(Id);
+               Passwords.deletePassEntry(Id);
                fillData();
     }
     
@@ -348,8 +375,8 @@ public class PassList extends ListActivity {
      * @param passwordId
      */
     private void movePassword(final long passwordId) {
-        final HashMap<String, Long> categoryToId=CategoryList.getCategoryToId(dbHelper);
-        String categoryName=getCategoryName(CategoryId);
+        final HashMap<String, Long> categoryToId=Passwords.getCategoryNameToId();
+        String categoryName=Passwords.getCategoryEntry(CategoryId).plainName;
         categoryToId.remove(categoryName);
         Set<String> categories=categoryToId.keySet();
         final String[] items=(String[])categories.toArray(new String[categories.size()]);
@@ -361,7 +388,7 @@ public class PassList extends ListActivity {
                        public void onClick(DialogInterface dialog, int which) {
 
                                long newCategoryId=categoryToId.get(items[which]);
-                               dbHelper.updatePasswordCategory(passwordId, newCategoryId);
+                               Passwords.updatePassCategory(passwordId, newCategoryId);
                                String result=getString(R.string.moved_to) + " " + items[which];
                        Toast.makeText(PassList.this, result,
                                        Toast.LENGTH_LONG).show();
@@ -391,18 +418,21 @@ public class PassList extends ListActivity {
                        vi.putExtra(KEY_ID, rows.get(position).id);
                        vi.putExtra(KEY_CATEGORY_ID, CategoryId);
                        startActivityForResult(vi,REQUEST_VIEW_PASSWORD);
+                       lastPosition=position;
                    break;
                case EDIT_PASSWORD_INDEX:
                        Intent i = new Intent(this, PassEdit.class);
                        i.putExtra(KEY_ID, rows.get(position).id);
                        i.putExtra(KEY_CATEGORY_ID, CategoryId);
                        startActivityForResult(i,REQUEST_EDIT_PASSWORD);
+                       lastPosition=position;
                        break;
                case DEL_PASSWORD_INDEX:
                        deletePassword(position);
                    break;
                case MOVE_PASSWORD_INDEX:
                        movePassword(rows.get(position).id);
+                       lastPosition=position;
                        break;
                }
                return super.onOptionsItemSelected(item);
@@ -422,9 +452,6 @@ public class PassList extends ListActivity {
        super.onActivityResult(requestCode, resultCode, i);
        //Log.d(TAG, "onActivityResult. requestCode: " + requestCode + ", resultCode: " + resultCode);
 
-       if (dbHelper == null) {
-                   dbHelper = new DBHelper(this);
-               }
        if (((requestCode==REQUEST_VIEW_PASSWORD)&&(PassView.entryEdited)) ||
                ((requestCode==REQUEST_EDIT_PASSWORD)&&(PassEdit.entryEdited)) ||
                ((requestCode==REQUEST_ADD_PASSWORD)&&(PassEdit.entryEdited)) ||
@@ -432,28 +459,4 @@ public class PassList extends ListActivity {
                fillData();
        }
     }
-    
-    /**
-     * Retrieve the decrypted category name based on the provided id.
-     *  
-     * @param Id category id
-     * @return decrypted category name
-     */
-    private String getCategoryName(long Id) {
-               CategoryEntry category=dbHelper.fetchCategory(Id);
-               category.plainName="";
-               if (ch==null) {
-                       ch=new CryptoHelper();
-               }
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium, salt);
-                       ch.setPassword(masterKey);
-                       category.plainName = ch.decrypt(category.name);
-           } catch (CryptoHelperException e) {
-                       Log.e(TAG,e.toString());
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e.getMessage(), Toast.LENGTH_SHORT).show();
-           }
-           return category.plainName;
-    }
 }
index 70877fab7d48462e2b791b4a3c33167622a81532..d29545d826470379ab05ac6659ce396eb1d936ab 100644 (file)
@@ -63,32 +63,20 @@ public class PassView extends Activity {
        private TextView packageAccessText;
        private Long RowId;
        private Long CategoryId;
-       private DBHelper dbHelper = null;
-       private CryptoHelper ch;
        public static boolean entryEdited=false;
 
        public void onCreate(Bundle icicle) {
                super.onCreate(icicle);
 
                if (debug) Log.d(TAG,"onCreate()");
+               if (!CategoryList.isSignedIn()) {
+                       finish();
+       }
+
                String title = getResources().getString(R.string.app_name) + " - "
                                + getResources().getString(R.string.view_entry);
                setTitle(title);
 
-               ch = new CryptoHelper();
-               try {
-                       ch.init(CryptoHelper.EncryptionMedium, PassList.getSalt());
-                       ch.setPassword(PassList.getMasterKey());
-               } catch (CryptoHelperException e1) {
-                       e1.printStackTrace();
-                       Toast.makeText(this,getString(R.string.crypto_error)
-                               + e1.getMessage(), Toast.LENGTH_SHORT).show();
-               }
-
-               if (dbHelper == null) {
-                       dbHelper = new DBHelper(this);
-               }
-
                setContentView(R.layout.pass_view);
 
                descriptionText = (TextView) findViewById(R.id.description);
@@ -162,8 +150,6 @@ public class PassView extends Activity {
        @Override
        protected void onPause() {
                super.onPause();
-               dbHelper.close();
-               dbHelper = null;
        }
 
        @Override
@@ -172,13 +158,9 @@ public class PassView extends Activity {
 
                if (debug) Log.d(TAG,"onResume()");
 
-               if (dbHelper == null) {
-                       dbHelper = new DBHelper(this);
-               }
                if (CategoryList.isSignedIn() == false) {
                        finish();
                }
-//             populateFields();
        }
 
        @Override
@@ -236,7 +218,7 @@ public class PassView extends Activity {
         * @param Id
         */
        private void delPassword(long Id) {
-               dbHelper.deletePassword(Id);
+               Passwords.deletePassEntry(Id);
                setResult(RESULT_OK);
                finish();
        }
@@ -285,61 +267,43 @@ public class PassView extends Activity {
        private void populateFields() {
                if (debug) Log.d(TAG,"populateFields()");
                if (RowId != null) {
-                       if (dbHelper == null) {
-                               dbHelper = new DBHelper(this);
+                       PassEntry row = Passwords.getPassEntry(RowId, true, false);
+               ArrayList<String> packageAccess = Passwords.getPackageAccess(RowId);
+                       descriptionText.setText(row.plainDescription);
+                       websiteText.setText(row.plainWebsite);
+                       usernameText.setText(row.plainUsername);
+                       passwordText.setText(row.plainPassword);
+                       noteText.setText(row.plainNote);
+                       String lastEdited;
+                       if (row.lastEdited!=null) {
+                               lastEdited=row.lastEdited;
+                       } else {
+                               lastEdited=getString(R.string.last_edited_unknown);
                        }
-                       PassEntry row = dbHelper.fetchPassword(RowId);
-                       if (row.id > -1) {
-                               String cryptDesc = row.description;
-                               String cryptWebsite = row.website;
-                               String cryptUsername = row.username;
-                               String cryptPass = row.password;
-                               String cryptNote = row.note;
-                               String cryptUniqueName = row.uniqueName;
-                       ArrayList<String> packageAccess = dbHelper.fetchPackageAccess(row.id);
-                               try {
-                                       descriptionText.setText(ch.decrypt(cryptDesc));
-                                       websiteText.setText(ch.decrypt(cryptWebsite));
-                                       usernameText.setText(ch.decrypt(cryptUsername));
-                                       passwordText.setText(ch.decrypt(cryptPass));
-                                       noteText.setText(ch.decrypt(cryptNote));
-                                       String lastEdited;
-                                       if (row.lastEdited!=null) {
-                                               lastEdited=row.lastEdited;
-                                       } else {
-                                               lastEdited=getString(R.string.last_edited_unknown);
-                                       }
-                                       lastEditedText.setText(getString(R.string.last_edited)+": "+lastEdited);
-                                       if (cryptUniqueName!=null) {
-                                               String plainUniqueName=ch.decrypt(cryptUniqueName);
-                                               if (plainUniqueName!="") {
-                                                       uniqueNameText.setText(getString(R.string.uniquename)+
-                                                                       ": "+plainUniqueName);
-                                               }
-                                       }
-                                       String packages="";
-                                       if (packageAccess!=null) {
-                                               for (String packageName : packageAccess) {
-                                                       String plainPackageName=ch.decrypt(packageName);
-                                                       PackageManager pm=getPackageManager();
-                                                       String appLabel="";
-                                                       try {
-                                                               ApplicationInfo ai=pm.getApplicationInfo(plainPackageName,0);
-                                                               appLabel=pm.getApplicationLabel(ai).toString();
-                                                       } catch (NameNotFoundException e) {
-                                                               appLabel="("+getString(R.string.not_found)+")";
-                                                       }
-                                                       packages+=plainPackageName+" "+appLabel+" ";
-                                               }
-                                       }
-                                       if (packages!="") {
-                                               packageAccessText.setText(getString(R.string.package_access)+
-                                                               ": "+packages);
+                       lastEditedText.setText(getString(R.string.last_edited)+": "+lastEdited);
+                       if (row.plainUniqueName!=null) {
+                               uniqueNameText.setText(getString(R.string.uniquename)+
+                                               ": "+row.plainUniqueName);
+                       }
+                       String packages="";
+                       if (packageAccess!=null) {
+                               for (String packageName : packageAccess) {
+                                       if (debug) Log.d(TAG,"packageName="+packageName);
+                                       PackageManager pm=getPackageManager();
+                                       String appLabel="";
+                                       try {
+                                               ApplicationInfo ai=pm.getApplicationInfo(packageName,0);
+                                               appLabel=pm.getApplicationLabel(ai).toString();
+                                       } catch (NameNotFoundException e) {
+                                               appLabel="("+getString(R.string.not_found)+")";
                                        }
-                               } catch (CryptoHelperException e) {
-                                       Log.e(TAG, e.toString());
+                                       packages+=packageName+" "+appLabel+" ";
                                }
                        }
+                       if (packages!="") {
+                               packageAccessText.setText(getString(R.string.package_access)+
+                                               ": "+packages);
+                       }
                }
        }
 }
diff --git a/src/org/openintents/safe/Passwords.java b/src/org/openintents/safe/Passwords.java
new file mode 100644 (file)
index 0000000..d009d50
--- /dev/null
@@ -0,0 +1,477 @@
+/* 
+ * Copyright (C) 2009 OpenIntents.org
+ *
+ * Licensed under the Apache License, Version 2.0 (the "License");
+ * you may not use this file except in compliance with the License.
+ * You may obtain a copy of the License at
+ *
+ *      http://www.apache.org/licenses/LICENSE-2.0
+ *
+ * Unless required by applicable law or agreed to in writing, software
+ * distributed under the License is distributed on an "AS IS" BASIS,
+ * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
+ * See the License for the specific language governing permissions and
+ * limitations under the License.
+ */
+
+package org.openintents.safe;
+
+import java.util.ArrayList;
+import java.util.Collection;
+import java.util.Collections;
+import java.util.Comparator;
+import java.util.HashMap;
+import java.util.Iterator;
+import java.util.List;
+import java.util.Set;
+
+import android.content.Context;
+import android.util.Log;
+
+/**
+ * Abstraction layer for storing encrypted and decrypted versions
+ * of all PassEntry and CategoryEntry data.
+ * Handles fetching and storing with DBHelper
+ * and encrypt/decrypt of data.
+ * 
+ * @author Randy McEoin
+ *
+ */
+public class Passwords {
+
+       private static final boolean debug = false;
+    private static final String TAG = "Passwords";
+
+       private static HashMap<Long, PassEntry> passEntries=null;
+       
+       private static HashMap<Long, CategoryEntry> categoryEntries=null;
+       
+       private static HashMap<Long, ArrayList<PackageAccessEntry>> packageAccessEntries=null;
+       
+       private static CryptoHelper ch=null;
+       private static DBHelper dbHelper=null;
+       
+       public static void Initialize(Context ctx) {
+               if (debug) Log.d(TAG,"Initialize()");
+
+               if (ch==null) {
+                       ch = new CryptoHelper();
+               }
+               if (dbHelper==null) {
+                       dbHelper = new DBHelper(ctx);
+               }
+               if (passEntries==null) {
+                       passEntries = new HashMap<Long, PassEntry>();
+                       InitPassEntries();
+               }
+               if (categoryEntries==null) {
+                       categoryEntries = new HashMap<Long, CategoryEntry>();
+                       InitCategoryEntries();
+               }
+               if (packageAccessEntries==null) {
+                       packageAccessEntries = new HashMap<Long, ArrayList<PackageAccessEntry>>();
+                       InitPackageAccess();
+               }
+       }
+
+       /**
+        * Force a fresh load from the database.
+        */
+       public static void Reset() {
+               categoryEntries.clear();
+               InitCategoryEntries();
+               passEntries.clear();
+               InitPassEntries();
+               packageAccessEntries.clear();
+               InitPackageAccess();
+       }
+       
+       public static void InitCrypto(int strength, String salt, String masterKey) 
+               throws Exception {
+               try {
+                       ch.init(strength,salt);
+                       ch.setPassword(masterKey);
+               } catch (CryptoHelperException e1) {
+                       e1.printStackTrace();
+                       throw new Exception("Error with Passwords.InitCrypto: "+
+                                       e1.getLocalizedMessage());
+               }
+       }
+
+       public static void deleteAll() {
+               dbHelper.deleteDatabase();
+               Reset();
+       }
+       
+       public static boolean getPrePopulate() {
+               return dbHelper.getPrePopulate();
+       }
+       
+       public static void clearPrePopulate() {
+               dbHelper.clearPrePopulate();
+       }
+       
+       public static String fetchSalt() {
+               return dbHelper.fetchSalt();
+       }
+       
+       public static String fetchMasterKeyEncrypted() {
+               return dbHelper.fetchMasterKey();
+       }
+       ///////////////////////////////////////////////////
+       ///////////// Category Functions //////////////////
+       ///////////////////////////////////////////////////
+
+       private static void InitCategoryEntries() {
+               List<CategoryEntry> catRows;
+               catRows = dbHelper.fetchAllCategoryRows();
+               for (CategoryEntry catRow : catRows) {
+                       catRow.nameNeedsDecrypt=true;
+                       catRow.plainNameNeedsEncrypt=false;
+                       categoryEntries.put(catRow.id, catRow);
+               }
+       }
+
+       public static List<CategoryEntry> getCategoryEntries() {
+               Collection<CategoryEntry> categories=categoryEntries.values();
+               Iterator<CategoryEntry> catIter=categories.iterator();
+               while (catIter.hasNext()) {
+                       CategoryEntry catEntry=catIter.next();
+                       // run through and ensure all entries are decrypted
+                       getCategoryEntry(catEntry.id);
+               }
+               List<CategoryEntry> catList=new ArrayList<CategoryEntry>(categories);
+               Collections.sort(catList, new Comparator<CategoryEntry>() {
+                   public int compare(CategoryEntry o1, CategoryEntry o2) {
+                       return o1.plainName.compareToIgnoreCase(o2.plainName);
+                   }});
+               return catList;
+       }
+       
+       public static List<String> getCategoryNames() {
+               List<String> items = new ArrayList<String>();
+
+               List<CategoryEntry> catList=getCategoryEntries();
+               for (CategoryEntry row : catList) {
+                       items.add(row.plainName);
+               }
+               return items;
+       }
+       
+       public static HashMap<Long, String> getCategoryIdToName() {
+               HashMap<Long, String> categoryMap = new HashMap<Long, String>();
+               Collection<CategoryEntry> categories=categoryEntries.values();
+               Iterator<CategoryEntry> catIter=categories.iterator();
+               while (catIter.hasNext()) {
+                       CategoryEntry catEntry=catIter.next();
+                       // run through and ensure all entries are decrypted
+                       getCategoryEntry(catEntry.id);
+                       categoryMap.put(catEntry.id, catEntry.plainName);
+               }
+               return categoryMap;
+       }
+       
+       public static HashMap<String, Long> getCategoryNameToId() {
+               HashMap<String, Long> categoryMap = new HashMap<String, Long>();
+               Collection<CategoryEntry> categories=categoryEntries.values();
+               Iterator<CategoryEntry> catIter=categories.iterator();
+               while (catIter.hasNext()) {
+                       CategoryEntry catEntry=catIter.next();
+                       // run through and ensure all entries are decrypted
+                       getCategoryEntry(catEntry.id);
+                       categoryMap.put(catEntry.plainName, catEntry.id);
+                       if (debug) Log.d(TAG,"map "+catEntry.plainName+" to "+catEntry.id);
+               }
+               return categoryMap;
+       }
+       
+       public static CategoryEntry getCategoryEntryByName(String category) {
+               Collection<CategoryEntry> categories=categoryEntries.values();
+               Iterator<CategoryEntry> catIter=categories.iterator();
+               while (catIter.hasNext()) {
+                       CategoryEntry catEntry=catIter.next();
+                       if (catEntry.name.compareTo(category)==0) {
+                               return catEntry;
+                       }
+               }
+               return null;
+       }
+       
+       public static CategoryEntry getCategoryEntry(Long id) {
+               CategoryEntry catEntry=categoryEntries.get(id);
+               if (catEntry.nameNeedsDecrypt) {
+                       if (debug) Log.d(TAG,"decrypt cat");
+                   try {
+                               catEntry.plainName = ch.decrypt(catEntry.name);
+                   } catch (CryptoHelperException e) {
+                               Log.e(TAG,e.toString());
+                   }
+                   catEntry.nameNeedsDecrypt=false;
+                       categoryEntries.put(id, catEntry);
+               }
+               return catEntry;
+       }
+       
+       public static long putCategoryEntry(CategoryEntry catEntry) {
+               if (catEntry.plainNameNeedsEncrypt) {
+                       if (debug) Log.d(TAG,"encrypt cat");
+                   try {
+                               catEntry.name = ch.encrypt(catEntry.plainName);
+                   } catch (CryptoHelperException e) {
+                               Log.e(TAG,e.toString());
+                   }
+                   catEntry.plainNameNeedsEncrypt=false;
+               }
+               if (catEntry.id==-1) {
+                       catEntry.id=dbHelper.addCategory(catEntry);
+               } else {
+                       dbHelper.updateCategory(catEntry.id, catEntry);
+               }
+               categoryEntries.put(catEntry.id, catEntry);
+               return catEntry.id;
+       }
+       
+       public static void deleteCategoryEntry(long id) {
+               if (debug) Log.d(TAG,"deleteCategoryEntry("+id+")");
+               dbHelper.deleteCategory(id);
+               categoryEntries.remove(id);
+       }
+
+       ///////////////////////////////////////////////////
+       ///////////// Password Functions //////////////////
+       ///////////////////////////////////////////////////
+
+       private static void InitPassEntries() {
+               List<PassEntry> passRows;
+               passRows = dbHelper.fetchAllRows(new Long(0));
+               for (PassEntry passRow : passRows) {
+                       passRow.needsDecryptDescription=true;
+                       passRow.needsDecrypt=true;
+                       passRow.needsEncrypt=false;
+                       passEntries.put(passRow.id, passRow);
+               }
+       }
+
+       public static List<PassEntry> getPassEntries(long categoryId, boolean decrypt, boolean descriptionOnly) {
+               Collection<PassEntry> passwords=passEntries.values();
+               List<PassEntry> passList=new ArrayList<PassEntry>();
+               Iterator<PassEntry> passIter=passwords.iterator();
+               while (passIter.hasNext()) {
+                       PassEntry passEntry=passIter.next();
+                       if ((categoryId==0) || (passEntry.category==categoryId)) {
+                               getPassEntry(passEntry.id, decrypt, descriptionOnly);
+                               passList.add(passEntry);
+                       }
+               }
+               if (decrypt==true) {
+                       Collections.sort(passList, new Comparator<PassEntry>() {
+                           public int compare(PassEntry o1, PassEntry o2) {
+                               return o1.plainDescription.compareToIgnoreCase(o2.plainDescription);
+                           }});
+               }
+               return passList;
+       }
+       
+       public static HashMap<Long, String> getPassIdToDescriptionOLD() {
+               HashMap<Long, String> passMap = new HashMap<Long, String>();
+               Collection<PassEntry> passwords=passEntries.values();
+               Iterator<PassEntry> passIter=passwords.iterator();
+               while (passIter.hasNext()) {
+                       PassEntry passEntry=passIter.next();
+                       // run through and ensure all entries are decrypted
+                       getPassEntry(passEntry.id, true, true);
+                       passMap.put(passEntry.id, passEntry.plainDescription);
+               }
+               return passMap;
+       }
+       
+       public static HashMap<String, Long> getPassDescriptionToIdOLD() {
+               HashMap<String, Long> passMap = new HashMap<String, Long>();
+               Collection<PassEntry> passwords=passEntries.values();
+               Iterator<PassEntry> passIter=passwords.iterator();
+               while (passIter.hasNext()) {
+                       PassEntry passEntry=passIter.next();
+                       // run through and ensure all entries are decrypted
+                       getPassEntry(passEntry.id, true, true);
+                       passMap.put(passEntry.plainDescription, passEntry.id);
+               }
+               return passMap;
+       }
+       
+       public static PassEntry getPassEntry(Long id, boolean decrypt, boolean descriptionOnly) {
+               if (debug) Log.d(TAG,"getPassEntry("+id+")");
+               PassEntry passEntry=passEntries.get(id);
+               if (passEntry==null) {
+                       return null;
+               }
+               if (decrypt==false) {
+                       return passEntry;
+               }
+               if (passEntry.needsDecryptDescription) {
+                       //if (debug) Log.d(TAG,"decrypt pass description");
+                   try {
+                               passEntry.plainDescription = ch.decrypt(passEntry.description);
+                   } catch (CryptoHelperException e) {
+                               Log.e(TAG,e.toString());
+                   }
+                   passEntry.needsDecryptDescription=false;
+                       passEntries.put(id, passEntry);
+               }
+               if (!descriptionOnly && passEntry.needsDecrypt) {
+                       if (debug) Log.d(TAG,"decrypt pass");
+                   try {
+                               passEntry.plainDescription = ch.decrypt(passEntry.description);
+                               passEntry.plainWebsite=ch.decrypt(passEntry.website);
+                               passEntry.plainUsername=ch.decrypt(passEntry.username);
+                               passEntry.plainPassword=ch.decrypt(passEntry.password);
+                               passEntry.plainNote=ch.decrypt(passEntry.note);
+                               passEntry.plainUniqueName=ch.decrypt(passEntry.uniqueName);
+                   } catch (CryptoHelperException e) {
+                               Log.e(TAG,e.toString());
+                   }
+                   passEntry.needsDecrypt=false;
+                       passEntries.put(id, passEntry);
+               }
+               return passEntry;
+       }
+       
+       public static PassEntry findPassWithUniqueName(String plainUniqueName) {
+               String uniqueName="";
+               try {
+                       uniqueName = ch.encrypt(plainUniqueName);
+               } catch (CryptoHelperException e) {
+                       Log.e(TAG,e.toString());
+                       return null;
+               }
+               Collection<PassEntry> passwords=passEntries.values();
+               Iterator<PassEntry> passIter=passwords.iterator();
+               while (passIter.hasNext()) {
+                       PassEntry passEntry=passIter.next();
+                       if (passEntry.uniqueName.compareTo(uniqueName)==0) {
+                               passEntry=getPassEntry(passEntry.id,true,false);
+                               return passEntry;
+                       }
+               }
+               return null;
+       }
+       public static long putPassEntry(PassEntry passEntry) {
+               if (debug) Log.d(TAG,"putPassEntry("+passEntry.id+")");
+               if (passEntry.needsEncrypt) {
+                       if (debug) Log.d(TAG,"encrypt pass");
+                   try {
+                               passEntry.description = ch.encrypt(passEntry.plainDescription);
+                               passEntry.website = ch.encrypt(passEntry.plainWebsite);
+                               passEntry.username = ch.encrypt(passEntry.plainUsername);
+                               passEntry.password = ch.encrypt(passEntry.plainPassword);
+                               passEntry.note = ch.encrypt(passEntry.plainNote);
+                               passEntry.uniqueName = ch.encrypt(passEntry.plainUniqueName);
+                   } catch (CryptoHelperException e) {
+                               Log.e(TAG,e.toString());
+                   }
+                   passEntry.needsEncrypt=false;
+               }
+               if (passEntry.id==0) {
+                       passEntry.id=dbHelper.addPassword(passEntry);
+               } else {
+                       dbHelper.updatePassword(passEntry.id, passEntry);
+               }
+               passEntries.put(passEntry.id, passEntry);
+               return passEntry.id;
+       }
+       
+       public static void deletePassEntry(long id) {
+               if (debug) Log.d(TAG,"deletePassEntry("+id+")");
+               dbHelper.deletePassword(id);
+               passEntries.remove(id);
+       }
+
+       public static void updatePassCategory(long passId, long categoryId) {
+               PassEntry passEntry=passEntries.get(passId);
+               passEntry.category=categoryId;
+               dbHelper.updatePasswordCategory(passId, categoryId);
+       }
+       
+       public static int countPasswords(long categoryId) {
+               return dbHelper.countPasswords(categoryId);
+       }
+
+       ///////////////////////////////////////////////////
+       ////////// Package Access Functions ///////////////
+       ///////////////////////////////////////////////////
+
+       private static void InitPackageAccess() {
+               HashMap<Long, ArrayList<String>> dbPackageAccess=dbHelper.fetchPackageAccessAll();
+               if (!dbPackageAccess.isEmpty()) {
+                       Set<Long> keys=dbPackageAccess.keySet();
+                       Iterator<Long> keysIter=keys.iterator();
+                       while (keysIter.hasNext()) {
+                               Long key=keysIter.next();
+                               ArrayList<PackageAccessEntry> packageNames=new ArrayList<PackageAccessEntry>();
+                               ArrayList<String> dbPackageNames=dbPackageAccess.get(key);
+                               Iterator<String> packIter=dbPackageNames.iterator();
+                               while (packIter.hasNext()) {
+                                       String packageName=packIter.next();
+                                       PackageAccessEntry packageAccess = new PackageAccessEntry(); 
+                                       packageAccess.packageAccess=packageName;
+                                       packageAccess.needsDecrypt=true;
+                                       packageAccess.needsEncrypt=false;
+                                       packageNames.add(packageAccess);
+                               }
+                               packageAccessEntries.put(key, packageNames);
+                       }
+               }
+       }
+
+       public static ArrayList<String> getPackageAccess(Long id) {
+               ArrayList<String> packageAccess=null;
+               if (packageAccessEntries.containsKey(id)) {
+                       ArrayList<PackageAccessEntry> packageAccessEntry=packageAccessEntries.get(id);
+                       Iterator<PackageAccessEntry> packIter=packageAccessEntry.iterator();
+                       packageAccess=new ArrayList<String>();
+                       while(packIter.hasNext()) {
+                               PackageAccessEntry packEntry=packIter.next();
+                               if (packEntry.needsDecrypt) {
+                                       try {
+                                               packEntry.plainPackageAccess=ch.decrypt(packEntry.packageAccess);
+                                   } catch (CryptoHelperException e) {
+                                               Log.e(TAG,e.toString());
+                                   }
+                               }
+                               packageAccess.add(packEntry.plainPackageAccess);
+                       }
+               }
+               return packageAccess;
+       }
+       
+       public static ArrayList<PackageAccessEntry> getPackageAccessEntries(Long id) {
+               if (packageAccessEntries.containsKey(id)) {
+                       return packageAccessEntries.get(id);
+               }
+               return null;
+       }
+       
+       public static void addPackageAccess(Long id, String packageName) {
+               String encryptedPackageName="";
+           try {
+                       encryptedPackageName = ch.encrypt(packageName);
+                       dbHelper.addPackageAccess(id, encryptedPackageName);
+           } catch (CryptoHelperException e) {
+                       Log.e(TAG,e.toString());
+               return;
+           }
+
+               ArrayList<PackageAccessEntry> packageNames;
+               if (packageAccessEntries.containsKey(id)) {
+                       packageNames=packageAccessEntries.get(id);
+               } else {
+                       packageNames=new ArrayList<PackageAccessEntry>();
+               }
+               PackageAccessEntry newPackageAccessEntry=new PackageAccessEntry();
+               newPackageAccessEntry.plainPackageAccess=packageName;
+               newPackageAccessEntry.packageAccess=encryptedPackageName;
+               newPackageAccessEntry.needsDecrypt=false;
+               newPackageAccessEntry.needsEncrypt=false;
+               packageNames.add(newPackageAccessEntry);
+               packageAccessEntries.put(id, packageNames);
+       }
+}
index 2a2d2ea53df111459a68f736b0976017539864e1..9b98ec90cc4466dd58879909dbd6d1242533d4ee 100644 (file)
@@ -308,6 +308,7 @@ public class Restore extends Activity {
                }
                dbHelper.commit();
                dbHelper.close();
+               Passwords.Reset();
 
                Toast.makeText(Restore.this, getString(R.string.restore_complete, 
                                Integer.toString(totalPasswords)),