client_info.go 1.5 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344
  1. package pac
  2. import (
  3. "encoding/binary"
  4. "gopkg.in/jcmturner/gokrb5.v2/mstypes"
  5. "gopkg.in/jcmturner/gokrb5.v2/ndr"
  6. )
  7. // ClientInfo implements https://msdn.microsoft.com/en-us/library/cc237951.aspx
  8. type ClientInfo struct {
  9. ClientID mstypes.FileTime // A FILETIME structure in little-endian format that contains the Kerberos initial ticket-granting ticket TGT authentication time
  10. NameLength uint16 // An unsigned 16-bit integer in little-endian format that specifies the length, in bytes, of the Name field.
  11. Name string // An array of 16-bit Unicode characters in little-endian format that contains the client's account name.
  12. }
  13. // Unmarshal bytes into the ClientInfo struct
  14. func (k *ClientInfo) Unmarshal(b []byte) error {
  15. //The PAC_CLIENT_INFO structure is a simple structure that is not NDR-encoded.
  16. var p int
  17. var e binary.ByteOrder = binary.LittleEndian
  18. k.ClientID = mstypes.ReadFileTime(&b, &p, &e)
  19. k.NameLength = ndr.ReadUint16(&b, &p, &e)
  20. if len(b[p:]) < int(k.NameLength) {
  21. return ndr.Malformed{EText: "PAC ClientInfo length truncated"}
  22. }
  23. //Length divided by 2 as each run is 16bits = 2bytes
  24. s := make([]rune, k.NameLength/2, k.NameLength/2)
  25. for i := 0; i < len(s); i++ {
  26. s[i] = rune(ndr.ReadUint16(&b, &p, &e))
  27. }
  28. k.Name = string(s)
  29. //Check that there is only zero padding left
  30. if len(b) >= p {
  31. for _, v := range b[p:] {
  32. if v != 0 {
  33. return ndr.Malformed{EText: "Non-zero padding left over at end of data stream"}
  34. }
  35. }
  36. }
  37. return nil
  38. }