2006-01-19 00:34:21 +01:00
|
|
|
/***********************************************************************
|
|
|
|
*
|
2006-02-01 18:48:29 +01:00
|
|
|
* Copyright (C) 2005-2006 Novell, Inc. All Rights Reserved.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* 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
|
2006-01-31 23:01:47 +01:00
|
|
|
* Library Lesser General Public License for more details.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* You should have received a copy of the GNU Lesser General Public
|
2006-01-31 23:01:47 +01:00
|
|
|
* License along with this library; if not, Novell, Inc.
|
2006-01-19 00:34:21 +01:00
|
|
|
*
|
|
|
|
* To contact Novell about this file by physical or electronic mail,
|
|
|
|
* you may find current contact information at www.novell.com.
|
|
|
|
*
|
|
|
|
***********************************************************************/
|
|
|
|
|
2006-01-25 22:24:37 +01:00
|
|
|
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()
|
|
|
|
{
|
|
|
|
|
2006-02-14 01:40:33 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
~GKEngine()
|
|
|
|
{
|
2006-02-15 01:17:28 +01:00
|
|
|
GnomeKeyring.ReleaseGnomeKeyringLib();
|
2006-01-25 22:24:37 +01:00
|
|
|
}
|
|
|
|
|
|
|
|
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()
|
|
|
|
{
|
2006-02-15 01:17:28 +01:00
|
|
|
Console.WriteLine("Checking GKEngine");
|
2006-01-25 22:24:37 +01:00
|
|
|
try
|
|
|
|
{
|
2006-02-15 01:17:28 +01:00
|
|
|
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;
|
|
|
|
}
|
2006-01-25 22:24:37 +01:00
|
|
|
}
|
|
|
|
catch(DllNotFoundException d)
|
|
|
|
{
|
2006-02-14 13:46:09 +01:00
|
|
|
//Console.WriteLine("Store Not Available Exception = " + d.ToString());
|
2006-01-25 22:24:37 +01:00
|
|
|
return false;
|
|
|
|
}
|
|
|
|
catch(Exception e)
|
|
|
|
{
|
2006-02-14 13:46:09 +01:00
|
|
|
//Console.WriteLine("Store Not Available Exception = " + e.ToString());
|
2006-01-25 22:24:37 +01:00
|
|
|
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
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|