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

     1  package kmgRadius
     2  
     3  import (
     4  	"bytes"
     5  	"crypto"
     6  	_ "crypto/md5"
     7  	"encoding/binary"
     8  	"encoding/hex"
     9  	"fmt"
    10  	"net"
    11  	"reflect"
    12  	"strconv"
    13  
    14  	"github.com/bronze1man/kmg/third/kmgRadius/eap"
    15  )
    16  
    17  type AVP interface {
    18  	GetType() AVPType
    19  	Encode() (b []byte, err error)
    20  	Copy() AVP
    21  
    22  	String() string
    23  	GetValue() interface{}
    24  	ValueAsString() string
    25  }
    26  
    27  func avpDecode(p *Packet, b []byte) (avp AVP, err error) {
    28  	if len(b) < 2 {
    29  		return nil, fmt.Errorf("[avp.Decode] protocol error 1 buffer too small")
    30  	}
    31  	typ := AVPType(b[0])
    32  	data := b[2:]
    33  	decoder := getTypeDesc(typ).decoder
    34  	return decoder(p, typ, data)
    35  }
    36  
    37  func encodeWithByteSlice(typ AVPType, data []byte) (b []byte, err error) {
    38  	if len(data) > 253 {
    39  		return nil, fmt.Errorf("[encodeWithByteSlice] data length %d overflow(should less than 253)", len(data))
    40  	}
    41  	length := len(data) + 2
    42  	b = make([]byte, length)
    43  	b[0] = byte(typ)
    44  	b[1] = byte(length)
    45  	copy(b[2:], data)
    46  	return b, nil
    47  }
    48  func avpBinary(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
    49  	return &BinaryAVP{
    50  		Type:  typ,
    51  		Value: data,
    52  	}, nil
    53  }
    54  
    55  type BinaryAVP struct {
    56  	Type  AVPType
    57  	Value []byte
    58  }
    59  
    60  func (a *BinaryAVP) GetType() AVPType {
    61  	return a.Type
    62  }
    63  func (a *BinaryAVP) String() string {
    64  	return fmt.Sprintf("Type: %s Value: %#v", a.Type, a.Value)
    65  }
    66  func (a *BinaryAVP) Encode() (b []byte, err error) {
    67  	if len(a.Value) > 253 {
    68  		return nil, fmt.Errorf("[BinaryAVP.Encode] len(a.Value)[%d]>253", len(a.Value))
    69  	}
    70  	return encodeWithByteSlice(a.Type, a.Value)
    71  }
    72  func (a *BinaryAVP) Copy() AVP {
    73  	return &BinaryAVP{
    74  		Type:  a.Type,
    75  		Value: append([]byte(nil), a.Value...),
    76  	}
    77  }
    78  func (a *BinaryAVP) GetValue() interface{} {
    79  	return a.Value
    80  }
    81  func (a *BinaryAVP) ValueAsString() string {
    82  	return hex.EncodeToString(a.Value)
    83  }
    84  
    85  func avpString(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
    86  	return &StringAVP{
    87  		Type:  typ,
    88  		Value: string(data),
    89  	}, nil
    90  }
    91  
    92  type StringAVP struct {
    93  	Type  AVPType
    94  	Value string
    95  }
    96  
    97  func (a *StringAVP) GetType() AVPType {
    98  	return a.Type
    99  }
   100  func (a *StringAVP) String() string {
   101  	return fmt.Sprintf("Type: %s Value: %s", a.Type, a.Value)
   102  }
   103  func (a *StringAVP) Encode() (b []byte, err error) {
   104  	if len(a.Value) > 253 {
   105  		return nil, fmt.Errorf("[StringAVP.Encode] len(a.Value)[%d]>253", len(a.Value))
   106  	}
   107  	return encodeWithByteSlice(a.Type, []byte(a.Value))
   108  }
   109  func (a *StringAVP) Copy() AVP {
   110  	return &StringAVP{
   111  		Type:  a.Type,
   112  		Value: a.Value,
   113  	}
   114  }
   115  func (a *StringAVP) GetValue() interface{} {
   116  	return a.Value
   117  }
   118  
   119  func (a *StringAVP) ValueAsString() string {
   120  	return a.Value
   121  }
   122  
   123  func avpIP(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   124  	return &IpAVP{
   125  		Type:  typ,
   126  		Value: net.IP(data),
   127  	}, nil
   128  }
   129  
   130  type IpAVP struct {
   131  	Type  AVPType
   132  	Value net.IP
   133  }
   134  
   135  func (a *IpAVP) GetType() AVPType {
   136  	return a.Type
   137  }
   138  func (a *IpAVP) String() string {
   139  	return fmt.Sprintf("Type: %s Value: %s", a.Type, a.Value)
   140  }
   141  func (a *IpAVP) Encode() (b []byte, err error) {
   142  	return encodeWithByteSlice(a.Type, []byte(a.Value))
   143  }
   144  func (a *IpAVP) Copy() AVP {
   145  	return &IpAVP{
   146  		Type:  a.Type,
   147  		Value: net.IP(append([]byte(nil), []byte(a.Value)...)),
   148  	}
   149  }
   150  func (a *IpAVP) GetValue() interface{} {
   151  	return a.Value
   152  }
   153  func (a *IpAVP) ValueAsString() string {
   154  	return a.Value.String()
   155  }
   156  
   157  func avpUint32(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   158  	if len(data) != 4 {
   159  		return nil, fmt.Errorf("[avpUint32] len(data)[%d]!=4", len(data))
   160  	}
   161  	return &Uint32AVP{
   162  		Type:  typ,
   163  		Value: uint32(binary.BigEndian.Uint32(data)),
   164  	}, nil
   165  }
   166  
   167  type Uint32AVP struct {
   168  	Type  AVPType
   169  	Value uint32
   170  }
   171  
   172  func (a *Uint32AVP) GetType() AVPType {
   173  	return a.Type
   174  }
   175  func (a *Uint32AVP) String() string {
   176  	return fmt.Sprintf("Type: %s Value: %d", a.Type, a.Value)
   177  }
   178  func (a *Uint32AVP) Encode() (b []byte, err error) {
   179  	data := make([]byte, 4)
   180  	binary.BigEndian.PutUint32(data, a.Value)
   181  	return encodeWithByteSlice(a.Type, data)
   182  }
   183  func (a *Uint32AVP) Copy() AVP {
   184  	return &Uint32AVP{
   185  		Type:  a.Type,
   186  		Value: a.Value,
   187  	}
   188  }
   189  func (a *Uint32AVP) GetValue() interface{} {
   190  	return a.Value
   191  }
   192  func (a *Uint32AVP) ValueAsString() string {
   193  	return strconv.Itoa(int(a.Value))
   194  }
   195  
   196  func avpPassword(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   197  	fmt.Printf("%#v\n", data)
   198  	if len(data) < 16 {
   199  		return nil, fmt.Errorf("[avpPassword] len(data)[%d]<16", len(data))
   200  	}
   201  	if len(data) > 128 {
   202  		return nil, fmt.Errorf("[avpPassword] len(data)[%d]>128", len(data))
   203  	}
   204  	//Decode password. XOR against md5(p.server.secret+Authenticator)
   205  	m := crypto.Hash(crypto.MD5).New()
   206  	m.Write(p.Secret)
   207  	m.Write(p.Authenticator[:])
   208  	md := m.Sum(nil)
   209  	pass := append([]byte(nil), data...)
   210  	blockNum := len(pass) / 16
   211  	if len(pass)%16 != 0 {
   212  		return nil, fmt.Errorf("[avpPassword] blockNum[%d]%%16!=0", blockNum)
   213  	}
   214  	outputPass := make([]byte, len(pass))
   215  	for i := 0; i < blockNum; i++ {
   216  		for j := 0; j < 16; j++ {
   217  			outputPass[i*16+j] = pass[i*16+j] ^ md[j]
   218  		}
   219  		m := crypto.Hash(crypto.MD5).New()
   220  		m.Write(p.Secret)
   221  		m.Write(pass[i*16 : i*16+16])
   222  		md = m.Sum(nil)
   223  	}
   224  	outputPass = bytes.TrimRight(outputPass, string([]rune{0}))
   225  	avpP := &PasswordAVP{
   226  		Value: string(outputPass),
   227  	}
   228  	avpP.SetPacket(p)
   229  	return avpP, nil
   230  }
   231  
   232  type PasswordAVP struct {
   233  	packet *Packet
   234  	Value  string // plain of password
   235  }
   236  
   237  func (a *PasswordAVP) GetType() AVPType {
   238  	return AVPTypeUserPassword
   239  }
   240  func (a *PasswordAVP) String() string {
   241  	return fmt.Sprintf("Type: %s Value: %s", a.GetType(), a.Value)
   242  }
   243  func (a *PasswordAVP) SetPacket(p *Packet) {
   244  	a.packet = p
   245  }
   246  func (a *PasswordAVP) Copy() AVP {
   247  	return &PasswordAVP{
   248  		packet: a.packet,
   249  		Value:  a.Value,
   250  	}
   251  }
   252  func (a *PasswordAVP) GetValue() interface{} {
   253  	return a.Value
   254  }
   255  
   256  func (a *PasswordAVP) ValueAsString() string {
   257  	return a.Value
   258  }
   259  
   260  //you need set packet before encode
   261  func (a *PasswordAVP) Encode() (b []byte, err error) {
   262  	m := crypto.Hash(crypto.MD5).New()
   263  	m.Write(a.packet.Secret)
   264  	m.Write(a.packet.Authenticator[:])
   265  	md := m.Sum(nil)
   266  	if len(a.Value) > 128 {
   267  		return nil, fmt.Errorf("[PasswordAVP.Encode] len(data)[%d]>128", len(a.Value))
   268  	}
   269  	inPassLen := len(a.Value) / 16 * 16
   270  	if len(a.Value)%16 != 0 {
   271  		inPassLen += 16
   272  	}
   273  	pass := make([]byte, inPassLen)
   274  	outPass := make([]byte, inPassLen)
   275  	copy(pass, a.Value)
   276  	blockNum := inPassLen / 16
   277  	for i := 0; i < blockNum; i++ {
   278  		for j := 0; j < 16; j++ {
   279  			outPass[i*16+j] = pass[i*16+j] ^ md[j]
   280  		}
   281  		m := crypto.Hash(crypto.MD5).New()
   282  		m.Write(a.packet.Secret)
   283  		m.Write(outPass[i*16 : i*16+16])
   284  		md = m.Sum(nil)
   285  	}
   286  	return encodeWithByteSlice(AVPTypeUserPassword, outPass)
   287  }
   288  
   289  // t should from a uint32 type like AcctStatusTypeEnum
   290  func avpUint32Enum(t Stringer) func(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   291  	return func(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   292  		value := reflect.New(reflect.TypeOf(t)).Elem()
   293  		value.SetUint(uint64(binary.BigEndian.Uint32(data)))
   294  		valueI := value.Interface().(Stringer)
   295  		return &Uint32EnumAVP{
   296  			Type:  typ,
   297  			Value: valueI,
   298  		}, nil
   299  	}
   300  }
   301  
   302  type Uint32EnumAVP struct {
   303  	Type  AVPType
   304  	Value Stringer // value should derive from a uint32 type like AcctStatusTypeEnum
   305  }
   306  
   307  func (a *Uint32EnumAVP) GetType() AVPType {
   308  	return a.Type
   309  }
   310  func (a *Uint32EnumAVP) String() string {
   311  	return fmt.Sprintf("Type: %s Value: %s", a.GetType(), a.Value)
   312  }
   313  func (a *Uint32EnumAVP) Encode() (b []byte, err error) {
   314  	b = make([]byte, 4)
   315  	value := reflect.ValueOf(a.Value)
   316  	out := value.Uint()
   317  	if out >= (1 << 32) {
   318  		panic("[Uint32EnumAVP.Encode] enum number overflow")
   319  	}
   320  	binary.BigEndian.PutUint32(b, uint32(out))
   321  	return encodeWithByteSlice(a.Type, b)
   322  }
   323  func (a *Uint32EnumAVP) Copy() AVP {
   324  	return &Uint32EnumAVP{
   325  		Type:  a.Type,
   326  		Value: a.Value,
   327  	}
   328  }
   329  func (a *Uint32EnumAVP) GetValue() interface{} {
   330  	return a.Value
   331  }
   332  func (a *Uint32EnumAVP) ValueAsString() string {
   333  	return a.Value.String()
   334  }
   335  
   336  func avpEapMessage(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   337  	eap, err := eap.Decode(data)
   338  	if err != nil {
   339  		return nil, err
   340  	}
   341  	return &EapAVP{
   342  		Value: eap,
   343  	}, nil
   344  }
   345  
   346  type EapAVP struct {
   347  	Value eap.Packet
   348  }
   349  
   350  func (a *EapAVP) GetType() AVPType {
   351  	return AVPTypeEAPMessage
   352  }
   353  func (a *EapAVP) String() string {
   354  	return fmt.Sprintf("Type: %s Value: %s", a.GetType(), a.Value.String())
   355  }
   356  func (a *EapAVP) Encode() (b []byte, err error) {
   357  	b = a.Value.Encode()
   358  	return encodeWithByteSlice(AVPTypeEAPMessage, b)
   359  }
   360  
   361  //TODO real copy
   362  func (a *EapAVP) Copy() AVP {
   363  	return &EapAVP{
   364  		Value: a.Value,
   365  	}
   366  }
   367  func (a *EapAVP) GetValue() interface{} {
   368  	return a.Value
   369  }
   370  func (a *EapAVP) ValueAsString() string {
   371  	return a.Value.String()
   372  }
   373  
   374  func avpVendorSpecific(p *Packet, typ AVPType, data []byte) (avp AVP, err error) {
   375  	vsa, err := vsaDecode(p, data)
   376  	if err != nil {
   377  		return nil, err
   378  	}
   379  	return &VendorSpecificAVP{
   380  		Value: vsa,
   381  	}, nil
   382  }
   383  
   384  type VendorSpecificAVP struct {
   385  	Value VSA
   386  }
   387  
   388  func (a *VendorSpecificAVP) GetType() AVPType {
   389  	return AVPTypeVendorSpecific
   390  }
   391  func (a *VendorSpecificAVP) String() string {
   392  	return fmt.Sprintf("Type: %s Value: %s", a.GetType(), a.Value.String())
   393  }
   394  func (a *VendorSpecificAVP) Encode() (b []byte, err error) {
   395  	b, err = a.Value.Encode()
   396  	if err != nil {
   397  		return nil, err
   398  	}
   399  	return encodeWithByteSlice(AVPTypeVendorSpecific, b)
   400  }
   401  
   402  //TODO real copy
   403  func (a *VendorSpecificAVP) Copy() AVP {
   404  	return &VendorSpecificAVP{
   405  		Value: a.Value,
   406  	}
   407  }
   408  func (a *VendorSpecificAVP) GetValue() interface{} {
   409  	return a.Value
   410  }
   411  func (a *VendorSpecificAVP) ValueAsString() string {
   412  	return a.Value.String()
   413  }
   414  
   415  type Stringer interface {
   416  	String() string
   417  }
   418  
   419  type AcctStatusTypeEnum uint32
   420  
   421  const (
   422  	AcctStatusTypeEnumStart         AcctStatusTypeEnum = 1
   423  	AcctStatusTypeEnumStop          AcctStatusTypeEnum = 2
   424  	AcctStatusTypeEnumInterimUpdate AcctStatusTypeEnum = 3
   425  	AcctStatusTypeEnumAccountingOn  AcctStatusTypeEnum = 7
   426  	AcctStatusTypeEnumAccountingOff AcctStatusTypeEnum = 8
   427  )
   428  
   429  func (e AcctStatusTypeEnum) String() string {
   430  	switch e {
   431  	case AcctStatusTypeEnumStart:
   432  		return "Start"
   433  	case AcctStatusTypeEnumStop:
   434  		return "Stop"
   435  	case AcctStatusTypeEnumInterimUpdate:
   436  		return "InterimUpdate"
   437  	case AcctStatusTypeEnumAccountingOn:
   438  		return "AccountingOn"
   439  	case AcctStatusTypeEnumAccountingOff:
   440  		return "AccountingOff"
   441  	}
   442  	return "unknow code " + strconv.Itoa(int(e))
   443  }
   444  
   445  type NASPortTypeEnum uint32
   446  
   447  // TODO finish it
   448  const (
   449  	NASPortTypeEnumAsync            NASPortTypeEnum = 0
   450  	NASPortTypeEnumSync             NASPortTypeEnum = 1
   451  	NASPortTypeEnumISDNSync         NASPortTypeEnum = 2
   452  	NASPortTypeEnumISDNSyncV120     NASPortTypeEnum = 3
   453  	NASPortTypeEnumISDNSyncV110     NASPortTypeEnum = 4
   454  	NASPortTypeEnumVirtual          NASPortTypeEnum = 5
   455  	NASPortTypeEnumPIAFS            NASPortTypeEnum = 6
   456  	NASPortTypeEnumHDLCClearChannel NASPortTypeEnum = 7
   457  	NASPortTypeEnumEthernet         NASPortTypeEnum = 15
   458  	NASPortTypeEnumCable            NASPortTypeEnum = 17
   459  )
   460  
   461  func (e NASPortTypeEnum) String() string {
   462  	switch e {
   463  	case NASPortTypeEnumAsync:
   464  		return "Async"
   465  	case NASPortTypeEnumSync:
   466  		return "Sync"
   467  	case NASPortTypeEnumISDNSync:
   468  		return "ISDNSync"
   469  	case NASPortTypeEnumISDNSyncV120:
   470  		return "ISDNSyncV120"
   471  	case NASPortTypeEnumISDNSyncV110:
   472  		return "ISDNSyncV110"
   473  	case NASPortTypeEnumVirtual:
   474  		return "Virtual"
   475  	case NASPortTypeEnumPIAFS:
   476  		return "PIAFS"
   477  	case NASPortTypeEnumHDLCClearChannel:
   478  		return "HDLCClearChannel"
   479  	case NASPortTypeEnumEthernet:
   480  		return "Ethernet"
   481  	case NASPortTypeEnumCable:
   482  		return "Cable"
   483  	}
   484  	return "unknow code " + strconv.Itoa(int(e))
   485  }
   486  
   487  type ServiceTypeEnum uint32
   488  
   489  // TODO finish it
   490  const (
   491  	ServiceTypeEnumLogin          ServiceTypeEnum = 1
   492  	ServiceTypeEnumFramed         ServiceTypeEnum = 2
   493  	ServiceTypeEnumCallbackLogin  ServiceTypeEnum = 3
   494  	ServiceTypeEnumCallbackFramed ServiceTypeEnum = 4
   495  	ServiceTypeEnumOutbound       ServiceTypeEnum = 5
   496  )
   497  
   498  func (e ServiceTypeEnum) String() string {
   499  	switch e {
   500  	case ServiceTypeEnumLogin:
   501  		return "Login"
   502  	case ServiceTypeEnumFramed:
   503  		return "Framed"
   504  	case ServiceTypeEnumCallbackLogin:
   505  		return "CallbackLogin"
   506  	case ServiceTypeEnumCallbackFramed:
   507  		return "CallbackFramed"
   508  	case ServiceTypeEnumOutbound:
   509  		return "Outbound"
   510  	}
   511  	return "unknow code " + strconv.Itoa(int(e))
   512  }
   513  
   514  type AcctTerminateCauseEnum uint32
   515  
   516  // TODO finish it
   517  const (
   518  	AcctTerminateCauseEnumUserRequest AcctTerminateCauseEnum = 1
   519  	AcctTerminateCauseEnumLostCarrier AcctTerminateCauseEnum = 2
   520  	AcctTerminateCauseEnumLostService AcctTerminateCauseEnum = 3
   521  	AcctTerminateCauseEnumIdleTimeout AcctTerminateCauseEnum = 4
   522  )
   523  
   524  func (e AcctTerminateCauseEnum) String() string {
   525  	switch e {
   526  	case AcctTerminateCauseEnumUserRequest:
   527  		return "UserRequest"
   528  	case AcctTerminateCauseEnumLostCarrier:
   529  		return "LostCarrier"
   530  	case AcctTerminateCauseEnumLostService:
   531  		return "LostService"
   532  	case AcctTerminateCauseEnumIdleTimeout:
   533  		return "IdleTimeout"
   534  	}
   535  	return "unknow code " + strconv.Itoa(int(e))
   536  }