From 94f6a428a95d28cdc775ac7566e4ba5dc1f87947 Mon Sep 17 00:00:00 2001 From: zhangjianjun_code <7844966+zhangjianjun_code@user.noreply.gitee.com> Date: Mon, 25 Jan 2021 14:58:39 +0800 Subject: [PATCH] For the low credibility of cve data, send an email to the security committee, first manually review, and then process --- common/common.go | 1 + conf/app.conf | 10 +- conf/product_app.conf | 8 +- controllers/file.go | 2 +- controllers/upload.go | 1 + models/cve.go | 10 +- models/issue.go | 23 +++++ models/modeldb.go | 15 ++- task/cve.go | 12 ++- task/inittask.go | 16 ++++ task/issuestatistics.go | 20 ++++ taskhandler/cve.go | 6 +- taskhandler/issuestatistics.go | 163 +++++++++++++++++++++++++++++---- taskhandler/sendemail.go | 24 ++++- 14 files changed, 271 insertions(+), 40 deletions(-) diff --git a/common/common.go b/common/common.go index 18d52cb..d0d446d 100644 --- a/common/common.go +++ b/common/common.go @@ -311,6 +311,7 @@ type CveOriginData struct { VulType CveVulType `json:"vulType"` FixSuggest CveFixSuggest `json:"fixSuggest"` Version string `json:"version"` + Credibility int `json:"credibility"` } type UploadData struct { diff --git a/conf/app.conf b/conf/app.conf index a19a796..e5c9ff7 100644 --- a/conf/app.conf +++ b/conf/app.conf @@ -73,7 +73,9 @@ exceptcve = 0 3 19 * * * gensaflag = 2 gensa = 0 3 19 * * * issuestatisticflag = 2 -issuestatistic = 0 19 10 * * * +issuestatistic = 0 43 14 * * * +cvecredflag = 2 +cvecredit = 0 53 14 * * * [gitee] #owner = cve-test @@ -82,8 +84,8 @@ issuestatistic = 0 19 10 * * * #email = 1499273991@qq.com #redirect_uri = http://119.8.126.102:80/v1/issue/oauth/callback # -------jianjun gitee 配置 -------- -owner = src-openeuler -#owner = cve-test +#owner = src-openeuler +owner = cve-test path = jasper email = 7844966+zhangjianjun_code@user.noreply.gitee.com redirect_uri = http://159.138.2.2:80/v1/issue/oauth/callback @@ -129,6 +131,8 @@ abn_cve_status =3 sa_re_amount = 4000 # The number of days the issue counts the mailing list cve_statistics_date = 20 +# Trusted data query(0-3) +credibility_level = 3 [reflink] diff --git a/conf/product_app.conf b/conf/product_app.conf index 0e38f38..85e09b2 100644 --- a/conf/product_app.conf +++ b/conf/product_app.conf @@ -74,8 +74,9 @@ exceptcve = 0 0 4 * * * gensaflag = 1 gensa = 0 1 0 * * * issuestatisticflag = 1 -issuestatistic = 0 0 9 * * 1,3 - +issuestatistic = 0 30 8 * * 1,3 +cvecredflag = 1 +cvecredit = 0 0 5 * * * [gitee] owner = src-openeuler @@ -126,6 +127,9 @@ abn_cve_status =3 sa_re_amount = 4000 # The number of days the issue counts the mailing list cve_statistics_date = 20 +# Trusted data query(0-3) +credibility_level = 3 + [reflink] comment_cmd = https://gitee.com/openeuler/cve-manager/blob/master/doc/md/manual.md diff --git a/controllers/file.go b/controllers/file.go index bad7ec7..78a9cf5 100644 --- a/controllers/file.go +++ b/controllers/file.go @@ -319,7 +319,7 @@ func uploadCvrfFile(cvrfFileList map[string][]string, totalFileSlice []string, d logs.Error("File compression failed: err: ", zipErr) } // send email - sendError := taskhandler.SendEmail(zipFileName, 1, "") + sendError := taskhandler.SendEmail(zipFileName, 1, "", "") if sendError != nil { logs.Error("SendEmail, sendErr: ", sendError) return diff --git a/controllers/upload.go b/controllers/upload.go index d82c195..dd97b93 100644 --- a/controllers/upload.go +++ b/controllers/upload.go @@ -227,6 +227,7 @@ func (u *UserUploadController) Post() { orCve.Version = version orCve.UpdateType = updateType orCve.CvePackName = cvePackName + orCve.Credibility = CveDataDict.Credibility if packName != "" { packName = common.DeletePreAndSufSpace(packName) } diff --git a/models/cve.go b/models/cve.go index 46bc17b..dc68f38 100644 --- a/models/cve.go +++ b/models/cve.go @@ -84,13 +84,15 @@ func QueryOriginCveIssue(prcnum int) ([]GiteOriginIssue, int64, error) { return gs, num, err } -func QueryOriginCve(days string, prcnum int) ([]OriginUpstream, int64, error) { +func QueryOriginCve(days string, prcnum, credibilityLevel int) ([]OriginUpstream, int64, error) { o := orm.NewOrm() var gs []OriginUpstream num, err := o.Raw("select cve_id,cve_un_ids,cve_num, update_type,cve_packname,"+ - "git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date,vul_status,cve_status,version"+ - " from cve_origin_upstream where update_time >= ? and cve_status in (?, ?) and is_exit = ? "+ - "order by cve_id asc limit ?", days, 0, 1, 1, prcnum).QueryRows(&gs) + "git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date," + + "vul_status,cve_status,version,credibility_level"+ + " from cve_origin_upstream where update_time >= ? and cve_status in (?, ?) " + + "and is_exit = ? and credibility_level <= ? "+ + "order by cve_id asc limit ?", days, 0, 1, 1, credibilityLevel, prcnum).QueryRows(&gs) if err == nil && num > 0 { logs.Info("cve_origin_upstream 查询结果: ", num) } else { diff --git a/models/issue.go b/models/issue.go index 94e25d3..bad9bfa 100644 --- a/models/issue.go +++ b/models/issue.go @@ -422,6 +422,12 @@ func GetIssueSpecErrByColName(se *SpecError, colName ...string) error { return err } +func GetOrgCveDesc(ord *OriginUpstreamDesc, colName ...string) error { + o := orm.NewOrm() + err := o.Read(ord, colName...) + return err +} + func LockUpdateIssueStatus(cveId int64, cveNum string, status int8) (bool) { o := orm.NewOrm() res, err := o.Raw("UPDATE cve_vuln_center SET cve_status = ? WHERE cve_id = ? and cve_num = ? and cve_status in (0,1)", @@ -543,3 +549,20 @@ func QueryIssueStatisticEmail() ([]IssueStatisticsMailList, error) { logs.Info("cve_issue_statistics_mail_list: ", num, err) return ism, err } + +func QueryLowCredibilityCve(days string, prcnum, credibilityLevel int, cveId int64) ([]OriginUpstream, int64, error) { + o := orm.NewOrm() + var gs []OriginUpstream + num, err := o.Raw("select cve_id,cve_un_ids,cve_num, update_type,cve_packname,"+ + "git_packname,cve_title,affect_porduct,cnnvd_id,cnvd_id,published_date," + + "vul_status,cve_status,version,credibility_level"+ + " from cve_origin_upstream where update_time >= ? and cve_status in (?, ?) " + + " and credibility_level > ? and cve_id > ? "+ + "order by cve_id asc limit ?", days, 0, 1, credibilityLevel, cveId, prcnum).QueryRows(&gs) + if err == nil && num > 0 { + logs.Info("cve_origin_upstream 查询结果: ", num) + } else { + logs.Info("当前无新增或者更新的cve, cur_time:", common.GetCurTime(), "err: ", err) + } + return gs, num, err +} \ No newline at end of file diff --git a/models/modeldb.go b/models/modeldb.go index 5ab2c75..9f120d0 100644 --- a/models/modeldb.go +++ b/models/modeldb.go @@ -296,14 +296,21 @@ type OriginUpstream struct { CnvdID string `orm:"size(256);column(cnvd_id);null" description:"Cnvd_id"` PublishedDate string `orm:"size(32);column(published_date);null" description:"漏洞发布日期"` VulStatus string `orm:"size(64);column(vul_status);null" description:"漏洞状态,REJECT, DISPUTED"` - Status int8 `orm:"default(0);column(cve_status)" description:"0:cve新增;1:数据已变化;2:数据已处理;3:错误数据;4:版本信息错误;5:cve年份不符合要求"` + Status int8 `orm:"default(0);column(cve_status)" description:"0:cve新增;1:数据已变化;2:数据已处理;3:错误数据;4:版本信息错误;5:cve年份不符合要求;6:低可信度数据已发邮件"` AffectedScope string `orm:"size(512);column(affected_scope);null" description:"影响范围推理"` Version string `orm:"size(64);column(version);index" description:"包对应的版本号"` AttackLink string `orm:"size(512);column(attack_link);null" description:"攻击链路推理"` IsExit int8 `orm:"default(1);column(is_exit)" description:"1: 当前包对应在src-openEuler有对应仓库; 0: 无;2:临时值"` - CreateTime string `orm:"size(32);column(create_time)"` - UpdateTime string `orm:"size(32);column(update_time);null"` - DeleteTime string `orm:"size(32);column(delete_time);null"` + Credibility int `orm:"default(0);column(credibility_level)" description:"0:包名、版本号都是漏洞库原始数据; + 1:包名通过别名匹配、版本号为漏洞库原始数据; + 2:包名版本号都通过漏洞描述获取; + 3:包名通过漏洞描述获取并通过别名匹配、版本号为漏洞描述获取; + 4:包名版本号通过SA获取、版本号为修复版本号、修复版本以下都视为受影响版本; + 5:包名版本号通过SA获取并通过别名匹配、版本号为修复版本号、修复版本以下都视为受影响版本; + 6:版本号未匹配、包名通过以上任意方式匹配、可信度最低"` + CreateTime string `orm:"size(32);column(create_time)"` + UpdateTime string `orm:"size(32);column(update_time);null"` + DeleteTime string `orm:"size(32);column(delete_time);null"` } type OriginUpstreamDesc struct { diff --git a/task/cve.go b/task/cve.go index b5046cc..011eb44 100644 --- a/task/cve.go +++ b/task/cve.go @@ -9,9 +9,9 @@ import ( ) //ProcCveOriginData Process raw data obtained by api -func ProcCveOriginData(prcNum, days, openeulerNum int, cveRef, owner string) (bool, error) { +func ProcCveOriginData(prcNum, days, credibilityLevel, openeulerNum int, cveRef, owner string) (bool, error) { // Process raw data obtained by api - ok, err := taskhandler.GetCveOriginData(prcNum, days, openeulerNum, cveRef) + ok, err := taskhandler.GetCveOriginData(prcNum, days, openeulerNum, credibilityLevel, cveRef) if !ok { logs.Error("接口上的原始数据处理失败(GetCveOriginData), err: ", err) } @@ -58,8 +58,14 @@ func ParamsCveOriginData() error { return ok } owner := BConfig.String("gitee::owner") + // cve credibility level + credibilityLevel, ok := BConfig.Int("cve::credibility_level") + if ok != nil { + logs.Error("config cve::credibility_level error:", err) + return ok + } // Get the data source of the table - _, errx := ProcCveOriginData(prcnum, days, openeulernum, cveRef, owner) + _, errx := ProcCveOriginData(prcnum, days, credibilityLevel, openeulernum, cveRef, owner) logs.Info("将cve原始数据生成cve库 task end") return errx } diff --git a/task/inittask.go b/task/inittask.go index 771906e..9a49d68 100644 --- a/task/inittask.go +++ b/task/inittask.go @@ -102,6 +102,14 @@ func IssueStstisticsTask(issueStatistic string) { logs.Info("issue统计 task end") } +// Cve data email task with low credibility +func cveLowCredTask(cvecredit string) { + logs.Info("cve 可信度 task start") + iStTask := toolbox.NewTask("ProcCveLowCred", cvecredit, ProcCveLowCred) + toolbox.AddTask("ProcCveLowCred", iStTask) + logs.Info("cve 可信度 task end") +} + // Print logs to the console and delete redundant logs func PrintLogTask(printLog string) { logs.Info("创建日志任务 task start") @@ -222,5 +230,13 @@ func InitTask() bool { } else { logs.Info("issue statistics task") } + // Cve data email task with low credibility + cvecredflag, errx := BConfig.Int("crontab::cvecredflag") + if cvecredflag == 1 && errx == nil { + cvecredit := BConfig.String("crontab::cvecredit") + cveLowCredTask(cvecredit) + } else { + logs.Info("cve credibility task") + } return true } diff --git a/task/issuestatistics.go b/task/issuestatistics.go index 8cc0467..6a3da43 100644 --- a/task/issuestatistics.go +++ b/task/issuestatistics.go @@ -27,3 +27,23 @@ func IssueStatistics() error { logs.Info("issue statistics task end") return err } + +// Cve data email task with low credibility +func ProcCveLowCred() error { + defer common.Catchs() + logs.Info("cve credibility task start") + // The number of days the issue counts the mailing list + beforeDate, beErr := beego.AppConfig.Int("cve::cve_statistics_date") + if beErr != nil { + beforeDate = 30 + } + prnum, prErr := beego.AppConfig.Int("crontab::prcnum") + if prErr != nil { + prnum = 100 + } + // Get the data source of the table + err := taskhandler.CveCredibilityStatistics(beforeDate, prnum) + logs.Info(err) + logs.Info("cve credibility task end") + return err +} diff --git a/taskhandler/cve.go b/taskhandler/cve.go index af25d61..18c8549 100644 --- a/taskhandler/cve.go +++ b/taskhandler/cve.go @@ -959,12 +959,12 @@ func SyncCveVuler(cveData models.OriginExcel, cveRef string, openeulerNum, manYe return true, nil } -func GetCveOriginData(prcnum, days, openeulernum int, cveRef string) (bool, error) { +func GetCveOriginData(prcnum, days, openeulernum, credibilityLevel int, cveRef string) (bool, error) { defer common.Catchs() count := 0 beforeTime := common.GetBeforeTime(days) for { - osx, num, err := models.QueryOriginCve(beforeTime, prcnum) + osx, num, err := models.QueryOriginCve(beforeTime, prcnum, credibilityLevel) if err != nil || num == 0 { logs.Info("当前无cve原始数据处理, err: ", err, ", 处理时间范围: beforetime: ", beforeTime, @@ -2013,7 +2013,7 @@ func GenerateExcelTrigger(wgx *sync.WaitGroup, fileName, startTime, fileCode, af logs.Error("File compression failed: err: ", zipErr) } // send email - sendError := SendEmail(zipFileName, 0, "") + sendError := SendEmail(zipFileName, 0, "", "") if sendError != nil { logs.Error("SendEmail, sendErr: ", sendError) return diff --git a/taskhandler/issuestatistics.go b/taskhandler/issuestatistics.go index 5577f1f..27c8528 100644 --- a/taskhandler/issuestatistics.go +++ b/taskhandler/issuestatistics.go @@ -3,11 +3,11 @@ package taskhandler import ( "cvevulner/common" "cvevulner/models" + "errors" "fmt" "github.com/360EntSecGroup-Skylar/excelize/v2" "github.com/astaxie/beego" "github.com/astaxie/beego/logs" - "os" "path/filepath" "strconv" ) @@ -31,11 +31,6 @@ func createExcel() (string, string) { dir := beego.AppConfig.String("fileDir") excelName := "CVE_ISSUE_" + common.GetCurDate() + ".xlsx" excelPath := filepath.Join(dir, excelName) - //Determine whether the file exists - ok, _ := PathExists(excelPath) - if ok { - os.Remove(excelPath) - } xlsx := excelize.NewFile() index := xlsx.NewSheet(sheetName) sheetTileMap := make(map[string]string) @@ -55,15 +50,51 @@ func createExcel() (string, string) { err := xlsx.SaveAs(excelPath) if err != nil { logs.Error(err) + return "", "" + } + return excelPath, dir +} + +func CveCredExcel() (string, string) { + // File storage directory + dir := beego.AppConfig.String("fileDir") + excelName := "CVE_Low_Credibility_" + common.GetCurDate() + ".xlsx" + excelPath := filepath.Join(dir, excelName) + xlsx := excelize.NewFile() + index := xlsx.NewSheet(sheetName) + sheetTileMap := make(map[string]string) + sheetTileMap["A1"] = "CVE编号" + sheetTileMap["B1"] = "CVE影响的组件和版本" + sheetTileMap["C1"] = "CVE描述" + sheetTileMap["D1"] = "CVE可信等级(4:包名版本号通过SA获取、版本号为修复版本号、修复版本以下都视为受影响版本;5:包名版本号通过SA获取并通过别名匹配、版本号为修复版本号、修复版本以下都视为受影响版本;6:版本号未匹配、包名通过以上任意方式匹配、可信度最低)" + sheetTileMap["E1"] = "CVE发布时间" + for k, v := range sheetTileMap { + xlsx.SetCellValue(sheetName, k, v) + } + xlsx.SetActiveSheet(index) + err := xlsx.SaveAs(excelPath) + if err != nil { + logs.Error(err) + return "", "" } return excelPath, dir } -func ReadWriteExcel(excelPath, owner string, iss []models.IssueTemplate, is *IssueStr) int64 { +func procCredData(org models.OriginUpstream, desc models.OriginUpstreamDesc) []interface{} { + cveData := make([]interface{}, 0) + cveData = append(cveData, org.CveNum) + cveData = append(cveData, org.PackName) + cveData = append(cveData, desc.EnDescription) + cveData = append(cveData, org.Credibility) + cveData = append(cveData, org.PublishedDate) + return cveData +} + +func ReadWriteExcel(excelPath, owner string, iss []models.IssueTemplate, is *IssueStr) (int64, error) { file, openErr := excelize.OpenFile(excelPath) if openErr != nil { logs.Error("fail to open the file, ", excelPath) - return 0 + return iss[len(iss)-1].TemplateId, openErr } var templateId = int64(0) for _, its := range iss { @@ -86,7 +117,7 @@ func ReadWriteExcel(excelPath, owner string, iss []models.IssueTemplate, is *Iss if fileErr != nil { logs.Error("Failed to save file, ", fileErr) } - return templateId + return templateId, fileErr } func procIssueData(its models.IssueTemplate, is *IssueStr, owner string) []interface{} { @@ -111,6 +142,48 @@ func procIssueData(its models.IssueTemplate, is *IssueStr, owner string) []inter return cveData } +func QueryCveDesc(cveId int64) models.OriginUpstreamDesc { + var desc models.OriginUpstreamDesc + desc.CveId = cveId + ordErr := models.GetOrgCveDesc(&desc, "CveId") + if ordErr != nil { + logs.Error("Failed to query data, GetOrgCveDesc, err: ", ordErr) + } + return desc +} + +func ReadWriteCredExcel(excelPath string, org []models.OriginUpstream) (int64, error) { + file, openErr := excelize.OpenFile(excelPath) + if openErr != nil { + logs.Error("fail to open the file, ", excelPath) + return org[len(org)-1].CveId, openErr + } + tempCveId := int64(0) + for _, cred := range org { + tempCveId = cred.CveId + desc := QueryCveDesc(cred.CveId) + cveData := procCredData(cred, desc) + if len(cveData) > 0 { + rows, sheetErr := file.GetRows(sheetName) + if sheetErr != nil { + logs.Error(sheetErr) + } + idx := len(rows) + 1 + axis := fmt.Sprintf("A%d", idx) + setErr := file.SetSheetRow(sheetName, axis, &cveData) + if setErr != nil { + logs.Error("setErr: ", setErr) + } + } + models.UpdateOriginStatus(common.GetCurTime(), cred.PackName, cred.Version, cred.CveId, 6) + } + fileErr := file.SaveAs(excelPath) + if fileErr != nil { + logs.Error("Failed to save file, ", fileErr) + } + return tempCveId, fileErr +} + func pressFileZip(excelPath, dir string) string { totalFileSlice := make([]string, 0) totalFileSlice = append(totalFileSlice, excelPath) @@ -125,29 +198,83 @@ func pressFileZip(excelPath, dir string) string { func IssueStatistics(beforeDate, prcnum int, owner string) error { excelPath, _ := createExcel() + if excelPath == "" { + logs.Error("Failed to create file") + return errors.New("Failed to create file") + } fileSlice := make([]string, 0) templateId := int64(0) var is IssueStr for { it, err := GetIssueData(beforeDate, prcnum, templateId) if err != nil { - return err + logs.Error("GetIssueData, err: ", err) + break } logs.Info("it==>", it) if len(it) == 0 { break } - templateId = ReadWriteExcel(excelPath, owner, it, &is) + templateId, err = ReadWriteExcel(excelPath, owner, it, &is) + if err != nil { + templateId = 0 + break + } } //zipFileName := pressFileZip(excelPath, dir) zipFileName := excelPath - cBody := fmt.Sprintf("hi all: \r\n 当前未解决漏洞有" + strconv.FormatInt(is.cveCount, 10) + "个, 其中" + - strconv.FormatInt(is.HighCveCount, 10) + "个7分以上漏洞, 详情见附件, 请在20号之前解决, 优先解决7分以上CVE. \r\n" + - "已经分析完毕的issue请maintainer尽快关掉, 否则影响数据统计; 提交PR时要关联issue, 若CVE在之前PR解决, 请PR提交人编辑PR信息将issue关联上. \r\n") - sendError := SendEmail(zipFileName, 2, cBody) - if sendError != nil { - logs.Error("SendEmail, sendErr: ", sendError) - return sendError + if templateId > 0 { + cBody := fmt.Sprintf("hi all: \r\n 当前未解决漏洞有" + strconv.FormatInt(is.cveCount, 10) + "个, 其中" + + strconv.FormatInt(is.HighCveCount, 10) + "个7分以上漏洞, 详情见附件, 请在20号之前解决, 优先解决7分以上CVE. \r\n" + + "已经分析完毕的issue请maintainer尽快关掉, 否则影响数据统计; 提交PR时要关联issue, 若CVE在之前PR解决, 请PR提交人编辑PR信息将issue关联上. \r\n") + sendError := SendEmail(zipFileName, 2, cBody, "") + if sendError != nil { + logs.Error("SendEmail, sendErr: ", sendError) + } + } + fileSlice = append(fileSlice, excelPath) + fileSlice = append(fileSlice, zipFileName) + DelFile(fileSlice) + return nil +} + +func CveCredibilityStatistics(beforeDate, prcnum int) error { + credibilityLevel, ok := beego.AppConfig.Int("cve::credibility_level") + if ok != nil { + credibilityLevel = 3 + } + beforeTime := common.GetSpecialDate(beforeDate) + excelPath, _ := CveCredExcel() + if excelPath == "" { + logs.Error("Failed to create file") + return errors.New("Failed to create file") + } + tempCveId := int64(0) + fileSlice := make([]string, 0) + for { + org, num, err := models.QueryLowCredibilityCve(beforeTime, prcnum, credibilityLevel, tempCveId) + if len(org) > 0 { + tempCveId, err = ReadWriteCredExcel(excelPath, org) + if err != nil { + tempCveId = 0 + break + } + } else { + logs.Error("failed: ", num, ", err: ", err) + break + } + } + zipFileName := excelPath + if tempCveId > 0 { + //zipFileName := pressFileZip(excelPath, dir) + cBody := fmt.Sprintf("hi all: \r\n 当前中科院上传的可信度为4/5/6等级的数据, " + + "请见附件! 如果有需要提交issue的CVE, 请整理成人工提交CVE的excel格式, 工具进行处理. \r\n") + subject := "可信度较低的cve漏洞反馈" + sendError := SendEmail(zipFileName, 3, cBody, subject) + if sendError != nil { + logs.Error("SendEmail, sendErr: ", sendError) + return sendError + } } fileSlice = append(fileSlice, excelPath) fileSlice = append(fileSlice, zipFileName) diff --git a/taskhandler/sendemail.go b/taskhandler/sendemail.go index 78f7b1b..a6a29fd 100644 --- a/taskhandler/sendemail.go +++ b/taskhandler/sendemail.go @@ -87,7 +87,7 @@ func ZipFiles(filename string, files []string, oldform, newform string) error { return nil } -func SendEmail(attchStr string, flag int, cBody string) error { +func SendEmail(attchStr string, flag int, cBody, subject string) error { var mail Mail emailName := beego.AppConfig.String("email::email_name") emailPwd := beego.AppConfig.String("email::email_pwd") @@ -161,6 +161,26 @@ func SendEmail(attchStr string, flag int, cBody string) error { } else { emailError = queryErr } + } else if flag == 3 { + message := Message{from: emailName, + to: toEmailName, + cc: []string{}, + bcc: []string{}, + subject: subject, + body: cBody, + contentType: "text/plain;charset=utf-8", + attachment: Attachment{ + name: attchStr, + contentType: "text/plain", + withFile: true, + }, + } + emailError = mail.Send(message) + if emailError == nil { + logs.Info("Notify cve that the email was sent successfully!") + } else { + logs.Error("Notify cve mail delivery failure!") + } } else { message := Message{from: emailName, to: toEmailName, @@ -213,7 +233,7 @@ func (mail SendMail) Send(message Message) error { attachment += "Content-Transfer-Encoding:base64\r\n" attachment += "Content-Disposition:attachment\r\n" attachment += "Content-Type:" + message.attachment.contentType + ";name=\"" + - strings.Replace(message.attachment.name, "download", "", -1) + "\"\r\n" + strings.Replace(message.attachment.name, "download/", "", -1) + "\"\r\n" buffer.WriteString(attachment) defer func() { if err := recover(); err != nil { -- Gitee