xenadmin/XenCenterLib/EncryptionUtils.cs
Cheng Zhang 934b0cf381 CP-12770: use server connection details received from XenCenter
1. Create named pipe: “HealthCheckServicePipe”
2. Receive credential send from XenServer and decrypt it
3. Update credential setting and save encrypted credential using current user scope system user.
4. Create work thread to handle the pipe communication.
5. If HealthCheckServicePipe already existed before service start, stop service and output service error log
6. If sign off information is received for a host (XenserverName or IP without username and password) then the existing saved credentials will be deleted
7. If the HealthCheckService connects to a host that is no longer enrolled, then it will delete the existing saved credentials

Signed-off-by: Cheng Zhang <cheng.zhang@citrix.com>
2015-07-01 09:54:11 +08:00

162 lines
6.2 KiB
C#

/* Copyright (c) Citrix Systems Inc.
* All rights reserved.
*
* Redistribution and use in source and binary forms,
* with or without modification, are permitted provided
* that the following conditions are met:
*
* * Redistributions of source code must retain the above
* copyright notice, this list of conditions and the
* following disclaimer.
* * Redistributions in binary form must reproduce the above
* copyright notice, this list of conditions and the
* following disclaimer in the documentation and/or other
* materials provided with the distribution.
*
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND
* CONTRIBUTORS "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES,
* INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES OF
* MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE
* DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR
* CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING,
* BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR
* SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS
* INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY,
* WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT (INCLUDING
* NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
* SUCH DAMAGE.
*/
using System;
using System.IO;
using System.Security.Cryptography;
using System.Text;
namespace XenAdmin.Core
{
/// <summary>
/// Used to centralise the encryption routines used for master password
/// & session lists
/// </summary>
public class EncryptionUtils
{
private static byte[] salt;
/// <summary>
/// Returns a secure hash of the given input string (usually the
/// master password). We currently use SHA-1.
/// </summary>
/// <param name="password">The string to hash</param>
/// <returns>The secure hash</returns>
public static byte[] ComputeHash(String password)
{
//SHA1 hasher = SHA1.Create();
MD5 hasher = MD5.Create();
UnicodeEncoding ue = new UnicodeEncoding();
byte[] bytes = ue.GetBytes(password);
byte[] hash = hasher.ComputeHash(bytes);
return hash;
}
public static string Protect(string data)
{
byte[] dataBytes = Encoding.Unicode.GetBytes(data);
byte[] protectedBytes = ProtectedData.Protect(dataBytes, GetSalt(), DataProtectionScope.CurrentUser);
return Convert.ToBase64String(protectedBytes);
}
public static string Unprotect(string protectedstring)
{
byte[] protectedBytes = Convert.FromBase64String(protectedstring);
byte[] dataBytes = ProtectedData.Unprotect(protectedBytes, GetSalt(), DataProtectionScope.CurrentUser);
return Encoding.Unicode.GetString(dataBytes);
}
public static string ProtectForLocalMachine(string data)
{
byte[] dataBytes = Encoding.Unicode.GetBytes(data);
byte[] protectedBytes = ProtectedData.Protect(dataBytes, GetSalt(), DataProtectionScope.LocalMachine);
return Convert.ToBase64String(protectedBytes);
}
public static string UnprotectForLocalMachine(string protectedstring)
{
byte[] protectedBytes = Convert.FromBase64String(protectedstring);
byte[] dataBytes = ProtectedData.Unprotect(protectedBytes, GetSalt(), DataProtectionScope.LocalMachine);
return Encoding.Unicode.GetString(dataBytes);
}
/// <summary>
/// Encrypt a given string using the given key. The cipherText is Base64
/// encoded and returned. The algorithjm currently used is "Rijndael"
/// </summary>
/// <param name="clearString">The string to encrypt.</param>
/// <param name="keyBytes">The key for the encryption algorithm</param>
/// <returns>The Base64 encoded cipher text</returns>
public static String EncryptString(String clearString, byte[] keyBytes)
{
MemoryStream ms = new MemoryStream();
//DES alg = DES.Create();
//RC2 alg = RC2.Create();
Rijndael alg = Rijndael.Create();
alg.Key = keyBytes;
alg.IV = GetSalt();
byte[] clearBytes = Encoding.Unicode.GetBytes(clearString);
CryptoStream cs = new CryptoStream(ms, alg.CreateEncryptor(), CryptoStreamMode.Write);
cs.Write(clearBytes, 0, clearBytes.Length);
cs.Close();
byte[] cipherText = ms.ToArray();
return Convert.ToBase64String(cipherText);
}
/// <summary>
/// Decrypt some cipher text that was created by the encryptString method.
/// </summary>
/// <param name="cipherText64">The base64 encoded cipher text that was produced
/// by encryptString</param>
/// <param name="keyBytes">The key to use to decrypt</param>
/// <returns>The decrypted text.</returns>
public static String DecryptString(String cipherText64, byte[] keyBytes)
{
MemoryStream ms = new MemoryStream();
byte[] cipherBytes = Convert.FromBase64String(cipherText64);
Rijndael alg = Rijndael.Create();
alg.Key = keyBytes;
alg.IV = GetSalt();
CryptoStream cs = new CryptoStream(ms, alg.CreateDecryptor(), CryptoStreamMode.Write);
cs.Write(cipherBytes, 0, cipherBytes.Length);
cs.Close();
byte[] plainBytes = ms.ToArray();
return Encoding.Unicode.GetString(plainBytes);
}
private static byte[] GetSalt()
{
// NOTE: This is what we did in Geneva - may want
// to do something less lame in future...
if (salt == null)
{
UnicodeEncoding ue = new UnicodeEncoding();
salt = ue.GetBytes("XenRocks");
}
return salt;
}
}
}