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 }