using System; using System.Collections; using System.Xml; using System.IO; using Novell.CASA; using Novell.CASA.DataEngines.Common; using System.Collections.Specialized; using System.Runtime.InteropServices; using Novell.CASA.DataEngines.KWallet; namespace Novell.CASA.DataEngines { /* * This class is implementation of Data engine for KWallet. */ class KWalletEngine : DataEngine { string[] EntryTypes = {"Binary","Passwords","Unknown", "Maps"}; public KWalletEngine() { // TBD: Read Policy information and have a list of wallet names; } public XmlNode Aggregate() { XmlDocument doc = new XmlDocument(); Hashtable lookup = new Hashtable(); XmlElement key1; XmlAttribute Atr; XmlElement value1; XmlAttribute idAttr; String secid, val; XmlElement currentWallet; XmlElement Folder; XmlElement Type; XmlElement Secret; String walletName, foldername, entryType, secretval; //Adding Kwallet Top Node XmlElement elem = doc.CreateElement(ConstStrings.CCF_KW); doc.AppendChild(elem); EnumSecretList enumList = new EnumSecretList(); //kwallet.Try(enumList); kwallet.AggregateKW(enumList); EnumSecretList tempEnumSecretList1 = enumList; //This can be Null only when nothing is aggregated. if (((String)Marshal.PtrToStringAnsi(tempEnumSecretList1.walletName)) == null ) { //TBD: Log that there are no secrets to aggregate } else // Something to Aggregate { while (tempEnumSecretList1 != null) { walletName = (String)Marshal.PtrToStringAnsi(tempEnumSecretList1.walletName); // Console.WriteLine("\n\nWallet name is***# : "+walletName); foldername = (String)Marshal.PtrToStringAnsi(tempEnumSecretList1.folderName); //Console.WriteLine("\tFolder***# : "+foldername); int entrytype = tempEnumSecretList1.entryType; //Console.WriteLine("\t\tEntryType ***#: "+entrytype); entryType = EntryTypes[entrytype]; //Console.WriteLine("\t\tEntryType in string ***#: "+entryType); secretval = (String)Marshal.PtrToStringAnsi(tempEnumSecretList1.secretVal); //Console.WriteLine("\t\tSecret***# : "+secretval); //Adding Wallet if (lookup.ContainsKey(walletName)) { //Console.WriteLine("Wallet Node found"); currentWallet = (XmlElement)lookup[walletName]; } else { currentWallet = doc.CreateElement(ConstStrings.CCF_WALLET); idAttr = doc.CreateAttribute(ConstStrings.CCF_ID); idAttr.Value = walletName; currentWallet.SetAttributeNode(idAttr); elem.AppendChild(currentWallet); lookup.Add(walletName,currentWallet); } //Adding Folder String xpath = "descendant::Folder[@Name='"+foldername+"']"; XmlNodeList folList = currentWallet.SelectNodes(xpath); if (folList.Count == 0) { Folder = doc.CreateElement(ConstStrings.CCF_FOLDER); XmlAttribute name_attr = doc.CreateAttribute(ConstStrings.CCF_NAME); name_attr.Value = foldername; Folder.SetAttributeNode(name_attr); currentWallet.AppendChild(Folder); } //Adding Type xpath = "descendant::Folder"; XmlNodeList folderlist = currentWallet.SelectNodes(xpath); foreach(XmlNode folder in folderlist) { XmlAttributeCollection atcol = folder.Attributes; XmlAttribute attr = atcol[ConstStrings.CCF_NAME]; if (attr.InnerXml.Equals(foldername)) { xpath = "descendant::Type[@ID='"+entryType+"']"; XmlNodeList keylist = folder.SelectNodes(xpath); if (keylist.Count == 0) { Type = doc.CreateElement(ConstStrings.CCF_TYPE); XmlAttribute name_attr = doc.CreateAttribute(ConstStrings.CCF_ID); name_attr.Value = entryType; Type.SetAttributeNode(name_attr); folder.AppendChild(Type); } else { //Console.WriteLine("Type Already Added"); } } } //Adding the Secret xpath = "descendant::Folder"; folderlist = currentWallet.SelectNodes(xpath); foreach(XmlNode folder in folderlist) { XmlAttributeCollection atcol = folder.Attributes; XmlAttribute attr = atcol[ConstStrings.CCF_NAME]; if (attr.InnerXml.Equals(foldername)) { xpath = "descendant::Type[@ID='"+entryType+"']"; XmlNodeList keylist = folder.SelectNodes(xpath); if (keylist.Count == 0) { //Console.WriteLine("Construction of CCF Failed"); } else { XmlNode TargetType = folder; string[] split = null; int index = secretval.IndexOf('='); secid = secretval.Substring(0,index); Secret = doc.CreateElement(ConstStrings.CCF_SECRET); XmlAttribute idattr = doc.CreateAttribute(ConstStrings.CCF_ID); idattr.Value = secid; Secret.SetAttributeNode(idattr); if (entryType.Equals("Maps")) { string delim = ";"; char[] delimiter = delim.ToCharArray(); string realval = secretval.Substring(index+1); for(int x = 1; x < 10 ; x++) { split = realval.Split(delimiter, x); } foreach(string s in split) { int ix; string key; string value; //Console.WriteLine("The val is :" + s); if (s.Equals("")) { //Console.WriteLine("No Secret Content for a Secret ID"); key = " "; value = " "; } else { ix = s.IndexOf(':'); key = s.Substring(0,ix); value = s.Substring(ix+1); } key1 = doc.CreateElement(ConstStrings.CCF_KEY); Atr = doc.CreateAttribute(ConstStrings.CCF_ID); Atr.Value = key; key1.SetAttributeNode(Atr); //Value value1 = doc.CreateElement(ConstStrings.CCF_VALUE); value1.InnerText = value; key1.AppendChild(value1); Secret.AppendChild(key1); TargetType.AppendChild(Secret); } } else if (entryType.Equals("Passwords")) { //Console.WriteLine("Passwords"); val = secretval.Substring(index+1); //Key key1 = doc.CreateElement(ConstStrings.CCF_KEY); Atr = doc.CreateAttribute(ConstStrings.CCF_ID); Atr.Value = "Credential"; key1.SetAttributeNode(Atr); //Value value1 = doc.CreateElement(ConstStrings.CCF_VALUE); value1.InnerText = val; key1.AppendChild(value1); Secret.AppendChild(key1); TargetType.AppendChild(Secret); } } } } if (tempEnumSecretList1.next == IntPtr.Zero) { // Console.WriteLine("Reached End ##"); break; } tempEnumSecretList1 = (EnumSecretList)Marshal.PtrToStructure(tempEnumSecretList1.next, typeof(EnumSecretList)); } } kwallet.FreeResources(); return doc.ChildNodes[0]; } public int SetSecret(XmlNode secret) { return ConstStrings.CASA_SUCCESS; } public int GetSecret(XmlNode secret) { return ConstStrings.CASA_SUCCESS; } public int Remove(XmlNode secret) { return ConstStrings.CASA_SUCCESS; } } }