/// <summary> /// Compares two list of histories to find the last place in which they differ /// </summary> /// <param name="low">low index of array</param> /// <param name="high">high index of array</param> /// <param name="list1">first history array</param> /// <param name="list2">second history array</param> /// <returns>index where arrays are similar up to</returns> public static int lastCommonHistory(int low, int high, HistoryItem[] list1, HistoryItem[] list2) { // found the first differing member if (low >= high) { if (list1[low].time == list2[low].time) return low; else return low - 1; } else { int mid = (low + high) / 2; if (list1[low].time == list2[low].time && list1[mid].time == list2[mid].time) return lastCommonHistory(mid + 1, high, list1, list2); else return lastCommonHistory(low, mid - 1, list1, list2); } }
public static HistoryItem[] SortHistory(int low, int high, HistoryItem[] array) { // i1 is the lowest part of the array // i2 is the highest part of the array int iFirst, iLast; HistoryItem pivot; iFirst = low; iLast = high; pivot = array[iFirst]; // since the left and right numbers will move around as we approach the pivot, we must always make sure we do not cross it while (low < high) { // move the right part of the array until it finds a number less than the pivot while ((array[high].time.CompareTo(pivot.time) >= 0) && (low < high)) { high--; } // if the two numbers are not equal if (low != high) { // move the element of the array into its new home array[low] = array[high]; low++; } // move the left part of the array until it finds a number greater than the pivot while ((array[low].time.CompareTo(pivot.time) <= 0) && (low < high)) { low++; } if (low != high) { // move the element of the array into its new home array[high] = array[low]; high--; } } // fill in these values that would have been overwritten in the above process array[low] = pivot; // pivot = low; // if the minimum part of the array was less than the pivot // that half must be quicksorted if (iFirst < low) SortHistory(iFirst, iLast - 1, array); // if the maximum part of the array was more than the pivot // that half must be quicksorted if (iLast > low) SortHistory(iFirst + 1, iLast, array); return array; }
/// <summary> /// Loads the encrypted part of the .mrb file into the Club /// </summary> public void LoadEncryptedSection() { /********************************** * HOW ENCRYPTION IN MARIMBA WORKS* * One part of the .mrb file is encrypted, the other is not * The part that is not encrypted is login information * A user will try to login with their password * The double-hash of the password is used to check the hash is correct * If correct, login will retrieve the key the rest of the file is encrypted with * That key is stored by being xor'd with the single hash of the password * As long as the password is unknown and SHA-256 is preimage resistant, this should be secure * The rest of the file is encrypted in 256-bit AES * The key is retreived, and the rest of the file is decrypted * The file is loaded into Marimba as normally would be * If a user changes their password, the key xor'd with the single hash is redone * If an admin updates the key, everyone gets their key/hash thing updated * This can easily be done if the key is known since xor is linear * */ // DECRYPT ENCRYPTED SECTION using (Aes aesAlg = Aes.Create()) { aesAlg.Key = this.aesInfo.Key; aesAlg.IV = this.aesInfo.IV; // Create a decrytor to perform the stream transform. ICryptoTransform decryptor = aesAlg.CreateDecryptor(aesAlg.Key, aesAlg.IV); // Create the streams used for decryption. using (MemoryStream memoryStream = new MemoryStream(cipherText)) { using (CryptoStream cryptoStream = new CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)) { using (StreamReader reader = new StreamReader(cryptoStream)) { // read the membership list iMember = Convert.ToInt16(reader.ReadLine()); for (int i = 0; i < iMember; i++) members[i] = new Member(reader); short numTerms = Convert.ToInt16(reader.ReadLine()); listTerms = new List<Term>(numTerms); for (int i = 0; i < numTerms; i++) { Term nextTerm = new Term(reader); listTerms.Add(nextTerm); } // read the budget stuff int iBudget = Convert.ToInt32(reader.ReadLine()); this.budget = new List<BudgetItem>(iBudget + BudgetBuffer); List<int> assetToDepIndices = new List<int>(iBudget); for (int i = 0; i < iBudget; i++) { BudgetItem newItem = new BudgetItem(); newItem.value = Convert.ToDouble(reader.ReadLine()); newItem.name = reader.ReadLine(); newItem.dateOccur = new DateTime(Convert.ToInt64(reader.ReadLine())); newItem.dateAccount = new DateTime(Convert.ToInt64(reader.ReadLine())); newItem.cat = reader.ReadLine(); newItem.type = (TransactionType)Convert.ToInt32(reader.ReadLine()); newItem.term = Convert.ToInt32(reader.ReadLine()); newItem.comment = ClsStorage.ReverseCleanNewLine(reader.ReadLine()); budget.Add(newItem); assetToDepIndices.Add(Convert.ToInt32(reader.ReadLine())); } int k = 0; foreach (BudgetItem item in this.budget) { int assetToDepIndex = assetToDepIndices[k]; item.depOfAsset = (assetToDepIndex == -1) ? null : this.budget[assetToDepIndex]; k++; } int iHistory = Convert.ToInt32(reader.ReadLine()); historyList = new List<HistoryItem>(iHistory + HistoryBuffer); for (int i = 0; i < iHistory; i++) { HistoryItem nextItem = new HistoryItem(reader); historyList.Add(nextItem); } // read email if (fileVersion >= 2) { emailAddress = reader.ReadLine(); imapServerAddress = reader.ReadLine(); this.bImap = Convert.ToBoolean(reader.ReadLine()); smptServerAddress = reader.ReadLine(); smtpRequiresSSL = Convert.ToInt32(reader.ReadLine()); imapRequiresSSL = Convert.ToBoolean(reader.ReadLine()); } } } } // remove cipherText from storage cipherText = null; } this.clubEmail = new Email(emailAddress, Properties.Settings.Default.emailPassword, imapServerAddress, this.bImap, smptServerAddress, smtpRequiresSSL, imapRequiresSSL); }
public void AddHistory(string additionalInfo, ChangeType type) { HistoryItem newItem = new HistoryItem(strCurrentUser, type, additionalInfo, DateTime.Now); historyList.Add(newItem); // mark unsaved changes ClsStorage.unsavedChanges = true; // if autosave is turned on, then save at this point if (Properties.Settings.Default.autoSave) Program.home.btnSave_Click(new object(), new EventArgs()); }