Introduction
The world has certainly become a small place with advancement in
technologies. Currently working across nation's, continents boundaries
is very easy and an common phenomenon. Most people I currently work
with live half-way across the globe mostly in USA while I work here
from India staying connected through Internet!! Although there are
times when your trusted email conversation does not suffice and you
need to talk - live using the phone!! This trivial thing as calling-up
can also be a very annoying problem, why?? - Time Zones are the
culprits! There is around 12 hours difference in time between Indian
Standard Time and Eastern Time. So many times in the middle of the
night I get calls and some sweet voice on the other end starts up with
"Good Afternoon Mr. Nandu, ...... " and I feel like "what the hell,
its middle of the night here can you please let me sleep!!". You have
to be extra cautious while with dealing with such situations, not to
annoy your business partners. Also there are many people who are on
the move globe trotting who also need to know what 'Time' is it in
that part of the world!
This problem laid the inspiration for me to create a World Time Web
Service (still in its beta), which allows a registered user to keep
track of time all over the world. Currently this Web Service is very
amateur and does not have any support for things like Daylight Savings
etc, also its has a very limited list of countries in its database.
There might be inaccuracies too, since I am not a expert on such
matters I have collected data from freely available sources on the
Internet. If you have any suggestion/additions please feel free to
email me on
saurabh@mastercsharp.com. You can access the Web Service at
http://www.MasterCSharp.com/live/TimeService/TimeService.asmx and
the WSDL for this service is available at
http://www.MasterCSharp.com/live/TimeService/TimeService.asmx?WSDL.
Although there are some websites that do provide such information
(not as a web service), most of them I found either provided static
time of a location at once (keep refreshing the page if you need the
current time!!) or others required you to purchase their software, so
I decided to build a small client application for myself!! In this
series of articles I will walk you through creating your own Windows
Forms client for the World Time Service.
Choice of Client
If you want to display dynamic information, plain static HTML won't
suffice. You can use JavaScript's embed in HTML pages, but for my
implementation I have used a Windows Forms client that load from the
Internet Explorer (IE) browser. This gives me the power and features
of the Windows Forms API and the flexibility of a web application that
can be easily updated/changed and managed. Client Architecture
Since I was building a Windows Forms client hosted in IE, I had to
make a number of choices to modularize my application for efficiency
and faster loading on the client-side. Here is where the power of
logically partitioning your application across several physical
libraries (Dll's) comes into highlight.
I have broken down my application into libraries, namely
1) WorldTimeClient.dll - This is the first assembly that is downloaded
in the browser, it has the necessary code to check the Isolated
Storage for user credentials, allow a user to sign-in, or register a
new account with the World Time Web Service.
2) MasterCSharp.WebService.WorldTimeService.dll - As the name
suggests, this assembly consists the proxy class that talks with
the World Time Web Service. This assembly is only downloaded when the
client application needs to communicate with the web service. Like
sign-in the user, register a new user or customize a users preference.
3) CustomizeControl.dll - This assembly contains a Windows Forms User
Control that has the necessary logic to help the user customize his
preference of clocks to be displayed. Since its a very GUI intensive
task I have separated it out from the main assembly. This assembly is
only downloaded if the client wants to customize his clock preference.
4) DateTimeDisplayControl.dll - This is again a User Control which is
used to display the world time clocks. It has an Windows Forms Timer
component within it that keeps updating the time once it has been set.
This assembly is usually everytime after the user has signed-in.

Figure 1: Client Architecture The above figure 1 shows the the
architecture of the client application, I will summarize the steps
below.
Step 1: In the first step the user browses to the page that hosts the
client application (Default.htm) with Internet Explorer. The .NET
Runtime senses the object on the page refers to an managed assembly,
so it performs a LoadAssembly to load the assembly from the
server. Due to this, the first assembly referred in the object tag
i.e. the WorldTimeClient.dll is downloaded from the server. Then its
checked for appropriate security permissions (more on this later)
based on the assembly evidence i.e. the location from where it was
downloaded, internet, intranet, localhost etc. If the appropriate
permissions are granted, the assembly is loaded.Step 2: Now the
logic in my assembly first checks the Isolated Storage of the computer
to find the user persisted credentials information, if appropriate
files are found and it jumps to Step 5. Incase there are no
appropriate files found in the Isolated Storage, then a Sign-In box is
displayed to the user to sign-in into the World Time Web Service, on
the same box the user also has an option to register a new account
with the World Time Web Service.
Step 3: If the user chooses to sign-in the
MasterCSharp.WebService.WorldTimeService.dll assembly is downloaded
since its contains the proxy class to communicate with the Web
Service. If the user provides appropriate credentials and gets
validated by the Web Service, the users clocks information is fetched
from the Web Service and then a jump is made to Step 5.
Incase a new account is registered then too the
MasterCSharp.WebService.WorldTimeService.dll assembly is downloaded to
communicate with the web service. Once the new account is registered we
jump to Step 4.
Step 4: When a new account is registered the user does not have any
clocks preferences set, so the CustomizeControls.dll assembly is
downloaded to help the user pick the necessary clocks. Even if a
registered user clicks the Customize link then too this
assembly is downloaded. Once the appropriate changes are made by the
user, they are saved to the Web Service and we jump to Step 5.
Remember here too we require the MasterCSharp.WebService.WorldTimeService.dll assembly to communicate
with the web service, so if it has not already been downloaded before,
it too gets downloaded.
Step 5: This is the final step where the
DateTimeDisplayControl.dll
assembly is downloaded and then the WorldTimeClient.dll assembly shows
the appropriate number of clocks to the user that have been chosen by
the user before in Step 4.
From the above description you might have noticed that while
building application that download from the internet its very
important to modularize your application. One of the most important
reason for this is that Bandwidth over internet is not unlimited!!
There are still a lot of people (including me) who work over crappy
56.6 dial-up internet connections which are very costly and bandwidth
drenched! With proper segmentation of the assemblies you can help your
application load faster and then the other remote features keep
getting downloaded as and when needed.
Although there is one drawback to the method I have used and that is
that while the new assembly is downloading the client has to wait,
like when the user enters his credentials and click's Sign-In, he has
to first wait while the assembly containing the proxy dll is
downloaded over the internet, to combat this I have used the status
bar to display messages to inform the user to wait.
Once the assembly has been downloaded its stays in the Download
Cache on the client machine, on every subsequent request for the
application, the .NET runtime checks the version of the assembly
present on the server with the one present in the download cache, if
its the same then the assembly from the download cache is loaded (i.e.
faster loading), if a new version of the assembly is found on the
server, then it gets downloaded. This way its very easy to distribute
application upgrades to clients, since if there are any bug fixes in
the application, you just have to upload one copy on the server and
all the clients will start using the new version!
Also remember that since the application has been downloaded in the
download cache, even if you are not connected to the internet i.e. you
are in offline mode in your browser, you can still load the assembly,
but of course if your assembly needs to connect to the Internet then
that operation will fail!
Dealing with .NET Security
Internet is not a perfect paradise! Where on one hand there is
tremendous resources on the internet not all resources can be trusted,
and then there are a bunch of people out there trying to do wacky
things with your computer and data. You need to shield yourself from
such sources. On the .NET Platform Microsoft has provided a very
extensive security architecture which is a great step forward from the
security mechanism used in ActiveX controls, its also more
customizable than the security sandbox present in JAVA.
There are two important faces of security that I explain here briefly
:
1) Evidence Based Security: As the name suggests this deals with
evidence the runtime has about the assembly in question. Like its
origin, its author, its digital signature etc. For example the .NET
security runs the same code with different permissions based on the
origin of the code. A application that runs from the local computer
has the permission to read/write to files from the local hard disk,
while if that same application was loaded from the internet it won't
(and shouldn't) be able to read/write to files on the local system.
2) Permission Set Based Security: Every operation your code can
perform has been classified into different permission sets by the .NET
runtime. While executing the application, the runtime checks if the
code has the necessary permission (based on the Evidence of the
Assembly) to execute a operation. This is a bit costly operation, but
with the amount of damaging code out there, its a very useful one. For
example, the permission to connect to a external website is grouped
under a separate permission set and the permission to read/write to a
file on the hard-disk comes under a different permission set.
As I said before .NET has an very extensive security architecture,
but its equally configurable. In the case of ActiveX Controls, when an
ActiveX control would first run, a dialog box would pop-up informing
the end-user that a ActiveX Control is attempting to run and the
dialog box would also give a bit more information about the owner of
the ActiveX Control (in case of signed controls). If the user clicked
Yes then the control would install and run else it would be rejected.
This kind of security has the following ills:-
1) Novice users never knows what this box is all about and hardly
makes a sensible decision.
2) The dialog never mentions what kind of operations the control will
perform, for example say you trusted a Windows Update ActiveX Control
to run, you never know what kind of operations it might perform!
3) System Administrator's nightmare! No matter how secure the
administrator can make his network, one malicious control loaded by an
user on the network could bring the whole network to its knees.
Microsoft did the relevant research in this field and found that
its only the System/Network Administrators who have the appropriate
knowledge to make the right decision in such cases and hence they have
taken away the decision making power from the hands of end-user and
provided tools that the network administrators could use to define
various security policies. One way its a good thing from Network
Administrators point of view, but from a programmers point of view it
might end-up being hell!! Having said this, on the .NET Platform no
longer will show dialog boxes pop-up in the users browser asking them
to trust the code! If the user has to provide the necessary
permissions to a assembly then he (or the network administrator) has
to manually use the tools and wizards provided by .NET to trust the
code. Currently in Beta2 these tools and wizards are not fully
developed, but I hope that in future Microsoft provides a more
user-friendly tools to solve this problem!!
caspol.exe Tool
This is one of the tools that helps you define security policies and
trust an assembly, but this is a command-line based tool so I won't be
describing it.
mscorcfg.msc Tool
This tool is an mmc (Microsoft Management Console) snap-in. It has
similar functionality of the caspol tool, but its provides a
host of wizards to make the definition of security policy easy. I will
show you how to use this tool to provide appropriate permissions the
WorldTimeClient assembly.
Note: Both these tools are installed when you install the .NET
Framework in the C:\WINNT\Microsoft.NET\Framework\v1.0.2914\
directory.
Isolated Storage
This is one feature I had to mention!! Microsoft has recognized that
security is a key concern, but then programmers should not suffer due
to the security sandbox, should they !! So Microsoft has come up with
the concept of Isolated Storage. Isolated Storage is nothing but a
space on your local hard-disk reserved for .NET Applications.
Assemblies from low-trust zones can use this special storage space to
persist their settings and other information to the local hard-disk.
To access files and directories stored in the Isolated Storage,
classes under the System.IO.IsolatedStorage namespace. Assemblies can
never get the exact absolute or relative path of the file stored on
the disk making it very safe. But Isolated Storage does have a limited
quota of hard-disk space that it can occupy. You can use the
StoreAdm tool to view and remove the files and directories stored
in Isolated Storage. Generally the Isolated Storage files are stored
under the C:\Documents and Settings\<User>\Local
Settings\Application Data\Microsoft\Isolated Storage\ directory on
Windows 2000.
Providing trust to the WorldTimeClient assembly
My World Time Client application also runs from the internet,
so if you would directly try to access it, of course the .NET Runtime
will not allow you to load it since the application performs some
functions that need your (end-users) consent and trust!! Trust Me, my
code is secure :) !!
If you read the Client Architecture section, you will find that some
of the important permissions my application requires is:
1) Download additional assemblies from the same server.
2) Access the Isolated Storage
3) Connect to a Web Service. This might be on the same server or some
other server.
The first two permissions can easily be granted by medium security,
but the last point of connecting to an external URL needs full
permissions to execute.
One important factor to note here is that you have to provide trust to
only the first assembly of the application, then all the assemblies
loaded later-on by the first assembly execute with the same
permissions the first assembly has. For Example, in my application you
have to trust the WorldTimeClient.dll assembly since its the first
assembly of the application (you can know that from the source of the
HTML file that loads the application). Now if you would just give the
first 2 (from the list above) permissions to this assembly, it would
work properly but when the MasterCSharp.WebService.WorldTimeService.dll assembly will be given a
call it will throw a Security Exception, since the application does
not have the necessary permission to connect to an external URL!!
Makes sense ??? Sounds Familiar ??
Let's Start
Step 1: Open your IE browser and navigate to
http://www.MasterCSharp.com/live/TimeClient/Default.htm (the
location where I have placed the application). You will find that you
browser is blank even after the page is loaded with probably just the
outline of the control showing!! This is because a 'Security
Exception' is thrown, but since there is no UI present yet, nothing is
shown to you. But the just the WorldTimeClient.dll has been
downloaded in to your download cache. To confirm this start the
command prompt (cmd) and give the command gacutil /ldl
to call the gacutil tool and show the list of assemblies
present in the download cache, you can use this tool again and again
to see how the assemblies get downloaded.
Step 2: In Step 1 my application did not load up at all, this is
because of two facts,
a) My application was loaded from the Internet, by default the code
from the Internet executes in low trust.
b) My application is designed to download more assemblies from the
same server, this is not permitted for application from the Internet.
Table 1: Permission Set's (Text taken from the mscorcfg tool)
| Permission Level |
Rights |
| No Trust |
No Programs can Execute |
| Low Trust |
Programs will not be able to
access protected resources like registry, environment variables,
domain names, or security policy settings. Programs have limited
ability to use windowing resources, and your local file system but
only with your approval. (Default for Internet Zone) |
| Medium Trust |
Programs will not be able to use
protected resources such as registry, or security policy settings
or access your local file system without user interaction.
Programs will be able to connect back to their site of origin,
resolve domain names and use all windowing resources. |
| Full Trust |
Security Checks are no performed
and the program can access all resources of your machine. (Default
for My Computer Zone) |
Since you need to give appropriate trust to mode assemblies start
the mscorcfg.msc tool, go to Start -> Run -> mscorcfg.msc and press
OK
to start the tool. You will see a lot of options, the total list of
functions of this tool is out of the scope of this article, even the
documentation on this is very sparse currently so whatever I am going
to describe below is from my personal experience and it could be
wrong! But if you play around with things its not too difficult to
find out most of the functions. For our example we will need to
concentrate on the 'Runtime Security Policy' so choose it from
the tree view.
Note: .NET also provides a mscorcfg.exe tool for similar purpose, but
its a stripped-down version of the mscorcfg.msc tool.

Figure 2: mscorcfg.msc tool
Step 3: As seen in Figure 2, there are 2 main settings under the
Runtime Security Policy that are important to us, first we will
adjust the zone security, so click the Adjust Zone Security
link in the .NET
Admin Tool (mscorcfg.msc) to start the wizard.

Figure 3: Adjust Zone Security
You will see this dialog many times in the .NET Admin Tool, it lets
to select whether you want to configure security for the computer or
for just the current user. Note that the user policy cannot gain more
permissions then the security permissions given to the computer. So in
our case select 'Make changes to this computer' and select Next.
Step 4: The next screen you see in the
Adjust Zone Security wizard
will be very familiar to you. Just like Internet Explorer, even the
.NET Platform divides code source into different zones. Then depending
upon the zone of your code necessary permissions are given to the
code. This is a very powerful way of defining security policies
depending on the origin of the code. If you see the My Computer Zone
you will find that its been given full trust so all applications that
reside on the local computer run without any security checks, but if
the Network Administrator decides this is not a good option for one of
the computers, he can simply set the zone to low or medium trust
and then even applications running from the local hard-disk will come
under the security check!! So its better you don't piss-off your
network administrator :)

Figure 4: Adjust Zone Security
Coming back to my application configuration, as I had said
before my application will require full trust since it wants to
communicate with the Web Service. Now, you have two options at this
point,
a) Increase the trust level of the Internet Zone, this would be a bad
idea since there could be some other harmful code on the internet that
could cause trouble.
b) Increase trust of the Trusted Sites Zone, this would be a better
idea but it would require you to perform one additional step and that
is to add my website to the favorites section in your browser.
According to me this would be a better step for you perform for all
such situations, where you need to trust code from the internet.
Once you set the Trusted Sites Zone to full trust click
Next and then
click Finish to save the security changes. This completes the zonal
security changes. In case of a multiple user computer you can set the
Computer zonal settings to the maximum any user might require and then
on a per user basis you could choose User from Step 4 above and then
lower the security trust for a particular user! Step 5: Now let's
for a moment step away from the .NET Admin Tool and go back to the
browser. In the browser choose Tools Menu -> Internet Options ->
Security. This will bring up a dialog that lets you configure the
security settings for your web browser. Choose the Trusted Sites
and
click the Sites.. button to bring-up a dialog that lets you enter
websites into the Trusted Zone. Uncheck the Require Server
verification (https:) for all sites in this zone and add the url
http://www.MasterCSharp.com/live/TimeClient/ in the add textbox
and click the Add button to enter this URL into the lists of your
trusted websites. Once done click OK to close this dialog and again
click OK to close the Internet Tools dialog.

Figure 5: Trusted Sites Dialog Step 6: This is the final step in
trusting the application, switch back to the .NET Admin Tool (mscorcfg.msc)
and this time click on Increase Assembly Trust link. This will bring
up a dialog similar to the one shown in Step 4, here you can choose
either Computer or User the choice is yours and then click
Next. In
the next screen enter the URL to the assembly that you want to trust.
In our case
http://www.MasterCSharp.com/live/TimeClient/WorldTimeClient.dll.
and click Next. In the next screen too click Next since it deals with
signed assemblies. Then in final screen incase the assembly has lower
trust you will be given an option to increase the trust based on the
zone the assembly originates or the wizard will inform you that the
assembly already has full trust. Click Finish to close the
wizard and then close the .NET Admin Tool too.

Figure 6: Increase Assembly Trust Step 7: If you have finished the
above steps successfully then you are ready to run the application,
start a new instance of the browser and load the url
http://www.MasterCSharp.com/live/TimeClient/Default.htm. If you
have the configurations right then the assembly will load and show up
everytime! In my testing I did notice that sometimes the browser (IE
6.0.2600.00) would appear hung for few minutes and then it would load
up correctly, but this was only if the assemblies were downloaded from
the internet. While running then from an intranet or localhost no such
errors appeared. I don't know what's the bug here, but I am sure there
is no problem with the code because other applications too gave me
similar problems!! If you are a registered user you can sign-in
directly and if you are a new user then you can register a new new
account for yourself! One tip is that if you select 'Persist User'
while signing-in your account the account details will get saved into
Isolated Storage and re-used again the next time you load the
control.

Figure 7: World Time Client While you are playing with the
application, remember to use the gacutil /ldl command from time to
time to see how the assemblies get downloaded in the download cache only when needed. You
could also use the gacutil /cdl command to clear all the assemblies
from the download cache. Conclusion
In this part we had a look at importance of modularizing an
application that downloads over the internet. Later we saw how to
customize .NET Security using the mscorcfg.msc tool and grant trust to
an assembly.
In the parts following this I will show you how to build this World
Time Client example!! So stay tuned!! |