mirror of
https://github.com/jakobadam/RDSFactor.git
synced 2025-07-22 17:45:54 +02:00
368 lines
14 KiB
VB.net
368 lines
14 KiB
VB.net
Imports System.DirectoryServices
|
|
Imports System.IO
|
|
Imports System.Reflection
|
|
Imports CICRadarR.SMS
|
|
Imports CICRadarR.LogFile
|
|
Imports System.Security.Cryptography
|
|
Imports System.Text
|
|
Imports System
|
|
Imports System.Net.Mail
|
|
|
|
|
|
Public Class CICRadarR
|
|
|
|
Public Shared LDAPDomain As String = ""
|
|
Public Shared ADField As String = ""
|
|
Public Shared ADMailField As String = ""
|
|
Public Shared EnableOTP As Boolean
|
|
' TODO: What this?
|
|
Public Shared encCode As String = "gewsyy#sjs2!"
|
|
|
|
Private Shared DEBUG As Boolean
|
|
|
|
Private Shared UserAccessLog As New LogWriter
|
|
Private Shared Log As New LogWriter
|
|
|
|
Private secrets As NASAuthList
|
|
Private radius1812 As RADIUSServer
|
|
Private radius1645 As RADIUSServer
|
|
Private userHash As New Hashtable
|
|
Private packetHash As New Hashtable
|
|
Private clientHash As New Hashtable
|
|
|
|
Public Shared NetBiosDomain As String = ""
|
|
|
|
Private Shared Provider As String = ""
|
|
|
|
|
|
Private Shared ModemType As String = ""
|
|
Private Shared ComPort As String = ""
|
|
Private Shared SmsC As String = ""
|
|
Private Shared MailServer As String = ""
|
|
Private Shared SenderEmail 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 LaunchTimeOut As Integer = 30 ' in seconds
|
|
Public Shared EnableSMS As Boolean = False
|
|
Public Shared EnableEmail As Boolean = False
|
|
|
|
Protected Overrides Sub OnStart(ByVal args() As String)
|
|
|
|
Log.filePath = ApplicationPath() & "\log.txt"
|
|
UserAccessLog.filePath = ApplicationPath() & "\UserAccessLog.txt"
|
|
|
|
Log.WriteLog("---------------------------------------------------------------------------------------------------")
|
|
ServerLog("Starting Service")
|
|
ServerLog("Loading Configuration...")
|
|
Call loadConfiguration()
|
|
ServerLog("Starting Radius listner ports...")
|
|
Call StartUpServer()
|
|
End Sub
|
|
|
|
Public Sub OnstartTest()
|
|
Log.filePath = ApplicationPath() & "\log.txt"
|
|
UserAccessLog.filePath = ApplicationPath() & "\UserAccessLog.txt"
|
|
|
|
ServerLog("---------------------------------------------------------------------------------------------------")
|
|
ServerLog("Starting Service")
|
|
ServerLog("Loading Configuration...")
|
|
Call loadConfiguration()
|
|
ServerLog("Starting Radius listner ports...")
|
|
Call StartUpServer()
|
|
End Sub
|
|
|
|
Protected Overrides Sub OnStop()
|
|
ServerLog("Stopping Radius listner ports...")
|
|
|
|
End Sub
|
|
|
|
Public Sub OnStopTest()
|
|
ServerLog("Stopping Radius listner ports...")
|
|
End Sub
|
|
|
|
Public Sub StartUpServer()
|
|
|
|
' First, let's load a list of RADIUS shared secrets
|
|
' in a NASAuthList object (a glorified Dictionary, basically)
|
|
secrets = New NASAuthList
|
|
' Populate from DB, I suppose ...
|
|
|
|
For Each cl As DictionaryEntry In clientHash
|
|
ServerLog("Adding Shared Secret to Radius Server")
|
|
secrets.AddSharedSecret(cl.Key, cl.Value)
|
|
Next
|
|
' Then, we just create a RADIUS server ...
|
|
Try
|
|
radius1812 = New RADIUSServer(1812, AddressOf ProcessPacket1812, secrets)
|
|
ServerLog("Starting Radius Server on Port 1812...OK")
|
|
Catch
|
|
ServerLog("Starting Radius Server on Port 1812...FAILED")
|
|
End Try
|
|
|
|
Try
|
|
radius1645 = New RADIUSServer(1645, AddressOf ProcessPacket1645, secrets)
|
|
ServerLog("Starting Radius Server on Port 1645...OK")
|
|
Catch
|
|
ServerLog("Starting Radius Server on Port 1645...FAILED")
|
|
End Try
|
|
|
|
End Sub
|
|
|
|
|
|
' Every valid RADIUS request generated by the server(s) we created earlier
|
|
' will fire up the callback procedure. Invalid requests are dropped, per RFC.
|
|
Private Sub ProcessPacket1812(ByVal packet As RADIUSPacket)
|
|
'Console.WriteLine("packet " & Now)
|
|
ProcessPacket(radius1812, packet)
|
|
End Sub
|
|
|
|
Private Sub ProcessPacket1645(ByVal packet As RADIUSPacket)
|
|
ProcessPacket(radius1645, packet)
|
|
End Sub
|
|
|
|
Public Shared Sub AccessLog(ByVal message)
|
|
If DEBUG = True Then
|
|
UserAccessLog.WriteLog(Now & ": DEBUG: " & message)
|
|
End If
|
|
End Sub
|
|
|
|
Public Shared Sub ServerLog(ByVal message)
|
|
Log.WriteLog(Now & ":" & message)
|
|
End Sub
|
|
|
|
Private Sub ProcessPacket(ByVal server As RADIUSServer, ByVal packet As RADIUSPacket)
|
|
If Not packet.IsValid Then
|
|
Console.WriteLine("Packet is not valid. Discarding.")
|
|
Exit Sub
|
|
End If
|
|
|
|
Dim handler
|
|
If TSGW = "1" Then
|
|
handler = New RDSHandler(packet)
|
|
Else
|
|
handler = New CitrixHandler(packet)
|
|
End If
|
|
|
|
handler.ProcessRequest()
|
|
End Sub
|
|
|
|
Public Shared Function GenerateCode() As String
|
|
|
|
|
|
Dim dummy As Integer = 0
|
|
|
|
Dim ordRand As New System.Random()
|
|
Dim temp As New System.Collections.ArrayList()
|
|
While temp.Count < 6
|
|
dummy = ordRand.[Next](1, 9)
|
|
If Not temp.Contains(dummy) Then
|
|
temp.Add(dummy)
|
|
End If
|
|
End While
|
|
Dim strVar As String = temp(0).ToString() + temp(1).ToString() + temp(2).ToString() + temp(3).ToString() + temp(4).ToString() + temp(5).ToString()
|
|
Return strVar
|
|
|
|
End Function
|
|
|
|
Public Sub loadConfiguration()
|
|
Dim ConfOk As Boolean = True
|
|
Dim RConfig As New IniFile
|
|
Try
|
|
RConfig.Load(ApplicationPath() & "\CICRadarR.ini")
|
|
DEBUG = RConfig.GetKeyValue("CICRadarR", "Debug")
|
|
NetBiosDomain = RConfig.GetKeyValue("CICRadarR", "NetBiosDomain")
|
|
If NetBiosDomain.Length = 0 Then
|
|
ServerLog("ERROR: NetBiosDomain can not be empty")
|
|
ConfOk = False
|
|
End If
|
|
LDAPDomain = RConfig.GetKeyValue("CICRadarR", "LDAPDomain")
|
|
If LDAPDomain.Length = 0 Then
|
|
ServerLog("ERROR: LDAPDomain can not be empty")
|
|
ConfOk = False
|
|
End If
|
|
|
|
TSGW = RConfig.GetKeyValue("CICRadarR", "TSGW")
|
|
|
|
EnableOTP = RConfig.GetKeyValue("CICRadarR", "EnableOTP")
|
|
|
|
If EnableOTP = True Then
|
|
If RConfig.GetKeyValue("CICRadarR", "EnableEmail") = "1" Then
|
|
EnableEmail = True
|
|
SenderEmail = RConfig.GetKeyValue("CICRadarR", "SenderEmail")
|
|
MailServer = RConfig.GetKeyValue("CICRadarR", "MailServer")
|
|
ADMailField = RConfig.GetKeyValue("CICRadarR", "ADMailField")
|
|
End If
|
|
|
|
ADField = RConfig.GetKeyValue("CICRadarR", "ADField")
|
|
If ADField.Length = 0 Then
|
|
ServerLog("ERROR: ADField can not be empty")
|
|
ConfOk = False
|
|
End If
|
|
|
|
If RConfig.GetKeyValue("CICRadarR", "EnableSMS") = "1" Then
|
|
EnableSMS = True
|
|
ModemType = RConfig.GetKeyValue("CICRadarR", "USELOCALMODEM")
|
|
Select Case ModemType
|
|
Case "0"
|
|
Provider = RConfig.GetKeyValue("CICRadarR", "Provider")
|
|
If Provider.Length = 0 Then
|
|
ServerLog("ERROR: Provider can not be empty")
|
|
ConfOk = False
|
|
End If
|
|
Case "1"
|
|
ComPort = RConfig.GetKeyValue("CICRadarR", "COMPORT")
|
|
If ComPort.Length = 0 Then
|
|
ServerLog("ERROR: ComPort can not be empty")
|
|
ConfOk = False
|
|
End If
|
|
SmsC = RConfig.GetKeyValue("CICRadarR", "SMSC")
|
|
If SmsC.Length = 0 Then
|
|
ServerLog("ERROR: SMSC can not be empty. See http://smsclist.com/downloads/default.txt for valid values")
|
|
ConfOk = False
|
|
End If
|
|
Case Else
|
|
ServerLog("ERROR: USELOCALMODEM contain invalid configuration. Correct value are 1 or 0")
|
|
ConfOk = False
|
|
End Select
|
|
End If
|
|
|
|
End If
|
|
|
|
Dim ClientList As String = ""
|
|
ClientList = RConfig.GetKeyValue("CICRadarR", "ClientList")
|
|
|
|
Dim ClientArray() As String
|
|
ClientArray = Split(ClientList, ",")
|
|
|
|
For i As Integer = 0 To ClientArray.Length - 1
|
|
ServerLog("Loading Shared Secret for Client: " & ClientArray(i))
|
|
clientHash.Add(ClientArray(i), EncDec.Decrypt(RConfig.GetKeyValue("Clients", ClientArray(i)), encCode))
|
|
Next
|
|
|
|
If ConfOk = True Then
|
|
ServerLog("Loading Configuration...OK")
|
|
Else
|
|
ServerLog("Loading Configuration...FAILED")
|
|
End If
|
|
Catch
|
|
ServerLog("ERROR: Missing CICRadarR.ini from startup path or CICRadarR.ini contains invalid configuration")
|
|
ServerLog("Loading Configuration...FAILED")
|
|
End
|
|
End Try
|
|
End Sub
|
|
|
|
Public Function ApplicationPath() As String
|
|
Return Path.GetDirectoryName([Assembly].GetExecutingAssembly().Location)
|
|
End Function
|
|
|
|
Public Shared Function SendSMS(ByVal number As String, ByVal passcode As String) As String
|
|
|
|
' test if using online sms provider or local modem
|
|
If ModemType = 1 Then ' local modem
|
|
Dim modem As New SmsClass(ComPort)
|
|
modem.Opens()
|
|
modem.sendSms(number, passcode, SmsC)
|
|
modem.Closes()
|
|
modem = Nothing
|
|
Return "Ok"
|
|
Else
|
|
|
|
|
|
Dim baseurl As String = Provider.Split("?")(0)
|
|
Dim client As New System.Net.WebClient()
|
|
' Add a user agent header in case the requested URI contains a query.
|
|
|
|
client.Headers.Add("user-agent", "Mozilla/4.0 (compatible; MSIE 6.0; Windows NT 5.2; .NET CLR1.0.3705;)")
|
|
|
|
Dim parameters As String = Provider.Split("?")(1)
|
|
Dim pary As String() = parameters.Split("&")
|
|
|
|
For i As Integer = 0 To pary.Length - 1
|
|
If pary(i).IndexOf("***TEXTMESSAGE***") > 0 Then
|
|
Dim qpar As String() = pary(i).Split("=")
|
|
client.QueryString.Add(qpar(0), passcode)
|
|
ElseIf pary(i).IndexOf("***NUMBER***") > 0 Then
|
|
Dim qpar As String() = pary(i).Split("=")
|
|
client.QueryString.Add(qpar(0), number)
|
|
Else
|
|
|
|
Dim qpar As String() = pary(i).Split("=")
|
|
client.QueryString.Add(qpar(0), qpar(1))
|
|
End If
|
|
Next
|
|
|
|
|
|
Dim data As Stream = client.OpenRead(baseurl)
|
|
Dim reader As New StreamReader(data)
|
|
Dim s As String = reader.ReadToEnd()
|
|
data.Close()
|
|
reader.Close()
|
|
Return (s)
|
|
End If
|
|
|
|
End Function
|
|
|
|
Public Shared Function SendEmail(email As String, passcode As String) As String
|
|
|
|
|
|
Dim mail As New MailMessage()
|
|
mail.To.Add(email)
|
|
mail.From = New MailAddress(SenderEmail)
|
|
mail.Subject = "Token: " & passcode
|
|
mail.Body = "Subject contains the token code to login to you site"
|
|
mail.IsBodyHtml = False
|
|
Dim smtp As New SmtpClient(MailServer)
|
|
|
|
|
|
Try
|
|
smtp.Send(mail)
|
|
If DEBUG = True Then
|
|
AccessLog(Now & ": Mail send to: " & email)
|
|
End If
|
|
Return "SEND"
|
|
Catch e As InvalidCastException
|
|
|
|
If DEBUG = True Then
|
|
AccessLog(Now & " : Debug: " & e.Message)
|
|
AccessLog(Now & " : Unable to send mail to: " & email & " ## Check that MAILSERVER and SENDEREMAIL are configured correctly in smscode.conf. Also check that your Webinterface server is allowed to relay through the mail server specified")
|
|
End If
|
|
Return "FAILED"
|
|
End Try
|
|
|
|
|
|
|
|
End Function
|
|
|
|
Private Sub TimerCleanUpHash_Elapsed(sender As System.Object, e As System.Timers.ElapsedEventArgs) Handles TimerCleanUpHash.Elapsed
|
|
' Clean Session and Launch hash for TSGW
|
|
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 Class
|