github.com/jcmturner/gokrb5/v8@v8.4.4/pac/supplemental_cred.go (about)

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