supplemental_cred.go 2.5 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687
  1. package pac
  2. import (
  3. "bytes"
  4. "encoding/binary"
  5. "errors"
  6. "fmt"
  7. "github.com/jcmturner/rpc/v2/mstypes"
  8. "github.com/jcmturner/rpc/v2/ndr"
  9. )
  10. const (
  11. // NTLMSupCredLMOWF indicates that the LM OWF member is present and valid.
  12. NTLMSupCredLMOWF uint32 = 31
  13. // NTLMSupCredNTOWF indicates that the NT OWF member is present and valid.
  14. NTLMSupCredNTOWF uint32 = 30
  15. )
  16. // NTLMSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237949.aspx
  17. type NTLMSupplementalCred struct {
  18. Version uint32 // A 32-bit unsigned integer that defines the credential version.This field MUST be 0x00000000.
  19. Flags uint32
  20. LMPassword []byte // A 16-element array of unsigned 8-bit integers that define the LM OWF. The LMPassword member MUST be ignored if the L flag is not set in the Flags member.
  21. NTPassword []byte // A 16-element array of unsigned 8-bit integers that define the NT OWF. The NTPassword member MUST be ignored if the N flag is not set in the Flags member.
  22. }
  23. // Unmarshal converts the bytes provided into a NTLMSupplementalCred.
  24. func (c *NTLMSupplementalCred) Unmarshal(b []byte) (err error) {
  25. r := mstypes.NewReader(bytes.NewReader(b))
  26. c.Version, err = r.Uint32()
  27. if err != nil {
  28. return
  29. }
  30. if c.Version != 0 {
  31. err = errors.New("NTLMSupplementalCred version is not zero")
  32. return
  33. }
  34. c.Flags, err = r.Uint32()
  35. if err != nil {
  36. return
  37. }
  38. if isFlagSet(c.Flags, NTLMSupCredLMOWF) {
  39. c.LMPassword, err = r.ReadBytes(16)
  40. if err != nil {
  41. return
  42. }
  43. }
  44. if isFlagSet(c.Flags, NTLMSupCredNTOWF) {
  45. c.NTPassword, err = r.ReadBytes(16)
  46. if err != nil {
  47. return
  48. }
  49. }
  50. return
  51. }
  52. // isFlagSet tests if a flag is set in the uint32 little endian flag
  53. func isFlagSet(f uint32, i uint32) bool {
  54. //Which byte?
  55. b := int(i / 8)
  56. //Which bit in byte
  57. p := uint(7 - (int(i) - 8*b))
  58. fb := make([]byte, 4)
  59. binary.LittleEndian.PutUint32(fb, f)
  60. if fb[b]&(1<<p) != 0 {
  61. return true
  62. }
  63. return false
  64. }
  65. // SECPKGSupplementalCred implements https://msdn.microsoft.com/en-us/library/cc237956.aspx
  66. type SECPKGSupplementalCred struct {
  67. PackageName mstypes.RPCUnicodeString
  68. CredentialSize uint32
  69. Credentials []uint8 `ndr:"pointer,conformant"` // Is a ptr. Size is the value of CredentialSize
  70. }
  71. // Unmarshal converts the bytes provided into a SECPKGSupplementalCred.
  72. func (c *SECPKGSupplementalCred) Unmarshal(b []byte) (err error) {
  73. dec := ndr.NewDecoder(bytes.NewReader(b))
  74. err = dec.Decode(c)
  75. if err != nil {
  76. err = fmt.Errorf("error unmarshaling SECPKGSupplementalCred: %v", err)
  77. }
  78. return
  79. }