Steve Holstad's "the bright lights"

"Just because your voice reaches halfway around the world doesn't mean you are wiser than when it reached only to the end of the bar." - Edward R. Murrow
in

July 2006 - Posts

That's a creature, not a bug

From printedowl.com's google computer history webpart: (I think stuff like this is great)

The term "Bug" is widely known to be an error or problem in software and hardware systems. The term originates at Harvard University in August 1945 when the Mark I computer project staff notice something is wrong with one of the computer's circuits. After a lengthy search, someone locates and removes a two-inch moth from one of the computer cabinets. From then on, computer problems are referred to as bugs.

Posted: Jul 24 2006, 10:23 AM by sholstad | with no comments
Filed under:
Vista due for January.... Anchorman-style

Sixty percent of the time, Bill Gates releases on time, everytime.  haha

Looks like Bill Gates is 80% sure that Vista will launch in January, while the next version of Office could come as early as December.

http://www.msnbc.msn.com/id/13812973/

He left the 20% as a disclaimer, stating that if beta bugs prove that the software isn't ready for primetime, he won't force a release.  What's the general consensus on this one, is it better to launch late and be more solid, or on-time, with more shaky code?  This is a software team's nightmare....neither is great, but Microsoft tends to have the reputation of "release now, let our production users test it", which is not an ideal strategy, and smells of bad PR when the patches come... I'll stay on the side of delaying to solidify code, and let the world have it when it is ready...

FBI security issues....and no strong passwords, yikes.

This is a pretty amazing story breaking today, and one that raises some SERIOUS questions about consulting, the FBI security policies, and much more.  A consultant working with the FBI's project "Trilogy" downloaded the hashed userkey/password list from the FBI, and ran online cracking programs to match the encrypted passwords to common dictionary words.  Here are some points that truly amaze me:

1) An FBI agent gave him his userkey/pw to gain access to the system

2) Many (most?) of 38,000 passwords were matched to common words, and thereby revealed.  This includes FBI director Robert Muller, which allowed the consultant to view all digital content the FBI has stored.

3) This consultant is charged with 4 counts of this offense...but the concern to me isn't the consultant, but the FBI not enforcing strong password requirements, which would have prevented this type of dictionary cracking.

4) Because of 90 day password expiration policies, this occurred 3 more times.  At what point would the agent think 'hey, this is getting a little weird'?

5) I don't think that this consultant had any plans of doing something harmful, but it serves as a solid reminder to all of us to use test environments & accounts, NOT PRODUCTION accounts!  Fighting through bureaucratic procedures can be tedious, but mistakes happen, and you can be burned badly by the backlash.

Original: http://seattletimes.nwsource.com/html/nationworld/2003107651_fbi06.html

Slashdot: http://it.slashdot.org/article.pl?sid=06/07/06/1431256&from=rss

Gridview Export to Excel

Exporting a gridview control to Excel isn't hard, but I did run into some problems with Response Headers when deploying this functionality to our production site.  Turns out the header settings were set at a global level, so I needed to explicitly set Response.Cache.SetCacheability to 'Public'.  I also noticed that some sites are publishing a version of this code, but it needed a few tweaks to work in some environments. I've upgraded it to work, and have added a few features I needed:

- The aforementioned SetCacheability property is set
- Added the event click code to show how you can export this gridview when AllowPaging is set to true.  Just turn paging off, rebind to data, export, then set paging on and bind again.
- Removed the footer row
- The gridview's headers contained hyperlinks, so I've replaced the cell with the link text after clearing the controls
- I've created an ArrayList of column names to exclude, and passed this to the Export method. 

protected void lnkExport_Click(object sender, EventArgs e)
        {
            // Disable paging
            grdMyData.AllowPaging = false;
            LoadGridData();

            // exluded columns arraylist
            ArrayList defaultExcludedColumns = new ArrayList();

            // Always exclude these columns
            defaultExcludedColumns.Add("MyHiddenFieldName");

            // Send to base Excel export method 
            ExportGridView(grdMyData, "defaultFileName", defaultExcludedColumns);

            // Rebind with paging enabled
            grdMyData.AllowPaging = true;
            LoadGridData();
        }


        /// <summary>
        /// Export GridView data to Excel.
        /// </summary>
        /// <param name="grdView">GridView control to export.</param>
        /// <param name="filename">Filename of excel spreadsheet.</param>
        /// <param name="excludedColumnList">ArrayList of columns to exlude.</param>
     protected void ExportGridView(GridView grdView, string filename, ArrayList excludedColumnList)
        {
            // Clear response content & headers
            Response.Clear();
            Response.ClearContent();
            Response.ClearHeaders();

            // Add header
            Response.AddHeader("content-disposition", "attachment;filename=" + filename + ".xls");

            Response.Charset = string.Empty;
            Response.Cache.SetCacheability(System.Web.HttpCacheability.Public);
            Response.ContentType = "application/vnd.xls";

            // Create stringWriter
            System.IO.StringWriter stringWrite = new System.IO.StringWriter();

             // Create HtmlTextWriter
            HtmlTextWriter htmlWrite = new HtmlTextWriter(stringWrite);

            // Remove controls from Column Headers
            if (grdView.HeaderRow != null && grdView.HeaderRow.Cells != null)
            {
                for (int ct = 0; ct < grdView.HeaderRow.Cells.Count; ct++)
                {
                    // Save initial text if found
                    string headerText = grdView.HeaderRow.Cells[ct].Text;

                    // Check for controls in header
                    if (grdView.HeaderRow.Cells[ct].HasControls())
                    {
                        // Check for link button
                        if (grdView.HeaderRow.Cells[ct].Controls[0].GetType().ToString() == "System.Web.UI.WebControls.DataControlLinkButton")
                        {
                            // link button found, get text
                            headerText = ((LinkButton)grdView.HeaderRow.Cells[ct].Controls[0]).Text;
                        }

                        // Remove controls from header
                        grdView.HeaderRow.Cells[ct].Controls.Clear();
                    }

                    // Reassign header text
                    grdView.HeaderRow.Cells[ct].Text = headerText;
                }
            }

            // Remove footer
            if (grdView.FooterRow != null)
            {
                grdView.FooterRow.Visible = false;
            }

            // Remove unwanted columns (header text listed in removeColumnList arraylist)
            foreach (DataControlField field in grdView.Columns)
            {             
                if (excludedColumnList.Contains(field.HeaderText))
                {
                    field.Visible = false;
                }
            }

            // Call gridview's renderControl
            grdView.RenderControl(htmlWrite);

            // Write Response to browser
            Response.Write(stringWrite.ToString());

            Response.End();
        }

         /// <summary>
         /// This allows Excel Exporting to function correctly, notifying Export function that control resides in server form.
        /// </summary>
        /// <param name="control"></param>
        public override void VerifyRenderingInServerForm(Control control)
        {
            // Confirms that an HtmlForm control is rendered for the specified ASP.NET server control at run time.
            // Required for Excel exporting
        }

Simple web.config encryption

Building an ASP.NET website is becoming easier with each new release of the .NET framework, but as the learning curve flattens and more and more developers create forward-facing sites, security concerns need to be considered. One of the easiest new methods of ensuring that confidential information remains secure is to encrypt sensitive sections of your web.config file.

Encrypting this information has never been easier, and should be included in the site's deployment task list, or incorporated as a custom task within the deployment files. You can take advantage of the power of the aspnet_regiis utilty to handle this task post-deployment:

Open up your Visual Studio 2005 command propmt tool, and run the following command:

aspnet_regiis -pe "connectionStrings" -app "/clarity" -prov "DataProtectionConfigurationProvider"

Let's take a quick look at the parameters we entered:

-pe: the encryption argument to aspnet_regiis utility

"connectionStrings": specifies the subsection of the web.config to encrypt

-app "/clarity": the encryption should occur at this virtual path

-prov "DataProtectionConfigurationProvider": determines the type of encryption to perform. Use DataProtectionConfigurationProvider to apply encryption via the Windows DPAPI. I find this is easier to use for basic encryption. This method will generate the decryption key and place it in the Local Security Authority.

The default encryption type is "RSAProtectedConfigurationProvider" uses the .NET Framework's RSACryptoServiceProvider class' public key algorithm.

Once you've encrypted your web.config sections, you're set. The beauty of this is that you as a developer need not do anything to your code to decrypt this information. Any component that requires access to an encrypted section will automagically decrypt this information.

In the event you would like to decrypt the section for modification or testing, simply run this command:

aspnet_regiis -pd "connectionStrings" -app "/clarity"

Notice that -pe has changed to -pd, which notifies the utility that the section should be decrypted.

Keep in mind this is ONE of the many things developers and net admins should be concerned with when deploying a web site to production. If your server isn't secure, these precautions won't mean much. But taking these steps is an important piece of the security puzzle.