CASA/c_adlib/GKEngine.cs

444 lines
18 KiB
C#

/***********************************************************************
*
* Copyright (C) 2005-2006 Novell, Inc.
*
* 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 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, write to the Free
* Software Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
*
* 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()
{
}
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);
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 = "GKPassword";
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("GKPassword"))
{
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));
return true;
}
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
}
}