Пример #1
0
//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
	}))
}
Пример #2
0
//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
	}))
}
Пример #3
0
// 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)
}
Пример #4
0
//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
	}))
}
Пример #5
0
// 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)
}
Пример #6
0
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)
	}
}
Пример #7
0
//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
	}))
}
Пример #8
0
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)
}
Пример #9
0
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
}
Пример #10
0
func LogError(err error) {
	s := ""
	if err != nil {
		s = err.Error()
	}
	kmgLog.Log("error", s)
}
Пример #11
0
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

}
Пример #12
0
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)
	}
}
Пример #13
0
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")
}
Пример #14
0
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
}
Пример #15
0
//批量上传接口
//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
	}))
}
Пример #16
0
// 默认不用这个,容易搞的测试里面到处都是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)
}
Пример #17
0
//异步运行服务器,返回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
}
Пример #18
0
func MustXsendMessage(massage Massege) {
	err := SendMessage(massage)
	if err != nil {
		defer func() {
			err := recover()
			kmgLog.Log("error", err)
		}()
		panic(err)
	}
}
Пример #19
0
func LogUserErrorWithStack(err error) {
	if err == nil {
		return
	}
	s := ""
	if err != nil {
		s = err.Error()
	}
	kmgLog.Log("userError", s, kmgDebug.GetCurrentStack(1))
}
Пример #20
0
func MustSendMail(email Mail) {
	err := SendMailForHtml(email)
	if err != nil {
		defer func() {
			err := recover()
			kmgLog.Log("error", err)
		}()
		panic(err)
	}
}
Пример #21
0
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
}
Пример #22
0
//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
	}))
}
Пример #23
0
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()))
	}
}
Пример #24
0
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
}
Пример #25
0
//用户发起支付,请传入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)
}
Пример #26
0
// 同步回调
// 调用前请清除您自己的参数.
// @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
}
Пример #27
0
// 目前支持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
}