📄 context.cxx
字号:
This routine copies the InString into the MessageBuffer at Where.
It then updates OutString to be a descriptor for the copied string. The
descriptor 'address' is an offset from the MessageBuffer.
Where is updated to point to the next available space in the MessageBuffer.
The caller is responsible for any alignment requirements and for ensuring
there is room in the buffer for the string.
Arguments:
MessageBuffer - Specifies the base address of the buffer being copied into.
OutString - Returns a descriptor for the copied string. The descriptor
is relative to the begining of the buffer.
InString - Specifies the string to copy.
Where - On input, points to where the string is to be copied.
On output, points to the first byte after the string.
Return Value:
None.
--*/
{
//
// Copy the data to the Buffer.
//
if ( InString->Buffer != NULL ) {
RtlCopyMemory( *Where, InString->Buffer, InString->Length );
}
//
// Build a descriptor to the newly copied data.
//
OutString->Length = OutString->MaximumLength = InString->Length;
OutString->Buffer = (ULONG)(*Where - ((PCHAR)MessageBuffer));
//
// Update Where to point past the copied data.
//
*Where += InString->Length;
}
VOID
SspContextCopyStringAbsolute(
IN PVOID MessageBuffer,
OUT PSTRING OutString,
IN PSTRING InString,
IN OUT PCHAR *Where
)
/*++
Routine Description:
This routine copies the InString into the MessageBuffer at Where.
It then updates OutString to be a descriptor for the copied string.
Where is updated to point to the next available space in the MessageBuffer.
The caller is responsible for any alignment requirements and for ensuring
there is room in the buffer for the string.
Arguments:
MessageBuffer - Specifies the base address of the buffer being copied into.
OutString - Returns a descriptor for the copied string. The descriptor
is relative to the begining of the buffer.
InString - Specifies the string to copy.
Where - On input, points to where the string is to be copied.
On output, points to the first byte after the string.
Return Value:
None.
--*/
{
//
// Copy the data to the Buffer.
//
if ( InString->Buffer != NULL ) {
RtlCopyMemory( *Where, InString->Buffer, InString->Length );
}
//
// Build a descriptor to the newly copied data.
//
OutString->Length = OutString->MaximumLength = InString->Length;
OutString->Buffer = *Where;
//
// Update Where to point past the copied data.
//
*Where += InString->Length;
}
BOOLEAN
SspConvertRelativeToAbsolute (
IN PVOID MessageBase,
IN ULONG MessageSize,
IN PSTRING32 StringToRelocate,
IN PSTRING OutputString,
IN BOOLEAN AlignToWchar,
IN BOOLEAN AllowNullString
)
/*++
Routine Description:
Convert a Relative string desriptor to be absolute.
Perform all boudary condition testing.
Arguments:
MessageBase - a pointer to the base of the buffer that the string
is relative to. The MaximumLength field of the descriptor is
forced to be the same as the Length field.
MessageSize - Size of the message buffer (in bytes).
StringToRelocate - A pointer to the string descriptor to make absolute.
AlignToWchar - If TRUE the passed in StringToRelocate must describe
a buffer that is WCHAR aligned. If not, an error is returned.
AllowNullString - If TRUE, the passed in StringToRelocate may be
a zero length string.
Return Value:
TRUE - The string descriptor is valid and was properly relocated.
--*/
{
ULONG_PTR Offset;
//
// If the buffer is allowed to be null,
// check that special case.
//
if ( AllowNullString ) {
if ( StringToRelocate->Length == 0 ) {
OutputString->MaximumLength = OutputString->Length = StringToRelocate->Length;
OutputString->Buffer = NULL;
return TRUE;
}
}
//
// Ensure the string in entirely within the message.
//
Offset = (ULONG_PTR) StringToRelocate->Buffer;
if ( Offset >= MessageSize ||
Offset + StringToRelocate->Length > MessageSize ) {
return FALSE;
}
//
// Ensure the buffer is properly aligned.
//
if ( AlignToWchar ) {
if ( !COUNT_IS_ALIGNED( Offset, ALIGN_WCHAR) ||
!COUNT_IS_ALIGNED( StringToRelocate->Length, ALIGN_WCHAR) ) {
return FALSE;
}
}
//
// Finally make the pointer absolute.
//
OutputString->Buffer = (((PCHAR)MessageBase) + Offset);
OutputString->MaximumLength = OutputString->Length = StringToRelocate->Length ;
return TRUE;
}
TimeStamp
SspContextGetTimeStamp(
IN PSSP_CONTEXT Context,
IN BOOLEAN GetExpirationTime
)
/*++
Routine Description:
Get the Start time or Expiration time for the specified context.
Arguments:
Context - Pointer to the context to query
GetExpirationTime - If TRUE return the expiration time.
Otherwise, return the start time for the context.
Return Value:
Returns the requested time as a local time.
--*/
{
NTSTATUS Status;
LARGE_INTEGER SystemTime;
LARGE_INTEGER LocalTime;
TimeStamp LocalTimeStamp;
//
// Get the requested time in NT system time format.
//
SystemTime = Context->StartTime;
if ( GetExpirationTime ) {
LARGE_INTEGER Interval;
//
// If the time is infinite, return that
//
if ( Context->Interval == INFINITE ) {
return NtLmGlobalForever;
}
//
// Compute the ending time in NT System Time.
//
Interval.QuadPart = Int32x32To64( (LONG) Context->Interval, 10000 );
SystemTime.QuadPart = Interval.QuadPart + SystemTime.QuadPart;
}
//
// Convert the time to local time
//
Status = RtlSystemTimeToLocalTime( &SystemTime, &LocalTime );
if ( !NT_SUCCESS(Status) ) {
return NtLmGlobalForever;
}
LocalTimeStamp.HighPart = LocalTime.HighPart;
LocalTimeStamp.LowPart = LocalTime.LowPart;
return LocalTimeStamp;
}
VOID
SspContextSetTimeStamp(
IN PSSP_CONTEXT Context,
IN LARGE_INTEGER ExpirationTime
)
/*++
Routine Description:
Set the Expiration time for the specified context.
Arguments:
Context - Pointer to the context to change
ExpirationTime - Expiration time to set
Return Value:
NONE.
--*/
{
LARGE_INTEGER BaseGetTickMagicDivisor = { 0xe219652c, 0xd1b71758 };
CCHAR BaseGetTickMagicShiftCount = 13;
LARGE_INTEGER TimeRemaining;
LARGE_INTEGER MillisecondsRemaining;
//
// If the expiration time is infinite,
// so is the interval
//
if ( ExpirationTime.HighPart == 0x7FFFFFFF &&
ExpirationTime.LowPart == 0xFFFFFFFF ) {
Context->Interval = INFINITE;
//
// Handle non-infinite expiration times
//
} else {
//
// Compute the time remaining before the expiration time
//
TimeRemaining.QuadPart = ExpirationTime.QuadPart -
Context->StartTime.QuadPart;
//
// If the time has already expired,
// indicate so.
//
if ( TimeRemaining.QuadPart < 0 ) {
Context->Interval = 0;
//
// If the time hasn't expired, compute the number of milliseconds
// remaining.
//
} else {
MillisecondsRemaining = RtlExtendedMagicDivide(
TimeRemaining,
BaseGetTickMagicDivisor,
BaseGetTickMagicShiftCount );
if ( MillisecondsRemaining.HighPart == 0 &&
MillisecondsRemaining.LowPart < 0x7fffffff ) {
Context->Interval = MillisecondsRemaining.LowPart;
} else {
Context->Interval = INFINITE;
}
}
}
}
BOOL
SsprCheckMinimumSecurity(
IN ULONG NegotiateFlags,
IN ULONG MinimumSecurityFlags
)
/*++
Routine Description:
Check that minimum security requirements have been met.
Arguments:
NegotiateFlags: requested security features
MinimumSecurityFlags: minimum required features
Return Value:
TRUE if minimum requirements met
FALSE otherwise
Notes:
The MinimumSecurityFlags can contain features that only apply if
a key is needed when doing signing or sealing. These have to be removed
if SIGN or SEAL is not in the NegotiateFlags.
--*/
{
ULONG EffFlags; // flags in effect
EffFlags = MinimumSecurityFlags;
if( (NegotiateFlags & NTLMSSP_NEGOTIATE_SIGN) == 0 )
EffFlags &= ~(NTLMSSP_NEGOTIATE_SIGN);
if( (NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) == 0 )
EffFlags &= ~(NTLMSSP_NEGOTIATE_SEAL);
//
// if SIGN or SEAL is not negotiated, then remove all key related
// requirements, since they're not relevant when a key isn't needed
//
if ((NegotiateFlags & (NTLMSSP_NEGOTIATE_SIGN | NTLMSSP_NEGOTIATE_SEAL)) == 0)
{
EffFlags &= ~(
NTLMSSP_NEGOTIATE_128 |
NTLMSSP_NEGOTIATE_56 |
NTLMSSP_NEGOTIATE_KEY_EXCH
);
} else if ((NegotiateFlags & NTLMSSP_NEGOTIATE_SEAL) == 0) {
//
// If SIGN is negotiated, but SEAL isn't, then remove flags
// that aren't relevant to encryption
//
EffFlags &= ~( NTLMSSP_NEGOTIATE_KEY_EXCH );
}
//
// FYI: flags that can be usefully spec'd even without SIGN or SEAL:
// NTLM2 -- forces stronger authentication
// All other flags should never be set.... and are nuked in initcomn
//
return ((NegotiateFlags & EffFlags) == EffFlags);
}
SECURITY_STATUS
SsprMakeSessionKey(
IN PSSP_CONTEXT Context,
IN PSTRING LmChallengeResponse,
IN UCHAR NtUserSessionKey[MSV1_0_USER_SESSION_KEY_LENGTH], // from the DC or GetChalResp
IN UCHAR LanmanSessionKey[MSV1_0_LANMAN_SESSION_KEY_LENGTH], // from the DC of GetChalResp
IN PSTRING DatagramSessionKey
)
/*++
// SsprMakeSessionKey
// on entry:
// if KEY_EXCH has been negotiated, then
// either Context->SessionKey has a random number to be encrypted
// to be sent to the server, or it has the encrypted session key
// received from the client
// if client, DatagramSessionKey must point to STRING set up to hold 16 byte key,
// but with 0 length.
// else Context->SessionKey and DatagramSessionKey are irrelevant on entry
// on exit:
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -