gokrb5

package module
Version: v5.3.0 Latest Latest
Warning

This package is not in the latest version of its module.

Go to latest
Published: Jul 31, 2018 License: Apache-2.0 Imports: 0 Imported by: 0

README

gokrb5

GoDoc Go Report Card Build Status

To get the package, execute:

go get -d gopkg.in/jcmturner/gokrb5.v5/...

To import this package, add the following line to your code:

import "gopkg.in/jcmturner/gokrb5.v5/<sub package>"

Features

  • Pure Go - no dependency on external libraries
  • No platform specific code
  • Server Side
    • HTTP handler wrapper implements SPNEGO Kerberos authentication
    • HTTP handler wrapper decodes Microsoft AD PAC authorization data
  • Client Side
    • Client that can authenticate to an SPNEGO Kerberos authenticated web service
    • Ability to change client's password
  • General
    • Kerberos libraries for custom integration
    • Parsing Keytab files
    • Parsing krb5.conf files
    • Parsing client credentials cache files such as /tmp/krb5cc_$(id -u $(whoami))
Implemented Encryption & Checksum Types
Implementation Encryption ID Checksum ID RFC
des3-cbc-sha1-kd 16 12 3961
aes128-cts-hmac-sha1-96 17 15 3962
aes256-cts-hmac-sha1-96 18 16 3962
aes128-cts-hmac-sha256-128 19 19 8009
aes256-cts-hmac-sha384-192 20 20 8009
rc4-hmac 23 -138 4757

Currently the following is working/tested:

  • Tested against MIT KDC (1.6.3 is the oldest version tested against) and Microsoft Active Directory (Windows 2008 R2)
  • Tested against a KDC that supports PA-FX-FAST.
  • Tested against users that have pre-authentication required using PA-ENC-TIMESTAMP.
  • Microsoft PAC Authorization Data is processed and exposed in the HTTP request context. Available if Microsoft Active Directory is used as the KDC.

Contributing

If you are interested in contributing to gokrb5, great! Please read the contribution guidelines.

Usage


Configuration

The gokrb5 libraries use the same krb5.conf configuration file format as MIT Kerberos, described here. Config instances can be created by loading from a file path or by passing a string, io.Reader or bufio.Scanner to the relevant method:

import "gopkg.in/jcmturner/gokrb5.v5/config"
cfg, err := config.Load("/path/to/config/file")
cfg, err := config.NewConfigFromString(krb5Str) //String must have appropriate newline separations
cfg, err := config.NewConfigFromReader(reader)
cfg, err := config.NewConfigFromScanner(scanner)
Keytab files

Standard keytab files can be read from a file or from a slice of bytes:

import 	"gopkg.in/jcmturner/gokrb5.v5/keytab"
ktFromFile, err := keytab.Load("/path/to/file.keytab")
ktFromBytes, err := keytab.Parse(b)


Kerberos Client

Create a client instance with either a password or a keytab:

import 	"gopkg.in/jcmturner/gokrb5.v5/client"
cl := client.NewClientWithPassword("username", "REALM.COM", "password")
cl := client.NewClientWithKeytab("username", "REALM.COM", kt)

Provide configuration to the client:

cl.WithConfig(cfg)

Login:

err := cl.Login()

Kerberos Ticket Granting Tickets (TGT) will be automatically renewed unless the client was created from a CCache.

A client can be destroyed with the following method:

cl.Destroy()
Active Directory KDC and FAST negotiation

Active Directory does not commonly support FAST negotiation so you will need to disable this on the client. If this is the case you will see this error: KDC did not respond appropriately to FAST negotiation To resolve this disable PA-FX-Fast on the client before performing Login() with the line below.

cl.GoKrb5Conf.DisablePAFXFast = true
Authenticate to a Service
HTTP SPNEGO

Create the HTTP request object and then call the client's SetSPNEGOHeader method passing the Service Principal Name (SPN) or to auto generate the SPN from the request object pass a null string ""

r, _ := http.NewRequest("GET", "http://host.test.gokrb5/index.html", nil)
spn := ""
cl.SetSPNEGOHeader(r, spn)
HTTPResp, err := http.DefaultClient.Do(r)
Generic Kerberos Client

To authenticate to a service a client will need to request a service ticket for a Service Principal Name (SPN) and form into an AP_REQ message along with an authenticator encrypted with the session key that was delivered from the KDC along with the service ticket.

The steps below outline how to do this.

  • Get the service ticket and session key for the service the client is authenticating to. The following method will use the client's cache either returning a valid cached ticket, renewing a cached ticket with the KDC or requesting a new ticket from the KDC. Therefore the GetServiceTicket method can be continually used for the most efficient interaction with the KDC.
tkt, key, err := cl.GetServiceTicket("HTTP/host.test.gokrb5")

The steps after this will be specific to the application protocol but it will likely involve a client/server Authentication Protocol exchange (AP exchange). This will involve these steps:

  • Generate a new Authenticator and generate a sequence number and subkey:
auth, _ := types.NewAuthenticator(cl.Credentials.Realm, cl.Credentials.CName)
etype, _ := crypto.GetEtype(key.KeyType)
auth.GenerateSeqNumberAndSubKey(key.KeyType, etype.GetKeyByteSize())
  • Set the checksum on the authenticator The checksum is an application specific value. Set as follows:
auth.Cksum = types.Checksum{
		CksumType: checksumIDint,
		Checksum:  checksumBytesSlice,
	}
  • Create the AP_REQ:
APReq, err := messages.NewAPReq(tkt, key, auth)

Now send the AP_REQ to the service. How this is done will be specific to the application use case.

Changing a Client Password

This feature uses the Microsoft Kerberos Password Change protocol (RFC 3244). This is implemented in Microsoft Active Directory and in MIT krb5kdc as of version 1.7. Typically the kpasswd server listens on port 464.

Below is example code for how to use this feature:

cfg, err := config.Load("/path/to/config/file")
if err != nil {
	panic(err.Error())
}
kt, err := keytab.Load("/path/to/file.keytab")
if err != nil {
	panic(err.Error())
}
cl := client.NewClientWithKeytab("username", "REALM.COM", kt)
cl.WithConfig(cfg)

ok, err := cl.ChangePasswd("newpassword")
if err != nil {
	panic(err.Error())
}
if !ok {
	panic("failed to change password")
}

The client kerberos config (krb5.conf) will need to have either the kpassd_server or admin_server defined in the relevant [realms] section. For example:

REALM.COM = {
  kdc = 127.0.0.1:88
  kpasswd_server = 127.0.0.1:464
  default_domain = realm.com
 }

See https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html#realms for more information.


Kerberised Service
SPNEGO/Kerberos HTTP Service

A HTTP handler wrapper can be used to implement Kerberos SPNEGO authentication for web services. To configure the wrapper the keytab for the SPN and a Logger are required:

kt, err := keytab.Load("/path/to/file.keytab")
l := log.New(os.Stderr, "GOKRB5 Service: ", log.Ldate|log.Ltime|log.Lshortfile)

Create a handler function of the application's handling method (apphandler in the example below):

h := http.HandlerFunc(apphandler)

Configure the HTTP handler:

serviceAccountName = ""
http.Handler("/", service.SPNEGOKRB5Authenticate(h, kt, serviceAccountName, l))

The serviceAccountName needs to be defined when using Active Directory where the SPN is mapped to a user account. If this is not required it should be set to an empty string "". If authentication succeeds then the request's context will have the following values added so they can be accessed within the application's handler:

  • service.CTXKeyAuthenticated - Boolean indicating if the user is authenticated. Use of this value should also handle that this value may not be set and should assume "false" in that case.
  • service.CTXKeyCredentials - The authenticated user's credentials. If Microsoft Active Directory is used as the KDC then additional ADCredentials are available in the credentials.Attributes map under the key credentials.AttributeKeyADCredentials. For example the SIDs of the users group membership are available and can be used by your application for authorization.

Access the credentials within your application:

ctx := r.Context()
if validuser, ok := ctx.Value(service.CTXKeyAuthenticated).(bool); ok && validuser {
        if creds, ok := ctx.Value(service.CTXKeyCredentials).(credentials.Credentials); ok {
                if ADCreds, ok := creds.Attributes[credentials.AttributeKeyADCredentials].(credentials.ADCredentials); ok {
                        // Now access the fields of the ADCredentials struct. For example:
                        groupSids := ADCreds.GroupMembershipSIDs
                }
        } 

}
Generic Kerberised Service - Validating Client Details

To validate the AP_REQ sent by the client on the service side call this method:

import 	"gopkg.in/jcmturner/gokrb5.v5/service"
var ktprinc string //The SPN of the service to find the key in the keytab.
var requireHostAddr bool //Whether to force requiring the ticket to contain host addresses to check the client against.
if ok, creds, err := service.ValidateAPREQ(mt.APReq, kt, ktprinc, r.RemoteAddr, requireHostAddr); ok {
        // Perform application specifc actions
        // creds object has details about the client identity
}

References

Thanks

  • Greg Hudson from the MIT Consortium for Kerberos and Internet Trust for providing useful advice.

Contributing

Thank you for your interest in contributing to gokrb5 please read the contribution guide as it should help you get started.

Known Issues

Issue Worked around? References
The Go standard library's encoding/asn1 package cannot unmarshal into slice of asn1.RawValue Yes https://github.com/golang/go/issues/17321
The Go standard library's encoding/asn1 package cannot marshal into a GeneralString Yes - using https://github.com/jcmturner/gofork/tree/master/encoding/asn1 https://github.com/golang/go/issues/18832
The Go standard library's encoding/asn1 package cannot marshal into slice of strings and pass stringtype parameter tags to members Yes - using https://github.com/jcmturner/gofork/tree/master/encoding/asn1 https://github.com/golang/go/issues/18834
The Go standard library's encoding/asn1 package cannot marshal with application tags Yes
The Go standard library's x/crypto/pbkdf2.Key function uses the int type for iteraction count limiting meaning the 4294967296 count specified in https://tools.ietf.org/html/rfc3962 section 4 cannot be met on 32bit systems Yes - using https://github.com/jcmturner/gofork/tree/master/x/crypto/pbkdf2 https://go-review.googlesource.com/c/crypto/+/85535

Documentation

Overview

Package gokrb5 provides a Kerberos 5 implementation for Go

Source Files

Directories

Path Synopsis
Package asn1tools provides tools for managing ASN1 marshaled data.
Package asn1tools provides tools for managing ASN1 marshaled data.
Package client provides a client library and methods for Kerberos 5 authentication.
Package client provides a client library and methods for Kerberos 5 authentication.
Package config implements KRB5 client and service configuration as described at https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html
Package config implements KRB5 client and service configuration as described at https://web.mit.edu/kerberos/krb5-latest/doc/admin/conf_files/krb5_conf.html
Package credentials provides credentials management for Kerberos 5 authentication.
Package credentials provides credentials management for Kerberos 5 authentication.
Package crypto implements cryptographic functions for Kerberos 5 implementation.
Package crypto implements cryptographic functions for Kerberos 5 implementation.
common
Package common provides encryption methods common across encryption types
Package common provides encryption methods common across encryption types
etype
Package etype provides the Kerberos Encryption Type interface
Package etype provides the Kerberos Encryption Type interface
rfc3961
Package rfc3961 provides encryption and checksum methods as specified in RFC 3961
Package rfc3961 provides encryption and checksum methods as specified in RFC 3961
rfc3962
Package rfc3962 provides encryption and checksum methods as specified in RFC 3962
Package rfc3962 provides encryption and checksum methods as specified in RFC 3962
rfc4757
Package rfc4757 provides encryption and checksum methods as specified in RFC 4757
Package rfc4757 provides encryption and checksum methods as specified in RFC 4757
rfc8009
Package rfc8009 provides encryption and checksum methods as specified in RFC 8009
Package rfc8009 provides encryption and checksum methods as specified in RFC 8009
Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication.
Package gssapi implements Generic Security Services Application Program Interface required for SPNEGO kerberos authentication.
Package iana provides Kerberos 5 assigned numbers.
Package iana provides Kerberos 5 assigned numbers.
addrtype
Package addrtype provides Address type assigned numbers.
Package addrtype provides Address type assigned numbers.
adtype
Package adtype provides Authenticator type assigned numbers.
Package adtype provides Authenticator type assigned numbers.
asnAppTag
Package asnAppTag provides ASN1 application tag numbers.
Package asnAppTag provides ASN1 application tag numbers.
chksumtype
Package chksumtype provides Kerberos 5 checksum type assigned numbers.
Package chksumtype provides Kerberos 5 checksum type assigned numbers.
errorcode
Package errorcode provides Kerberos 5 assigned error codes.
Package errorcode provides Kerberos 5 assigned error codes.
etypeID
Package etypeID provides Kerberos 5 encryption type assigned numbers.
Package etypeID provides Kerberos 5 encryption type assigned numbers.
flags
Package flags provides Kerberos 5 flag assigned numbers.
Package flags provides Kerberos 5 flag assigned numbers.
keyusage
Package keyusage provides Kerberos 5 key usage assigned numbers.
Package keyusage provides Kerberos 5 key usage assigned numbers.
msgtype
Package msgtype provides Kerberos 5 message type assigned numbers.
Package msgtype provides Kerberos 5 message type assigned numbers.
nametype
Package nametype provides Kerberos 5 principal name type numbers.
Package nametype provides Kerberos 5 principal name type numbers.
patype
Package patype provides Kerberos 5 pre-authentication type assigned numbers.
Package patype provides Kerberos 5 pre-authentication type assigned numbers.
trtype
Package trtype provides Transited Encoding Type assigned numbers.
Package trtype provides Transited Encoding Type assigned numbers.
Package kadmin provides Kerberos administration capabilities.
Package kadmin provides Kerberos administration capabilities.
Package keytab implements Kerberos keytabs: https://web.mit.edu/kerberos/krb5-devel/doc/formats/keytab_file_format.html.
Package keytab implements Kerberos keytabs: https://web.mit.edu/kerberos/krb5-devel/doc/formats/keytab_file_format.html.
Package krberror provides error type and functions for gokrb5.
Package krberror provides error type and functions for gokrb5.
Package messages implements Kerberos 5 message types and methods.
Package messages implements Kerberos 5 message types and methods.
Package mstypes implements representations of Microsoft types for PAC processing.
Package mstypes implements representations of Microsoft types for PAC processing.
Package ndr is DEPRECATED and will be removed from next major revision of gokrb5.
Package ndr is DEPRECATED and will be removed from next major revision of gokrb5.
Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing.
Package pac implements Microsoft Privilege Attribute Certificate (PAC) processing.
Package service provides server side integrations for Kerberos authentication.
Package service provides server side integrations for Kerberos authentication.
Package types provides Kerberos 5 data types.
Package types provides Kerberos 5 data types.

Jump to

Keyboard shortcuts

? : This menu
/ : Search site
f or F : Jump to
y or Y : Canonical URL