• Care, Share and Grow!

    Anonymous PUT in WebDAV on IIS 7+ deprecated

    • 7 Comments

    I have been seeing this question being put up on lot many forums plus we are getting a lot of support cases opened by customers requesting for this feature.

    In IIS 7+ we have changed the feature of allowing PUT, MKCOL, PROPPATCH, COPY, MOVE, and DELETE to require authentication. Anonymous PROPFINDs are allowed for file listings, but others require the request be authenticated. This was done as a security measure. In IIS 6.0 we did have the provision of using the above methods using anonymous requests from the clients but not anymore. I think the reason people still want this feature in IIS 7 is because of some 3rd party applications like CURL etc which send Anonymous PUT requests to a WebDAV site.

    Lot of people who have migrated from IIS 6.0 to IIS 7+ still request for this functionality. Please note that this is neither recommended nor supported by Microsoft Product Support Services (PSS).

    Here, however I will show you a method of achieving a similar feature without users requiring to send user credentials for WebDAV requests. Basically the WebDAV module checks whether the request is authenticated or not. If not (i.e. using Anonymous authentication) WebDAV module will respond saying “Anonymous access not allowed” in the FREB logs.

     

    There is a KB article which talks about this as well http://support.microsoft.com/kb/2021641/en-us

    So one way of hacking this is to convince WebDAV module that your request is authenticated. So before the WebDAV module gets a chance to handle the request ensure we change the identity context as an authenticated user. In IIS 7 we can write a native ISAPI filter (preferred for performance reasons) or a managed HTTP Module which can intercept the request and change the user context to some pre-configured windows identity. Or else you can read a username/password from a configuration file (or hard code the vale) and then create a basic Base64 hash for the combination and add it to the Request header collection. This in my opinion is a neater way than the first method.

    Here are the steps for injecting Basic Base64 hash in the Request header collection:

    • Create a custom HTTP Module (attached with the post) and on Application_BeginRequest read the username/password (either a local or a domain user credential, your choice). Here in the sample I have hardcoded these values but you can read it from a configuration file or by some other means. After we have the username and the password, we concatenate the strings separated by a colon (:), and then compute the Base64 hash for this string and then add a custom HTTP header (“Authorization”) to the incoming request with this Base64 value. The processing in the remaining pipeline thinks that the end user has sent a Basic authentication credential whereas our module is adding this in the BeginRequest event.
    • Compile the Http Module and copy the dll in to the bin folder under your WebDAV site in IIs 7.
    • Ensure that the custom HTTP Module is invoked before the WebDAV module. WebDAV module thinks that the request is authenticated and hence allows operations like PUT/DELETE etc.
    • In the Web.config file under your WebDAV site, add the following:

    <modules runManagedModulesForWebDavRequests="true">

    <add name="CustomBasicWebDAVModule" type="CustomBasicWebDAVModule"/>

    </modules>

    • Ensure that we have added the following attribute runManagedModulesForWebDavRequests="true" to the Modules section as shown above.
    • Last but not least enable only Basic authentication for your WebDAV site (Don’t worry user/client won’t be required to pass in any credentials).

    Now go ahead and you should be able to use PUT/DELETE etc verbs for the WebDAV requests for this site anonymously (well, not technically correct though).

    Thanks to Robert for the valuable suggestion on this forum and the inputs.

    **PLEASE NOTE THAT THIS IS NEITHER RECOMMENDED NOR SUPPORTED BY MICROSOFT PSS. USE IT WITH CAUTION.

  • Care, Share and Grow!

    Backing up ASP.Net configuration files

    • 2 Comments

    Recently I authored a fast publish KB article on backing up configuration files for ASP.Net on IIS 6/7.

    http://support.microsoft.com/kb/2434810

    If you would like PSS to write on more topics that may interest you please put up your suggestions.

    HTH

  • Care, Share and Grow!

    CRL checking by IIS

    • 1 Comments

    ·         When a Client certificate is presented to an IIS website, IIS looks for the CRL verification to determine the validity of the certificate, much in a similar way a browser does the CRL checking for an SSL enabled website. When IIS receives the client cert it looks into the CDP (CRL Distribution point) under the details tab of the client cert. It then uses one of the HTTP/LDAP links listed there to download the CRL on the server. This link will basically be pointing to one of the CDP servers hosted by the CA. IIS uses this link to download the CRL for future verification purpose. This is overall what IIS does. Obviously internally it is making calls to Crypto Subsystem for all these activities.

    When does IIS kick off a new download of a CRL? Does it look at the Next Update field within the CRL and then keep a log (somewhere on IIS or registry) on when it requires to download the next CRL from the CA?

    ==>

    To answer the above question in specific it depends upon various settings/scenarios as described below.

    IIS by default looks into the downloaded CRL for the next update field. This is stored in its own memory cache and also physically in the server under either

    %windir%\System32\config\systemprofile\Application Data\Microsoft\CryptnetUrlCache\MetaData (on Win2k3 server), or

    %windir%\System32\config\systemprofile\AppData\LocalLow\Microsoft\CryptnetUrlCache\MetaData (on Win2k8)

    You can find the cached CRLs using this command as well Certutil –urlcache CRL at a command-line prompt.

    If the current date is well behind the ‘Next Update’ field value it will use the current CRL to validate the client certificates.

    CRL verification depends upon the metabase properties (IIS 6.0) like CertCheckMode, RevocationFreshnessTime and RevocationURLRetrievalTimeout.

    1. If CertCheckMode is set to 0, IIS does the CRL verification based on the cached CRL on the server (based on its properties like current date and ‘Next Update’ field).

    If the current date is in the range of ‘Effective Date’ and ‘Next Update’ fields it will use the local CRL cache. If the current date is beyond ‘Next Update’ field it will try downloading the CRL from the remote location and use it.

    2. If CertCheckMode is set to 1 Certificate revocation checking is not performed.

    3. If CertCheckMode is set to 2 Certificate revocation verification will be done based on the cached CRL on the IIS server. IIS will not try to connect to the remote server to download the CRL even if it has expired and in which case CRL verification will obviously fail.

    4. If CertCheckMode is set to 4 Certificate revocation verification will be done by downloading the remote CRL, even if we have the valid cached CRL on the server. It ignores the cached CRL completely.

    The frequency with which we download the remote CRL depends upon the value of the metabase property called RevocationFreshnessTime.

    If this property is set to 1 (true) then the CRL on the server is updated from the remote location (even though local cached CRL is valid) every 1 day by default. If the metabase property RevocationFreshnessTime is set to a higher value (instead of 1) IIS uses its value directly to look for the frequency with which CRL is updated. Remember the value defines the time interval in seconds.

    This default timeout interval for updating the CRL is controlled by another metabase property called RevocationURLRetrievalTimeout. This defines the timeout interval in milliseconds. You can increase this value if you think there might be some latency in downloading the CRL from the remote server.

              When you are dealing with the 4th option above ensure you check this link in case you are getting this same issue.      

    Hopefully the above explanation gives you an idea as to how and when IIS asks the Crypto subsystem to retrieve a copy of the CRL. This is finally done by Schannel during TLS negotiation.

    In IIS 7+ you can use netsh commands to set different values for CRL verification (Equivalent to setting CertCheckMode in IIS 6.0). Refer to this and this for details.

    Ciao

     

  • Care, Share and Grow!

    FREB Log file Formatter

    • 0 Comments

    IIS 7/7.5 has a module called Failed Request Tracing (aka FREB) using which we can capture a lot of valuable information in the modular pipeline within IIS. We in PSS use it quite often for troubleshooting various issues with regard to Performance, Authentication, custom Module/handler/ISAPI filter issues in the pipeline etc.

    For more details on how FREB works here is a good link.

    However you may notice that based on the rule that you configure with FREB you may end up with lot many log files that are generated by the FREB module. It again depends upon the number of requests hitting your website and how many of them fall under one of the rules that you have configured. The pain starts when you navigate to the folder where you have all these log files. The default location is %systemdrive%\inetpub\logs\FailedReqLogFiles\. If you have lot of log files created you may see them listed as below:

    image

    Looking at the above screenshot we know that the file names are not descriptive enough to help us distinguish which file corresponds to which request/property. It may be a little painful to go through all of them just to find the right one. Imagine 100+ files in the folder!

    I have developed a simple application which asks you for the location where you have the FREB logs and then creates a copy of all the logs in a subfolder with more descriptive names. These names are actually based on the request properties associated with that log file like time-stamp, page name, verb, status code, time-taken etc.

    image

     

    After you run the tool it creates a subfolder named “NewFREBLogs” under the folder you selected above. It doesn’t modify or delete the existing FREB logs anyway.

    The new file names will be more descriptive as shown below.

    image

     

    Hope this saves some time while rummaging through all the logs.

    You can download it from the following link

    http://www.iis.net/community/default.aspx?tabid=34&g=6&i=2011

    Till next time…Cheers to life!

  • Care, Share and Grow!

    Internet Explorer 6 may fail to open an SSL Web site after installing MS10-049

    • 0 Comments

    You may see this behaviour when accessing an SSL enabled Website through IE 6.0 after installing MS10-049.

    “The Page cannot be displayed”

    This can happen for websites that use TLS security protocol for encryption.

    If you are experiencing this behaviour please check the following support KB for more information.

    http://support.microsoft.com/kb/2384778

  • Care, Share and Grow!

    Failing to run ADSI scripts remotely against IIS?

    • 0 Comments

    If you are trying to run an ADSI/WMI Script remotely from a client machine which gets information the from IIS web server around websites etc. you may see this:

    Invalid syntax” or error code 800401E4

    Or

    Microsoft VBScript runtime error: The remote server machine does not exist or is unavailable: 'GetObject'

    In my script I was using the following

    GetObject( "IIS://" & ServerName & "/W3SVC" )

    So basically the above error was complaining about the use of GetObject.

    Resolution

    1. Ensure Firewall is not blocking access to your server from remote access on the client.

    2. ADSI provider should be installed on the client as well as the IIS machine for the above script to work. For running ADSI script against IIS we need to ensure the ADSI provider is installed as below.

    Windows Server 2003/XP:

    Add/Remove windows Components –> Application Server –> Internet Information services (IIS) –> Common Files.

    Windows Vista/Windows 7:

    Control Panel –> Programs and Features –> Turn Windows Features on or off –>  Internet Information Services –> Web Management tools –> IIS 6 Management Compatibility –> IIS Metabase and IIS 6 configuration compatibility

    Windows Server 2008:

    Server Manager –> Roles –> web Server (IIS) –> Add Role Services  –> Management Tools –> IIS 6 Management Compatibility –> Select IIS 6 Metabase compatibility, IIS 6 WMI compatibility and IIS 6 Scripting Tools.

    Hoping It may help someone who might be struggling with trying to run the script remotely.

    Ciao!

  • Care, Share and Grow!

    Debug.Assert does not launch a popup window on IIS7 while debugging in Visual Studio

    • 1 Comments

    If you are trying to debug an IIS 7 hosted web application using Visual Studio and trying to use System.Diagnostics.Debug.Assert()/System.Diagnostics.Trace.Assert() in your code to launch a popup window it will not work. However you can write the output to a log file using the following:

    <configuration>
    
      <system.diagnostics>
    
        <assert assertuienabled="true" logfilename="c:\\myFile.log" />
    
      </system.diagnostics>
    
    </configuration>

    You can also get the output of Debug.Assert (..) in the Output window within Visual Studio. It will also be logged in the System event log. However, this seems to work with the earlier version of IIS, i.e. IIS 6.0 in the console session.

    After going through various forums I see that developers do complain about this being a deprecated feature in IIS 7+ versions which hampers debugging.

    However In my opinion it should *never* have worked in the first place for any service based application. ASP.Net application runs as a service on the server side and it should never launch an interactive window which might lead to the process getting into a hung state for all the clients. Lot of times developers miss deleting one of these entries from their code before moving it to the production environment and that leads to hang/frozen condition for the application for all the end users. This is not specific to IIS or ASP.Net in my opinion but manifestation of a feature from Vista onwards at the OS level. Session 0 isolation in Vista onwards prevents services from interacting with user sessions in the way it was possible in the previous versions of Windows like Windows Server 2003.

    http://www.microsoft.com/whdc/system/sysinternals/Session0Changes.mspx

    http://channel9.msdn.com/posts/Charles/Session-0-Changes-and-Vista-Compatibility-for-Services-running-as-Interactive-with-Desktop/

    Important  All services run in Terminal Services session 0 from Vista onwards. Therefore, if an interactive service displays a user interface, it is visible only to the user who is connected to session 0. Applications running in other sessions cannot access Session 0 GUIs. Because there is no way to guarantee that the interactive user is connected to session 0, do not configure a service to run as an interactive service under Terminal Services or on a system that supports fast user switching.

    HTH

    Saurabh

  • Care, Share and Grow!

    Microsoft Professional Advisory Services

    • 0 Comments

    As per the excerpt in the link below:

    Professional Advisory Services is an hourly, fee-based, consultative support option that provides proactive support beyond break-fix product support needs. Typical Advisory Services cases involve providing recommendations or best practices to solve problems leveraging Microsoft Products and Technologies. These scenarios include topics such as migration, product customization, performance degradation analysis, deployment training, scaling infrastructure, server recovery, optimization, supportability, risk analysis, root cause analysis, extensibility, architecture, and knowledge transfer.

    If you are a Developer/Administrator and looking for consulting/advisory services from Microsoft here is the link you can follow and see what all products/technologies are covered and other details.

    http://support.microsoft.com/gp/advisoryservice#tab7

    HTH

    Saurabh

  • Care, Share and Grow!

    You may see your IIS 6.0 applications failing to respond after you install Microsoft update KB 982666

    • 0 Comments

    We are recently seeing lot many support cases coming our way. If you are seeing the following after installing the Microsoft update KB 982666 on a Windows Server 2003 machine:

    • IIS application pools or websites no longer starts.
    • IIS web-sites may not be able to start.
    • Rapid Fail Protection shuts down your application pools.
    • An inspection of the event logs show that the IIS worker processes are terminating unexpectedly, showing event messages similar to the following:

    Event Type: Warning
    Event Source: W3SVC
    Event Category: None
    Event ID: 1009
    Date:  12/9/2009
    Time:  10:55:01 AM
    User:  N/A
    Computer: WEBSERVER01
    Description:
    A process serving application pool 'DefaultAppPool' terminated unexpectedly. The process id was '1234'.
    The process exit code was '0xffffffff'.

    Please go ahead and reapply Windows Server 2003 Service Pack 2 to resolve this issue.

    For more details visit the following link.

  • Care, Share and Grow!

    SSL Bindings are randomly getting deleted for a website with error "SSL Certificate Settings deleted for Port : X.X.X.X:443" in the event logs (IIS 7.0/7.5)

    • 4 Comments

    Symptoms

    Are you getting into a scenario wherein randomly your Website loses or changes the SSL certificate bindings from within the IIS manager? And you realize it only when users complain that they are unable to reach the HTTPS site, or that they get a certificate warning. They are able to access the website over HTTP but not over HTTPS because the certificate binding is lost for the website, or they may be prompted that the certificate is expired, or the site name is incorrect. At this point of time you also notice that System Event log entry shows the following:

    Log Name:      System
    Source:        Microsoft-Windows-HttpEvent
    Date:          3/31/2010 2:43:28 PM
    Event ID:      15300
    Task Category: None
    Level:         Warning
    Keywords:      Classic
    User:          N/A
    Computer:      myMachine
    Description:
    SSL Certificate Settings deleted for Port : 0.0.0.0:443 .

    If you go to the IIS manager and check the bindings for the Website in question you will see either the certificate binding is lost or some other certificate is listed.

    You can also crosscheck the registry entry below for your IP/Port binding associated with your website and you may find it deleted.

    HKLM\System\CurrentControlSet\SERVICES\HTTP\Parameters\SslBindingInfo\X.X.X.X:443

    Here is how it looks if you have the proper binding set at the http.sys level in the Registry.

    clip_image002

    Note:  Should the certificate be changed, the binding will look the same.

    Assessment

    If you are experiencing the above problem it could be related to the following <customMetadata> tag in your ApplicationHost.config.

    <key path="LM/W3SVC/X">

    <property id="5506" dataType="Binary" userType="1" attributes="None" value="oXiHOzFAMOF0YxIuI7soWvDFEzg=" />

    </key>

    The above property is used to store a SSL certificate hash. It is specifically the ID 5506 entry you need to check for. That ID is the legacy property for certificate hash. Whenever any application/service which depends upon the ABO mapper runs/starts, it tries to initialize the ABO tree structure which includes generating custom nodes and properties. During this process it reads from this custom metadata section and tries to map the properties in the ABO tree structure. During mapping it deletes the current SSL mapping(s) at the http.sys level and recreates a new one using the above hash value. If this value is invalid for some reason it fails to add the new entry for SSL binding at the http.sys level. So in such a case the above registry key does not have an entry for the website’s IP:Port combination corresponding to the SSL setting in the UI like below:

    clip_image004

    Call stack output

    If you use the Debugging Tools for Windows and the Microsoft symbol server to attach to the process Inetinfo.exe, you will notice a call stack that resembles the following below:

    abocomp!UpdateSSLProperty
    abocomp!SITE_CUSTOM_PROVIDER::MapSetData+0x371
    abocomp!ABO_NODE::MapSetData+0xd9
    abocomp!ABO_NODE::SetData+0xbd
    abocomp!ABO_TREE::SetCustomProperty+0x34a
    abocomp!ABO_TREE::GenerateCustomNodesAndProperties+0x1ad
    abocomp!ABO_TREE::GenerateTree+0x28d
    abocomp!ABO_WRAPPER::InitializeTreeAndState+0xad
    abocomp!ABO_WRAPPER::GetCurrentAboTree+0xc7
    abocomp!ABO_WRAPPER::OpenKey+0x154
    COADMIN!CADMCOMW::OpenKeyHelper+0x172
    COADMIN!CADMCOMW::OpenKey+0x53
    RPCRT4!Invoke+0x65
    RPCRT4!NdrStubCall2+0x348
    RPCRT4!CStdStubBuffer_Invoke+0x9a
    ole32!SyncStubInvoke+0x5d
    ole32!StubInvoke+0xdf
    ole32!CCtxComChnl::ContextInvoke+0x19f
    ole32!AppInvoke+0xc2
    ole32!ComInvokeWithLockAndIPID+0x407
    ole32!ThreadInvoke+0x1f0
    RPCRT4!DispatchToStubInCNoAvrf+0x14
    RPCRT4!RPC_INTERFACE::DispatchToStubWorker+0x100
    RPCRT4!RPC_INTERFACE::DispatchToStub+0x62
    RPCRT4!RPC_INTERFACE::DispatchToStubWithObject+0x5b
    RPCRT4!LRPC_SCALL::DispatchRequest+0x436
    RPCRT4!LRPC_SCALL::HandleRequest+0x200
    RPCRT4!LRPC_ADDRESS::ProcessIO+0x44a
    RPCRT4!LOADABLE_TRANSPORT::ProcessIOEvents+0x24a
    RPCRT4!ProcessIOEventsWrapper+0x9
    RPCRT4!BaseCachedThreadRoutine+0x94
    RPCRT4!ThreadStartRoutine+0x24
    kernel32!BaseThreadInitThunk+0xd
    ntdll!RtlUserThreadStart+0x1d

    We break into the function which calls into the HTTP.sys at the kernel mode to delete the SslBindingInfo Registry key.

    Steps to reproduce

    We can reproduce this issue at will by adding the following under <CustomMetadata> section of your applicationhost.config file

    <key path="LM/W3SVC/X">

    <property id="5506" dataType="Binary" userType="1" attributes="None" value="oXiHOzFAMOF0YxIuI7soWvDFEzg=" />

    </key>

    and then launching any application which requires ABO Mapper, for e.g. launching Inetmgr6.exe or enumerating using ADSUTIL VBscript.

    Resolution

    This property is a legacy feature from IIS 6 days and ported onto IIS 7+. If we have correctly added the certificate in the IIS manager this specific property with id 5506 is not needed. Search for the above entry in your ApplicationHost.config file and remove the property in case you are seeing the above issue.

    PS: I have got the above issue/resolution recently documented as a fast-publish KB article 2025598.

    till next time

  • Care, Share and Grow!

    Export SQL table records to XML form

    • 0 Comments

    I am not a SQL guy. But while working on something I found this which seemed cool to me. So thought of sharing it with folks in case you are not aware. Using SQL Management studio and running T-SQL command we can export the Database table entries into an XML form.

    Let's say you run this SQL command in the SQL editor.

    SELECT * from Saurabh.dbo.Customers

    And we get the following output in the table.

    clip_image001

    Now in order to export the table content into an XML form we need to use FOR XML PATH as below:

    SELECT * from Saurabh.dbo.Customers

    FOR XML AUTO

    clip_image002

    Or

    SELECT * from Saurabh.dbo.Customers

    FOR XML RAW

    clip_image003

    Or

    SELECT * from Saurabh.dbo.Customers

    FOR XML PATH

    Or

    clip_image004

    …..

    Or

    SELECT * from Saurabh.dbo.Customers

    FOR XML PATH('Customer')

    clip_image005

    …….

    If you want to wrap the content under a specific ROOT node use the following:

    clip_image006

    ….

    ….

    clip_image007

    It may not be something new for the SQL folks but this was something new to me.

    Reference:

    http://msdn.microsoft.com/en-us/library/ms189885.aspx

    http://theengineroom.provoke.co.nz/archive/2007/04/27/using-for-xml-path-a-primer.aspx

    till next time….

  • Care, Share and Grow!

    bother to track my blog?

    • 0 Comments

    Just in case if anyone bothers to track my blog here is an update. I have contributed two posts recently to our IIS/ASP.Net Support blogging site.

    1. If you are seeing the following error during the IIS 6.0 Install/Setup:

    Error writing encrypted data to the Web Server's configuration database (Metabase).

    0x80090010=Access denied.

    This post may be useful to you.

    http://blogs.msdn.com/webtopics/archive/2010/04/26/iis-6-0-installation-setup-failure-with-the-error-0x80090010-access-denied.aspx

    2. We had an article on http://learn.iis.net around how you can configure One-to-One mapping for client certificate authentication feature in IIS 7/7.5 but we did not have an equivalent for Many-to-One mapping. If you are interested you may want to follow the link below:

    http://blogs.msdn.com/webtopics/archive/2010/04/27/configuring-many-to-one-client-certificate-mappings-for-iis-7-7-5.aspx

    This post also highlights how you can use the cool Configuration Editor extension to manage IIS configurations including Client Certificate mapping and how easily and automatically you can generate code/scripts/commands to manage IIS features.

     

  • Care, Share and Grow!

    Unexpected 401.1 error over Windows Integrated Authentication on IIS 7.5 website

    • 0 Comments

    I recently added a post to our Support team blog which talks about unexpected 401.1 that you might see when you browse to an IIS 7.5 website over Windows Integrated Authentication. If you are seeing the following in the Error summary on your web page go check this link out.

    image

    Module WindowsAuthenticationModule
    Notification AuthenticateRequest
    Handler StaticFile
    Error Code 0x80090305

     

    Cheers to life!

  • Care, Share and Grow!

    Are you seeing 401’s too often for HTTP web requests?

    • 4 Comments

    We often hear concerns from our customers saying that they are seeing performance issues because of extra round trips being made to the Web server while requesting for web pages. Where they expected just one sequence of 401.2/401.1/200 (NTLM) or 401.2/200 (Kerberos) they are seeing the sequence more often for the subsequent page requests. They would like a way to avoid making extra round trips from the client to the server for an already authenticated page request.

    Why such a behaviour?? Read on…

    Before we proceed let’s clear the two terminologies.

    Connection-based authentication: Client that is authenticated after an initial HTTP request stays authenticated for the duration of the HTTP Keep-Alive session. This means that the server will assume subsequent requests coming on the same connection without an authorization header, to be executed as the last authenticated user. Subsequent requests on the same connection will not be challenged to send the authorization headers as part of their HTTP requests.

    Clients only have to re-authenticate if they make another HTTP request by using a different client TCP port. This scenario occurs when a new HTTP Keep-Alive session must be established.

    Request-based authentication: This means that the client has to be re-authenticated for each HTTP request. This behaviour causes an increase in the network traffic because of the extra round trips made to the server from the client.

    So with that clear in mind here are the scenarios you may encounter for the IIS versions when using Windows Integrated authentication for your web application.

    Authentication method: NTLM
    IIS 6.0

    NTLM on IIS 6.0 uses Connection-based authentication. This behaviour is governed by a metabase property called AuthPersistSingleRequest. By default this value is set to false which means when using NTLM authentication you should see lesser round trips for every page requests. The default value of FALSE is applicable to all versions of IIS, i.e. IIS 5.0, 6.0 and 7.0/7.5.

    Here is how IIS log will look like when it is set to the default value of FALSE.

    1st request
    GET /iisstart.htm - 401 2 2148074254  
    GET /iisstart.htm - 401 1 0  
    GET /iisstart.htm DOMAIN1\User1 200 0 0  
    GET /pagerror.gif DOMAIN1\User1 200 0 0  
    GET /magnifyingglass.ico - 401 2 2148074254  
    GET /magnifyingglass.ico - 401 1 0  
    GET /magnifyingglass.ico DOMAIN1\User1 200 0 0  
    
    2nd request (refresh)  
    
    GET /iisstart.htm DOMAIN1\User1 304 0 0  
    GET /magnifyingglass.ico DOMAIN1\User1 304 0 0  
    GET /pagerror.gif DOMAIN1\User1 304 0 0  

    You may see some requests showing additional 401.2/401.1/200(or 304) here because they are initiating the request on a different client socket and hence a new connection is being established. 

    If we have the AuthPersistSingleRequest value set to TRUE then each request will have to be authenticated irrespective of the previous request on the same connection. Consequently requests will require authorization headers to be sent. Here is the step you need to follow to enable the setting in such a case.

    > cscript.exe adsutil.vbs set w3svc/<Website ID>/AuthPersistSingleRequest TRUE  

    Here is how the IIS log looks like after setting AuthPersistSingleRequest to TRUE.

    1st request  
    
    GET /iisstart.htm - 401 2 2148074254  
    GET /iisstart.htm - 401 1 0  
    GET /iisstart.htm DOMAIN1\User1 200 0 0  
    GET /pagerror.gif - 401 2 2148074254  
    GET /pagerror.gif - 401 1 0  
    GET /magnifyingglass.ico - 401 2 2148074254  
    GET /magnifyingglass.ico - 401 1 0  
    GET /pagerror.gif DOMAIN1\User1 200 0 0  
    GET /magnifyingglass.ico DOMAIN1\User1 200 0 0  
    
    2nd request (refresh)  
    
    GET /iisstart.htm - 401 2 2148074254  
    GET /iisstart.htm - 401 1 0  
    GET /iisstart.htm DOMAIN1\User1 304 0 0  
    GET /pagerror.gif - 401 2 2148074254  
    GET /pagerror.gif - 401 1 0  
    GET /magnifyingglass.ico - 401 2 2148074254  
    GET /magnifyingglass.ico - 401 1 0  
    GET /pagerror.gif DOMAIN1\User1 304 0 0  
    GET /magnifyingglass.ico DOMAIN1\User1 304 0 0  
    Check this link and this link for other possible settings when proxies are involved.

    IIS 7.0

    AuthPersistSingleRequest in IIS 7 is set as an attribute under windowsAuthentication in applicationhost.config file.

    <windowsAuthentication
       enabled="True|False"
       authPersistSingleRequest="True|False"
       UseKernelMode
    >
       <providers>...</providers>
    </windowsAuthentication>  
    http://msdn.microsoft.com/en-us/library/aa347472.aspx

    This completes our discussion on NTLM.

    Authentication method: KERBEROS
    IIS 6.0

    Kerberos used to be Connection-based in IIS 5.0. Starting IIS 6.0+ Kerberos is by default Request-based authentication instead of Connection-based as in NTLM. You may see performance hit because of this behaviour because of the extra round trips.
    So, if we have Kerberos instead of NTLM being used for your web application then we need to ensure that the following hotfix is applied (This hotfix requires the prerequisite as Win2k3 Sp1. If you are already running on SP2 you don’t need to install this hotfix.). Ensure the Registry key EnableKerbAuthPersist is set as per the KB article 917557.

    Here is how the IIS log will look like when this hotfix/key is not set.

    GET /iisstart.htm - 401 2 2148074254 
    GET /iisstart.htm DOMAIN1\User1 200 0 0 
    GET /pagerror.gif - 401 2 2148074254 
    GET /magnifyingglass.ico - 401 2 2148074254 
    GET /pagerror.gif DOMAIN1\User1 200 0 0 
    GET /magnifyingglass.ico DOMAIN1\User1 200 0 0

    After adding the registry key EnableKerbAuthPersist and restarting IIS services we should see something like this:
    GET /iisstart.htm - 401 2 2148074254 
    GET /iisstart.htm DOMAIN1\User1 200 0 0 
    GET /magnifyingglass.ico - 401 2 2148074254 
    GET /pagerror.gif DOMAIN1\User1 200 0 0 
    GET /magnifyingglass.ico DOMAIN1\User1 200 0 0 
    GET /iisstart.htm DOMAIN1\User1 304 0 0 
    GET /pagerror.gif DOMAIN1\User1 304 0 0 
    GET /magnifyingglass.ico DOMAIN1\User1 304 0 0 
    GET /iisstart.htm DOMAIN1\User1 304 0 0 
    GET /magnifyingglass.ico DOMAIN1\User1 304 0 0 
    GET /pagerror.gif DOMAIN1\User1 304 0 0

    IIS 7.0

    EnableKerbAuthPersist is no more applicable in IIS 7. Instead use the attribute AuthPersistNonNTLM in the applicationhost.config file.

    <windowsAuthentication
       enabled="True|False"
       AuthPersistNonNTLM="True | False"
       UseKernelMode
    >
       <providers>...</providers>
    </windowsAuthentication>

    http://msdn.microsoft.com/en-us/library/aa347472.aspx

    The above article seems to have incorrect wording. Ensure we set the attribute to true to have connection-based authentication.

    <location path="Default Web Site"> 
            <system.webServer> 
                <security> 
                    <authentication> 
                        <anonymousAuthentication enabled="false" /> 
                        <windowsAuthentication enabled="true" authPersistNonNTLM="true" /> 
                    </authentication> 
                </security> 
            </system.webServer> 
    </location>

    Caveat: If we are going via a Proxy server IIS will only persist requests per request and that is by by design.

    Going forward if we have Win2k8 R2+ as the web server using Windows Integrated Authentication (user mode) and Win7+IE8 as the client, Nego2 schema based authentication can be feasible.
    Improvements in Win7+IE8 will further reduce the unnecessary traffic for Kerberos based requests.

    Cheers to life!!

  • Care, Share and Grow!

    A simple exe to find DEBUG build for managed modules and DEBUG attribute in Web.Config for Web applications in IIS 6/7

    • 4 Comments

    CAVEAT: Some stories before I get to the point, so you may want to skip to the end.

    We in Microsoft PSS get lot many cases on a daily basis which are related to performance issues with Web applications developed using ASP.Net and hosted on IIS. Based on my experience with debugging these issues many-a-times I have seen that one (or two) very basic step is often missed by our customers. Guess what, they develop the projects/class libraries/modules/assemblies etc (name it whatever you want) and test it thoroughly in the development/testing/staging environments and then go ahead and deploy the same binaries in the Production. What they overlook or tend to forget is that they are deploying the same DEBUG build modules/dlls in the production as against the recommended RELEASE builds/dlls.

    Most of us know that for performance reasons it is always recommended to deploy a release build in the production as against a debug build to reap more benefits from compiler optimizations etc. The above observation is generic and applies to any application running managed code.

    There is one more thing people often overlook when it comes in specific to IIS ASP.Net Web applications, i.e. DEBUG attribute in the Web.Config file under system.web/compilation tag. This is one setting which has a lot of repercussions on the performance of the Web applications running ASP.Net as a web technology like memory issues, fragmentations, etc.

    A very nice detailed tutorial by Rahul (one of our former Technical leads in IIS/ASPNET support group) just reflects what I will never be able to convey any better. Check this link if you want to know more on how this DEBUG attribute may affect your application.

    What we often do in support is that we capture memory dumps of the IIS process and analyze it using various tools (most common here being WinDBG). There are some public extensions available to our customers like sos.dll to debug managed memory dumps. However this extension has been deprecated (from .Net 2.0) and it does not have a feature to find out debug modules that were loaded in the IIS process and the value of the debug attribute set in the Web.Config file.

    I felt that getting memory dumps from our customers and then finding out the above in their application settings and then recommending them to fix it just adds to the overall delay in finally fixing their core issue. This should be done by default. This is something that does not even need our support in the first place if people are well aware of it.

    I wrote this tool just to help reduce their downtime or getting one step closer to their ultimate resolution. I know I write a lot so I will come straight to the point now :).

    Point:

    Feature 1:

    This tool (I rechristened it as DebugFinder.exe) will attach non-invasively to any currently running process on the system and find out if any managed modules that are loaded is a DEBUG or a RELEASE build. This is applicable to any process and not only to Web applications. That way you can find out at run time which managed modules referenced in the current process are deployed as release versus debug builds. This helps keeps track of any debug build assembly that is being referenced from the GAC at runtime apart from the modules loaded from its current working directory if any. Once done it then detaches from the attached process without terminating it.

    Feature 2:

    We know that it is always recommended to have DEBUG attribute set to false in a Web.Config file in a production server.

    This tool scans the machine for the Web applications that are configured in IIS. It looks for the Web.Config files corresponding to all the web applications configured in IIS and checks if they have the DEBUG attribute set to true or false and notifies in the display.

    The Debug flag checking in the Web.Config file works for the web applications running either in IIS 6.0 or IIS 7.0/7.5 by this tool.

    Pre-conditions:

    • DebugFinder has to be run locally on the machine where we want to get the debug related details (remotely may be in another version).
    • It needs .Net framework 2.0 to be installed on the machine for successful running.
    • Currently it is designed/tested for Win2k3/Vista/Win2k8/Win7 for finding Debug attribute in the Web.Config file.
    • If we have UAC turned on on Vista/Win2k8/Win7 ensure we run it in the privileged mode.

    Here are some screenshots:

    image

    image

    Here I have used MdbgCore.dll to attach/detach to a process at run time and show the details for debug modules.

    Attached is a zip file, containing a 32bit and a 64bit DebugFinder builds along with MdbgCore.dll. Ensure we keep both the DebugFinder32/64.exe and the MdbgCore.dll in the same folder while running it.

    Chill!

  • Care, Share and Grow!

    Configuring FTP 7.5 with Host Header and SSL

    • 1 Comments

    FTP 7.5 comes with new features like Host header and SSL. I recently saw some cases coming in from our customers on this. Scanning the Internet made me realize that we need more information posted on this as far as the configuration is concerned.

    If you are seeing any of these errors while connecting to an IIS FTP server using SSL/Host header like

    534-Local policy on server does not allow TLS secure connections.
    Win32 error:   Access is denied.
    Error details: SSL certificate was not configured.

    or

    Primary connection and data connection certificates don't match.
    Error:  Transfer connection interrupted: ECONNABORTED - Connection aborted

    or

    431-Failed to setup secure session.
    Win32 error:  
    Error details: SSL certificate hash has invalid length.

    or

    534-Protection level negotiation failed.
    Win32 error:   Access is denied.
    Error details: Protection negotiation failed. PROT command with recognized parameter must precede this command.

    then check this blog post here.

    I wrote this article on our Team blog site hoping it reduces the confusion around this topic.

    Ciao!

  • Care, Share and Grow!

    WWW Service not listed in the Services console (IIS 6.0)?

    • 2 Comments

    This post is a continuation to the series on IIS service startup issues. I did not feel like writing it since we haven’t seen much cases on this type of behavior and I thought this could be one of those rare issues which always happens with IIS but my customer who bore the brunt of trying to reinstall IIS multiple times without luck virtually forced me into writing it. So here I go…

    Problem Description

    IIS gets installed successfully on a fresh Win2k3 Server. IISADMIN service is up and running. However we do not see World Wide Service (WWW) listed in the Services console. Hence we cannot start any website.

    Resolution

    If you are seeing a similar behavior as above you may want to follow the steps below.

    1. Check for the default permissions as per this KB on

    <SystemDrive:>\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys.

    2. Open iis6.log from the location <SystemDrive:>\Windows and look for

    OC_COMPLETE_INSTALLATION:iis_www:SetupInstallServicesFromInfSection failed.Ret=5

    *Return code 5 suggests access denied

    ……………………………

    OC_CLEANUP:InetStartService():ServiceName=W3SVC unable to start

    WARNING. Err=0x424

    OC_CLEANUP:!FAIL!

    OC_CLEANUP:PostInstall of Component 'iis_www' FAILED

    3. This suggests we are having some permission issues while installing IIS.

    4. Download and run the Process Monitor tool from here while reinstalling IIS again from the Add/Remove Components wizard. Ensure we run it only during the install process since it collects a lot of data.

    5. Check for any ACCESS DENIED entry in the log captured by the Process Monitor tool.

    6. You may see an ACCESS DENIED for the Registry key

    HKLM\SOFTWARE\Microsoft\Windows NT\CurrentVersion\SvcHost.

    Using the Process Monitor tool you can get the identity which does not have the permission. Generally it will be the current logged on user’s credentials running the wizard. Grant Full permission to the Administrators group (assuming that this user trying to install IIS is also a part of this group).

    7. Reinstall IIS and hopefully you should be good.

     

    If this does not help Microsoft PSS support for IIS is always there to help you out ;-)

    Good Luck!!

  • Care, Share and Grow!

    Using System.Net trace configuration file to troubleshoot Certificate errors in ASP.Net

    • 0 Comments

    System.Net trace configuration feature in ASP.Net 2.0 onwards is extremely useful when dealing with certificate related errors.

    Jeff P. Sanders from WinInet/System.Net API Escalation team has written this valuable post for troubleshooting ASP.Net certificate related issues.

    I am adding it  here as a quick reference for others and myself.

    http://blogs.msdn.com/jpsanders/archive/2009/09/16/troubleshooting-asp-net-the-remote-certificate-is-invalid-according-to-the-validation-procedure.aspx

    Great article!

  • Care, Share and Grow!

    Been away for a while…

    • 6 Comments

    I was away for a while now in the wilderness of the Himalayas.
    I was out covering Leh, Ladakh and Kashmir by road (alas, not biking which I badly missed).
    Ladakh is one of those places one should not miss and that too its journey via road. It has its own esoteric beauty
    comprising of barren landscapes, rocky mountains stripped of vegetations, deserts and rivers. A must for adventure
    trip enthusiasts.

    Here are some snaps from the places I was at during this trip.

    IMG_6762 IMG_6933 IMG_7081

    I wasn't able to respond to comments from people on various posts during this time. I will ensure all of them are
    taken care of at the earliest.

     

    Cheers to life!

  • Care, Share and Grow!

    Required permissions when calling a Web service using client certificate for authentication in an ASP.NET Web application

    • 9 Comments

    A Web service requiring Client certificate authentication is a common scenario.

    You may have a client application which needs to send the Client certificate as part of the web request for accessing the web service.

    This client application may be a Windows/Console application or another Web application.

    Often you will get into issues wherein you are able to send Client certificate as part of the web request from a windows/console app but not from another web app. The primary reason for this could often be around Web app not being able to send the client cert to the target Web service.

    This can happen for multiple reasons, in particular account under which Web app is running doesn't have enough permissions to access the Client cert in its local certificate store.

    Refer to this excellent kb for this for more details.

    In this post I want to highlight ways in which you can grant access to the Web application account to access the Client certificate in its local machine store.

     

    When we have to send client cert as part of the web service call from a web app we need to ensure that the client cert is installed in the Local Computer -> Personal Store on the local box (where Web app is running). By default you will see the client cert installed in the Local User Store for the user who requested and installed the cert on the machine. You need to ensure first that the client cert is installed on the Local Computer Store instead of the Local User Store and then follow any of the methods below to grant access to the private key for the account (under which your web app is running).

     

    Method 1:

    The above article kb gives an example of granting access using the Microsoft Windows HTTP Services Certificate Configuration Tool

     

    > WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s " IssuedToName " -a " AccountName "

    for e.g.

    > WinHttpCertCfg.exe -g -c LOCAL_MACHINE\MY -s " IssuedToName " -a "Network Service"

     

    There are other ways in which you can achieve the same result. This feature is in fact built in on Windows Server 2008 within the Certificate mmc console.

     

    Method 2:

    Using the WSE X509 Certificate tool (This tool has features that can be used to check certificate properties).

    You need to download Web Services enhancements (WSE) 2.0+ SP3 for Microsoft.Net and in the install wizard ensure you select Tools as shown below:

     

    image

    Once installed go ahead and launch the tool. It has a clean UI. You have the option to check certificates in the Local Computer/Current user for the available stores like Personal/Trusted/Intermediate Root CA etc. If you click on View Private Key File Properties (shown below) you can directly modify the permission for private key associated with the certificate. Basically this is just a file under C:\Documents and Settings\All Users\Application Data\Microsoft\Crypto\RSA\MachineKeys on Win2k3 server and  C:\ProgramData\Microsoft\Crypto\RSA\MachineKeys on Win2k8 server.

     

    image

    You may want to go ahead and give the Service account under which the web app is running Full permission on this file (modify the permissions from the Security tab).

     

    Method 3:

    If you are running the web app on Windows Server 2008/Vista there is a far simpler way built in the Certificate mmc.

    image

    Right click on the certificate and go to All Tasks -> Manage Private Keys and then give Full permission for the associated account.

     

    Till next time..

    Cheers!

  • Care, Share and Grow!

    Avoid this confusion around Client certificate mapping in IIS 6.0/7.0

    • 0 Comments

    I just wanted to add this quick post around Client certificate Mapping on IIS. This is focused on 1-to-1/Many-to-1 mapping in IIS 6.0/7.0.

    If you are interested to know more about configuring Client certificate mapping in IIS 6.0 please check this post of mine and for IIS 7.0 this is an excellent article.

    Recently a colleague of mine and I was working on this issue for one of our internal teams and after some real slogging we figured out that one *cannot* set this mapping at any Virtual directory/Application level in IIS.

    One has to set the Client certificate mapping at the specific Web site level only!

    image This is wrong!

    image This is right!

    I couldn't find a documentation on this so thought of putting this as a short post for general audience in case someone is scratching their head over this.

    Cheers!

  • Care, Share and Grow!

    Visual Studio 2005/2008 IDE: Web Controls in the Toolbox seen grayed out for Asp.Net projects ?

    • 4 Comments

    Here is a quick post that may help you save few hours if you get into this problem.

    Symptoms

    -- Out of blue you realize that when you try to create and open a new Web  site/Web Application project we do not see any of the Web controls in the Toolbox. It includes most of the sections in the Toolbox pane including Common controls, Data, Login, validation and in fact any of the controls which are associated with an Asp.Net web page.

    -- When you click on 'Show All' in the toolbox you see all the Asp.Net related controls grayed out. In fact you will see most if not all, of the sections in the toolbox being grayed out except HTML controls.

    image

     

    Go to the Source view for the Web form in the VS IDE and add an ASP control yourself like <asp:TextBox...></asp:TextBox>

    Browsing to the web page shows the control getting rendered without any issues. So seems like more of a VS IDE issue than anything to do with ASP.Net application configuration.

    -- Creating a new Winform project works fine with all the relevant controls being displayed and working in the Toolbox window.

     

    Resolution

    This issue may happen if by mistake you had associated ASPX pages with the HTML Editor in the VS IDE. It should be ideally associated with the Web form Editor.

    To resolve this, In the Solution Explorer, locate the ASPX that we are working on, right click on the page and select 'Open with...'.

    You may be seeing that the current selection is HTML Editor (Default). Change it Web Form Editor and click on 'Set as Default'.

    image

    Close the current VS IDE and re-launch it and now we should *hopefully* be good.

  • Care, Share and Grow!

    Automate client certificate one-to-one mapping in IIS 6.0 using C#

    • 32 Comments

    In PSS, we occasionally get requests from our customers wherein they want to automatically add entries for client certificate mapping in IIS or Active Directory (AD). That is either a 1-to-1, Many-to-1 or AD mapping for the client certificate authentication for the web site. I recommend going with AD mapping because that eases the management but it finally depends upon one's need.

    I am not sure but I feel there is a security breach plus annoyance when an administrator has to laboriously enter the mappings for all the accounts/certificates (I am being specific to 1-to-1/Many-to-1 here).

    The concern I feel when dealing with the administrator doing it for 1-to-1 and Many-to-1 are:

    a. If there are hundreds of users you need to do this manually for everyone of those accounts and it's a pain.

    b. Yes, the above can be automated using a script but then the second concern that arises is that whoever is running the script has to know the passwords for all these accounts to be mapped. I think this doesn't sound good.

    I have written a sample application using which users can enter the mappings themselves in the IIS's Client certificate setting, i.e. entries having the client certificate mapped to a windows account (either a local IIS or AD account) and the corresponding password.

    So this is how it works:

    • User accesses this web page from their workstation which already has the client certificate installed.
    • They are authenticated over Basic with SSL.
    • Browser sends across the client certificate as part of the HTTP web request.
    • This application gathers the user account, password plus the client certificate from the incoming HTTP web request and does the mapping in IIS.

     

    image

    I am adding the code here in case someone may want to extract the section for automated scripting instead of using it as a web app.

    This code is also attached to this post as well.

    using System;
    using System.Data;
    using System.Configuration;
    using System.Web;
    using System.Web.Security;
    using System.Security.Cryptography.X509Certificates;
    using System.Web.UI;
    using System.Web.UI.WebControls;
    using System.Web.UI.WebControls.WebParts;
    using System.Web.UI.HtmlControls;
    using System.DirectoryServices;
     
    /* This sample application is to automate One-to-One Client certificate mapping in IIS 6.0.
     * User should be able to access this site from the browser and select the client certificate
     * in their machine which will be mapped to their account on the IIS server for 1-to-1 mapping. 
     * You need to deploy this application on the IIS server which is hosting the website(s) which 
     * needs client certificate mapping, preferably under its own virtual directory.
     *
     * Important:
     * - Have the authentication for this web application configured to use Basic along with SSL.
     * - Have the "Accept client certificates" or "Require client certificates" selected under 
     *   <Website> -> Properties -> Directory Security -> Secure communications -> Edit -> Client certificates
     * - Ensure the website that we want the mapping for is mentioned in the web.config file associated with
     *   this application under <appSettings>
     * - In the Web.config file we are impersonating an Administrator account for this application. 
     *   <identity impersonate="true" userName="Administrator" password="myadminpassword"/>
     *   This is done because non-admin users cannot modify the IIS metabase. If you do not want users to map
     *   entries themselves through web page you can change this to <identity impersonate="true" />.
     *   In such a case only admins can add the mappings for their user accounts. Non-admins won't be able to 
     *   add the client mapping entries.
     *   This is valid for both domain or local Windows NT accounts.
     * - This app is written using .Net 2.0, ASP.Net 2.0 and above in mind. You should be able to make it work
     *   with ASP.Net 1.1 as well.
     * - You may prefer to run this application under its own dedicated application pool to ensure stability and security.
     * 
     * DISCLAIMER: The code is not tested for production scenarios so use it at your own risk. 
     *             In case one wants to use batch scripting etc or some kind of console app instead 
     *             of web app you can extract the code section from this page which should work fine for the job.
     */
     
    public partial class _Default : System.Web.UI.Page 
    {
        protected void Page_Load(object sender, EventArgs e)
          {
            Response.Write("<B>Client Certificate One-to-One Mapping Application:</B><BR><HR>");
            Response.Write("Serial number: " + Request.ClientCertificate.SerialNumber + "</BR><HR>");
            Response.Write("Issuer: " + Request.ClientCertificate.Issuer + "</BR><HR>");
            Response.Write("Subject Name: " + Request.ClientCertificate.Subject + "</BR><HR>");
            if (Request.ClientCertificate.IsPresent)
            {
                Response.Write("Validity<BR>");
                Response.Write("&nbsp;&nbsp;&nbsp;&nbsp;Not before: " + Request.ClientCertificate.ValidFrom + "</BR>");
                Response.Write("&nbsp;&nbsp;&nbsp;&nbsp;Not after: " + Request.ClientCertificate.ValidUntil + "</BR><HR>");
            }
            else
                Response.Write("<B>There is no client certificate sent along with the request!</B><HR>");
     
            Response.Write("Authenticated User: " + Request.ServerVariables["AUTH_USER"] + "</BR><HR>");
            Response.Write("Authentication Type: " + Request.ServerVariables["AUTH_TYPE"] + "</BR><HR>");
        }
        protected void Button1_Click(object sender, EventArgs e)
        {
            string user = Request.ServerVariables["AUTH_USER"];
            string password = Request.ServerVariables["AUTH_PASSWORD"];
            string clientCertMappingName = "Mapping for " + user;  // <--- Our One-to-One Mapping name for the entry
            HttpClientCertificate cert = Request.ClientCertificate;
            /*
              If you want to map a client certificate located on the disk instead of the one as part of the 
              HTTP Web request try the code below.
              
              X509Certificate certificate = X509Certificate2.CreateFromCertFile(@"c:\cert.cer");
              X509Certificate certificate = cert.Certificate;
              byte[] certHash = certificate.GetRawCertData();
            */
            byte[] certHash = Request.ClientCertificate.Certificate;
            try
            {
            //Get the name of the Web site for which mapping has to be done from the App settings in the web.config file.
            string friendlyWebsiteName = ConfigurationManager.AppSettings["websitename"].ToString();
     
            //Get the Site Identifier based on the friendly name of the Web Site.
            string siteId = getsiteid(friendlyWebsiteName);
     
            if (siteId != null)
                {
                string sitePath = "IIS://localhost/W3SVC/" + siteId + "/IIsCertMapper";
                using (DirectoryEntry de = new DirectoryEntry(sitePath))
                {
                    de.Invoke("CreateMapping", new object[] { certHash, user, password, clientCertMappingName, true });
                }
                Response.Write("Account Mapped: <B>" + Request.ServerVariables["AUTH_USER"] + "</B></BR>");
                Response.Write("Mapping Name: <B>" + "Mapping for " + Request.ServerVariables["AUTH_USER"] + "</B></BR>");
                Response.Write("Web Site: <B>" + friendlyWebsiteName + "</B></BR>");
                }
            else
                {
                Response.Write("<B>Web Site does not have a valid Site ID. Ensure we have the correct site name in the config file for this app.</B>");
                }
            }
            
            catch (System.Runtime.InteropServices.COMException)
            {
                Response.Write("A COM exception occurred while setting up the mapping.");
            }
            catch (SystemException)
            {
                Response.Write("An error occurred while setting up the mapping.");
            }
            catch (Exception)
            {
                Response.Write("An error occurred while setting up the mapping.");
            }
           
        }
     
        public string getsiteid(string websitename)
        {
            DirectoryEntry root = new DirectoryEntry("IIS://localhost/W3SVC");
            try
            {
                string siteid = null;
                foreach (DirectoryEntry de in root.Children)
                {
                    if (de.SchemaClassName == "IIsWebServer")
                    {
                        if (websitename.ToUpper() == de.Properties["ServerComment"].Value.ToString().ToUpper())
                            siteid = de.Name;
                    }
                }
                if (siteid == null) return null;
                return siteid;
            }
            catch
            {
                return null;
            }
            finally
            {
                root.Close();
            }
        }
    }

     

    Ciao

    Nice weekend!

  • Care, Share and Grow!

    Unable to load DLL 'bcrypt.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)

    • 2 Comments

    I recently had the privilege to get access to a machine from a colleague of mine. It was a Windows server 2003 server and I had to test some ASP.Net application for one of my pet projects. I was focusing completely on the project at hand before I was completely taken off by a surprise, although not a pleasant one.

    I found that my application was throwing the following exception, in fact forget my own application even a test Asp.Net 2.0 page having just a one word was failing. Also this happened for web resources hosted directly in IIS. If you run this app from within Cassini (ASP.Net Web server) you may not see this issue at all. This happened for both Website as well as WAP based applications hosted in IIS.

    Server Error in '/' Application.
    --------------------------------------------------------------------------------
    
    Unable to load DLL 'bcrypt.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E) 
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.DllNotFoundException: Unable to load DLL 'bcrypt.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)
    
    Source Error: 
    
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below.  
    
    Stack Trace: 
    
    
    [DllNotFoundException: Unable to load DLL 'bcrypt.dll': The specified module could not be found. (Exception from HRESULT: 0x8007007E)]
       Microsoft.Win32.Win32Native.BCryptGetFipsAlgorithmMode(Boolean& pfEnabled) +0
       System.Security.Cryptography.Utils.get_FipsAlgorithmPolicy() +140
       System.Security.Cryptography.RijndaelManaged..ctor() +13
       System.Web.Configuration.MachineKeySection.ConfigureEncryptionObject() +232
       System.Web.Configuration.MachineKeySection.EnsureConfig() +156
       System.Web.Configuration.MachineKeySection.GetEncodedData(Byte[] buf, Byte[] modifier, Int32 start, Int32& length) +37
       System.Web.UI.ObjectStateFormatter.Serialize(Object stateGraph) +166
       System.Web.UI.ObjectStateFormatter.System.Web.UI.IStateFormatter.Serialize(Object state) +4
       System.Web.UI.Util.SerializeWithAssert(IStateFormatter formatter, Object stateGraph) +37
       System.Web.UI.HiddenFieldPageStatePersister.Save() +79
       System.Web.UI.Page.SavePageStateToPersistenceMedium(Object state) +105
       System.Web.UI.Page.SaveAllState() +236
       System.Web.UI.Page.ProcessRequestMain(Boolean includeStagesBeforeAsyncPoint, Boolean includeStagesAfterAsyncPoint) +1099
    
     
    
    
    --------------------------------------------------------------------------------
    Version Information: Microsoft .NET Framework Version:2.0.50727.3053; ASP.NET Version:2.0.50727.3053 

    This was quite perplexing as I couldn't find much information on this across the net. One incident I found talked about un-installation of  MS07-040 security update. I was running on .Net framework 2.0 Sp2, Windows Server 2003 SP2. No luck with it. I had no clues about this dll which was missing as in the exception and why the heck it was looking for it in the first place.

    The interesting part here was that the call stack looked like having some encryption/decryption algorithm (RijndaelManaged) being used perhaps related to viewstate. I finally had to disable the attribute EnableViewStateMac="false" for the web page to make it work, but well that may not be an option all the time for everyone.

    If you face such a scenario just don't go ahead with reinstallation of .Net framework 2.0, it may not help you but only drain your precious time.

     

    Analysis/Resolution

    From this KB article this is what RijndaelManaged is all about.

    "ASP.NET 2.0 uses the RijndaelManaged implementation of the AES algorithm when it processes view state data. The ReindaelManaged implementation has not been certified by the National Institute of Standards and Technology (NIST) as compliant with the Federal Information Processing Standard (FIPS). Therefore, the AES algorithm is not part of the Windows Platform FIPS validated cryptographic algorithms."

    To work around this either set EnableViewStateMac to false or else add the following entry as mentioned in the kb under <system.web> section for the web application.

    <machineKey validationKey="AutoGenerate,IsolateApps" decryptionKey="AutoGenerate,IsolateApps" validation="3DES" decryption="3DES"/>

    ASP.NET use the Triple Data Encryption Standard (3DES) algorithm to process view state data instead of the AES (Rijndael) algorithm. Remember this is comparatively weaker than Rijndael based encryption and hence your application will be comparatively insecure.

     

    *Note that the error message in the above article is not exactly the same as what I saw here for this post but the resolution remains the same :-).

     

    Till next time..Beer mug

  • Care, Share and Grow!

    Asp.Net Request routing implementation fails with Null Reference exception

    • 3 Comments

    I recently had the pleasure of working on the implementation of Asp.Net Request Routing feature that comes in bundled with .Net Framework 3.5 SP1. This is a cool stuff wherein care has been taken to ensure it can be used independently of MVC Framework. It can be used with Dynamic Data as well as implemented for any generic Asp.Net 2.0 application for Request routing functionality.

    *Remember this is different from ASP.NET 2.0's URL Mapping.

    The aim of this post is so obvious for many but I am writing this post because I couldn't get any pointers on this over the Internet, although I know I should have checked the end resolution in the very beginning; silly of me.

     

    We were getting the following exception when we we were trying to route a request. Exception was being thrown from within our custom class implementing IRouteHandler.

    Server Error in '/' Application. 
    ________________________________________
    Object reference not set to an instance of an object. 
    Description: An unhandled exception occurred during the execution of the current web request. Please review the stack trace for more information about the error and where it originated in the code. 
    
    Exception Details: System.NullReferenceException: Object reference not set to an instance of an object.
    
    Source Error: 
    An unhandled exception was generated during the execution of the current web request. Information regarding the origin and location of the exception can be identified using the exception stack trace below. 
    
    Stack Trace: 
    
    [NullReferenceException: Object reference not set to an instance of an object.]
       System.Collections.Generic.Dictionary`2.GetEnumerator() +38
       Mycustomdll.Net.RouteHandler`1.GetHttpHandler(RequestContext requestContext) in C:\abcdedfgh\myprojectforfun\asdfsdf\Net\RouteHandler.cs:37
       System.Web.Routing.UrlRoutingModule.PostResolveRequestCache(HttpContextBase context) +106
       System.Web.Routing.UrlRoutingModule.OnApplicationPostResolveRequestCache(Object sender, EventArgs e) +80
       System.Web.SyncEventExecutionStep.System.Web.HttpApplication.IExecutionStep.Execute() +68
       System.Web.HttpApplication.ExecuteStep(IExecutionStep step, Boolean& completedSynchronously) +75
    

    This application was failing for one of my customers in his environment. I was finally able to reproduce this problem locally on one of my machines as well. Found that ideally this should work fine if you have the latest build.

    On debugging found it was failing at the section shown below in the custom Routehandler class while trying to iterate through the RouteValueDictionary collection even though there were items in the collection. It was failing with the null reference exception.

    public class RouteHandler:IRouteHandler
         {
            ...... 
            ......
           public IHttpHandler GetHttpHandler(RequestContext requestContext)
            {
                 foreach (var value in requestContext.RouteData.Values) <------------
                 {
                     .....
                 }
                 .....
                 .....
                 return (Page)BuildManager.CreateInstanceFromVirtualPath(VirtualPath, typeof(Page));
            }
         } 

    You may see this crash behavior if you are running with the build version of System.Web.routing as shown below. I assume this is from the ASP.Net 3.5 SP1 Beta release, not sure. 

    image

    In order to rectify this issue ensure you move to the latest build for System.Web.Routing.dll as well as for System.Web.Abstractions.dll.

    image

    Lesson: Never try to run Beta/CTP version etc. on the production environment. Ensure you have the latest bits deployed.

     Coffee-cup

Page 1 of 3 (71 items) 123