Let’s Fix Some Issues
In a previous post (here), I mentioned a number of issues I found while testing. During writing that post I found five issues that made using the security in CruiseControl.Net. Since I’m the one who wrote it, I shouldn’t be having a hard time, but yes, I did find issues
In this post I’ll start to look at the different issues and how to resolve them.
Issue #1: Documentation
Yes, my documentation on the original work was sorely lacking. While I documented most things from a technical viewpoint, there was no clear and easy-to-understand documentation on how to configure security on the server.
I’ve now gone through and added some articles on how to configure the documentation. These articles can be found here.
As I stated, this is my short-term resolution. When the security work is moved into the trunk I’ll get these added to the main documentation for CruiseControl.Net.
And in the long term I’m going to build a security settings tool (or maybe get it added to CCNetConfig).
Issue #2: Complete Implementation
My second headache was discovered I had mentioned things I was planning on doing in my posts, but I hadn’t actually done them yet! These basically fell into two areas:
- No default right for the assertions
- No implementation for starting/stopping a project
The default right is merely a matter of modifying AssertionBase. This is the class that contains all the security rights – so I added the default right, decorated it with the correct attributes and then modified CheckPermissionActual() to return this right instead of SecurityPermission.Inherit. Now a default right can be set for each assertion.
The start/stop implementations were a it more work. This involved first modifying ICruiseServer/CruiseServer to allow passing in a session token. I also added the session token to CancelPendingRequest() and SendMessage() just to be thorough.
From here I also had to modify ICruiseManager/CruiseManager. This again involved adding another override to take in a session token for each of the secured methods. The old methods are also there, but they pass in null for the session token.
Since these methods are called by both CCTray and the dashboard, these applications also needed changing.
In CCTray the starting point is ICruiseProjectManager, since this is the interface that handles the communications. This required modifying HttpCruiseProjectManager, RemotingCruiseProjectManager and WcfProjectManager (in the WCF extensions) to handle the secured methods. Finally ProjectMonitor was modified to pass in the session tokens.
In the dahboard the starting point is IFarmService. This only has two methods to be modified – Start() and Stop(). This required modifying ServerAggregatingCruiseManagerWrapper to match (just passed on the session token) and then finished with VelocityProjectGridAction - getting it to pass in the session token to the modified methods.
That is now all the update actions secured. Not sure about whether there is a need to secure read-only actions, so I’m going to leave these for now.
Issue #3: Friendly display names
The next issue is reasonably simple – there is no friendly displayname for each extension. Instead each extension has the full .Net assembly name (not very nice, especially as they are too wide for the display). To get around this I have added a new attribute – ExtensionAttribute. Currently this has only one property – DisplayName, but later I’m planning on adding more.
When I load the list of extensions I call a helper method in ExtensionHelpers - CheckForDisplayName(). This loads the specified type, looks for the new attribute and if found returns the DisplayName property. If there is no attribute, or the DisplayName property hasn’t been set, then it returns the full assembly-based type name.
This code is called from ConfigureServer - which is what currently displays the list of security extensions. I had to do a bit of playing around to get it working nicely (since comboboxes don’t have name/value pairs for their items). This involved adding an internal struct to hold the extensions and their display names.
Now I can see some nice friendly names:

- Improved server configuration
The authentication modes can now easily be distinguished
Issue #4: No Warnings
I not sure why this is happening, but looking at my code I saw that the exceptions were defined in both Core and Remote, which might be causing problems. I’ve taken them out of Core so both CCTray and the server should be using the same settings.
However, even so when I try it the exceptions don’t come through
So I did some more investigations. Currently I have three different communications protocols – HTTP, .Net Remoting and WCF. It turns out the problem one is HTTP – obviously the error is being trapped somewhere and not passed on. .Net Remoting and WCF both tell me there is a problem – although WCF doesn’t tell me what the problem is!
Time For a Break
That’s enough problem-solving for the moment. I’ve tracked down where the issues are for the non-displayed warnings, but as it’s going to take a while to fix the HTTP problem I’m going to leave it for later.
Since issue #5 depends on issue #4 I’m also going to leave this for later.
But I have resolved some of the issues, so if you want to try it, download the code from the security branch and give it a spin