//upload a dir func (obj *BulkUpyun) UploadDir(upyun_path, local_path string) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { kmgLog.Log("upyun", "upload dir: "+upyun_path, nil) dir, err := os.Open(local_path) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } file_list, err := dir.Readdir(0) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } err = obj.UpYun.MkDir(upyun_path, true) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } for _, file_info := range file_list { file_name := file_info.Name() this_local_path := local_path + "/" + file_name this_upyun_path := upyun_path + "/" + file_name if file_info.IsDir() { obj.UploadDir(this_upyun_path, this_local_path) } else { obj.UploadFile(this_upyun_path, this_local_path) } } return })) }
//resursive download a dir func (obj *BulkUpyun) DownloadDir(upyun_path string, file_path string) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { kmgLog.Log("upyun", "download dir: "+upyun_path, nil) file_list, err := obj.UpYun.ReadDir(upyun_path) file_mode := os.FileMode(0777) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } for _, file_info := range file_list { file_type := file_info.Type file_name := file_info.Name this_local_path := file_path + "/" + file_name this_upyun_path := upyun_path + "/" + file_name if file_type == "folder" { err := os.MkdirAll(this_local_path, file_mode) if err != nil { kmgLog.Log("upyunError", "os.MkdirAll fail!"+err.Error(), err) return } obj.DownloadDir(this_upyun_path, this_local_path) } else if file_type == "file" { obj.DownloadFile(this_upyun_path, this_local_path) } else { kmgLog.Log("upyunError", "unknow file type2:"+file_type, err) return } } return })) }
// http-json-api v1 // 1.数据传输使用psk加密,明文不泄漏信息 // 2.使用json序列化信息 // 3.只有部分api func (s *generateServer_Demo) ServeHTTP(w http.ResponseWriter, req *http.Request) { b1, err := kmgHttp.RequestReadAllBody(req) if err != nil { http.Error(w, "error 1", 400) kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) return } //解密 b1, err = kmgCrypto.CompressAndEncryptBytesDecode(kmgRpc_Demo_encryptKey, b1) if err != nil { http.Error(w, "error 2", 400) kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) return } outBuf, err := s.handleApiV1(b1) if err != nil { kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) outBuf = append([]byte{kmgRpc_Demo_ResponseCodeError}, err.Error()...) } else { outBuf = append([]byte{kmgRpc_Demo_ResponseCodeSuccess}, outBuf...) } //加密 outBuf = kmgCrypto.CompressAndEncryptBytesEncode(kmgRpc_Demo_encryptKey, outBuf) w.WriteHeader(200) w.Header().Set("Content-type", "image/jpeg") w.Write(outBuf) }
//we need to know when is finish delete all file in it ,so we can delete the dir func (obj *BulkUpyun) deleteDir(upyun_path string, finish_wg *sync.WaitGroup) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { wg := &sync.WaitGroup{} defer obj.Tm.AddTaskNewThread(kmgTask.TaskFunc(func() { wg.Wait() wg.Add(1) obj.deleteFile(upyun_path, wg) wg.Wait() finish_wg.Done() })) kmgLog.Log("upyun", "delete dir: "+upyun_path, nil) file_list, err := obj.UpYun.ReadDir(upyun_path) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } for _, file_info := range file_list { file_type := file_info.Type file_name := file_info.Name this_upyun_path := upyun_path + "/" + file_name if file_type == "folder" { wg.Add(1) obj.deleteDir(this_upyun_path, wg) } else if file_type == "file" { wg.Add(1) obj.deleteFile(this_upyun_path, wg) } else { kmgLog.Log("upyunError", "unknow file type2:"+file_type, nil) return } } return })) }
// http-json-api v1 // 1.数据传输使用psk加密,明文不泄漏信息 // 2.使用json序列化信息 // 3.只有部分api func (s *generateServer_ServiceRpc) ServeHTTP(w http.ResponseWriter, req *http.Request) { b1, err := kmgHttp.RequestReadAllBody(req) if err != nil { http.Error(w, "error 1", 400) kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) return } if s.psk != nil { //解密 b1, err = kmgCrypto.CompressAndEncryptBytesDecodeV2(s.psk, b1) if err != nil { http.Error(w, "error 2", 400) kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) return } } outBuf, err := s.handleApiV1(b1, w, req) if err != nil { kmgLog.Log("InfoServerError", err.Error(), kmgHttp.NewLogStruct(req)) outBuf = append([]byte{1}, err.Error()...) // error } else { outBuf = append([]byte{2}, outBuf...) // success } if s.psk != nil { //加密 outBuf = kmgCrypto.CompressAndEncryptBytesEncodeV2(s.psk, outBuf) } w.WriteHeader(200) w.Header().Set("Content-type", "image/jpeg") w.Write(outBuf) }
func httpLog(req httpLogRequest) { errStr := "" if req.Err != nil { errStr = req.Err.Error() } kmgLog.Log("apiAccess", errStr, req) if errStr != "" { kmgLog.Log("apiError", errStr, req) } }
//delete a file func (obj *BulkUpyun) deleteFile(upyun_path string, finish_wg *sync.WaitGroup) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { defer finish_wg.Done() kmgLog.Log("upyun", "delete file: "+upyun_path, nil) err := obj.UpYun.DeleteFile(upyun_path) if err != nil { kmgLog.Log("upyunError", "delete file failed!:"+upyun_path+":"+err.Error(), nil) return } return })) }
func (c *Client) EasyPush(config *JpushConfig) (err error) { if c.IsActive == false { kmgLog.Log("jpush", "Jpush Client is not active,please checkout your configure", c.name, c.IsIosProduct, c.IsActive, config) return } if config.Badge == "" { config.Badge = "1" } nb := jpush.NewNoticeBuilder() nb.SetPlatform(jpush.AllPlatform()) if config.Alias == "" || config.Tag == "" { nb.SetAudience(jpush.AllAudience()) } else { au := &jpush.Audience{} if config.Alias != "" { au.SetAlias([]string{config.Alias}) } if config.Tag != "" { au.SetTag([]string{config.Tag}) } nb.SetAudience(au) } //Android配置 notice := jpush.NewNoticeAndroid() notice.Alert = config.Content nb.SetNotice(notice) //iOS配置 iosNotice := jpush.NewNoticeIos() iosNotice.Sound = "default" iosNotice.Badge = "1" iosNotice.Alert = config.Content nb.SetNotice(iosNotice) op := jpush.NewOptions() op.SetApns_production(c.IsIosProduct) nb.SetOptions(op) ret, err := c.c.Send(nb) if err != nil { return err } if ret.Error.Code == 0 { kmgLog.Log("jpush", "Push success", c.name, config.Content) return nil } if ret.Error.Code == 1011 { kmgLog.Log("jpush", "Not Found User", c.name, config) return NotFoundUser } return fmt.Errorf("code:%d err: %s", ret.Error.Code, ret.Error.Message) }
func SendMessage(massage Massege) (err error) { massegeApiUrl := "https://api.submail.cn/message/xsend" resp, e := http.PostForm(massegeApiUrl, url.Values{ // "appid": {EmailConfig.Appid}, // "signature": {EmailConfig.Signature}, "appid": {"10111"}, "signature": {"142a3e0d66c4dda1e918487b1952b26c"}, "to": {massage.To}, "project": {massage.ProjectId}, }) if e != nil { return e } defer resp.Body.Close() body, e := ioutil.ReadAll(resp.Body) if e != nil { return e } kmgLog.Log("Submail", string(body), massage) data := kmgJson.MustUnmarshalToMapDeleteBOM(body) if data["status"] == "error" { return errors.New(kmgStrconv.InterfaceToString(data["msg"])) } return nil }
func LogError(err error) { s := "" if err != nil { s = err.Error() } kmgLog.Log("error", s) }
func XSendMessage(message Message) (err error) { subMessageUrl := "https://api.submail.cn/message/xsend.json" kmgDebug.Println(message.Vars) response, err := http.PostForm(subMessageUrl, url.Values{ "appid": {MessageConfig.Appid}, "signature": {MessageConfig.Signature}, "to": {message.To}, "project": {kmgStrconv.InterfaceToString(message.Project)}, "vars": {message.Vars}, }) defer response.Body.Close() if err != nil { return err } body, err := ioutil.ReadAll(response.Body) if err != nil { return err } kmgLog.Log("SubMessage", string(body), message) data := kmgJson.MustUnmarshalToMapDeleteBOM(body) if data["status"] == "error" { return errors.New(kmgStrconv.InterfaceToString(data["msg"])) } return nil }
func (handler *JsonHttpHandler) returnOutput(w http.ResponseWriter, output *JsonHttpOutput) { w.Header().Set("Content-Type", "text/json; charset=utf-8") err := json.NewEncoder(w).Encode(output) if err != nil { kmgLog.Log("apiError", "[JsonHttpHandler.returnOutput] json.NewEncoder(w).Encode(output)"+err.Error(), nil) } }
func (ot *OverseaTrade) mustNotifyActionV2(ctx *kmgHttp.Context, f func(info OverseaTradeTransaction)) { kmgLog.Log("Alipay", "Oversea PayNotifyAction", ctx.GetInMap()) var err error ctx.MustPost() info := OverseaTradeTransaction{} //info.NotifyId = ctx.MustInStr("notify_id") 这两项没有什么意义. //info.NotifyTime = kmgTime.MustFromMysqlFormatInLocation(ctx.MustInStr("notify_time"), kmgTime.BeijingZone) info.OutTradeNo = ctx.MustInStr("out_trade_no") info.Currency = ctx.MustInStr("currency") info.TotalFee, err = kmgStrconv.ParseFloat64(ctx.MustInStr("total_fee")) if err != nil { panic(err) } info.TradeStatus = OverseaTradeStatus(ctx.MustInStr("trade_status")) info.TradeNo = ctx.MustInStr("trade_no") err = ot.md5Verify(ctx.GetInMap()) if err != nil { panic(err) } err = ot.VerifyNotify(ctx.MustInStr("notify_id")) if err != nil { panic(err) } // 向支付宝询问这个订单的情况 oInfo := ot.MustSingleTransactionQuery(info.OutTradeNo) if oInfo.TradeStatus != info.TradeStatus { panic("两次查询订单状态不一致") } info.Subject = oInfo.Subject f(info) ctx.WriteString("success") }
func Ping(address string) Echo { p := fastping.NewPinger() p.MaxRTT = MaxRtt ra, err := net.ResolveIPAddr("ip4:icmp", address) handleErr(err) p.AddIPAddr(ra) echo := Echo{ Address: address, } p.OnRecv = func(addr *net.IPAddr, rtt time.Duration) { echo.Rtt = rtt echo.Status = EchoStatusSuccess } p.OnIdle = func() { if echo.Status == EchoStatusSuccess { return } echo.Status = EchoStatusFail echo.Rtt = time.Duration(1e9) } err = p.Run() handleErr(err) if echo.Rtt == 0 && echo.Status == EchoStatusSuccess { kmgLog.Log("error", "[kmgPing.Ping] echo.Rtt==0 && echo.Status==EchoStatusSuccess", address) } return echo }
//批量上传接口 //upload a file func (obj *BulkUpyun) UploadFile(upyun_path, local_path string) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { kmgLog.Log("upyun", "upload file: "+upyun_path, nil) file, err := os.Open(local_path) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } defer file.Close() err = obj.UpYun.WriteFile(upyun_path, file, true) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } return })) }
// 默认不用这个,容易搞的测试里面到处都是log. // TODO 静态文件的log问题 // TODO 尝试搞出更好用的log系统. func RequestLogger(ctx *kmgHttp.Context, processorList []HttpProcessor) { startTime := time.Now() processorList[0](ctx, processorList[1:]) time := time.Since(startTime) log := ctx.Log() log.ProcessTime = kmgTime.DurationFormat(time) kmgLog.Log("Request", log) }
//异步运行服务器,返回Closer以便可以关闭服务器,所有无法运行的错误panic出来,其他错误丢到kmgLog error里面. func RunServerWithPacketHandler(address string, secret []byte, handler PacketHandler) func() error { connChan := make(chan *net.UDPConn) go func() { var conn *net.UDPConn addr, err := net.ResolveUDPAddr("udp", address) if err != nil { panic(err) } conn, err = net.ListenUDP("udp", addr) if err != nil { panic(err) } connChan <- conn for { b := make([]byte, 4096) n, senderAddress, err := conn.ReadFrom(b) if err != nil { panic(err) } go func(p []byte, senderAddress net.Addr) { pac, err := DecodeRequestPacket(secret, p) if err != nil { kmgLog.Log("error", "radius.Decode", err.Error()) return } npac := handler(pac) if npac == nil { // 特殊情况,返回nil,表示抛弃这个包. return } err = npac.Send(conn, senderAddress) if err != nil { kmgLog.Log("error", "radius.Send", err.Error()) return } }(b[:n], senderAddress) } return }() conn := <-connChan close(connChan) return conn.Close }
func MustXsendMessage(massage Massege) { err := SendMessage(massage) if err != nil { defer func() { err := recover() kmgLog.Log("error", err) }() panic(err) } }
func LogUserErrorWithStack(err error) { if err == nil { return } s := "" if err != nil { s = err.Error() } kmgLog.Log("userError", s, kmgDebug.GetCurrentStack(1)) }
func MustSendMail(email Mail) { err := SendMailForHtml(email) if err != nil { defer func() { err := recover() kmgLog.Log("error", err) }() panic(err) } }
func SmtpSendEmail(req *SmtpRequest) (err error) { parameters := &struct { From string To string Subject string Message string }{ req.From, strings.Join([]string(req.To), ","), req.Subject, req.Message, } buffer := new(bytes.Buffer) t := template.Must(template.New("emailTemplate").Parse(_EmailScript())) t.Execute(buffer, parameters) auth := smtp.PlainAuth("", req.From, req.SmtpPassword, req.SmtpHost) var conn net.Conn if req.Socks4aProxyAddr != "" { conn, err = kmgProxy.Socks4aDial(req.Socks4aProxyAddr, kmgNet.JoinHostPortInt(req.SmtpHost, req.SmtpPort)) } else { conn, err = net.Dial("tcp", kmgNet.JoinHostPortInt(req.SmtpHost, req.SmtpPort)) } if err != nil { kmgLog.Log("Email", "1", err.Error()) return } c, err := smtp.NewClient(conn, req.SmtpHost) if err != nil { kmgLog.Log("Email", err.Error()) return } err = smtpSendMailPart2(c, req.SmtpHost, auth, req.From, req.To, buffer.Bytes()) return err }
//download a file func (obj *BulkUpyun) DownloadFile(upyun_path, local_path string) { obj.Tm.AddTask(kmgTask.TaskFunc(func() { kmgLog.Log("upyun", "download file: "+upyun_path, nil) err := os.MkdirAll(filepath.Dir(local_path), os.FileMode(0777)) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } file, err := os.Create(local_path) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } defer file.Close() err = obj.UpYun.ReadFile(upyun_path, file) if err != nil { kmgLog.Log("upyunError", err.Error(), err) return } return })) }
func (p *server) asyncAccountingRequest(request *Packet) { acctReq := AcctRequest{ SessionId: request.GetAcctSessionId(), Username: request.GetUsername(), SessionTime: request.GetAcctSessionTime(), InputBytes: request.GetAcctTotalInputOctets(), OutputBytes: request.GetAcctTotalOutputOctets(), NasPort: request.GetNASPort(), } switch request.GetAcctStatusType() { case AcctStatusTypeEnumStart: kmgLog.Log("Radius", "Acct Start", request.ToStringMap()) p.handler.AcctStart(acctReq) case AcctStatusTypeEnumInterimUpdate: p.handler.AcctUpdate(acctReq) case AcctStatusTypeEnumStop: kmgLog.Log("Radius", "Acct Stop", request.ToStringMap()) p.handler.AcctStop(acctReq) default: LogError(fmt.Errorf("radius.AccountingRequest AcctStatusType unknow %d", request.GetAcctStatusType())) } }
func MailBreack(email Mail, u url.Values, submailUrl string) (err error) { resp, e := http.PostForm(submailUrl, u) if e != nil { return e } defer resp.Body.Close() body, e := ioutil.ReadAll(resp.Body) if e != nil { return e } kmgLog.Log("Submail", string(body), email) data := kmgJson.MustUnmarshalToMapDeleteBOM(body) if data["status"] == "error" { return errors.New(kmgStrconv.InterfaceToString(data["msg"])) } return nil }
//用户发起支付,请传入Request,然后redirect到这个函数返回的url里面去. func (ot *OverseaTrade) Pay(req *OverseaTradePayRequest) (url string) { query := map[string]string{ "_input_charset": "utf-8", "service": "create_forex_trade", "partner": ot.PartnerId, "notify_url": ot.SelfSchemeAndHost + "/?n=github.com.bronze1man.kmg.third.kmgAlipay.OverseaTrade.NotifyAction", "return_url": ot.SelfSchemeAndHost + "/?n=github.com.bronze1man.kmg.third.kmgAlipay.OverseaTrade.ReturnPage", "subject": req.Subject, "body": req.Body, "out_trade_no": req.OutTradeNo, "currency": req.Currency, "supplier": req.Supplier, "timeout_rule": req.TimeoutRule, "specified_pay_channel": req.SpecifiedPayChannel, "seller_id": req.SellerId, "seller_name": req.SellerName, "seller_industry": req.SellerIndustry, } if req.NotifyUrl != "" { query["notify_url"] = req.NotifyUrl } if req.ReturnUrl != "" { query["return_url"] = req.ReturnUrl } if req.TotalFee != 0 { if req.Currency == "JPY" { //日元精度是整数,传入小数点会报错,这个文档上没有写,但是经过实验发现是这个样子的. query["total_fee"] = kmgStrconv.FormatFloatPrec0(req.TotalFee) } else { query["total_fee"] = kmgStrconv.FormatFloatPrec2(req.TotalFee) } } if req.RmbFee != 0 { query["rmb_fee"] = kmgStrconv.FormatFloatPrec2(req.RmbFee) } ot.md5Sign(query) kmgLog.Log("Alipay", "Oversea Pay", query) //已经手动验证url里面的参数顺序无关紧要. return kmgHttp.MustSetParameterMapToUrl("https://mapi.alipay.com/gateway.do", query) }
// 同步回调 // 调用前请清除您自己的参数. // @deprecated 请使用 OverseaTrade.PayFinishCallback 和 OverseaTrade.PayCloseCallback func (ot *OverseaTrade) MustReturnPage(ctx *kmgHttp.Context) (info OverseaTradeTransaction) { kmgLog.Log("Alipay", "Oversea PayReturnPage", ctx.GetInMap()) var err error info.OutTradeNo = ctx.MustInStr("out_trade_no") info.Currency = ctx.MustInStr("currency") info.TotalFee, err = kmgStrconv.ParseFloat64(ctx.MustInStr("total_fee")) if err != nil { panic(err) } info.TradeStatus = OverseaTradeStatus(ctx.MustInStr("trade_status")) info.TradeNo = ctx.MustInStr("trade_no") //这个也可以验证数据,只是文档上面没写. err = ot.md5Verify(ctx.GetInMap()) if err != nil { panic(err) } // 向支付宝询问这个订单的情况 oInfo := ot.MustSingleTransactionQuery(info.OutTradeNo) if oInfo.TradeStatus != info.TradeStatus { panic("两次查询订单状态不一致") } info.Subject = oInfo.Subject return info }
// 目前支持pap和mschapv2认证方式 func (p *server) radiusAccess(request *Packet) *Packet { kmgLog.Log("Radius", "Access Request", request.ToStringMap()) npac := request.Reply() username := request.GetUsername() password := request.GetPassword() if username == "" { //不支持的认证方式,或者包格式错误 npac.AVPs = append(npac.AVPs, &StringAVP{Type: AVPTypeReplyMessage, Value: "need username"}) npac.Code = CodeAccessReject LogError(fmt.Errorf("[kmgRadius.radiusAccess] need username or auth method not support")) return npac } AuthPassword, exist := p.handler.Auth(username) if !exist { LogError(fmt.Errorf("[kmgRadius.radiusAccess] username [%s] not exist or do not have any transfer", username)) npac.Code = CodeAccessReject return npac } //简单认证方式 pap if password != "" { if AuthPassword != password { LogError(fmt.Errorf("[kmgRadius.radiusAccess] username [%s] password not match", username)) npac.Code = CodeAccessReject return npac } npac.Code = CodeAccessAccept return npac } //复杂认证方式 //如果没有输入密码,要求用户输入密码(遗留代码,应该是之前的bug导致的) e := request.GetEAPMessage() if e != nil { //第一次请求,eapCode应该是 Response // mschapv2 step 1 switch e.Header().Type { case eap.TypeIdentity, eap.TypeLegacyNak: npac.Code = CodeAccessChallenge mschapV2Challenge := [16]byte{} _, err := rand.Read(mschapV2Challenge[:]) if err != nil { panic(err) } sessionId := kmgRand.MustCryptoRandToAlphaNum(18) npac.SetState([]byte(sessionId)) p.mschapMap[sessionId] = mschapStatus{ Challenge: mschapV2Challenge, } npac.AddAVP(&EapAVP{ Value: &eap.MSCHAPV2Packet{ PacketHeader: eap.PacketHeader{ Code: eap.CodeRequest, Identifier: e.Header().Identifier, Type: eap.TypeMSCHAPV2, }, MSCHAPV2: &MSCHAPV2.ChallengePacket{ Identifier: e.Header().Identifier, Challenge: mschapV2Challenge, Name: username, }, }, }) return npac //TODO process next step read Response packet and write Success Request packet // reference http://tools.ietf.org/id/draft-kamath-pppext-eap-mschapv2-01.txt case eap.TypeMSCHAPV2: // mschapv2 step 3 and step 5 if e.Header().Code != eap.CodeResponse { npac.Code = CodeAccessReject LogError(fmt.Errorf("MSCHAPV2 step 3 fail! 1 eap.Code[%s]!=radius.EapCodeResponse", e.Header().Code)) return npac } mschapv2I := e.(*eap.MSCHAPV2Packet).MSCHAPV2 switch mschapv2I.OpCode() { case MSCHAPV2.OpCodeResponse: state := request.GetState() //step 3 status, ok := p.mschapMap[string(state)] if !ok { npac.Code = CodeAccessReject LogError(fmt.Errorf("MSCHAPV2 step 3 fail! 3 mschapStatus not found state:%s", state)) return npac } status.NTResponse = mschapv2I.(*MSCHAPV2.ResponsePacket).NTResponse p.mschapMap[string(state)] = status successPacket := MSCHAPV2.ReplySuccessPacket(&MSCHAPV2.ReplySuccessPacketRequest{ AuthenticatorChallenge: status.Challenge, Response: mschapv2I.(*MSCHAPV2.ResponsePacket), Username: []byte(username), Password: []byte(AuthPassword), Message: "success", }) npac.AddAVP(&EapAVP{ Value: &eap.MSCHAPV2Packet{ PacketHeader: eap.PacketHeader{ Code: eap.CodeRequest, Identifier: e.Header().Identifier, Type: eap.TypeMSCHAPV2, }, MSCHAPV2: successPacket, }, }) npac.Code = CodeAccessChallenge return npac case MSCHAPV2.OpCodeSuccess: //step 5 // reference http://www.ietf.org/rfc/rfc3079.txt state := request.GetState() //step 3 status, ok := p.mschapMap[string(state)] if !ok { npac.Code = CodeAccessReject LogError(fmt.Errorf("MSCHAPV2 step 5 fail! 5 mschapStatus not found state:%#v", state)) return npac } npac.AddAVP(&EapAVP{ Value: &eap.SimplePacket{ PacketHeader: eap.PacketHeader{ Code: eap.CodeSuccess, Identifier: e.Header().Identifier, }, }, }) npac.AddAVP(&StringAVP{ Type: AVPTypeUserName, Value: username, }) //MS-MPPE-Encryption-Policy: Encryption-Allowed (1) npac.AddAVP(&BinaryAVP{ Type: AVPTypeVendorSpecific, Value: []byte{0x00, 0x00, 0x01, 0x37, 0x07, 0x06, 0, 0, 0, 1}, }) //MS-MPPE-Encryption-Types: RC4-40-128 (6) npac.AddAVP(&BinaryAVP{ Type: AVPTypeVendorSpecific, Value: []byte{0x00, 0x00, 0x01, 0x37, 0x08, 0x06, 0, 0, 0, 6}, }) sendkey, recvKey := MSCHAPV2.MsCHAPV2GetSendAndRecvKey([]byte(AuthPassword), status.NTResponse) npac.AddAVP(&VendorSpecificAVP{ Value: NewMSMPPESendOrRecvKeyVSA(request, VendorTypeMSMPPESendKey, sendkey), }) npac.AddAVP(&VendorSpecificAVP{ Value: NewMSMPPESendOrRecvKeyVSA(request, VendorTypeMSMPPERecvKey, recvKey), }) npac.Code = CodeAccessAccept npac.DeleteOneType(AVPTypeState) return npac default: npac.Code = CodeAccessReject LogError(fmt.Errorf("MSCHAPV2 step 3 and 5 fail! 2.5 mschapv2I.OpCode()[%s]!= MSCHAPV2.OpCodeResponse", mschapv2I.OpCode())) return npac } default: npac.Code = CodeAccessReject LogError(fmt.Errorf("MSCHAPV2 eap fail! 4")) return npac } } //不支持的认证方式,或者包格式错误 npac.AVPs = append(npac.AVPs, &StringAVP{Type: AVPTypeReplyMessage, Value: "need password"}) npac.Code = CodeAccessReject LogError(fmt.Errorf("[kmgRadius.radiusAccess] username[%s] need password or auth method not support", username)) return npac }