Cleanup stale user sessions

This commit is contained in:
Jakob A. Dam 2015-04-16 14:27:30 +02:00
parent 59885e7c5a
commit 070abbc2ac
4 changed files with 78 additions and 72 deletions

View file

@ -49,20 +49,21 @@ Partial Class RDSFactor
' Do not modify it using the code editor. ' Do not modify it using the code editor.
<System.Diagnostics.DebuggerStepThrough()> _ <System.Diagnostics.DebuggerStepThrough()> _
Private Sub InitializeComponent() Private Sub InitializeComponent()
Me.TimerCleanUpHash = New System.Timers.Timer() Me.cleanupEvent = New System.Timers.Timer()
CType(Me.TimerCleanUpHash, System.ComponentModel.ISupportInitialize).BeginInit() CType(Me.cleanupEvent, System.ComponentModel.ISupportInitialize).BeginInit()
' '
'TimerCleanUpHash 'cleanupEvent
' '
Me.TimerCleanUpHash.Enabled = True Me.cleanupEvent.Enabled = True
Me.TimerCleanUpHash.Interval = 60000.0R Me.cleanupEvent.Interval = 60000.0R
' '
'CICRadarR 'RDSFactor
' '
Me.ServiceName = "Service1" Me.ServiceName = "Service1"
CType(Me.TimerCleanUpHash, System.ComponentModel.ISupportInitialize).EndInit() CType(Me.cleanupEvent, System.ComponentModel.ISupportInitialize).EndInit()
End Sub End Sub
Friend WithEvents TimerCleanUpHash As System.Timers.Timer
Public WithEvents cleanupEvent As System.Timers.Timer
End Class End Class

View file

@ -117,7 +117,7 @@
<resheader name="writer"> <resheader name="writer">
<value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value> <value>System.Resources.ResXResourceWriter, System.Windows.Forms, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089</value>
</resheader> </resheader>
<metadata name="TimerCleanUpHash.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a"> <metadata name="cleanupEvent.TrayLocation" type="System.Drawing.Point, System.Drawing, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a">
<value>17, 17</value> <value>17, 17</value>
</metadata> </metadata>
<metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089"> <metadata name="$this.TrayLargeIcon" type="System.Boolean, mscorlib, Version=4.0.0.0, Culture=neutral, PublicKeyToken=b77a5c561934e089">

View file

@ -44,11 +44,6 @@ Public Class RDSFactor
Private Shared SenderEmail As String = "" Private Shared SenderEmail As String = ""
Private TSGW As String = "" Private TSGW As String = ""
Private TSGWSessionIdHash As New Hashtable
Private TSGWSessionIdTimeStampHash As New Hashtable
Private TSGWLaunchIdTimeStampHash As New Hashtable
Private TSGWFirstLoginHash As New Hashtable ' Ensure that only one sms is send even if radius need to re-authenticate.
Private TSGWFirstLoginTimeStampHash As New Hashtable ' Ensure that only one sms is send even if radius need to re-authenticate.
Public Shared SessionTimeOut As Integer = 30 ' in minutes Public Shared SessionTimeOut As Integer = 30 ' in minutes
Public Shared LaunchTimeOut As Integer = 30 ' in seconds Public Shared LaunchTimeOut As Integer = 30 ' in seconds
@ -131,11 +126,12 @@ Public Class RDSFactor
Public Shared Sub AccessLog(packet As RADIUSPacket, message As String) Public Shared Sub AccessLog(packet As RADIUSPacket, message As String)
Dim from_address = packet.EndPoint.Address.ToString Dim from_address = packet.EndPoint.Address.ToString
Dim log_message = Now & ": DEBUG: [" & packet.UserName & " " & from_address & "] " & message message = "[" & packet.UserName & " " & from_address & "] " & message
AccessLog(log_message) AccessLog(message)
End Sub End Sub
Public Shared Sub AccessLog(message As String) Public Shared Sub AccessLog(message As String)
message = Now & ": DEBUG: " & message
If DEBUG = True Then If DEBUG = True Then
UserAccessLog.WriteLog(message) UserAccessLog.WriteLog(message)
@ -350,34 +346,10 @@ Public Class RDSFactor
End If End If
Return "FAILED" Return "FAILED"
End Try End Try
End Function End Function
Private Sub TimerCleanUpHash_Elapsed(sender As System.Object, e As System.Timers.ElapsedEventArgs) Handles TimerCleanUpHash.Elapsed Public Sub CleanupEventHandler(sender, e) Handles cleanupEvent.Elapsed
' Clean Session and Launch hash for TSGW RDSHandler.Cleanup()
Try
Dim Item As DictionaryEntry
For Each Item In TSGWSessionIdTimeStampHash
Dim hTime As DateTime = DirectCast(Item.Value, DateTime)
Dim tValid = DateDiff(DateInterval.Minute, hTime, Now)
If tValid >= SessionTimeOut Then
TSGWSessionIdTimeStampHash.Remove(Item.Key)
If TSGWSessionIdHash.Contains(Item.Key) Then
TSGWSessionIdHash.Remove(Item.Key)
End If
End If
Next
For Each Item In TSGWLaunchIdTimeStampHash
Dim hTime As DateTime = DirectCast(Item.Value, DateTime)
Dim tValid = DateDiff(DateInterval.Second, hTime, Now)
If tValid >= LaunchTimeOut Then
TSGWLaunchIdTimeStampHash.Remove(Item.Key)
End If
Next
Catch
End Try
End Sub End Sub
End Class End Class

View file

@ -5,10 +5,7 @@ Public Class RDSHandler
Private Shared userSessions As New Hashtable Private Shared userSessions As New Hashtable
Private Shared sessionTimestamps As New Hashtable Private Shared sessionTimestamps As New Hashtable
Private Shared userSidTokens As New Hashtable Private Shared userSidTokens As New Hashtable
Private Shared tokenTimestamps As New Hashtable
Private Shared userLaunchTimestamps As New Hashtable Private Shared userLaunchTimestamps As New Hashtable
Private mPacket As RADIUSPacket Private mPacket As RADIUSPacket
@ -80,36 +77,59 @@ Public Class RDSHandler
' When the packet is an AppLaunchRequest the password attribute contains the session id! ' When the packet is an AppLaunchRequest the password attribute contains the session id!
Dim packetSessionId = mPassword Dim packetSessionId = mPassword
Dim storedSessionId = userSessions(mUsername) Dim storedSessionId = userSessions(mUsername)
Dim sessionTimestamp = sessionTimestamps(mUsername)
If storedSessionId = Nothing Or sessionTimestamp = Nothing Then If storedSessionId = Nothing Then
RDSFactor.AccessLog(mPacket, "User has no session. MUST re-authenticate!") RDSFactor.AccessLog(mPacket, "User has no session. MUST re-authenticate!")
mPacket.RejectAccessRequest() mPacket.RejectAccessRequest()
Exit Sub Exit Sub
End If End If
If packetSessionId = storedSessionId Then If Not storedSessionId = packetSessionId Then
Dim minsSinceLastActivity = DateDiff(DateInterval.Minute, sessionTimestamp, Now)
If minsSinceLastActivity < RDSFactor.SessionTimeOut Then
RDSFactor.AccessLog(mPacket, "Opening window")
' Pro-long session
sessionTimestamps(storedSessionId) = Now
' Open launch window
userLaunchTimestamps(mUsername) = Now
mPacket.AcceptAccessRequest()
Exit Sub
Else
RDSFactor.AccessLog(mPacket, "Session timed out -- User MUST re-authenticate")
userSessions.Remove(mUsername)
sessionTimestamps.Remove(mUsername)
End If
Else
RDSFactor.AccessLog(mPacket, "Stored session id didn't match packet session id!") RDSFactor.AccessLog(mPacket, "Stored session id didn't match packet session id!")
mPacket.RejectAccessRequest()
Exit Sub
End If
If HasValidSession(mUsername) Then
RDSFactor.AccessLog(mPacket, "Opening window")
' Pro-long user session
sessionTimestamps(mUsername) = Now
' Open gateway connection window
userLaunchTimestamps(mUsername) = Now
mPacket.AcceptAccessRequest()
Exit Sub
Else
RDSFactor.AccessLog(mPacket, "Session timed out -- User MUST re-authenticate")
userSessions.Remove(mUsername)
sessionTimestamps.Remove(mUsername)
mPacket.RejectAccessRequest()
End If End If
mPacket.RejectAccessRequest()
End Sub End Sub
Public Shared Function HasValidLaunchWindow(username) As Boolean
Dim timestamp = userLaunchTimestamps(username)
Dim secondsSinceLaunch = DateDiff(DateInterval.Second, timestamp, Now)
If secondsSinceLaunch < RDSFactor.LaunchTimeOut Then
Return True
Else
Return False
End If
End Function
Public Shared Function HasValidSession(username) As Boolean
Dim id = userSessions(username)
Dim timestamp = sessionTimestamps(username)
Dim minsSinceLastActivity = DateDiff(DateInterval.Minute, timestamp, Now)
If minsSinceLastActivity < RDSFactor.SessionTimeOut Then
Return True
Else
Return False
End If
End Function
' Process the request from the Network Policy Server in the RDS Gateway. ' Process the request from the Network Policy Server in the RDS Gateway.
' These are sent when an RDP client tries to connect through the Gateway. ' These are sent when an RDP client tries to connect through the Gateway.
' '
@ -140,16 +160,15 @@ Public Class RDSHandler
attributes.Add(proxyState) attributes.Add(proxyState)
End If End If
Dim secondsSinceLaunch = DateDiff(DateInterval.Second, launchTimestamp, Now) If HasValidLaunchWindow(mUsername) Then
If secondsSinceLaunch < RDSFactor.LaunchTimeOut Then RDSFactor.AccessLog(mPacket, "Opening gateway launch window")
RDSFactor.AccessLog(mPacket, "Opening gateway connection window")
mPacket.AcceptAccessRequest(attributes) mPacket.AcceptAccessRequest(attributes)
Else Else
RDSFactor.AccessLog(mPacket, "Gateway connection window has timed out!") RDSFactor.AccessLog(mPacket, "Gateway launch window has timed out!")
mPacket.RejectAccessRequest()
End If End If
RDSFactor.AccessLog(mPacket, "Removing gateway connection window") RDSFactor.AccessLog(mPacket, "Removing gateway launch window")
' close window
userLaunchTimestamps.Remove(mUsername) userLaunchTimestamps.Remove(mUsername)
End Sub End Sub
@ -199,6 +218,7 @@ Public Class RDSHandler
Dim sid = EncDec.Encrypt(mUsername & "_" & challangeCode, RDSFactor.encCode) Dim sid = EncDec.Encrypt(mUsername & "_" & challangeCode, RDSFactor.encCode)
If sid = state.ToString Then If sid = state.ToString Then
userSidTokens.Remove(mUsername)
Accept() Accept()
Else Else
mPacket.RejectAccessRequest() mPacket.RejectAccessRequest()
@ -211,7 +231,6 @@ Public Class RDSHandler
RDSFactor.AccessLog(mPacket, "Access Challange Code: " & code) RDSFactor.AccessLog(mPacket, "Access Challange Code: " & code)
userSidTokens(mUsername) = sid userSidTokens(mUsername) = sid
tokenTimestamps(mUsername) = Now
If mUseSMSFactor Then If mUseSMSFactor Then
RDSFactor.AccessLog(mPacket, "TODO: Send SMS") RDSFactor.AccessLog(mPacket, "TODO: Send SMS")
@ -282,5 +301,19 @@ Public Class RDSHandler
Return email Return email
End Function End Function
Public Shared Sub Cleanup()
RDSFactor.AccessLog("TimerCleanUp")
Dim users = New ArrayList(userSessions.Keys)
For Each username In users
If Not HasValidSession(username) Then
userSessions.Remove(username)
sessionTimestamps.Remove(username)
userLaunchTimestamps.Remove(username)
userSidTokens.Remove(username)
End If
Next
End Sub
End Class End Class