github.com/keysonZZZ/kmg@v0.0.0-20151121023212-05317bfd7d39/third/kmgRadius/vsa.go (about)

     1  package kmgRadius
     2  
     3  import (
     4  	"crypto"
     5  	_ "crypto/md5"
     6  	"crypto/rand"
     7  	"encoding/binary"
     8  	"fmt"
     9  	"reflect"
    10  )
    11  
    12  //Vendor Specific Attributes
    13  type VSA interface {
    14  	GetType() VendorType
    15  	String() string
    16  	Encode() (b []byte, err error)
    17  }
    18  
    19  // the data is the data from avp
    20  func vsaDecode(p *Packet, data []byte) (vsa VSA, err error) {
    21  	if len(data) < 4 {
    22  		return nil, fmt.Errorf("[vsaDecode] len(data)[%d]<4", len(data))
    23  	}
    24  	vendorId := VendorId(binary.BigEndian.Uint32(data[:4]))
    25  	switch vendorId {
    26  	case VendorIdMicrosoft:
    27  		if len(data) < 5 {
    28  			return nil, fmt.Errorf("[vsaDecode] len(data)[%d]<5", len(data))
    29  		}
    30  		vendorType := VendorType(data[4])
    31  		decoder := vendorType.decoder()
    32  		return decoder(p, vendorType, data[6:])
    33  	default:
    34  		return nil, fmt.Errorf("[vsaDecode] not implement vendorid:%d", vendorId)
    35  	}
    36  }
    37  
    38  type VendorId uint32
    39  
    40  const (
    41  	VendorIdMicrosoft = 311
    42  )
    43  
    44  func (a VendorId) String() string {
    45  	switch a {
    46  	case VendorIdMicrosoft:
    47  		return "Microsoft"
    48  	default:
    49  		return fmt.Sprintf("unknow VendorId:%d", a)
    50  	}
    51  }
    52  
    53  type VendorType uint8 //微软的?
    54  
    55  const (
    56  	VendorTypeMSMPPEEncryptionPolicy VendorType = 7
    57  	VendorTypeMSMPPEEncryptionTypes  VendorType = 8
    58  	VendorTypeMSMPPESendKey          VendorType = 16
    59  	VendorTypeMSMPPERecvKey          VendorType = 17
    60  )
    61  
    62  func (a VendorType) String() string {
    63  	switch a {
    64  	case VendorTypeMSMPPEEncryptionPolicy:
    65  		return "MSMPPEEncryptionPolicy"
    66  	case VendorTypeMSMPPEEncryptionTypes:
    67  		return "MSMPPEEncryptionTypes"
    68  	case VendorTypeMSMPPESendKey:
    69  		return "MSMPPESendKey"
    70  	case VendorTypeMSMPPERecvKey:
    71  		return "MSMPPERecvKey"
    72  	default:
    73  		return fmt.Sprintf("unknow VendorType:%d", a)
    74  	}
    75  }
    76  
    77  func (a VendorType) decoder() func(p *Packet, typ VendorType, data []byte) (avp VSA, err error) {
    78  	switch a {
    79  	case VendorTypeMSMPPEEncryptionPolicy:
    80  		return vsaUint32Enum(MSMPPEEncryptionPolicy(0))
    81  	case VendorTypeMSMPPEEncryptionTypes:
    82  		return vsaUint32Enum(MSMPPEEncryptionTypes(0))
    83  	case VendorTypeMSMPPESendKey, VendorTypeMSMPPERecvKey:
    84  		return vsaSendOrRecvKey
    85  	default:
    86  		return vsaBinary
    87  	}
    88  }
    89  
    90  func (a VendorType) VendorId() VendorId {
    91  	return VendorIdMicrosoft
    92  }
    93  
    94  func vsaEncodeWithByteSlice(typ VendorType, data []byte) (b []byte, err error) {
    95  	if len(data) > 255-2 {
    96  		return nil, fmt.Errorf("[encodeWithByteSlice] data length %d overflow(should less than 253)", len(data))
    97  	}
    98  	length := len(data) + 6
    99  	b = make([]byte, length)
   100  	binary.BigEndian.PutUint32(b[:4], uint32(typ.VendorId()))
   101  	b[4] = byte(typ)
   102  	b[5] = byte(len(data) + 2)
   103  	copy(b[6:], data)
   104  	return b, nil
   105  }
   106  func vsaBinary(p *Packet, typ VendorType, data []byte) (avp VSA, err error) {
   107  	return &BinaryVSA{
   108  		Type:  typ,
   109  		Value: data,
   110  	}, nil
   111  }
   112  
   113  type BinaryVSA struct {
   114  	Type  VendorType
   115  	Value []byte
   116  }
   117  
   118  func (a *BinaryVSA) GetType() VendorType {
   119  	return a.Type
   120  }
   121  func (a *BinaryVSA) String() string {
   122  	return fmt.Sprintf("Type: %s Value: %#v", a.Type, a.Value)
   123  }
   124  func (a *BinaryVSA) Encode() (b []byte, err error) {
   125  	if len(a.Value) > 253 {
   126  		return nil, fmt.Errorf("[BinaryAVP.Encode] len(a.Value)[%d]>253", len(a.Value))
   127  	}
   128  	return vsaEncodeWithByteSlice(a.Type, a.Value)
   129  }
   130  func (a *BinaryVSA) GetValue() interface{} {
   131  	return a.Value
   132  }
   133  
   134  // t should from a uint32 type like AcctStatusTypeEnum
   135  func vsaUint32Enum(t Stringer) func(p *Packet, typ VendorType, data []byte) (avp VSA, err error) {
   136  	return func(p *Packet, typ VendorType, data []byte) (avp VSA, err error) {
   137  		if len(data) != 4 {
   138  			return nil, fmt.Errorf("[vsaUint32Enum] len(data)[%d]!=4", len(data))
   139  		}
   140  		value := reflect.New(reflect.TypeOf(t)).Elem()
   141  		value.SetUint(uint64(binary.BigEndian.Uint32(data)))
   142  		valueI := value.Interface().(Stringer)
   143  		return &Uint32EnumVSA{
   144  			Type:  typ,
   145  			Value: valueI,
   146  		}, nil
   147  	}
   148  }
   149  
   150  type Uint32EnumVSA struct {
   151  	Type  VendorType
   152  	Value Stringer // value should derive from a uint32 type like AcctStatusTypeEnum
   153  }
   154  
   155  func (a *Uint32EnumVSA) GetType() VendorType {
   156  	return a.Type
   157  }
   158  func (a *Uint32EnumVSA) String() string {
   159  	return fmt.Sprintf("Type: %s Value: %s", a.GetType(), a.Value)
   160  }
   161  func (a *Uint32EnumVSA) Encode() (b []byte, err error) {
   162  	b = make([]byte, 4)
   163  	value := reflect.ValueOf(a.Value)
   164  	out := value.Uint()
   165  	if out >= (1 << 32) {
   166  		panic("[Uint32EnumAVP.Encode] enum number overflow")
   167  	}
   168  	binary.BigEndian.PutUint32(b, uint32(out))
   169  	return vsaEncodeWithByteSlice(a.Type, b)
   170  }
   171  func (a *Uint32EnumVSA) Copy() VSA {
   172  	return &Uint32EnumVSA{
   173  		Type:  a.Type,
   174  		Value: a.Value,
   175  	}
   176  }
   177  func (a *Uint32EnumVSA) GetValue() interface{} {
   178  	return a.Value
   179  }
   180  
   181  func vsaSendOrRecvKey(p *Packet, typ VendorType, data []byte) (avp VSA, err error) {
   182  	key, salt, err := msMPPEKeyDecode(p, data)
   183  	if err != nil {
   184  		return nil, err
   185  	}
   186  	return &MSMPPESendOrRecvKeyVSA{
   187  		packet: p,
   188  		Type:   typ,
   189  		Salt:   salt,
   190  		Key:    key,
   191  	}, nil
   192  }
   193  
   194  //send or recv key
   195  type MSMPPESendOrRecvKeyVSA struct {
   196  	packet *Packet
   197  	Type   VendorType
   198  	Salt   [2]byte //最高位要是1
   199  	Key    []byte
   200  }
   201  
   202  func (a *MSMPPESendOrRecvKeyVSA) SetPacket(p *Packet) {
   203  	a.packet = p
   204  }
   205  func (a *MSMPPESendOrRecvKeyVSA) GetType() VendorType {
   206  	return a.Type
   207  }
   208  func (a *MSMPPESendOrRecvKeyVSA) String() string {
   209  	return fmt.Sprintf("Type: %s Salt: %#v Key: %#v", a.GetType(), a.Salt, a.Key)
   210  }
   211  func (a *MSMPPESendOrRecvKeyVSA) Encode() (b []byte, err error) {
   212  	b, err = msMPPEKeyEncode(a.packet, a.Salt, a.Key)
   213  	if err != nil {
   214  		return nil, err
   215  	}
   216  	return vsaEncodeWithByteSlice(a.Type, b)
   217  }
   218  func (a *MSMPPESendOrRecvKeyVSA) GetValue() interface{} {
   219  	return a.Key
   220  }
   221  
   222  //随机一个新的 MSMPPESendOrRecvKeyVSA 的对象
   223  func NewMSMPPESendOrRecvKeyVSA(p *Packet, typ VendorType, key []byte) *MSMPPESendOrRecvKeyVSA {
   224  	salt := [2]byte{}
   225  	_, err := rand.Read(salt[:])
   226  	if err != nil {
   227  		panic(err)
   228  	}
   229  	salt[0] = salt[0] | 0x80 //最高位要是1
   230  	vsa := &MSMPPESendOrRecvKeyVSA{
   231  		packet: p,
   232  		Type:   typ,
   233  		Salt:   salt,
   234  		Key:    key,
   235  	}
   236  	return vsa
   237  }
   238  
   239  type MSMPPEEncryptionPolicy uint32
   240  
   241  const (
   242  	MSMPPEEncryptionPolicyEncryptionAllowed  MSMPPEEncryptionPolicy = 1
   243  	MSMPPEEncryptionPolicyEncryptionRequired MSMPPEEncryptionPolicy = 2
   244  )
   245  
   246  func (a MSMPPEEncryptionPolicy) String() string {
   247  	switch a {
   248  	case MSMPPEEncryptionPolicyEncryptionAllowed:
   249  		return "Allowed"
   250  	case MSMPPEEncryptionPolicyEncryptionRequired:
   251  		return "Required"
   252  	default:
   253  		return fmt.Sprintf("unknow MSMPPEEncryptionPolicy:%d", a)
   254  	}
   255  }
   256  
   257  type MSMPPEEncryptionTypes uint32
   258  
   259  const (
   260  	MSMPPEEncryptionTypesRC4Bit40      MSMPPEEncryptionTypes = 2
   261  	MSMPPEEncryptionTypesRC4Bit128     MSMPPEEncryptionTypes = 4
   262  	MSMPPEEncryptionTypesRC4Bit40Or128 MSMPPEEncryptionTypes = 6
   263  )
   264  
   265  func (a MSMPPEEncryptionTypes) String() string {
   266  	switch a {
   267  	case MSMPPEEncryptionTypesRC4Bit40:
   268  		return "RC4Bit40"
   269  	case MSMPPEEncryptionTypesRC4Bit128:
   270  		return "RC4Bit128"
   271  	case MSMPPEEncryptionTypesRC4Bit40Or128:
   272  		return "RC4Bit40Or128"
   273  	default:
   274  		return fmt.Sprintf("unknow MSMPPEEncryptionTypes:%d", a)
   275  	}
   276  }
   277  
   278  //内有随机
   279  func msMPPEKeyEncode(p *Packet, salt [2]byte, inData []byte) (out []byte, err error) {
   280  	paddingSize := 16 - (len(inData)+1)%16
   281  	if paddingSize == 16 {
   282  		paddingSize = 0
   283  	}
   284  	paddingedData := make([]byte, len(inData)+1+paddingSize)
   285  	if len(inData) > 255 {
   286  		return nil, fmt.Errorf("[msMPPEKeyEncode] length overflow len(inData)[%d]>255", len(inData))
   287  	}
   288  	paddingedData[0] = byte(len(inData))
   289  	copy(paddingedData[1:], inData)
   290  	out = make([]byte, len(paddingedData)+2)
   291  	copy(out[:2], salt[:])
   292  	h := crypto.MD5.New()
   293  	h.Write(p.Secret)
   294  	h.Write(p.Authenticator[:])
   295  	h.Write(out[:2])
   296  	b := h.Sum(nil)
   297  	blockSize := len(paddingedData) / 16
   298  	for i := 0; i < blockSize; i++ {
   299  		thisC := out[2+i*16 : 2+i*16+16]
   300  		thisP := paddingedData[i*16 : i*16+16]
   301  		xor(b, thisP, thisC)
   302  		//最后一次不用hash了
   303  		h := crypto.MD5.New()
   304  		h.Write(p.Secret)
   305  		h.Write(thisC)
   306  		b = h.Sum(nil)
   307  	}
   308  	return out, nil
   309  }
   310  
   311  func msMPPEKeyDecode(p *Packet, inData []byte) (out []byte, salt [2]byte, err error) {
   312  	if len(inData) < 18 {
   313  		return nil, salt, fmt.Errorf("[msMPPEKeyDecode] len(inData)[%d]<18", len(inData))
   314  	}
   315  	if (len(inData)-2)%16 != 0 {
   316  		return nil, salt, fmt.Errorf("[msMPPEKeyDecode] (len(inData)[%d]-2)%%16!=0", len(inData))
   317  	}
   318  	salt = [2]byte{}
   319  	copy(salt[:], inData[:2])
   320  	h := crypto.MD5.New()
   321  	h.Write(p.Secret)
   322  	h.Write(p.Authenticator[:])
   323  	h.Write(salt[:])
   324  	b := h.Sum(nil)
   325  	blockSize := (len(inData) - 2) / 16
   326  	out = make([]byte, len(inData)-2)
   327  	for i := 0; i < blockSize; i++ {
   328  		thisC := inData[2+i*16 : 2+i*16+16]
   329  		thisP := out[i*16 : i*16+16]
   330  		xor(b, thisC, thisP)
   331  		//最后一次不用hash了
   332  		h := crypto.MD5.New()
   333  		h.Write(p.Secret)
   334  		h.Write(thisC)
   335  		b = h.Sum(nil)
   336  	}
   337  	//fmt.Printf("%#v\n%#v\n%#v\n", salt, inData, out)
   338  	if int(out[0]) > len(inData)-3 {
   339  		return nil, salt, fmt.Errorf("[msMPPEKeyDecode] out[0][%d]>len(inData)[%d]-3", out[0], len(inData))
   340  	}
   341  	return out[1 : out[0]+1], salt, nil
   342  }
   343  
   344  func xor(inA []byte, inB []byte, out []byte) {
   345  	for i := 0; i < len(inA); i++ {
   346  		out[i] = inA[i] ^ inB[i]
   347  	}
   348  }