diff --git a/c_micasad/verbs/ReadBinaryKey.cs b/c_micasad/verbs/ReadBinaryKey.cs new file mode 100644 index 00000000..ab6c8e83 --- /dev/null +++ b/c_micasad/verbs/ReadBinaryKey.cs @@ -0,0 +1,180 @@ +using System; +using System.Collections; +using System.Text; +using System.Threading; +using sscs.verbs; +using sscs.cache; +using sscs.common; +using sscs.constants; +namespace sscs.verbs +{ + + /* + * This class is implementation of ReadKey call. + * There will be one instance existing for every call made by the client. + */ + + internal class ReadBinaryKey : SSVerb + { + private ushort msgId = 0; + private uint inMsgLen = 0; + private uint outMsgLen = 0; + private uint keyChainIdLen = 0; + private uint secretIdLen = 0; + private int retCode = 0; + private string keyChainId; + private string secretId; + private uint keyLen; + private string key; + private uint valLen; + private byte[] val; + + //private byte[] secretVal; + + private byte[] inBuf; + private byte[] outBuf; + + /* + * This method sets the class member with the byte array received. + */ + + public void SetMessageContent(byte[] ipcBytes) + { + CSSSLogger.ExecutionTrace(this); + inBuf = ipcBytes; + } + + /* + * This method does the actual implementation of ReadKey + * + */ + + public byte[] ProcessRequest(UserIdentifier userId) + { + + Secret secret = null; + + CSSSLogger.ExecutionTrace(this); + + /* If an exception occurs in message format decoding, + * it is handled by AppHandler + */ + + // Message Format decipher - Start + msgId = BitConverter.ToUInt16(inBuf,0); + inMsgLen = BitConverter.ToUInt32(inBuf,2); + + if( inMsgLen != inBuf.Length ) + throw new FormatException(" MsgLen sent does not match the length of the message received."); + + keyChainIdLen = BitConverter.ToUInt32(inBuf,6); + + byte[] keyChainIdArr = new byte[keyChainIdLen]; + Array.Copy(inBuf,10,keyChainIdArr,0,keyChainIdLen); + keyChainId = Encoding.UTF8.GetString(keyChainIdArr); + + secretIdLen = BitConverter.ToUInt32(inBuf, + (10 + (int)keyChainIdLen)); + + byte[] secretIdArr = new byte[secretIdLen]; + Array.Copy(inBuf,(10+keyChainIdLen+4),secretIdArr,0,secretIdLen); + secretId = Encoding.UTF8.GetString(secretIdArr); + // Message Format decipher - End + + keyLen = BitConverter.ToUInt32(inBuf,(14+(int)keyChainIdLen+(int)secretIdLen)); + + byte[] keyArr = new byte[keyLen]; + Array.Copy(inBuf,(18+(int)keyChainIdLen+(int)secretIdLen),keyArr,0,keyLen); + key = Encoding.UTF8.GetString(keyArr); + + try + { + KeyChain keyChain = null; + // Secret secret = null; + SecretStore ssStore = SessionManager.GetUserSecretStore(userId); + if (!ssStore.IsStoreLocked()) + { + if( ssStore.CheckIfKeyChainExists(keyChainId) ) + { + keyChain = ssStore.GetKeyChain(keyChainId); + if( keyChain.CheckIfSecretExists(secretId) == false) + { + retCode = IPCRetCodes.SSCS_E_SECRETID_DOES_NOT_EXIST; + } + else + { + secret = keyChain.GetSecret(secretId); + val = secret.GetKeyValue(key).GetValueAsBytes(); + } + } + else + { + retCode = IPCRetCodes.SSCS_E_KEYCHAIN_DOES_NOT_EXIST; + } + } + else + retCode = IPCRetCodes.SSCS_E_SECRETID_DOES_NOT_EXIST; + + } + catch(UserNotInSessionException) + { + CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable user's secretstore" ); + retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR; + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR; + } + + try + { + msgId = 16; + if( 0 == retCode ) + { + valLen = (uint)val.Length; + outMsgLen = 14 + valLen; + } + else + { + outMsgLen = 14; //2+4+4+4 + } + + outBuf = new byte[outMsgLen]; + byte[] t = new byte[10]; + + t = BitConverter.GetBytes((ushort)msgId); + Array.Copy(t,0,outBuf,0,2); + + t = BitConverter.GetBytes((uint)outMsgLen); + Array.Copy(t,0,outBuf,2,4); + + t = BitConverter.GetBytes(valLen); + Array.Copy(t,0,outBuf,6,4); + + if( 0 == retCode ) + Array.Copy(val,0,outBuf,10,valLen); + + t = BitConverter.GetBytes(retCode); + Array.Copy(t,0,outBuf,10+valLen,4); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + throw new FormatException("Unable to form the response " + e.ToString()); + } + return outBuf; + + } + + /* + * Gives the name of operation performed. Will be used in case + * of error. + */ + public string GetVerbName() + { + CSSSLogger.ExecutionTrace(this); + return this.ToString(); + } + } +} diff --git a/c_micasad/verbs/WriteBinaryKey.cs b/c_micasad/verbs/WriteBinaryKey.cs new file mode 100644 index 00000000..f21cbeff --- /dev/null +++ b/c_micasad/verbs/WriteBinaryKey.cs @@ -0,0 +1,291 @@ +using System; +using System.Collections; +using System.Text; +using System.Threading; +using sscs.verbs; +using sscs.common; +using sscs.cache; +using sscs.constants; + +using Novell.CASA.MiCasa.Common; + +namespace sscs.verbs +{ + + /* + * This class is implementation of WriteKey call. + * There will be one instance existing for every call made by the client. + */ + + class WriteBinaryKey : SSVerb + { + private ushort msgId = 0; + private uint inMsgLen = 0; + private uint outMsgLen = 0; + private uint keyChainIdLen = 0; + private uint secretIdLen = 0; + private uint secretValLen = 0; + private int retCode = 0; + private string keyChainId; + private string secretId; + + private uint keyLen; + private string key; + private uint valLen; + private byte[] val; + //private string valStr; + + private byte[] inBuf; + private byte[] outBuf; + + // extension operations + private uint extId = 0; +#if W32 + private int luidLow = 0; + private int luidHigh = 0; +#endif + + /* + * This method sets the class member with the byte array received. + */ + + public void SetMessageContent(byte[] ipcBytes) + { + CSSSLogger.ExecutionTrace(this); + inBuf = ipcBytes; + } + + /* + * This method does the actual implementation of WriteKey + * + */ + + public byte[] ProcessRequest(UserIdentifier userId) + { + CSSSLogger.ExecutionTrace(this); + UserIdentifier tempUserId = userId; + // Message Format decipher - Start + msgId = BitConverter.ToUInt16(inBuf,0); + inMsgLen = BitConverter.ToUInt32(inBuf,2); + + if( inMsgLen != inBuf.Length ) + throw new FormatException(" MsgLen sent does not match the length of the message received."); + + keyChainIdLen = BitConverter.ToUInt32(inBuf,6); + + byte[] keyChainIdArr = new byte[keyChainIdLen]; + Array.Copy(inBuf,10,keyChainIdArr,0,keyChainIdLen); + keyChainId = Encoding.UTF8.GetString(keyChainIdArr); + + secretIdLen = BitConverter.ToUInt32(inBuf, + (10 + (int)keyChainIdLen )); + + byte[] secretIdArr = new byte[secretIdLen]; + Array.Copy(inBuf,(10+keyChainIdLen+4),secretIdArr,0,secretIdLen); + secretId = Encoding.UTF8.GetString(secretIdArr); + + if (secretId.IndexOf("*") < 0) + { + + keyLen = BitConverter.ToUInt32(inBuf,(14+(int)keyChainIdLen+(int)secretIdLen)); + byte[] keyArr = new byte[keyLen]; + Array.Copy(inBuf,(18+keyChainIdLen+secretIdLen),keyArr,0,keyLen); + key = Encoding.UTF8.GetString(keyArr); + + + valLen = BitConverter.ToUInt32(inBuf,(18+(int)keyChainIdLen+(int)secretIdLen+(int)keyLen)); + val = new byte[valLen]; + Array.Copy(inBuf,(22+keyChainIdLen+secretIdLen+keyLen),val,0,valLen); + + try + { + // get extension ID + int extLocation = 26 + ((int)keyChainIdLen) + ((int)secretIdLen) + ((int)keyLen) + ((int)valLen); + extId = BitConverter.ToUInt32(inBuf, extLocation); + } + catch (Exception) + { + //CSSSLogger.ExpLog(e.ToString()); + } + + if (extId == 1) + { +#if W32 + + // WINDOWS LUID + // This is how the Login Capture module on windows, running as System, sets the Desktop Credential. + // we might be able to change this if/when we abstract the session. + // [4 byte extID][4 byte length][4 byte luidLow][4 byte luidHigh] + luidLow = BitConverter.ToInt32(inBuf, 26 + ((int)keyChainIdLen)+((int)secretIdLen) +((int)keyLen) + (int)valLen + 8); + luidHigh = BitConverter.ToInt32(inBuf, 26 + ((int)keyChainIdLen)+((int)secretIdLen) +((int)keyLen) + (int)valLen + 12); + tempUserId = new WinUserIdentifier(luidLow, luidHigh); + SecretStore ss = SessionManager.CreateUserSession(tempUserId); + try + { + ss.AddKeyChain(new KeyChain("SSCS_SESSION_KEY_CHAIN_ID\0")); + } + catch (Exception) + { + + } +#endif + } + + + try + { + KeyChain keyChain = null; + SecretStore ssStore = SessionManager.GetUserSecretStore(tempUserId); + if (!ssStore.IsStoreLocked()) + { + if( ssStore.CheckIfKeyChainExists(keyChainId) ) + { + keyChain = ssStore.GetKeyChain(keyChainId); + Secret secret = null; + + // add this secret if it doesn't already exist + if( keyChain.CheckIfSecretExists(secretId) == false) + { + secret = new Secret(secretId); + keyChain.AddSecret(secret); + } + else + { + secret = keyChain.GetSecret(secretId); + } + string oldPasswd = null; + if((ConstStrings.MICASA_DESKTOP_PASSWD == secretId) && + (ConstStrings.MICASA_DESKTOP_PASSWD_KEYNAME == key) + ) + { + KeyValue kv = secret.GetKeyValue(ConstStrings.MICASA_DESKTOP_PASSWD_KEYNAME); + if( null != kv ) + oldPasswd = kv.GetValue(); + } + + secret.SetKeyValue(key,val); + + if((ConstStrings.MICASA_DESKTOP_PASSWD == secretId) && + (ConstStrings.MICASA_DESKTOP_PASSWD_KEYNAME == key) + ) + { + string passwd = secret.GetKeyValue(ConstStrings.MICASA_DESKTOP_PASSWD_KEYNAME).GetValue(); + + if( ( oldPasswd != null ) && ( passwd != null ) ) + { + if( oldPasswd != passwd ) + { + byte[] baPasscode = ssStore.GetPasscodeFromOldDesktopPasswd(oldPasswd); + if( null != baPasscode ) + { + ssStore.RewriteDesktopPasswdFile(baPasscode, passwd); + } + } + } + ssStore.StartPersistenceByDesktopPasswd(passwd); + } + + // Now change all values for linked keys + //ChangeLinkedKeys(keyChain, secret, key, valStr); + ssStore.UpdatePersistentStore(); + + } + else + { + retCode = IPCRetCodes.SSCS_E_KEYCHAIN_DOES_NOT_EXIST; + } + } + else + { + // do nothing + } + + } + catch(UserNotInSessionException) + { + CSSSLogger.DbgLog("In " + CSSSLogger.GetExecutionPath(this) + " Unable to get user's secretstore" ); + retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR; + } + catch(Exception e ) + { + CSSSLogger.ExpLog(e.ToString()); + retCode = IPCRetCodes.SSCS_E_SYSTEM_ERROR; + } + } + else + retCode = IPCRetCodes.SSCS_E_INVALID_SECRETID; + + try + { + msgId = 9; + outMsgLen = 10; + outBuf = new byte[10]; + byte[] t = new byte[10]; + + t = BitConverter.GetBytes((ushort)msgId); + Array.Copy(t,0,outBuf,0,2); + + t = BitConverter.GetBytes((uint)outMsgLen); + Array.Copy(t,0,outBuf,2,4); + + t = BitConverter.GetBytes(retCode); + Array.Copy(t,0,outBuf,6,4); + } + catch(Exception e) + { + CSSSLogger.ExpLog(e.ToString()); + throw new FormatException("Unable to form the response " + e.ToString()); + } + + return outBuf; + } + + + private void ChangeLinkedKeys(KeyChain keyChain, Secret secret, string key, string valStr) + { + Hashtable htLinkedkeys = secret.GetLinkedKeys(key); + if (htLinkedkeys != null) + { + // enumerate the hashtable, getting each secret/key and change it's value + ICollection coll = htLinkedkeys.Values; + IDictionaryEnumerator ienum = (IDictionaryEnumerator)coll.GetEnumerator(); + + LinkedKeyInfo linkedInfo; // = (LinkedKeyInfo)ienum.Current; + + while (ienum.MoveNext()) + { + linkedInfo = (LinkedKeyInfo)ienum.Value; + + // Get the target Secret + Secret targetSecret = keyChain.GetSecret(linkedInfo.GetLinkedSecretID()); + if (targetSecret != null) + { + // get target key value + string targetkv = targetSecret.GetKeyValue(linkedInfo.GetLinkedKeyID()).GetValue(); + + // if a change is required in the target, then call this method recursively using the TargetSecret + if (!targetkv.Equals(valStr)) + { + // NOTE: ORDER IS IMPORTANT + // first change this one + targetSecret.SetKeyValue(linkedInfo.GetLinkedKeyID(), valStr); + + // now call the traget to change it's linked ones + ChangeLinkedKeys(keyChain, targetSecret, key, valStr); + } + } + } + } + } + + /* + * Gives the name of operation performed. Will be used in case + * of error. + */ + public string GetVerbName() + { + CSSSLogger.ExecutionTrace(this); + return this.ToString(); + } + } +}