/// <summary> /// Default constructor /// </summary> public TDSLogin7Token() { // Instantiate the first optional flags OptionalFlags1 = new TDSLogin7TokenOptionalFlags1(); // Instantiate the second optional flags OptionalFlags2 = new TDSLogin7TokenOptionalFlags2(); // Instantiate the third optional flags OptionalFlags3 = new TDSLogin7TokenOptionalFlags3(); // Instantiate type flags TypeFlags = new TDSLogin7TokenTypeFlags(); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read packet length uint length = TDSUtilities.ReadUInt(source); // Read TDS version string tdsVersion = string.Format("{0:X}", TDSUtilities.ReadUInt(source)); // Consturct TDS version TDSVersion = new Version(int.Parse(tdsVersion.Substring(0, 1)), int.Parse(tdsVersion.Substring(1, 1)), Convert.ToInt32(tdsVersion.Substring(2, 2), 16), Convert.ToInt32(tdsVersion.Substring(4, 4), 16)); // Read packet length PacketSize = TDSUtilities.ReadUInt(source); // Read client program version ClientProgramVersion = TDSUtilities.ReadUInt(source); // Read client program identifier ClientPID = TDSUtilities.ReadUInt(source); // Read connection identifier ConnectionID = TDSUtilities.ReadUInt(source); // Instantiate the first optional flags OptionalFlags1 = new TDSLogin7TokenOptionalFlags1((byte)source.ReadByte()); // Instantiate the second optional flags OptionalFlags2 = new TDSLogin7TokenOptionalFlags2((byte)source.ReadByte()); // Instantiate type flags TypeFlags = new TDSLogin7TokenTypeFlags((byte)source.ReadByte()); // Instantiate the third optional flags OptionalFlags3 = new TDSLogin7TokenOptionalFlags3((byte)source.ReadByte()); // Read client time zone ClientTimeZone = TDSUtilities.ReadInt(source); // Read client locale identifier ClientLCID = TDSUtilities.ReadUInt(source); // Prepare a collection of property values that will be set later IList <TDSLogin7TokenOffsetProperty> variableProperties = new List <TDSLogin7TokenOffsetProperty>(); // Read client host name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("HostName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read user name and password variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("UserID"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Password"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read application name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ApplicationName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read server name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ServerName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Check if extension is used if (OptionalFlags3.ExtensionFlag) { // Read Feature extension. Note that this is just an offset of the value, not the value itself variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("FeatureExt"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source), true)); } else { // Skip unused TDSUtilities.ReadUShort(source); TDSUtilities.ReadUShort(source); } // Read client library name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("LibraryName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read language variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Language"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Database"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); ClientID = new byte[6]; // Read unique client identifier source.Read(ClientID, 0, ClientID.Length); // Read SSPI blob variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("SSPI"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database file to be attached variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("AttachDatabaseFile"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read password change variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ChangePassword"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read long SSPI uint sspiLength = TDSUtilities.ReadUInt(source); // At this point we surpassed the fixed packet length long inflationOffset = FixedPacketLength; // Order strings in ascending order by offset // For the most cases this should not change the order of the options in the stream, but just in case variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // We can't use "foreach" because FeatureExt processing changes the collection hence we can only go index-based way int iCurrentProperty = 0; // Iterate over each property while (iCurrentProperty < variableProperties.Count) { // Get the property at the indexed position TDSLogin7TokenOffsetProperty property = variableProperties[iCurrentProperty]; // Check if length is positive if (property.Length == 0) { // Move to the next propety iCurrentProperty++; continue; } // Ensure that current offset points to the option while (inflationOffset < property.Position) { // Read the stream source.ReadByte(); // Advance position inflationOffset++; } // Check special properties if (property.Property.Name == "Password" || property.Property.Name == "ChangePassword") { // Read passwod string property.Property.SetValue(this, TDSUtilities.ReadPasswordString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } else if (property.Property.Name == "SSPI") { // If cbSSPI < USHRT_MAX, then this length MUST be used for SSPI and cbSSPILong MUST be ignored. // If cbSSPI == USHRT_MAX, then cbSSPILong MUST be checked. if (property.Length == ushort.MaxValue) { // If cbSSPILong > 0, then that value MUST be used. If cbSSPILong ==0, then cbSSPI (USHRT_MAX) MUST be used. if (sspiLength > 0) { // We don't know how to handle SSPI packets that exceed TDS packet size throw new NotSupportedException("Long SSPI blobs are not supported yet"); } } // Use short length instead sspiLength = property.Length; // Allocate buffer for SSPI data SSPI = new byte[sspiLength]; // Read SSPI blob source.Read(SSPI, 0, SSPI.Length); // Advance the position inflationOffset += sspiLength; } else if (property.Property.Name == "FeatureExt") { // Check if this is the property or a pointer to the property if (property.IsOffsetOffset) { // Read the actual offset of the feature extension property.Position = TDSUtilities.ReadUInt(source); // Mark that now we have actual value property.IsOffsetOffset = false; // Advance the position inflationOffset += sizeof(uint); // Re-order the collection variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // Subtract position to stay on the same spot for subsequent property iCurrentProperty--; } else { // Create a list of features. FeatureExt = new TDSLogin7FeatureOptionsToken(); // Inflate feature extension FeatureExt.Inflate(source); // Advance position by the size of the inflated token inflationOffset += FeatureExt.InflationSize; } } else { // Read the string and assign it to the property of this instance property.Property.SetValue(this, TDSUtilities.ReadString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } // Advance to the next property iCurrentProperty++; } return(true); }
/// <summary> /// Inflate the token /// NOTE: This operation is not continuable and assumes that the entire token is available in the stream /// </summary> /// <param name="source">Stream to inflate the token from</param> /// <returns>TRUE if inflation is complete</returns> public override bool Inflate(Stream source) { // Read packet length uint length = TDSUtilities.ReadUInt(source); // Read TDS version string tdsVersion = String.Format("{0:X}", TDSUtilities.ReadUInt(source)); // Consturct TDS version TDSVersion = new Version(int.Parse(tdsVersion.Substring(0, 1)), int.Parse(tdsVersion.Substring(1, 1)), Convert.ToInt32(tdsVersion.Substring(2, 2), 16), Convert.ToInt32(tdsVersion.Substring(4, 4), 16)); // Read packet length PacketSize = TDSUtilities.ReadUInt(source); // Read client program version ClientProgramVersion = TDSUtilities.ReadUInt(source); // Read client program identifier ClientPID = TDSUtilities.ReadUInt(source); // Read connection identifier ConnectionID = TDSUtilities.ReadUInt(source); // Instantiate the first optional flags OptionalFlags1 = new TDSLogin7TokenOptionalFlags1((byte)source.ReadByte()); // Instantiate the second optional flags OptionalFlags2 = new TDSLogin7TokenOptionalFlags2((byte)source.ReadByte()); // Instantiate type flags TypeFlags = new TDSLogin7TokenTypeFlags((byte)source.ReadByte()); // Instantiate the third optional flags OptionalFlags3 = new TDSLogin7TokenOptionalFlags3((byte)source.ReadByte()); // Read client time zone ClientTimeZone = TDSUtilities.ReadInt(source); // Read client locale identifier ClientLCID = TDSUtilities.ReadUInt(source); // Prepare a collection of property values that will be set later IList<TDSLogin7TokenOffsetProperty> variableProperties = new List<TDSLogin7TokenOffsetProperty>(); // Read client host name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("HostName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read user name and password variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("UserID"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Password"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read application name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ApplicationName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read server name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ServerName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Check if extension is used if (OptionalFlags3.ExtensionFlag) { // Read Feature extension. Note that this is just an offset of the value, not the value itself variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("FeatureExt"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source), true)); } else { // Skip unused TDSUtilities.ReadUShort(source); TDSUtilities.ReadUShort(source); } // Read client library name variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("LibraryName"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read language variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Language"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("Database"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); ClientID = new byte[6]; // Read unique client identifier source.Read(ClientID, 0, ClientID.Length); // Read SSPI blob variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("SSPI"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read database file to be attached variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("AttachDatabaseFile"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read password change variableProperties.Add(new TDSLogin7TokenOffsetProperty(GetType().GetProperty("ChangePassword"), TDSUtilities.ReadUShort(source), TDSUtilities.ReadUShort(source))); // Read long SSPI uint sspiLength = TDSUtilities.ReadUInt(source); // At this point we surpassed the fixed packet length long inflationOffset = FixedPacketLength; // Order strings in ascending order by offset // For the most cases this should not change the order of the options in the stream, but just in case variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // We can't use "foreach" because FeatureExt processing changes the collection hence we can only go index-based way int iCurrentProperty = 0; // Iterate over each property while (iCurrentProperty < variableProperties.Count) { // Get the property at the indexed position TDSLogin7TokenOffsetProperty property = variableProperties[iCurrentProperty]; // Check if length is positive if (property.Length == 0) { // Move to the next propety iCurrentProperty++; continue; } // Ensure that current offset points to the option while (inflationOffset < property.Position) { // Read the stream source.ReadByte(); // Advance position inflationOffset++; } // Check special properties if (property.Property.Name == "Password" || property.Property.Name == "ChangePassword") { // Read passwod string property.Property.SetValue(this, TDSUtilities.ReadPasswordString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } else if (property.Property.Name == "SSPI") { // If cbSSPI < USHRT_MAX, then this length MUST be used for SSPI and cbSSPILong MUST be ignored. // If cbSSPI == USHRT_MAX, then cbSSPILong MUST be checked. if (property.Length == ushort.MaxValue) { // If cbSSPILong > 0, then that value MUST be used. If cbSSPILong ==0, then cbSSPI (USHRT_MAX) MUST be used. if (sspiLength > 0) { // We don't know how to handle SSPI packets that exceed TDS packet size throw new NotSupportedException("Long SSPI blobs are not supported yet"); } } // Use short length instead sspiLength = property.Length; // Allocate buffer for SSPI data SSPI = new byte[sspiLength]; // Read SSPI blob source.Read(SSPI, 0, SSPI.Length); // Advance the position inflationOffset += sspiLength; } else if (property.Property.Name == "FeatureExt") { // Check if this is the property or a pointer to the property if (property.IsOffsetOffset) { // Read the actual offset of the feature extension property.Position = TDSUtilities.ReadUInt(source); // Mark that now we have actual value property.IsOffsetOffset = false; // Advance the position inflationOffset += sizeof(uint); // Re-order the collection variableProperties = variableProperties.OrderBy(p => p.Position).ToList(); // Subtract position to stay on the same spot for subsequent property iCurrentProperty--; } else { // Create a list of features. FeatureExt = new TDSLogin7FeatureOptionsToken(); // Inflate feature extension FeatureExt.Inflate(source); // Advance position by the size of the inflated token inflationOffset += FeatureExt.InflationSize; } } else { // Read the string and assign it to the property of this instance property.Property.SetValue(this, TDSUtilities.ReadString(source, (ushort)(property.Length * 2)), null); // Advance the position inflationOffset += (property.Length * 2); } // Advance to the next property iCurrentProperty++; } return true; }