404 lines
11 KiB
C#
404 lines
11 KiB
C#
/***********************************************************************
|
|
*
|
|
* 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.Text;
|
|
using System.Collections;
|
|
|
|
using Novell.CASA.MiCasa.Common;
|
|
|
|
namespace sscs.cache
|
|
{
|
|
class Secret : ISecret
|
|
{
|
|
private string secretID;
|
|
//private byte[] data;
|
|
string ePasswd ; // TBD
|
|
|
|
DateTime createdTime;
|
|
public DateTime CreatedTime
|
|
{
|
|
get
|
|
{
|
|
return createdTime;
|
|
}
|
|
set
|
|
{
|
|
createdTime = value;
|
|
}
|
|
}
|
|
|
|
DateTime accessedTime;
|
|
public DateTime AccessedTime
|
|
{
|
|
get
|
|
{
|
|
return accessedTime;
|
|
}
|
|
set
|
|
{
|
|
accessedTime = value;
|
|
}
|
|
}
|
|
|
|
DateTime modifiedTime;
|
|
public DateTime ModifiedTime
|
|
{
|
|
get
|
|
{
|
|
return modifiedTime;
|
|
}
|
|
set
|
|
{
|
|
modifiedTime = value;
|
|
}
|
|
}
|
|
|
|
|
|
private Hashtable htKeyValues = new Hashtable();
|
|
internal Secret()
|
|
{
|
|
}
|
|
|
|
internal Secret(string secretID)
|
|
{
|
|
this.secretID = secretID;
|
|
}
|
|
|
|
internal Secret(string secretID, byte[] data)
|
|
{
|
|
this.secretID = secretID;
|
|
//this.data = data;
|
|
|
|
// parse the data
|
|
ParseDataBuffer(data);
|
|
|
|
}
|
|
|
|
internal Secret(string secretID, byte[] data, string ePasswd)
|
|
{
|
|
this.secretID = secretID;
|
|
this.ePasswd = ePasswd;
|
|
ParseDataBuffer(data);
|
|
}
|
|
|
|
internal void ParseDataBuffer(byte[] data)
|
|
{
|
|
|
|
if (data != null)
|
|
{
|
|
UTF8Encoding dec = new UTF8Encoding();
|
|
string theData = dec.GetString(data);
|
|
|
|
char[] theChars = new char[2];
|
|
theChars[0] = '\n';
|
|
theChars[1] = '\0';
|
|
String[] keyValues = theData.Split(theChars);
|
|
|
|
char delimiter = '=';
|
|
foreach (string keyValue in keyValues)
|
|
{
|
|
int iLocation = keyValue.IndexOf(delimiter);
|
|
if (iLocation > 0)
|
|
{
|
|
String key = keyValue.Substring(0, iLocation);
|
|
String value = keyValue.Substring(iLocation + 1);
|
|
|
|
if (key != null && value != null)
|
|
this.SetKeyValue(key, value);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
internal void SetEpasswd(string value)
|
|
{
|
|
ePasswd = value;
|
|
}
|
|
|
|
internal string GetEpasswd()
|
|
{
|
|
return ePasswd;
|
|
}
|
|
|
|
public void SetValue(byte[] data)
|
|
{
|
|
this.ModifiedTime = DateTime.Now;
|
|
ParseDataBuffer(data);
|
|
}
|
|
|
|
public void SetKey(String newkey)
|
|
{
|
|
//Validation TBD
|
|
this.secretID = newkey;
|
|
}
|
|
|
|
//Get methods
|
|
public byte[] GetValue(String key)
|
|
{
|
|
//validation TBD
|
|
//if (data == null)
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
IDictionaryEnumerator etor = (IDictionaryEnumerator)this.htKeyValues.GetEnumerator();
|
|
while(etor.MoveNext())
|
|
{
|
|
string sKey = (string)etor.Key;
|
|
KeyValue kv = (KeyValue)this.htKeyValues[sKey];
|
|
|
|
sb.Append(kv.Key);
|
|
sb.Append("=");
|
|
if (kv.GetValueType() ==(KeyValue.VALUE_TYPE_BINARY))
|
|
sb.Append("BINARY - Do not change");
|
|
else
|
|
sb.Append(kv.GetValue());
|
|
sb.Append('\n');
|
|
}
|
|
//sb.Append('\0');
|
|
|
|
UTF8Encoding enc = new UTF8Encoding();
|
|
this.AccessedTime = DateTime.Now;
|
|
return (enc.GetBytes(sb.ToString()));
|
|
}
|
|
//else
|
|
// return data;
|
|
}
|
|
public byte[] GetValue()
|
|
{
|
|
//validation TBD
|
|
this.AccessedTime = DateTime.Now;
|
|
return GetValue(null);
|
|
}
|
|
|
|
public string GetKey()
|
|
{
|
|
return secretID;
|
|
}
|
|
|
|
public void SetKeyValue(string key, string value)
|
|
{
|
|
KeyValue kv;
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
kv = (KeyValue)htKeyValues[key];
|
|
kv.SetValue(value);
|
|
}
|
|
else
|
|
{
|
|
kv = new KeyValue(key, value);
|
|
htKeyValues.Add(key, kv);
|
|
}
|
|
this.ModifiedTime = DateTime.Now;
|
|
}
|
|
|
|
public void SetKeyValue(string key, byte[] baValue)
|
|
{
|
|
KeyValue kv;
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
kv = (KeyValue)htKeyValues[key];
|
|
kv.SetValue(baValue);
|
|
}
|
|
else
|
|
{
|
|
kv = new KeyValue(key, baValue);
|
|
htKeyValues.Add(key, kv);
|
|
}
|
|
this.ModifiedTime = DateTime.Now;
|
|
}
|
|
|
|
public KeyValue GetKeyValue(string key)
|
|
{
|
|
this.AccessedTime = DateTime.Now;
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
KeyValue kv = (KeyValue)htKeyValues[key];
|
|
return kv;
|
|
}
|
|
else
|
|
return null;
|
|
}
|
|
|
|
internal void RemoveAllKeyValuePairs(KeyChain kc)
|
|
{
|
|
if (htKeyValues != null)
|
|
{
|
|
IDictionaryEnumerator enumer = htKeyValues.GetEnumerator();
|
|
while (enumer.MoveNext())
|
|
{
|
|
String key = (String)enumer.Key;
|
|
RemoveKeyValue(kc, key);
|
|
// refresh enumerator
|
|
enumer = htKeyValues.GetEnumerator();
|
|
}
|
|
}
|
|
}
|
|
|
|
public void RemoveKeyValue(KeyChain kc, string key)
|
|
{
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
// remove all reverse links first
|
|
RemoveReverseLinkedKeys(kc, key);
|
|
htKeyValues.Remove(key);
|
|
}
|
|
}
|
|
|
|
private void RemoveReverseLinkedKeys(KeyChain kc, string keyId)
|
|
{
|
|
Hashtable linkedKeys = GetLinkedKeys(keyId);
|
|
if (kc != null && linkedKeys != null)
|
|
{
|
|
IDictionaryEnumerator lkis = linkedKeys.GetEnumerator();
|
|
while (lkis.MoveNext())
|
|
{
|
|
LinkedKeyInfo lki = (LinkedKeyInfo)lkis.Value;
|
|
|
|
// look up reverse linked key
|
|
Secret secret = kc.GetSecret(lki.GetLinkedSecretID());
|
|
if (secret != null)
|
|
{
|
|
// look up linked key
|
|
KeyValue kv = secret.GetKeyValue(lki.GetLinkedKeyID());
|
|
kv.RemoveLink(secretID + ":" + keyId);
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
public DateTime GetKeyValueCreatedTime(string key)
|
|
{
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
KeyValue kv = (KeyValue)htKeyValues[key];
|
|
return kv.CreatedTime;
|
|
}
|
|
else
|
|
return (new DateTime(0));
|
|
}
|
|
|
|
public Hashtable GetLinkedKeys(string keyId)
|
|
{
|
|
if (htKeyValues.Contains(keyId))
|
|
{
|
|
KeyValue kv = (KeyValue)htKeyValues[keyId];
|
|
return kv.GetLinkedKeys();
|
|
}
|
|
else
|
|
return null;
|
|
|
|
}
|
|
|
|
public DateTime GetKeyValueModifiedTime(string key)
|
|
{
|
|
if (htKeyValues.Contains(key))
|
|
{
|
|
KeyValue kv = (KeyValue)htKeyValues[key];
|
|
return kv.ModifiedTime;
|
|
}
|
|
else
|
|
return (new DateTime(0));
|
|
}
|
|
|
|
|
|
public void MergeSecret(SecretStore store, Secret newSecret)
|
|
{
|
|
|
|
IDictionaryEnumerator etor = (IDictionaryEnumerator)newSecret.htKeyValues.GetEnumerator();
|
|
while(etor.MoveNext())
|
|
{
|
|
string sKey = (string)etor.Key;
|
|
|
|
// TODO: When we sync, we should consider modified time as well
|
|
KeyValue newKV = (KeyValue)newSecret.htKeyValues[sKey];
|
|
this.SetKeyValue(newKV.Key, newKV.GetValue());
|
|
}
|
|
etor = (IDictionaryEnumerator)newSecret.htKeyValues.GetEnumerator();
|
|
while(etor.MoveNext())
|
|
{
|
|
string sKey = (string)etor.Key;
|
|
if(!htKeyValues.Contains(sKey))
|
|
this.RemoveKeyValue(store.GetKeyChainDefault(), sKey);
|
|
}
|
|
}
|
|
|
|
public ArrayList GetKeyList()
|
|
{
|
|
IDictionaryEnumerator etor = (IDictionaryEnumerator)this.htKeyValues.GetEnumerator();
|
|
ArrayList list = new ArrayList();
|
|
if( null == etor )
|
|
{
|
|
return null;
|
|
}
|
|
while(etor.MoveNext())
|
|
{
|
|
string key = (string)etor.Key;
|
|
list.Add(key);
|
|
}
|
|
return list;
|
|
}
|
|
|
|
internal IDictionaryEnumerator GetKeyValueEnumerator()
|
|
{
|
|
if( htKeyValues != null)
|
|
return htKeyValues.GetEnumerator();
|
|
else
|
|
return null;
|
|
}
|
|
|
|
public string ToXML()
|
|
{
|
|
StringBuilder sb = new StringBuilder();
|
|
|
|
sb.Append("<SECRET>");
|
|
|
|
sb.Append("<ID>");
|
|
sb.Append(secretID);
|
|
sb.Append("</ID>");
|
|
|
|
sb.Append("<DATA>");
|
|
// enum the htKeyValues list
|
|
//IDictionaryEnumerator ienum = htKeyValues.GetEnumerator();
|
|
ICollection coll = htKeyValues.Values;
|
|
|
|
IDictionaryEnumerator ienum = (IDictionaryEnumerator)coll.GetEnumerator();
|
|
|
|
|
|
KeyValue kv = (KeyValue)ienum.Current;
|
|
while (kv != null)
|
|
{
|
|
sb.Append(kv.ToXML());
|
|
if (ienum.MoveNext())
|
|
kv = (KeyValue)ienum.Value;
|
|
else
|
|
kv = null;
|
|
}
|
|
sb.Append("</DATA>");
|
|
sb.Append("</SECRET>");
|
|
|
|
return sb.ToString();
|
|
}
|
|
}
|
|
}
|