Host Hopping Cookies

It started with a tweet on Saturday morning.

@MsIngalls: When I go to the Checklist in @Desire2Learn -when I am logged in – I get an error message that says my log in has expired – ideas? #d2l

This sounded like an issue we had in WebCT Vista product I called Failed Sessions. FSes occur when the user is actively working in the product and suddenly gets dumped to the login page. Not to be confused with Login Loop which is providing the correct username and password but never getting a valid session. I hated working either issue because they were never repeatable. The problem could involve any piece of software that could somehow touch a cookie on the user’s computer. Occasionally they were the fault of Weblogic too.

I recommended Amy open a Desire2Learn ticket through our portal on behalf of the professor. I also started my own investigation.

First, I poked around in the logging database for errors involving checklist. I found different courses not the one involved.

Second, I pulled out of our load balancer logs the id number for the course. That yielded plenty of data showing the problem.

These, I added to the ticket and suggested capturing the HTTP headers should the issue not be repeatable by others. Of course, the support agent was not able to repeat it. The headers clearly showed the cookies were not sent.

The professor of course poked holes all through my suggestions of tracking down which of the many software is involved. Different software, hardware, networks, and browsers meant the cause was probably not something residing on the computers. But the issue definitely was still all of these browsers in a wide variety of places all chose not to send the cookies. This is also when he dropped the next bomb that the problem only occurs on links in a specific widget.

Checking the code behind the widget, I only saw simple absolute URLs. Which made me shudder because earlier this week absolute URLs in the login page for a development site put me in production without me being aware for several minutes.

PSA: Only use absolute URLs when sending a visitor to another web server. Say you are here, at www.ezrasf.com and you want someone to see another of my blog entries. Drop http://www.ezrasf.com from the URL and start the path with / (a relative URL). Should I change the host name to blog.ezrasf.com or www.ezrafreelove.com, then the link has better success of working.

It turns out the problem is the professor used the pre-production host name for the web application. The widget absolute URL links used a different host name for production. Both resolve to the same servers. But cookies are tied to a specific host name. So being logged into one of host and getting a link to the variant means the session is not valid at the variant.

At least the workaround and fix are easy.

The workaround for the professor is to stop using the pre-production URL.

The fix is for the widget designer to turn the absolute URLs to relative URLs since they point to same location.

Also, it would be nice for a better error message than:

No Login

Either you have failed to login, or your login has expired.

First the comma is bad grammar. Second, if I am a normal user who encounters this problem, then what can I do to fix it myself? This is not an error someone sees if their password or username are wrong. This is also not what a user normally sees when they are idle too long. But then again, there are lots and lots of potential causes and solutions.

Detecting .NET Version

Background: We got a notice a few minutes before last week’s maintenance window that side work to configure a tool ran into a snap. Today we found out that the server intended to be used did not have the right .NET version. Why did they not just install it? Good question.

This made me curious about which of the 114 servers have which version. So I found a Stackflow post on identifying .NET version. I then wrote this Powershell wrapper script around one of the solutions. The one I picked looks at the registry keys.

# Get my list of servers
$computers = Get-Content ‘server_list.txt’

# Contact each server in the list in order before moving on to next
foreach ($computer in $computers)
{
# Remote connect to current server
Invoke-Command -computername $computer -scriptblock {
# ID host name
$remotehostname = c:\windows\system32\hostname.exe
# Find largest .NET version
$dotnet = Get-ChildItem ‘HKLM:\SOFTWARE\Microsoft\NET Framework Setup\NDP’ | sort pschildname -des | select -fi 1 -exp pschildname
# Write hostname and .NET version
Write-Host “$remotehostname == $dotnet”
}
}

The foreach loop essentially forces the Invoke-Command to do the test in order. This is slower as it contacts the remote server, does the commands, then closes the connection. Without it, servers would respond at about the same time and the output reside on the same line and out of order.

Probably there are better ways to do this, but I am just a beginner.

Also on the Stackflow page there are better approaches. Because uninstalling .NET does not remove the registry keys, this method is vulnerable to be incorrect. I guess that is a possibility.

Oh, on which have what: 22 have .NET2, 48 have .NET3.5, and 44 have .NET4. Not consistently obvious factors like version of the application, life cycle tiers, or anything obvious explain why which have what. Though, they do tend to be the same version within the same cluster of servers.

Convert Webserver.log to CSV

A security guy at a campus wanted our web server log file in the CSV format. The original file has lines which look something like:

machine.usg.edu: webserver.log13646,2010-11-30        11:08:32        0.0010  999.999.999.999    b7tPM1hTgGYMn90bLTM1    200     GET     /webct/urw/lc987189066271.tp1333853785371/blank.html    –       262     “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4” username:0:0

Turns out I only need three sed edits to make it look the way I want:

sed ‘s|:2009-|,2009-|g’ testfile.txt | sed ‘s|\t|,|g’ | sed ‘s|: |,|g’

The first converts the colon between the end of the file name and the year into a comma. The second converts all the tabs into commas, and the last changes the colon-space between the host name and webserver.log into a comma.

Easy enough. That line from the web server log now looks like:

machine.usg.edu,webserver.log13646,2010-11-30,11:08:32,0.0010,999.999.999.999,b7tPM1hTgGYMn90bLTM1,200,GET, /webct/urw/lc987189066271.tp1333853785371/blank.html,-,262, “Mozilla/5.0 (Macintosh; U; Intel Mac OS X 10_6_5; en-us) AppleWebKit/533.19.4 (KHTML, like Gecko) Version/5.0.3 Safari/533.19.4”,username:0:0

I love regular expressions.

I have a feeling I’ll need to make a primer for this guy too. 🙁

Hostname,Log Name, Date, Time, Seconds to Process, Load Balancer IP, Session ID, HTTP Response Code, HTTP Method, URI, URI Parameters, Bytes Returned, User Agent, Username:Transactions Read:Transaction Written