Thursday, September 18, 2008

ASPNET user account folder and files

Did you ever thought about the folder and files created by Windows XP for the ASPNET user account?

"The ASPNET user account is an internal account and no one is able to log using this identity"

This is the most common answer for my question. And yes, the answer is true. At least it touches the most important part. But there's more.

You see, since Windows XP invokes ASP.NET processes using ASPNET account, it also automatically creates a user folder with typical structure (Application Data, Cookies, My Documents etc.) for this account.

And here comes the strange part: the folder structure for the ASPNET user account is created under "Documents and Settings" but instead of username as a folder name, the machinename/username is used.

Suppose now that your machine's name is XYZ and you use a user account named XYZ. Guess what - you'll see ASPNET user local folder inside your own user folder.

Something tells me that this is not quite right. I should not be able to peek into other user's files but since the folder sits inside my own local folder, I am able to browse it with no restrictions.

I would say that this is rather insecure, no matter if it can be easily misused or not.

Tuesday, September 9, 2008

The "cookie" property of mshtml.IHtmlDocument2 does not work anymore

In one of our applications we host the Internet Explorer ActiveX control in a window and manually create parameters for navigation (including the body and http headers). To correctly inject the ASP.NET session id cookie into such requests (the page we navigate to comes from the ASP.NET server) we have to be able to somehow inject the ASP.NET_SessionId cookie into the navigation context.

The application was written two (or three) years ago, and we've been injecting the cookie using the cookie property of the mshtml.IHtmlDocument2 interface.

/* we've retrieving the reference to the document */
mshtml.IHtmlDocument2 doc = ...; 
 
/* and we've been setting the aspnet session id cookie */
doc.cookie = ...;

This worked like a charm, up to this year - the application is heavily used but only in september (it's responsible for gathering and processing some data available in september and then the data is passed to another appliaction) and this year we've been surprised to see that the cookie property does not work (at least in Internet Explorer 7). Both accessors (set and get) seem to have no effect and you always get the null value from the getter.


Pretty annoying. I guess it's somehow related to security issues but surely it broke the backward compatibility, at least for us.


The solution is to use another method which can inject cookies into the http processing chain:



/* injects cookies into the http processing for
   current process */
[DllImport("wininet.dll")]
public static extern bool InternetSetCookie( 
    [MarshalAs(UnmanagedType.LPStr)]
    string Url,
    [MarshalAs(UnmanagedType.LPStr)]
    string CookieName,
    [MarshalAs(UnmanagedType.LPStr)]
    string CookieData
    );
 
...
    /* first inject the cookie */
    InternetSetCookie(
        "url",
        "ASP.NET_SessionId",
        "theaspnetcookievalue_nomatterhowyougetit" );
 
    /* then navigate */
    webBrowser1.Navigate( "url" );
  
    /* the cookie is correctly set for the navigation.
       although you STILL cannot see it using mshtml.IHtmlDocument2.cookie,
       the http debugger reveals that it's really there 
    */

Wednesday, September 3, 2008

SmtpClient exception - An invalid character was found in the mail header

This hit me today as I tried to move a configuration section to another configuration file. It seems that the SmtpClient class does not like non-english letters in email header.

MailMessage mail = new MailMessage();
 
mail.From = new MailAddress( 
    "noreply@noreply.com", 
    "ąęłóżśńć", // <- the cause of the exception
    Encoding.UTF8 ); 

What's really scary is that the code above actually works - the exception occured only when the subject name was read from the configuration file!


After an intense struggle, I've found the solution. Just add



mail.SubjectEncoding = Encoding.UTF8;
somewhere around. It works, at least for me.

Wednesday, August 27, 2008

Remote desktop to another OS and back again

As you surely know, XP is a single-user OS which means that there can be only a single user logged-in at one time. If the administrator logs in from a remote machine using the remote desktop tool, the current user is logged off and a message shows up saying "this machine is currently in use [...]"

If you have a spare 3 minutes, try to reproduce following steps:

  1. Log into a non-virtual Windows XP
  2. Use Virtual PC to boot a virtual Windows XP and log into it
  3. Use remote desktop in the virtual Windows XP to log back to the non-virtual Windows XP (which hosts the virtual one)

What happens to your non-virtual Windows session after you log into it from the virtual machine? Will the "this machine is currently in use" message show up?

Well, if you do it using two XPs, the host screen goes black and the machine stops responding. The non-virtual XP is controlled "from the inside".

What's great is that the non-virtual machine still runs - you can access all it's services, the application server, the database server and others run perfectly. You just cannot control the machine anymore using the keyboard.

I belive that there are few other interesting options to continue this experiment.

For example, can you regain the control of the OS by accessing it with the remote desktop from yet another machine? What happens when the Windows Server 2003 is used instead Windows XP?

Thursday, August 14, 2008

Lightweight Service Bus frameworks

The application environment I work on needs an architectural fundament capable of a loose-coupled integration. There's a reference handbook on integration patterns, the "Enterprise Integration Patterns" by Hohpe/Woolf (also take a look at the "Integration Patterns" book from Microsoft Patterns & Practices group).

 

Anyway, there are four major integration patterns:

  • File Sharing - where application share data by exchaning files
  • Shared Database - where applications are build around a single database
  • Remote Procedure Calls - where applications expose their data through remote interfaces
  • Messaging - where applications exchange messages with the help of a centralized component (called a "Service Broker" when the messages are processed synchronously or the "Enterprise Service Bus" when a messaging component is used to store and handle messages) which acts as a backbone of the application environment


[http://msdn.microsoft.com/en-us/library/aa475433.aspx]

One of the most interesting aspects of an ESB implementation is handling various MEPs (Message Exchange Patterns: synchronous, asynchronous, send-and-forget, publish-subscribe). The latter, publish/subscribe seems the most attractive option to integrate an environment consisting of different components.

There are plenty of fully fledged ESB implementations but the core of a service bus can be built using much a simple environment based solely on a messaging component like MSMQ or IBM Webshpere MQ. And since the "low level" integration with a messaging component could be painful, we need lightweight service bus frameworks just to wrap unnecessary calls into friendly APIs.

After some research, I've found three such lightweight service bus frameworks for the .NET platform:

  • nServiceBus - uses MSMQ as messaging component and Spring.NET as the IoC container. Supports so called "sagas" which are just long-running workflows as well as the scalability over a large enterprise system.
  • Simple Service Bus - built on top of the nServiceBus. At first look seems like the porting of few nServiceBus features is not completed at the moment. Uses the Castle.Microkernel as the IoC container.
  • MassTransit  - seems to take a more universal approach, supports MSMQ / ActiveMQ as messaging components and  different IoC containers. There's not much to evaluate since the useful versions cannot be downloaded at the moment.

I hope to write more on the topic soon since this is not only the top-priority task I work on at the moment but also, in the same time, it's just just quite fun to play with.

Friday, July 18, 2008

Generating random sequences with LINQ

A concise random number generator

Inspired by The LINQ Enumerable Class article from the lastest MSDN Magazine issue, I started to play a little bit with the random sequence generator:

/* generate the sequence */
Random rnd = new Random();
var sequence = Enumerable.Range( 1, 10 ).OrderBy( n => rnd.Next() );
 
/* write down the sequence */
sequence.ToList().ForEach( n => Console.WriteLine( n ) );

As you can see, the sequence is generated with two statements, the first one initializes a random number generator and the second one sorts the list using the results from the generator.


My immediate thought was: "Is there a way to genearte such random sequence using a single statement?"


The obvious approach



var sequence = Enumerable.Range( 1, 10 ).OrderBy( n => (new Random()).Next() );

does not work because a new random number generator is created for each value from the list and the same random value is returned from all these newly created generators.




Random number generator testing

Let's write a test of the random number generator - we treat consecutive values from the array as coordinates and draw an image of the generator:



static void RandomSequenceGeneratorTest( IEnumerable<int> Sequence )
{
    int Max = Sequence.Max();
 
    /* create image */
    using ( Bitmap bitmap = new Bitmap( Max, Max ) )
    using ( Graphics graphics = Graphics.FromImage( bitmap ) )
    {
        graphics.Clear( Color.Black );
 
        int prev = Sequence.First();
        foreach ( var current in Sequence.Skip(1) )
        {
            graphics.DrawRectangle( 
                Pens.White, 
                new Rectangle( 
                    /* draw a point 
                       using current and previous values
                       as coordinates
                    */
                    new Point( prev, current ), 
                    new Size( 1, 1 ) ) );
 
            prev = current;
        }
 
        bitmap.Save( "test.png", ImageFormat.Png );
    }
}

Testing the generator (version 1)

Let's also test our generator:



var sequence = Enumerable.Range( 1, 500 ).OrderBy( n => ( new Random() ).Next() );
RandomSequenceGeneratorTest( sequence );


An improved generator (version 2)

However, I can modify the generator slightly to get much better results!



var sequence = Enumerable.Range( 1, 500 ).OrderBy( n => n * ( new Random() ).Next() );
RandomSequenceGeneratorTest( sequence );


Hey! It seems that the multiplication makes the generator much less predictive, however as the clear pattern reveals, the resulting sequence is still not random!


What exacly happens is the arithmetic overflow caused by



n * (new Random()).Next()

which "distrubutes" multiplied values in a more "random" way.


Do we really need (new Random())?

After I've realized that the "randomness" of the improved generator is caused by arithmetic overflows, I immediately thought of getting rid of the (new Random()). Maybe the overflow itself is enough to get random sequence?



var sequence = Enumerable.Range( 1, 500 ).OrderBy( n => n * 1234567890 );
RandomSequenceGeneratorTest( sequence );


Well, it is not. Altough the sequence printed on the console looks quite random at first sight, the image reveals that it's not random at all. It seems that the value produced by the (new Random()).Next() is then important, even though the first test (version 1) revealed that the value itself is not enough!


Even more improved generator (version 3)

Let's go back to our improved generator and try to improve it even more:



var sequence = Enumerable.Range( 1, 500 ).OrderBy( n => n * n * ( new Random() ).Next() );
RandomSequenceGeneratorTest( sequence );


I guess, I am satisfied. However, I do not think I am curious enough to dig for a exhaustive explanation. Does really the arithmetic overflow causes this generator to produce random sequence? What's the exact role of (new Random()).Next() here? It seems that it's not important itself (version 1), however removing it completely also does not work.


I belive that the deferred nature of LINQ enumeration is the one of keys to explain these obervations. I would also like to see some deeper and more throughout tests of my "yet-improved" generator.


On the other hand, could it be possible that incidentally, by making a square function (n*n), I've built a chaotic function with random distribution over its domain?

Friday, July 11, 2008

C# Puzzle No. 11 (intermediate)

Generic list type needs an item type to be initialized:

List<int>    listInt;
List<string> listString;
...

On the other hand, C# 3.0 allows anonymous types to be used in the code. An anonymous type is never explicitely named:



var item = new { Field1 = "The value", Field2 = 5 };
Console.WriteLine( item.Field1 );

How it is then possible to declare a generic list of anonymous type?



var item = new { Field1 = "The value", Field2 = 5; };
 
List<?> theList = 
    /* how do I make a generic list with item in it 
       so that I can add other items of the same anonymous type?
     */