//****************************************************************************************************** // ClientInfo.cs - Gbtc // // Copyright © 2012, Grid Protection Alliance. All Rights Reserved. // // Licensed to the Grid Protection Alliance (GPA) under one or more contributor license agreements. See // the NOTICE file distributed with this work for additional information regarding copyright ownership. // The GPA licenses this file to you under the MIT License (MIT), the "License"; you may // not use this file except in compliance with the License. You may obtain a copy of the License at: // // http://www.opensource.org/licenses/MIT // // Unless agreed to in writing, the subject software distributed under the License is distributed on an // "AS-IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. Refer to the // License for the specific language governing permissions and limitations. // // Code Modification History: // ---------------------------------------------------------------------------------------------------- // 09/12/2006 - Pinal C. Patel // Generated original version of source code. // 09/30/2008 - James R. Carroll // Converted to C#. // 03/09/2009 - Pinal C. Patel // Edited code comments. // 07/10/2009 - Pinal C. Patel // Modified to transmit serialized identity token used for authentication by the ServiceHelper. // 07/21/2009 - Pinal C. Patel // Modified identity token generation to use the new ClientHelper.AuthenticationInput property. // 09/14/2009 - Stephen C. Wills // Added new header and license agreement. // 02/08/2010 - Pinal C. Patel // Corrected the assignment of ClientName property for web applications. // 06/16/2010 - Pinal C. Patel // Made changes necessary to implement role-based security. // 12/20/2012 - Starlynn Danyelle Gilliam // Modified Header. // //****************************************************************************************************** using System; using System.Runtime.Serialization; using System.Security; using System.Security.Principal; using System.Web.Hosting; using GSF.Identity; using GSF.Reflection; namespace GSF.ServiceProcess { /// /// Represents information about a client using for connecting to a Windows Service that uses . /// /// /// can be serialized and deserialized using only. /// /// /// [Serializable] public class ClientInfo : ISerializable { #region [ Members ] // Fields private Guid m_clientID; private readonly ApplicationType m_clientType; private readonly string m_clientName; private IPrincipal m_clientUser; private readonly string m_clientUsername; private readonly SecureString m_clientPassword; private readonly string m_machineName; private DateTime m_connectedAt; #endregion #region [ Constructors ] /// /// Initializes a new instance of the class. /// public ClientInfo() : this(null) { } /// /// Initializes a new instance of the class. /// /// An object. public ClientInfo(ClientHelper parent) { // Initialize member variables. m_clientType = Common.GetApplicationType(); m_machineName = Environment.MachineName; if ((object)parent != null) m_clientUsername = parent.Username; // Initialize user principal. if (m_clientType == ApplicationType.Web) m_clientUser = new GenericPrincipal(new GenericIdentity(m_clientUsername ?? UserInfo.RemoteUserID), new string[] { }); else m_clientUser = new GenericPrincipal(new GenericIdentity(m_clientUsername ?? UserInfo.CurrentUserID), new string[] { }); // Initialize user credentials. if ((object)parent != null && !string.IsNullOrEmpty(parent.Username) && parent.Password != null && parent.Password.Length > 0) m_clientPassword = parent.SecurePassword; // Initialize client application name. if (m_clientType == ApplicationType.Web) { if (HostingEnvironment.ApplicationVirtualPath == "/") m_clientName = HostingEnvironment.SiteName; else m_clientName = HostingEnvironment.ApplicationVirtualPath.ToNonNullString().Trim('/'); } else { m_clientName = AssemblyInfo.EntryAssembly.Name; } } /// /// Creates a new from serialization parameters. /// /// The with populated with data. /// The source for this deserialization. protected ClientInfo(SerializationInfo info, StreamingContext context) { // Deserialize client request fields m_clientID = info.GetOrDefault("clientID", Guid.Empty); m_clientType = info.GetOrDefault("clientType", ApplicationType.Unknown); m_clientName = info.GetOrDefault("clientName", "__undefined"); string clientUserCredentials = info.GetOrDefault("clientUserCredentials", ""); if (!string.IsNullOrEmpty(clientUserCredentials)) { string[] parts = clientUserCredentials.Split(':'); if (parts.Length == 2) { if (!string.IsNullOrEmpty(parts[0])) m_clientUsername = parts[0].Trim(); if (!string.IsNullOrEmpty(parts[1])) m_clientPassword = parts[1].ToSecureString(); } } // Initialize user principal. if (m_clientType == ApplicationType.Web) m_clientUser = new GenericPrincipal(new GenericIdentity(m_clientUsername ?? UserInfo.RemoteUserID), new string[] { }); else m_clientUser = new GenericPrincipal(new GenericIdentity(m_clientUsername ?? UserInfo.CurrentUserID), new string[] { }); m_machineName = info.GetOrDefault("machineName", "__unknown"); m_connectedAt = info.GetOrDefault("connectedAt", DateTime.UtcNow); } #endregion #region [ Properties ] /// /// Gets the identifier of the remote client application. /// public Guid ClientID { get { return m_clientID; } set { m_clientID = value; } } /// /// Gets the of the remote client application. /// public ApplicationType ClientType => m_clientType; /// /// Gets the friendly name of the remote client application. /// public string ClientName => m_clientName; /// /// Gets the of the remote client application's user. /// public IPrincipal ClientUser => m_clientUser; /// /// Gets the username portion of the credentials supplied by the client. /// public string ClientUsername => m_clientUsername; /// /// Gets the password portion of the credentials supplied by the client. /// public string ClientPassword => m_clientPassword.ToUnsecureString(); /// /// Gets the in a . /// public SecureString SecureClientPassword => m_clientPassword; /// /// Gets the credentials in 'username:password' format for authenticating the remote client application's user if a valid is not available. /// public string ClientUserCredentials => $"{m_clientUsername}:{m_clientPassword.ToUnsecureString()}"; /// /// Gets the name of the machine running the remote client application. /// public string MachineName => m_machineName; /// /// Gets or sets the when the remote client application connected to the . /// public DateTime ConnectedAt { get { return m_connectedAt; } set { m_connectedAt = value; } } #endregion #region [ Methods ] /// /// Updates the . /// /// New object to be assigned to . public void SetClientUser(IPrincipal user) { if ((object)user == null) throw new ArgumentNullException(nameof(user)); m_clientUser = user; } /// /// Populates a with the data needed to serialize the target object. /// /// The to populate with data. /// The destination (see ) for this serialization. /// The caller does not have the required permission. public virtual void GetObjectData(SerializationInfo info, StreamingContext context) { // Serialize client request fields info.AddValue("clientID", m_clientID); info.AddValue("clientType", m_clientType, typeof(ApplicationType)); info.AddValue("clientName", m_clientName); info.AddValue("clientUserCredentials", ClientUserCredentials); info.AddValue("machineName", m_machineName); info.AddValue("connectedAt", m_connectedAt); } #endregion } }