432 lines
15 KiB
C#
432 lines
15 KiB
C#
using System;
|
|
using System.IO;
|
|
using System.Collections.Specialized;
|
|
|
|
using Gtk;
|
|
|
|
using Novell.CASA.MiCasa.Communication;
|
|
using Novell.CASA.MiCasa.Common;
|
|
|
|
namespace Novell.CASA.GUI
|
|
{
|
|
/// <summary>
|
|
/// Summary description for ImportSecrets.
|
|
/// </summary>
|
|
public class ImportSecrets
|
|
{
|
|
Config m_config = null;
|
|
public MiCasa m_objMiCasa = null;
|
|
string sFile = null;
|
|
byte[] buffer = null;
|
|
TreeStore tsConflicts;
|
|
|
|
SecretStore m_ss = null;
|
|
StringCollection m_scConflicts;
|
|
|
|
#region GladeWidgets
|
|
[Glade.Widget]
|
|
Gtk.Entry entryMasterPassword;
|
|
|
|
[Glade.Widget]
|
|
Gtk.Dialog dialogImport,
|
|
dialogLogin,
|
|
dialogResolveConflict;
|
|
|
|
[Glade.Widget]
|
|
Gtk.TreeView tvConflicts;
|
|
|
|
[Glade.Widget]
|
|
Gtk.Button bttnImport,
|
|
bttnIgnore;
|
|
|
|
[Glade.Widget]
|
|
Gtk.CheckButton cbShowValues;
|
|
#endregion
|
|
|
|
public ImportSecrets(SecretStore ss, Config config, MiCasa objMiCasa)
|
|
{
|
|
m_ss = ss;
|
|
m_config = config;
|
|
m_objMiCasa = objMiCasa;
|
|
}
|
|
|
|
public void Run()
|
|
{
|
|
String sHintDir = m_config.GetConfigSetting(CommonGUI.HINT_DIR, null);;
|
|
String sHintFilename = m_config.GetConfigSetting(CommonGUI.HINT_FILENAME, null);
|
|
|
|
FileChooser fc = new FileChooser(FileChooser.ACTION_OPEN);
|
|
sFile = fc.GetFile(sHintDir, sHintFilename, "*.casa");
|
|
|
|
//fc.Show(sHintDir, sHintFilename);
|
|
//sFile = fc.GetSelectedFile();
|
|
|
|
#if W32
|
|
// ask the user to locate the secret file to import
|
|
//sFile = CommonGUI.FileChooser(Gtk.FileChooserAction.Open, "Select import file", sHintDir, sHintFilename);
|
|
#else
|
|
//sFile = null;
|
|
//CommonGUI.DisplayMessage(Gtk.MessageType.Info, "Not implemented");
|
|
#endif
|
|
if (sFile != null)
|
|
{
|
|
// parse of the file:///
|
|
if (sFile.StartsWith("file:///"))
|
|
{
|
|
sFile = sFile.Substring(8);
|
|
}
|
|
|
|
if (File.Exists(sFile))
|
|
{
|
|
|
|
try
|
|
{
|
|
// let's read it
|
|
FileStream fs = new FileStream(sFile, FileMode.Open);
|
|
buffer = new byte[fs.Length];
|
|
|
|
int iBytes = fs.Read(buffer, 0, (int)fs.Length);
|
|
string data = System.Text.Encoding.ASCII.GetString(buffer);
|
|
|
|
fs.Flush();
|
|
fs.Close();
|
|
|
|
// check for clear text secrets
|
|
if (data.StartsWith("<?xml"))
|
|
{
|
|
ImportXMLSecrets addSecrets = new ImportXMLSecrets(null, null, sFile);
|
|
MiCasaRequestReply.Send(MiCasaRequestReply.VERB_ADD_XML_SECRETS, null, null, null, addSecrets);
|
|
|
|
// check for conflicts
|
|
if (m_ss == null)
|
|
m_ss = SecretStore.GetInstance();
|
|
|
|
m_scConflicts = m_ss.EnumerateSecretIDs(SecretStore.SSCS_CONFLICT_KEYCHAIN);
|
|
if (m_scConflicts.Count > 0)
|
|
{
|
|
HandleConficts(m_ss, m_scConflicts);
|
|
}
|
|
else
|
|
{
|
|
CommonGUI.DisplayMessage(Gtk.MessageType.Info, "Import complete");
|
|
}
|
|
}
|
|
else
|
|
{
|
|
GetMasterPasswordUsedForImport();
|
|
}
|
|
}
|
|
catch (Exception e)
|
|
{
|
|
CommonGUI.DisplayMessage(Gtk.MessageType.Error, e.Message);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
public void GetMasterPasswordUsedForImport()
|
|
{
|
|
// prompt for master password, and optional passphrase to encrypt
|
|
//Logger.DbgLog("GUI:CasaMain.Login() - IsMasterPasswordSet returned false");
|
|
#if W32
|
|
Glade.XML gxmlTemp = new Glade.XML ("../images/casa.glade", "dialogImport", null);
|
|
#endif
|
|
#if LINUX
|
|
Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogImport", null);
|
|
#endif
|
|
|
|
gxmlTemp.Autoconnect (this);
|
|
dialogImport.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain");;
|
|
dialogImport.Modal = true;
|
|
dialogImport.Show();
|
|
}
|
|
|
|
public void OnDialogLoginDeleted(object obj, EventArgs args)
|
|
{
|
|
//cbuttonShowPassword.Active = false;
|
|
dialogLogin.Destroy();
|
|
}
|
|
|
|
public void okbuttonLogin_clicked(object obj, EventArgs args)
|
|
{
|
|
dialogLogin.Destroy();
|
|
}
|
|
|
|
public void closebuttonLogin_clicked(object obj, EventArgs args)
|
|
{
|
|
dialogLogin.Destroy();
|
|
}
|
|
|
|
public void on_entryMasterPassword3_activate(object obj, EventArgs args)
|
|
{
|
|
}
|
|
|
|
public void on_entryMasterPassword4_activate(object obj, EventArgs args)
|
|
{
|
|
}
|
|
|
|
public void on_helpbuttonAuthentication_clicked(object obj, EventArgs args)
|
|
{
|
|
Common.ShowHelpUrl("CASAMasterPasswordAuthentication.htm");
|
|
}
|
|
|
|
private void on_buttonImportOK_clicked(object sender, EventArgs args)
|
|
{
|
|
if (entryMasterPassword != null)
|
|
{
|
|
ImportXMLSecrets addSecrets = new ImportXMLSecrets(entryMasterPassword.Text, null, sFile);
|
|
addSecrets = (ImportXMLSecrets)MiCasaRequestReply.Send(MiCasaRequestReply.VERB_ADD_XML_SECRETS, null, null, null, addSecrets);
|
|
|
|
if (dialogImport != null)
|
|
{
|
|
dialogImport.Destroy();
|
|
}
|
|
if (m_objMiCasa != null)
|
|
{
|
|
m_objMiCasa.AggregateStore();
|
|
}
|
|
|
|
// check for conflicts
|
|
if (m_ss == null)
|
|
m_ss = SecretStore.GetInstance();
|
|
|
|
m_scConflicts = m_ss.EnumerateSecretIDs(SecretStore.SSCS_CONFLICT_KEYCHAIN);
|
|
if (m_scConflicts.Count > 0)
|
|
{
|
|
HandleConficts(m_ss, m_scConflicts);
|
|
}
|
|
else
|
|
{
|
|
if (addSecrets.GetStatus().Equals("Success"))
|
|
CommonGUI.DisplayMessage(Gtk.MessageType.Info, "Import complete");
|
|
else
|
|
CommonGUI.DisplayMessage(Gtk.MessageType.Info, "Failed: " + addSecrets.GetStatus());
|
|
}
|
|
}
|
|
}
|
|
|
|
private void on_buttonImportClose_clicked(object sender, EventArgs args)
|
|
{
|
|
if (dialogImport != null)
|
|
{
|
|
dialogImport.Destroy();
|
|
}
|
|
}
|
|
|
|
private void HandleConficts(SecretStore store, StringCollection scConflicts)
|
|
{
|
|
|
|
bool bShowConflictDialog = false;
|
|
|
|
// 0:secretID, 1:keyID, 2:importValue, 3:currentValue
|
|
tsConflicts = new TreeStore(typeof(string), typeof(string), typeof(string), typeof(string), typeof(string));
|
|
|
|
StringEnumerator sEnum = scConflicts.GetEnumerator();
|
|
{
|
|
while (sEnum.MoveNext())
|
|
{
|
|
string sSecretID = sEnum.Current;
|
|
Secret currentSecret = store.GetSecret(sSecretID);
|
|
|
|
string sConflictSecretID;
|
|
if (sSecretID.StartsWith("SS_CredSet"))
|
|
{
|
|
sConflictSecretID = sSecretID.Substring(11);
|
|
}
|
|
else
|
|
{
|
|
sConflictSecretID = sSecretID;
|
|
}
|
|
Secret conflictSecret = store.GetSecret(SecretStore.SSCS_CONFLICT_KEYCHAIN, 0, sConflictSecretID, Secret.SS_CREDSET, "");
|
|
|
|
// add this conflict to the treestore
|
|
NameValueCollection nvcConflict = conflictSecret.GetKeyValueCollection();
|
|
NameValueCollection nvcCurrent = currentSecret.GetKeyValueCollection();
|
|
for (int i = 0; i < nvcConflict.Count; i++)
|
|
{
|
|
String sConflictKey = nvcConflict.GetKey(i);
|
|
String sConflictValue = nvcConflict.Get(sConflictKey);
|
|
String sCurrentValue = nvcCurrent.Get(sConflictKey);
|
|
|
|
if (sCurrentValue != null)
|
|
{
|
|
if (sCurrentValue != sConflictValue)
|
|
{
|
|
tsConflicts.AppendValues(sSecretID, sConflictKey, sConflictValue, sCurrentValue, "*********");
|
|
bShowConflictDialog = true;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tsConflicts.AppendValues(sSecretID, sConflictKey, sConflictValue, "", "*********");
|
|
bShowConflictDialog = true;
|
|
}
|
|
}
|
|
}
|
|
|
|
if (bShowConflictDialog == true)
|
|
{
|
|
// show dialog
|
|
Glade.XML gxmlTemp = new Glade.XML(Common.GladeFile, "dialogResolveConflict", null);
|
|
gxmlTemp.Autoconnect(this);
|
|
|
|
dialogResolveConflict.SetPosition(WindowPosition.CenterOnParent);
|
|
|
|
tvConflicts.AppendColumn("SecretID", new Gtk.CellRendererText(), "text", 0);
|
|
tvConflicts.AppendColumn("Key", new Gtk.CellRendererText(), "text", 1);
|
|
if (cbShowValues.Active)
|
|
{
|
|
tvConflicts.AppendColumn("Import value", new Gtk.CellRendererText(), "text", 2);
|
|
tvConflicts.AppendColumn("Current value", new Gtk.CellRendererText(), "text", 3);
|
|
}
|
|
else
|
|
{
|
|
tvConflicts.AppendColumn("Import value", new Gtk.CellRendererText(), "text", 4);
|
|
tvConflicts.AppendColumn("Current value", new Gtk.CellRendererText(), "text", 4);
|
|
}
|
|
|
|
tvConflicts.Selection.Mode = SelectionMode.Multiple;
|
|
|
|
// hook up event handlers
|
|
bttnImport.Clicked += new EventHandler(bttnImport_Clicked);
|
|
bttnIgnore.Clicked += new EventHandler(bttnIgnore_Clicked);
|
|
cbShowValues.Toggled += new EventHandler(cbShowValues_Toggled);
|
|
|
|
tvConflicts.Model = tsConflicts;
|
|
dialogResolveConflict.Show();
|
|
}
|
|
else
|
|
{
|
|
ClearConflicts();
|
|
CommonGUI.DisplayMessage(MessageType.Info, "Import complete");
|
|
}
|
|
}
|
|
}
|
|
|
|
void cbShowValues_Toggled(object sender, EventArgs e)
|
|
{
|
|
TreeViewColumn tvCol;
|
|
|
|
if (cbShowValues.Active)
|
|
{
|
|
// verify MasterPassword
|
|
CommonGUI cg = new CommonGUI();
|
|
if (cg.VerifyMasterPasswordWithUser())
|
|
{
|
|
tvConflicts.RemoveColumn(tvConflicts.GetColumn(3));
|
|
tvConflicts.RemoveColumn(tvConflicts.GetColumn(2));
|
|
|
|
// add columns
|
|
tvCol = new TreeViewColumn("Import value", new CellRendererText(), "text", 2);
|
|
tvConflicts.InsertColumn(tvCol, 2);
|
|
|
|
tvCol = new TreeViewColumn("Current value", new CellRendererText(), "text", 3);
|
|
tvConflicts.InsertColumn(tvCol, 3);
|
|
}
|
|
else
|
|
{
|
|
cbShowValues.Active = false;
|
|
}
|
|
}
|
|
else
|
|
{
|
|
tvConflicts.RemoveColumn(tvConflicts.GetColumn(3));
|
|
tvConflicts.RemoveColumn(tvConflicts.GetColumn(2));
|
|
|
|
// add columns
|
|
tvCol = new TreeViewColumn("Import value", new CellRendererText(), "text", 4);
|
|
tvConflicts.InsertColumn(tvCol, 2);
|
|
|
|
tvCol = new TreeViewColumn("Current value", new CellRendererText(), "text", 4);
|
|
tvConflicts.InsertColumn(tvCol, 3);
|
|
}
|
|
}
|
|
|
|
void bttnIgnore_Clicked(object sender, EventArgs e)
|
|
{
|
|
ClearConflicts();
|
|
dialogResolveConflict.Destroy();
|
|
}
|
|
|
|
void bttnImport_Clicked(object sender, EventArgs e)
|
|
{
|
|
DoImport();
|
|
}
|
|
|
|
void DoImport()
|
|
{
|
|
// get selected rows
|
|
TreeModel model;
|
|
TreeIter iter;
|
|
TreePath[] treePaths = tvConflicts.Selection.GetSelectedRows(out model);
|
|
|
|
|
|
if (treePaths.Length > 0)
|
|
{
|
|
// iterate thru those to change
|
|
for (int i = 0; i < treePaths.Length; i++)
|
|
{
|
|
if (tsConflicts.GetIter(out iter, treePaths[i]))
|
|
{
|
|
string sSecretID = (string)tsConflicts.GetValue(iter, 0);
|
|
string sKey = (string)tsConflicts.GetValue(iter, 1);
|
|
string sNewValue = (string)tsConflicts.GetValue(iter, 2);
|
|
string sCurValue = (string)tsConflicts.GetValue(iter, 3);
|
|
|
|
if ((sCurValue == null) || (sCurValue.Length == 0))
|
|
{
|
|
StoreDataInterface.AddCASASecretKey(sSecretID, sKey, sNewValue);
|
|
}
|
|
else
|
|
{
|
|
StoreDataInterface.ModifyCASASecretKey(sSecretID, sKey, sNewValue);
|
|
}
|
|
|
|
tsConflicts.SetValue(iter, 3, sNewValue);
|
|
}
|
|
}
|
|
|
|
for (int i = 0; i < treePaths.Length; i++)
|
|
{
|
|
if (tsConflicts.GetIter(out iter, treePaths[i]))
|
|
{
|
|
tsConflicts.Remove(ref iter);
|
|
}
|
|
}
|
|
|
|
// refresh the store
|
|
//ClearConflicts();
|
|
m_objMiCasa.AggregateStore();
|
|
}
|
|
else
|
|
{
|
|
CommonGUI.DisplayMessage(MessageType.Error, "Select the values you want to import");
|
|
}
|
|
}
|
|
|
|
private void ClearConflicts()
|
|
{
|
|
// enumerate thru conflicts, clearing each one
|
|
if (m_ss != null)
|
|
{
|
|
if (m_scConflicts != null)
|
|
{
|
|
StringEnumerator sEnum = m_scConflicts.GetEnumerator();
|
|
while (sEnum.MoveNext())
|
|
{
|
|
string sSecretID = (string)sEnum.Current;
|
|
if (sSecretID.StartsWith("SS_CredSet"))
|
|
{
|
|
sSecretID = sSecretID.Substring(11);
|
|
}
|
|
m_ss.RemoveSecret(0, SecretStore.SSCS_CONFLICT_KEYCHAIN, null, sSecretID, Secret.SS_CREDSET);
|
|
}
|
|
}
|
|
}
|
|
|
|
tsConflicts.Clear();
|
|
}
|
|
}
|
|
}
|