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 }