CA2000: Object is not disposed along all exception paths - asp.net

I am having trouble trying to figure out why I'm getting this warning in following code.
CA2000 : Microsoft.Reliability : In method 'Encryption64.Decrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.
CA2000 : Microsoft.Reliability : In method 'Encryption64.Encrypt(String, String)', object 'des' is not disposed along all exception paths. Call System.IDisposable.Dispose on object 'des' before all references to it are out of scope.
Public Class Encryption64
Private key() As Byte = {}
Private IV() As Byte = {&H12, &H34, &H56, &H78, &H90, &HAB, &HCD, &HEF}
Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Try
Dim inputByteArray(stringToDecrypt.Length) As Byte
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
ReturnValue = encoding.GetString(ms.ToArray())
Catch e As Exception
ReturnValue = e.Message
Finally
If des IsNot Nothing Then
des.Dispose()
End If
If ms IsNot Nothing Then
ms.Dispose()
End If
End Try
Return ReturnValue
End Function
Public Function Encrypt(ByVal stringToEncrypt As String, ByVal SEncryptionKey As String) As String
Dim des As New DESCryptoServiceProvider()
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Try
key = System.Text.Encoding.UTF8.GetBytes(Left(SEncryptionKey, 8))
Dim inputByteArray() As Byte = Encoding.UTF8.GetBytes(stringToEncrypt)
Dim cs As New CryptoStream(ms, des.CreateEncryptor(key, IV), CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
ReturnValue = Convert.ToBase64String(ms.ToArray())
Catch e As Exception
ReturnValue = e.Message
Finally
If des IsNot Nothing Then
des.Dispose()
End If
If ms IsNot Nothing Then
ms.Dispose()
End If
End Try
Return ReturnValue
End Function
End Class

Since you are declaring (and instantiating) your des objects outside of the Try ... Finally blocks, it is possible for your code to raise an exception in the line Dim ms As New MemoryStream() and your .Dispose() will not be called.
When you are working with objects that implement IDisposable, it is much preferable where possible to wrap them in a Using block instead of a Try...Finally block. For example:
Public Function Decrypt(ByVal stringToDecrypt As String, ByVal sEncryptionKey As String) As String
Dim ms As New MemoryStream()
Dim ReturnValue As String = String.Empty
Dim inputByteArray(stringToDecrypt.Length) As Byte
key = System.Text.Encoding.UTF8.GetBytes(Left(sEncryptionKey, 8))
inputByteArray = Convert.FromBase64String(stringToDecrypt)
Using ms as New MemoryStream
Using des As New DESCryptoServiceProvider
Dim cs As New CryptoStream(ms, des.CreateDecryptor(key, IV),CryptoStreamMode.Write)
cs.Write(inputByteArray, 0, inputByteArray.Length)
cs.FlushFinalBlock()
End Using ' des
Dim encoding As System.Text.Encoding = System.Text.Encoding.UTF8
ReturnValue = encoding.GetString(ms.ToArray())
End Using ' ms
Catch e As Exception
ReturnValue = e.Message
End Try
Return ReturnValue
End Function

Just a guess, but maybe it's not smart enough to realize that this code line will always be true:
If des IsNot Nothing Then
In other words, it might assume that because there is a conditional statement, the Dispose() call might not be executed.
To check, you can try commenting out the "if" and see if the warning goes away.

Related

QueryStringModule with FriendlyUrls does not working

Good morning, I need to encrypt my querystring and i found an interesting method in this link and I convert it in vb.net:
Imports System
Imports System.IO
Imports System.Web
Imports System.Text
Imports System.Security.Cryptography
Public Class QueryStringModule
Implements IHttpModule
Public Sub Dispose() Implements IHttpModule.Dispose
End Sub
Public Sub Init(ByVal context As HttpApplication) Implements IHttpModule.Init
AddHandler context.BeginRequest, New EventHandler(AddressOf context_BeginRequest)
End Sub
Private Const PARAMETER_NAME As String = "enc="
Private Const ENCRYPTION_KEY As String = "key"
Private Sub context_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = HttpContext.Current
If context.Request.Url.OriginalString.Contains("aspx") AndAlso context.Request.RawUrl.Contains("?") Then
Dim query As String = ExtractQuery(context.Request.RawUrl)
Dim path As String = GetVirtualPath()
If query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase) Then
Dim rawQuery As String = query.Replace(PARAMETER_NAME, String.Empty)
Dim decryptedQuery As String = Decrypt(rawQuery)
context.RewritePath(path, String.Empty, decryptedQuery)
ElseIf context.Request.HttpMethod = "GET" Then
Dim encryptedQuery As String = Encrypt(query)
context.Response.Redirect(path & encryptedQuery)
End If
End If
End Sub
Private Shared Function GetVirtualPath() As String
Dim path As String = HttpContext.Current.Request.RawUrl
path = path.Substring(0, path.IndexOf("?"))
path = path.Substring(path.LastIndexOf("/") + 1)
Return path
End Function
Private Shared Function ExtractQuery(ByVal url As String) As String
Dim index As Integer = url.IndexOf("?") + 1
Return url.Substring(index)
End Function
Private ReadOnly Shared SALT As Byte() = Encoding.ASCII.GetBytes(ENCRYPTION_KEY.Length.ToString())
Public Shared Function Encrypt(ByVal inputText As String) As String
Dim rijndaelCipher As RijndaelManaged = New RijndaelManaged()
Dim plainText As Byte() = Encoding.Unicode.GetBytes(inputText)
Dim SecretKey As PasswordDeriveBytes = New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using encryptor As ICryptoTransform = rijndaelCipher.CreateEncryptor(SecretKey.GetBytes(32), SecretKey.GetBytes(16))
Using memoryStream As MemoryStream = New MemoryStream()
Using cryptoStream As CryptoStream = New CryptoStream(memoryStream, encryptor, CryptoStreamMode.Write)
cryptoStream.Write(plainText, 0, plainText.Length)
cryptoStream.FlushFinalBlock()
Return "?" & PARAMETER_NAME & Convert.ToBase64String(memoryStream.ToArray())
End Using
End Using
End Using
End Function
Public Shared Function Decrypt(ByVal inputText As String) As String
Dim rijndaelCipher As RijndaelManaged = New RijndaelManaged()
Dim encryptedData As Byte() = Convert.FromBase64String(inputText)
Dim secretKey As PasswordDeriveBytes = New PasswordDeriveBytes(ENCRYPTION_KEY, SALT)
Using decryptor As ICryptoTransform = rijndaelCipher.CreateDecryptor(secretKey.GetBytes(32), secretKey.GetBytes(16))
Using memoryStream As MemoryStream = New MemoryStream(encryptedData)
Using cryptoStream As CryptoStream = New CryptoStream(memoryStream, decryptor, CryptoStreamMode.Read)
Dim plainText As Byte() = New Byte(encryptedData.Length - 1) {}
Dim decryptedCount As Integer = cryptoStream.Read(plainText, 0, plainText.Length)
Return Encoding.Unicode.GetString(plainText, 0, decryptedCount)
End Using
End Using
End Using
End Function
End Class
but also my project use FriendlyUrls and I figured out that with FriendlyUrls the things does not working and always return the url without the extension ".aspx" but with the querystring not encrypted
Imports System.Web.Routing
Imports Microsoft.AspNet.FriendlyUrls
Public Module RouteConfig
Sub RegisterRoutes(ByVal routes As RouteCollection)
Dim settings As FriendlyUrlSettings = New FriendlyUrlSettings() With {
.AutoRedirectMode = RedirectMode.Permanent
}
routes.EnableFriendlyUrls(settings)
End Sub
End Module
of course if I set .AutoRedirectMode to Off it works but without friendlyurls.
Am I doing something wrong?
EDIT 09/10/2019:
We figured out that remove the test of OriginalString.Contains("aspx") in the context_BeginRequest the encryption works, now the code is like:
Private Sub context_BeginRequest(ByVal sender As Object, ByVal e As EventArgs)
Dim context As HttpContext = HttpContext.Current
If context.Request.RawUrl.Contains("?") Then
Dim query As String = ExtractQuery(context.Request.RawUrl)
Dim path As String = GetVirtualPath()
If query.StartsWith(PARAMETER_NAME, StringComparison.OrdinalIgnoreCase) Then
Dim rawQuery As String = query.Replace(PARAMETER_NAME, String.Empty)
Dim decryptedQuery As String = Decrypt(rawQuery)
context.RewritePath(path, String.Empty, decryptedQuery)
ElseIf context.Request.HttpMethod = "GET" Then
Dim encryptedQuery As String = Encrypt(query)
context.Response.Redirect(path & encryptedQuery)
End If
End If
End Sub
But now the question is: there is other method to target an aspx page without test the extension? I think there is a risk that targeting things that not should target like "ashx" or cache-busting code that use querystring.

Get each key value out of a dictionary of strings object without using newsoft json

I have an indexpage.aspx which I post data into on page load. In this page I created list of strings
Protected Sub Page_Load(sender As Object, e As EventArgs) Handles Me.Load
Dim openWith As New SortedList(Of String, String)
' Add some elements to the list. There are no
' duplicate keys, but some of the values are duplicates.
openWith.Add("version", "1")
openWith.Add("key", ConfigurationManager.AppSettings("publickey"))
openWith.Add("cmd", "get_callback_address")
openWith.Add("currency", "coin")
Call POSTAPI("get_callback_address", openWith)
End Sub
Now I have a payment class which has postapi function, here's the class
Public Shared Function POSTAPI(cmd As String, Optional parms As SortedList(Of String, String) = Nothing) As Dictionary(Of String, Object)
Dim post_data As String = ""
For Each parm As KeyValuePair(Of String, String) In parms
If post_data.Length > 0 Then
post_data += "&"
End If
post_data += parm.Key + "=" + Uri.EscapeDataString(parm.Value)
Next
Dim keyBytes As Byte() = encoding.GetBytes(s_privkey)
Dim postBytes As Byte() = encoding.GetBytes(post_data)
Dim hmacsha512 = New System.Security.Cryptography.HMACSHA512(keyBytes)
Dim hmac As String = BitConverter.ToString(hmacsha512.ComputeHash(postBytes)).Replace("-", String.Empty)
' do the post:
Dim cl As New System.Net.WebClient()
cl.Headers.Add("Content-Type", "application/x-www-form-urlencoded")
cl.Headers.Add("HMAC", hmac)
cl.Encoding = encoding
Dim ret = New Dictionary(Of String, Object)()
Try
Dim resp As String = cl.UploadString("https://www.coinpayments.net/api.php", post_data)
Dim decoder = New System.Web.Script.Serialization.JavaScriptSerializer()
ret = decoder.Deserialize(Of Dictionary(Of String, Object))(resp)
Catch e As System.Net.WebException
ret("error") = "Exception while contacting CoinPayments.net: " + e.Message
Catch e As Exception
ret("error") = "Unknown exception: " + e.Message
End Try
Return ret
End Function
Its posting successfully but A successful call to the 'get_callback_address' or 'get_deposit_address' command will give you a result similar to this (JSON):
{
"error":"ok",
"result":{
"address":"1BitcoinAddress",
"pubkey":"",
"dest_tag":100,
}
}
Above are the keys and values is returning. Now my question is I only want to get the values of result and split it so it gives me "1BitcoinAddress", "pubkey" and save it to my database(I want to get the 3 values of that resultkey so i can save it in my database".
Thank you.
Since you deserialized the incoming json as a Dictionary(Of String, Object) the JavaScriptSerializer should have already created a second dictionary for the value of the result key. The only thing you have to do now, is create a variable that takes the value stored in the dictionary and cast it as a Dictionary(Of String, Object) in order to use it, like in this example
Dim json As String = "{" +
"""error"":""ok""," +
"""result"":{" +
"""address"":""1BitcoinAddress""," +
"""pubkey"":""""," +
"""dest_tag"":100" +
"}" +
"}"
Dim deserializer = New System.Web.Script.Serialization.JavaScriptSerializer()
'get the full dictionary
Dim dictionary = deserializer.Deserialize(Of Dictionary(Of String, Object))(json)
' make sure there is a key in your dictionary
If dictionary.ContainsKey("result") Then
'cast the value for "result" as a dictionary
Dim resultDictionary As Dictionary(Of String, Object) = _
DirectCast(dictionary("result"), Dictionary(Of String, Object))
'you can then access the keys by their key
Console.WriteLine("address: {0}, pubkey: {1}, dest_tag: {2}", _
resultDictionary("address"), _
resultDictionary("pubkey"), _
resultDictionary("dest_tag"))
End If
With your input, the program gives an output on the console, like this:
address: 1BitcoinAddress, pubkey: , dest_tag: 100
The big question of your question is really why you want to solve the deserialization without the use of Json.net. On the website for the JavaScriptSerializer,
it says at once:
Json.NET should be used serialization and deserialization. Provides serialization and deserialization functionality for AJAX-enabled applications.

Upload a document after saving it with agility pack fails

I've been struggling with some issue with an upload (thru FtpWebRequest) of a document after it's been saved with Html Agility pack.
I'm trying to edit a html file and then save it to a stringWriter and then upload it to a server.
I'm saving the document like this
...
doc.OptionAutoCloseOnEnd = True
doc.OptionWriteEmptyNodes = True
Dim sr As New StringWriter
doc.Save(sr)
And then upload it using asyncFtpUpload sub like the one on msdn but only with a few changes (instead of a filename I use the string)
http://msdn.microsoft.com/en-us/library/system.net.ftpwebrequest.aspx#Y3024
The result of this is that the file beeing uploaded get's the last bytes cut off.
When I see the source code of that file on the server, it misses the <\html> tag.
i have debugged the code and the string created on the doc.save() is correct, then in the upload routine, when i use the getBytes() it's still correct, and the requestStream write method writes the correct length of the stream.
I can't figure out what's happening with this code.
Can anyone help me figuring this out?
Here's the code:
Dim outStream As MemoryStream = New MemoryStream(ASCIIEncoding.Default.GetBytes(str))
Dim uploader As AsynchronousFtpUpLoader = New AsynchronousFtpUpLoader
uploader.startUpload(pag, outStream)
And the class:
Public Class AsynchronousFtpUpLoader
Public Sub startUpload(ByVal pag As FtpPage, ByVal stream As Stream)
Try
Dim waitObject As ManualResetEvent
Dim target As New Uri(pag.currentUrl)
Dim state As New FtpState()
Dim request As FtpWebRequest = DirectCast(WebRequest.Create(target), FtpWebRequest)
request.Method = WebRequestMethods.Ftp.UploadFile
request.UseBinary = False
request.Credentials = New NetworkCredential(pag.login, pag.password)
state.Request = request
state.stream = stream
' Get the event to wait on.
waitObject = state.OperationComplete
' Asynchronously get the stream for the file contents.
request.BeginGetRequestStream(New AsyncCallback(AddressOf EndGetStreamCallback), state)
' Block the current thread until all operations are complete.
waitObject.WaitOne()
' The operations either completed or threw an exception.
If state.OperationException IsNot Nothing Then
Throw state.OperationException
Else
End If
Catch ex As Exception
End Try
End Sub
Private Shared Sub EndGetStreamCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim requestStream As Stream = Nothing
Try
requestStream = state.Request.EndGetRequestStream(ar)
Const bufferLength As Integer = 2048
Dim buffer As Byte() = New Byte(bufferLength) {}
Dim readBytes As Integer = 0
Dim stream As MemoryStream = state.stream
Do
readBytes = stream.Read(buffer, 0, bufferLength)
If readBytes <> 0 Then
requestStream.Write(buffer, 0, readBytes)
End If
Loop While readBytes <> 0
requestStream.Flush()
state.stream.Close()
requestStream.Close()
state.Request.BeginGetResponse(New AsyncCallback(AddressOf EndGetResponseCallback), state)
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
Return
End Try
End Sub
Private Shared Sub EndGetResponseCallback(ByVal ar As IAsyncResult)
Dim state As FtpState = DirectCast(ar.AsyncState, FtpState)
Dim response As FtpWebResponse = Nothing
Try
response = DirectCast(state.Request.EndGetResponse(ar), FtpWebResponse)
response.Close()
state.StatusDescription = response.StatusDescription
state.OperationComplete.[Set]()
Catch e As Exception
state.OperationException = e
state.OperationComplete.[Set]()
End Try
End Sub

EnableDocumentFunction Asp.net XSLT XML

how do I enable xsltSettingf EnableDocumentFunction in Asp.net/VB in order to use document() in XSLT?
Public Shared Function xmlGetter(ByVal strXSLTFile As String, ByVal strXMLFile As String) As String
Dim reader As XmlReader = XmlReader.Create(strXMLFile)
Dim objXSLTransform As New XslCompiledTransform()
Dim xsltSettings As New XsltSettings()
xsltSettings.EnableDocumentFunction = True
objXSLTransform.Load(strXSLTFile)
Dim htmlOutput As New StringBuilder()
Dim htmlWriter As TextWriter = New StringWriter(htmlOutput)
objXSLTransform.Transform(reader, Nothing, htmlWriter)
Dim s As String
s = htmlOutput.ToString()
Return s
reader.Close()
End Function
There are overloads of the Load method (such as http://msdn.microsoft.com/en-us/library/ms163426.aspx) that take XsltSettings: objXSLTransform.Load(strXSLTFile, xsltSettings, Nothing).

AD Password About to Expire check

I am trying to write some code to check the AD password age during a user login and notify them of the 15 remaining days. I am using the ASP.Net code that I found on the Microsoft MSDN site and I managed to add a function that checks the if the account is set to change password at next login. The login and the change password at next login works great but I am having some problems with the check for the password age.
This is the VB.Net code for the DLL file:
Imports System
Imports System.Text
Imports System.Collections
Imports System.DirectoryServices
Imports System.DirectoryServices.AccountManagement
Imports System.Reflection 'Needed by the Password Expiration Class Only -Vince
Namespace FormsAuth
Public Class LdapAuthentication
Dim _path As String
Dim _filterAttribute As String
'Code added for the password expiration added by Vince
Private _domain As DirectoryEntry
Private _passwordAge As TimeSpan = TimeSpan.MinValue
Const UF_DONT_EXPIRE_PASSWD As Integer = &H10000
'Function added by Vince
Public Sub New()
Dim root As New DirectoryEntry("LDAP://rootDSE")
root.AuthenticationType = AuthenticationTypes.Secure
_domain = New DirectoryEntry("LDAP://" & root.Properties("defaultNamingContext")(0).ToString())
_domain.AuthenticationType = AuthenticationTypes.Secure
End Sub
'Function added by Vince
Public ReadOnly Property PasswordAge() As TimeSpan
Get
If _passwordAge = TimeSpan.MinValue Then
Dim ldate As Long = LongFromLargeInteger(_domain.Properties("maxPwdAge")(0))
_passwordAge = TimeSpan.FromTicks(ldate)
End If
Return _passwordAge
End Get
End Property
Public Sub New(ByVal path As String)
_path = path
End Sub
'Function added by Vince
Public Function DoesUserHaveToChangePassword(ByVal userName As String) As Boolean
Dim ctx As PrincipalContext = New PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)
Dim up = UserPrincipal.FindByIdentity(ctx, userName)
Return (Not up.LastPasswordSet.HasValue)
'returns true if last password set has no value.
End Function
Public Function IsAuthenticated(ByVal domain As String, ByVal username As String, ByVal pwd As String) As Boolean
Dim domainAndUsername As String = domain & "\" & username
Dim entry As DirectoryEntry = New DirectoryEntry(_path, domainAndUsername, pwd)
Try
'Bind to the native AdsObject to force authentication.
Dim obj As Object = entry.NativeObject
Dim search As DirectorySearcher = New DirectorySearcher(entry)
search.Filter = "(SAMAccountName=" & username & ")"
search.PropertiesToLoad.Add("cn")
Dim result As SearchResult = search.FindOne()
If (result Is Nothing) Then
Return False
End If
'Update the new path to the user in the directory.
_path = result.Path
_filterAttribute = CType(result.Properties("cn")(0), String)
Catch ex As Exception
Throw New Exception("Error authenticating user. " & ex.Message)
End Try
Return True
End Function
Public Function GetGroups() As String
Dim search As DirectorySearcher = New DirectorySearcher(_path)
search.Filter = "(cn=" & _filterAttribute & ")"
search.PropertiesToLoad.Add("memberOf")
Dim groupNames As StringBuilder = New StringBuilder()
Try
Dim result As SearchResult = search.FindOne()
Dim propertyCount As Integer = result.Properties("memberOf").Count
Dim dn As String
Dim equalsIndex, commaIndex
Dim propertyCounter As Integer
For propertyCounter = 0 To propertyCount - 1
dn = CType(result.Properties("memberOf")(propertyCounter), String)
equalsIndex = dn.IndexOf("=", 1)
commaIndex = dn.IndexOf(",", 1)
If (equalsIndex = -1) Then
Return Nothing
End If
groupNames.Append(dn.Substring((equalsIndex + 1), (commaIndex - equalsIndex) - 1))
groupNames.Append("|")
Next
Catch ex As Exception
Throw New Exception("Error obtaining group names. " & ex.Message)
End Try
Return groupNames.ToString()
End Function
'Function added by Vince
Public Function WhenExpires(ByVal username As String) As TimeSpan
Dim ds As New DirectorySearcher(_domain)
ds.Filter = [String].Format("(&(objectClass=user)(objectCategory=person)(sAMAccountName={0}))", username)
Dim sr As SearchResult = FindOne(ds)
Dim user As DirectoryEntry = sr.GetDirectoryEntry()
Dim flags As Integer = CInt(user.Properties("userAccountControl").Value)
If Convert.ToBoolean(flags And UF_DONT_EXPIRE_PASSWD) Then
'password never expires
Return TimeSpan.MaxValue
End If
'get when they last set their password
Dim pwdLastSet As DateTime = DateTime.FromFileTime(LongFromLargeInteger(user.Properties("pwdLastSet").Value))
' return pwdLastSet.Add(PasswordAge).Subtract(DateTime.Now);
If pwdLastSet.Subtract(PasswordAge).CompareTo(DateTime.Now) > 0 Then
Return pwdLastSet.Subtract(PasswordAge).Subtract(DateTime.Now)
Else
Return TimeSpan.MinValue
'already expired
End If
End Function
'Function added by Vince
Private Function LongFromLargeInteger(ByVal largeInteger As Object) As Long
Dim type As System.Type = largeInteger.[GetType]()
Dim highPart As Integer = CInt(type.InvokeMember("HighPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Dim lowPart As Integer = CInt(type.InvokeMember("LowPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Return CLng(highPart) << 32 Or CUInt(lowPart)
End Function
'Function added by Vince
Private Function FindOne(ByVal searcher As DirectorySearcher) As SearchResult
Dim sr As SearchResult = Nothing
Dim src As SearchResultCollection = searcher.FindAll()
If src.Count > 0 Then
sr = src(0)
End If
src.Dispose()
Return sr
End Function
End Class
End Namespace
And this is the Login.aspx page:
sub Login_Click(sender as object,e as EventArgs)
Dim adPath As String = "LDAP://DC=xxx,DC=com" 'Path to your LDAP directory server
Dim adAuth As LdapAuthentication = New LdapAuthentication(adPath)
Try
If (True = adAuth.DoesUserHaveToChangePassword(txtUsername.Text)) Then
Response.Redirect("passchange.htm")
ElseIf (True = adAuth.IsAuthenticated(txtDomain.Text, txtUsername.Text, txtPassword.Text)) Then
Dim groups As String = adAuth.GetGroups()
'Create the ticket, and add the groups.
Dim isCookiePersistent As Boolean = chkPersist.Checked
Dim authTicket As FormsAuthenticationTicket = New FormsAuthenticationTicket(1, _
txtUsername.Text, DateTime.Now, DateTime.Now.AddMinutes(60), isCookiePersistent, groups)
'Encrypt the ticket.
Dim encryptedTicket As String = FormsAuthentication.Encrypt(authTicket)
'Create a cookie, and then add the encrypted ticket to the cookie as data.
Dim authCookie As HttpCookie = New HttpCookie(FormsAuthentication.FormsCookieName, encryptedTicket)
If (isCookiePersistent = True) Then
authCookie.Expires = authTicket.Expiration
End If
'Add the cookie to the outgoing cookies collection.
Response.Cookies.Add(authCookie)
'Retrieve the password life
Dim t As TimeSpan = adAuth.WhenExpires(txtUsername.Text)
'You can redirect now.
If (passAge.Days = 90) Then
errorLabel.Text = "Your password will expire in " & DateTime.Now.Subtract(t)
'errorLabel.Text = "This is"
'System.Threading.Thread.Sleep(5000)
Response.Redirect("http://somepage.aspx")
Else
Response.Redirect(FormsAuthentication.GetRedirectUrl(txtUsername.Text, False))
End If
Else
errorLabel.Text = "Authentication did not succeed. Check user name and password."
End If
Catch ex As Exception
errorLabel.Text = "Error authenticating. " & ex.Message
End Try
End Sub
`
Every time I have this Dim t As TimeSpan = adAuth.WhenExpires(txtUsername.Text) enabled, I receive "Arithmetic operation resulted in an overflow." during the login and won't continue.
What am I doing wrong? How can I correct this? Please help!!
Thank you very much for any help in advance.
Vince
Ok I tried to use a different approach.
Here are the functions converted from C#:
Public Function PassAboutToExpire(ByVal userName As String) As Integer
Dim passwordAge As TimeSpan
Dim currentDate As DateTime
Dim ctx As PrincipalContext = New PrincipalContext(System.DirectoryServices.AccountManagement.ContextType.Domain)
Dim up = UserPrincipal.FindByIdentity(ctx, userName)
'Return (Not up.LastPasswordSet.HasValue)
'returns true if last password set has no value.
Dim pwdLastSet As DateTime = DateTime.FromFileTime(LongFromLargeInteger(up.LastPasswordSet))
currentDate = Now
passwordAge = currentDate.Subtract(pwdLastSet)
If passwordAge.Days > 75 Then
'If pwdLastSet.Subtract(passwordAge).CompareTo(DateTime.Now) > 0 Then
'Dim value As TimeSpan = pwdLastSet.Subtract(passwordAge).Subtract(DateTime.Now)
'If (value.Days > 75) Then
Return passwordAge.Days
'End If
Else
Return False
'already expired
End If
End Function
Private Function LongFromLargeInteger(ByVal largeInteger As Object) As Long
Dim type As System.Type = largeInteger.[GetType]()
Dim highPart As Integer = CInt(type.InvokeMember("HighPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Dim lowPart As Integer = CInt(type.InvokeMember("LowPart", BindingFlags.GetProperty, Nothing, largeInteger, Nothing))
Return CLng(highPart) << 32 Or CUInt(lowPart)
End Function
And here is the code snippet from the logon.aspx page:
sub Login_Click(sender as object,e as EventArgs)
Dim adPath As String = "LDAP://DC=xzone,DC=com" 'Path to your LDAP directory server
Dim adAuth As LdapAuthentication = New LdapAuthentication(adPath)
Try
If (True = adAuth.DoesUserHaveToChangePassword(txtUsername.Text)) Then
Response.Redirect("http://mypass.nsu.edu")
ElseIf (adAuth.PassAboutToExpire(txtUsername.Text) > 0) Then
Response.Redirect("http://www.yahoo.com")
Now when I try to login I receive the exception error: Error authenticating. Method 'System.DateTime.HighPart' not found.
and I don't know why. Anyone has any idea?
I would use the DateDiff function to determine the remaining number of days rather than using currentDate.Subtract
Dim passwordAge As Integer = (CInt)DateDiff(DateInterval.Day, Now, up.LastPasswordSet))
That will return an integer representing the number of days between now and when the password will need to be set.

Resources