Select Page

New programming language of choice – Ruby

I have fallen out of love with Perl some time ago, I cannot point to one specific thing about it that put me off, I think it’s just a general un-sexyness about it now.

I have been doing some Java and PHP development that was very OOP heavy and have been doing OO coding since school in the Pascal 6 days, I find it’s almost become the natural way of thinking when thinking about problems.  OO though does not generally translate well to scripting tasks which is what I generally use Perl for so it’s not been too bad.

I am however a Perl 4 coder, Perl 5’s OO syntax really puts me off, I’ve used it, have written some pluggable systems in the past where plugins were Perl Ojbects, but I’ve never liked them…with Perl 6 coming (or not) having to relearn a large chunk of Perl is becoming inevitable so I figured I might as well switch.  This is a decision I’ve made ages ago.

I could however not decide on where to go from here?  There are several contenders out there for scripting languages thesedays and weighing up their merits is a time consuming business for sure. 

So along came Puppet, I am doing massive amount of Puppet work now for 3 clients and my own systems.  Puppet is extendible using Ruby code as it’s written in Ruby itself so I think the decision has been made.  I still have no interest in using it on the web, but for scripting I’ve found my new love.

I wont go into long examples and discussions about the Ruby Language, but I’ll say I have learned in the space of a week on the train and have found it incredibly friendly and usable.  The Core and Standard Libraries are rich and modern including out of the box XML, YAML, SOAP, XML-RPC and very powerful networking libraries such as GServer.

Documentation has been generally good but I did buy a copy of Beginning Ruby From Novice to Professional which I believe is a awesome introduction to the language, I followed that up with The Ruby Way 2nd Edition and Ruby Cookbook.

Beginning Ruby takes you on a gentle stroll through a lot of the major features of the language, shows you Strings, Arrays, Numbers, OO, Threads, Sockets and RPC.  It doesn’t go too deep into any of these subjects, for instance it does not show much about Mutexes or any locking methods inside threads, but it puts down a very solid framework to go from.

The Ruby Way is more task based and goes into more detail about the tasks, returning to the threads example, The Ruby Way discusses Mutexes and shows some of the concurrency issues you can expect, it has a whole chapter devoted to Threading. 

These two books more than put you in a position to quickly and effectively use any of the online documentation resources so I would greatly recommend this combination.

I have skimmed through the Cookbook, it’s your typical O’Reilly Cookbook – I mostly bought it because I have 6 or 7 other Cookbook titles and they are all invaluable, I spent an hour with it so far and it looks to live up to this reputation.

If you’ve programmed before in any serious way picking up Ruby should be a walk in the park, the syntax is great, the language does what you’d expect and as you’ll see in my next post spending a week with it on and off is enough to write a capable multi threaded socket server.

On working from home

I’ve not been posting much here, work has been incredibly manic the last while, especially I need to still finish off my SSO posts with the last installment, for now though, some thoughts on my work arrangement and freelancing.
 
I have been working from home as self employed since around December (self employed for longer) and as before when I’ve done many months of home working it has started to get to me.

In the past I generally had an office to go to but didn’t unless I had to, worked from home when I could, home is nearer to the Data Center than the office and generally home has better workstations.

Now as I am self employed I do not have an office to go to and I’ve also realised that all the reading I have done in the past were generally on the train while commuting, and this is something that I cannot let slip but just do not get around to reading while at home.

So I now have an office in London Soho, it is just a desk in a shared office full of other freelancers and startups but for the last 2 weeks I have been pretty happy, I have learned Ruby (more about that in my next post) and I am finding I really enjoy the ritual of going to an office again, but an office where there aren’t project managers and other people waiting to harass you, I think that is the main ingredient.

I will probably stay at this office till the clocks change for winter time, then I’ll be working from home again till the summer.  The main thing is I have the freedom to choose now and that more than anything is what I love about self employment.

Rework of puppet facts for /etc/facts.txt

Previously I blogged a custom fact that reads /etc/facts.txt to build up some custom facts for use in Puppet manifests, well I’ve since learned a thing or two about Ruby and have improved the code, new code below:


if File.exists?(“/etc/facts.txt”)
   File.open(“/etc/facts.txt”).each do |line|
      var = nil
      value = nil

      var = $1 and val = $2 if line =~ /^(.+)=(.+)$/

      if var != nil && val != nil
         Facter.add(var) do
            setcode { val }
         end
      end
   end
end

As I mentioned previously I knew the code was horrible and had a whole redundant loop in it but couldn’t get it going otherwise.  The big change is in choice of variable names to use inside the setcode, sees value must be a reserved word or something, so now the code is much cleaner.


				
					

Designing a Single Sign On system – part 3

This is the 3rd part of my ongoing series of posts about designing a
simple Single Signon System for PHP, you should read part 1 and 2 first.

Today we look a bit more about the general information flow between browser, target web site and the SSO Server.  We will use the term Secure Site for the target site, lets say a corporate intranet.

The following diagram shows the flow of information, the information flows via the browser using redirects etc.

First a few words on the requierd bits of information before this exchange can happen.

  • The
    Secure Site has a pre-shared key (PSK) that the SSO Server assigns,
    this key gets hardcoded in the Secure Site and kept private, it never
    gets passed between the parties during normal authentication requests.
  • The Secure Site has a siteid
    that is simply a number that uniquely identifies it to the SSO Server. 
    This too gets assigned by the SSO Server and does not change for the
    life time of the site.
  • Encryption gets done using a simple symmetrical algorithm, the PSK is the passphrase.
  • The
    SSO server knows what domain name a site is in, the SSO Server will use
    this to validate auth requests and generate redirects based on this
    domain name only.

Now on to the actual information flow, this demonstrates the flow for a first time visit of an unauthenticated user, future visits will be exactly like any cookie based auth system where the user will not interact with the SSO server at all:

  1. The user tries to access the Secure Site
  2. Secure Site generate a unique single use token, and saves it in a Session
  3. The Secure Site redirect the browser to the SSO server with a request that has the siteid unencrypted and a encrypted string containing the URL the browser should go to if he is authenticated correctly by the SSO Server and also the Token generated in step 2.
  4. The SSO Server validates the request, checking Next URL against that stored for siteid after using the PSK stored for siteid to decrypt the packet.
  5. The user is presented with a login form.  The login form shows detail about the Secure Site such as its URL, a description of the site and who to contact with any support requests about this site.  The user is warned that his personal details will be shared with the site.  The user logs in with a username and password and gets redirected to the Secure Site.
  6. The Secure Site gets a authentication packet in the redirect that has – encrypted using the PSK – the username, email address, real name, time zone and the previously generated token.  In unencrypted form is a md5 hash of all the private information concatenated with the PSK, this is signature for the request and could be used as a cryptographic digital signature if the SSO Server is configured to not encrypt the private data.  The Token gets removed from the session and the user gets marked as Logged In using a cookie or existing session.
  7. At this point the user is logged in and can access the Secure Site, the Secure Site knows his private details and can associate his data with him.  From this point on it’s a standard cookie based auth and the Secure Site can decide how long the login session is valid for etc.

I think we’ll keep it at that for today, in the next part I’ll explain some of the choices made in designing this protocol and what security exploits it tries to prevent (replay attacks), what it is vulnerable too (man in the middle attacks) and how to mitigate those risks.

Designing a Single Sign On system – part 2

This is the 2nd part of my ongoing series of posts about designing a simple Single Signon System for PHP, you should read part 1 first.

I am often annoyed about series of blog posts that don’t make it clear what the end goal is early on, so you end up wasting time reading through loads of stuff only to realise at the end its a bad fit.  So below you’ll see some sample bits of code using my Single Sign On system in PHP and Apache after this you can easily decide to just ignore the rest of the posts or to keep paying attention.

First as I said the authentication should be pluggable, I want to be able to fetch users from LDAP, MySQL, and any number of other things, towards this goal I made the actual code that does the hard work pluggable by using a simple OO module and an interface.  Below is a bit of code to just always allow a user ‘john’ in with the password ‘secret’, the values for name etc is hardcoded and you can’t change the settings, but you’ll get the basic idea!


<?
class StupidAuth implements pSSO_Authenticator {
    public function 
_authenticate($username$password) {
        if (
$username == "john" && $password == "secret") {
            return(
1);
        }

        return(0);
    }

    public function _getEmailAddress() {
        return(
"john@doe.net");
    }

    public function _getRealName() {
        return(
"John Doe");
    }

    public function _getUsername() {
        return(
"john");
    }

    public function _getTimeZone() {
        return(
"Europe/London");
    }

    public function _setEmailAddress() {
    }

    public function _setRealName() {
    }

    public function _setUsername() {
    }

    public function _setTimeZone() {
    }
}
?>



It doesn’t really come simpler than that, within this framework you really should be able to do almost any form of authentication, if PHP can talk to it and auth then so should the SSO system.  This code will live in the server, I won’t go much into the server here, it’s just a really a system to wrap the code above into a well defined protocol between client and server, more on this some other day.  For now just assume there is a config file on the server and you tell it what Class implements the actual auth – StupidAuth in this case.

Now for a quick client, remember the client can run anywhere on any domain, and I want my clients to be registered with me before they can use the SSO system.  To this end each client has a Pre Shared Key (PSK) and a unique ID.  The PSK is used to encrypt the communications from the SSO server to the SSO client as the reply will have real names, email addresses and such in it, you don’t want this to show up in proxy logs and such!

Here’s a quick client:


<?
    
require("pSSO_Client.class.php");

    $psk "goG4mUrJeacE7VyidEfd";
    
$siteid 1;
    
$ssoServer "http://sso.yourcompany.com/";
   
$thisURL "http://" $_SERVER["HTTP_HOST"] . $_SERVER['SCRIPT_NAME'];

    session_start();

    // the SSO server sent us back a token, validate it and set cookies
    
if (isSet($_GET['authdata']) && ($_GET['v'])) {
        
$psso = new pSSO_Client($_GET['authdata'], $_GET['v'], $psk,
                                     $siteid$ssoServer);
        
        if (
$psso->authenticate()) {
            
// The user is logged in, send him back to this same url
            // except without any GET params etc, so he'll be a normal
            // returning logged in user.
           
header("Location: " .$thisURL);
           
exit;
        } else {
            
// login failed, eventhough it shouldn't have, bail out
            
Throw new Exception ("Login failed:" $psso->getError());
        }
    } else {
        
// We didn't get a token, either its a guest or he already has cookies
        // from a previous visit
        
$psso = new pSSO_Client(""""$psk$siteid$ssoServer);
        if (
$psso->isLoggedIn()) {
            print(
"You are logged in:<br><br>");
            print(
"Your 
username is: " 
$psso->getUserName() . "<br>");
            print(
"Your real name is: " $psso->getRealName() . "<br>");
            print(
"Your email address is: " $psso->getEmailAddress() . "<br>");
            print(
"Your timezone is: " $psso->getTimeZone() . "<br>");
            exit;
        } else {

            print(
"Welcome guest, you can login <a href='" $psso->getAuthURL($thisURL)
                . 
"'>here</a>");
            exit;
        }
    }
?>

A quick run through the code:

  • Define the PSK, SSO Server URL and your unique ID, all of this will be supplied by the SSO server when you register your site.
  • Start a session – this is used to associate a one-time-use token that travels between the SSO client and Server, more on this later but it helps prevent session replay attacks.
  • Check if we got the data that the SSO server will typically pass us $_GET[‘authdata’] and $_GET[‘v’], if we did get it, start up a SSO client and authenticate.  Showing the protected page on success or an error message if it failed.
  • If the GET parameters aren’t present it is either a first visit or a returning visit, the SSO Client lib gets used to find out if its a returning visit and shows some personal information if the user is logged in, else presents the user with a bit of guest info and a link to the login form.  Again here the SSO client library generate all the needed URLs and encryption and what not.

I think this very simple use case should demonstrate the ease of use, you could now easily decide to either just not have a local user database at all, just perhaps ACL’s based on username or some local cached user data that has additional information your app provides in a local database perhaps referenced by username, so relying simply on the SSO for auth.

You’ll remember I also wanted to do HTTP Authentication, I have a beta stage Apache mod_perl module to do this, below you’ll see a bit of Apache config to protect my Nagios installation using the SSO:

        <Directory “/usr/share/nagios”>
               AuthType Apache::Auth_pSSO
               AuthName pSSO
               PerlAuthenHandler Apache::Auth_pSSO->authenticate
               require valid-user
               PerlSetVar pSSO_PSK “goG4mUrJeacE7VyidEfd”
        </Directory>

Again notice the PSK in there, at the moment site id and SSO server URLs are hardcoded, but like I said, its beta code ๐Ÿ™‚

With both of the samples above, instead of a pop-up HTTP Auth dialog, you will simply see the SSO login form if you’ve not authenticated already, else you will just see the protected resource or nagios no questions asked.

So that’s it, a quick run through what can be achieved with the SSO libraries on both server and client, in the next post I’ll get into some details of the protocol between server and client.