/*********************************************************************** * * Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved. * * This library is free software; you can redistribute it and/or * modify it under the terms of the GNU Lesser General Public * License as published by the Free Software Foundation; version 2.1 * of the License. * * This library is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU * Library Lesser General Public License for more details. * * You should have received a copy of the GNU Lesser General Public * License along with this library; if not, Novell, Inc. * * To contact Novell about this file by physical or electronic mail, * you may find current contact information at www.novell.com. * ***********************************************************************/ using System; using System.Collections; using System.Xml; using System.IO; using System.Collections.Specialized; using System.Runtime.InteropServices; using Novell.CASA.DataEngines.Common; using Novell.CASA.DataEngines.GK; namespace Novell.CASA.DataEngines { /* * This class is implementation of Data engine for Gnome-Keyring. */ class GKEngine : DataEngine { enum KeyringResultExtended { GNOME_KEYRING_RESULT_NO_SUCH_ITEM = 128, GNOME_KEYRING_RESULT_CANNOT_DELETE_SECRET_VALUE, GNOME_KEYRING_RESULT_MALFORMED_XML, GNOME_KEYRING_RESULT_CANNOT_CREATE_KEYRING, GNOME_KEYRING_RESULT_ERROR_UNKNOWN }; public GKEngine() { } ~GKEngine() { GnomeKeyring.ReleaseGnomeKeyringLib(); } public XmlNode Aggregate() { XmlDocument doc = new XmlDocument(); XmlNode rootElem = doc.CreateElement(ConstStrings.CCF_GKTAG); doc.AppendChild(rootElem); XmlElement keyringElem; ArrayList itemList; ArrayList attrList; ItemInfo itemInfo; KeyringInfo keyringInfo; int itemId; ArrayList keyringList = GnomeKeyring.GKGetKeyrings(); IEnumerator kEtor = keyringList.GetEnumerator(); IEnumerator iEtor; while(kEtor.MoveNext()) { string keyring = (string)(kEtor.Current); keyringElem = doc.CreateElement(ConstStrings.CCF_GKKEYRING); XmlAttribute idAttr = doc.CreateAttribute(ConstStrings.CCF_ID); idAttr.Value = keyring; keyringElem.SetAttributeNode(idAttr); keyringInfo = GnomeKeyring.GKGetKeyringInfo(keyring); itemList = GnomeKeyring.GKGetItems(keyring); iEtor = itemList.GetEnumerator(); while(iEtor.MoveNext()) { itemId = (int)iEtor.Current; itemInfo = GnomeKeyring.GKGetItemInfo(keyring,itemId); attrList = GnomeKeyring.GKGetAttributeList(keyring,itemId); if(itemInfo.displayName==null) continue; XmlElement secretElem = doc.CreateElement(ConstStrings.CCF_SECRET); XmlAttribute secIdAttr = doc.CreateAttribute(ConstStrings.CCF_ID); secIdAttr.Value = itemInfo.displayName + ":" + itemId; secretElem.SetAttributeNode(secIdAttr); XmlAttribute typeAttr = doc.CreateAttribute(ConstStrings.CCF_TYPE); typeAttr.Value = itemInfo.itemType.ToString(); secretElem.SetAttributeNode(typeAttr); XmlElement keyElem = null; XmlAttribute keyIdAttr = null; XmlElement valueElem = null; if ((itemInfo.secret != null) && (itemInfo.secret.Length != 0)) { keyElem = doc.CreateElement(ConstStrings.CCF_KEY); keyIdAttr = doc.CreateAttribute(ConstStrings.CCF_ID); keyIdAttr.Value = "password"; keyElem.SetAttributeNode(keyIdAttr); valueElem = doc.CreateElement(ConstStrings.CCF_VALUE); valueElem.InnerText = itemInfo.secret; keyElem.AppendChild(valueElem); secretElem.AppendChild(keyElem); } IEnumerator attrEtor = (IEnumerator)(attrList.GetEnumerator()); while(attrEtor.MoveNext()) { Novell.CASA.DataEngines.GK.Attribute attr = (Novell.CASA.DataEngines.GK.Attribute)(attrEtor.Current); keyElem = doc.CreateElement(ConstStrings.CCF_KEY); keyIdAttr = doc.CreateAttribute(ConstStrings.CCF_ID); keyIdAttr.Value = attr.key; keyElem.SetAttributeNode(keyIdAttr); valueElem = doc.CreateElement(ConstStrings.CCF_VALUE); valueElem.InnerText = attr.value; keyElem.AppendChild(valueElem); secretElem.AppendChild(keyElem); } keyringElem.AppendChild(secretElem); XmlElement timeElem = doc.CreateElement(ConstStrings.CCF_TIME); XmlElement itemCreatedTimeElem = doc.CreateElement(ConstStrings.CCF_CRTIME); itemCreatedTimeElem.InnerText = itemInfo.mTime.ToString(); timeElem.AppendChild(itemCreatedTimeElem); XmlElement itemModifiedTimeElem = doc.CreateElement(ConstStrings.CCF_MDTIME); itemModifiedTimeElem.InnerText = itemInfo.cTime.ToString(); timeElem.AppendChild(itemModifiedTimeElem); secretElem.AppendChild(timeElem); } XmlElement keyringTimeElem = doc.CreateElement(ConstStrings.CCF_TIME); XmlElement createdTimeElem = doc.CreateElement(ConstStrings.CCF_CRTIME); createdTimeElem.InnerText = keyringInfo.mTime.ToString(); keyringTimeElem.AppendChild(createdTimeElem); XmlElement modifiedTimeElem = doc.CreateElement(ConstStrings.CCF_MDTIME); modifiedTimeElem.InnerText = keyringInfo.cTime.ToString(); keyringTimeElem.AppendChild(modifiedTimeElem); keyringElem.AppendChild(keyringTimeElem); XmlElement lockElem = doc.CreateElement(ConstStrings.CCF_LOCK); XmlAttribute lockStatusAttr = doc.CreateAttribute(ConstStrings.CCF_LOCKSTATUS); if( keyringInfo.isLocked == 1 ) lockStatusAttr.Value = "locked"; else lockStatusAttr.Value = "unlocked"; lockElem.SetAttributeNode(lockStatusAttr); XmlAttribute lockOnIdleAttr = doc.CreateAttribute(ConstStrings.CCF_LOCKHAND); if( keyringInfo.lockOnIdle == 1) lockOnIdleAttr.Value = "true"; else lockOnIdleAttr.Value = "false"; lockElem.SetAttributeNode(lockOnIdleAttr); XmlAttribute lockTimeoutAttr = doc.CreateAttribute(ConstStrings.CCF_LOCKTIME); lockTimeoutAttr.Value = keyringInfo.lockTimeout.ToString(); lockElem.SetAttributeNode(lockTimeoutAttr); keyringElem.AppendChild(lockElem); rootElem.AppendChild(keyringElem); } #if TEST XmlTextWriter writer = new XmlTextWriter("./gk.xml",null); writer.Formatting = Formatting.Indented; doc.Save(writer); writer.Close(); #endif return doc.ChildNodes[0]; } public int SetSecret(XmlNode secret) { return (int)KeyringResultExtended.GNOME_KEYRING_RESULT_ERROR_UNKNOWN; } public int SetSecret(XmlNode secret, int opnType) { string password = ""; int retValue; try { int itemid = ExtractSecretId(secret); string keyringname = ExtractKeyringName(secret); NameValueCollection newNVC = new System.Collections.Specialized.NameValueCollection(); XmlNodeList keylist = secret.SelectNodes("descendant::Key"); foreach (XmlNode tuple in keylist) { //Get the Key XmlAttributeCollection at = tuple.Attributes; String keyname = (at["ID"]).InnerText; if (keyname.Equals("password")) { password = tuple.ChildNodes[0].InnerText; } else { newNVC.Add(keyname, tuple.ChildNodes[0].InnerText); } } if (opnType == ConstStrings.OPERATION_ADD_SECRET ) //Add Item Opn { string strItemType = ExtractItemType(secret); string secretName = ExtractSecretName(secret, opnType); return(GnomeKeyring.CreateSecret(keyringname, strItemType, secretName, password, newNVC)); } //Modify secret Opn retValue = GnomeKeyring.SetPassword(keyringname, itemid, password); if (retValue != 0) { return retValue; } if (newNVC.Count != 0) { return (GnomeKeyring.SetAttributes( keyringname, itemid, newNVC)); } return 0; } catch(NullReferenceException n) { //Console.WriteLine("Exception in SetSecret = "+n.ToString()); return (int)KeyringResultExtended.GNOME_KEYRING_RESULT_MALFORMED_XML; } catch(Exception e) { //Console.WriteLine("Exception in SetSecret = "+e.ToString()); return (int)KeyringResultExtended.GNOME_KEYRING_RESULT_ERROR_UNKNOWN; } } public int GetSecret(XmlNode secret) { return ConstStrings.CASA_SUCCESS; } public int Remove(XmlNode secret) { try { int itemid = ExtractSecretId(secret); string keyringname = ExtractKeyringName(secret); return (GnomeKeyring.RemoveItem( keyringname, itemid)); } catch(NullReferenceException n) { //Console.WriteLine("Exception in Remove = "+n.ToString()); return (int)KeyringResultExtended.GNOME_KEYRING_RESULT_MALFORMED_XML; } catch(Exception e) { //Console.WriteLine("Exception in Remove = "+e.ToString()); return (int)KeyringResultExtended.GNOME_KEYRING_RESULT_ERROR_UNKNOWN; } } public static Boolean IsStoreAvailable() { try { System.Runtime.InteropServices.Marshal.PrelinkAll(typeof(GnomeKeyring)); if (GnomeKeyring.IsGnomeKeyringInstalled()) { //Console.WriteLine("IsGnomeKeyringInstalled is true"); return true; } else { //Console.WriteLine("IsGnomeKeyringInstalled is false"); return false; } } catch(DllNotFoundException d) { //Console.WriteLine("Store Not Available Exception = " + d.ToString()); return false; } catch(Exception e) { //Console.WriteLine("Store Not Available Exception = " + e.ToString()); return false; } } int ExtractSecretId(XmlNode secret) { XmlAttributeCollection atcol = secret.Attributes; String secretid = atcol["ID"].InnerXml; //Check if itemId is present /*if (secretid.EndsWith(":")) { return -2; } */ int itemIdx = secretid.LastIndexOf(":"); if (itemIdx == -1) { return -1; } int itemid = Convert.ToInt32(secretid.Substring(itemIdx + 1)); return itemid; } string ExtractSecretName(XmlNode secret, int opnType) { XmlAttributeCollection atcol = secret.Attributes; String secretid = atcol["ID"].InnerXml; if (opnType == ConstStrings.OPERATION_ADD_SECRET) { return secretid; //Not expecting an item Id } int itemIdx = secretid.LastIndexOf(":"); //Return substring without itemId return(secretid.Substring(0,itemIdx)); } string ExtractKeyringName(XmlNode secret) { XmlAttributeCollection atcol; XmlNode parentNode = secret.ParentNode; atcol = parentNode.Attributes; String keyringname = atcol["ID"].InnerXml; return keyringname; } string ExtractItemType(XmlNode secret) { XmlAttributeCollection atcol = secret.Attributes; String itemType = atcol[ConstStrings.CCF_TYPE].InnerXml; return(itemType); } #if TEST public static void Main() { GKEngine gk = new GKEngine(); Console.WriteLine(); Console.WriteLine("********** Menu ***********"); Console.WriteLine("* 1. Add secret *"); Console.WriteLine("* 2. Modify secret *"); Console.WriteLine("* 3. Set secret *"); Console.WriteLine("* 4. Remove secret *"); Console.WriteLine("* 5. Refresh *"); Console.WriteLine("* 6. Is Store Avail *"); Console.WriteLine("* 7. Quit *"); Console.WriteLine("***************************"); Console.WriteLine("For all options the input is the file /root/gktest.xml"); Console.WriteLine("Select option and Press enter"); String line = Console.ReadLine(); int res = 0; if (line.Length > 0) { char[] c = line.Substring(0, 1).ToCharArray(); if (c.Length > 0) { if (c[0].Equals('7')) return; if (c[0].Equals('6')) { Console.WriteLine("Store Available is = " + GKEngine.IsStoreAvailable()); return; } if (c[0].Equals('5')) { XmlNode node = gk.Aggregate (); XmlDocument doc = node.OwnerDocument; XmlTextWriter writer = new XmlTextWriter("/root/gktest.xml",null); writer.Formatting = Formatting.Indented; doc.Save(writer); writer.Close(); } else { XmlDocument xmlDoc = new XmlDocument(); XmlTextReader tr = new XmlTextReader("/root/gktest.xml"); tr.Read(); xmlDoc.Load(tr); XmlNode root = xmlDoc.LastChild; if (root == null) { Console.WriteLine("Root is null"); } XmlNode secret = root.ChildNodes[0].ChildNodes[0]; Console.WriteLine("secret Name \n" + secret.Name); if (c[0].Equals('4')) res =gk.Remove(secret); else if (c[0].Equals('1')) res = gk.SetSecret(secret, ConstStrings.OPERATION_ADD_SECRET); else if (c[0].Equals('2')) res = gk.SetSecret(secret, ConstStrings.OPERATION_MODIFY_SECRET); else if (c[0].Equals('3')) res = gk.SetSecret(secret); } } } Console.WriteLine("Result of Operation = " + res); } #endif } }