No Description

Jonathan Turner ee5f882b13 fixed tcp, test against older krb5kdc 9 years ago
GSSAPI 78313f1530 gssapi unit tests 9 years ago
asn1tools 0bd461fc52 refactor app tag 9 years ago
client ee5f882b13 fixed tcp, test against older krb5kdc 9 years ago
config f62ca44c30 comment update 9 years ago
credentials 28c696288e comment updates 9 years ago
crypto 72d5546332 host address and comments 9 years ago
iana 7a9007a2ed hostaddress items 9 years ago
keytab 05a18c7de2 http server spnego auth 9 years ago
messages ee5f882b13 fixed tcp, test against older krb5kdc 9 years ago
service 72d5546332 host address and comments 9 years ago
testdata ee5f882b13 fixed tcp, test against older krb5kdc 9 years ago
testenv ee5f882b13 fixed tcp, test against older krb5kdc 9 years ago
types 72d5546332 host address and comments 9 years ago
.gitignore 95ab435b4c initial commit 9 years ago
LICENSE caee2dc83a Initial commit 9 years ago
README.md fa6fe72439 fixed client PA-REQ-ENC-PA-REP checksum validation 9 years ago
example.go 0174084baf tests and docker testenv 9 years ago

README.md

gokrb5

This is work in progress and may have some issues. Full testing is still required.

Currently the following is working/tested:

  • Works with a KDC that supports PA FAST. Older KDCs need testing.
  • Client side authentication to HTTP servers that implement SPNEGO using Kerberos 5.
  • Service side handling for Kerberos SPNEGO seems to be working but not yet fully tested.

GoDoc

Implemented Encryption & Checksum Types

The currently implemented encrytion types are:

Implementation Encryption ID Checksum ID
aes128-cts-hmac-sha1-96 17 15
aes256-cts-hmac-sha1-96 18 16

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 "github.com/jcmturner/gokrb5/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 	"github.com/jcmturner/gokrb5/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 	"github.com/jcmturner/gokrb5/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

(Optional) Enable automatic refresh of Kerberos Ticket Granting Ticket (TGT):

cl.EnableAutoSessionRenewal()

Authenticate to a Service

Native Kerberos

Request a Serivce ticket for a Service Principal Name (SPN). This 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, err := cl.GetServiceTicket("HTTP/host.test.gokrb5")
HTTP SPNEGO

Create the HTTP request object and then call the client's SetSPNEGOHeader method passing the Service Principal Name (SPN)

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

Kerberos Web 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:

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

If authentication succeeds then the request's context will have the following values added so they can be accessed within the application's handler:

  • "authenticated" - 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.
  • "cname" - The authenticated user name.
  • "crealm" - The authenticated user's realm.

References

RFCs

Useful Links

Thanks

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

Known Issues

Issue Worked around? References
Golang's ASN1 package cannot unmarshal into slice of asn1.RawValue Yes https://github.com/golang/go/issues/17321
Golang's ASN1 package cannot marshal into a GeneralString Yes - using https://github.com/jcmturner/asn1 https://github.com/golang/go/issues/18832
Golang's ASN1 package cannot marshal into slice of strings and pass stringtype parameter tags to members Yes - using https://github.com/jcmturner/asn1 https://github.com/golang/go/issues/18834
Golang's ASN1 package cannot marshal with application tags Yes