package  kadmin 
 
import  ( 
	"bytes"  
	"encoding/binary"  
	"errors"  
	"fmt"  
	"math"  
 
	"github.com/jcmturner/gokrb5/v8/messages"  
	"github.com/jcmturner/gokrb5/v8/types"  
) 
 
const  ( 
	verisonHex = "ff80"  
) 
 
 
type  Request  struct  { 
	APREQ   messages .APReq  
	KRBPriv messages .KRBPriv  
} 
 
 
type  Reply  struct  { 
	MessageLength int  
	Version       int  
	APREPLength   int  
	APREP         messages .APRep  
	KRBPriv       messages .KRBPriv  
	KRBError      messages .KRBError  
	IsKRBError    bool  
	ResultCode    uint16  
	Result        string  
} 
 
 
func  (m  *Request ) Marshal () (b  []byte , err  error ) { 
	b  = []byte {255 , 128 }  
	ab , e  := m .APREQ .Marshal () 
	if  e  != nil  { 
		err  = fmt .Errorf ("error marshaling AP_REQ: %v" , e ) 
		return  
	} 
	if  len (ab ) > math .MaxUint16  { 
		err  = errors .New ("length of AP_REQ greater then max Uint16 size" ) 
		return  
	} 
	al  := make ([]byte , 2 ) 
	binary .BigEndian .PutUint16 (al , uint16 (len (ab ))) 
	b  = append (b , al ...) 
	b  = append (b , ab ...) 
	pb , e  := m .KRBPriv .Marshal () 
	if  e  != nil  { 
		err  = fmt .Errorf ("error marshaling KRB_Priv: %v" , e ) 
		return  
	} 
	b  = append (b , pb ...) 
	if  len (b )+2  > math .MaxUint16  { 
		err  = errors .New ("length of message greater then max Uint16 size" ) 
		return  
	} 
	ml  := make ([]byte , 2 ) 
	binary .BigEndian .PutUint16 (ml , uint16 (len (b )+2 )) 
	b  = append (ml , b ...) 
	return  
} 
 
 
func  (m  *Reply ) Unmarshal (b  []byte ) error  { 
	m .MessageLength  = int (binary .BigEndian .Uint16 (b [0 :2 ])) 
	m .Version  = int (binary .BigEndian .Uint16 (b [2 :4 ])) 
	if  m .Version  != 1  { 
		return  fmt .Errorf ("kadmin reply has incorrect protocol version number: %d" , m .Version ) 
	} 
	m .APREPLength  = int (binary .BigEndian .Uint16 (b [4 :6 ])) 
	if  m .APREPLength  != 0  { 
		err  := m .APREP .Unmarshal (b [6  : 6 +m .APREPLength ]) 
		if  err  != nil  { 
			return  err  
		} 
		err  = m .KRBPriv .Unmarshal (b [6 +m .APREPLength  : m .MessageLength ]) 
		if  err  != nil  { 
			return  err  
		} 
	} else  { 
		m .IsKRBError  = true  
		m .KRBError .Unmarshal (b [6 :m .MessageLength ]) 
		m .ResultCode , m .Result  = parseResponse (m .KRBError .EData ) 
	} 
	return  nil  
} 
 
func  parseResponse(b  []byte ) (c  uint16 , s  string ) { 
	c  = binary .BigEndian .Uint16 (b [0 :2 ]) 
	buf  := bytes .NewBuffer (b [2 :]) 
	m  := make ([]byte , len (b )-2 ) 
	binary .Read (buf , binary .BigEndian , &m ) 
	s  = string (m ) 
	return  
} 
 
 
func  (m  *Reply ) Decrypt (key  types .EncryptionKey ) error  { 
	if  m .IsKRBError  { 
		return  m .KRBError  
	} 
	err  := m .KRBPriv .DecryptEncPart (key ) 
	if  err  != nil  { 
		return  err  
	} 
	m .ResultCode , m .Result  = parseResponse (m .KRBPriv .DecryptedEncPart .UserData ) 
	return  nil  
} 
  
The pages are generated with Golds   v0.6.7 . (GOOS=linux GOARCH=amd64)
Golds  is a Go 101  project developed by Tapir Liu .
PR and bug reports are welcome and can be submitted to the issue list .
Please follow @Go100and1  (reachable from the left QR code) to get the latest news of Golds .