|
|
8 лет назад | |
|---|---|---|
| asn1tools | 8 лет назад | |
| client | 8 лет назад | |
| config | 8 лет назад | |
| credentials | 8 лет назад | |
| crypto | 8 лет назад | |
| examples | 8 лет назад | |
| gssapi | 8 лет назад | |
| iana | 8 лет назад | |
| keytab | 8 лет назад | |
| krberror | 8 лет назад | |
| messages | 8 лет назад | |
| mstypes | 8 лет назад | |
| ndr | 8 лет назад | |
| pac | 8 лет назад | |
| service | 8 лет назад | |
| testdata | 8 лет назад | |
| testenv | 8 лет назад | |
| types | 8 лет назад | |
| .gitignore | 9 лет назад | |
| .travis.yml | 8 лет назад | |
| CONTRIBUTING.md | 8 лет назад | |
| LICENSE | 9 лет назад | |
| README.md | 8 лет назад | |
| gokrb5.go | 8 лет назад |
To get the package, execute:
go get gopkg.in/jcmturner/gokrb5.v4
To import this package, add the following line to your code:
import "gopkg.in/jcmturner/gokrb5.v4/<sub package>"
/tmp/krb5cc_$(id -u $(whoami))| 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:
If you are interested in contributing to gokrb5, great! Please read the contribution guidelines.
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.v4/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)
Standard keytab files can be read from a file or from a slice of bytes:
import "gopkg.in/jcmturner/gokrb5.v4/keytab"
ktFromFile, err := keytab.Load("/path/to/file.keytab")
ktFromBytes, err := keytab.Parse(b)
Create a client instance with either a password or a keytab:
import "gopkg.in/jcmturner/gokrb5.v4/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.
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:
To resolve this disable PA-FX-Fast on the client before performing Login() with the line below.
```go
cl.GoKrb5Conf.DisablePAFXFast = true
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)
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:
go
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,
}
go
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.
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:
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
}
}
}
To validate the AP_REQ sent by the client on the service side call this method:
import "gopkg.in/jcmturner/gokrb5.v4/service"
if ok, creds, err := service.ValidateAPREQ(mt.APReq, kt, r.RemoteAddr); ok {
// Perform application specifc actions
// creds object has details about the client identity
}
Thank you for your interest in contributing to gokrb5 please read the contribution guide as it should help you get started.
| 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 |