Archive for June, 2012

Local Build Using/Incrementing Team City Version Number

Jun 18

On my current project we have a problem in that one of the assemblies we use requires an expensive license that is per computer so our build server would need it’s own license which we are not doing at this point. Now I need to run our publish deploy script locally which means manually increasing the version number on each build. Something that has been missed before causing a new version to overwrite an old version… which is bad… very bad.

To combat this I started digging and found a way to have my build script use and change the TeamCity build counter remotely using their REST API.

First open up http://[Server]/httpAuth/app/rest/projects/ and find your project you want to work with.

Then open up http://[Server]/httpAuth/app/rest/projects/id:project2 and find the configuration you want to work with.

Then open up http://[Server]/httpAuth/app/rest/buildTypes/bt5/settings/buildNumberCounter to get the current build counter

Here is the C# code I use

    public class TeamCityVersionIncrementer
    {
        private readonly string _buildCounterUri;
        private readonly NetworkCredential _credentials;
        public TeamCityVersionIncrementer()
        {
            _buildCounterUri = “http://[server]/httpAuth/app/rest/buildTypes/bt5/settings/buildNumberCounter”;
            _credentials = new NetworkCredential(“[user]“, “[pass]“);
        }
        public int Increment()
        {
            int originalCounter = GetBuildCounterFromTeamCity();
            UpdateCounter(originalCounter + 1);
            int counterAfterIncrement = GetBuildCounterFromTeamCity();
            if (counterAfterIncrement != originalCounter + 1)
            {
                throw new ApplicationException(“Expected build to be incremented to ” + (originalCounter + 1) + “but was ” + counterAfterIncrement);
            }
            return counterAfterIncrement;
        }
        private int GetBuildCounterFromTeamCity()
        {
            WebRequest webrequest = WebRequest.Create(_buildCounterUri);
            webrequest.Credentials = _credentials;
            webrequest.Method = “GET”;
            WebResponse webResponse = webrequest.GetResponse();
            using (var reader = new StreamReader(webResponse.GetResponseStream()))
            {
                string readToEnd = reader.ReadToEnd();
                return int.Parse(readToEnd);
            }
        }
        private void UpdateCounter(int number)
        {
            byte[] arr = Encoding.UTF8.GetBytes(number.ToString());
            var request = (HttpWebRequest)WebRequest.Create(_buildCounterUri);
            request.Method = “PUT”;
            request.ContentType = “text/xml”;
            request.ContentLength = arr.Length;
            request.Credentials = _credentials;
            Stream dataStream = request.GetRequestStream();
            dataStream.Write(arr, 0, arr.Length);
            dataStream.Close();
            var response = (HttpWebResponse)request.GetResponse();
            if (response.StatusCode != HttpStatusCode.NoContent)
                throw new ApplicationException(“Unexepected status code: ” + response.StatusCode);
        }
    }

Hope that helps someone in this rare situation!

Filed Under: General

LinkedIn Hashes Leaked

Jun 6

Today it is being reported that LinkedIn has 6.5 million hashes leaked. It is good to see that the passwords were hashed. Unfortunately, it was done in a poor fashion.

The main issue is that salts were not used. Salts add random data per password and then are hashed. This makes things drastically harder to crack. Why? Well in attacking a database of hashes (without salts) the procedure is:

  1. Generate a password
  2. Hash the password
  3. Compare the hash to all items in the database

This means that we generate one hash and check it against every account. If we add salts to the mix we have to work on a password at a time

  1. Load hash and salt from database
  2. Generate a password
  3. Hash the password + salt
  4. Compare the generated hash to the one record

For this scenario we have to crack a user at a time which is a huge time increase. Also, we don’t know how the salt was used internally. It could be:

  • password + salt
  • salt + password
  • salt + password + salt
  • FirstHalfOfSalt + password + LastHalfOfSalt
  • etc.

 

Lack of salting is a big failure here and I don’t see why it was not done. The other issue is the use of SHA-1 as the hashing algorithm which is no longer recommended. SHA-1 is fairly strong but has some collision weaknesses (two words generate the same hash which reduces the amount of time to generate all hashes). It is recommended to use SHA-256 or higher to avoid this issue.

While this may have been an oversight of the developers involved it is more likely a case of hash/crypto phobia. It is scary dealing with hashes and crypto as if you screw up data could be irreversibly lost. As developers we always want recoverability and not to mess with things that are working. Unfortunately for this sort of data we have to face the problem.

Now the big issue people face is migrating hashes from one scheme to another. Most leave it as is because hashes are one way so we can’t reverse the hash to upgrade it to a new format. It is quite easy to do though in a way that allows a seamless migration:

  • Add in new fields to store the new format into your database
  • When a user successfully logs in, take the password they typed in (which would be the plain text version) and run it through the new algorithm.
  • Store the output into the new database fields
  • Remove the original hash (the one we are replacing) from the database

As users login they get upgraded to the new scheme. It takes very little logic and time to implement this. The more users that login the stronger the database store gets.

Filed Under: Security

Syncing Facebook/Meetup/Google Calendar On My phone

Jun 5

One issue I have been running into is not adding my facebook/meetup events onto my phone. I then miss these events or forget until the last minute. I thought there must be a way to automate this and after a bit of tinkering I got it to work.

I am on an iPhone that uses Google Calendar as it’s calendar provider. I assume that the steps will be the same for any device that supports Google Calendar:

Facebook

  1. Click events on the left
  2. click export events
  3. copy the url
  4. login to google calendar
  5. under other calendars click “add by url”
  6. paste in the url for your fb calendar

Meetup

  1. On the main page click the “add to” right above the calendar
  2. Click the Google Calendar icon
  3. It will open up the google calendar website and prompt you to add it

Once this is done the calendars did not appear on my phone. Some people posted to add them by visiting: https://www.google.com/calendar/iphoneselect which did nothing for me.

After a bit more reading I found that if I opened http://m.google.com/sync on my phone I could check off the calendars I wanted to snyc and viola there they were.

 

Filed Under: General