Jonathan Turner 8 년 전
부모
커밋
f147be6a56
13개의 변경된 파일39개의 추가작업 그리고 68개의 파일을 삭제
  1. 3 1
      asn1tools/tools.go
  2. 1 1
      client/ASExchange.go
  3. 2 2
      client/TGSExchange.go
  4. 6 6
      client/cache.go
  5. 6 6
      client/client.go
  6. 2 1
      client/http.go
  7. 1 1
      client/network.go
  8. 2 2
      client/session.go
  9. 5 5
      config/krb5conf.go
  10. 6 5
      credentials/credentials.go
  11. 3 36
      messages/KDCRep_test.go
  12. 1 1
      messages/Ticket.go
  13. 1 1
      pac/client_info.go

+ 3 - 1
asn1tools/tools.go

@@ -1,4 +1,4 @@
-// Package asn1tools - Tools for managing ASN1 marshaled data.
+// Package asn1tools provides tools for managing ASN1 marshaled data.
 package asn1tools
 
 import (
@@ -45,6 +45,7 @@ func GetLengthFromASN(b []byte) int {
 	return l
 }
 
+// GetNumberBytesInLengthHeader returns the number of bytes in the ASn1 header that indicate the length.
 func GetNumberBytesInLengthHeader(b []byte) int {
 	if int(b[1]) <= 127 {
 		return 1
@@ -53,6 +54,7 @@ func GetNumberBytesInLengthHeader(b []byte) int {
 	return 1 + int(b[1]) - 128
 }
 
+// AddASNAppTag adds an ASN1 encoding application tag value to the raw bytes provided.
 func AddASNAppTag(b []byte, tag int) []byte {
 	r := asn1.RawValue{
 		Class:      asn1.ClassApplication,

+ 1 - 1
client/ASExchange.go

@@ -12,7 +12,7 @@ import (
 	"sort"
 )
 
-// Perform an AS exchange for the client to retrieve a TGT.
+// ASExchange performs an AS exchange for the client to retrieve a TGT.
 func (cl *Client) ASExchange() error {
 	if !cl.IsConfigured() {
 		return errors.New("Client is not configured correctly")

+ 2 - 2
client/TGSExchange.go

@@ -10,7 +10,7 @@ import (
 	"time"
 )
 
-// Perform a TGS exchange to retrieve a ticket to the specified SPN.
+// TGSExchange performs a TGS exchange to retrieve a ticket to the specified SPN.
 // The ticket retrieved is added to the client's cache.
 func (cl *Client) TGSExchange(spn types.PrincipalName, tkt messages.Ticket, sessionKey types.EncryptionKey, renewal bool) (tgsReq messages.TGSReq, tgsRep messages.TGSRep, err error) {
 	if cl.Session == nil {
@@ -42,7 +42,7 @@ func (cl *Client) TGSExchange(spn types.PrincipalName, tkt messages.Ticket, sess
 	return tgsReq, tgsRep, nil
 }
 
-// Make a request to get a service ticket for the SPN specified
+// GetServiceTicket makes a request to get a service ticket for the SPN specified
 // SPN format: <SERVICE>/<FQDN> Eg. HTTP/www.example.com
 // The ticket will be added to the client's ticket cache
 func (cl *Client) GetServiceTicket(spn string) (messages.Ticket, types.EncryptionKey, error) {

+ 6 - 6
client/cache.go

@@ -22,20 +22,20 @@ type CacheEntry struct {
 	SessionKey types.EncryptionKey
 }
 
-// Create a new client ticket cache.
+// NewCache creates a new client ticket cache instance.
 func NewCache() *Cache {
 	return &Cache{
 		Entries: map[string]CacheEntry{},
 	}
 }
 
-// Get a cache entry that matches the SPN.
+// GetEntry returns a cache entry that matches the SPN.
 func (c *Cache) GetEntry(spn string) (CacheEntry, bool) {
 	e, ok := (*c).Entries[spn]
 	return e, ok
 }
 
-// Add a ticket to the cache.
+// AddEntry adds a ticket to the cache.
 func (c *Cache) AddEntry(tkt messages.Ticket, authTime, startTime, endTime, renewTill time.Time, sessionKey types.EncryptionKey) CacheEntry {
 	spn := strings.Join(tkt.SName.NameString, "/")
 	(*c).Entries[spn] = CacheEntry{
@@ -49,12 +49,12 @@ func (c *Cache) AddEntry(tkt messages.Ticket, authTime, startTime, endTime, rene
 	return c.Entries[spn]
 }
 
-// Remove the cache entry for the defined SPN.
+// RemoveEntry removes the cache entry for the defined SPN.
 func (c *Cache) RemoveEntry(spn string) {
 	delete(c.Entries, spn)
 }
 
-// Get a ticket from the cache for the SPN.
+// GetCachedTicket returns a ticket from the cache for the SPN.
 // Only a ticket that is currently valid will be returned.
 func (cl *Client) GetCachedTicket(spn string) (messages.Ticket, types.EncryptionKey, bool) {
 	if e, ok := cl.Cache.GetEntry(spn); ok {
@@ -74,7 +74,7 @@ func (cl *Client) GetCachedTicket(spn string) (messages.Ticket, types.Encryption
 	return tkt, key, false
 }
 
-// Renew a cache entry ticket
+// RenewTicket renews a cache entry ticket
 func (cl *Client) RenewTicket(e CacheEntry) (CacheEntry, error) {
 	spn := e.Ticket.SName
 	_, tgsRep, err := cl.TGSExchange(spn, e.Ticket, e.SessionKey, true)

+ 6 - 6
client/client.go

@@ -1,4 +1,4 @@
-// A client for Kerberos 5 authentication.
+// Package client provides a client library and methods for Kerberos 5 authentication.
 package client
 
 import (
@@ -22,7 +22,7 @@ type Config struct {
 	Assume_PA_ENC_TIMESTAMP_Required bool
 }
 
-// Create a new client with a password credential.
+// NewClientWithPassword creates a new client from a password credential.
 func NewClientWithPassword(username, realm, password string) Client {
 	creds := credentials.NewCredentials(username, realm)
 	return Client{
@@ -34,7 +34,7 @@ func NewClientWithPassword(username, realm, password string) Client {
 	}
 }
 
-// Create a new client with a keytab credential.
+// NewClientWithKeytab creates a new client from a keytab credential.
 func NewClientWithKeytab(username, realm string, kt keytab.Keytab) Client {
 	creds := credentials.NewCredentials(username, realm)
 	return Client{
@@ -46,13 +46,13 @@ func NewClientWithKeytab(username, realm string, kt keytab.Keytab) Client {
 	}
 }
 
-// Set the Kerberos configuration for the client.
+// WithConfig sets the Kerberos configuration for the client.
 func (cl *Client) WithConfig(cfg *config.Config) *Client {
 	cl.Config = cfg
 	return cl
 }
 
-// Load the Kerberos configuration for the client from file path specified.
+// LoadConfig loads the Kerberos configuration for the client from file path specified.
 func (cl *Client) LoadConfig(cfgPath string) (*Client, error) {
 	cfg, err := config.Load(cfgPath)
 	if err != nil {
@@ -62,7 +62,7 @@ func (cl *Client) LoadConfig(cfgPath string) (*Client, error) {
 	return cl, nil
 }
 
-// Has the client got sufficient values required.
+// IsConfigured indicates if the client has the values required set.
 func (cl *Client) IsConfigured() bool {
 	if !cl.Credentials.HasPassword() && !cl.Credentials.HasKeytab() {
 		return false

+ 2 - 1
client/http.go

@@ -12,7 +12,7 @@ import (
 	"strings"
 )
 
-// Get service ticket and set as the SPNEGO authorization header on HTTP request object.
+// SetSPNEGOHeader gets the service ticket and sets it as the SPNEGO authorization header on HTTP request object.
 // To auto generate the SPN from the request object pass a null string "".
 func (cl *Client) SetSPNEGOHeader(r *http.Request, spn string) error {
 	if spn == "" {
@@ -29,6 +29,7 @@ func (cl *Client) SetSPNEGOHeader(r *http.Request, spn string) error {
 	return nil
 }
 
+// SetSPNEGOHeader sets the provided ticket as the SPNEGO authorization header on HTTP request object.
 func SetSPNEGOHeader(creds credentials.Credentials, tkt messages.Ticket, sessionKey types.EncryptionKey, r *http.Request) error {
 	SPNEGOToken, err := gssapi.GetSPNEGOKrbNegTokenInit(creds, tkt, sessionKey)
 	nb, err := SPNEGOToken.Marshal()

+ 1 - 1
client/network.go

@@ -11,7 +11,7 @@ import (
 	"time"
 )
 
-// Send bytes to the KDC.
+// SendToKDC performs network actions to send data to the KDC.
 func (cl *Client) SendToKDC(b []byte) ([]byte, error) {
 	var rb []byte
 	var kdcs []string

+ 2 - 2
client/session.go

@@ -18,7 +18,7 @@ type Session struct {
 	SessionKeyExpiration time.Time
 }
 
-//Enable the automatic renewal for the client's TGT session.
+// EnableAutoSessionRenewal turns on the automatic renewal for the client's TGT session.
 func (cl *Client) EnableAutoSessionRenewal() {
 	// TODO look into using a context here
 	go func() {
@@ -34,7 +34,7 @@ func (cl *Client) EnableAutoSessionRenewal() {
 	}()
 }
 
-//Renew the client's TGT session.
+// RenewTGT renews the client's TGT session.
 func (cl *Client) RenewTGT() error {
 	spn := types.PrincipalName{
 		NameType:   nametype.KRB_NT_SRV_INST,

+ 5 - 5
config/krb5conf.go

@@ -30,7 +30,7 @@ type Config struct {
 // List of encryption types that have been deemed weak.
 const WEAK_ETYPE_LIST = "des-cbc-crc des-cbc-md4 des-cbc-md5 des-cbc-raw des3-cbc-raw des-hmac-sha1 arcfour-hmac-exp rc4-hmac-exp arcfour-hmac-md5-exp des"
 
-// Create a new config struct.
+// NewConfig creates a new config struct instance.
 func NewConfig() *Config {
 	d := make(DomainRealm)
 	return &Config{
@@ -419,7 +419,7 @@ func (d *DomainRealm) deleteMapping(domain, realm string) {
 	delete(*d, domain)
 }
 
-// Resolve the realm for the specified domain name from the domain to realm mapping.
+// ResolveRealm resolves the kerberos realm for the specified domain name from the domain to realm mapping.
 // The most specific mapping is returned.
 func (c *Config) ResolveRealm(domainName string) string {
 	domainName = strings.TrimSuffix(domainName, ".")
@@ -444,19 +444,19 @@ func Load(cfgPath string) (*Config, error) {
 	return NewConfigFromScanner(scanner)
 }
 
-// Create a new Config struct from a string.
+// NewConfigFromString creates a new Config struct from a string.
 func NewConfigFromString(s string) (*Config, error) {
 	reader := strings.NewReader(s)
 	return NewConfigFromReader(reader)
 }
 
-// Create a new Config struct from an io.Reader.
+// NewConfigFromReader creates a new Config struct from an io.Reader.
 func NewConfigFromReader(r io.Reader) (*Config, error) {
 	scanner := bufio.NewScanner(r)
 	return NewConfigFromScanner(scanner)
 }
 
-// Create a new Config struct from a bufio.Scanner.
+// NewConfigFromScanner creates a new Config struct from a bufio.Scanner.
 func NewConfigFromScanner(scanner *bufio.Scanner) (*Config, error) {
 	c := NewConfig()
 	sections := make(map[int]string)

+ 6 - 5
credentials/credentials.go

@@ -34,7 +34,7 @@ type ADCredentials struct {
 	LogonServer         string
 }
 
-// Create a new Credentials struct.
+// NewCredentials creates a new Credentials instance.
 func NewCredentials(username string, realm string) Credentials {
 	return Credentials{
 		Username: username,
@@ -48,6 +48,7 @@ func NewCredentials(username string, realm string) Credentials {
 	}
 }
 
+// NewCredentialsFromPrincipal creates a new Credentials instance with the user details provides as a PrincipalName type.
 func NewCredentialsFromPrincipal(cname types.PrincipalName, realm string) Credentials {
 	return Credentials{
 		Username:   cname.GetPrincipalNameString(),
@@ -58,19 +59,19 @@ func NewCredentialsFromPrincipal(cname types.PrincipalName, realm string) Creden
 	}
 }
 
-// Set the Keytab in the Credentials struct.
+// WithKeytab sets the Keytab in the Credentials struct.
 func (c *Credentials) WithKeytab(kt keytab.Keytab) *Credentials {
 	c.Keytab = kt
 	return c
 }
 
-// Set the password in the Credentials struct.
+// WithPassword sets the password in the Credentials struct.
 func (c *Credentials) WithPassword(password string) *Credentials {
 	c.Password = password
 	return c
 }
 
-// Query if the Credentials has a keytab defined.
+// HasKeytab queries if the Credentials has a keytab defined.
 func (c *Credentials) HasKeytab() bool {
 	if len(c.Keytab.Entries) > 0 {
 		return true
@@ -78,7 +79,7 @@ func (c *Credentials) HasKeytab() bool {
 	return false
 }
 
-// Query if the Credentials has a password defined.
+// HasPassword queries if the Credentials has a password defined.
 func (c *Credentials) HasPassword() bool {
 	if c.Password != "" {
 		return true

+ 3 - 36
messages/KDCRep_test.go

@@ -257,7 +257,7 @@ func TestUnmarshalASRepDecodeAndDecrypt(t *testing.T) {
 	assert.Equal(t, 18, asRep.DecryptedEncPart.Key.KeyType, "KeyType in decrypted EncPart not as expected")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.LastReqs[0].LRValue, "LastReqs did not have a time value")
 	assert.Equal(t, 2069991465, asRep.DecryptedEncPart.Nonce, "Nonce value not as expected")
-	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.KeyExpiration, "Key expriation not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.KeyExpiration, "Key expiration not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.AuthTime, "AuthTime not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.StartTime, "StartTime not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.EndTime, "StartTime not a time type")
@@ -297,7 +297,7 @@ func TestUnmarshalASRepDecodeAndDecrypt_withPassword(t *testing.T) {
 	assert.Equal(t, 18, asRep.DecryptedEncPart.Key.KeyType, "KeyType in decrypted EncPart not as expected")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.LastReqs[0].LRValue, "LastReqs did not have a time value")
 	assert.Equal(t, 2069991465, asRep.DecryptedEncPart.Nonce, "Nonce value not as expected")
-	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.KeyExpiration, "Key expriation not a time type")
+	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.KeyExpiration, "Key expiration not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.AuthTime, "AuthTime not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.StartTime, "StartTime not a time type")
 	assert.IsType(t, time.Time{}, asRep.DecryptedEncPart.EndTime, "StartTime not a time type")
@@ -305,37 +305,4 @@ func TestUnmarshalASRepDecodeAndDecrypt_withPassword(t *testing.T) {
 	assert.Equal(t, test_realm, asRep.DecryptedEncPart.SRealm, "Service realm not as expected")
 	assert.Equal(t, 2, asRep.DecryptedEncPart.SName.NameType, "Name type for AS_REP not as expected")
 	assert.Equal(t, []string{"krbtgt", test_realm}, asRep.DecryptedEncPart.SName.NameString, "Service name string not as expected")
-}
-
-//func TestKDCRep_Validate(t *testing.T) {
-//	d, _ := os.Getwd()
-//	asreqData, err := ioutil.ReadFile(d + "/../testdata/AS-REQ.raw")
-//	if err != nil {
-//		t.Fatalf("AS REP read error: %v\n", err)
-//	}
-//	asReq, err := UnmarshalASReq(asreqData)
-//	if err != nil {
-//		t.Fatalf("AS REP Unmarshal error: %v\n", err)
-//	}
-//
-//	usr, _ := user.Current()
-//	dir := usr.HomeDir
-//	asrepData, err := ioutil.ReadFile(d + "/../testdata/AS-REP.raw")
-//	if err != nil {
-//		t.Fatalf("AS REP read error: %v\n", err)
-//	}
-//	var asRep ASRep
-//	err = asRep.Unmarshal(asrepData)
-//	if err != nil {
-//		t.Fatalf("AS REP Unmarshal error: %v\n", err)
-//	}
-//	kt, err := keytab.Load(dir + "/tmp.keytab")
-//	if err != nil {
-//		fmt.Printf("keytab parse error: %v\n", err)
-//	}
-//	ok, err := asRep.Validate(asReq, kt)
-//	if !ok || err != nil {
-//		t.Fatalf("Validation of AS REP failed: %v", err)
-//	}
-//	t.Log("AS REP validation tests finished")
-//}
+}

+ 1 - 1
messages/Ticket.go

@@ -162,7 +162,7 @@ func MarshalTicketSequence(tkts []Ticket) (asn1.RawValue, error) {
 	btkts = append(asn1tools.MarshalLengthBytes(len(btkts)), btkts...)
 	btkts = append([]byte{byte(32 + asn1.TagSequence)}, btkts...)
 	raw.Bytes = btkts
-	// If we need to create teh full bytes then identifier octet is "context-specific" = 128 + "constructed" + 32 + the wrapping explicit tag (11)
+	// If we need to create the full bytes then identifier octet is "context-specific" = 128 + "constructed" + 32 + the wrapping explicit tag (11)
 	//fmt.Fprintf(os.Stderr, "mRaw fb: %v\n", raw.FullBytes)
 	return raw, nil
 }

+ 1 - 1
pac/client_info.go

@@ -23,7 +23,7 @@ func (k *ClientInfo) Unmarshal(b []byte) error {
 	if len(b[p:]) < int(k.NameLength) {
 		return ndr.Malformed{EText: "PAC ClientInfo length truncated"}
 	}
-	//Length devided by 2 as each run is 16bits = 2bytes
+	//Length divided by 2 as each run is 16bits = 2bytes
 	s := make([]rune, k.NameLength/2, k.NameLength/2)
 	for i := 0; i < len(s); i++ {
 		s[i] = rune(ndr.Read_uint16(&b, &p, &e))