/// <summary> /// What to do when the Export button is clicked /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnExport_Click(object sender, EventArgs e) { // Asbestos underpants: try { // This only makes sense if the registry keys are open... if (CryptnosRegistryKeyOpen()) { // ... and if there are any actual sites saved in the registry: if (siteParamsKey.GetValueNames().Length > 0) { // Open up the export dialog and let the user select what sites // they want to export: object[] sitesToExport = new object[cbSites.Items.Count]; cbSites.Items.CopyTo(sitesToExport, 0); ExportSitesForm esf = new ExportSitesForm(sitesToExport, chkShowTooltips.Checked, TopMost, this); // If they selected anything to export: if (esf.ShowDialog() == DialogResult.OK && esf.SelectedSites != null && esf.SelectedSites.Length > 0) { sitesToExport = esf.SelectedSites; // Prompt the user for a passphrase. All Cryptnos export files are // encrypted, so we need a passphrase to encrypt the data with. PassphraseDialog pd = new PassphraseDialog(PassphraseDialog.Mode.Export_Initial, TopMost); if (pd.ShowDialog() == DialogResult.OK) { string passphrase = pd.Passphrase; pd.Dispose(); // Now prompt them for their passphrase again to make sure they // don't misstype it: pd = new PassphraseDialog(PassphraseDialog.Mode.Export_Confirm, TopMost); if (pd.ShowDialog() == DialogResult.OK) { // If the passphrases match: if (passphrase == pd.Passphrase) { // Now prompt the user for a file to save to: SaveFileDialog sfd = new SaveFileDialog(); sfd.InitialDirectory = lastImportExportPath; if (sfd.ShowDialog() == DialogResult.OK) { string filename = sfd.FileName; // Save the last import/export path for later // use. Note that if this fails, don't sweat it. try { lastImportExportPath = (new FileInfo(filename)).DirectoryName; } catch { } // Generate a generic List of SiteParameters objects. // Site Parameters are serializable, as are generic // Lists (if the underlying object is serializable), so // our output file will simply be a serialized List of // these objects, encrypted to protect their data. List<SiteParameters> siteParams = new List<SiteParameters>(); foreach (object site in sitesToExport) { SiteParameters sp = SiteParameters.ReadFromRegistry(siteParamsKey, SiteParameters.GenerateKeyFromSite((string)site)); siteParams.Add(sp); } // Hand the actual heavy lifting off to the // import/export handler class: ImportExportHandler.ExportToFile(filename, passphrase, exportGenerator, siteParams); // If we get this far, we must have been successful. // Display a success message to the user: MessageBox.Show("Your site parameters have been " + "successfully exported.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); } } // The two passphrases did not match: else MessageBox.Show("The two passphrases did not match. " + "Please try exporting your parameters again.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } } // No parameters were found to export: else { MessageBox.Show("You have no settings to export, so there's nothing " + "for me to do!", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); btnExport.Enabled = false; } } // The registry keys weren't open: else MessageBox.Show("I could not open the registry to get your site parameter " + "options, so I can't export anything!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // Something blew up. We need more robust, user-friendly error messages here. catch (Exception ex) { if (debug) MessageBox.Show(ex.ToString(), "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); else MessageBox.Show(ex.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }
/// <summary> /// What to do when the Import button is clicked /// </summary> /// <param name="sender"></param> /// <param name="e"></param> private void btnImport_Click(object sender, EventArgs e) { // Asbestos underpants: try { // This should never happen as the import button gets disabled when the Lock checkbox // is checked, but as a sanity check, don't let them change their settings if they've // locked the parameters: if (chkRemember.Checked && chkLock.Checked) { MessageBox.Show("You currently have your site parameters locked. You " + "must unlock your site parameters for this change to take effect.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); btnForget.Enabled = false; btnForgetAll.Enabled = false; } // Otherwise: else { // This only makes sense if we can open the registry: if (CryptnosRegistryKeyOpen()) { // Prompt the user for an import file: OpenFileDialog ofd = new OpenFileDialog(); ofd.InitialDirectory = lastImportExportPath; if (ofd.ShowDialog() == DialogResult.OK) { // Take note of the file name, as well as update the last // import/export path for later use. Note that if, for some // bizarre reason, the last import/export path fetch fails, // we don't sweat it. That's not important right now. string filename = ofd.FileName; try { lastImportExportPath = (new FileInfo(filename)).DirectoryName; } catch { } // Prompt the user for their passphrase (Cryptnos files are always // encrypted): PassphraseDialog pd = new PassphraseDialog(PassphraseDialog.Mode.Import, TopMost); if (pd.ShowDialog() == DialogResult.OK) { string passphrase = pd.Passphrase; pd.Dispose(); // Read the data from the import file. For this, we hand // the heavy lifting to the ImportExportHandler. Note that // this should transparently handle both the old and new // export formats, so we don't have to sweat that detail. List<SiteParameters> siteParamList = ImportExportHandler.ImportFromFile(filename, passphrase); if (siteParamList != null && siteParamList.Count > 0) { // Launch the import dialog so the user can pick and choose which // sites to import: ImportDialog id = new ImportDialog(this, siteParamList, debug, TopMost, chkShowTooltips.Checked); if (id.ShowDialog() == DialogResult.OK) { // Get the filtered list of parameters. Note that this should // always have something in it; if the list were empty, the dialog // should switch to a Cancel result. siteParamList = id.SiteParams; // If the import didn't blow up, step through the list // and save each set of parameters to the registry. Note that // if a given site already exists in the registry, this will // overwrite it. foreach (SiteParameters siteParam in siteParamList) siteParam.SaveToRegistry(siteParamsKey); // Now regenerate the sites drop-down list with the newly // imported data and let the user know we were successful. PopulateSitesDropdown(); MessageBox.Show("The parameters have been successfully " + "imported from the file.", "Information", MessageBoxButtons.OK, MessageBoxIcon.Information); btnExport.Enabled = true; btnForgetAll.Enabled = true; btnForget.Enabled = true; } } // I don't think this will happen (an exception should be thrown if the file // is invalid), but if the site list is empty, complain: else MessageBox.Show("No valid Cryptnos parameters could be loaded " + "from the file. Make sure the file is not corrupted", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } } // The registry keys weren't open: else MessageBox.Show("I could not open the registry to get your site parameter " + "options, so I can't import anything!", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } } // If we got an ImportHandlerException, it probably has some sort of very specific // message we can show back to the user: catch (ImportHandlerException ihe) { MessageBox.Show(ihe.Message, "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } // Otherwise, if something else blew up, notify the user. This needs to be more // robust with more specific and user-friendly messages. catch { MessageBox.Show("I was unable to import site parameters from the specified " + "file. Make sure you have entered your passphrase correctly and that " + "the file has not been corrupted.", "Error", MessageBoxButtons.OK, MessageBoxIcon.Error); } }