February, 2007

  • Never doubt thy debugger

    Unable to attach to process (on localhost)

    • 9 Comments

    Another interesting one I got a few days ago: after installing the SP1 for Visual Studio 2003, the customer was unable to debug his web application (on localhost) neither pressing F5 nor attaching to the target w3wp.exe process. As you can imagine, removing SP1 the problem disappeared. Moreover they had multiple machines running the same OS and software that worked fine, only one particular machine was affected by this problem; more interestingly, other developers were able to remotely debug their application hosted on the affected server, so only debugging on localhost was not working (WinForm debugging was also working fine). Of course the account used to login on the server was a local administrator.

    The target platform we were running on was Windows Server 2003 R2 x64 on AMD Operton 280 (dual core, 2.4GHz) with 4GB RAM; IIS is configured to run in 32 bit mode (w3svc/AppPools/Enable32bitAppOnWin64 = TRUE), and of course Visual Studio .NET 2003 with Service Pack 1.

    To start troubleshooting this I did a quick research in our internal docs and it turner out that his is a known issue due to loopback check; basically the reason is because the underlying DEBUG request is getting a 401 response, causing the debugger to fail. There are two options to resolve this problem:

    Method 1: Disable the loopback check

    • Click Start, click Run, type regedit, and then click OK
    • In Registry Editor, locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa
    • Right-click Lsa, point to New, and then click DWORD Value
    • Type DisableLoopbackCheck, and then press ENTER
    • Right-click DisableLoopbackCheck, and then click Modify
    • In the Value data box, type "1", and then click OK
    • Quit Registry Editor

    Method 2: Specify host names

    To specify the host names that are mapped to the loopback address and can connect to Web sites on your computer, follow these steps:

    • Click Start, click Run, type regedit, and then click OK
    • In Registry Editor, locate and then click the following registry key: HKEY_LOCAL_MACHINE\SYSTEM\CurrentControlSet\Control\Lsa\MSV1_0
    • Right-click MSV1_0, point to New, and then click Multi-String Value
    • Type BackConnectionHostNames, and then press ENTER
    • Right-click BackConnectionHostNames, and then click Modify
    • In the Value data box, type the host name or the host names for the sites that are on the local computer, and then click OK

    The customer applied the first method and then happily started debugging his application smile_regular

     

    Cheers

  • Never doubt thy debugger

    Deploy CAS new code groups

    • 0 Comments

    Yesterday I got a call from a customer who needed some help configuring CAS settings for his application, and after finding the right one for his needs, he asked me how to easily configure all of their few thousands clients with the new settings.

    Well... a quick research brought up the following article: "HOW TO: Build and Deploy a .NET Security Policy Deployment Package"; but the customer wanted to deploy only the new code group we created for the application, and not his entire "Machine" policy... the CAS administration console allows you to create a .msi deployment package for the entire Enterprise, Machine or User, but unfortunately not for a single Code Group.

    The easiest way we found was to run the following command on the clients (through some automation mechanism the customer will identify depending on his needs):
    caspol -machine -addgroup All_Code -site localhost FullTrust -name "code group name"

    The above command will create a new code group at machine level, as child of the group “All_Code”, will use the “Site” membership condition and will set it to “localhost” granting “FullTrust”, and the new code group will be assigned whatever name you’ll set as the “–name” argument (this must be enclosed on double quotes); caspol.exe is part of the .NET Framework so you don’t need to have the SDK installed on the target machines. You can find other samples at Code Access Security Tool (caspol.exe) and How to: Add Code Groups Using Caspol.exe.

    If you need to temporarily disable the policy change warning, have a look here: How To: Suppress policy change warning using caspol.exe.

     

    Cheers

  • Never doubt thy debugger

    Connected again... finally!

    • 0 Comments

    After about 40 days of argues, debates, emails, calls etc... well... finally our beloved Telecom company found some time to give me a phone line and the long awaited broadband Internet connection! clock

  • Never doubt thy debugger

    WebClient 2.0 class not working under Win2000 with HTTPS

    • 0 Comments

    Here is another problem I had a couple of days ago: the customer had a critical problem with on one of his .NET applications: he has migrated it to the .NET Framework 2.0, but it doesn't work anymore under Windows 2000. They have isolated the problem and here is the source code to reproduce the problem:

    using System;
    using System.Text;
    using System.Net;
    
    namespace ConsoleApplication
    {
        class Program
        {
            static void Main(string[] args)
            {
                try
                {
                    string url = "https://myprotectedsite.com";
                    WebClient client = new WebClient();
                    byte[] result = client.DownloadData(url);
                    Console.WriteLine("result len=" + result.Length);
                }
                catch (Exception ex)
                {
                    Console.WriteLine("EXCEPTION: " + ex);
                }
                Console.Write("Type enter to exit");
                Console.ReadLine();
            }
        }
    }

    The code above works properly on Windows XP and Windows 2003, and it displays "result len=582" (or wathever the lenght of the retrieved http stream is). It works also on Windows 2000 if you compile it with Visual Studio 2003 (i.e. .NET Framework 1.1); however if you compile it with Visual Studio 2005, it doesn't work under Windows 2000. This is the exception we got:

    System.Net.WebException: The underlying connection was closed: Could not establish secure channel for SSL/TLS
    at System.Net.WebClient.DownloadDataInternal(Uri address, WebRequest request)
    at System.Net.WebClient.DownloadData(Uri address)
    at System.Net.WebClient.DownloadData(String address)
    at ConsoleApplication.Program.Main(String[] args)

    I first thought to something related to the SSL certificate and asked the customer to check this, but everything was fine on that regard.

    After some more troubleshooting and tests (enabling Systen.Net tracing on my repro machine as expliained in http://blogs.msdn.com/dgorti/archive/2005/09/18/471003.aspx), it turned out that this is due to the SSL3/TLS negotiation: in WinXP and Win2003 when doing the negotiation we try SSL3 first and if that fails TLS, while on Win2000 we try TLS first and then SSL3. According to the RFC the server should allow us to renegotiate if TLS fails, but the server would just return an error that the negotiation was not successful. In the other 2 scenarios we try SSL3 first and it goes successfully.

    This is what I get from the Win2003 log, just before successfully establishing the connection:
    System.Net Information: 0 : [3976] InitializeSecurityContext(In-Buffer length=6, Out-Buffer length=0, returned code=ContinueNeeded)

    This is what I get from the Win2000 log, just before we throw the exception:
    System.Net Information: 0 : [3976] InitializeSecurityContext(In-Buffer length=7, Out-Buffer length=0, returned code=MessageAltered)

    The solution to this is to specify the SSL3 propocol type before issuing the request, adding the following line of code in the try block:

    try
    {
        string url = "https://myprotectedsite.com";
        WebClient client = new WebClient();
        ServicePointManager.SecurityProtocol = SecurityProtocolType.Ssl3;
        byte[] result = client.DownloadData(url);
        Console.WriteLine("result len=" + result.Length);
    }
    

    It was not a WebClient issue, I reproed it with HttpWebRequest hitting that particular URL; that web server won't accept TLS (verified it) and will only work with SSL3.

    Hope this helps if you get something similar...

     

    Cheers

  • Never doubt thy debugger

    ASP.NET 2.0 posts back to ASP.NET 1.1: supported?

    • 1 Comments

    Last week I got an interesting question from a customer, apparently easy but something I really had never thought before...

    They have some ASP.NET 1.1 applications running in their environment, while the new apps they are currently developing, are based on ASP.NET 2.0: from one of those new pages they need to post some form values to an ASP.NET 1.1 page (both running on the same Win2003 server but in different application pools, to avoid the limitation of having just one CLR version per process); they use cross-page postback through the PostBackPage property for the submit button to target the 1.1 page, but this throws an InvalidCastException on LoadPageViewState() (which I guess is expected since 1.1 and 2.0 Viewstates are encoded differently).

    Question: is this scenario supported at all? How could this work? Well... it turns out that the ASP.NET 1.1 and 2.0 viewstate are encoded differently and are not compatible; moreover even if you set EnableViewState="false" at page level this does not completely turns viewstate off, so every time you'll execute the page you'll get the InvalidCastException as before.

    Based on customer's requirements, we identified the following possible solutions:

    • POST from a classic ASP or HTML page: of course, since there is no viewstate posted with the form, we also don't get the exception
    • From 2.0 POST to the same page (ASP.NET default, without using CrossPagePostback) and then do a server side Response.Redirect() to the target 1.1 page passing the parameters to the Query String. Unfortunately it's not possible to use Server.Transfer() because this works only between pages in the same application (while here we had two separate applications). Using the query string is not the best approach if you need to pass sensitive values...
    • If the target page does not need to rely on viewstate, override the LoadPageStateFromPersistenceMedium() method (we simply returned an empty object) so the posted viewstate will be ignored and we'll not throw the InvalidCastException; this has the advantage to be a "standard" POST (we don't use the query string) so the values are not passed in clear text

    Probably I'm missing some other possible solutions, but the above (the latest point) at least fit the customer's requirements...

     

    Cheers

Page 1 of 1 (5 items)