diff --git a/CASA.changes b/CASA.changes index ba42af83..1573715c 100644 --- a/CASA.changes +++ b/CASA.changes @@ -1,3 +1,9 @@ +------------------------------------------------------------------- +Wed Mar 15 21:22:48 IST 2006 - lsreevatsa@novell.com + +- Added Modify and Delete functionalities for Firefox Password + Manager Secrets into CASAManager. + ------------------------------------------------------------------- Tue Mar 14 15:53:02 MST 2006 - jnorman@novell.com - Bug 155529. Detect whether or not Firefox is installed diff --git a/c_adlib/AD_Facade.cs b/c_adlib/AD_Facade.cs index 4883de5d..5c6911c5 100644 --- a/c_adlib/AD_Facade.cs +++ b/c_adlib/AD_Facade.cs @@ -55,7 +55,7 @@ namespace Novell.CASA.DataEngines //for firefox below. kwEngine = new KWalletEngine(); gkEngine = new GKEngine(); - //ffEngine = new FFEngine(); + ffEngine = new FFEngine(); //Note: //The new instantiation of a wallet should not be done here since //if the policy has a specific wallet disabled, the constructor for the wallet @@ -245,6 +245,8 @@ namespace Novell.CASA.DataEngines return kwEngine.SetSecret(secret, opnType); if (StoreID == ConstStrings.CASA_STORE_GK) return gkEngine.SetSecret(secret, opnType); + if (StoreID == ConstStrings.CASA_STORE_FFOX) + return ffEngine.SetSecret(secret, opnType); #endif else { @@ -355,6 +357,8 @@ namespace Novell.CASA.DataEngines return kwEngine.Remove(secret); if (StoreID == ConstStrings.CASA_STORE_GK) return gkEngine.Remove(secret); + if (StoreID == ConstStrings.CASA_STORE_FFOX) + return ffEngine.Remove(secret); #endif return -1; } diff --git a/c_adlib/Common.cs b/c_adlib/Common.cs index c0a04de6..97642d41 100644 --- a/c_adlib/Common.cs +++ b/c_adlib/Common.cs @@ -76,10 +76,12 @@ namespace Novell.CASA.DataEngines.Common public static string CCF_SYNCH = "Synch"; public static string CCF_NAME = "Name"; public static string CCF_FFTAG = "FireFox"; - public static string CCF_FFPROFILE = "Profile"; + public static string CCF_FFPROFILE = "Profile"; + public static string CCF_PASSWDSTATUS = "PasswordStatus"; //Add Operation Types on CCF - public static int OPERATION_ADD_SECRET = 0; + public static int OPERATION_ADD_SECRET = 0; + public static int OPERATION_DELETE_SECRET = 1; public static int OPERATION_MODIFY_SECRET = 2; diff --git a/c_adlib/FFEngine.cs b/c_adlib/FFEngine.cs index c6a6694f..771b0441 100644 --- a/c_adlib/FFEngine.cs +++ b/c_adlib/FFEngine.cs @@ -130,7 +130,52 @@ namespace Novell.CASA.DataEngines public int SetSecret(XmlNode secret, int opnType) { - return (int)FireFoxResultExtended.FIREFOX_RESULT_ERROR_UNKNOWN; + string ProfileName=null,secretName=null; + int retVal=0; + ProfileName = ExtractProfileName(secret); + //Console.WriteLine("FfEngine.cs : ProfileName : " + ProfileName); + secretName = ExtractSecretName(secret, opnType); + + Host newHost = new Host(); + HostElement nh1 = null; + try + { + newHost.hostName = Marshal.StringToHGlobalAnsi(secretName); + //Console.WriteLine("FFEngine.cs : SecretName " + secretName); + }catch(Exception e) + { + Console.WriteLine("Unable to Marshal the SecretName" + e.ToString()); + } + XmlNodeList keylist = secret.SelectNodes("descendant::Key"); + try + { + IntPtr next = IntPtr.Zero; + + for (int i=keylist.Count-1;i>=0;i--) + { + //Get the Key + HostElement nh = new HostElement(); + XmlAttributeCollection at = keylist.Item(i).Attributes; + String keyname = (at["ID"]).InnerText; + String passwordstatus = (at["PasswordStatus"]).InnerText; + //Console.WriteLine("FFEngine.cs : Keyname : " + keyname); + //Console.WriteLine("FFEngine.cs : Value : " + keylist.Item(i).ChildNodes[0].InnerText ); + nh.name = Marshal.StringToHGlobalAnsi(keyname); + nh.value = Marshal.StringToHGlobalAnsi(keylist.Item(i).ChildNodes[0].InnerText); + nh.isPassword = Convert.ToInt32(passwordstatus); + nh.next = next; + next = Marshal.AllocHGlobal(Marshal.SizeOf(nh)); + Marshal.StructureToPtr(nh,next,false); + } + newHost.hostElement = next; + + retVal = FireFox.Modify_Host(ProfileName,newHost,1); + } + catch(Exception e) + { + Console.WriteLine("Unable to Marshal the Key/Value Pairs" + e.ToString()); + } + return retVal; } public int GetSecret(XmlNode secret) @@ -140,7 +185,11 @@ namespace Novell.CASA.DataEngines public int Remove(XmlNode secret) { - return (int)FireFoxResultExtended.FIREFOX_RESULT_ERROR_UNKNOWN; + string ProfileName = ExtractProfileName(secret); + string secretName = ExtractSecretName(secret, ConstStrings.OPERATION_DELETE_SECRET); + int retVal = FireFox.Remove_Host(ProfileName,secretName); + //return (int)FireFoxResultExtended.FIREFOX_RESULT_ERROR_UNKNOWN; + return retVal; } //-------------------------------------------------------------- @@ -253,6 +302,7 @@ namespace Novell.CASA.DataEngines XmlElement xmlKeyElement = null; XmlAttribute keyIdAttr = null; + XmlAttribute keyPasswdStatusAttr = null; XmlElement xmlValueElement = null; name = (String)Marshal.PtrToStringAnsi(hostElementList.name); @@ -267,6 +317,13 @@ namespace Novell.CASA.DataEngines keyIdAttr.Value = name; xmlKeyElement.SetAttributeNode(keyIdAttr); + keyPasswdStatusAttr = doc.CreateAttribute(ConstStrings.CCF_PASSWDSTATUS); //-ID + if(isPassword == 1) + keyPasswdStatusAttr.Value = "1"; + else + keyPasswdStatusAttr.Value = "0"; + xmlKeyElement.SetAttributeNode(keyPasswdStatusAttr); + xmlValueElement = doc.CreateElement(ConstStrings.CCF_VALUE); // xmlValueElement.InnerText = value; xmlKeyElement.AppendChild(xmlValueElement); // @@ -326,6 +383,33 @@ namespace Novell.CASA.DataEngines } } + string ExtractSecretName(XmlNode secret, int opnType) + { + XmlAttributeCollection atcol = secret.Attributes; + String secretid = atcol["ID"].InnerXml; + //Console.WriteLine("FFEngine.cs: SecretId : " + secretid); + + if (opnType == ConstStrings.OPERATION_ADD_SECRET) + { + return secretid; //Not expecting an item Id + + } + + return secretid; + //int itemIdx = secretid.LastIndexOf("]"); + //Return substring without itemId + //return(secretid.Substring(0,itemIdx)); + } + + string ExtractProfileName(XmlNode secret) + { + XmlAttributeCollection atcol; + XmlNode parentNode = secret.ParentNode; + atcol = parentNode.Attributes; + String profilename = atcol["ID"].InnerXml; + return profilename; + } + //#if TEST public static void Main() { diff --git a/c_adlib/ad_ff/FireFox.cs b/c_adlib/ad_ff/FireFox.cs index 32999b03..4f34b1e1 100644 --- a/c_adlib/ad_ff/FireFox.cs +++ b/c_adlib/ad_ff/FireFox.cs @@ -167,16 +167,34 @@ public class HostElement //Signon functions [DllImport("libad_ff.so.1.1.1")] public static extern int FPM_GetSignonData(string profileName,out IntPtr host,int doRefresh); + + [DllImport("libad_ff.so.1.1.1")] + public static extern int FPM_ModifyHost(string profileName, Host host, int doUpdate); + + [DllImport("libad_ff.so.1.1.1")] + public static extern int FPM_RemoveHost(string profileName, string hostName, int doUpdate); + //TBD //int FPM_WriteSignonData(char *profileName) //int FPM_AddHost(char *profileName, struct Host *host, int doUpdate) - //int FPM_ModifyHost(char *profileName, struct Host *host, int doUpdate) - //int FPM_RemoveHost(char *profileName, char *hostname, int doUpdate) + public static int IsStoreAvailable() { return FPM_IsStoreAvailable(); } + public static int Remove_Host(string ProfileName, string hostName) + { + return (FPM_RemoveHost(ProfileName, hostName, 1)); + } + + public static int Modify_Host(string profileName, Host mhost, int doUpdate) + { + //Console.WriteLine("FireFox.cs : ProfileName : " + profileName); + //Console.WriteLine("FireFox.cs : HostName : " + (String)Marshal.PtrToStringAnsi(mhost.hostName)); + + return FPM_ModifyHost(profileName, mhost,1); + } //-------------------------------------------------------------- //GetDefaultProfileName diff --git a/c_gui/CasaMain.cs b/c_gui/CasaMain.cs index a3cbbdf5..4234c8b5 100644 --- a/c_gui/CasaMain.cs +++ b/c_gui/CasaMain.cs @@ -842,8 +842,8 @@ namespace Novell.CASA.GUI case Common.STORE_FIREFOX: if( 0 != objFirefox.tvSecretIDFirefox.Selection.CountSelectedRows() ) { - mmiView.Sensitive = true; - mmiDelete.Sensitive = mmiLink.Sensitive = mmiCopy.Sensitive = false; + mmiView.Sensitive = mmiDelete.Sensitive = true; + mmiLink.Sensitive = mmiCopy.Sensitive = false; } else { @@ -1250,6 +1250,7 @@ namespace Novell.CASA.GUI break; case Common.STORE_FIREFOX: + objFirefox.OnDeleteActivated(obj, args); break; case Common.STORE_MOZILLA: diff --git a/c_gui/Firefox.cs b/c_gui/Firefox.cs index 48af0b86..8457141a 100644 --- a/c_gui/Firefox.cs +++ b/c_gui/Firefox.cs @@ -55,7 +55,8 @@ public class Firefox : Store [Glade.Widget] Gtk.Dialog dialogNewSecret, dialogManageSecret, - dialogLogin; + dialogLogin, + dialogConfirmDelete; [Glade.Widget] Gtk.Menu menuRightClick; @@ -65,7 +66,8 @@ public class Firefox : Store entryKey, entryValue, entryMasterPassword3, - entryMasterPassword4; + entryMasterPassword4, + entryDeleteSecretID; [Glade.Widget] Gtk.CheckButton cbuttonShowPassword; @@ -193,7 +195,7 @@ public class Firefox : Store menuRightClick.Popup(null, null, null, IntPtr.Zero, 3, Gtk.Global.CurrentEventTime); if( 0 != tvSecretIDFirefox.Selection.CountSelectedRows() ) - cmiNewSecret.Sensitive = cmiNewKey.Sensitive = cmiDelete.Sensitive = cmiLink.Sensitive = cmiCopy.Sensitive = false; + cmiNewSecret.Sensitive = cmiNewKey.Sensitive = cmiLink.Sensitive = cmiCopy.Sensitive = false; else cmiNewSecret.Sensitive = cmiNewKey.Sensitive = cmiDelete.Sensitive = cmiLink.Sensitive = cmiCopy.Sensitive = cmiView.Sensitive = false; } @@ -235,7 +237,8 @@ public class Firefox : Store dialogManageSecret.Title = "Firefox - Manage Secret"; cellEditable = new CellRendererText(); - cellEditable.Editable = false; + cellEditable.Editable = true; + cellEditable.Edited += new EditedHandler(OnKeyValueEdited); //cellEditable.Edited += new EditedHandler(OnKeyValueEdited); /// KEY:0 VALUE:1 VALUE-DUP:2 DIRTY-BIT:3 LINK:4 tsKeyValue = new TreeStore(typeof(string),typeof(string), typeof(string), typeof(bool), typeof(string)); @@ -262,6 +265,77 @@ public class Firefox : Store Logger.DbgLog("GUI:Firefox.ViewKeyValues() - END"); } + + /// + /// EDIT KEY-VALUE + /// + public void OnKeyValueEdited(object obj, EditedArgs args) + { + Logger.DbgLog("GUI:Firefox.OnKeyValueEdited() - BEGIN"); + + TreeModel model; + TreeIter iter; + object val; + string KeyName = null, + KeyValue = null; + string[] Keys = null, + Values = null; + + try + { + tvKeyValue.Selection.GetSelected (out model, out iter); + val = tsKeyValue.GetValue(iter,0); + KeyName = val.ToString(); + if( true == cbuttonShowPassword.Active ) + val = tsKeyValue.GetValue(iter,1); + else + val = tsKeyValue.GetValue(iter,2); + KeyValue = val.ToString(); + + tvSecretIDFirefox.Selection.GetSelected (out model, out iter); + + if( false == entrySecretID.Editable ) + { + if( ("" != args.NewText) && (KeyValue != args.NewText) ) + if( Common.STATUS_SUCCESS == StoreDataInterface.UpdateStore(Common.STORE_FIREFOX, Common.OPERATION_MODIFY_KEY, KeyName, args.NewText, ref model, ref iter) ) + { + Logger.DbgLog("GUI:Firefox.OnKeyValueEdited() - StoreDataInterface.UpdateStore() succeeded"); + tvKeyValue.Selection.GetSelected (out model, out iter); + tsKeyValue.SetValue(iter, 1, args.NewText); + tsKeyValue.SetValue(iter, 2, "********"); + + tvSecretIDFirefox.Selection.GetSelected (out model, out iter); + Keys = (string[]) model.GetValue(iter, 1); + Values = (string[]) model.GetValue(iter, 2); + for( int i=0; i< Keys.Length; i++ ) + { + if( Keys[i] == KeyName ) + { + Values[i] = args.NewText; + tsSecretIDFirefox.SetValue(iter, 2, Values); + break; + } + } + AggregateStore(); + } + else + Logger.DbgLog("GUI:Firefox.OnKeyValueEdited() - ERROR: STATUS_STORE_UPDATEFAILED"); + } + else + { + tvKeyValue.Selection.GetSelected (out model, out iter); + tsKeyValue.SetValue(iter, 1, args.NewText); + tsKeyValue.SetValue(iter, 2, "********"); + } + } + catch(Exception exp) + { + Logger.DbgLog("GUI:Firefox.OnKeyValueEdited() - EXCEPTION:" + exp.ToString()); + } + + Logger.DbgLog("GUI:Firefox.OnKeyValueEdited() - END"); + + } /// /// ADD BUTTON CLICKED @@ -450,6 +524,62 @@ public class Firefox : Store /// public void OnDeleteActivated(object obj, EventArgs args) { + Logger.DbgLog("GUI:Firefox.OnDeleteActivated() - BEGIN"); + if( 0 != tvSecretIDFirefox.Selection.CountSelectedRows() ) + { + Glade.XML gxmlTemp = new Glade.XML (Common.GladeFile, "dialogConfirmDelete", null); + gxmlTemp.Autoconnect (this); + dialogConfirmDelete.TransientFor = (Gtk.Window)CasaMain.gxmlMain.GetWidget("windowMain"); + dialogConfirmDelete.Title = "Firefox - Delete Secret"; + + TreeModel model; + TreeIter iter; + string selected = null; + if( tvSecretIDFirefox.Selection.GetSelected (out model, out iter) ) + { + selected = (string) model.GetValue (iter, 0); + if( (null != selected) && (selected.Length > 0) ) + entryDeleteSecretID.Text = selected; + } + } + Logger.DbgLog("GUI:Firefox.OnDeleteActivated() - END"); + } + + public void on_buttonYes_clicked(object obj, EventArgs args) + { + Logger.DbgLog("GUI:Firefox.on_buttonYes_clicked() - BEGIN"); + + TreeModel model; + TreeIter iter; + + try + { + if( tvSecretIDFirefox.Selection.GetSelected (out model, out iter) ) + { + if( Common.STATUS_SUCCESS == StoreDataInterface.UpdateStore(Common.STORE_FIREFOX, Common.OPERATION_DELETE_SECRET, "", "", ref model, ref iter) ) + { + tsSecretIDFirefox.Remove(ref iter); + tvSecretIDFirefox.ColumnsAutosize(); + tsNativeInfoFirefox.Clear(); + dialogConfirmDelete.Destroy(); + Logger.DbgLog("GUI:Firefox.on_buttonYes_clicked() - DELETE_SECRET_SUCCEEDED"); + + } + else + Logger.DbgLog("GUI:Firefox.on_buttonYes_clicked() - DELETE_SECRET_FAILED"); + } + } + catch(Exception exp) + { + Logger.DbgLog("GUI:Firefox.on_buttonYes_clicked() - EXCEPTION:" + exp.ToString()); + } + + Logger.DbgLog("GUI:Firefox.on_buttonYes_clicked() - END"); + } + + public void on_buttonNo_clicked(object obj, EventArgs args) + { + dialogConfirmDelete.Destroy(); } ///####################################################################### diff --git a/c_gui/StoreDataInterface.cs b/c_gui/StoreDataInterface.cs index ce85baaf..71473533 100644 --- a/c_gui/StoreDataInterface.cs +++ b/c_gui/StoreDataInterface.cs @@ -640,6 +640,23 @@ namespace Novell.CASA.GUI { newKeyElement.AppendChild(newValue); } } + else if( Common.STORE_FIREFOX == storeIDentifier ) + { + storeChainKey = CCFXML_ELEMENT_FIREFOX_PROFILE; + ccfRootStorePath = "//CCF/FireFox"; + if( Common.OPERATION_MODIFY_KEY == operation || Common.OPERATION_DELETE_KEY == operation ) + { + ccfSecretPath = "//CCF/FireFox/Profile[@ID='" + keyChainID + "']/Secret[@ID='" + SecretID + "']/Key[@ID='" + keyID + "']"; + //Console.WriteLine("OPERATION_MODIFY_KEY-OR-OPERATION_DELETE_KEY:ccfSecretPath:"+ccfSecretPath);//FIXME:Remove this line + } + else if( Common.OPERATION_DELETE_SECRET == operation ) + { + ccfKeyChainPath = "//CCF/FireFox/Profile[@ID='" + keyChainID + "']"; + ccfSecretPath = "Secret[@ID='" + SecretID + "']"; + //Console.WriteLine("OPERATION_DELETE_SECRET:ccfKeyChainPath:"+ccfKeyChainPath);//FIXME:Remove this line + //Console.WriteLine("OPERATION_DELETE_SECRET:ccfSecretPath:"+ccfSecretPath);//FIXME:Remove this line + } + } else return( Common.STATUS_STORE_UNSUPPORTEDOPERATION );