• Care, Share and Grow!

    Considering hosting Web based services on IIS 7.0?

    • 0 Comments

    If you are contemplating to move over (upgrade) to IIS 7.0 from your existing Web hosting on either IIS 5.0 or 6.0 this is a very useful Technical White Paper link. It talks about various aspects of improvements in IIS 7.0 dealing with Management, Performance, Extensibility, Security and Deployment.

    Migrating a Large, High-Volume Web Site to Internet Information Services 7.0

    Cheers!

  • Care, Share and Grow!

    Some Info around WebDAV content access issues

    • 3 Comments

    If you have a Web folder (WebDAV) hosted on IIS using Basic Authentication there are a few things you need to ensure such that any client accessing the resource does not get into failures.

    If your WebDAV site is restricted using Basic authentication and you are trying to access it over HTTP, access may fail. Over HTTP it may keep prompting you for authentication or else will show the following error:

    "Internet Explorer could not open http://ComputerName/WebDav as a Web

    Folder. Would you like to see its default view instead?"

    image

    Windows Vista will fail to connect to the server using Basic authentication which is insecure over the network. Vista/XP requires SSL connection to be used with Basic. However you can connect to the Web folder if you set the following registry key on the client machine to 2.

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\WebClient\Parameters\BasicAuthLevel

    The BasicAuthLevel can be set to the following values:

    • 0 - Basic authentication disabled
    • 1 - Basic authentication enabled for SSL shares only (Default)
    • 2 or greater - Basic authentication enabled for SSL shares and for non-SSL shares

    Check this article for more on this Q841215

     

    Also You may not be able to edit an Office 2007 document from within a Web folder from your client. In such a case ensure the following registry key is set:

    HKEY_CURRENT_USER\Software\Microsoft\Office\12.0\Common\Internet\OpenDocumentsReadWriteWhileBrowsing = 1

    Refer to this Q870853 for more around Office 2003/2007.

    * If you are still having issues editing the Office document ensure that there is no Certificate Security alert or Error when browsing to the same Web folder URL. If you do see a security alert because of any of the three reasons associated with it ensure they are fixed. 

    Also these should be handy for other WebDAV related issues, KB912152 and KB900900.

     

    Until next time...

  • Care, Share and Grow!

    Increase the concurrent connections limit for IIS FTP site if you see server reset

    • 1 Comments

    If you have a FTP site hosted on IIS which receives a burst of client connections at specific intervals and you see the connections getting reset from server-end please read on.

    Let's say you have over 1500 concurrent FTP client connections being made at every 'n' minute you may see that the IIS FTP server is resetting many of those client connections. From a FTP client (the typical ftp.exe from the command prompt) you may see the following:

    "Connection closed by remote host"

    At other times when there is less load on the server things will look good.

    Capturing a network trace may show you that a 3-way handshake between the client and the server is taking place and after that server resets the connection. You don't even get to a point wherein you can enter your credentials to access the FTP site. FTP site's maximum concurrent connections property (MaxConnections) is well above this value.

    If you are in a similar scenario wherein a sudden bursts of concurrent client connections is leading to the FTP server resetting the requests you may want to play with some combinations of the settings mentioned below. It may be that you are hitting some connection limit for your server. It may not be the total number of connections being made but the total number of simultaneous connections that is causing the problem.

    You will have to play with the following settings on the IIS 6.0 server:

    HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Services\InetInfo\Parameters
        ListenBacklog = xxx (Range: 1 -250, Default: 25)
        MaxPoolThreads = xx (Range: 0 - 4,294,967,295 (unlimited), Default: 4)
        DisableBacklogMonitor=1

    And in the metabase, under /LM/MSFTPSVC/
        ServerListenBacklog=”xxx”

    * The ServerListenBacklog property specifies the number of outstanding sockets that can be queued. The value is based on the AcceptEx operating system parameter, and the server size specified in the ServerSize property. Valid values for this property range from 5 to 500.

    Reset IIS after making the above changes.

    See this link for more details on the Global registry entries for IIS 6.0.   

    The ListenBacklog setting in the registry controls how many active connections are queued by winsock if IIS is unable to service new requests.  ServerListenBacklog is used by IIS to proactively create sockets to handle incoming requests. This setting adjusts the number of outstanding sockets that your Web server can queue. Setting ServerListenBacklog to a higher value allows IIS to handle a larger number of requests, while ListenBacklog helps the system buffer the connection spikes if the number of new connections briefly exceeds what IIS can service immediately.

    Although the range for ListenBacklog  & ServerListenBacklog is given I had seen a scenario wherein we had to adjust the value to a higher number than the given range. You may need to tweak the combination yourself!

    *I give credit to Rob Patrick from PSS IIS Escalation team for this post

  • Care, Share and Grow!

    Getting fatal error LNK1181: cannot open input file 'kernel32.lib'

    • 17 Comments

    I was a happy man until a few hours back when I was playing with some C, C++ programs built using Visual Studio 2008 on my work and home machines. I could write some program on my workstation, copy the solution to my personal laptop at home and thereby continue from where I left in office. Things  were good until I installed the latest Windows SDK v6.1 on my Vista laptop while trying my hands on Windows PowerShell.

    I realized a day or so later after installing SDK v6.1 that now I could not build my application written in C or C++. I could compile it but not link it during build process from within Visual Studio. Funny though I realized I could not even build a very basic Win32 console application.

    I started getting the following error:

    fatal error LNK1181: cannot open input file 'kernel32.lib' 

    I did something while troubleshooting it and now also started seeing:

    Error spawning 'rc.exe'. Project myProject

    I did check on the Internet and found all sorts of reasoning around this. One thing looked clear that installing the latest SDK v6.1 had caused me all these headaches. Some links suggested rebooting the server, some talked about  low system  memory, some said remove the latest SDK v6.1, and some also suggested to reinstall Visual Studio. But somehow I felt this can be fixed without reinstallation of VS2008 or un-installation of SDK v6.1 or etc etc and etc.

    I opened the cool Process Monitor tool and found the following:

    28836    11:51:31.5538847    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\lib\kernel32.lib    NAME NOT FOUND    
    28837    11:51:31.5539987    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\lib\kernel32.lib    NAME NOT FOUND    
    28839    11:51:31.5542065    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\kernel32.lib    NAME NOT FOUND    
    28841    11:51:31.5543630    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\kernel32.lib    NAME NOT FOUND    
    28842    11:51:31.5544705    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\i386\kernel32.lib    PATH NOT FOUND    
    28844    11:51:31.5545935    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\VC\atlmfc\lib\i386\kernel32.lib    PATH NOT FOUND    
    28846    11:51:31.5547253    devenv.exe    5528    QueryOpen    D:\Program Files\Microsoft SDKs\Windows\v6.1\lib\kernel32.lib    PATH NOT FOUND    
    28847    11:51:31.5548633    devenv.exe    5528    QueryOpen    D:\Program Files\Microsoft SDKs\Windows\v6.1\lib\kernel32.lib    PATH NOT FOUND    
    28848    11:51:31.5550927    devenv.exe    5528    QueryOpen    D:\Program Files\Microsoft SDKs\Windows\v6.1\lib\kernel32.lib    PATH NOT FOUND    
    28849    11:51:31.5552863    devenv.exe    5528    QueryOpen    D:\Program Files\Microsoft SDKs\Windows\v6.1\lib\kernel32.lib    PATH NOT FOUND    
    28850    11:51:31.5556190    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\kernel32.lib    NAME NOT FOUND    
    28851    11:51:31.5559045    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\kernel32.lib    NAME NOT FOUND    
    28852    11:51:31.5561361    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\lib\kernel32.lib    PATH NOT FOUND    
    28853    11:51:31.5563280    devenv.exe    5528    QueryOpen    E:\Program Files\Microsoft Visual Studio 9.0\lib\kernel32.lib    PATH NOT FOUND    

    It was crystal clear that while trying to link Visual Studio was encountering a file not found kind of error and hence could be the resulting failure.

    ------ Build started: Project: aa, Configuration: Debug Win32 ------
    Linking...
    LINK : fatal error LNK1104: cannot open file 'kernel32.lib'
    Build log was saved at "file://xxxxxxxxxxx\Visual Studio 2008\Projects\myProject\myProject\Debug\BuildLog.htm"
    myProject - 1 error(s), 0 warning(s)
    ========== Build: 0 succeeded, 1 failed, 0 up-to-date, 0 skipped ==========

    Similarly rc.exe showed NOT FOUND.

    It looked simple yet intriguing as to why the default path was changed for Visual Studio.

    I realized that the path it was trying to look at for these files did not even exist, lest I could just have copied these files to the corresponding location.

    Looked at the Environment variables from Visual Studio 2008 command prompt and found that WindowsSdkDir environment variable was pointing to D:\Program Files\Microsoft SDKs\Windows\v6.1\ which did not exist.

    Tried changing this to the path where I did find the above files on my box which was pointing to C:\program files\microsoft sdks\windows\v6.0A\ (So yes it pretty much looked like after installing SDK v6.1 my environment variable WindowsSdkDir had changed). Tried logging off/rebooting, no luck.

    Finally figured out that in order to get things back to normal I had to update the following registry key:

    HKEY_CURRENT_USER\SOFTWARE\Microsoft\MicrosoftSDKs\Windows\CurrentInstallFolder

    I changed this value to point to the original location which was C:\Program Files\Microsoft SDKs\Windows\v6.0A\ in my case.

    I wasted a lot of time on this, so thought of sharing with a wider audience.

    bye!

  • Care, Share and Grow!

    New features in SETSPN.EXE on Windows Server 2008

    • 4 Comments

    The version of Setspn.exe that came with Microsoft Windows Server 2000/2003 Support Tools did not have features to detect duplicate SPNs. The new version of Setspn.exe that comes bundled with Windows Server 2008 utilities has some really cool features. For someone dealing with the dreaded Kerberos authentication failure issues on a daily basis like me it's a sigh of relief.

    If you try the following command on the Windows Server 2008 you will see the various new options (or switches) available.

    image

    Notice the modifiers/switches:

    -F = perform the duplicate checking on forestwide level

    -S = add arbitrary SPN after verifying no duplicates exist

    -Q = query for existence of SPN

    -X = search for duplicate SPNs

     

    Searching for duplicate SPNs using Setspn.exe:

    D:\>setspn -X http/www.test.com
    Processing entry 0
    http/www.test.com is registered on these accounts:
        CN=mstest,CN=Users,DC=<some-DC-primary>,DC=<some-DC-secondary>
        CN=<IIS-servername>,OU=Domain Controllers,DC=<some-DC-primary>,DC=<some-DC-secondary> 
    
    found 1 group of duplicate SPNs.
    

    Searching for the existence of an SPN in the domain:

    D:\>setspn -Q http/www.test.com
    CN=<IIS-servername>,OU=Domain Controllers,DC=<some-DC-primary>,DC=<some-DC-secondary>
        http/www.test.com
        ldap/2334590-45566-113f....
        HOST/<IIS-servername>
        HOST/<IIS-servername.<some-DC-primary>.<some-DC-secondary>
        .......
        .......
    CN=mstest,CN=Users,DC=<some-DC-primary>,DC=<some-DC-secondary>
        http/www.test.com 
    
    Existing SPN found!
    

    Adding an arbitrary SPN after verifying no duplicates exist in the domain:

    D:\>setspn -S http/www.test.com <IIS-servername>
    CN=mstest,CN=Users,.<some-DC-primary>.<some-DC-secondary>
        http/www.test.com 
    
    Duplicate SPN found, aborting operation!
    
    

    Adding an arbitrary SPN after verifying no duplicates exist in the forest:

    D:\>setspn -F -S http/www.test.com <IIS-servername>
    Operation will be performed forestwide, it might take a while.
    CN=mstest,CN=Users,DC=<some-DC-primary>,DC=<some-DC-secondary>
        http/www.test.com
    CN=mstest1,CN=Users,DC=<some-DC-primary>,DC=<some-DC-secondary>
        http/www.test.com 
    
    Duplicate SPN found, aborting operation! 
    

    So what does this mean? It means you no longer have to depend upon boggling commands using LDIFDE or your own custom scripts to find out the duplicate SPNs. This is a good news indeed!

    *Prior to this using Windows Server 2000/2003 Support Tools we could use commands using LDIFDE to find duplicate SPNs as below:

    Syntax:

    ldifde -f <filename> -d "<dc=domain-netbiosname,dc=primary-domain>" -l serviceprincipalname -r "(serviceprincipalname=<serviceprincipalname-to-check-for-duplicates>)" -p subtree

    For example, if the domain name is test.abcd.com and the site URL is http//test.abcd.com command should be as shown below:

    ldifde –f C:\log.txt -d "dc=test, dc=abcd, dc=com"-l serviceprincipalname –r "(serviceprinicpalname=http/test.abcd.com)" -p subtree

    With the newer version of Setspn hopefully the dependency on the above command should reduce drastically.

    Till next time,

    Cheers!

  • Care, Share and Grow!

    Service Principal Name (SPN) checklist for Kerberos authentication with IIS 7.0/7.5

    • 3 Comments

    In continuation to one of my earlier posts which focused on IIS 6.0 this post is more about the confusion that may arise around SPNs for setting up Kerberos authentication in IIS 7.0. IIS 7.0 has a new Kernel-mode authentication feature using which the ticket for the requested service is decrypted using Machine account (Local system) of the IIS server. It no longer depends upon the application pool Identity for this purpose by default and in turn improves the performance.

    Here is how it looks like.

    image

    image

    So what does this mean?

    You no longer need to worry about the correlation between HTTP SPNs and the Application pool Identity that was required in the earlier version i.e. IIS 6.0. But that's not blindly true. There has been some confusion whether we don't have to care at all about SPNs or may have to depending upon the settings. Here is a checklist to give more clarity for different scenarios that you may fall under:

    SCENARIO 1a

    IIS 7.0 Web Site/Application  
    Authentication Integrated Windows authentication
    Application Pool Identity NETWORK SERVICE
    Kernel-Mode authentication Enabled (<attribute name="useKernelMode" type="bool" defaultValue="true" /> in the ApplicationHost.config file)
    Site URL Accessed with the NetBIOS name, like http://<myIISserver-NetBIOS-name>/Default.aspx

    SPNs will be required ONLY for the IIS machine account:

    HOST/<myIISserver-NetBIOS-name>
    HOST/<myIISserver-NetBIOS-name.fully-qualified-domainname> for e.g. HOST/myIISserver.mydomain.com

    ***Note: By default HOST/<myIISserver-NetBIOS-name> and HOST/<myIISserver-NetBIOS-name.fully-qualified-name> is already added for the machine account when a machine is added to a domain and HTTP forms a part of HOST. So you may not have to do anything special here for SPNs. Everything should be set by default.

    You can check the set of existing SPNs for the machine account by running the following command:

    > Setspn.exe -L <myIISserver-NetBIOS-name> or directly using a Snap-in like Adsiedit.msc.

    SCENARIO 1b

    IIS 7.0 Web Site/Application  
    Authentication Integrated Windows authentication
    Application Pool Identity Custom account for e.g. Domain1\Username1
    Kernel-Mode authentication Enabled (<attribute name="useKernelMode" type="bool" defaultValue="true" /> in the ApplicationHost.config file)
    Site URL Accessed with the NetBIOS name, like http://<myIISserver-NetBIOS-name>/Default.aspx

    The SPN requirements remain the same as above. You don't have to add SPNs like http/<myIISserver-NetBIOS-name> for the Domain1\Username1 unlike in IIS 6.0 (where we had to add an SPN of the form http/<myIISserver-NetBIOS-name> for the Application Pool identity).

    SPNs will be required ONLY for the IIS machine account:

    HOST/<myIISserver-NetBIOS-name>
    HOST/<myIISserver-NetBIOS-name.fully-qualified-domainname> for e.g. HOST/myIISserver.mydomain.com

    ***Note: By default HOST/<myIISserver-NetBIOS-name> and HOST/<myIISserver-NetBIOS-name.fully-qualified-name> is already added for the machine account when a machine is added to a domain and HTTP forms a part of HOST. So you may not have to do anything special here for SPNs. Everything should be set by default.

    You can check the set of existing SPNs for the machine account by running the following command:

    > Setspn.exe -L <myIISserver-NetBIOS-name> or directly using Snap-in like Adsiedit.msc.

     

    SCENARIO 2a

    IIS 7.0 Web Site/Application  
    Authentication Integrated Windows authentication
    Application Pool Identity NETWORK SERVICE
    Kernel-Mode authentication Enabled (<attribute name="useKernelMode" type="bool" defaultValue="true" /> in the ApplicationHost.config file)
    Site URL Accessed with a Custom Host name, like http://www.mysite.com


    SPNs will be required ONLY for the IIS machine account in the following format:

    HTTP/<site-custom-name> for e.g. HTTP/www.mysite.com

    You can add an SPN using Setspn.exe like

    > Setspn -a http/<site-custom-name> <myIISserver-NetBIOS-name> 

    where <myIISserver-NetBIOS-name> is the IIS machine account and <site-custom-name> is the custom host/host header name for the Web Site URL.

    e.g. > Setspn -a http/www.mysite.com <myIISserver-NetBIOS-name>
    *The command is NOT case sensitive

    You can check the existing set of SPNs for the machine account by running the following command:

    > Setspn.exe -L <myIISserver-NetBIOS-name>

    SCENARIO 2b

    IIS 7.0 Web Site/Application  
    Authentication Integrated Windows authentication
    Application Pool Identity Custom account for e.g. Domain1\Username1
    Kernel-Mode authentication Enabled (<attribute name="useKernelMode" type="bool" defaultValue="true" /> in the ApplicationHost.config file)
    Site URL Accessed with a Custom host/Host header name, like http://www.mysite.com


    SPNs will be required ONLY for the IIS machine account and NOT for Domain1\Username1 account unlike in IIS 6.0.

    HTTP/<site-custom-name> for e.g. HTTP/www.mysite.com

    You can add an SPN using Setspn.exe like

    > Setspn -a http/<site-custom-name> <myIISserver-NetBIOS-name> where <myIISserver-NetBIOS-name> is the IIS machine account and <site-custom-name> is the custom host/host header name for the Web Site URL.

    e.g. > Setspn -a http/www.mysite.com <myIISserver-NetBIOS-name>
    *The command is NOT case sensitive  

    You can check the existing set of SPNs for the machine account by running the following command:

    > Setspn.exe -L <myIISserver-NetBIOS-name>

    Special case of running IIS 7.0 in a WEB FARM

    If you are running IIS 7.0 server in a Web farm the KDC will not know in advance which individual server the request may go to and hence ticket decryption may fail. Hence in such a scenario instead of registering SPNs under a specific machine account use a domain account. I am not a SharePoint guy but based on what I have read on the Web this scenario is also applicable to a single SharePoint server configuration.

    There are two ways to go:

    Either

    Disable Kernel mode authentication and follow the general steps for Kerberos as in the previous IIS 6.0 version. Refer this

    Or,

    [Recommended for Performance reasons]

    Let Kernel mode authentication be enabled and the Application pool's identity be used for Kerberos ticket decryption. The only thing you need to do here is:

    1. Run the Application pool under a common custom domain account.

    2. Add this attribute "useAppPoolCredentials" in the ApplicationHost.config file.

    <system.webServer>
       <security>
          <authentication>
             <windowsAuthentication enabled="true" useKernelMode="true" useAppPoolCredentials="true" />
          </authentication>
       </security>
    </system.webServer>

    Remember there is no GUI setting for this. You need to modify the ApplicationHost.config file from

    <%SystemDrive%>/Windows/System32/inetsrv/config folder on the IIS 7.0 machine.

    3. Add the SPNs in the form:

    http/<virtualhost-name> and

    http/<virtualhost-name.fully-qualified-name>  for the Application Pool Identity.

    Ensure that we don't have such an entry for SPNs for any other account including IIS server machine account.

    ***If we have the same SPN mapped to multiple accounts (be it a machine or an user account) it leads to Duplicate SPNs and will break Kerberos.

    Hope this helps!

  • Care, Share and Grow!

    FTP changes not taking effect in IIS 7.0?

    • 1 Comments

    I was working on an FTP issue the other day on IIS 7.0 and I missed something very basic which could have resolved my issue way back had I noticed the nuances of this new model. Normally people tend to go ahead with restarting IIS services for some changes done in the configuration to make sure everything is fresh. Like running IISRESET from the cmd prompt or Restarting IIS services from the IIS manager itself. But in IIS 7.0 if you want to restart FTP services ensure you don't go by the above. This will restart IISADMIN, WAS and W3SVC services but not FTPSVC. IIS 7.0 OOB Secure FTP module runs under a separate process Svchost.exe. So doing an IISRESET won't help for FTP changes to take effect.

    Ensure you run these two commands instead:

    Start -> Run -> cmd

    At the cmd prompt:

    >net stop ftpsvc
    The Microsoft FTP Service service is stopping.
    The Microsoft FTP Service service was stopped successfully.

    >net start ftpsvc
    The Microsoft FTP Service service is starting.
    The Microsoft FTP Service service was started successfully.

    Hope this helps one who may have unnoticed this change.

  • Care, Share and Grow!

    Who knows! You may be missing these points for Kerberos authentication failures for Web applications...

    • 3 Comments

    I am sharing here some of the general + elusive + ignored + must-have info that you may want to recheck when you are troubleshooting a kerberos cum delegation failure scenario and feel like reaching nowhere near the end of the tunnel (resolution!). These are my personal checklists based on experiences of troubleshooting kerberos related gotchas. I had also posted my first article on troubleshooting kerberos issues way back in January 2007. This article is a kind of continuation to it since I still see a lot of people missing some finer points here and there. Please check this post for the general kerberos checklist.

    So here I go...

    • Kerberos was designed and is supported in Intranet scenarios. If you are trying to make it work over an Internet environment you may want to recheck other options (unless you are going ahead with Protocol transition for e.g. from Basic/NTLM to kerberos). Remember that for kerberos to work, the client (e.g. client browser) should be able to connect to the Domain Controller(KDC) to acquire the tickets. If your clients are coming over the Internet they may not be having access to the Domain Controller. Most security conscious organizations keep their DC away from Internet facing network in order to reduce the likelihood of it getting compromised. You may have to check with the firewall/proxy settings etc. and more...to make this work which I personally feel is not a good idea.

     

    • Kerberos will work for resources (client-IIS-Backend DB etc.) in the same domain or in trusted domains within the same forest. Either have mutual trust (preferable) between the domains in the forest or at least have the IIS domain trust the client's domain. If your clients are coming from a domain across the forest with an external trust we need to do extra work. Refer to this article. I am not an AD guy Embarrassed.

           Here is an excerpt from the same article:

    The Windows Server 2003 family supports domain trusts and forest trusts. We know what domain trusts are: they allow a user to authenticate to resources in another domain. Like always, all domain trust relationships have only two domains in the relationship: the trusting domain and the trusted domain. There are one-way trusts (unidirectional) and two-way trusts (bi-directional) and a Windows Server 2003 domain can establish a trust among other Windows 2000/2003 domains in the same or different forest, Windows NT 4.0 domains and Kerberos V5 realms. In Windows 2000, if users in one forest needed access to resources in a second forest, an administrator could create an external trust relationship between the two domains, which is one-way and non-transitive. This meant that in order to extend your trust to other domains in the forests you had to explicitly configure each and every one of them.

    Windows Server 2003 offers a forest trust: two-way Kerberos-based transitive trust between Windows Server 2003 forests, enabling a transitive trust between all the domains in the two forests. Forest trusts are established between the root domain of both forests and can be either one way or two way. A Few things to remember are to make sure all domain controllers in both forests are running Windows Server 2003, with a correctly configured DNS infrastructure and forest functionality level set to Windows Server 2003 mode in both forests.

     

    • Many a times you will see something as shown below when connecting to a web site over Windows integrated authentication. You may have checked all the basic settings for kerberos and things look okay, yet somehow mysteriously this is failing to work with kerberos. After three attempts it will fail with 401.

          You typed in http://www.test.com in the browser and it seems to be connecting to some other machine   name  as  shown below in the picture.

    image

    Look at the IE prompt which shows that we are trying to connect to testkrb.saurabh1.com although web site URL in the browser's address box shows we are trying to reach the site www.test.com. Ideally we should have seen "Connecting to www.test.com" and not "connecting to testkrb.saurabh1.com". Equivalently try a ping to www.test.com and see what it resolves to.

    image

    If you see such a scenario it's time to check whether the web site URL is an Alias(CNAME) or a DNS Host (A) Record. There is a known issue with using Alias for a site which may not allow kerberos to work. There are some details which I don't want to get into at this point, probably some other day. In short, it tries to look into the KDC based on the SPN http/testkrb.saurabh1.com and not an SPN of the form http/www.test.com.

    Solution:

    Server side: Either go ahead and change the DNS entry to add www.test.com as a DNS Host (A) Record and not CNAME.

    or,

    Client side: Apply this hotfix to IE browser on the client(s) (I don't see this as a good option).

     

    • I would recommended to use a host name instead of an IP address to access a web site meant for a kerberos based authentication. You may see it working just fine even with IP address in some scenarios but then it may pose problems when we have client and servers in different domains etc. You may get into an issue wherein domain2 will not give any referral back to to the client to look into domain1 for the SPN. This can occur if IP address is being used to look for a service. In such a case even after adding SPN's for IP addresses, Kerberos won't work and will fall back to NTLM.

     

    • If your web site is configured to use a non-default HTTP port like 81 instead of 80, users will access the site as http://www.test.com:81 and not http://www.test.com (browsers append ':80' as the default port if none specified). Here lies the confusion when you add SPNs for the web site. Don't have an SPN with the port number appended even if you are running your site on a non-default port.

    If the site is accessed as http://www.test.com:8080 SPN will still be of the form http/www.test.com  and  not http/www.test.com:8080.

          Refer to this article. It confuses me further but I would suggest go ahead with the default as above.

     

    • Consider a scenario wherein two applications http://servername/app1 and http://servername/app2 are running under a NETWORK SERVICE & a domain user Application Pool identities respectively .
      The SPNs requested will be http/servername in both the cases, and since we can’t have duplicate SPNs; kerberos may not work for either of the applications. We need to then either use the same Application Pool identity or separate host headers for the web sites and set SPNs accordingly. NOTE: This issue is taken care of in IIS 7.0 with Kernal mode authentication.

      Again,if you are using two web sites with same name but different ports like http://servername:81 and http://servername:82; by default IE will request a ticket for the same SPN HTTP/servername.

      We would then need an hotfix for the client machines, Refer to this.

       

    • When do we have Duplicate SPNs leading to kerberos not working?

    Duplicate SPN arises from the fact that the same SPN is mapped to multiple accounts, it may be a machine or an user account. Doesn't matter. Mapping to multiple accounts will lead to duplicate SPNs!

    *Remember: You can have multiple different SPNs registered under the same account but not vice-versa, i.e. you should *not* have the same SPN registered under multiple accounts.

     

    • IIS uses NTLM credentials when accessing a resource for a local request coming to it (i.e. client say IE, and IIS are on the same box). It may use Kerberos or NTLM from a separate client machine depending on the setup.The best way to check if delegation is working is from a client machine which is not same as the IIS server. NTLM doesn't support delegation. Kerberos does!

     

    • At times making sure all the settings on the client, IIS, AD, back-end (if any) to make kerberos work properly doesn't help, and in such cases make sure that we purge all the kerberos tickets using Klist or Kerbtray on the client. In fact if possible logoff and re-login to the client machine from where you are testing the web application for kerberos authentication so that the client is issued a fresh ticket.

     *Check the following link for my other posts related to Kerberos.

    Till next time...Martini Glass

  • Care, Share and Grow!

    Programmatically managing Virtual Server using C#

    • 3 Comments

    Virtual Server 2005 (VS2005) is a well-known tool to manage Virtual Machines (VMs) on a host server. It is a great feature to manage virtualization for hardware/software. Most often one would use the VS2005 Web Admin  interface to manage VMs. But at times (like the way it recently happened for a customer of mine) one may want to programmatically control the VMs. This would most often sound a necessity if you would like to provide end users access to manage basic VM activities like turn on/off, save state etc. etc. without giving them access to everything as in through the VS2005 Web Admin site.

    Here are some code snippets/sample web application/links in case you would like to try your hands on something like this.

    Let me show you a typical screen-shot of how VS2005 Web Admin interface looks like.

    image

    image

    To programmatically manage the Virtual machines on a host server, you need to add a reference to a COM object for your .Net application which exposes various properties/methods.

     image

    Visual Studio will add a COM Interop layer for this. You should see the following in your Visual Studio project:

    image

    Ensure we add a namespace as "using Microsoft.VirtualServer.Interop;" in the web/form page.

    Here are code snippets (in C#) to:

    a. Turn On/Restore from a saved state for a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    b. Turn Off a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_Running || vm.State == VMVMState.vmVMState_Paused)
    {
    // Turn the power off on the Guest VM
    Label1.Text = "Forcefully shutting down VM...";
    VMTask vt = vm.TurnOff();
    if (vt != null)
    vt.WaitForCompletion(-1);
    else
    Label1.Text = "Not ready for a turn off. Please wait and try again after a few seconds...";
    }

    c. Save state of a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    d. Pause a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    e. Resume a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    f. Reset a Virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    g. Shut down a virtual machine on a local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    h. Enumerate all the Virtual machines running on the local host machine.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    if (vm.State == VMVMState.vmVMState_TurnedOff || vm.State == VMVMState.vmVMState_Saved)
    {
    VMTask vt = vm.Startup();
    if (vt != null)
    vt.WaitForCompletion(-1);
    }

    i. Check various properties exposed through the COM API.

    VMVirtualServerClass vs = new VMVirtualServerClass();

    VMVirtualMachine vm = vs.FindVirtualMachine(VM_name);

    string _VMName = vm.Name;
    string _guestOS = String.Empty;
    if (vm.State == VMVMState.vmVMState_Running)
    _guestOS = vm.GuestOS.OSName;
    else
    _guestOS = "OS: n/a";
    string _memory = vm.Memory.ToString();
    .......

    j. At times if you want to manage VMs hosted on a remote machine and not on the local machine, here is what you need to do besides all the steps already mentioned above.

    private VMVirtualServerClass connectToRemoteHost(string remoteHost)
    {
    VMVirtualServerClass virtualServerCOM = null;
    Type VMVirtualServerClassType = typeof(VMVirtualServerClass);
    try
    {
    // create remote type from class identifier
    Type DCOMType = Type.GetTypeFromCLSID(VMVirtualServerClassType.GUID, remoteHost, true);
    object DCOMObject = Activator.CreateInstance(DCOMType);
    // create local object from remote object
    virtualServerCOM = (VMVirtualServerClass)Marshal.CreateWrapperOfType(DCOMObject, VMVirtualServerClassType);
    TextBox1.Text = String.Empty;
    return virtualServerCOM;
    }
    catch
    {
    TextBox1.Text ="There was an error while connecting to the remote host. Make sure that we have the necessary permissions/settings to access the remote host";
    return null;
    }
    }

                                                                                                                           (Courtesy this MSDN magazine)

    I have not included error handling in the code snippets above. Please do so when you build the actual application. Also there are many other activities that can be performed besides the ones discussed above like setting up a VM from the beginning with various components like differencing, memory, network adapter etc., changing the disk configuration of an existing machine etc. etc.

    The more you explore the more you get to control through the code using the API mentioned above.

    Here are some useful links related to the topic.

    http://msdn.microsoft.com/en-us/magazine/cc163935.aspx

    http://dotnet.sys-con.com/node/47338

    http://blogs.msdn.com/david.wang/archive/2006/04/17/HOWTO-Perform-VHD-Maintenance-Automatically.aspx

    http://blog.anildesai.net/?p=220, http://blog.anildesai.net/?p=214

    Attached is a sample ASP.Net 2.0 web application to try the above commands if interested.

    Till next time our paths cross.

    Bye!

  • Care, Share and Grow!

    Troubleshooting TS Gateway connectivity on Windows 2008, IIS 7.0

    • 10 Comments

    Here is something which is not my domain but had to learn the hard way. I recently encountered an issue while enabling Terminal Services Gateway (TSG) on Windows 2008 server. TSG is coupled with IIS 7.0 hosted on Windows 2k8 server and that's how I came into picture. TSG in simple terms is a feature using which one can connect remotely to an internal network over secure HTTPS port 443 from the Internet. Earlier Remote Desktop Protocol (RDP) connections used TCP port 3389. In many corporate environment this port may be blocked by the firewall. However now with TSG connecting on port 443 (common SSL port for http traffic) user should not get into the common issues of port being blocked. In my case we had the TSG installed as one of the roles on the server. The setup was fine.
    The only concern was that we already were using the Default Web site for some application. It can also happen otherwise, you have the TSG setup on an IIS 7 web site and if you go ahead and install let's say Exchange on top of it under the same site it may break the TSG functionality.

    When you install TSG, it creates two virtual directories called Rpc and RpcWithCert under the web site as shown below.

    image

    Under the hood it appears a call is made for

    http://<server-name>:443/rpc/rpcproxy.dll?localhost:3388 when you try to connect through TSG. So yes IIS is very much involved here.

    Now what can you do to fix this, perhaps you can install your web application (say Exchange) on some other web site and a different SSL port like 444 and have TSG site listening on port 443. Or else just the opposite.

    In my case we went with the 2nd option since we didn't want Exchange to be reinstalled again.
    But even if you use either of the above options it may not go that smoothly as it looks to be.

    You may see the error as shown below when you try to use terminal service through TSG.

    image Click on OK...

    image

    If you are seeing something like this, as a workaround create a new web site and copy the settings for the Virtual directories /Rpc and /RpcwithCert from the previous site to the the new web site. You can do this easily by copying the configuration in the applicationHost.config file.

    Here are the steps:

    1. Copy the following configuration (in the ApplicationHost.config file from C:\<Windows>\System32\inetsrv\config) from the previous site to the new site to add the virtual directories for your new web site.

    <site name="<new-web-site>" id=...>
    ...
    <application path="/Rpc" applicationPool="SomeAppPool">
           <virtualDirectory path="/" physicalPath="C:\Windows\System32\RpcProxy" />
    </application>
    <application path="/RpcWithCert" applicationPool="SomeAppPool">
            <virtualDirectory path="/" physicalPath="C:\Windows\System32\RpcProxy" />
    </application> 
    ...
    </site>

    So this will create two virtual directories in your new web site called Rpc and RpcWithCert.

    image

    Add an SSL binding for the new Web site on port 443 as well. Ensure no other site is listening on port 443.

    2. Copy the following for the previous web site in the ApplicationHost.config file to the new web site.

    This is the section contained in the Location tag for the Virtual directories /Rpc and /RpcWithCert. You need to copy this section from the location tag for the <previous-web-site> and add it to the location tag for the <new-web-site>.

    <location path="<previous-web-site>/Rpc">
            <system.webServer>
                <directoryBrowse enabled="false" showFlags="Date, Time, Size, Extension" />
                <handlers accessPolicy="Execute">
                    <add name="RPCPROXY" path="*" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\system32\RpcProxy\RpcProxy.dll" requireAccess="Execute" />
                </handlers>
                <serverRuntime uploadReadAheadSize="0" />
                <defaultDocument enabled="true" />
                <modules>
                    <add name="PasswordExpiryModule" />
                </modules>
                <security>
                    <requestFiltering>
                        <requestLimits maxAllowedContentLength="2147483648" />
                    </requestFiltering>
                    <authentication>
                        <anonymousAuthentication enabled="false" />
                        <basicAuthentication enabled="false" />
                        <windowsAuthentication enabled="true" useKernelMode="false" />
                    </authentication>
                    <access sslFlags="Ssl, Ssl128" />
                </security>
                <httpErrors>
                    <remove statusCode="401" />
                    <error statusCode="401" path="C:\Windows\system32\RpcProxy\Error401.txt" responseMode="File" />
                </httpErrors>
            </system.webServer>
        </location>
    <location path="<previous-web-site>/RpcWithCert">
            <system.webServer>
                <directoryBrowse enabled="false" showFlags="Date, Time, Size, Extension" />
                <handlers accessPolicy="Execute">
                    <add name="RPCPROXY" path="*" verb="*" modules="IsapiModule" scriptProcessor="C:\Windows\system32\RpcProxy\RpcProxy.dll" requireAccess="Execute" />
                </handlers>
                <defaultDocument enabled="true" />
                <security>
                    <authentication>
                        <anonymousAuthentication enabled="false" />
                        <basicAuthentication enabled="false" />
                        <clientCertificateMappingAuthentication enabled="true" />
                        <digestAuthentication enabled="false" />
                        <windowsAuthentication enabled="false" useKernelMode="false" />
                        <iisClientCertificateMappingAuthentication enabled="true" />
                    </authentication>
                    <access sslFlags="Ssl, SslNegotiateCert, SslRequireCert, Ssl128" />
                    <requestFiltering>
                        <requestLimits maxAllowedContentLength="2147483648" />
                    </requestFiltering>
                </security>
                <serverRuntime uploadReadAheadSize="0" />
                <modules>
                    <add name="PasswordExpiryModule" />
                </modules>
                <httpErrors>
                    <remove statusCode="401" />
                    <error statusCode="401" path="C:\Windows\system32\RpcProxy\Error401.txt" responseMode="File" />
                </httpErrors>
            </system.webServer>
        </location> 


    3. Ensure that we replace <previous-web-site> with the <new-web-site> in the following tags above:

    <location path="<previous-web-site>/RpcWithCert"> -----> <location path="<new-web-site>/RpcWithCert">

    <location path="<previous-web-site>/Rpc">  -----> <location path="<new-web-site>/Rpc">

    4. Run iisreset from the cmd prompt. Or it may also work with just restarting W3SVC service (net stop w3svc, net start w3svc).

    Go ahead and test RDP over TSG from the client. If it still doesn't work you may have to try the 5th step as below.

    5. Add the following registry entry. Run this from the cmd prompt:
    > reg add HKLM\Software\Microsoft\RPC\RpcProxy /v Website /t REG_SZ /d  <new-web-site>

    One last thing, ensure that the certificate issued to the TS server gateway is trusted on the client from where we are doing a terminal login.

    Happy troubleshooting!

    Cheers Martini Glass

  • Care, Share and Grow!

    My IIS 6.0 Mobile Manager - Manage your Web Sites, application Pools through mobile device from anywhere...

    • 0 Comments

    In May this year I had written a Web application using which we can manage basic IIS settings through Web browser from anywhere. Here is another application which I feel brings in more convenience to the end user (meant for Web administrators) since one can manage IIS through a Mobile phone.

    These are the features available through this Mobile web application.

    Application Pool related activities

    . Check the current Application Pool(s) State/Identity

    · Recycle/Start/Stop Application Pool(s)

    · Change Application Pool(s) Identity.

    Web Site related activities

    · Start/Stop Web Site(s)

    · Check features like current Web Site state, and some configuration related settings like Web Site physical path, Server Bindings, Secure Bindings, Authentication method, SSL accessibility, Application Pool etc.

    IISRESET

    · At times the only way to recover from a problem is to restart IIS services. You can restart all IIS services like IISADMIN, SMTP and World Wide Web Publishing service from any where through this application.

     

    Pre-requisites

    · You need to have .Net Framework 2.0 installed on the IIS 6.0 web server.

    Steps to deploy the application

    1. Download the ZIP file from the URL linked with this post.

    2. Extract all the contents to some physical folder on the IIS Web server.

    3. Create a new Web Site (or a new Virtual Directory under any of your existing Internet-facing Web sites) and point it to this physical path for the extracted files/folders.

    4. ***ENSURE that you create a new application Pool for this Web Site/Virtual Directory, and put the application under this application pool. In such a scenario this application will not interfere with any of your existing web applications running on the server.

    5. Open the web.config file associated with this application and modify the <appSettings> to reflect the name of your Application Pool and name of the Web site under which this Mobile Web application is running [Attached ZIP file contains a word document as well with detailed steps for deployment].

    6. This application is built using ASP.Net 2.0 Mobile controls, WMI built on top of .Net and supports most of the WAP enabled browsers.

    Here are some screen captures associated with this application. I have used an Emulator to show the same.

    image

    Application Pool related usage.

     image image

    Web Site related usage.

    image image image

    IISRESET

    image

    When you reset IIS, you won't be able to browse to the Web application for a few seconds to a minute or so, depending upon how long it takes for the IIS services to stop and then start back running.

    In this interval if you try to access the site you will see the following error:

    image

     

    Hope this adds to your convenience when taking care of bare minimum action items for the IIS web sites from anywhere across the world.

    Until next time, cheersMartini Glass

    ***This is provided "AS IS".

     


    Links for download:

    IIS Mobile managerhttp://cid-d6e3b4cd95f9d0f2.skydrive.live.com/self.aspx/Public/Mobile%20IIS%20Mananger%20resources/MobileIISManager.rar

    Steps for deploymenthttp://cid-d6e3b4cd95f9d0f2.skydrive.live.com/self.aspx/Public/Mobile%20IIS%20Mananger%20resources/Steps%20for%20Deployment-Mobile%20IIS%20manager.doc

    *It should also be available in some days @ http://www.iis.net/downloads/default.aspx?tabid=34&g=6&i=1720

  • Care, Share and Grow!

    Some tips if your IIS 6.0 World Wide Web Service (WWW) ever goes down...

    • 5 Comments

    Well, every time I try writing some thing different than IIS and for some reason I come back to it :-)

    Here is a quick troubleshooting tip for a scenario where World Wide Web service on my test IIS 6.0 box went down for no apparent reason. Here is what I started seeing when we tried to start all IIS related services. IIS ADMIN service came up fine but I wasn't lucky enough with WWW Sad

    image

    From the Services console I got this error message when tried to start WWW service:

    image

    Now this was weird, I remember everything was fine just few minutes ago. I wondered how we could resolve the issue.

    Event log showed the following:

    Event Type:    Error
    Event Source:    Service Control Manager
    Event Category:    None
    Event ID:    7023
    Date:        7/25/2008
    Time:        6:59:50 AM
    User:        N/A
    Computer:    SAURABSI-SEC
    Description:
    The World Wide Web Publishing Service service terminated with the following error:
    Access is denied.

    Now, this started making some sense. It was quite apparent that there was a permission issue. But then I was a local admin on the box and I had not changed any file permission recently, at least not in the last few minutes for sure.

    I tried running Process Monitor from www.sysinternals.com. It is a handy tool to troubleshoot permission issues. Unfortunately I couldn't see any ACCESS DENIED anywhere in the log collected via this tool. Now if there was no access denied anywhere what else could have led to such an error message!!!

    I ran DebugView while reproducing the WWW startup issue.

    It showed the following:

    image

    I noticed this in the above log:

    image

    Now it was clear that there were no issues as far as accessing this metabase file was concerned. Had there been a permission issue to access this file it should have been captured by the Process Monitor utility. Also since IISADMIN was up and running it was sure that metabase was fine and was accessible. I wondered if there was something within this file, maybe some key/property etc. which was giving the problem.

    I went ahead with Metabase Explorer (also called as MBExplorer, part of IIS 6.0 Resource kit) and tried to read through the various hierarchy in the metabase. The moment I tried to launch MBExplorer it gave the following error:

    image

    This was getting interesting now :-). I clicked on Yes and launched the utility anyway.

    While scanning through the various structures within MBExplorer I got another similar alert when I reached the following location:

    image

    I knew now that this subkey was having the permission issue for sure. However I could not even import this setting from any other machine since I could not even rename the key !!

    Looked like even administrator account had no permission on this key. It could not even be inherited from its parent level using MBExplorer.

    So, after some thought this is what I did. Stopped IISADMIN service and opened metabase.xml file in a notepad.

    Found the section which described the Filters subkey properties as shown below:

    image

    The only way to change the ACL on this key was to remove the AdminACL attribute such that it would inherit the same from its parent level, i.e. W3SVC level in the above MBExplorer window. I deleted the above AdminACL attribute completely, saved the file and gave a restart with my fingers crossed ;-). I had a backup.

    Hurray!!! this is what I got finally.

    image 

    image

    Later on, found that while playing with permissions for compression filter, accidentally the ACL permissions for Administrators and IIS_WPG was removed, and I was a member of both these two groups :-(

    image

    Finally all that ends well is well, I am a happy man now Tongue out.

    Hope this helps someone stuck in a similar situation...

    CheersMartini Glass

  • Care, Share and Grow!

    Case Study: Much ado about Browser's HTTP connection

    • 6 Comments

    Here I will be going in-depth on how a browser maintains HTTP connections with the Server. Something which a Web Developer should be aware of. My main aim is to show some of the tidbits of how a connection is made, how it is reset (from client or server) and some of the connection limitations.

    Let's say you have a web application set to run with restricted access. Now assuming that you do not want client browser to renegotiate user's credentials every time it accesses a web resource like .css, .js, .aspx etc, you would like to have a seamless one-time authentication challenge when the user visits the page the first time. This is achieved by IE appending the HTTP header 'Connection: Keep-alive' along with the HTTP request to the server. Note that at times a single page may include tens (sometimes hundreds) of images, each initiating a separate request to the server. If the server is set to honor HTTP Keep-Alive's, a client can maintain an open connection with the server, rather than re-opening the client connection every time with each new request. This will boost up the overall performance of the Web application.

    So when a client, say IE requests a web page for the first time, it opens a new connection from some random client port to the HTTP port (By default it is port 80) on the IIS (or any) web server. Now a days most modern browsers like IE/Firefox ask the server to keep the connection open across multiple requests. This is what is HTTP Keep-Alive is all about. If we do not have it in the request header, a browser will make multiple connections for various resources. Let's say you have a Web page that has some graphics and you also need to download some JavaScript/CSS files etc. All these are independent components which have to be downloaded from the web server and depending upon the Keep-Alive header, may have to be downloaded to the client on multiple connections which will need re-authentication every time.

    Remember, whenever IE opens a new connection to request a web resource it will be challenged by the server (if it is for a restricted access) and it has to be re-authenticated. This is costly and redundant if all the resources are coming from the same host.

    In IIS web server you can enable/disable this option as shown below:

    image

    Let's look at the network traffic and see how it looks.

    Here's how Client sends a web request. Note the HTTP Keep-alive in the request header.

    image

    Depending upon whether your web site is designed to provide anonymous access or restricted access, here's how the server responds back. Since in our case IIS Web site is set to restricted access it will send back the response as 401 the first time, with the list of supported Authentication methods.

    image

    The client sends back the requested credentials/tokens (depending upon the authentication method), on the same connection this time. Note, had the Keep-Alive not been supported by the IIS web site, it would have sent back a response header ('Connection =close') and would have closed the connection with the client as shown below.

    image

    If IIS has Keep-Alives enabled it will not send the 'Connection: close' header in its response leading to the same connection being used for subsequent requests (until there are other factors coming in which I will talk about shortly). Also notice that since the same connection is being used for subsequent requests by the client, the source and destination ports will remain the same.

    Client's HTTP Web request:

    image

    Server's HTTP Web response:

    image

    Here I am not going to delve deeper into how IE request is authenticated by IIS. You can refer to this KB for more information on this topic.

    Now any related requests corresponding to the same web page (like embedded Image, css files) etc are made on the same connection by the browser. Notice the ports and the Connection header for further requests on the same connection.

    image

    Let's see another trace wherein HTTP Keep-Alive is disabled in the IIS web site.

    Client sends a request (as usual with 'Connection =Keep-Alive' in the request header):

    image

    Server responds back with a 401 the first time since it's a restricted access. Forget the status code for now.

    image

    Notice that this time IIS responds back with a 'Connection: Close' header in its response. So this means that for further requests IE has to initiate a new connection, which means a new source port will be used this time.

    Here it is. Notice the source port has changed from 60122 to 60123.

    Client sends another request:

    image

    Server responds back with 200 status code this time. Notice the 'Connection =close' again this time in the server's response.

    image

    So next request for any resource by the browser will again be on a new connection.

    Remember an IE browser can open a maximum of two concurrent connections (by default) to a single host. Hence if you have lot of images etc that have to be downloaded as part of the web page, you will see them coming slowly two at a time. What I mean is that an IE client will open two simultaneous connections to the same host, let's say www.abc.com and request for resources associated with the page. This is as per the HTTP specifications. IE will wait until the two connections are released or if they are reset for any reason for any further requests. Check this out.

    Firefox by default also opens two simultaneous connections to the same host. You can increase the concurrent connection limit for IE as per this KB. Also check this for tweaking Firefox.

    It's the same reason why you may not be able to make multiple AJAX calls from the same client. You can have as many objects open and waiting as you wish, but the browser will only work on two at a time while the others wait for one of the two active requests to finish.

    **In IE8, considering the strong increase in popularity of AJAX applications the number of connections per host has been increased to 6 from 2 for HTTP 1.1 server for broadband connections. Check this specification.

    What will happen if we have let's say IFRAMES in a Web page. Let's thinks of such a scenario:

    Let's say I have an HTML page which uses IFRAME's and each IFRAME makes a call to some host for a resource. And each of these web requests are long-running. It may be a long executing task at the server end or downloading of large image files etc. Now since we now know that IE has a default limitation of 2 concurrent connections to a host (web site) by default, let's see how will the response be.

    You will notice that responses from the IFRAMES come two at a time if they are made to the same host. Every individual IFRAME request takes up one connection of the browser. Basically once two connections are already made to the same host, IE has reached its concurrent connection limit for that host, and hence other IFRAME requests will have to wait if they are being made to the same host as the other two connections.

    If on the other hand you have multiple IFRAMES and not more than two are requesting resources from the same host, all of them will open new connections simultaneously to their hosts and get the response accordingly depending on other factors like request execution time/network congestion etc.

     

    *Another thing that one needs to keep in mind is that IE6 will reset an existing connection if it received a 404 as a response from the server. IE7 (going forward IE8..) will not show the above behavior.

    What I meant can be better understood by analyzing the HTTP traces below:

    An IE Client sends a request:

    image 

    Server responds back with a 404, assuming request is authenticated this time but resource '/Graphics/main.css' is not found.

    image

    Now what should happen? Should the same connection be used for further requests? No

    IE initiates a fresh connection to the server for the next request (here '/StyleSheet.css') after server has returned 404. This happens even though HTTP 1.1 is being used. Notice the source port is changed this time. New port means a new connection.

    image

    What happens is that initially IE6's WinInet socket connection attempts to download the missing file. Server returns a 404 as a response. But due to the nature of WinInet design it will not immediately return the socket back to the keep-alive pool for about 2 minutes. Hence this will spur a new connection attempt on a new socket/port.

    WinInet does not reuse the port by default after a 404 if the socket is in a TIME_WAIT state. TIME_WAIT means the port is still half-open. One side hasn't completely terminated the connection. WinInet in IE6 returning used sockets back to the keepalive pool is less than optimal, and it can take up to 2 minutes for a released socket to go back to the pool (and this can cause 401s, client hangs due to max connections reached, etc).  WinInet in IE7 went through a rewrite, and this section of the code was cleaned up quite a bit, causing the behavior difference between IE6 and IE7.

     

    So far we had been seeing how the client behaves when it comes to initiating/persisting a connection. what about the server?

    When a browser establishes a connection with the server, the connection is open as long as the transaction is going on between them. Once the client has received what it needed, it can close the connection or leave it open for further requests. Most browsers ask the server to keep the connections open using their 'Keep-alive' feature. Now since we know that a connection is a costly affair, it doesn't make sense to keep it idle for a long time. Here in, a Server can pitch in and reset the connection from its end if the connection has remained idle for a long time. This is set at the server side by using the property called "Connection timeout" of the Web site.

    image

    Here is how the network trace will look like:

    image

    image

    After ~120 seconds idle time (as in the pic above), server will send a TCP RESET to close the inactive connection.

    image

    So you see not all reset from the Server side is bad, it helps ensure the server does not get into any DoS attack situation. There is always someone to clean up the litters ;-)

    L8Rz,

    >SS

  • Care, Share and Grow!

    SSL Troubleshooting for IIS Web Sites contd...

    • 17 Comments

    Recently a colleague of mine was working on a customer's case which was a Critical level incident. High pressure job, huhh!

    The issue was with SSL not working for one of their web sites. They were seeing "Page cannot be displayed" when trying to access this site over SSL. It worked just fine over HTTP.

    In the System event log we were seeing this intermittently:

    Event Type: Error
    Event Source: W3SVC
    Event Category: None
    Event ID: 1114
    Description:
    One of the IP/Port combinations for site 'NNNNN' has already been configured to be used
    by another program. The other program's SSL configuration will be used.

    We troubleshot on this issue for hours without luck :-(. We tried all the steps I guess as mentioned here .

    Here is what all we tried:

    • Checked the Certificate properties to ensure it was a valid one. It was good.
    • Yet, replaced the current certificate with a new one, still no luck.
    • Here customer had all the sites running under different IP addresses. Rest of the other sites were working over SSL, except this one :-(.
    • We ran SSLDiag which gave a misleading error.
    • We tried running the site on a different SSL port, still no luck.
    • We setup the securebindings metabase property for the web site in question, still no luck.
    • We ran netstat -ano to check for any other process listening on this port, everything looked clean. refer this.
    • We disabled all the 3rd party non-MS services, restarted Windows Server in selective startup mode, no luck.
    • We installed Windows Server 2003 Service Pack 1 32-bit Support Tools on the server, ran the httpcfg query iplisten. It gave a clean output, no specific IP entries listed by it.
    • Restarted IIS/HTTP services umpteen number of times during the course of troubleshooting, no luck whatsoever. Even reboot was done a couple of times.

    Finally after few hours of troubleshooting we decided to run this site on a different IP address (we had thought of this earlier but our customer was under a constraint) and hurray it worked this time!!!. Now everything was set but we had a lingering question in mind as to why, why, why this site did not work on that IP address we had. It had an entry in the Advanced TCP/IP Settings, was a valid one in all the sense to our best knowledge.

    Finally we figured out that there was a problem with the IIS SSL listener.

    To get a list of IP and port configuration binded to a certificate, run "httpcfg query ssl". Here is an excerpt from a technet article:

    The HTTP API enables applications to communicate over HTTP without using Microsoft Internet Information Services (IIS). Applications can register to receive HTTP requests for particular URLs, receive HTTP requests, and send HTTP responses. The HTTP API includes SSL support so applications can also exchange data over secure HTTP connections without depending on IIS. It is also designed to work with I/O completion ports.....Such meta-information is maintained by the HTTP API in a metastore, and is used to locate certificates for certificate exchange in HTTPS sessions.

    Below is a sample of a working and non-working scenario:
    ------------------------------------------------------------------------------

    \Program Files\Support Tools> httpcfg.exe query ssl

    Working scenario:

    IP                      : 192.168.100.118:443
    Hash                  : c96667684997887f 5b889b7b3f737c8c4da5f16
    Guid                  : {4dc3e181-e14b-4a21-b022-59fc669b0914}
    CertStoreName           : MY
    CertCheckMode           : 0
    RevocationFreshnessTime : 0
    UrlRetrievalTimeout     : 0
    SslCtlIdentifier        :
    SslCtlStoreName         :
    Flags                   : 0

    Non-working scenario:

    IP                     : 192.168.100.234:443
    Hash                :
    Guid                : {00000000-0000-0000-0000-000000000000}
    CertStoreName : (null)
    CertCheckMode : 0
    RevocationFreshnessTime : 0
    UrlRetrievalTimeout : 0
    SslCtlIdentifier : (null)
    SslCtlStoreName : (null)
    Flags : 0

    Here Hash will have the same value as the Thumbprint in your SSL certificate. You will notice that the Guid is all zero in a non-working scenario. You may see the Hash either having some value or blank. Even if we remove the certificate from the web site, and then run "httpcfg query ssl", the site with all Guid as all "0" will still be listed. If you see the GUID as "{0000...............000}, there is a problem.

    We need to remove this entry by running the command "httpcfg delete ssl -i <IP:Port Number>". In the above example, we need to type "httpcfg delete ssl -i 192.168.100.234:443". Once we remove it, then we need to reinstall the certificate back on to the web site.

    Also once certificate is installed, in the cmd prompt type in "httpcfg query ssl" to confirm the GUID is no longer all 0.

    This fixed the issue for the web site on the failing IP address.

    Hope this helps someone.

    Till next time, Cheers!

     

  • Care, Share and Grow!

    My IIS 6.0 Web Manager - Manage your Web Sites, Application Pools from any where on the Web.

    • 9 Comments

    A Web administrator has to have access to the IIS server in order to ensure that any diagnostic/preventive measures can be performed at any point of time. One has to ensure all the web sites are running up and fine during the course of a day. Activities like recycling Application pools, starting/stopping Web sites etc. are an essential part of this process. This may be most painful when you are away having a good time and you get a call that the web sites are having performance issues etc, and you are required to ensure they are recycled, restarted etc. etc.

    I have written this Web application to ensure one has access to their IIS 6.0 Web server from any part of the world. I have used WMI features built on top of .Net. It has the following features at this point.

    Application Pool related activities

    · Recycle/Start/Stop Application Pool(s)

    · Change Application Pool Identity.

    · Check features like Application Pool Recycling options, Current state of an Application Pool and current Application Pool Identity.

    · Enumerate an Application Pool to see the Web applications running underneath it.

    Web Site related activities

    · Start/Stop Web Site(s)

    · Check features like current Web Site state, and some configuration related settings like Web Site physical path, Server Bindings, Secure Bindings, Authentication method, SSL access, Application Pool etc.

    IISRESET

    · At times the only way to recover from a problem is to restart IIS services. You can restart all IIS services like IISADMIN, SMTP and World Wide Web Publishing service from any where through this application.

    There are tools available like MS Administration site, but it had somewhat limited features in my opinion. I intend to modify the existing features in my application as time permits.


    Pre-requisites

    · You need to have .Net Framework 2.0 installed on the IIS web server.

    · If AJAX-enabled version of this application is deployed, you need to have Microsoft ASP.Net 2.0 AJAX Extensions 1.0 installed on the server for it to work.

    Steps to deploy the application

    1. Download the ZIP file attached with this post.

    2. Extract all the contents to some physical folder on the IIS Web server.

    3. Create a new web site (or better in my opinion, a new virtual Directory under any of your existing Internet-facing Web sites) and point it to this physical path for the extracted files/folders.

    4. ***ENSURE that you create a new application Pool for this Virtual Directory, and put the application under this application pool. In such a scenario this application will not interfere with any of your existing web applications running on the server.

    5. This application is built using ASP.Net 2.0 and has two flavors, AJAX-enabled and non-AJAX based. if you are using AJAX-enabled application you need to ensure Microsoft ASP.Net 2.0 AJAX Extensions 1.0 is installed on the server.

    6. Open the web.config file associated with this application and modify the <appSettings> to reflect the name of your Application Pool and name of the Web site under which this application is running [Attached ZIP file contains a word document as well with detailed steps for deployment].

    I have covered the essential features required for a web server management and plan to modify it with more granular features with time.

    Here are some screen captures related to usage

    image

    image

    image

    image

    image

    ****Ensure the application pool Identity entered forms a part of Local IIS_WPG group on the server.

    image

    image

    Click on IIS Reset shown below to restart all IIS services like IISADMIN, FTP, SMTP and WWW.

    image

    When you reset IIS, you won't be able to browse to the Web application for a minute or so, depending upon how long it takes for the IIS services to stop and then start back running.

    In this interval if you try to access the site you will see the following error:

    For AJAX-enabled version, you will get a pop up as shown below:

    image

    For Non-AJAX version you will see the following page:

    image

    At any point you can check the status of the selected Application Pool and the selected Web site.

    image

    image


    This is provided "AS IS".

    Any constructive feedback is appreciated ;-)

    Till next time, Cheers! 

     


     

    Links for download:

    AJAX enabled version: http://cid-d6e3b4cd95f9d0f2.skydrive.live.com/self.aspx/Public/AJAX%20enabled%20version.rar

    Non-AJAX version: http://cid-d6e3b4cd95f9d0f2.skydrive.live.com/self.aspx/Public/Non-AJAX%20version.rar

    Steps for Deployment: http://cid-d6e3b4cd95f9d0f2.skydrive.live.com/self.aspx/Public/Steps%20for%20Deployment.doc

    *You can also download the AJAX version from here www.iis.net/downloads

  • Care, Share and Grow!

    Change in IIS MMC setting may cause unwanted restarts of W3SVC

    • 5 Comments

    Recently we have discovered an issue with IIS Manager wherein changing settings in a certain way may cause unexpected restart of World wide Web Publishing Service. And this may happen before you realize until you go back to the Application event log and find entries corresponding to the W3SVC restart event as shown below:

    Event Type:    Information
    Event Source:    ASP.NET 2.0.50727.0
    Event Category:    None
    Event ID:    1023
    Date:        4/22/2008
    Time:        6:35:20 AM
    User:        N/A
    Computer:    SAURABSI-SEC
    Description:
    Restarting W3SVC

    Event Type:    Information
    Event Source:    ASP.NET 2.0.50727.0
    Event Category:    None
    Event ID:    1025
    Date:        4/22/2008
    Time:        6:35:25 AM
    User:        N/A
    Computer:    SAURABSI-SEC
    Description:
    Finish restarting W3SVC

    Also as part of the above symptom, you will see IIS mmc paused like in a hung state (you may see a transient hour glass).
    So what are the steps you need to be cautious of especially in a production environment?

    First, a little background...

    If you intend to change the version of ASP.Net through IIS manager by going to the Web Site properties --> ASP.Net tab, you should be fully aware that W3SVC service will get restarted in order to reflect the change. Restarting of W3SVC will lead to all the application pools getting recycled along with it, hence leading to all your currently running web applications to spawn new worker processes for further requests. This is by design and if you want to circumvent the recycling of other application pools not corresponding to your website, you should have a way to control W3SVC restart after the version change. You can do so by following this excellent post by Jerry Orman.

    So far so good. But I have something else to disclose too.

    Let's say you go to the IIS manager, select a Web site, go to its properties and poke around with different settings. At some point you visit ASP.Net tab (even if you do not modify any settings like current ASP.Net version) and move out from there to some other tab. On this tab if you do any change(s), and you click on Apply and then OK (in the same order) bang!, your W3SVC service will restart and all your application pools will recycle subsequently as a result of it.

    Here are some quick steps to reproduce the problem, follow it to believe it.

    1) Open IIS manager (Start -> Run -> inetmgr.exe)
    2) Select any website --> right click and select properties
    3) Click on ASP.NET TAB - do not change or modify anything - just click on the TAB.

     image

    4) Now click on any other TAB and change some values (for example: go to website tab and change port to say 8080 from 80)
    5) Hit apply
    6) Hit OK
    7) This will restart W3SVC and you will see following event in application event logs.

    In the above steps the key points are basically to visit the ASP.NET TAB and then click on Apply and then OK to reproduce the issue.

    Why is this behavior?
    ===================
    The reason this behavior occurs is in the code where we make a check to see if ASP.NET runtime version is changed and if yes we need to fire W3SVC restart. We are comparing the selected version of ASP.NET TAB with what has been changed incorrectly. There is an additional code in place that checks for the QFE versions of the ASP.NET framework installed, but in the IIS manager UI, we only give an option to either select 1.x.xxxx or 2.0.xxxxx. We really don’t care about the QFE versions installed after that. But the code that gets executed on OK or APPLY does. For the 1st execution (i.e. click on APPLY) it’s correctly able to remove the QFE information from the version string it retrieved (i.e. 2.0.xxxxx, instead of 2.0.xxxxx.QFE), the check is successful noting that nothing is changed in ASP.NET TAB, and hence no restart of W3SVC is required. But now when we go ahead with 2nd execution (i.e. click on OK) the same code executes again and this time the version information string is truncated further to RTM (i.e. to 2.0 from 2.0.xxxxx) and thus the check fails (ASP.Net version is changed from 2.0.xxxxx to 2.0), which incorrectly indicates that ASP.NET runtime version has been changed and thus calls a restart of W3SVC.

    In short, you could click anywhere in UI all day long, but for you to reproduce this issue, you need to
    1) Go to ASP.NET UI once.
    2) Click APPLY and OK (both in that order). If you only click OK then the code gets executed only once and hence correctly and would not restart the w3svc.

    Latest update on this:

    We have informed the Product group about this issue. A Knowledge base article is in work.

    Laterz!
    Saurabh

  • Care, Share and Grow!

    IIS ASP.Net Developer Support Group comes with its own Weblog

    • 1 Comments

    Recently we have come up with a dedicated blog site for IIS support group. Our aim is to include topics which will be of relevance to end users with regard to troubleshooting, and technical readiness for IIS ASP.Net including the latest in offering i.e. IIS 7.0. Using this as a medium we will try to provide information on matters closely related to IIS and Web applications built in ASP/ASP.Net etc. I am myself being one of the bloggers for this site http://blogs.msdn.com/webtopics .

    Watch out for some useful posts to come in future from the entire group here...

  • Care, Share and Grow!

    Unable to access IIsCertMapper object through ADSI

    • 7 Comments

    Today, I was working on an issue where we were trying to add mapping for client certificate for a windows account using ADSI and VBScript. Something similar as below:

    <%
      Dim CertObj, vCert
      vCert = Request.ClientCertificate("CERTIFICATE")
      Set CertObj = GetObject("IIS://<path>/IIsCertMapper")
      CertObj.CreateMapping vCert, "MYACCT", "MYPASS", "My Name", True
    %>

    where path is in the format: "<IISServerName>/W3SVC/<Identifier>"
    However, script was failing on the 3rd line,

    Set CertObj = GetObject("IIS://<path>/IIsCertMapper")

    We get “Path not found error”, 80070003. Now this is an expected behavior if this object type is not found in the IIS's metabase. You can search for the above in metabase.xml file. Ideally this should have been there, but since we did not have this, to make it work we had to manually create this for a website in question.

    You can try this to have the necessary object type:

    > cscript adsutil.vbs CREATE w3svc/1/IIsCertMapper  "IIsCertMapper"     

    Microsoft (R) Windows Script Host Version 5.6

    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

    created "w3svc/1/IIsCertMapper"

    >

    Here 1 is the identifier for the website in question and "IIsCertMapper" is the Object type.

    Once done, try restarting IIS services as like (IISRESET from the cmd prompt).

    Open the metabase.xml and now we should see an entry as below:

    <IIsCertMapper    Location ="/LM/W3SVC/1/IIsCertMapper"
        >
    </IIsCertMapper>

    Once this entry was created in the metabase.xml we should be able to access this object via ADSI script. This is not only applicable to a specific object type like IIsCertMapper but any other object type associated with IIS.

    Hope this helps someone, somewhere, somehow ;-)

  • Care, Share and Grow!

    Enabling Active Directory Isolation mode for FTP to work for trusted domain users

    • 1 Comments

    Let's consider a scenario wherein we have an FTP site hosted on an IIS Server and we are trying to setup the site to work in Active Directory (AD) Isolation mode. Now things should work just fine if we have the setup done properly. I have talked about general setup and common issues with FTP sites here.

    This should ideally work fine for the domain users which are in same domain as IIS (Let's say Domain 1). We should know AD isolation mode is supported for domain users only and not local users. Now consider a scenario wherein you want to have FTP working for users from a different domain (Let's say Domain 2).This is not as simple as just running the iisftp.vbs script on the IIS server to set FTP Root and FTP directory properties for domain2 users.

    When you try to set this up you will see something like this:

    C:\WINDOWS\system32>cscript iisftp.vbs /setadprop test1 ftproot "C:\inetpub"
    Microsoft (R) Windows Script Host Version 5.6
    Copyright (C) Microsoft Corporation 1996-2001. All rights reserved.

    User test1 was not found in Active Directory.

    [Here assuming test1 to be a domain 2 account and we are running this script on the IIS server which is in Domain 1]

    This is expected since test1 is not a domain 1 account, and hence iisftp.vbs won't be able to find it in the Active Directory. By default, iisftp.vbs will look into the domain where it is running and since we are running this on IIS's domain (i.e. domain 1) it will fail. this is its limitation.

    To ensure we can set the FTP root and FTP directories for different domain users (to which IIS doesn't belong), ensure this domain has a trust relationship with IIS's domain first.

    Also to set the above properties we need to manually run iisftp.vbs on a machine which belongs to domain 2. You may see this error when you run the script:

    Could not create an instance of the IIsScriptHelper object.
    Please register the Microsoft.IIsScriptHelper component.

    We need to ensure we have these two files IIsScHlp.wsc and IIsFtp.vbs copied locally from a working machine (where iisftp.vbs works for e.g. the IIS server). So if IIS is not installed on a machine in domain 2 you can just copy these two files from the IIS server to the domain 2 machine and register the script IISScHlp.

    C:\FTP>regsvr32 iisschlp.wsc

    You will get an alert like this:

    image

    Once done you can run the iisftp script in there.

    Now once we have the iisftp.vbs running fine on a domain 2 machine, using admin privilege you can set the FTP root and FTP directory for the domain 2 users. iisftp.vbs does the changes to the account in AD and has nothing to do with IIS metabase settings.

    So after this you can follow the /setadprop and /getadprop to set/get the FTP root/directory settings for domain 2 users.

    Remember that in this case the FTP root should be a network share like \\server1\... etc.

    Reason being that FTP service which is running on IIS server in domain 1 should be able to access this location (or share). If we give a local path on a machine in domain 2, IIS FTP service has no way to access it since it is running on IIS server in domain 1.

    Once done if you access the FTP site from any of the machine, let's say from anywhere on domain1 or domain 2 you should be able to access the site with your own domain credentials (could be a domain1 or domain2 account) provided there is an FTP root and FTP directory for your account set in either domain 1 or domain 2 as mentioned above.

    Happy FTP' ing ;-)

  • Care, Share and Grow!

    Unable to correctly display Chinese (Unicode) characters in Excel when opened through ASP.Net page

    • 9 Comments

    Recently I was working on an issue wherein one of our customers was trying to stream data from their web application in CSV format for it to be recognizable and opened through Excel on the client's end. Basically they were setting content-type and content-disposition to open the file outside the browser and open it in MS-Excel. Everything would have worked had they not used Chinese characters as data in this case.

    Something like this:

    Page.Response.Clear()
    Page.Response.ContentType = "application/vnd.ms-excel"
    Page.Response.ContentEncoding = System.Text.Encoding.UTF8
    Page.Response.AddHeader("Content-Disposition", "attachment; filename=ExportData.xls")

    And later in the code they were reading the column headers and column row in CSV format into a string which will get flushed as a response output.

    Something like this:

    'Output Column Headers as 

            columnHeaders = "HEADER1" + Chr(9) + "HEADER2"             
            columnHeaders = columnHeaders & Chr(13) & Chr(10)

    [Here, Chr(9), Chr(10) and Chr(13) correspond to Tab, Linefeed and Carriage Return characters in ASCII respectively to adhere to CSV format]

    Page.Response.Write(columnHeaders)
    Page.Response.Write(Chr(10))

    and

    'Output Column Row as
    columnRow = ""

    After populating the columns in various strings we do this to adhere to CSV format:

    columnRow = coulmn1 + Chr(9) + column2

    columnRow = columnRow & Chr(13) & Chr(10)

    ...............

    Page.Response.Write(columnRow)        ' Finally display the data

    Now if you see above this should work if we try to open the file using Excel. Although if we are sending the data in UTF-8 encoding (let's say for Chinese characters), Excel doesn't recognize it correctly and opens it in ASCII. In normal scenarios the above functionality will not cause issues but if we are using any Unicode characters like Chinese the data will be wrongly displayed in Excel. You may see "???????" etc. Although it may display perfectly fine in the webpage control , let's say in a datagrid.

    The resolution to such an issue is to switch from UTF-8 to Unicode and add Unicode byte leader
    to the start of the file. Excel will recognize the byte-leader as an indication of Unicode data coming in, and correctly read the file as Unicode. This way Unicode characters like Chinese can be preserved when opened through Excel.

    Here is something you can try:

    Dim rgByteLeader(1) As Byte
            rgByteLeader(0) = &HFF
            rgByteLeader(1) = &HFE

            Page.Response.Clear()
            Page.Response.ContentType = "application/vnd.ms-excel"
            Page.Response.ContentEncoding = System.Text.Encoding.Unicode
            Page.Response.AddHeader("Content-Disposition", "attachment; filename=ExportData.xls")

    ' Write out the Unicode header FFFE so that Excel recognizes the file as Unicode()
            Page.Response.BinaryWrite(rgByteLeader)

    'Output Column Headers as before

            columnHeaders = "HEADER1" + Chr(9) + "HEADER2"             
            columnHeaders = columnHeaders & Chr(13) & Chr(10)

            Page.Response.Write(columnHeaders)
            Page.Response.Write(Chr(10))

     

    'Output Column Rows as before
            columnRow = ""

            .............

           columnRow = coulmn1 + Chr(9) + column2
           columnRow = columnRow & Chr(13) & Chr(10)

           Page.Response.Write(columnRow)

           .....

           Page.Response.End()

     

    I am no Globalization/MS-Excel expert but I had a tough time researching on this issue so thought of sharing it with others. Hope this helps!

  • Care, Share and Grow!

    HTTP to HTTPS (SSL) Web Request Redirection

    • 13 Comments

    We often get requests from our customers asking how they can seamlessly redirect web requests from HTTP to HTTPS, i.e. how they can redirect a non-SSL request to an SSL based request. Recently a colleague of mine got a similar issue and we decided to use some existing scripts that we had in our database. Unfortunately none could meet the requirement.

    Basically the existing scripts redirected an HTTP request to another URL and that URL was not the original request user had asked for. It took us to let's say the homepage of the site and from there one again has to click on specific links to reach the desired page. So this will be a problem for users who have book-marked their desired web page.

    Here are the steps you can try for your website such that all HTTP requests get translated to HTTPS requests and have the original URL intact.

    Here are two sample codes which one can try. Both of them should *hopefully* work. First one uses VBScript in an ASP page and second one uses Javascript in an HTML page.

    a).

    redirectSSL.asp

    <%@ Language=VBScript %>
    <% 
    strQueryString = Request.QueryString
    sslPort = null
    PlainURL = Right(strQueryString, len(strQueryString) - 4)
    FindLastCOlon = InStrRev(PlainURL, ":")
    FirstPart = Mid(PlainURL, 1, FindLastColon - 1)
    LastPart = Mid(PlainURL, FindLastColon)
    LastPart = (Mid(LastPart, InStr(LastPart, "/")))
     
    'If the SSL Port is not the default 443, you need to uncomment the line below, by default SSL port is 443.
    'sslPort = ":449"
    if (sslPort = null) then
        url= FirstPart & LastPart
    else
        url = FirstPart & sslPort & LastPart
    end if 
    strSecure = Replace(url, "http:", "https:", 1, 1)
    Response.Redirect strSecure
    %> 

    Steps:

    -- Copy the above code and put in a file redirectSSL.asp under your Website root directory for which you want redirection to work.

    -- Force SSL on the web site. To do that follow the steps mentioned below:
          - Go to --> <Your_Web_Site> -> Properties -> Directory Security -> Edit (Secure Communications)
          - Select Require secure channel (SSL).

    -- Uncheck "Require secure channel (SSL)" option for the redirectSSL.asp page. To achieve that:
         - Go to --> <Your_Web_Site> -> redirectSSL.asp -> Properties -> File Security -> Edit (Secure Communications)
         - Uncheck Require secure channel (SSL).

    So now we are forcing SSL to be used for all of the website contents except the redirectSSL.asp page which can be accessed over non-SSL (HTTP).

    -- In the IIS manager -> <Your_Web_Site> -> Properties -> Custom Errors, modify the entry for 403;4 to look like this:

    image

    Now if you try to browse to some URL, let's say http://www.abc.com/asp/test/ssl/iistsart.htm, you will be redirected to https://www.abc.com/asp/test/ssl/iistsart.htm, without you requiring to modify HTTP to HTTPS.

    If your SSL port is not the default port 443 then you need to un-comment a line in the code as mentioned in there and it will redirect the request to the appropriate URL with corrected SSL port embedded in it.

    b).

    redirectSSL.html

    <html>
    <head>
     
    <script language="javascript">
     
    var currentURL=location.href.substring(0,5)
     
    if(currentURL.toLowerCase()!="https")
    {
    currentURL = location.href.substring(4,location.href.lastIndexOf(''))
    var portStartPos = currentURL.lastIndexOf(':')
    var sslPort = null
    if(portStartPos!=0)
    {
    var relativeURL = currentURL.substring(portStartPos)
    var postPortURL = relativeURL.substring(relativeURL.indexOf('/'))
    var URL = currentURL.substring(0,portStartPos)
    // If you are running your SSL site on a non default port other than 443 then uncomment the next line and add the right Port number.
    //sslPort = ":447"
    if(sslPort == null)
        currentURL = URL + postPortURL
    else
        currentURL = URL + sslPort + postPortURL
    }
     
    var targetURL = "https" + currentURL
    window.location = targetURL
    }
    </script> 
     
    </head>
    </html>

    Steps:

    -- Copy the above code and put in a file redirectSSL.html under your Website root directory for which you want redirection to work.

    -- Force SSL on the web site. To do that follow the steps mentioned below:
          - Go to --> <Your_Web_Site> -> Properties -> Directory Security -> Edit (Secure Communications)
          - Select Require secure channel (SSL).

    So now we are forcing SSL to be used for all of the Website contents.

    -- In the IIS manager -> <Your_Website> -> Properties -> custom Errors, modify the entry for 403;4 to look like this:

    image

    You need not follow the step below since we are using File Type for custom error page and not a URL as shown above in the picture. If you select URL as Type above then you will need to follow the step below.

    "-- Uncheck "Require secure channel (SSL)" option for the redirectSSL.html page. To achieve that:
          - Go to --> <Your_Web_Site> -> redirectSSL.asp -> Properties -> File Security -> Edit (Secure Communications)
          - Uncheck Require secure channel (SSL).
    "

     

    This is all you need and you should see your URL changing automagically from HTTP to HTTPS (SSL).

    Hope this helps...

  • Care, Share and Grow!

    New Year Resolution

    • 1 Comments

    I am writing this post on the 1st of January 2008. It's a brand new day and hopefully a brand new beginning with lots of hope, expectations and ambitions being carried over my lean shoulders. I have been seeing the same day and night everyday of my life, but when it is the first day of a new year I tend to see it differently, or better said; force myself to see it differently of course with a tinge of optimism in it. With the onset of this new year I complete one year of my blogging experience and to be honest I loved it all the way. I am glad I could help some people no matter how less the number was and make change in the world how miniscule it may be...but I am happy and that's what matters.

    Every year-end I spare a few hours for introspection, I sit down all alone in a secluded place and look back at the entire year...on various aspects of how my life was touched upon in both good and bad ways....but at the end of the day I end up with no grudges because I always feel whatever happens it happens for a reason and the reason is always rewarding and enriching....every experience teaches one some lesson and makes one prepared for "what come may". It's funny how people find ways to keep themselves going forward  but that's a hidden agenda of how nature keeps the momentum going.....one has to move on and prepare oneself for what is coming ahead than holding oneself back with what has already gone by.

    I have lot of expectations from this year for some very personal reasons. Let's see how far I can reach in achieving them. There are no new year resolutions for me; in fact I never make one because my free-will always tend to break it and go against my determination just to make a mockery of how undetermined I am. And I say this with my bitter experiences in the past ;-)

    Wish you a happy and prosperous new year 2008 ahead.

    Cheers!!!

  • Care, Share and Grow!

    My turn will get over too...

    • 1 Comments

    [Non Technical]

    Recently I got an extra responsibility to be an On-call engineer for IIS/ASP.Net support for one week apart from my daily work schedule. And I never realized what toll it can take on me until I took over it.

    Basically an On-Call engineer has to be available during the Night hours for the entire week. S/he is just a backup, reserved in case a Critical issue comes in and no one is around to take it. So its like passively working 24x7 for a complete week. Remember it's an extra add-on after one's office hours.

    We have very limited number of Engineers in support during US night shift hours and weekends, assuming that call/case volume will be very low during this period. And when an incident case is opened during this time and no one is available to take it (assuming all the limited workforce is already occupied with work on other cases) the call goes on to the so-called privileged On-Call engineer. And depending upon the severity of the case s/he may have to work on it either from home or come to office and then take over the mantle. Look how that poor person has to manage if s/he already had a tough day in office. In my case I had no choice but to come to office.

    And I was told that we don't get much calls for an On-call, and believing in the sanctity of the advice I was quite happy. But looks like everyday in my so called night hours (I work in US time zone although based in India) I get a ring for a critical (high severity and visible) case and the person on other line starts gabbling all the technical stuffs he damn cares to know about. And I am, brutally woken up from my deep slumber trying to recover at the earliest to make sense of what other person is speaking....It kind of, makes it amusing to me how fast I need to recover my senses (wherein few seconds back I was dreaming running around the trees in a state of bliss), to understand the technicalities of the phone conversation and get on with a bunch of people on the other line talking about how their server crashed like hell and how they saw their application getting into a hung state, or leaking memory etc. and what not. I understand their state (no one would like to work off hours in night or weekends out of choice after a hectic day unless a lot is on stake) and I try my best to empathize with their state and help them to the best of my abilities, meanwhile also knowing my own state at that point ;-)....well part of my job anyway.

    In fact, these days I have started dreaming that my cell is ringing and when I wake up there is an utter silence, and I try to console myself that I will get a peaceful sleep today (I tell myself I won't get a call today for sure, let peace behold on me), which doesn't seem to be happening for the last few days.

    I am happy that it won't last long, another few days to go :-) and then I can be a free bird enjoying my after-hours (beyond my shift) and then of course the weekends. You see there are a lot of plans one tend to make for weekends if their weekdays had a perilous impact on them. Just a kind of compensation I feel. One needs to find ways to freshen up. On a brighter note, I feel this stretch is really challenging and puts back hope in one's abilities (if you have lost one) to handle pressure and situation elsewhere too in other walks of life and shows how far one can stretch his/her own limits if required. I am an optimist at the end and knows ways to soothe myself.

    Looking forward to an exciting weekend ahead....guess today is just the start of the week.

    Cheers!

    Martini Glass

  • Care, Share and Grow!

    Certificate Trust List not being honored by IIS 5.0/6.0/7.0?

    • 8 Comments

    Something one should be aware of if one is dealing with Client certificate and assuming Certificate Trust List (CTL) will limit the list of Trusted Certificate Authorities (CA's) being sent to the client during the initial SSL handshake.

    In IIS 5.0 Post MS04-011 update and IIS 6.0/7.0 using CTL's you cannot limit the list of CA's sent back to the client during the SSL/TLS handshake. i.e. you can't use CTL's to limit the list of certificates that Internet Explorer is showing. IE will show all the certificates irrespective of whether the issuing CA is a part of the CTL or not.

    This however is not applicable to Apache web server. Apache will send the list of CA's which are part of the CTL. The above behavior was implemented in IIS as a security design feature. You can use OpenSSL to check the behavior:

    Let's assume we have a web site www.test.com which accepts client certificates. OpenSSL will show the following transaction. Note that it sends the list of all the CA's even if you have configured CTL to allow specific CA's.

     

    C:\>OpenSSL s_client -connect www.test.com:443 -prexit
    Loading 'screen' into random state - done
    CONNECTED(00000790)
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=27:certificate not trusted
    verify return:1
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=21:unable to verify the first certificate
    verify return:1
    ---
    Certificate chain
    0 s:/C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
       i:/DC=com/DC=Saurabh1/CN=Microsoft
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIE3DCCA8SgAwIBAgIKEfew+wAAAAAANTANBgkqhkiG9w0BAQUFADBDMRMwEQYK
    CZImiZPyLGQBGRYDY29tMRgwFgYKCZImiZPyLGQBGRYIU2F1cmFiaDExEjAQBgNV
    BAMTCU1pY3Jvc29mdDAeFw0wNzExMTYyMzE1MjFaFw0wOTExMTUyMzE1MjFaMGgx
    CzAJBgNVBAYTAkNBMRIwEAYDVQQIEwlLYXJuYXRha2ExEjAQBgNVBAcTCUJhbmdh
    bG9yZTEMMAoGA1UEChMDYWJjMQwwCgYDVQQLEwNJSVMxFTATBgNVBAMTDHd3dy50
    ZXN0LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyHwhBcSOgyfAe2WJ
    2m391qWNTEKj9ScSKrbrzxEFWqEKIReH5pkabxG188vX1uQoo5MUCGd3WIEAb3Xa
    T+mY7P/nA3fwMEUjF1apwXPwQf8hpx5GXhPM6YjyizFGxq06qgNTG3+gCh8arwhu
    u8f9zKOEUicGDOJaQHIK1ofp4G8CAwEAAaOCAi8wggIrMAsGA1UdDwQEAwIFoDBE
    BgkqhkiG9w0BCQ8ENzA1MA4GCCqGSIb3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAw
    BwYFKw4DAgcwCgYIKoZIhvcNAwcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0O
    BBYEFBi8sz9sklijc8tObd/kfYp13IQXMB8GA1UdIwQYMBaAFAVRxGOV1iHL6wJC
    f2vFzSTt5QFwMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9sYXhtaW5iLnNhdXJh
    YmgxLmNvbS9DZXJ0RW5yb2xsL01pY3Jvc29mdC5jcmwwggEVBggrBgEFBQcBAQSC
    AQcwggEDMIGpBggrBgEFBQcwAoaBnGxkYXA6Ly8vQ049TWljcm9zb2Z0LENOPUFJ
    QSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25m
    aWd1cmF0aW9uLERDPVNhdXJhYmgxLERDPWNvbT9jQUNlcnRpZmljYXRlP2Jhc2U/
    b2JqZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTBVBggrBgEFBQcwAoZJ
    aHR0cDovL2xheG1pbmIuc2F1cmFiaDEuY29tL0NlcnRFbnJvbGwvTEFYTUlOQi5T
    YXVyYWJoMS5jb21fTWljcm9zb2Z0LmNydDAhBgkrBgEEAYI3FAIEFB4SAFcAZQBi
    AFMAZQByAHYAZQByMA0GCSqGSIb3DQEBBQUAA4IBAQAPf48JnKDC5qnGUOwzPsVY
    iz454kHCa6hWxO4L8Lf4uZ/iTwhjvG+LsPZpsijxAkpa/Me2YAtTJS8HaKa0l+on
    VAsDl4AJLK0epH7iQUfahe5BH3DxYcXFi2uAZeSFa12STxa5Ywtknrlxelimzak+
    CgEZTSUDTtSDAOxwIpIXlmsPzBmaI7Cx6+R0Kul3H+DPRP/iE/Qh7yzlXbDqcAsA
    i91ungRcHtiFxkLSwfRbV/qyr2OszKa+7SM9GJ6R0lJC5oRBy/JkQqWiAYvRaf5J
    iTdC7eourVL+TH+GhXnFpmCs+YlotkWLj7EsLKwKiEuX8mm8T6UXKzis2OazfHfh
    -----END CERTIFICATE-----
    subject=/C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    issuer=/DC=com/DC=Saurabh1/CN=Microsoft
    ---
    No client certificate CA names sent
    ---
    SSL handshake has read 1384 bytes and written 324 bytes
    ---
    New, TLSv1/SSLv3, Cipher is RC4-MD5
    Server public key is 1024 bit
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : RC4-MD5
        Session-ID: B21A0000950C415B75F380724109AE354A29437F77C62FCEF493BD823C62C616
        Session-ID-ctx:
        Master-Key: 6A2F53DBE5ED1565D1E7CB218B4D1B7AF7CFE07594469D69772C26232BBB0253326ACC25A106D3A6B452
    1B3B0989D57D
        Key-Arg   : None
        Start Time: 1197061986
        Timeout   : 300 (sec)
        Verify return code: 21 (unable to verify the first certificate)
    ---
    GET /test.asp
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=20:unable to get local issuer certificate
    verify return:1
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=27:certificate not trusted
    verify return:1
    depth=0 /C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    verify error:num=21:unable to verify the first certificate
    verify return:1
    read R BLOCK
    <!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01//EN" "http://www.w3.org/TR/html4/strict.dtd">
    <HTML><HEAD><TITLE>The page requires a client certificate</TITLE>
    <META HTTP-EQUIV="Content-Type" Content="text/html; charset=Windows-1252">
    <STYLE type="text/css">
      BODY { font: 8pt/12pt verdana }
      H1 { font: 13pt/15pt verdana }
      H2 { font: 8pt/12pt verdana }
      A:link { color: red }
      A:visited { color: maroon }
    </STYLE>
    </HEAD><BODY><TABLE width=500 border=0 cellspacing=10><TR><TD>

    <h1>The page requires a client certificate</h1>
    The page you are attempting to access requires your browser to have a Secure Sockets Layer (SSL) cli
    ent certificate that the Web server will recognize. The client certificate is used for identifying y
    ou as a valid user of the resource.
    <hr>
    <p>Please try the following:</p>
    <ul>
    <li>Contact the Web site administrator if you believe you should be able to view this directory or p
    age without a client certificate, or to obtain a client certificate.</li>
    <li>If you already have a client certificate, use your Web browser's security features to ensure tha
    t your client certificate is installed properly. (Some Web browsers refer
    to client certificates as browser or personal certificates.)</li>
    </ul>
    <h2>HTTP Error 403.7 - Forbidden: SSL client certificate is required.<br>Internet Information Servic
    es (IIS)</h2>
    <hr>
    <p>Technical Information (for support personnel)</p>
    <ul>
    <li>Go to <a href="http://go.microsoft.com/fwlink/?linkid=8180">Microsoft Product Support Services</
    a> and perform a title search for the words <b>HTTP</b> and <b>403</b>.</li>
    <li>Open <b>IIS Help</b>, which is accessible in IIS Manager (inetmgr),
    and search for topics titled <b>About Certificates</b>, <b>Using Certificate Trust Lists</b>, <b>En
    abling Client Certificates</b>, and <b>About Custom Error Messages</b>.</li>
    </ul>

    </TD></TR></TABLE></BODY></HTML>

    read:errno=0
    ---
    Certificate chain
    0 s:/C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
       i:/DC=com/DC=Saurabh1/CN=Microsoft
    ---
    Server certificate
    -----BEGIN CERTIFICATE-----
    MIIE3DCCA8SgAwIBAgIKEfew+wAAAAAANTANBgkqhkiG9w0BAQUFADBDMRMwEQYK
    CZImiZPyLGQBGRYDY29tMRgwFgYKCZImiZPyLGQBGRYIU2F1cmFiaDExEjAQBgNV
    BAMTCU1pY3Jvc29mdDAeFw0wNzExMTYyMzE1MjFaFw0wOTExMTUyMzE1MjFaMGgx
    CzAJBgNVBAYTAkNBMRIwEAYDVQQIEwlLYXJuYXRha2ExEjAQBgNVBAcTCUJhbmdh
    bG9yZTEMMAoGA1UEChMDYWJjMQwwCgYDVQQLEwNJSVMxFTATBgNVBAMTDHd3dy50
    ZXN0LmNvbTCBnzANBgkqhkiG9w0BAQEFAAOBjQAwgYkCgYEAyHwhBcSOgyfAe2WJ
    2m391qWNTEKj9ScSKrbrzxEFWqEKIReH5pkabxG188vX1uQoo5MUCGd3WIEAb3Xa
    T+mY7P/nA3fwMEUjF1apwXPwQf8hpx5GXhPM6YjyizFGxq06qgNTG3+gCh8arwhu
    u8f9zKOEUicGDOJaQHIK1ofp4G8CAwEAAaOCAi8wggIrMAsGA1UdDwQEAwIFoDBE
    BgkqhkiG9w0BCQ8ENzA1MA4GCCqGSIb3DQMCAgIAgDAOBggqhkiG9w0DBAICAIAw
    BwYFKw4DAgcwCgYIKoZIhvcNAwcwEwYDVR0lBAwwCgYIKwYBBQUHAwEwHQYDVR0O
    BBYEFBi8sz9sklijc8tObd/kfYp13IQXMB8GA1UdIwQYMBaAFAVRxGOV1iHL6wJC
    f2vFzSTt5QFwMEUGA1UdHwQ+MDwwOqA4oDaGNGh0dHA6Ly9sYXhtaW5iLnNhdXJh
    YmgxLmNvbS9DZXJ0RW5yb2xsL01pY3Jvc29mdC5jcmwwggEVBggrBgEFBQcBAQSC
    AQcwggEDMIGpBggrBgEFBQcwAoaBnGxkYXA6Ly8vQ049TWljcm9zb2Z0LENOPUFJ
    QSxDTj1QdWJsaWMlMjBLZXklMjBTZXJ2aWNlcyxDTj1TZXJ2aWNlcyxDTj1Db25m
    aWd1cmF0aW9uLERDPVNhdXJhYmgxLERDPWNvbT9jQUNlcnRpZmljYXRlP2Jhc2U/
    b2JqZWN0Q2xhc3M9Y2VydGlmaWNhdGlvbkF1dGhvcml0eTBVBggrBgEFBQcwAoZJ
    aHR0cDovL2xheG1pbmIuc2F1cmFiaDEuY29tL0NlcnRFbnJvbGwvTEFYTUlOQi5T
    YXVyYWJoMS5jb21fTWljcm9zb2Z0LmNydDAhBgkrBgEEAYI3FAIEFB4SAFcAZQBi
    AFMAZQByAHYAZQByMA0GCSqGSIb3DQEBBQUAA4IBAQAPf48JnKDC5qnGUOwzPsVY
    iz454kHCa6hWxO4L8Lf4uZ/iTwhjvG+LsPZpsijxAkpa/Me2YAtTJS8HaKa0l+on
    VAsDl4AJLK0epH7iQUfahe5BH3DxYcXFi2uAZeSFa12STxa5Ywtknrlxelimzak+
    CgEZTSUDTtSDAOxwIpIXlmsPzBmaI7Cx6+R0Kul3H+DPRP/iE/Qh7yzlXbDqcAsA
    i91ungRcHtiFxkLSwfRbV/qyr2OszKa+7SM9GJ6R0lJC5oRBy/JkQqWiAYvRaf5J
    iTdC7eourVL+TH+GhXnFpmCs+YlotkWLj7EsLKwKiEuX8mm8T6UXKzis2OazfHfh
    -----END CERTIFICATE-----
    subject=/C=CA/ST=Karnataka/L=Bangalore/O=abc/OU=IIS/CN=www.test.com
    issuer=/DC=com/DC=Saurabh1/CN=Microsoft
    ---
    Acceptable client certificate CA names
    /DC=com/DC=Saurabh1/CN=Microsoft
    /DC=com/DC=Saurabh1/CN=Saurabh CA
    /C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign,
    Inc. - For authorized use only/OU=VeriSign Trust Network
    /C=US/O=VeriSign, Inc./OU=Class 4 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign,
    Inc. - For authorized use only/OU=VeriSign Trust Network
    /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services Division/CN=Thawte P
    ersonal Freemail CA/emailAddress=personal-freemail@thawte.com
    /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services Division/CN=Thawte P
    ersonal Premium CA/emailAddress=personal-premium@thawte.com
    /C=US/O=First Data Digital Certificates Inc./CN=First Data Digital Certificates Inc. Certification A
    uthority
    /C=ZA/ST=Western Cape/L=Cape Town/O=Thawte Consulting/OU=Certification Services Division/CN=Thawte P
    ersonal Basic CA/emailAddress=personal-basic@thawte.com
    /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority
    /C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority
    /C=US/O=VeriSign, Inc./OU=Class 1 Public Primary Certification Authority
    /C=US/O=VeriSign, Inc./OU=Class 3 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign,
    Inc. - For authorized use only/OU=VeriSign Trust Network
    /C=HU/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Uzleti (Class B) T
    anusitvanykiado
    /C=US/O=GTE Corporation/CN=GTE CyberTrust Root
    /C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Global Root
    /C=US/O=Entrust.net/OU=www.entrust.net/CPS incorp. by ref. (limits liab.)/OU=(c) 1999 Entrust.net Li
    mited/CN=Entrust.net Secure Server Certification Authority
    /C=HU/ST=Hungary/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Kozjegy
    zoi (Class A) Tanusitvanykiado
    /C=US/O=VeriSign, Inc./OU=Class 2 Public Primary Certification Authority - G2/OU=(c) 1998 VeriSign,
    Inc. - For authorized use only/OU=VeriSign Trust Network
    /C=US/O=GTE Corporation/OU=GTE CyberTrust Solutions, Inc./CN=GTE CyberTrust Root
    /C=HU/L=Budapest/O=NetLock Halozatbiztonsagi Kft./OU=Tanusitvanykiadok/CN=NetLock Expressz (Class C)
    Tanusitvanykiado
    /OU=Copyright (c) 1997 Microsoft Corp./OU=Microsoft Corporation/CN=Microsoft Root Authority
    /DC=com/DC=microsoft/CN=Microsoft Root Certificate Authority

    ---
    SSL handshake has read 7991 bytes and written 740 bytes
    ---
    New, TLSv1/SSLv3, Cipher is RC4-MD5
    Server public key is 1024 bit
    SSL-Session:
        Protocol  : TLSv1
        Cipher    : RC4-MD5
        Session-ID: 7F0A00002D0024D14CCB9D959D185669A22B6F9ECF613E75C0B9A7DD75DD436A
        Session-ID-ctx:
        Master-Key: A17E388F8744B03CAA268418A700F92B5BABDBD09908F8E5503B299579CA4C09A93CCEC5BBCB7BD2F39A
    2C64EF36F674
        Key-Arg   : None
        Start Time: 1197061993
        Timeout   : 300 (sec)
        Verify return code: 21 (unable to verify the first certificate)
    ---

    This is the default behavior for IIS 5.0 (Post MS04-011), IIS 6.0 and to my knowledge will remain so going forward with IIS 7.0 as well.

  • Care, Share and Grow!

    My IIS 7.0 Administration UI Extension Page

    • 1 Comments

    The UI extension option in IIS 7.0 is an exciting feature for any .Net developer. You can write your own custom UI pages and can add various features to it to manage IIS on Windows Vista and Windows Server 2008. I have written an UI extension and is attached with this post.

    I have added the IIsReset feature provided by my good friend Rakki as part of this UI module. He had blogged about it here. Besides IISRESET, I have also added an integrated browser, AppCmd.exe UI and a generic Request monitoring tab.

    To add this module in your IIS 7 manager follow the steps below:

    1. Download the ExtensibilityDemo.dll.
    2. Drag and Drop the ExtensibilityDemo.dll into the Global Assembly Cache (C:\Windows\assembly) or use GacUtil -i ExtensibilityDemo.dll to install it to the GAC.
    3. From the Windows Explorer, browse to the file

    %WinDir%\System32\InetSrv\config\Administration.config.

     

        4. Search for the <moduleProviders> section and add the following

    <add name="ExtensibilityDemo" type="ExtensibilityDemo.DemoModuleProvider, ExtensibilityDemo, Version=1.0.0.0, Culture=neutral, PublicKeyToken=204f1a1ad20ba534" />

    You need to crosscheck that PublickKeyToken matches what is present in the GAC.

    This should be same as the following in the Assembly folder:

    image

        5. Search for the <modules> section and add the following

    <!-- For all Sites -->
      <location path=".">
        <modules>
          <add name="ExtensibilityDemo" />

     

        6. Open Inetmgr (Start Menu->Run->Inetmgr) and You will see the module listed in your IIS 7 Manager if everything went fine during the installation.

    You can see the Module listed in Connections Pane as well as middle pane in its own category. If you want you can remove from the Connections Pane by right click and "remove".

    Here are some screen shots for this extension:

    image

    In the central IIS manager pane (window) you should see the following:

    imageimage

    image

    image

    image

    image image

    I will be adding some new functionalities as time progresses to have more UI interface for various features. I will recommend if you are interested start developing your modules today to customize/extend IIS 7.0 features.

    Good luck....

Page 2 of 3 (71 items) 123