Skip to content

Commit 41bf034

Browse files
Merge branch 'release/v7.4' into backport/release/v7.4/26145-6887f3b57
2 parents 6887f3b + 3b631f3 commit 41bf034

2 files changed

Lines changed: 198 additions & 47 deletions

File tree

src/System.Management.Automation/engine/remoting/common/RemoteSessionHyperVSocket.cs

Lines changed: 31 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -258,30 +258,7 @@ public RemoteSessionHyperVSocketServer(bool LoopbackMode, string token, DateTime
258258
listenSocket.Listen(1);
259259
HyperVSocket = listenSocket.Accept();
260260

261-
TimeSpan timeout = TimeSpan.FromMinutes(MAX_TOKEN_LIFE_MINUTES);
262-
DateTimeOffset timeoutExpiry = tokenCreationTime.Add(timeout);
263-
DateTimeOffset now = DateTimeOffset.UtcNow;
264-
265-
// Calculate remaining time and create cancellation token
266-
TimeSpan remainingTime = timeoutExpiry - now;
267-
268-
// Check if the token has already expired
269-
if (remainingTime <= TimeSpan.Zero)
270-
{
271-
throw new PSDirectException(
272-
PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential, "Token has expired"));
273-
}
274-
275-
// Set socket timeout for receive operations to prevent indefinite blocking
276-
int timeoutMs = (int)remainingTime.TotalMilliseconds;
277-
HyperVSocket.ReceiveTimeout = timeoutMs;
278-
HyperVSocket.SendTimeout = timeoutMs;
279-
280-
// Create a cancellation token that will be cancelled when the timeout expires
281-
using var cancellationTokenSource = new CancellationTokenSource(remainingTime);
282-
CancellationToken cancellationToken = cancellationTokenSource.Token;
283-
284-
ValidateToken(HyperVSocket, token, cancellationToken);
261+
ValidateToken(HyperVSocket, token, tokenCreationTime, MAX_TOKEN_LIFE_MINUTES * 60);
285262

286263
Stream = new NetworkStream(HyperVSocket, true);
287264

@@ -389,9 +366,33 @@ public void Dispose()
389366
/// </summary>
390367
/// <param name="socket">The connected HyperVSocket.</param>
391368
/// <param name="token">The expected token string.</param>
392-
/// <param name="cancellationToken">Cancellation token for timeout handling.</param>
393-
internal static void ValidateToken(Socket socket, string token, CancellationToken cancellationToken = default)
369+
/// <param name="tokenCreationTime">The creation time of the token.</param>
370+
/// <param name="maxTokenLifeSeconds">The maximum lifetime of the token in seconds.</param>
371+
internal static void ValidateToken(Socket socket, string token, DateTimeOffset tokenCreationTime, int maxTokenLifeSeconds)
394372
{
373+
TimeSpan timeout = TimeSpan.FromSeconds(maxTokenLifeSeconds);
374+
DateTimeOffset timeoutExpiry = tokenCreationTime.Add(timeout);
375+
DateTimeOffset now = DateTimeOffset.UtcNow;
376+
377+
// Calculate remaining time and create cancellation token
378+
TimeSpan remainingTime = timeoutExpiry - now;
379+
380+
// Check if the token has already expired
381+
if (remainingTime <= TimeSpan.Zero)
382+
{
383+
throw new PSDirectException(
384+
PSRemotingErrorInvariants.FormatResourceString(RemotingErrorIdStrings.InvalidCredential, "Token has expired"));
385+
}
386+
387+
// Create a cancellation token that will be cancelled when the timeout expires
388+
using var cancellationTokenSource = new CancellationTokenSource(remainingTime);
389+
CancellationToken cancellationToken = cancellationTokenSource.Token;
390+
391+
// Set socket timeout for receive operations to prevent indefinite blocking
392+
int timeoutMs = (int)remainingTime.TotalMilliseconds;
393+
socket.ReceiveTimeout = timeoutMs;
394+
socket.SendTimeout = timeoutMs;
395+
395396
// Check for cancellation before starting validation
396397
cancellationToken.ThrowIfCancellationRequested();
397398

@@ -430,6 +431,7 @@ internal static void ValidateToken(Socket socket, string token, CancellationToke
430431
// So we expect a response of length 6 + 100 = 106 characters.
431432
responseString = RemoteSessionHyperVSocketClient.ReceiveResponse(socket, 110);
432433

434+
// Final check if we got the token before the timeout
433435
cancellationToken.ThrowIfCancellationRequested();
434436

435437
if (string.IsNullOrEmpty(responseString) || !responseString.StartsWith("TOKEN ", StringComparison.Ordinal))
@@ -454,6 +456,9 @@ internal static void ValidateToken(Socket socket, string token, CancellationToke
454456

455457
// Acknowledge the token is valid with "PASS".
456458
socket.Send("PASS"u8);
459+
460+
socket.ReceiveTimeout = 0; // Disable the timeout after successful validation
461+
socket.SendTimeout = 0;
457462
}
458463
}
459464

0 commit comments

Comments
 (0)