The next logical step for the Kerberos.NET project is setting up automated builds and releases. What exactly does this entail? Basically, I want a build to kick off any time changes are committed to the main repo, and automatically generate a production-ready Nuget package that is available to upload if deemed worthy of release.

If you’ve done any sort of build automation or release management before, you’ve got a pretty good idea of how to make this work. For a given build service do the following:

  1. Observe changes to repo
  2. Pull down changes
  3. Build project(s)
  4. Package the packages
  5. Artifact the necessary files for future release

And if you’re really wanting to be fancy:

  1. Push packages to nuget repository on release signal

I chose to use Visual Studio Online to do this for me. I can use hosted build agents to build and package the project without a ton of effort. This is how I did it.

First, you need to have a Visual Studio Online account. If you don’t have one, go set one up. It’s easy.

Next, you need to create a new Team Project. Give it a name, select the Version Control and Work Item types. You can leave these as the defaults unless you have specific reasons to use the other options. The options don’t matter at all if you’re using Github because you’ll never commit or track work here.

Now you need to wire it into Github to track changes. Select the gear icon at the top to get into the project settings and select the Services tab.

Select the Services Tab

Add a new Service Endpoint and select Github:

Select Github

Now you can configure which account to connect to Github as. Just select the Authorize button and you’ll see a popup asking to be… authorized. There are more advanced options to configure if you’re specifying things like personal access tokens too. Your browser may block the Authorize pop up window. You’ll need to allow the pop up before it’ll allow you to continue.

Authorize Github

Now you can start configuring the build. Select the Builds and Releases tab and click the New button.

Add a New Build

And now you need to select a build template. We’re now building a .NET Core project in the case of Kerberos.NET, so you can start with an empty process or select the ASP.NET Core template.

Select your Build Template

Next you’ll want to configure the Get sources step, which will checkout changes to the repo. You need to select the Github tab. It’ll automatically populate the fields because you previously registered Github as a service. Select which repository you want to use and configure branches or other settings.

Configure Get Sources

Next you’ll need to configure the Restore/Build/Test/Publish steps. By default these steps are configured as .NET Core 1.*, which in our case is incorrect. We need to use .NET Core 2.0.

Select .NET Core 2.*

You’ll need to do this for the 4 steps. You can probably leave all the other settings alone and the system will just pick up any projects it needs to build or test — assuming you’ve got tests.

One thing I’d recommend you do is also add the new task before the restore or build called the “.NET Core Tool Installer”.

Add .NET Tools Installer

The reason for this is that it’ll download and install any runtimes or SDKs for any future versions of .NET that haven’t been added to the build agents yet. This isn’t strictly necessary, but it may save you some headaches in the future (or in the past, in my case, because the 2.* versions weren’t available when I originally set this up).

Install .NET Builds

From there you can configure the build/test/publish steps as necessary. Once you think you’re in a good spot go ahead and queue it up:

Save and Queue the build

You’ll be asked which queue to use. You’ll want the Hosted VS2017 agent in this case because of .NET Core 2.0.

Queue the Build

The build should then kick off with and you can track the results based on the console output or the logs. You can see there’s been some, uh, trial-and-error.

Build Build Build.

Once you’ve got a working build you can start configuring how you want it to kick off through the Triggers mechanism.

Trigger on Commit

In this case trigger when there are changes to the master branch. The Pull Requests option is super-handy when you’re working with teams and actually use PRs — there’s only been one PR with Kerberos.NET, and that was before builds were set up. You should consider committing to the project!

Once your build is ready to go you can even badge it to see the most recent build status easily:

Badge the Build

And now you have can embed the status wherever you want:

Next time we can look at automatically publishing.

I started the Kerberos.NET project with a simple intention: be able to securely parse Kerberos tickets for user authentication without requiring an Active Directory infrastructure. This had been relatively successful so far, but one major milestone that I hadn’t hit yet was making sure it worked with .NET Core. It now works with .NET Core.

Porting a Project

There is no automated way to port a project to .NET Core. This is because it’s a fundamentally different way of doing things in .NET and things are bound to break (I’m sure that’s not actually the reason). There is documentation available, but it’s somewhat high-level and not necessarily useful when you’re in the weeds tracking down weird dependency issues. Given that, you’re kinda stuck just copying over the code and doing the build-break-tweak-build-wtf dance until you have something working. This was my process.

  1. Create a new .NET Standard project — Standard dictates the API level the library is compatible with; Core dictates the runtime compatibility. I didn’t have any particular targeting requirements, so I made it as broad as possible. Now any runtime supporting .NET Standard can use this library.
  2. Copy all the code from the main project into the new project — I probably could have created the .NET Standard project in the same location, but it’s often easier to start with a blank slate and move things in.
  3.  Build!
  4. Build fails — MemoryCache/ObjectCache don’t exist in the current API set. Thankfully this is isolated to just the Ticket Replay detection, so I was able to temporarily convert it to a simple dictionary. I eventually found a library that replaces the original caching library.
  5. Build fails again — SecurityIdentifier doesn’t exist in the current API set either. Doh! I wasn’t going to hold my breath waiting for this to be moved over, so I created my own class that had the same usefulness. This also gave me the opportunity to fix some ugly code required to merge RIDs into SIDs, which added a nice little performance boost.
  6. Build succeeds!
  7. Unload/remove the original .NET 4.6 projects from the solution.
  8. Adjust test project dependencies to use the new project instead.
  9. Run!

Once I was able to get the test projects up and running I could run them through the test cases and verify everything worked correctly. Everything worked, except for the AES support. 😒

Porting a Project with a Dependency

I added support for AES tickets a while back and it was built in such a way that it lived in a separate package because it had an external dependency on BouncyCastle. I’m not a fan of core packages taking dependencies on third parties, so I built it as an add-on that you could wire-in later. This worked relatively well, until I needed to migrate to .NET Core.

It turns out there are a number of Core/Standard/PCL packages for BouncyCastle, but what’s the right one? Weeeeelll, none of them, of course!

At this point I decided to suck it up and figure out how to make SHA1 do what I want. One option was to muck with the internals of the SHA1Managed class with reflection, but that turned out to be a bad idea because the original developers went out of their way to make it difficult to get access to intermediate values (there are philosophical arguments here. I don’t fault them for it, but it’s really frustrating). I considered rewriting the class based on the reference source, but that too was problematic for the same basic reason. Eventually I ended up porting the BouncyCastle implementation because it was relatively self-contained, and already worked the way I needed.

Security note: You should never trust crypto code written by some random person you found on the internet. That said, there’s a higher chance of finding a vulnerability in other parts of the code than with the port of this algorithm, so…

This actually works out well because now all the code can go back into a single package without any dependencies whatsoever. Neat!

Porting a Nuget Package

The nuget pieces didn’t really change much, but now the manifest is defined in the project file itself, and packages are built automatically.

Simpler Package Management

Now the package is just an artifact of the build, which will be useful if/when I ever move this to an automated build process.

Active Directory has had the ability to issue claims for users and devices since Server 2012. Claims allow you to add additional values to a user’s kerberos ticket and then make access decisions based on those values at the client level. This is pretty cool because you normally can only make access decisions based on group membership, which is fairly static in nature. Claims can change based on any number of factors, but originate as attributes on the user or computer object in Active Directory. Not so coincidentally, this is exactly how claims on the web work via a federation service like ADFS.

Of course, claims aren’t enabled by default on Windows for compatibility reasons. You can enable them through Group Policy:

Computer Configuration > Policies > Administrative Templates > System > KDC > KDC support for claims, compound authentication and Kerberos armoring

Allow Claims in Group Policy

You can configure claims through the Active Directory Administrative Center Dynamic Access Control.

Active Directory Administrative Center Dynamic Access Control

You can see the Claim Types option on the left hand menu. From there you can add a claim by hitting the New > Claim Type menu.

The configuration is pretty simple. Find the attribute of the user or device you want to issue, and select whether it should be issued for users or computers or both. You can configure more advanced settings below the fold, but you only need to select the attribute for this to work.

Add New Claim Type

Once the claim type is configured you can modify attributes of a user through the Attribute Editor in either ADAC or the AD Users and Computers console.

User Attributes in ADAC

That’s all it takes to get use claims. You do have to sign out and back in before these claims will take effect though since Active Directory issues claims in the Kerberos tickets, and the tickets are only issued during sign in (or the myriad other times it does, but sign out/in is the most effective).

However, once you’ve signed out and back in you can pop open PowerShell and see the claims in your token:

[System.Security.Principal.WindowsIdentity]::getcurrent().claims | fl type, value

Type : ad://ext/department:88d4d68c39060f49
Value : Super secret division

Windows 8 and higher automatically extract the claims from the PAC in the ticket and make them available in the user token. Additionally, .NET understands claims natively and can extract them from the Windows token.

And of course now Kerberos.NET! The library will automatically parse any user or device claims and stick them in to the resultant claims produced during authentication:

Kerberos Claims

No configuration necessary. The library will do all the work. Enjoy!