Master C# Logo banner
Welcome to MasterCSharp.com - Master C#, the easy way... - by Saurabh Nandu

 


World Time Client Part1 : Introduction and Installation

Add Comment
 

 
<p> <span class=wboxheado>Introduction</span><br> 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 &quot;<i>Good Afternoon Mr. Nandu, ...... </i>&quot; and I feel like &quot;<i>what the hell, its middle of the night here can you please let me sleep!!</i>&quot;. 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 '<b>Time</b>' is it in that part of the world!<br> This problem laid the inspiration for me to create a <i>World Time Web Service</i> (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 <a class="wbox" href="mailto:saurabh@mastercsharp.com"> saurabh@mastercsharp.com</a>. You can access the Web Service at <br> <a class="wbox" target="_blank" href="http://www.MasterCSharp.com/live/TimeService/TimeService.asmx">http://www.MasterCSharp.com/live/TimeService/TimeService.asmx</a> and the <b>WSDL</b> for this service is available at <a class="wbox" target="_blank" href="http://www.MasterCSharp.com/live/TimeService/TimeService.asmx?WSDL">http://www.MasterCSharp.com/live/TimeService/TimeService.asmx?WSDL</a>.&nbsp;&nbsp; </p> <p>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.</p> <p><span class=wboxheado>Choice of Client</span><br> 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.<p><span class=wboxheado>Client Architecture</span><br> 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.<br> I have broken down my application into libraries, namely<br> 1) <b>WorldTimeClient.dll</b> - This is the first assembly that is downloaded in the browser, it has the necessary code to check the <i>Isolated Storage</i> for user credentials, allow a user to sign-in, or register a new account with the World Time Web Service.<br> 2) <b>MasterCSharp.WebService.WorldTimeService.dll</b> - As the name suggests, this assembly consists&nbsp; the proxy class that talks with the <i>World Time Web Service</i>. 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.<br> 3) <b>CustomizeControl.dll</b> - 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.<br> 4) <b>DateTimeDisplayControl.dll</b> - This is again a User Control which is used to display the world time clocks. It has an Windows Forms <i>Timer</i> component within it that keeps updating the time once it has been set. This assembly is usually everytime after the user has signed-in.<p align="center"> <img border="0" src="../../img/worldtimeclient1_1.gif" width="400" height="400"><br> <b>Figure 1: </b>Client Architecture </p>The above figure 1 shows the the architecture of the client application, I will summarize the steps below.<br> <span class=wboxhead>Step 1:</span> 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 <b>LoadAssembly</b> to load the assembly from the server. Due to this, the first assembly referred in the object tag i.e. the <i>WorldTimeClient.dll </i>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.<p><span class=wboxhead>Step 2:</span> Now the logic in my assembly first checks the <i>Isolated Storage</i> of the computer to find the user persisted credentials information, if appropriate files are found and it jumps to <i>Step 5</i>. Incase there are no appropriate files found in the <i>Isolated Storage</i>, then a Sign-In box is displayed to the user to sign-in into the <i>World Time Web Service</i>, on the same box the user also has an option to register a new account with the <i>World Time Web Service</i>. </p> <p><span class=wboxhead>Step 3:</span> If the user chooses to sign-in the <i>MasterCSharp.WebService.WorldTimeService.dll</i> 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 <i>Step 5.</i><br> Incase a new account is registered then too the <i>MasterCSharp.WebService.WorldTimeService.dll</i> assembly is downloaded to communicate with the web service. Once the new account is registered we jump to <i>Step 4</i>.</p> <p><span class=wboxhead>Step 4:</span> When a new account is registered the user does not have any clocks preferences set, so the <i>CustomizeControls.dll</i> assembly is downloaded to help the user pick the necessary clocks. Even if a registered user clicks the <b>Customize</b> 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 <i>Step 5</i>. Remember here too we require the <i>MasterCSharp.WebService.WorldTimeService.dll</i> assembly to communicate with the web service, so if it has not already been downloaded before, it too gets downloaded.</p> <p><span class=wboxhead>Step 5:</span> This is the final step where the <i>DateTimeDisplayControl.dll</i> assembly is downloaded and then the <i>WorldTimeClient.dll </i>assembly shows the appropriate number of clocks to the user that have been chosen by the user before in <i>Step 4</i>.</p> <p>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 <b>Bandwidth</b> over internet is not <b>unlimited</b>!! 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.<br> 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 <i>Sign-In</i>, 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.</p> <p>Once the assembly has been downloaded its stays in the <b>Download Cache</b> 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 <i>download cache</i>, if its the same then the assembly from the <i>download cache</i> 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!<br> 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!</p> <p><span class=wboxheado>Dealing with .NET Security</span><br> 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 <b>ActiveX </b>controls, its also more customizable than the security sandbox present in <b>JAVA</b>.<br> There are two important faces of security that I explain here briefly :</p> <p><span class=wboxhead>1) Evidence Based Security:</span> 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.</p> <p><span class=wboxhead>2) Permission Set Based Security:</span> Every operation your code can perform has been classified into different <i>permission sets</i> 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.</p> <p>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 <b>Yes</b> then the control would install and run else it would be rejected.</p> <p>This kind of security has the following ills:-<br> 1) Novice users never knows what this box is all about and hardly makes a sensible decision.<br> 2) The dialog never mentions what kind of operations the control will perform, for example say you trusted a <i>Windows Update</i> ActiveX Control to run, you never know what kind of operations it might perform!<br> 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.</p> <p>Microsoft did the relevant research in this field and found that its only the <b>System/Network Administrators</b> 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!!</p> <p><span class=wboxhead>caspol.exe Tool</span><br> 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.</p> <p><span class=wboxhead>mscorcfg.msc Tool</span><br> This tool is an mmc (Microsoft Management Console) snap-in. It has similar functionality of the <i>caspol</i> 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 <i>WorldTimeClient</i> assembly.</p> <p>Note: Both these tools are installed when you install the .NET Framework in the <b>C:\WINNT\Microsoft.NET\Framework\v1.0.2914\</b> directory.</p> <p><span class=wboxhead>Isolated Storage</span><br> 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 <i>Isolated Storage</i>. <i>Isolated Storage</i> 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 <i>Isolated Storage</i>, classes under the <b>System.IO.IsolatedStorage</b> namespace. Assemblies can never get the exact absolute or relative path of the file stored on the disk making it very safe. But <i>Isolated Storage</i> does have a limited quota of hard-disk space that it can occupy. You can use the <b> StoreAdm</b> tool to view and remove the files and directories stored in <i>Isolated Storage</i>. Generally the <i>Isolated Storage</i> files are stored under the <b>C:\Documents and Settings\&lt;User&gt;\Local Settings\Application Data\Microsoft\Isolated Storage\ </b>directory on Windows 2000. </p> <p><span class=wboxheado>Providing trust to the WorldTimeClient assembly</span><br> My <i>World Time Client</i> 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 :) !!<br> If you read the Client Architecture section, you will find that some of the important permissions my application requires is:<br> 1) Download additional assemblies from the same server.<br> 2) Access the Isolated Storage<br> 3) Connect to a Web Service. This might be on the same server or some other server.<br> The first two permissions can easily be granted by <i>medium</i> security, but the last point of connecting to an external URL needs <i>full</i> permissions to execute.<br> 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 <i>WorldTimeClient.dll</i> 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 <i>MasterCSharp.WebService.WorldTimeService.dll</i> assembly will be given a call it will throw a <b>Security Exception</b>, since the application does not have the necessary permission to connect to an external URL!! Makes sense ??? Sounds Familiar ??</p> <p><span class=wboxheado>Let's Start</span><br> <span class=wboxhead>Step 1:</span> Open your IE browser and navigate to <a class="wbox" target="_blank" href="http://www.MasterCSharp.com/live/TimeClient/Default.htm">http://www.MasterCSharp.com/live/TimeClient/Default.htm</a> (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 '<b>Security Exception</b>' is thrown, but since there is no UI present yet, nothing is shown to you. But the just the <i>WorldTimeClient.dll </i>has been downloaded in to your download cache. To confirm this start the command prompt (<b>cmd</b>) and give the command <b>gacutil /ldl</b> to call the <i>gacutil</i> 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.</p> <p><span class=wboxhead>Step 2:</span> In <i>Step 1</i> my application did not load up at all, this is because of two facts, <br> a) My application was loaded from the Internet, by default the code from the Internet executes in <i>low trust</i>.<br> b) My application is designed to download more assemblies from the same server, this is not permitted for application from the Internet.</p> <p><b>Table 1:</b> Permission Set's (Text taken from the mscorcfg tool)</p> <table width="100%" class="outline"> <tr> <td width="33%" class="outline"><b>Permission Level</b></td> <td width="67%" class="outline"><b>Rights </b> </td> </tr> <tr> <td width="33%" class="outline">No Trust</td> <td width="67%" class="outline">No Programs can Execute</td> </tr> <tr> <td width="33%" class="outline">Low Trust</td> <td width="67%" class="outline">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)</td> </tr> <tr> <td width="33%" class="outline">Medium Trust</td> <td width="67%" class="outline">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.&nbsp; </td> </tr> <tr> <td width="33%" class="outline">Full Trust</td> <td width="67%" class="outline">Security Checks are no performed and the program can access all resources of your machine. (Default for My Computer Zone)</td> </tr> </table> <p>Since you need to give appropriate trust to mode assemblies start the <b>mscorcfg.msc</b> tool, go to <b>Start -&gt; Run -&gt; mscorcfg.msc</b> and press <b>OK</b> 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&nbsp; '<b>Runtime Security Policy</b>' so choose it from the tree view.<br> <i><b>Note:</b></i> .NET also provides a <b>mscorcfg.exe</b> tool for similar purpose, but its a stripped-down version of the <b>mscorcfg.msc</b> tool.</p> <p align="center"> <img border="0" src="../../img/worldtimeclient1_2.gif" width="440" height="286"><br> <b>Figure 2:</b> mscorcfg.msc tool</p> <p><span class=wboxhead>Step 3:</span> As seen in <i>Figure 2</i>, there are 2 main settings under the <i>Runtime Security Policy</i> that are important to us, first we will adjust the zone security, so click the <b>Adjust Zone Security</b> link in the <i>.NET Admin Tool (mscorcfg.msc)</i> to start the wizard.</p> <p align="center"> <img border="0" src="../../img/worldtimeclient1_3.gif" width="477" height="446"><br> Figure 3: Adjust Zone Security </p> <p>You will see this dialog many times in the <i>.NET Admin Tool</i>, 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 '<b>Make changes to this computer</b>' and select <b>Next</b>.</p> <p><span class=wboxhead>Step 4:</span> The next screen you see in the <b>Adjust Zone Security</b> wizard will be very familiar to you. Just like <i>Internet Explorer</i>, 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 <b>My Computer Zone</b> 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 <i>Network Administrator</i> decides this is not a good option for one of the computers, he can simply set the zone to <i>low</i> or <i>medium trust</i> 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 :)</p> <p align="center"> <img border="0" src="../../img/worldtimeclient1_4.gif" width="477" height="446"><br> <b>Figure 4:</b> Adjust Zone Security</p> <p>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,<br> a) Increase the trust level of the <i>Internet Zone</i>, this would be a bad idea since there could be some other harmful code on the internet that could cause trouble.<br> b) Increase trust of the <i>Trusted Sites Zone</i>, 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.<br> Once you set the <i>Trusted Sites</i> Zone to <b>full trust </b>click <b>Next</b> and then click <b>Finish</b> to save the security changes. This completes the zonal security changes. In case of a multiple user computer you can set the <b>Computer</b> zonal settings to the maximum any user might require and then on a per user basis you could choose <b>User</b> from <i>Step 4</i> above and then <i>lower</i> the security trust for a particular user!<p><span class=wboxhead>Step 5:</span> Now let's for a moment step away from the <i>.NET Admin Tool</i> and go back to the browser. In the browser choose <b>Tools Menu -&gt; Internet Options -&gt; Security</b>. This will bring up a dialog that lets you configure the security settings for your web browser. Choose the <b>Trusted Sites </b>and click the <b>Sites..</b> button to bring-up a dialog that lets you enter websites into the <i>Trusted Zone</i>. Uncheck the <i>Require Server verification (https:) for all sites in this zone</i> and add the url <b> http://www.MasterCSharp.com/live/TimeClient/</b> in the add textbox and click the <b>Add</b> button to enter this URL into the lists of your trusted websites. Once done click <b>OK</b> to close this dialog and again click <b>OK</b> to close the <i>Internet Tools</i> dialog.<p align="center"> <img border="0" src="../../img/worldtimeclient1_5.gif" width="384" height="335"><br> <b>Figure 5:</b> Trusted Sites Dialog<p><span class=wboxhead>Step 6:</span> This is the final step in trusting the application, switch back to the <i>.NET Admin Tool</i> (mscorcfg.msc) and this time click on <b>Increase Assembly Trust</b> link. This will bring up a dialog similar to the one shown in <i>Step 4</i>, here you can choose either <b>Computer</b> or <b>User</b> the choice is yours and then click <b>Next</b>. In the next screen enter the URL to the assembly that you want to trust. In our case <b> http://www.MasterCSharp.com/live/TimeClient/WorldTimeClient.dll</b>. and click <b>Next</b>. In the next screen too click <b>Next</b> 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 <b>Finish</b> to close the wizard and then close the <i>.NET Admin Tool</i> too.<p align="center"> <img border="0" src="../../img/worldtimeclient1_6.gif" width="477" height="452"><br> <b>Figure 6:</b> Increase Assembly Trust<p><span class=wboxhead>Step 7:</span> If you have finished the above steps successfully then you are ready to run the application, start a <b>new</b> instance of the browser and load the url <a class="wbox" target="_blank" href="http://www.MasterCSharp.com/live/TimeClient/Default.htm"> http://www.MasterCSharp.com/live/TimeClient/Default.htm</a>. 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!!<p>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 '<b>Persist User</b>' while signing-in your account the account details will get saved into <i>Isolated Storage</i> and re-used again the next time you load the control.<p align="center"> <img border="0" src="../../img/worldtimeclient1_7.gif" width="323" height="263"><br> Figure 7: World Time Client<p>While you are playing with the application, remember to use the <b>gacutil /ldl</b> command from time to time to see how the assemblies get downloaded in the <i>download cache</i> only when needed. You could also use the <b>gacutil /cdl</b> command to clear all the assemblies from the <i>download cache</i>.<p><span class=wboxheado>Conclusion</span><br> 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 <i>mscorcfg.msc</i> tool and grant trust to an assembly.<br> In the parts following this I will show you how to build this <i>World Time Client</i> example!! So stay tuned!!

Comments

Add Comment