.net.devcity.weekly ---
If you are unable to see the message, visit http://www.devcity.net/newsletter/archive/devcity/devcity20051220.htm

Advertisement

AdvertisementAdvertisement

The newsletter is compiled by DevCity.NET NewsMasters Ged Mead and Mike McIntyre

Happy Holiday Season to all DevCity.NET newsletter subscribers!

We launched vbCity Members Map powered by Google Maps and Frappr - feel free to explore member map and photos and reserve your spot - read on for more details.

Advertisement

Table Of Content:

Advertisement
Diary of a .NET Newbie: Zoom Boon

by Ged Mead

Some days as I'm making one of my daily wanders through the VBCity Forums, I'll sometimes come across an answer that makes me think "Wow! That makes a difficult solution look impressively easy."

This happened recently when someone wanted to be able to select a section of one image and see the selected portion enlarged in a second PictureBox.

You'll be familiar with the sort of thing I mean. As the user moves the mouse over the larger image, the area that immediately surrounds the mouse is shown in an inset type PictureBox, enlarged. As the mouse moves over the image, so the zoomed clip is dynamically updated and redrawn in the second PictureBox. Some map display programmes, for instance, do this kind of thing.

VBCity Member CJMills came up with a very neat answer. The core elements were:

  1. Set the SizeMode of the PictureBox which will display the zoomed selection to StretchImage.
  2. In the MouseMove event of the source PictureBox, create a rectangle object to hold the selected area.
  3. Constrain the selection rectangle to remain within the source PictureBox.
  4. Continuously assign the selection rectangle to a Bitmap object and display this bitmap in the zoom PictureBox.

Having a bit of time on my hands (and a particular fondness for playing around with graphics code), I added a few bells and whistles just for the heck of it. The version below makes full use of CJMills' code and adds the ability to change the zoom factor plus some other minor tweaks. None of which I hope detracts from the usefulness and simplicity of his original answer.

Here's my tarted up version:
First, some initial variables:

Dim bmpic As Bitmap  ' Declare a variable to hold the main image

'  Variables for the size of the selection area
Dim ZoomWidth As Integer = 32
Dim ZoomHeight As Integer = 32

Then in the Form_Load event, ensure that the PictureBoxes are configured to the correct SizeMode. Also load the image into the source PictureBox.

Private Sub Form2_Load(ByVal sender As Object, _
  ByVal e As System.EventArgs) Handles MyBase.Load
    '  Get image for source PictureBox
    Dim strPicFilePath As String = "H:\Dated Pic.jpg"
    PicSource.Image = Drawing.Image.FromFile(strPicFilePath)
    '  Set Both PictureBoxes' SizeMode Settings
    PicSource.SizeMode = PictureBoxSizeMode.AutoSize
    PicZoom.SizeMode = PictureBoxSizeMode.StretchImage
    '  Assign the source image to the bitmap variable
    bmpic = New Bitmap(PicSource.Image)
End Sub

In the MouseMove event of the source PictureBox, create a selection rectangle and constrain it within the PictureBox bounds. As the mouse moves, dynamically assign the latest rectangle as a bitmap to the Zoom PictureBox.

Private Sub picsource_MouseMove(ByVal sender As System.Object, _
  ByVal e As System.Windows.Forms.MouseEventArgs) Handles PicSource.MouseMove
    '  Create a Rectangle object for the selection area
    Dim rZoomArea As Rectangle = New Rectangle(0, 0, ZoomWidth, ZoomHeight)

    '  Ensure that you don't select anything outside the source PictureBox:
    If e.Y < (ZoomHeight / 2) Then
        rZoomArea.Y = 0
    ElseIf e.Y > PicSource.Image.Size.Height - (ZoomHeight / 2) Then
        rZoomArea.Y = PicSource.Image.Size.Height - ZoomHeight
    Else
        rZoomArea.Y = e.Y - CInt((ZoomHeight / 2))
    End If

    If e.X < (ZoomWidth / 2) Then
        rZoomArea.X = 0
    ElseIf e.X > PicSource.Image.Size.Width - (ZoomWidth / 2) Then
        rZoomArea.X = PicSource.Image.Size.Width - ZoomWidth
    Else
        rZoomArea.X = e.X - CInt(ZoomWidth / 2)
    End If

    '  Assign the selected part of the source image as a bitmap to the 
    '  Zoom PictureBox
    PicZoom.Image = bmpic.Clone(rZoomArea, bmpic.PixelFormat)
End Sub

To highlight the effect of the mouse action inside the source PictureBox, switch the cursor icon as it enters and leaves. Also optionally hide the zoom PictureBox if the mouse is not inside the source PictureBox.

Private Sub picsource_MouseEnter(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles PicSource.MouseEnter
    Me.Cursor = Cursors.SizeAll
    PicZoom.Visible = True
End Sub

Private Sub picsource_MouseLeave(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles PicSource.MouseLeave
    Me.Cursor = Cursors.Default
    PicZoom.Visible = False
End Sub

I thought it might be handy to invite the user to set different zoom settings. I used a NumericUpDown control for this and set its Minimum and Maximum values to 1 and 10 respectively. I also set its initial Value to 2 (for a default of 2x zoom)

Private Sub NumericUpDown1_ValueChanged(ByVal sender As System.Object, _
  ByVal e As System.EventArgs) Handles NumericUpDown1.ValueChanged
    ZoomWidth = CInt(PicZoom.Width / NumericUpDown1.Value)
    ZoomHeight = CInt(PicZoom.Height / NumericUpDown1.Value)
End Sub

So, having used up all my allowed period of playtime with this very enjoyable idea, all I need now is to find a real world need to implement it in. Watch out, you guys at Ordnance Survey, I'm right behind you!

The original Thread can be found here.

Thanks again to Chris Mills for the source for this article.

- Junior (Ged Mead aka XTab, xtab@vbcity.com)

by Mike McIntyre

Part 3 of 3

This, the third and final installment of the article, discusses some of the security concerns for cookies and cookieless sessions.

Security Considerations

Session ID Cookies, State Cookies, and Cookieless Sessions are used to associate client sessions on the host with client requests and to maintain potentially sensitive state on behalf of a client.

Session ID Cookies, State Cookies, and Cookieless Sessions are at risk of theft

Session ID can be stolen by stealing a Session ID Cookie or a Cookieless Session. Stealing a valid session ID may allow an attacker to exploit a system.

Once stolen, a State Cookie that contains sensitive information may disclose its contents to malicious hackers and facilitate other types of attacks on users, an application, and on supporting systems.

Threats and Countermeasures

How much damage can an attacker with a valid Session ID Cooke, a State Cookie, or the mangled URL from a cookieless session inflict on users, applications, and systems? That depends on what is actually stored in session state and state cookies.

This section contains some, but not all, the threats and counter measures that relate to Session ID Cookies, State Cookies, and Cookieless Sessions.

Session Hijacking

A session hijacking attack occurs when an attacker uses network monitoring software to capture the authentication token (often a cookie) used to represent a user's session with an application. With the captured cookie, the attacker can spoof the user's session and gain access to the application. The attacker has the same level of privileges as the legitimate user.

Countermeasures to prevent session hijacking include:

  • Use SSL to create a secure communication channel and only pass the authentication cookie over an HTTPS connection.
  • Implement logout functionality to allow a user to end a session that forces authentication if another session is started.
  • Make sure you limit the expiration period on the session cookie if you do not use SSL. Although this does not prevent session hijacking, it reduces the time window available to the attacker.

Cookie Replay Attacks

With this type of attack, the attacker captures the user's authentication cookie using monitoring software and replays it to the application to gain access under a false identity.

Countermeasures to prevent cookie replay include:

  • Use an encrypted communication channel provided by SSL whenever an authentication cookie is transmitted.
  • Use a cookie timeout to a value that forces authentication after a relatively short time interval. Although this doesn't prevent replay attacks, it reduces the time interval in which the attacker can replay a request without being forced to re-authenticate because the session has timed out.

Session Replay

Session replay occurs when a user's session token is intercepted and submitted by an attacker to bypass the authentication mechanism. For example, if the session token is in plaintext in a cookie or URL, an attacker can sniff it. The attacker then posts a request using the hijacked session token.

Countermeasures to help address the threat of session replay include:

  • Re-authenticate when performing critical functions. For example, prior to performing a monetary transfer in a banking application, make the user supply the account password again.
  • Expire sessions appropriately, including all cookies and session tokens.
  • Create a "do not remember me" option to allow no session data to be stored on the client.

Cookieless Session Replay

Cookieless session replay occurs when a client's request containing a mangled URL session token is intercepted and submitted by an attacker to bypass the authentication mechanism. In a mangled URL session ID is clearly visible to potential hackers who can easily steal it and represent themselves as an authorized client.

Countermeasures to help address the threat of session replay include:

  • Re-authenticate when performing critical functions. For example, prior to performing a monetary transfer in a banking application, make the user supply the account password again.
  • Expire sessions appropriately, including session tokens.

Cookie Manipulation

Cookies are susceptible to modification by the client. This is true of both persistent and memory-resident cookies. A number of tools are available to help an attacker modify the contents of a memory-resident cookie. Cookie manipulation is the attack that refers to the modification of a cookie, usually to gain unauthorized access to a Web site.

Countermeasures to help address the threat of session replay include:

  • While SSL protects cookies over the network, it does not prevent them from being modified on the client computer. To counter the threat of cookie manipulation, encrypt or use an HMAC with the cookie.
  • Validate cookie data.
  • Detect altered cookie data.

Cross-Site Scripting

An XSS attack can cause arbitrary code to run in a user's browser while the browser is connected to a trusted Web site. The attack targets an application's users and not the application itself, but it uses the application as the vehicle for the attack. Because the script code is downloaded by the browser from a trusted site, the browser has no way of knowing that the code is not legitimate. Internet Explorer security zones provide no defense. Since the attacker's code has access to the cookies associated with the trusted site and are stored on the user's local computer, a user's authentication cookies are typically the target of attack.

Countermeasures to prevent XSS include:

  • Perform thorough input validation. Your applications must ensure that input from query strings, form fields, and cookies are valid for the application. Consider all user input as possibly malicious, and filter or sanitize for the context of the downstream code. Validate all input for known valid values and then reject all other input. Use regular expressions to validate input data received via HTML form fields, cookies, and query strings.
  • Use HTMLEncode and URLEncode functions to encode any output that includes user input. This converts executable script into harmless HTML.
.NET Upgraders: The FileSystemWatcher

by David Jeavons

Introduction

Have you ever had a need to monitor a directory or set of directories to determine when something has happened? Maybe you need to be aware of when a file has been changed in some way, maybe a new file has been created or an existing file deleted. Writing this type of program in the past would probably have required some fancy code to read the contents of a directory and compare each file (size, date stamp etc.) against a stored list of known files. This would be quite complex and become even more so if you needed to monitor sub directories (or possibly an entire drive).

Enter the FileSystemWatcher (FSW) component. With this tool in your armoury, you have the ability to respond to changes to the file system that you are monitoring.

I recently had to write such a monitoring tool that would monitor a network share and process specific files when they were created. This tool would be used to send emails when these files were placed in a specific directory on a network. The files in question would contain instructions on who to send an email to and what content and attachments (if any) were required.

I already had a solid idea on how I was going to read the text files and send the emails using the System.IO and System.Web.Mail namespaces respectively but I was unsure as to the monitoring of the network share. I had previously read about the FSW component in an article somewhere but never actually had a need to use it. I did, however, remember that it seemed to contain the sort of functionality I was after.

So I did a little research and was pleasantly surprised at how easy and intuitive a tool it was. I then created a small test program that would monitor the required network share for files and read them as they came in. Within a couple of hours, I had a working test application that performed the base functionality required and was ready for testing. Following are my findings during my research into the FSW component.

Settings

The FSW component can be found in the toolbox under the Components tab. To use, simply drag it onto a form. Alternatively, you can create an instance of the FSW through code like so:

Dim objFSO As New System.IO.FileSystemWatcher

The FSW component does not have many properties to modify and can be set directly through the designer. For my monitoring tool, I required to know when a file was created with an extension of ".api" in a specific path on a network. The following table lists all of the properties of the FSW component and the values that I used for my requirements:

Property    DescriptionSetting
FilterDetermines what type of file you will be monitoring. For example, to monitor for only text files, you would set this property to *.txt, likewise, to monitor for all files you would set the property to *.**.api
PathSets the path you wish to monitor. This can be any directory on your local PC or a network share. Note, only operating systems based on NT technology can be monitored.\\server\share\directory\
IncludeSubDirectoriesSpecifies whether or not to monitor directories under the main directory set in the Path property. False
NotifyFilterThis property is probably the most important as it specifies what type of attributes you want to monitor. The table below describes each value.FileName
EnableRaisingEventsDetermines whether or not the FSW will raise events to your program. By default, this property is set to True. However if you have instantiated your FSW object through code then the default will be False so don't forget to set this property, otherwise you may be scratching your head wondering why your program isn't working (not that I have done this, of course)True

NotifyFilter property values

ValueDescription
AttributesChanges to a file or directories attribute.
CreationTimeChanges to a file or directories creation time.
DirectoryNameThe name of the directory.
FileNameThe name of the file.
LastAccessDate file or directory was last accessed.
LastWriteDate file or directory was last edited.
SecuritySecurity changes to the file or directory.
SizeChanges to a file or directory's size.

NB: You can set multiple NotifyFilter values by separating each value with a comma in the Properties list or using the Or operator through code.

Responding to Events

After setting all of the required properties, it is time to start writing the code that will respond to the events raised by the FSW component. There are only five events that are of particular interest, namely:

EventDescription
ChangedRaised when a file or directory has been changed.
CreatedRaised when a file or directory has been created.
RenamedRaised when a file or directory has been renamed.
DeletedRaised when a file or directory has been deleted.
ErrorRaised when an error occurs with the FSW component.

The Changed, Created and Deleted events expose a FileSystemEventArgs object which can be used to query the properties of the file/directory that has raised any of the aforementioned events. As these three events share the same argument list, you can code one routine that handles all three events. The following snippet will display a message box showing the name of the file that caused the event to be raised and will also specify what type of event it is:

Private Sub FileSystemWatcher1_Changed _
  (ByVal sender As Object, ByVal e As System.IO.FileSystemEventArgs) Handles _
  FileSystemWatcher1.Changed, FileSystemWatcher1.Created, FileSystemWatcher1.Deleted

    'Determine the type of change.
    Select Case e.ChangeType

        Case IO.WatcherChangeTypes.Changed
            MessageBox.Show("Changed event raised. File that raised event " _
              & ControlChars.NewLine & e.Name)
        Case IO.WatcherChangeTypes.Created
            MessageBox.Show("Created event raised. File that raised event " _
              & ControlChars.NewLine & e.Name)
        Case IO.WatcherChangeTypes.Deleted
            MessageBox.Show("Deleted event raised. File that raised event " _
              & ControlChars.NewLine & e.Name)

    End Select

End Sub

In the example above, the Created and Deleted events will be fired when a file is created or deleted due to the NotifyFilter property being set to FileName. However, if you want the Changed event to be raised, you will also have to monitor the Size attribute, so you will need to modify the NotifyFilter property accordingly.

The Renamed event differs slightly from the three events mentioned above in that it exposes a RenamedEventArgs object. This object allows you to determine the original and new name values for the file that raised this event:

Private Sub FileSystemWatcher1_Renamed _
  (ByVal sender As Object, ByVal e As System.IO.RenamedEventArgs) Handles _
  FileSystemWatcher1.Renamed

    MessageBox.Show("Renamed event raised." & ControlChars.NewLine _
      & "Original file name " & e.OldName & ControlChars.NewLine _
      & "New file name " & e.Name)

End Sub

The last event to mention is the Error event. This event is raised when the internal buffer overflows, which can occur when many changes to the file system you are monitoring take place at the same time. If you find that this event is being raised an inordinately large number of times you can increase the buffer size given to the FSW by setting the InternalBufferSize property to a larger value. Take care however not to set this too high as any memory allocated to the size of the internal buffer is retrieved from non paging memory.

Summary

The FSW component proved to be the right tool for my small monitoring program and was also very easy to use. I am sure that you will find many useful scenarios where this tool will prove extremely handy.

We updated recently launched http://vbfeeds.com and it is mobile enabled now.

This was easily done using new ASP.NET 2.0 Master Pages and enhanced Request.Browser object - see blog post link below for details.

Subscribe to the latest VB related news via aggregated vbcity.com RSS link - http://feeds.feedburner.com/vbfeeds

More details - SergeB Blog post

http://blogs.vbcity.com/sergeb/archive/2005/10/19/5589.aspx
Advertisement

We launched vbCity Members Map powered by Google Maps and Frappr - feel free to explore member map and photos and reserve your spot.

vbCity Map link - http://www.frappr.com/vbcity

For more details see Forum post

http://www.frappr.com/vbcity
Advertisement

We encourage you to pass this issue of
.net.devcity.weekly on to anyone you know with an interest in .NET technology and News You Can Compile

Manage Your Subscription Here.

You are currently subscribed as '*EMAIL*' to .net.devcity.weekly.

Click here to unsubscribe.

Thanks for reading!

Contact:
vbCity.com, LLC
4957 Lakemont Blvd SE C4 #331
Bellevue, WA 98006


DevCity.NET is hosted by FullControl.NET

Copyright vbCity.com, LLC 2003. All Rights Reserved.