Automated Coder

Exploring the Code of CruiseControl.Net

Archive for January, 2009

Public Service Announcement

Posted by Craig Sutherland on 28 January, 2009

Do You Want to Modify CruiseControl.Net?

One of the things about CruiseControl.Net being open source is that things only change if people give of their time to make changes. Currently there’s about four or five of us who make changes to the code (at least based on the check-ins), so sometimes things just don’t happen (or things that people would like don’t happen).

Now there are a number of reasons why people don’t contribute code, but one of them is the complexity of the project (it has grown organically over the past few years). To try and overcome this issue Ruben has started posting a series of tutorials on coding for CruiseControl.Net. You can read these articles on his blog (http://rubenwillems.blogspot.com/).

Additionally if there are other things we could do to make it easier to contribute, please let me know :)

Posted in CruiseControl.Net | Tagged: , | Leave a Comment »

Changing to Messages

Posted by Craig Sutherland on 28 January, 2009

There’s Too Many Arguments!

Recently I added dynamic parameters to CruiseControl.Net. This caused a large number of method signatures to change – in multiple classes. After the project lead saw these changes, he mentioned that we’re probably not using the best approach for passing arguments, especially as in future we could potentially add more arguments!

At the same time this offers some possibilities for future-proofing. While we can’t move to WCF (at least for a while yet), we can set things up so a move to WCF is easy.

Some Messaging Approaches

Before I implement messaging, the question arises as to what is the best way to do it? There are a number of different models for messaging, so I’m going to quickly look at three.

One Way Messaging

Messaging-OneWay

In this model messages are sent from the client to the server. Nothing comes back from the server at all.

While this is nice and simple, there is no way of checking that the server has received the message and that the message is valid. It’s kind of like dropping a message into a black hole and hoping that it works.

This is how CruiseControl.Net Remoting works in many ways. When a force/abort build, start/stop project or other similar request is sent, it is assumed that they will work. As part of the security changes I turned on exception reporting, but this is using .Net Remoting instead of a reply from the server.

Two Way Messaging

Messaging-TwoWay

This is similar to one-way messaging, except the server also sends back a response. Depending on the action, this response could be immediate or it could take a long time.

Most of the information requests to CruiseControl.Net use this model (e.g. get snapshot, get projects statuses, etc.) The server gets the request, processes it immediately and sends back the response.

Asynchronous Two Way Messaging

Messaging-TwoWayAsync

In this model the request and response are decoupled. Instead an acknowledgement is returned (ack for short) letting the message sender know that the message has been received. When the server receives the message it sends an ack and then processes the request. Finally, once the request has been completed it sends the response (optionally waiting for an ack that the client received it).

CruiseControl.Net doesn’t use this model at all, although the project build queuing does provide part of the model (the only part missing is the response at the end). While I foresee this as being very useful for clients in the future, I’m not going to attempt this (basically because of its complexity.)

Additional Models

These are three of the common messaging models – there are many other patterns also (I haven’t covered routing, composition, transactions, reliability, etc.) As this are the simple models I’m going to leave it here and instead move onto how we can use them in CruiseControl.Net.

Aiming For Consistency

With this background I can now begin to look at adding messaging. But first, some goals:

  • Consistency – every message should have the same common elements, and every message should use the same model
  • No exceptions – errors should be part of a message, rather than being outside of messaging
  • Decoupling – the client should not be forced to wait on the server

The first two are readily achievable – the final goal will have to wait until I look at a common communications library.

For consistency, I want to move every message to a two-way model. This means that even the current one-way messages (e.g. force/abort build, start/stop project, etc.) will return a response to the client. In most scenarios this means the server will send a “success” response (e.g. I have received your force build request and added it to the queue), but it also allows for sending errors back to the client.

Currently an error is returned using an exception, which is a security hole (it allows external parties to see the structure of the code and potentially helps them to hack in). With the new model, errors will be returned as part of the response, allowing us much greater control over what is actually sent.

Next, I want to split the messages into two parts – a body and a header. The header contains information about the request that doesn’t directly apply to the message. At the moment I’m thinking about adding a project identifier, the session token and a message identifier.

The project identifier is a unique way of identifying every project. This identifier must be globally unique since the dashboard can handle multiple servers. As such this identifier will consist of the server name plus the the project name. If the request is a server-level request, then just the server name is required.

While this may seem like some duplicate of data (e.g. the server name is part of both the protocol and the message) it allows for consistency, plus provides some avenues for message validation later.

The session token is new to security. It allows a client to tell the server who is using it. Currently it is only used for active requests (e.g. force/abort build, start/stop project, etc.) plus security requests (e.g. change password, list users, etc.) I think this would also be useful for every request – both for consistency, plus for the future options it allows.

And finally, a message identifier. This would be a unique identifier for each message. While there is no requirement for it at the moment I foresee it being useful in security (for preventing message-repeat attacks). Ideally this should be combined with a timestamp to narrow the window of attack.

Laying the Foundation

Since this post is mainly about my plans for messaging, I’m not going to include any coding. Instead I’ll finish off with my design for the messages. Now this isn’t the full design, instead it’s an example of how the classes will be built:

Requests

The base class that every request needs to inherit from is ServerRequest. This contains the common “header” data for every request. Additionally, methods that need no further information can use this request directly.

Requests that inherit from this just add the additional properties that they require. For example, ProjectRequest just adds the project name. Any methods that just needs the project name (e.g. start/stop project) could then use this request.

More specialised requests can then inherit from these classes depending on what base information they need (e.g. ChangePasswordRequest inherits from ServerRequest while ForceBuildRequest and SendMessageRequest inherit from ProjectRequest).

Each request must be serialisable so it can be passed via .Net Remoting. Additionally I’m thinking of marking them up with XML serialisation attributes to help with HTTP requests.

Responses are very similar:

Responses

This is very similar – one root class (Response) plus some specialised classes.

The basic idea with these is to use any existing class if possible, otherwise add a new class to provide the custom request/response.

What About the Future?

With these request/response classes it should be fairly easy to port them to WCF. Just add the data contract attributes and then write a contract interface, plus implementation.

So this approach should also handle the move to WCF.

That’s a Wrap

So, that’s my intentions for messaging. Next I’ll have a go at implementing them and see how things work out.

Posted in CruiseControl.Net | Tagged: | 3 Comments »

Stylish Passwords on the Web

Posted by Craig Sutherland on 27 January, 2009

A Quick Recap

In my last post (read it here) I wrote about adding password management to the server-side components. This built on the new external file security manager and allows the changing and resetting of passwords. What I hadn’t added was the ability for a client application to change the password.

In this post I’ll start with the web dashboard and add first a password login view, then a change password view and finally I’ll add the ability for an administrator to reset the password. Along the way I’ll be modifying how jQuery is used in the application and add some nice styles.

Who Are You? Really?

One of the short-comings in security via the web is the inability to enter a password. At the moment the only security mechanism in place is simple user (i.e. user name only). As almost every secure scenario requires a password, this really limits things.

To get around this I have expanded the login mechanism to also accept a password. The plug-in for user name login is UserNameSecurityPlugin, with UserNameSecurityAction as its action. I have extended the view to also display a password input box. When the user clicks on login the password is added to the credentials and sent to the server.

Since this is a simple change, I have also added a reflector-backed property to the plug-in to allow turning the password display off. This allows current configurations to continue to function as they do now. But by default the password input will now be displayed. The following shows how this page now looks:

LoginWithPassword

As a final note on this, the password is not required. This is so people with just a user name can still login – they just leave the password field empty. It is completely up to the server whether a password is required or not.

At the same time I also fixed a bug in the login/logout routines. This bug meant the login/logout text was incorrect at the top of the page. In the routine that set this text, it checks the session retriever – which is responsible for retrieving the session token. Unfortunately, this value was incorrect as the login/logout routines set a different value.

To get around this I changed to using the session storer. This accepts the new value of the session token and uses it to generate the URLs. With this minor change the correct text is now displayed.

Changing Passwords

In order to change passwords, the user needs some way to get to the page. Since most of the security functions (e.g. login/logout) are at the top of the page I modified this area to also include a change password option:

ChangePasswordOption

Clicking on this button takes the user through to the change password page:

ChangePasswordPage

There is nothing special about this page. The action behind it is ChangePasswordSecurityAction – which is currently hard-coded into the system. This basically means whenever the user is logged in they will see the change password option.

The logic behind the page is also simple – check that the new passwords match and if so, send the details to the server. Once the server has finished, take whatever results come back and display them to the user. If there are any problems, display an error message.

As a final note on this, the dashboard doesn’t care what the server allows or disallows. If the security manager at the server doesn’t allow password changing the user will just get an error:

ChangePasswordError

Stylish Results

In my screenshots the results of any operations are displayed in a nicely styled box. Now, since I’m not a designer (or artistic at all) I cannot take credit for these. Instead these are the work of people on the jQuery project (http://jquery.com/).

jQuery is a JavaScript library that designed to be lightweight, fast and (most importantly) cross-browser. Additionally, there are now a number of UI “widgets” available, which add functionality like tabs, dialog boxes and calendars to a plain old HTML page.

As well as this work, there is also work on-going for themes – which are basically pre-built combinations of colours and fonts to make things look good. Take a look at http://ui.jquery.com/themeroller sometime – this has some nice preset themes, plus the ability to generate your own variations!

To try and make it easier for people to change and modify the themes, I’ve added the jQuery libraries to site template. I’ve also modified the configuration so people can set their own jQuery themes. Just open dashboard.config and go down to the stylesheets section:

<stylesheets>
  <stylesheet location="css/Black Tie/ui.all.css" name="Black Tie"/>
  <stylesheet location="css/Blitzer/ui.all.css" name="Blitzer"/>
  <stylesheet location="css/Excite Bike/ui.all.css" name="Excite Bike"/>
  <stylesheet location="css/Humanity/ui.all.css" name="Humanity"/>
  <stylesheet location="css/Start/ui.all.css" name="Start"/>
</stylesheets>

As you can see, it is possible to set multiple style-sheets, so nice modern browsers like FireFox can offer the users different styles.

To achieve this I had to modify SiteTemplateActionDecorator, but it has the plus affect of making the jQuery functionality available to the whole site! So hopefully over time we’ll start to see some more jQuery-based interaction and styling across the whole dashboard :)

Resetting Passwords

As well as changing passwords, there is also the scenario when a user forgets their password (shock, horror!) In the internal security manager, this is not a problem – the administrator just retrieves the config file and looks up their password.

But, with the changes I’ve slowly been implementing, this may not be possible. Plus there is the possibility the administrator is somewhere where there is no access to the config (trying to view it in the dashboard hides the passwords). So it’s time to allow resetting passwords in the dashboard.

Currently the administrator has the ability to view all the users and diagnose their permissions. So rather than add a whole new user section I’ve just expanded on this:

ResettingPasswords

This involved adding a new button to the view that allows the administrator to reset the password. At the moment this password needs to be configured in dashboard.config (it defaults to password). Clicking on the button will change the user’s password to the configured password. Of course, at this time it’s normally a good idea for the user to login and change their password!

Just like the user changing their own password, this requires a security manager that allows password changing:

ResettingPasswordsError

Behind the scenes, this action just sends the reset password request to the server. The server validates that the user has the valid permission and then changes the password.

Dashboard Updated

These changes were pretty simple really – most of the time invested was in working on the UI side of things. I’d already made the server-side changes previously, so I just needed to make things look nice :)

That just leaves CCTray. After some investigation I was unable to find a good area to add this into :( The current security has been hacked in, and I think adding in password management would just confuse things further! Therefore, for the time being I’m not to add password changing into CCTray.

Posted in CruiseControl.Net, Security | Tagged: | Leave a Comment »

Password Management

Posted by Craig Sutherland on 26 January, 2009

Starting Down the Dark Path of Password Obfuscation

One of the other devs saw my post on an external file security manager (read it here), and asked “why?” The pre-processor already handles importing files, so why would I want to duplicate the effort? The answer to this question lies not in the current capacities of the security managers, but instead further down the path of possibilities!

One of the current issues with security is all the configuration is plain text – if someone can crack the server they have access to all the passwords! Secondly, in order for passwords to be used, somebody needs to add them to the configuration – which means this person (or people) will know all the passwords. Finally, there is no way for an individual to change his or her password – they are stuck with the password they have been given :(

So, it’s time to start looking at password management.

Step 1: Changing Passwords

The first step to reversing these problems lies with the ability to change passwords.

With internal security, everything is defined “internally” in the configuration. While it is possible to modify this file, there can be unexpected results. The main one that I know of is the file watching – change the configuration file and the entire file is reloaded!

The external file security manager gets around this problem by putting the users and permissions in external files. If one of these files changes, the configuration watcher doesn’t know, and therefore doesn’t care.

But, before I can actually get to the point of updating these files, I first need to add some password management methods. To start with I’m going to add two new methods – ChangePassword() and ResetPassword().

ChangePassword() will change the password of a logged on user. It will use the session token to identify the user.

ResetPassword() will allow the current user to change anybody’s password. Therefore this method will need to be secured (I’m going to use the ViewSecurity permission for now).

These two methods have been added to ICruiseManager, ICruiseServer and ISecurityManager, plus all their implementations. For the manager and server implementations, they merely function as pass-through layers – the end point is the methods in the security manager implementations. For now, all of these will throw a NotImplementedException – and for the internal and null security managers this won’t change.

In due time I’ll update the clients to call these methods, but for now I’m calling them via unit tests.

All the security manager now needs to do is find the user (via the session token for changing passwords, via the user name for resetting), call the relevant method and then save the changes.

Step 2: Updating the Files

Now, since the external file security manager uses external files for its storage, it’s not too hard to update them.

The first challenge is knowing which file to update. Since potentially the password could have come from one of many files, I’ll need someway of linking the setting to the file. To do this I added a new dictionary that has the identifier as the key and the filename as the value. Now when an item is updated I can use this dictionary to find the file to update.

Now that I know the source file, the next step is to find the security item (I do by iterating through the file) and updating it. The actual update is done by calling NetReflector to generate the new XML, which is then used to replace the old XML. Finally the file is saved with the changes.

I used this approach instead of a simple find-and-replace because I cannot guarantee that the setting stores the password in an element called “password”. This approach allows the password to be stored in any applicable element (or even externally again).

As a side note, another idea I want to implement is encrypting passwords. This will remove the responsibility for passwords from the admin and make them a little bit more secure. This is another reason why I didn’t want to directly update the XML.

However, one down side to this approach is the XML is slightly changed. NetReflector always uses elements and it strips comments – but since this allows more flexibility long-term I can live with these changes.

Step 3: The Clients

The final step for getting this to work is to allow the actual users to update their own passwords. However, since this is not easy (for a number of reasons) I’m going to leave this for my next post (or posts).

For now, know that I have updated ICruiseManager to allow password changes over .Net Remoting. Since .Net Remoting is the only way to connect to the actual server, this opens the way for clients to change passwords. In terms of what is required, the following breaks down each client:

  • For the web dashboard I need to add a login handler for password users, and then add the change password view. I also need to add an XML version for HTTP clients to use.
  • For CCTray I need to figure out where to add this functionality, and then modify both the transport mechanisms and add the dialog.
  • Finally, I need to work out where to allow resetting passwords (currently I’m thinking this will be a web dashboard task).

So, stay tuned for allowing clients to change their passwords :-)

Posted in CruiseControl.Net, Security | Tagged: | 1 Comment »

Security Scenario 3: Small Open Source

Posted by Craig Sutherland on 23 January, 2009

The Saga Continues…

Previously I’ve put together two scenarios on security. These were:

Both of these scenarios covered in-house development projects. In this scenario I’m going to change tack and look at a small open source project.

Petros has been working on an open source project called Midas for about a year now. This project is hosted on SourceForge, and he is the only administrator. However recently it’s been getting some press and other people have volunteered to help, which he thinks is wonderful!

He has convinced his work (a chemical conversion company) to host a CruiseControl.Net instance for the community to use. However, he doesn’t want to allow everybody full access to the server. He is happy to let everybody view the current status, but he only wants to let approved developers force build. He doesn’t want to let anybody stop or start the projects. Finally he wants to know who performs any release builds.

The Build Setup

Petros’s build setup is really simple – there is only two projects in his config.

The first project is a CI build – it polls every five minutes and performs a build if any changes are detected. This does the standard compile, run unit tests and generate installer. The outputs are stored in a publically accessible location.

The second project is a releasing build. Again it does the compile, unit tests, etc, except this time in release mode. The outputs are then stored on his open source website and a release post is added to tell the world. This project must be manually forced.

The Goals

Since Petros has full access to the server and is the only person who needs access, there will be only one security zone.

This security zone will grant approved developers access to force or abort a build on the project. Currently security does not prevent viewing the reports, so this will not require configuration.

To keep things simple, all force builds will be audited.

The Plan

There will be only one security group – CanBuild. This group will have force build access to both projects, but no other access.

All developers who need force build rights will be manually added to this group.

The Configuration

The full configuration is as follows:

<cruisecontrol>
  <project name="Open_Source(Build)">
    <workingDirectory>C:\Build\OSB</workingDirectory>
    <artifactDirectory>C:\Build\OSB\Deploy</artifactDirectory>
    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
    <triggers>
      <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
    </triggers>
    <publishers>
      <xmllogger/>
    </publishers>
  </project>
  <project name="Open_Source(Deploy)">
    <workingDirectory>C:\Build\OSD</workingDirectory>
    <artifactDirectory>C:\Build\OSD\Deploy</artifactDirectory>
    <webURL>http://localhost/server/local/project/LAS-Main/ViewProjectReport.aspx</webURL>
    <triggers>
      <intervalTrigger buildCondition="IfModificationExists" seconds="300"/>
    </triggers>
    <publishers>
      <xmllogger/>
    </publishers>
  </project>
</cruisecontrol>

Again the first step is turning on security – just added the internalSecurity element, plus the users and permissions children.

Adding the Roles and Users

Now the security has been added the next step is to add the users and the CanBuild security group. Since this is an open source project, Petros doesn’t want to bother with much security. Therefore each person who is allowed to build has been added as a password user. At the moment, this is only Petros himself:

<users>
  <passwordUser name="petros" password="whoareyou"/>
</users>

The role is very similar, but just contains the force build permission and the list of users:

<permissions>
  <rolePermission name="all" defaultRight="Deny" forceBuild="Allow">
    <users>
      <userName name="petros"/>
    </users>
  </rolePermission>
</permissions>

I’ve also set the default right on the internal security element to Deny, so everyone else will be unable to do a force build.

Locking Down the Projects

The final step for preventing force builds is to secure the projects. This is the same configuration as previous:

<security type="defaultProjectSecurity">
  <permissions>
    <rolePermission name="all" ref="all"/>
  </permissions>
</security>

Again, this checks that the user is in the role, and if so the user can do a force build. All other permissions are denied at the server level.

Audit Logging

The final step once more is the auditing. Since this is very simple, I’ve just added the default audit logger block:

<audit>
  <xmlFileAudit/>
</audit>

I haven’t added an audit reader as there is no way of accessing it at the moment.

Some Comments

Again, there’s still no way of allowing password users to log onto the dashboard (hence why I haven’t covered it).

One issue I did think about with this scenario is sending the login requests to a remote service (e.g. something like SourceForge or CodePlex). At the moment I don’t know whether these services even have a login API, but if so it would be nice to have a pass-through for this. However since it opens up a whole set of security issues I decided not to even try it!

Posted in CruiseControl.Net, Security | Tagged: , | Leave a Comment »

Speeding Up Validation

Posted by Craig Sutherland on 22 January, 2009

The Problem

The validator tool that I built recently works reasonably well. It has all the same validation options as both the console and the service (it’s built on top of the same code), and it allows someone to check all their projects in one go. Additionally the version in the security branch allows some of the extra features that I’ve added into that branch (e.g. internal validation).

But, there is one problem: as the number of projects increases the time to run the tool increases, and sometimes quite significantly! On my machine I find it tends to slow down after around 10-15 projects, and by the time I’m up to 50 projects I’m waiting over a minute – not so good :-(

The Cause

Anyway, I started inserting some timing statements into my code to try and work out the slow point. And in the end I found it, but it wasn’t where I expected!

As some background, here is the sequence of processing:

  1. Load and pre-process the XML
  2. Format and display the original XML
  3. Validate each XML element and write the results to the display
  4. Pass each element through NetReflector to regenerate the XML
  5. Format and display the processed XML

Each of the first four steps worked without any problems. For my config with 50 projects in it they all took around 2.5s to achieve. It is the last step, formatting the XML, that took the rest of the time.

Now to do the formatting I use the CSharpFormat library from manoli.net (http://www.manoli.net/csharpformat/) which normally works very nicely (this is the first time I’ve had an issue with it). Now I haven’t tried modifying the code, but I know it uses regular expressions under the hood to do the formatting, so there might be an issues with this :(

However, on further investigation it looks like there is more of an issue with the amount of XML that  NetReflector generates. Basically NetReflector generates XML for nearly every item in the configuration, plus it uses elements for everything, instead of attributes in places.

The Solution

Originally I wanted to par down the amount of XML that NetReflector generates. There are some approaches that can be used, such as eliminating empty elements (i.e. those with empty strings or empty lists) and changing to use attributes instead of elements.

The eliminating empty elements pared down the resultant XML from ~1800 to ~1600 lines, but this still took a while to format.

Next I tried switching to using attributes, but I kept getting run-time errors, so in the end I gave up on this.

I then added some DefaultValue attributes into the code and modified NetReflector to check for these, which saved me an extra 300 lines, but not enough to make a speed difference.

After this, I gave up! Obviously I’m not going to be able to trim down the generated XML enough to make a huge difference, when the issue obviously lies in the amount of time it takes to format the code. This left me with two choices – finding another code formatter or removing the formatting.

I had a look around, but couldn’t find anything that would be better, and I didn’t want to totally remove it, so in the end I settled for a compromise. I moved the XML formatting step into a background worker.

Once the validator has finished the first four steps I pass the XML into the background worker to do the actual formatting. Once this has finished it is displayed like it did originally.

The two main differences the end user will see is faster processing of the validation, plus when they attempt to view the processed XML they will get a message saying it is processing. Then once the background worker has finished the formatted code will be displayed.

Posted in CruiseControl.Net, Tools | Tagged: | 5 Comments »

Big Visible Cruise II (BVC2)

Posted by Craig Sutherland on 21 January, 2009

Improving BVC

There is not one, but two versions of Big Visible Cruise! Originally I had posted on BVC, and after showing my manager at work, got approval to get a new monitor and box so we can run it.

Now I’ve learnt about a second initiative called Big Visible Cruise II (http://www.codeplex.com/BigVisibleCruise). This is a continuation/branch of the original, and has a few enhancements to make it nicer.

For those of you who haven’t seen BVC/BVC2, here is what is looks like:

BVC2

There is a full screen version, which works really well on a large monitor. If you don’t like the stacked approach, it’s also possible to have all the items laid out in a grid:

BVC2-Grid

Supposedly it also shows the build breaker – but as you see from the screenshots this doesn’t appear to be working. I’m not sure whether this has been turned off by default – and I can’t find anyway of turning it on.

Installing and configuring it is very easy. To install it you need to copy the binaries to a folder somewhere (there’s no installer, but one is not really necessary). To configure it just click on the settings link and the following dialog is displayed:

BVC-Settings

Here you just set the URL to watch (only HTTP is allowed) and then it’s ready to go. You can change a few other settings, but it’s still very simple and easy to use.

All in all, I like this project (both versions). It’s simple and easy to use, and it does it’s job very nicely. Good going guys!!!

Posted in CruiseControl.Net | Tagged: | 3 Comments »

Ruben Willems Blog

Posted by Craig Sutherland on 21 January, 2009

For those who don’t know him, Ruben is one of the developers on the CruiseControl.Net project. He’s also the guy who answers a lot of the support e-mails!

Ruben has recently started a blog on Continuous Integration, so if you are interested in finding out more about what is happening with CruiseControl.Net check it out – http://rubenwillems.blogspot.com/.

Posted in CruiseControl.Net | Tagged: | Leave a Comment »

External Security

Posted by Craig Sutherland on 19 January, 2009

A New Security Manager is Here

When I started on security I put in an interface called ISecurityManager. This interface handles all the security functions – CruiseServer merely calls this interface. Now I could have put all the security functionality directly in CruiseServer, but this had a couple of disadvantages. First it would have made it harder to turn security off (i.e. CruiseServer would have to know whether security was on or off). Second it would have meant that security was hard-coded in.

With ISecurityManager I can easily implement a new security manager and I don’t need to change CruiseServer at all! Actually, anybody can implement a new security manager – CC.Net wouldn’t care as long as it uses Exortech.NetReflector and implements ISecurityManager.

(One idea I’m playing with is getting the security manager to call directly into Active Directory for all it’s security, but that’s just an idea currently!)

In this post, I have implemented a new security manager – one that stores the users and permissions in external files (yes, I said files – it will handle multiple external definitions).

ExternalFileSecurityManager

The new class is called ExternalFileSecurityManager – yes this is a mouthful, but it describes the manager nicely. The security settings are stored in external files (that is external to the main configuration.)

Here is an example of what the configuration looks like:

<externalFileSecurity>
  <audit>
    <xmlFileAudit location="C:\Logs\CCNet_Audit.xml"/>
  </audit>
  <auditReader type="xmlFileAuditReader" location="C:\Logs\CCNet_Audit.xml"/>
  <files>
    <file>users.xml</file>
  </files>
</externalFileSecurity>

And the external file would look something like this:

<security>
  <simpleUser name="johndoe"/>
</security>

When the security manager is initialised, it will load each external file and load all the users and permissions (the external file can contain both). Otherwise this manager functions the same as the internal security manager.

As for allowed settings in the external files, the manager will handle any settings from either the users or permissions sections in the internal security. Actually, this manager is the same, but there is the additional step of loading from the file, instead of getting it from the configuration.

Behind the Scenes

For those who want to know how I implemented this manager – it was pretty simple. First off, I cheated – I copied all the code from InternalSecurityManager and did some renaming. (There’s a lot of code in these classes so writing one from scratch would take a lot of work.)

Next, I removed the Users and Permissions properties (plus their backing fields) and added a Files property.

Finally, I modified the Initialise() method to go through the list of files and load each one. The load method merely loads the external file into an XmlDocument, and then iterates through each element and attempts to load it with NetReflector.

If the element is a valid security setting (i.e. IPermission or IAuthentication) it loads it into the correct dictionary and then moves on. Otherwise an exception is thrown.

Otherwise, nothing else has been changed. Because the Initialise() method in InternalSecurityManager loaded the settings anyway, I was able to piggy-back on the process :-)

As a final note, I didn’t inherit from InternalSecurityManager because I didn’t want the Users and Permissions properties. Since they both use NetReflector under the hood the user would still have been able to set these properties.

Where to Next?

Now, while this works, there are a couple of extra steps I want to add:

  1. File monitoring – when the external files change, they should automatically reload. But at the same time I don’t want to force everything to reload (i.e. the entire configuration file).
  2. Password changing – the entire drive behind this is I want to allow users to change their passwords. With internal security this is not possible (persisting the passwords causes the entire config to reload!) Now I can start to add in this functionality.

So that’s my next plans for security – in between working on testing and documenting the whole thing.

Stay tuned…

Posted in CruiseControl.Net, Security | Tagged: | 1 Comment »

Oops, I Made a Mistake

Posted by Craig Sutherland on 18 January, 2009

What’s in a Name?

When I first started working on security (around four months ago) I had a very clear plan on what I was going to do. However, like life, things changed as I progressed. I’d like to think the changes have made a better end-product, but along the way some things became less clear.

One example of this is the names within security. Originally the names were along the lines of what I was planning – but things changed and the names became less and less clear :( And instead of changing the names to reflect their new meaning, I left them as they were.

An example of this is the settings element on the security manager. Initially this was designed to hold all the server-level security settings – without any differentiation on the different types. When I implemented server-level permissions, I could no longer use the settings (got a conflict with the names) so I added the assertions section (i.e. the same section as for project security).

Now there is a section in the security element for permissions, and a second section for permissions and users! But which section should which permission go into?

Assertion != Permission

The first change is to move from assertions to permissions. An assertion is something that is checks to see that it is true (e.g. a if the current user is Joe then he can force build), but it is more generic than just permissions (e.g. if the user name is Joe and the password is whoareyou, then the user is Joe).

In my code I’ve been referring to permissions as assertions. While these are included in an assertion it’s a very narrow sub-set. Therefore to clarify this, and make it easier for new users, I’ve changed from <assertions> to <permissions>. I’ve also changed the current names of the assertions to be permission names (e.g. userPermission and rolePermission).

Under the hood this required no changes to the code beyond some renaming of classes (I’m trying to keep the class names reasonably close to the reflection names) and the changing of the reflection attributes.

Specifying Users, No More Settings

The second change is to remove the settings section under the security manager, and add in a users section instead. I say remove and add, rather than rename, because I’ve subtly changed the way this section works.

In the old code the settings section could contain users, permissions or any other class that implements ISecuritySetting. The new users section can only contain users now – which forces the permissions to be in their own section. If we add more types of security settings later on, they will need their own sections to be added to the configuration.

This required renaming (similar to the permissions change), plus removing and adding the properties. But still very straight-forward.

Why Session Security?

My final change is to rename SessionSecurityManager. Initially when I designed security I had the grand allow of allowing people to use different means of passing security information between the client and the server. As the project progressed this narrowed down to user credentials for logging in and session tokens for everything else.

Additionally I hard-coded these session tokens into all of the external methods – so calling the method now requires a session token for any secured method. While it is possible to pass non-session details in this token, it’s a bit hacky.

Therefore, since I’ve modified the security to be all session-based this means the name of SessionSecurityManager doesn’t have as much meaning. Instead a better name is InternalSecurityManager (and internalSecurity for the XML). As the name means, it’s a security manager that stores it’s configuration internal to the configuration file.

On my to-do list is to make an ExternalSecurityManager – this will store the settings in an external configuration file and load them as required (this will also allow changing or passwords).

Enough Changes for Now

That covers the three names that I wasn’t happy with – settings, assertions and sessionSecurityManager. With these changes it should make the configuration more meaningful and also easier to develop moving forward.

And now to you dear reader, are there any other names that you think are incorrect? If so, please let me know and I’ll see if I can make them clearer.

Posted in CruiseControl.Net, Security | Tagged: | 2 Comments »