Challange-Response: Follow the RFC spec

On Challange-Responses the result is sent back encrypted to the server.
The shared RADIUS key is used for encryption. The State attribute
necessary in challange request/responses is assigned a guid.
This commit is contained in:
Jakob Aarøe Dam 2015-04-21 12:52:04 +02:00
parent 6ecba61ffd
commit 3d8463d7d8
10 changed files with 115 additions and 304 deletions

View file

@ -13,15 +13,15 @@ Option Explicit On
Namespace My
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
<Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute(), _
Global.System.CodeDom.Compiler.GeneratedCodeAttribute("Microsoft.VisualStudio.Editors.SettingsDesigner.SettingsSingleFileGenerator", "12.0.0.0"), _
Global.System.ComponentModel.EditorBrowsableAttribute(Global.System.ComponentModel.EditorBrowsableState.Advanced)> _
Partial Friend NotInheritable Class MySettings
Inherits Global.System.Configuration.ApplicationSettingsBase
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()), MySettings)
Private Shared defaultInstance As MySettings = CType(Global.System.Configuration.ApplicationSettingsBase.Synchronized(New MySettings()),MySettings)
#Region "My.Settings Auto-Save Functionality"
#If _MyType = "WindowsForms" Then
Private Shared addedHandler As Boolean
@ -36,10 +36,10 @@ Namespace My
End Sub
#End If
#End Region
Public Shared ReadOnly Property [Default]() As MySettings
Get
#If _MyType = "WindowsForms" Then
If Not addedHandler Then
SyncLock addedHandlerLockObject
@ -57,13 +57,13 @@ Namespace My
End Namespace
Namespace My
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
<Global.Microsoft.VisualBasic.HideModuleNameAttribute(), _
Global.System.Diagnostics.DebuggerNonUserCodeAttribute(), _
Global.System.Runtime.CompilerServices.CompilerGeneratedAttribute()> _
Friend Module MySettingsProperty
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
<Global.System.ComponentModel.Design.HelpKeywordAttribute("My.Settings")> _
Friend ReadOnly Property Settings() As Global.RDSFactor.My.MySettings
Get
Return Global.RDSFactor.My.MySettings.Default

View file

@ -15,17 +15,14 @@ Public Class RDSFactor
Public Shared ADField As String = ""
Public Shared ADMailField As String = ""
Public Shared EnableOTP As Boolean
' Shared key: used for challange encryption
' TODO: Fix
Public Shared encCode As String = "gewsyy#sjs2!"
Public Shared secrets As NASAuthList
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
@ -160,7 +157,7 @@ Public Class RDSFactor
If TSGW = "1" Then
handler = New RDSHandler(packet)
Else
handler = New CitrixHandler(packet)
'handler = New CitrixHandler(packet)
End If
handler.ProcessRequest()
@ -254,7 +251,7 @@ Public Class RDSFactor
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))
clientHash.Add(ClientArray(i), EncDec.Decrypt(RConfig.GetKeyValue("Clients", ClientArray(i)), "gewsyy#sjs2!"))
Next
If ConfOk = True Then

View file

@ -15,7 +15,8 @@
<FileAlignment>512</FileAlignment>
<MyType>Console</MyType>
<TargetFrameworkVersion>v4.0</TargetFrameworkVersion>
<TargetFrameworkProfile>Client</TargetFrameworkProfile>
<TargetFrameworkProfile>
</TargetFrameworkProfile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
<PlatformTarget>x86</PlatformTarget>
@ -60,6 +61,7 @@
<Reference Include="System.DirectoryServices" />
<Reference Include="System.Drawing" />
<Reference Include="System.ServiceProcess" />
<Reference Include="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL" />
<Reference Include="System.Windows.Forms" />
<Reference Include="System.Xml" />
<Reference Include="System.Core" />
@ -80,7 +82,6 @@
<Compile Include="Crypto.vb" />
<Compile Include="exceptions\MissingRadiusSecret.vb" />
<Compile Include="exceptions\MissingUser.vb" />
<Compile Include="handlers\CitrixHandler.vb" />
<Compile Include="handlers\RDSHandler.vb" />
<Compile Include="IniFileVb.vb" />
<Compile Include="Log.vb" />
@ -137,6 +138,7 @@
</EmbeddedResource>
</ItemGroup>
<ItemGroup>
<None Include="app.config" />
<None Include="My Project\app.manifest" />
<None Include="My Project\Application.myapp">
<Generator>MyApplicationCodeGenerator</Generator>

23
RDSFactor/app.config Normal file
View file

@ -0,0 +1,23 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<system.diagnostics>
<sources>
<!-- This section defines the logging configuration for My.Application.Log -->
<source name="DefaultSource" switchName="DefaultSwitch">
<listeners>
<add name="FileLog"/>
<!-- Uncomment the below section to write to the Application Event Log -->
<!--<add name="EventLog"/>-->
</listeners>
</source>
</sources>
<switches>
<add name="DefaultSwitch" value="Information"/>
</switches>
<sharedListeners>
<add name="FileLog" type="Microsoft.VisualBasic.Logging.FileLogTraceListener, Microsoft.VisualBasic, Version=8.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL" initializeData="FileLogWriter"/>
<!-- Uncomment the below section and replace APPLICATION_NAME with the name of your application to write to the Application Event Log -->
<!--<add name="EventLog" type="System.Diagnostics.EventLogTraceListener" initializeData="APPLICATION_NAME"/> -->
</sharedListeners>
</system.diagnostics>
<startup><supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.0"/></startup></configuration>

View file

@ -1,254 +0,0 @@
Imports System.DirectoryServices
Imports RADAR
' TODO: I don't use this! It's a leftover, moved out of the way
' from the CICRadarR.vb
'
' Look in RDSHandler how this should be refactored.
Public Class CitrixHandler
Private mPacket As RADIUSPacket
Public Sub New(packet As RADIUSPacket)
End Sub
Private Sub ProcessPacketCSG(ByVal server As RADIUSServer, ByVal packet As RADIUSPacket)
' Let's take a look at just authentication requests,
' and drop other requests silently ...
If packet.Code <> RadiusPacketCode.AccessRequest Then
RDSFactor.AccessLog(mPacket, "Not a valid radius packet.. Drop!")
Exit Sub
End If
' Let's see if we have a username present ...
Dim username As RADIUSAttribute = packet.Attributes.GetFirstAttribute(RadiusAttributeType.UserName)
Dim pass As RADIUSAttribute = packet.Attributes.GetFirstAttribute(RadiusAttributeType.UserPassword)
Dim sid As String = ""
Dim mobile As String = ""
Dim smsCode As String = ""
Dim UserEmail As String = ""
' If an attribute of a particular type is not found, the function
' will return Nothing.
If username Is Nothing Then
' Technically, this case is against RFC, so ... drop.
RDSFactor.AccessLog(mPacket, "Not a valid radius packet.. No username pressent.. Drop!")
Exit Sub
End If
RDSFactor.AccessLog(mPacket, "Processing packet for user: " & username.ToString)
'If packetHash.ContainsKey(username.GetString & "_" & pass.GetString) Then
' Exit Sub
'End If
Dim existState As Boolean = packet.Attributes.AttributeExists(RadiusAttributeType.State)
RDSFactor.AccessLog(mPacket, "Packet contains a state attribute? State=" & existState.ToString)
If existState = True Then ' Ok we have at packet with the State attribute set. Check if we can identify the authtentication packet.
Dim state As String = packet.Attributes.GetFirstAttribute(RadiusAttributeType.State).ToString
RDSFactor.AccessLog(mPacket, "Packet contains a state attribute State=" & state)
Dim UserDomain As String = ""
'lets see if user login using upd or UPN name
Dim sUserName As String = username.ToString
Dim sPassword As String = packet.UserPassword
RDSFactor.AccessLog(mPacket, "SMSToken supplied by user: " & sUserName)
sid = ""
If InStr(sUserName, "@") > 0 Then 'UPN
UserDomain = sUserName
Else 'UPD
'read domain from Hashtable
UserDomain = RDSFactor.NetBiosDomain & "\" & sUserName
End If
sid = EncDec.Encrypt(UserDomain & "_" & packet.UserPassword, RDSFactor.encCode)
RDSFactor.AccessLog(mPacket, "Checking for userHash " & sid)
If sid = state Then
packet.AcceptAccessRequest()
Else
packet.RejectAccessRequest()
End If
Else ' process the first login
' packetHash.Add(username.GetString & "_" & pass.GetString, 0)
' Console.WriteLine(username.GetString & " is trying to log in ... ")
' Note that an attribute can represent a string, number, IP, etc.
' RADAR will not guess that automatically, so use the appropriate
' function according to the attribute you're trying to read. Otherwise,
' the Value property is just a bunch of bytes as received in the
' RADIUS packet.
'Now lets get some information from ad if password is valid
Dim success As Boolean = False
Dim UserDomain As String = ""
'lets see if user login using upd or UPN name
Dim sUserName As String = username.ToString
Dim sPassword As String = packet.UserPassword
If InStr(sUserName, "@") > 0 Then 'UPN
UserDomain = sUserName
Else 'UPD
'read domain from Hashtable
UserDomain = RDSFactor.NetBiosDomain & "\" & sUserName
End If
RDSFactor.AccessLog(mPacket, "User " & UserDomain & " is trying to log in ...")
Try
Dim dirEntry As New DirectoryEntry("LDAP://" & RDSFactor.LDAPDomain, UserDomain, sPassword)
Dim obj As Object = dirEntry.NativeObject
Dim search As New DirectorySearcher(dirEntry)
If InStr(sUserName, "@") > 0 Then
search.Filter = "(userPrincipalName=" + sUserName + ")"
Else
search.Filter = "(SAMAccountName=" + sUserName + ")"
End If
'Load the Properties we need from AD
search.PropertiesToLoad.Add("distinguishedName")
'search.PropertiesToLoad.Add("primaryTelexNumber")
If RDSFactor.EnableOTP = True Then
If RDSFactor.EnableEmail = True Then
search.PropertiesToLoad.Add(RDSFactor.ADMailField)
End If
If RDSFactor.EnableSMS = True Then
search.PropertiesToLoad.Add(RDSFactor.ADField)
End If
End If
' Time to find out if user entered the correct username and pasword
RDSFactor.AccessLog(mPacket, "Trying to authenticate user agains Active Directory using te following parameters: " & "LDAPPAth: " & "LDAP://" & RDSFactor.LDAPDomain & ", Username: " & UserDomain & ", Password: " & sPassword)
Dim result As SearchResult = search.FindOne()
'Get the setting form AD. Yes we uses the field primaryTelexNumber, for who the f... still users telex. (I bet half the people reading this code don't even know what a telex is!)
'Dim code As String = DirectCast(result.Properties("primaryTelexNumber")(0), String)
'Dim aCode As String() = code.Split("/")
'Dim userLdap As String = "LDAP://" & LDAPPath & "/" & result.Properties("distinguishedName")(0)
'Dim userEntry As New DirectoryEntry(userLdap, UserDomain, sPassword)
If RDSFactor.EnableOTP = True Then
smsCode = RDSFactor.GenerateCode()
' REMEMBER to put at check for empty phone string
If RDSFactor.EnableEmail = True Then
Try
UserEmail = DirectCast(result.Properties(RDSFactor.ADMailField)(0), String)
If UserEmail.Trim.Length = 0 Or InStr(UserEmail, "@") = 0 Then
success = False
RDSFactor.AccessLog(mPacket, "Unable to find correct email for user " & UserDomain)
Else
success = True
End If
Catch
RDSFactor.AccessLog(mPacket, "Unable to find correct email for user " & UserDomain)
success = False
End Try
End If
If RDSFactor.EnableSMS = True Then
Try
mobile = DirectCast(result.Properties(RDSFactor.ADField)(0), String)
mobile = Replace(mobile, "+", "")
If mobile.Trim.Length = 0 Then
success = False
RDSFactor.AccessLog(mPacket, "Unable to find correct phone number for user " & UserDomain)
Else
success = True
End If
Catch
RDSFactor.AccessLog(mPacket, "Unable to find correct phone number for user " & UserDomain)
success = False
End Try
End If
sid = EncDec.Encrypt(UserDomain & "_" & smsCode, RDSFactor.encCode) 'generate unique code
End If
' sid = UserDomain & "_" & smsCode
'userEntry.Properties("primaryTelexNumber").Value = aCode(0) & "/" & smsCode & "/" & aCode(2) & "/" & aCode(3)
'userEntry.CommitChanges()
'userEntry.Dispose()
If 1 = 1 Then ' check if smscode is disabled for the user (Need to write this code)
'If userHash.ContainsKey(sid) Then
' userHash(sid) = sPassword
' If DEBUG = True Then
' CICRadarR.AccessLog(mPacket, "Updating userHash " & sid)
' End If
'Else
' userHash.Add(sid, sPassword)
' If DEBUG = True Then
' CICRadarR.AccessLog(mPacket, "Adding userHash " & sid)
' End If
'End If
' new code stored in AD now send it to the users phone
' Console.WriteLine(smsCode)
success = True
Else
success = False
End If
Catch
RDSFactor.AccessLog(mPacket, "Failed to authenticate user agains Active Directory using the following parameters: " & "LDAPPAth: " & "LDAP://" & RDSFactor.LDAPDomain & ", Username: " & UserDomain & ", Password: " & sPassword)
success = False
End Try
Dim attributes As New RADIUSAttributes
If success Then ' Yay! Someone guess the password ...
RDSFactor.AccessLog(mPacket, "User " & UserDomain & " authenticated agains Active Directory")
If RDSFactor.EnableOTP = True Then
Dim attr As New RADIUSAttribute(RadiusAttributeType.ReplyMessage, "SMS Token")
attributes.Add(attr)
Dim state As New RADIUSAttribute(RadiusAttributeType.State, sid)
attributes.Add(state)
' Console.WriteLine("len " & packet.Authenticator.Length.ToString)
server.SendAsResponse( _
New RADIUSPacket(RadiusPacketCode.AccessChallenge, _
packet.Identifier, attributes, _
packet.EndPoint), _
packet.Authenticator)
If RDSFactor.EnableSMS = True Then
RDSFactor.AccessLog(mPacket, "Sending access token: " & smsCode & " to phonenumber " & mobile)
Call RDSFactor.SendSMS(mobile, smsCode)
End If
If RDSFactor.EnableEmail = True Then
RDSFactor.AccessLog(mPacket, "Sending access token: " & smsCode & " to email " & UserEmail)
Call RDSFactor.SendEmail(UserEmail, smsCode)
End If
Else
RDSFactor.AccessLog(mPacket, "One time Password not enabled, so we let the user in")
packet.AcceptAccessRequest()
End If
' packetHash.Remove(username.GetString & "_" & pass.GetString)
Else ' Wrong username / password ...
RDSFactor.AccessLog(mPacket, "User " & UserDomain & " failed to authenticate against Active Directory")
Dim pk As New RADIUSPacket(RadiusPacketCode.AccessReject, packet.Identifier, Nothing, packet.EndPoint)
server.SendAsResponse(pk, packet.Authenticator)
' FYI ... if no additional attributes need to be added
' to the response, you can sepcify Nothing instead of
' creating an empty RADIUSAttributes object.
' packetHash.Remove(username.GetString & "_" & pass.GetString)
End If
End If
End Sub
End Class

View file

@ -1,13 +1,20 @@
Imports System.DirectoryServices
Imports System.Web.Helpers
Imports RADAR
Public Class RDSHandler
' User -> Token that proves user has authenticated, but not yet proved
' herself with the 2. factor
Private Shared authTokens As New Hashtable
Private Shared userSessions As New Hashtable
Private Shared sessionTimestamps As New Hashtable
Private Shared userSidTokens As New Hashtable
Private Shared encryptedChallangeResults As New Hashtable
Private Shared userLaunchTimestamps As New Hashtable
Private mPacket As RADIUSPacket
Private mUsername As String
Private mPassword As String
@ -210,27 +217,41 @@ Public Class RDSHandler
End Sub
Private Sub ProcessChallengeResponse()
RDSFactor.AccessLog(mPacket, "ChallengeResponse")
Dim authToken = mPacket.Attributes.GetFirstAttribute(RadiusAttributeType.State).ToString
If Not authToken = authTokens(mUsername) Then
Throw New Exception("User is trying to respond to challange without valid auth token")
End If
' When the packet is an Challange-Response the password attr. contains the token
Dim challangeCode = mPassword
Dim state = mPacket.Attributes.GetFirstAttribute(RadiusAttributeType.State)
' When the packet is an Challange-Response the password attr. contains the encrypted result
Dim userEncryptedResult = mPassword
Dim localEncryptedResult = encryptedChallangeResults(mUsername)
Dim sid = EncDec.Encrypt(mUsername & "_" & challangeCode, RDSFactor.encCode)
If sid = state.ToString Then
userSidTokens.Remove(mUsername)
If localEncryptedResult = userEncryptedResult Then
RDSFactor.AccessLog(mPacket, "ChallengeResponse Success")
encryptedChallangeResults.Remove(mUsername)
authTokens.Remove(mUsername)
Accept()
Else
RDSFactor.AccessLog(mPacket, "Wrong challange code!")
mPacket.RejectAccessRequest()
End If
End Sub
Private Sub TwoFactorChallenge()
Dim code = RDSFactor.GenerateCode
Dim sid = EncDec.Encrypt(mUsername & "_" & code, RDSFactor.encCode) 'generate unique code
RDSFactor.AccessLog(mPacket, "Access Challange Code: " & code)
Dim challangeCode = RDSFactor.GenerateCode
Dim authToken = System.Guid.NewGuid.ToString
Dim clientIP = mPacket.EndPoint.Address.ToString
Dim sharedSecret = RDSFactor.secrets(clientIP)
userSidTokens(mUsername) = sid
RDSFactor.AccessLog(mPacket, "Access Challange Code: " & challangeCode)
If sharedSecret = Nothing Then
Throw New Exception("No shared secret for client:" & clientIP)
End If
authTokens(mUsername) = authToken
Dim encryptedChallangeResult = Crypto.SHA256(mUsername & challangeCode & sharedSecret)
encryptedChallangeResults(mUsername) = encryptedChallangeResult
If mUseSMSFactor Then
RDSFactor.AccessLog(mPacket, "TODO: Send SMS")
@ -242,11 +263,11 @@ Public Class RDSHandler
Dim attributes As New RADIUSAttributes
Dim attr As New RADIUSAttribute(RadiusAttributeType.ReplyMessage, "SMS Token")
Dim state As New RADIUSAttribute(RadiusAttributeType.State, sid)
Dim replyMessageAttr As New RADIUSAttribute(RadiusAttributeType.ReplyMessage, "SMS Token")
Dim stateAttr As New RADIUSAttribute(RadiusAttributeType.State, authToken)
attributes.Add(attr)
attributes.Add(state)
attributes.Add(replyMessageAttr)
attributes.Add(stateAttr)
mPacket.SendAccessChallange(attributes)
End Sub
@ -310,7 +331,8 @@ Public Class RDSHandler
userSessions.Remove(username)
sessionTimestamps.Remove(username)
userLaunchTimestamps.Remove(username)
userSidTokens.Remove(username)
encryptedChallangeResults.Remove(username)
authTokens.Remove(username)
End If
Next
End Sub

View file

@ -38,9 +38,9 @@
<add key="ShowOptimizeExperience" value="true"/>
<add key="OptimizeExperienceState" value="false"/>
<add key="SmsToken" value="true"/>
<add key="RadiusServer" value="192.168.121.9"/>
<add key="RadiusServer" value="127.0.0.1"/>
<add key="RadiusSecret" value="helloworld"/>
<add key="OTP" value="true"/>
<add key="OTP" value="false"/>
<add key="EnableSMS" value="true"/>
<add key="EnableMail" value="false"/>
</appSettings>
@ -85,7 +85,11 @@
</authorization>
</personalization>
</webParts>
<compilation targetFramework="4.5"/>
<compilation targetFramework="4.5" debug="true">
<assemblies>
<add assembly="System.Web.Helpers, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31BF3856AD364E35"/>
</assemblies>
</compilation>
<pages controlRenderingCompatibilityVersion="3.5" clientIDMode="AutoID"/>
</system.web>
<system.webServer>
@ -94,12 +98,10 @@
<add name="RDWAFormsAuthenticationModule" type="Microsoft.TerminalServices.Publishing.Portal.FormAuthentication.TSFormsAuthentication"/>
</modules>
<security>
<authentication>
<windowsAuthentication enabled="false"/>
<anonymousAuthentication enabled="true"/>
</authentication>
</security>
<httpRedirect enabled="false"/>
</system.webServer>

View file

@ -2,7 +2,10 @@
<?xml-stylesheet type="text/xsl" href="../Site.xsl"?>
<?xml-stylesheet type="text/css" href="../RenderFail.css"?>
<% @Page Language="C#" Debug="false" ResponseEncoding="utf-8" ContentType="text/xml" %>
<% @Import Namespace="System" %>
<% @Import Namespace="System.IO" %>
<% @Import Namespace="System.Web.Helpers" %>
<% @Import Namespace="System.Threading" %>
<% @Import Namespace="System.Security" %>
<% @Import Namespace="Microsoft.TerminalServices.Publishing.Portal.FormAuthentication" %>
@ -71,7 +74,8 @@
void Page_Load(object sender, EventArgs e)
{
logit("pageload");
btnSignIn.Text = L_SubmitLabel_Text;
btnCancel.Text = L_CancelLabel_Text;
@ -87,18 +91,25 @@
RADIUSClient client = new RADIUSClient(RadiusServer, 1812, RadiusSecret);
RADIUSAttributes atts = new RADIUSAttributes();
client.Debug = Debug;
try {
VendorSpecificAttribute vsa = new VendorSpecificAttribute(VendorSpecificType.Generic,(string)Session["Delivery"]);
vsa.SetRADIUSAttribute(ref atts);
logit("AccessReqeust");
RADIUSPacket response = client.Authenticate(username, strPassword, atts);
if (response.Code == RadiusPacketCode.AccessChallenge) {
logit("Challange");
state = response.Attributes.GetFirstAttribute(RadiusAttributeType.State);
Session["State"] = state;
}
// Access-Accept
else if (response.Code == RadiusPacketCode.AccessAccept) {
logit("Accept");
string sessionGuid = response.Attributes.GetFirstAttribute(RadiusAttributeType.ReplyMessage).GetString();
Session["SESSIONGUID"] = sessionGuid;
HttpCookie myCookie = new HttpCookie("RadiusSessionId");
@ -172,18 +183,26 @@
Response.Redirect(strRedirectSafeUrl,false);
}
public void logit(String message) {
String path = "C:\\RDSFactor\\RDSFactorWeb\\RDWeb\\Pages\\log\\web.log";
message = DateTime.Now + ": " + message;
using (StreamWriter log = File.AppendText(path)) {
log.WriteLine(message);
}
}
protected void btnSignIn_Click(object sender, EventArgs e)
{
username = (string)Session["DomainUserName"];
state = (RADIUSAttribute)Session["state"];
RADIUSClient myRadius = new RADIUSClient(RadiusServer, 1812, RadiusSecret);
RADIUSClient client = new RADIUSClient(RadiusServer, 1812, RadiusSecret);
RADIUSAttributes atts = new RADIUSAttributes();
atts.Add(state);
RADIUSPacket response = myRadius.Authenticate(username, SmsToken.Text, atts);
String encryptedChallangeResult = Crypto.SHA256(username + SmsToken.Text + RadiusSecret);
RADIUSPacket response = client.Authenticate(username, encryptedChallangeResult, atts);
if (response.Code == RadiusPacketCode.AccessAccept)
{