/*********************************************************************** * * 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(""); sb.Append(""); sb.Append(secretID); sb.Append(""); sb.Append(""); // 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(""); sb.Append(""); return sb.ToString(); } } }