DSInternals/Src/DSInternals.Common/Data/Principals/ManagedPassword.cs
2015-12-26 23:44:43 +01:00

112 lines
4.5 KiB
C#

using System;
using System.IO;
using System.Text;
namespace DSInternals.Common.Data
{
/// <summary>
/// Represents a group-managed service account's password information.
/// </summary>
/// <see>https://msdn.microsoft.com/en-us/library/hh881234.aspx</see>
public class ManagedPassword
{
private const int MinimumBlobLength = 6 * sizeof(short) + sizeof(int);
/// <summary>
/// Gets the version of the msDS-ManagedPassword binary large object (BLOB).
/// </summary>
public short Version
{
get;
private set;
}
/// <summary>
/// Gets the current password.
/// </summary>
public string CurrentPassword
{
get;
private set;
}
/// <summary>
/// Gets the previous password.
/// </summary>
public string PreviousPassword
{
get;
private set;
}
/// <summary>
/// Gets the length of time after which the receiver should requery the password.
/// </summary>
public TimeSpan QueryPasswordInterval
{
get;
private set;
}
/// <summary>
/// Gets the length of time before which password queries will always return this password value.
/// </summary>
public TimeSpan UnchangedPasswordInterval
{
get;
private set;
}
/// <summary>
/// Initializes a new instance of the <see cref="ManagedPassword"/> class.
/// </summary>
/// <param name="blob">
/// The MSDS-MANAGEDPASSWORD_BLOB, which is a representation
/// of a group-managed service account's password information.
/// This structure is returned as the msDS-ManagedPassword constructed attribute.
/// </param>
public ManagedPassword(byte[] blob)
{
Validator.AssertMinLength(blob, MinimumBlobLength, "blob");
using (Stream stream = new MemoryStream(blob))
{
using (BinaryReader reader = new BinaryReader(stream))
{
// A 16-bit unsigned integer that defines the version of the msDS-ManagedPassword binary large object (BLOB). The Version field MUST be set to 0x0001.
this.Version = reader.ReadInt16();
// TODO: Test that version == 1
// A 16-bit unsigned integer that MUST be set to 0x0000.
short reserved = reader.ReadInt16();
// TODO: Test that reserved == 0
// A 32-bit unsigned integer that specifies the length, in bytes, of the msDS-ManagedPassword BLOB.
int length = reader.ReadInt32();
Validator.AssertLength(blob, length, "blob");
// A 16-bit offset, in bytes, from the beginning of this structure to the CurrentPassword field. The CurrentPasswordOffset field MUST NOT be set to 0x0000.
short currentPasswordOffset = reader.ReadInt16();
this.CurrentPassword = blob.ReadWString(currentPasswordOffset);
// A 16-bit offset, in bytes, from the beginning of this structure to the PreviousPassword field. If this field is set to 0x0000, then the account has no previous password.
short previousPasswordOffset = reader.ReadInt16();
if(previousPasswordOffset > 0)
{
this.PreviousPassword = blob.ReadWString(previousPasswordOffset);
}
// A 16-bit offset, in bytes, from the beginning of this structure to the QueryPasswordInterval field.
short queryPasswordIntervalOffset = reader.ReadInt16();
long queryPasswordIntervalBinary = BitConverter.ToInt64(blob, queryPasswordIntervalOffset);
this.QueryPasswordInterval = TimeSpan.FromTicks(queryPasswordIntervalBinary);
// A 16-bit offset, in bytes, from the beginning of this structure to the UnchangedPasswordInterval field.
short unchangedPasswordIntervalOffset = reader.ReadInt16();
long unchangedPasswordIntervalBinary = BitConverter.ToInt64(blob, unchangedPasswordIntervalOffset);
this.UnchangedPasswordInterval = TimeSpan.FromTicks(unchangedPasswordIntervalBinary);
}
}
}
}
}