using System; using System.Collections.Generic; using System.Collections.Specialized; using System.Diagnostics.CodeAnalysis; namespace ScreenConnect; public static class ClientLaunchParametersExtensions { public static ClientLaunchParameters AssertValid([System.Diagnostics.CodeAnalysis.NotNull] this ClientLaunchParameters? @this) { try { if (@this == null) { throw new ArgumentException("Not specified"); } if (string.IsNullOrEmpty(@this.Host)) { throw new ArgumentException("Must specify relay host"); } if (@this.Port == 0) { throw new ArgumentException("Must specify relay port"); } if (@this.EncryptionKey.IsNullOrEmpty()) { throw new ArgumentException("Must specify encryption key"); } return @this; } catch (Exception ex) { throw new InvalidOperationException("Invalid client launch parameters (" + @this.ToQueryString() + "): " + ex.Message, ex); } } public static void CopyToParameters(this ClientLaunchParameters clp, NameValueCollection parameters) { clp.AssertArgumentNonNull("clp"); parameters.AssertArgumentNonNull("parameters"); if (clp.SessionType != SessionType.Unknown) { parameters.Add("e", clp.SessionType.ToString()); } if (clp.ProcessType != ProcessType.Unknown) { parameters.Add("y", clp.ProcessType.ToString()); } if (clp.Host != null) { parameters.Add("h", clp.Host); } if (clp.Port != 0) { parameters.Add("p", clp.Port.ToString()); } if (clp.SessionID != default(Guid)) { parameters.Add("s", clp.SessionID.ToString()); } if (clp.EncryptionKey != null) { parameters.Add("k", Convert.ToBase64String(clp.EncryptionKey)); } if (clp.AccessToken != null) { parameters.Add("n", Convert.ToBase64String(clp.AccessToken)); } if (clp.EncryptedGuestClientValidationKey != null) { parameters.Add("v", Convert.ToBase64String(clp.EncryptedGuestClientValidationKey)); } if (clp.ParticipantName != null) { parameters.Add("r", clp.ParticipantName); } if (clp.LogonSessionID != null) { parameters.Add("l", clp.LogonSessionID); } if (clp.SessionTitle != null) { parameters.Add("i", clp.SessionTitle); } if (clp.NameCallbackFormat != null) { parameters.Add("t", clp.NameCallbackFormat); } if (clp.Attributes != ClientLaunchAttributes.None) { parameters.Add("a", clp.Attributes.ToString()); } if (clp.CustomPropertyValueCallbackFormats != null) { string[] customPropertyValueCallbackFormats = clp.CustomPropertyValueCallbackFormats; foreach (string text in customPropertyValueCallbackFormats) { parameters.Add("c", text ?? string.Empty); } } } public static string ToQueryString(this ClientLaunchParameters? clp) { return ToQueryString(clp, delegate(ClientLaunchParameters it, NameValueCollection parameters) { it.CopyToParameters(parameters); }); } private static string ToQueryString(T? @this, Proc copyToParametersProc) { if (@this == null) { return string.Empty; } NameValueCollection nameValueCollection = new NameValueCollection(); copyToParametersProc(@this, nameValueCollection); if (nameValueCollection.Count == 0) { return string.Empty; } return "?" + nameValueCollection.EncodeQueryString(); } public static void CopyFromParameters(this ClientLaunchParameters clp, NameValueCollection parameters) { clp.AssertArgumentNonNull("clp"); parameters.AssertArgumentNonNull("parameters"); parameters["e"]?.Pass(delegate(string it) { clp.SessionType = Extensions.TryParseEnum(it) ?? SessionType.Unknown; }); parameters["y"]?.Pass(delegate(string it) { clp.ProcessType = Extensions.TryParseEnum(it).GetValueOrDefault(); }); parameters["h"]?.Pass(delegate(string it) { clp.Host = it; }); parameters["p"]?.Pass(delegate(string it) { clp.Port = it.TryParseInt32Nullable().GetValueOrDefault(); }); parameters["r"]?.Pass(delegate(string it) { clp.ParticipantName = it; }); parameters["i"]?.Pass(delegate(string it) { clp.SessionTitle = it; }); parameters["t"]?.Pass(delegate(string it) { clp.NameCallbackFormat = it; }); parameters["s"]?.Pass(delegate(string it) { clp.SessionID = new Guid(it); }); parameters["k"]?.Pass(delegate(string it) { clp.EncryptionKey = Extensions.ConvertFromBase64StringFlexible(it); }); parameters["n"]?.Pass(delegate(string it) { clp.AccessToken = Extensions.ConvertFromBase64StringFlexible(it); }); parameters["v"]?.Pass(delegate(string it) { clp.EncryptedGuestClientValidationKey = Extensions.ConvertFromBase64StringFlexible(it); }); parameters.GetValues("c")?.Pass(delegate(string[] it) { clp.CustomPropertyValueCallbackFormats = it; }); parameters["a"]?.Pass(delegate(string it) { clp.Attributes = Extensions.TryParseEnum(it).GetValueOrDefault(); }); if (Constants.ProtocolVersion >= 17) { parameters["l"]?.Pass(delegate(string it) { clp.LogonSessionID = it; }); } } public static void CopyTo(this ClientLaunchParameters source, ClientLaunchParameters destination) { destination.AssertArgumentNonNull("destination"); source.AssertArgumentNonNull("source"); NameValueCollection parameters = new NameValueCollection(); source.CopyToParameters(parameters); destination.CopyFromParameters(parameters); } public static ClientLaunchParametersConstraint ToConstraint(this ClientLaunchParameters source) { source.AssertArgumentNonNull("source"); NameValueCollection parameters = new NameValueCollection(); source.CopyToParameters(parameters); ClientLaunchParametersConstraint clientLaunchParametersConstraint = new ClientLaunchParametersConstraint(); clientLaunchParametersConstraint.CopyFromParameters(parameters); return clientLaunchParametersConstraint; } public static void CopyToParameters(this ClientLaunchParametersConstraint constraint, NameValueCollection parameters) { constraint.To().CopyToParameters(parameters); if (constraint.SessionTypeConstraint.HasValue) { parameters.Add("e", constraint.SessionTypeConstraint.Value.ToString()); } if (constraint.AttributesConstraint.HasValue) { parameters.Add("a", constraint.AttributesConstraint.Value.ToString()); } } public static string ToQueryString(this ClientLaunchParametersConstraint? constraint) { return ToQueryString(constraint, delegate(ClientLaunchParametersConstraint it, NameValueCollection parameters) { it.CopyToParameters(parameters); }); } public static void CopyFromParameters(this ClientLaunchParametersConstraint constraint, NameValueCollection parameters) { ((ClientLaunchParameters)constraint).CopyFromParameters(parameters); parameters["e"]?.Pass(delegate(string it) { constraint.SessionTypeConstraint = (Extensions.TryParseEnum(it, out var value) ? new SessionType?(value) : ((SessionType?)null)); }); parameters["a"]?.Pass(delegate(string it) { constraint.AttributesConstraint = (Extensions.TryParseEnum(it, out var value) ? new ClientLaunchAttributes?(value) : ((ClientLaunchAttributes?)null)); }); } public static void EnforceConstraint(this ClientLaunchParametersConstraint @this, ClientLaunchParameters testClientLaunchParameters) { EnforceParameterConstraint("SessionType", testClientLaunchParameters.SessionType, @this.SessionTypeConstraint); EnforceParameterConstraint("Attributes", testClientLaunchParameters.Attributes, @this.AttributesConstraint); EnforceParameterConstraint("ProcessType", testClientLaunchParameters.ProcessType, @this.ProcessType); EnforceParameterConstraint("Host", testClientLaunchParameters.Host, @this.Host); EnforceParameterConstraint("Port", testClientLaunchParameters.Port, @this.Port); EnforceParameterConstraint("SessionID", testClientLaunchParameters.SessionID, @this.SessionID); EnforceParameterConstraint("ParticipantName", testClientLaunchParameters.ParticipantName, @this.ParticipantName); EnforceParameterConstraint("LogonSessionID", testClientLaunchParameters.LogonSessionID, @this.LogonSessionID); EnforceParameterConstraint("SessionTitle", testClientLaunchParameters.SessionTitle, @this.SessionTitle); EnforceParameterConstraint("NameCallbackFormat", testClientLaunchParameters.NameCallbackFormat, @this.NameCallbackFormat); EnforceBytesParameterConstraint("EncryptionKey", testClientLaunchParameters.EncryptionKey, @this.EncryptionKey); EnforceBytesParameterConstraint("AccessToken", testClientLaunchParameters.AccessToken, @this.AccessToken); EnforceBytesParameterConstraint("EncryptedGuestClientValidationKey", testClientLaunchParameters.EncryptedGuestClientValidationKey, @this.EncryptedGuestClientValidationKey); static void EnforceBytesParameterConstraint(string name, byte[]? testBytes, byte[]? expectedBytes) { if (expectedBytes != null && !expectedBytes.EqualsConstantTime(testBytes)) { throw new ArgumentException($"Client launch parameters failed constraint: expected '{Convert.ToBase64String(expectedBytes)}', but found '{testBytes?.Pipe(Convert.ToBase64String)}'", name); } } static void EnforceParameterConstraint(string name, T testValue, T expectedValue) { if (!expectedValue.EqualsDefault() && !EqualityComparer.Default.Equals(expectedValue, testValue)) { throw new ArgumentException($"Client launch parameters failed constraint: expected '{expectedValue}', but found '{testValue}'", name); } } } }