mirror of https://github.com/bjdgyc/anylink.git
101 lines
2.8 KiB
Go
101 lines
2.8 KiB
Go
package dbdata
|
||
|
||
import (
|
||
"context"
|
||
"encoding/json"
|
||
"errors"
|
||
"fmt"
|
||
"net"
|
||
"reflect"
|
||
"time"
|
||
|
||
"github.com/bjdgyc/anylink/base"
|
||
"layeh.com/radius"
|
||
"layeh.com/radius/rfc2865"
|
||
)
|
||
|
||
type AuthRadius struct {
|
||
Addr string `json:"addr"`
|
||
Secret string `json:"secret"`
|
||
Nasip string `json:"nasip"`
|
||
}
|
||
|
||
func init() {
|
||
authRegistry["radius"] = reflect.TypeOf(AuthRadius{})
|
||
}
|
||
|
||
func (auth AuthRadius) checkData(authData map[string]interface{}) error {
|
||
authType := authData["type"].(string)
|
||
bodyBytes, err := json.Marshal(authData[authType])
|
||
if err != nil {
|
||
return errors.New("Radius的密钥/服务器地址填写有误")
|
||
}
|
||
json.Unmarshal(bodyBytes, &auth)
|
||
if !ValidateIpPort(auth.Addr) {
|
||
return errors.New("Radius的服务器地址填写有误")
|
||
}
|
||
// freeradius官网最大8000字符, 这里限制200
|
||
if len(auth.Secret) < 8 || len(auth.Secret) > 200 {
|
||
return errors.New("Radius的密钥长度需在8~200个字符之间")
|
||
}
|
||
return nil
|
||
}
|
||
|
||
func (auth AuthRadius) checkUser(name, pwd string, g *Group, ext map[string]interface{}) error {
|
||
pl := len(pwd)
|
||
if name == "" || pl < 1 {
|
||
return fmt.Errorf("%s %s", name, "密码错误")
|
||
}
|
||
authType := g.Auth["type"].(string)
|
||
if _, ok := g.Auth[authType]; !ok {
|
||
return fmt.Errorf("%s %s", name, "Radius的radius值不存在")
|
||
}
|
||
bodyBytes, err := json.Marshal(g.Auth[authType])
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius Marshal出现错误")
|
||
}
|
||
err = json.Unmarshal(bodyBytes, &auth)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius Unmarshal出现错误")
|
||
}
|
||
// radius认证时,设置超时3秒
|
||
packet := radius.New(radius.CodeAccessRequest, []byte(auth.Secret))
|
||
err = rfc2865.UserName_SetString(packet, name)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius set name 出现错误")
|
||
}
|
||
err = rfc2865.UserPassword_SetString(packet, pwd)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius set pwd 出现错误")
|
||
}
|
||
if auth.Nasip != "" {
|
||
nasip := net.ParseIP(auth.Nasip)
|
||
err = rfc2865.NASIPAddress_Set(packet, nasip)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius set nasip 出现错误")
|
||
}
|
||
}
|
||
macAddr := ""
|
||
if ext["mac_addr"] != nil {
|
||
macAddr = ext["mac_addr"].(string)
|
||
base.Trace("AuthRadius", ext, macAddr)
|
||
}
|
||
if macAddr != "" {
|
||
err = rfc2865.CallingStationID_AddString(packet, macAddr)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s", name, "Radius set CallingStationID 出现错误")
|
||
}
|
||
}
|
||
|
||
ctx, done := context.WithTimeout(context.Background(), 3*time.Second)
|
||
defer done()
|
||
response, err := radius.Exchange(ctx, packet, auth.Addr)
|
||
if err != nil {
|
||
return fmt.Errorf("%s %s %s", name, "Radius服务器连接异常, 请检测服务器和端口", err)
|
||
}
|
||
if response.Code != radius.CodeAccessAccept {
|
||
return fmt.Errorf("%s %s", name, "Radius:用户名或密码错误")
|
||
}
|
||
return nil
|
||
}
|