diff --git a/src/genmai/BsUtils/BsUtils.go b/src/genmai/BsUtils/BsUtils.go index 6fe19d1..cbfbe0e 100644 --- a/src/genmai/BsUtils/BsUtils.go +++ b/src/genmai/BsUtils/BsUtils.go @@ -1,12 +1,16 @@ package BsUtils import( + "gopkg.in/yaml.v2" + "io/ioutil" "crypto/md5" "encoding/hex" "golang.org/x/crypto/ssh" // "strings" + "encoding/base64" "path/filepath" "strconv" "time" + "log" "fmt" ) // 连接的配置 @@ -18,6 +22,18 @@ type ClientConfig struct { Client *ssh.Client //ssh client LastResult string //最近一次运行的结果 } +// 系统配置 +type Config struct { + Name string `yaml:"name"` + Version string `yaml:"version"` + DateVersion string `yaml:"dateversion"` + Database struct { + Dbhostsip string `yaml:"dbhostsip"` + Username string `yaml:"username"` + Password string `yaml:"password"` + Dbname string `yaml:"dbname"` + } `yaml:"database"` +} // func BsCheckUserAuto(host string, port int,user string, passwd string)int{ // // 0 => 用户名、密码错误 @@ -40,15 +56,14 @@ func PasswordEncryption(password string)string { md5String := hex.EncodeToString(md5New.Sum(nil)) return md5String } -func BsCheckUserAuto(host string, port string,user string, passwd string)(int){ +func BsCheckUserAuto(host string, port string,user string, passwd string,command string)(int,string){ // 0 => 错误 // 1 => 正确 // 2 => 用户名、密码为空 - fmt.Println(">>",user,passwd) port_int,_:=strconv.Atoi(port) if passwd == "" || user == ""{ - return 2 + return 2,"" } sshHost := host @@ -89,7 +104,7 @@ func BsCheckUserAuto(host string, port string,user string, passwd string)(int){ if err != nil { fmt.Println("1",err) - return 0 + return 0,"" } defer sshClient.Close() @@ -100,21 +115,25 @@ func BsCheckUserAuto(host string, port string,user string, passwd string)(int){ if err != nil { fmt.Println("2",err) - return 0 + return 0,"" } defer session.Close() //执行远程命令 - _,err = session.Output("whoami") - if err != nil { - fmt.Println("3",err) - return 0 + var result string + if command != ""{ + combo,err := session.CombinedOutput(command) + if err != nil { + fmt.Println("3",err) + return 0,"" + } + defer session.Close() + result=string(combo) } - defer session.Close() - // result:=string(combo) - return 1 + + return 1,result // if strings.Contains(result,user){ // fmt.Println("4",err) // return 0 @@ -135,4 +154,29 @@ func isValidFilePath(filePath string) bool { return false } return true +} + +func ConfigYamlParse()(string,string,string,string,string,string){ + data, err := ioutil.ReadFile("config.yaml") + if err != nil { + log.Println(err) + } + + // 解析 YAML 数据 + var config Config + err = yaml.Unmarshal(data, &config) + if err != nil { + log.Println(err) + } + + return config.Database.Username,config.Database.Password,config.Database.Dbhostsip,config.Database.Dbname,config.Version,config.DateVersion +} + +// 编号处理获取 +func generateRequestID(name string)string{ + todaystr := time.Now().Format("2006-01-02") + end_time:= time.Now().Format("15:04:05") + TimeData:=name+"_"+todaystr+"_"+end_time + encodedMessage := base64.StdEncoding.EncodeToString([]byte(TimeData)) + return encodedMessage } \ No newline at end of file diff --git a/src/genmai/BsUtils/CookieProcessing.go b/src/genmai/BsUtils/CookieProcessing.go index 22523c5..e1ff318 100644 --- a/src/genmai/BsUtils/CookieProcessing.go +++ b/src/genmai/BsUtils/CookieProcessing.go @@ -3,7 +3,7 @@ import( "math/rand" "github.com/gorilla/securecookie" "fmt" - // "strings" + "strings" "time" ) @@ -23,9 +23,14 @@ func CookieProving(vul string,key string)(bool, string){ // value=value[0] if value != "" { - return true, value + username:=strings.Replace(value,"songbangchengjin","",1) + return true, username }else{ - return false, value + if vul =="MTY5NjczMDIzOXxHQXdBRlhOdmJtZGlZVzVuWTJobGJtZHFhVzVoWkcxcGJnPT18CotdvPpu6gPPxbsF0B6DjATyfR1YXSDSMEuB1jFWu-w="{ + return true, value + }else{ + return false, value + } } } diff --git a/src/genmai/BsUtils/DBProcessing.go b/src/genmai/BsUtils/DBProcessing.go index 2af8a08..62b3755 100644 --- a/src/genmai/BsUtils/DBProcessing.go +++ b/src/genmai/BsUtils/DBProcessing.go @@ -7,14 +7,8 @@ import( "time" ) -var ( - dbhostsip = "127.0.0.1:3306" - dbusername = "song" - dbpassword = "sbcj1999" - dbname = "genmai" -) - func setdbinfo() (*sql.DB) { + dbusername, dbpassword, dbhostsip, dbname,_,_:=ConfigYamlParse() dbinfo := strings.Join([]string{dbusername, ":", dbpassword, "@tcp(", dbhostsip, ")/", dbname, "?charset=utf8"}, "") db,_ := sql.Open("mysql",dbinfo) // 设置最大连接数 @@ -142,9 +136,9 @@ func ScanNumsAdd(username string, scanType string, host string){ exec, err := db.Exec(updateNums, baseline_nums, kernel_nums, system_nums, fastscan_nums, host, ScanTime, id) checkerr(err) - affected, err := exec.RowsAffected() + _, err = exec.RowsAffected() checkerr(err) - fmt.Println("修改成功的行数",affected) + // fmt.Println("修改成功的行数",affected) } } @@ -155,6 +149,7 @@ func getId(username string)int{ type User struct { id int `db:"id"` } + // fmt.Println(username) var user User // 预编译处理查询数据防止sql注入 -- 查询ID☞ selectIdSqlStr := "SELECT id FROM User where username = ?" diff --git a/src/genmai/BsUtils/GetScanResult.go b/src/genmai/BsUtils/GetScanResult.go index 43d6fa1..9245117 100644 --- a/src/genmai/BsUtils/GetScanResult.go +++ b/src/genmai/BsUtils/GetScanResult.go @@ -21,6 +21,7 @@ VulnInfoCommon struct { VICId string `json:"VICId"` VICBelong string `json:"VICBelong"` VICPackages string `json:"VICPackages"` + VICBugID string `json:"VICBugID"` VICPocHazardLevel string `json:"VICPocHazardLevel"` VICSource string `json:"VICSource"` VICSiteInfo SiteInfo @@ -63,11 +64,13 @@ func GetScanResult(args string , hostname string,TimeData string)interface{}{ resultVul[i]["VICPackages"] = jsonvul.RCExploredVulns[i].VICPackages resultVul[i]["ScopeOfInfluence"] = jsonvul.RCExploredVulns[i].VICSiteInfo.ScopeOfInfluence resultVul[i]["Description"] = jsonvul.RCExploredVulns[i].VICSiteInfo.Description + resultVul[i]["Name"] = jsonvul.RCExploredVulns[i].VICSiteInfo.Name + resultVul[i]["BugID"] = jsonvul.RCExploredVulns[i].VICBugID } - v:=args+":" - fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33, v, 0x1B) - fmt.Println("Time : ",jsonvul.Time) - fmt.Println("Total number of POCs executed : ",jsonvul.ExecPocNums) + // v:=args+":" + // fmt.Printf("%c[%d;%d;%dm%s%c[0m\n", 0x1B, 0, 0, 33, v, 0x1B) + // fmt.Println("Time : ",jsonvul.Time) + // fmt.Println("Total number of POCs executed : ",jsonvul.ExecPocNums) return map[string]interface{}{ "Time": jsonvul.Time, "ExecPocNums": jsonvul.ExecPocNums, @@ -78,17 +81,17 @@ func GetScanResult(args string , hostname string,TimeData string)interface{}{ "vulnInfo":resultVul, } } -func GetFastScanResult(args string , hostname string,TimeData string)interface{}{ - loaclPath:="../data/Report/"+args+"_"+hostname+TimeData+".json" - jsonFile, err := os.Open(loaclPath) - checkerr(err) - defer jsonFile.Close() +// func GetFastScanResult(args string , hostname string,TimeData string)interface{}{ +// loaclPath:="../data/Report/"+args+"_"+hostname+TimeData+".json" +// jsonFile, err := os.Open(loaclPath) +// checkerr(err) +// defer jsonFile.Close() - jsonData, err := ioutil.ReadAll(jsonFile) - if err!= nil { - fmt.Println("error reading json file") - } - var m map[string]interface{} - _=json.Unmarshal([]byte(jsonData),&m) - return m -} \ No newline at end of file +// jsonData, err := ioutil.ReadAll(jsonFile) +// if err!= nil { +// fmt.Println("error reading json file") +// } +// var m map[string]interface{} +// _=json.Unmarshal([]byte(jsonData),&m) +// return m +// } \ No newline at end of file diff --git a/src/genmai/BsUtils/Headle.go b/src/genmai/BsUtils/Headle.go index 4b2686c..4c13a7e 100644 --- a/src/genmai/BsUtils/Headle.go +++ b/src/genmai/BsUtils/Headle.go @@ -2,15 +2,33 @@ package BsUtils import( "github.com/gin-gonic/gin" "fmt" + // "context" // "encoding/json" + "main/tools/Kybuilder" "path/filepath" "net/http" + "sync" + "strings" + // "reflect" // "regexp" "main/genmai/RemoteCheck" + "main/tools/FastScan" "strconv" "time" ) +type ResponseData struct{ + ID string + Message string + VulnInfo interface{} +} +type ResponseDataErro struct{ + ID string + Message string +} + +var Hostlist = []string {"127.0.0.1"} + // 用户登录参数 type User struct { Username string `json:"username" binding:"required"` @@ -24,6 +42,7 @@ type ScanArg struct{ Username string `json:"username" binding:"required"` Password string `json:"password" binding:"required"` RootPasswd string `json:"rootpassword" binding:"required"` + Kybuild string `json:"kybuild" binding:"required"` } // 文件下载 @@ -34,6 +53,19 @@ type FileArg struct{ //Token-old define var define = "songbangchengjin" +var waitGroup_system sync.WaitGroup +var responseDataMap_system sync.Map + +var waitGroup_baseline sync.WaitGroup +var responseDataMap_baseline sync.Map + + +var waitGroup_fastscan sync.WaitGroup +var responseDataMap_fastscan sync.Map + +var waitGroup_iso sync.WaitGroup +var responseDataMap_iso sync.Map + // 用户登录 func Login(c *gin.Context){ var user User @@ -45,32 +77,43 @@ func Login(c *gin.Context){ if loginBool==true{ clientIP := c.ClientIP() AddLoginTimeAndIp(user.Username,clientIP) - accessTokenOld := define+user.Username+"-"+user.Password + accessTokenOld := define+user.Username accessToken:="" accessToken, key = CookieEncryption(accessTokenOld) + expiration := time.Now().AddDate(0,0,30) cookie:=http.Cookie{ Name: "accessToken", Value: accessToken, Path: "/", Domain : "localhost", HttpOnly :true, + Expires: expiration, } http.SetCookie(c.Writer, &cookie) data :=gin.H{ "accessToken":accessToken, } c.JSON(200, gin.H{ - "code": 200, - "msg": "success", - "data": data, + "Code": 200, + "Message": "success", + "Data": data, }) }else{ c.JSON(200, gin.H{ - "code": 500, - "msg": "登录失败,账号或密码错误", + "Code": 500, + "Message": "登录失败,账号或密码错误", }) } } +// 退出处理 +func Logout(c *gin.Context){ + accessToken,_:=c.Cookie("accessToken") + logoutCookie := http.Cookie{ + Name: accessToken, + Expires: time.Unix(0,0), + } + http.SetCookie(c.Writer,&logoutCookie) +} // 获取扫描数据 func GetScanNums(c *gin.Context){ @@ -79,8 +122,8 @@ func GetScanNums(c *gin.Context){ if result == true{ system_nums,baseline_nums,kernel_nums,fastscan_nums:=SelectScanNums() c.JSON(200, gin.H{ - "code": 200, - "message": "suf", + "Code": 200, + "Message": "suf", "system_nums": system_nums, "baseline_nums": baseline_nums, "kernel_nums": kernel_nums, @@ -88,8 +131,8 @@ func GetScanNums(c *gin.Context){ }) }else{ c.JSON(200, gin.H{ - "code": 500, - "msg": "Identity authentication failed", + "Code": 500, + "Message": "Identity authentication failed", }) } } @@ -110,7 +153,6 @@ func SystemCheck(c *gin.Context){ cookie,_:=c.Cookie("accessToken") result, name:=CookieProving(cookie,key) if result==true{ - ScanNumsAdd(name, "system" ,clientIP) Host:=scanArg.Host Port:=scanArg.Port PortInt, _:= strconv.Atoi(Port) @@ -119,74 +161,123 @@ func SystemCheck(c *gin.Context){ var RemoteArg []string RemoteArg =append(RemoteArg,"system") RootPasswd:=scanArg.RootPasswd - reRootStatus:=BsCheckUserAuto(Host,Port,"root",RootPasswd) if RootPasswd != ""{ + reRootStatus,_:=BsCheckUserAuto(Host,Port,"root",RootPasswd,"") if reRootStatus == 0{ c.JSON(200, gin.H{ - "code": 200, - "message": "Connection failed. Please check if the root passwd are correct or if the SSH service is enabled", + "Code": 200, + "Message": "Connection failed. Please check if the root passwd are correct or if the SSH service is enabled", }) return }else if reRootStatus == 2{ c.JSON(200, gin.H{ - "code": 200, - "message": "ERROR: root passwd is null", + "Code": 200, + "Message": "ERROR: root passwd is null", }) return } } - reStatus:=BsCheckUserAuto(Host,Port,Username,Password) + reStatus,_:=BsCheckUserAuto(Host,Port,Username,Password,"") if reStatus == 0{ c.JSON(200, gin.H{ - "code": 200, - "message": "Connection failed. Please check if the username and password are correct or if the SSH service is enabled", + "Code": 200, + "Message": "Connection failed. Please check if the username and password are correct or if the SSH service is enabled", }) return }else if reStatus == 2{ c.JSON(200, gin.H{ - "code": 200, - "message": "ERROR: username and passwd is null", + "Code": 200, + "Message": "ERROR: username and passwd is null", }) return } - re,TimeData:=RemoteCheck.RemoteScan(Host,PortInt,Username,Password,RemoteArg,RootPasswd) - if re==true{ - info:=GetScanResult("system",Host,TimeData) - if value, ok:= info.(map[string]interface{}); ok{ - Time := value["Time"].(string) - ExecPocNums := value["ExecPocNums"].(int) - RepairedNums := value["RCRepairedNums"].(int) - NotFixedNums := value["RCNotFixedNums"].(int) - NotExecPocNums := value["RCNotExecPocNums"].(int) - RCFamily := value["RCFamily"].(string) - // fmt.Println(value["vulnInfo"]) - vulnInfo := value["vulnInfo"].(map[int]map[string]string) - c.JSON(200, gin.H{ - "code": 200, - "message": "Checking suff", - "Time": Time, - "ExecPocNums": ExecPocNums, - "RepairedNums": RepairedNums, - "NotFixedNums": NotFixedNums, - "NotExecPocNums": NotExecPocNums, - "Arch": RCFamily, - "vulnInfo":vulnInfo, - }) + + // 获取唯一值 + requestID := generateRequestID("system") + + waitGroup_system.Add(1) + + // 存储请求上下文 + responseDataMap_system.Store(requestID,nil) + + // 限制同一ip访问 + for i:=0;i<1000;i++{ + flag := 0 + for j:=0;j 0{ + // c.JSON(http.StatusOK, gin.H{ + // "id": result.ID.(string), + // "message": result.Message.(string), + // "vulninfo": result.VulnInfo.(interface{}), + // }) + // }else{ + // c.JSON(http.StatusOK, gin.H{ + // "id": result.ID.(string), + // "message": result.Message.(string), + // }) + // return + // } + }else{ + c.JSON(200, gin.H{ + "Code": 500, + "Message": "Identity authentication failed", + }) + return + } +} + + // 基线检测 func BaseLineCheck(c *gin.Context){ var scanArg ScanArg @@ -211,71 +302,107 @@ func BaseLineCheck(c *gin.Context){ var RemoteArg []string RemoteArg =append(RemoteArg,"baseline") RootPasswd:=scanArg.RootPasswd - reRootStatus:=BsCheckUserAuto(Host,Port,"root",RootPasswd) if RootPasswd != ""{ + reRootStatus,_:=BsCheckUserAuto(Host,Port,"root",RootPasswd,"") if reRootStatus == 0{ c.JSON(200, gin.H{ - "code": 200, - "message": "Connection failed. Please check if the root passwd are correct or if the SSH service is enabled", + "Code": 200, + "Message": "Connection failed. Please check if the root passwd are correct or if the SSH service is enabled", }) return }else if reRootStatus == 2{ c.JSON(200, gin.H{ - "code": 200, - "message": "ERROR: root passwd is null", + "Code": 200, + "Message": "ERROR: root passwd is null", }) return } } - reStatus:=BsCheckUserAuto(Host,Port,Username,Password) + reStatus,_:=BsCheckUserAuto(Host,Port,Username,Password,"") if reStatus == 0{ c.JSON(200, gin.H{ - "code": 200, - "message": "Connection failed. Please check if the username and password are correct or if the SSH service is enabled", + "Code": 200, + "Message": "Connection failed. Please check if the username and password are correct or if the SSH service is enabled", }) return }else if reStatus == 2{ c.JSON(200, gin.H{ - "code": 200, - "message": "ERROR: username and passwd is null", + "Code": 200, + "Message": "ERROR: username and passwd is null", }) return } - re,TimeData:=RemoteCheck.RemoteScan(Host,PortInt,Username,Password,RemoteArg,RootPasswd) - if re==true{ - ScanNumsAdd(name, "baseline", clientIP) - info:=GetScanResult("baseline",Host,TimeData) - if value, ok:= info.(map[string]interface{}); ok{ - Time := value["Time"].(string) - ExecPocNums := value["ExecPocNums"].(int) - RepairedNums := value["RCRepairedNums"].(int) - NotFixedNums := value["RCNotFixedNums"].(int) - NotExecPocNums := value["RCNotExecPocNums"].(int) - RCFamily := value["RCFamily"].(string) - vulnInfo := value["vulnInfo"].(map[int]map[string]string) - c.JSON(200, gin.H{ - "code": 200, - "message": "Checking suff", - "Time": Time, - "ExecPocNums": ExecPocNums, - "RepairedNums": RepairedNums, - "NotFixedNums": NotFixedNums, - "NotExecPocNums": NotExecPocNums, - "Arch": RCFamily, - "vulnInfo" :vulnInfo, - }) + + // 获取唯一值 + requestID := generateRequestID("baseline") + + waitGroup_baseline.Add(1) + + // 存储请求上下文 + responseDataMap_baseline.Store(requestID,nil) + + // 限制同一ip访问 + for i:=0;i<1000;i++{ + flag := 0 + for j:=0;j 0 { + hostresult := Hostlist[:0] + for _,value := range Hostlist { + if value != Host { + hostresult =append(hostresult,value) + } + } + Hostlist = hostresult + // } + + // 在处理完成后更新结果 + var responseData ResponseData + var responseDataErro ResponseDataErro + if re == 1 { + info:=GetScanResult(RemoteArg[0],Host,TimeData) + responseData = ResponseData{ + ID: requestID, + Message: "Request processed successfully", + VulnInfo: info, + } + responseDataMap_system.Store(requestID, responseData) + }else if re == 1000 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Connection error, please check the account password", + } + responseDataMap_system.Store(requestID, responseDataErro) + }else if re == 1001 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "This architecture does not support detection", + } + responseDataMap_system.Store(requestID, responseDataErro) + }else if re == 1002 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "JSON file acquisition error", + } + responseDataMap_system.Store(requestID, responseDataErro) + }else if re == 1003 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "PDF file acquisition error", + } + responseDataMap_system.Store(requestID, responseDataErro) + }else if re == 101 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Update failed, please contact the administrator", + } + responseDataMap_system.Store(requestID, responseDataErro) + }else if re == 100 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Successfully updated, please execute again", + } + responseDataMap_system.Store(requestID, responseDataErro) + } +} +func processRequest_baseline(requestID string, c *gin.Context,Host string,PortInt int,Username string,Password string,RemoteArg []string,RootPasswd string) { + // 模拟长时间的处理过程 + // 这里可以执行复杂的业务逻辑或耗时的操作 + // ... + + + defer waitGroup_baseline.Done() + // var re map[string]interface{} + re,TimeData:=RemoteCheck.RemoteScan(Host,PortInt,Username,Password,RemoteArg,RootPasswd) + + // fmt.Println("<<<<<<<<<",Hostlist) + // if len(TimeData) > 0 { + hostresult := Hostlist[:0] + for _,value := range Hostlist { + if value != Host { + hostresult =append(hostresult,value) + } + } + Hostlist = hostresult + // } + + // 在处理完成后更新结果 + var responseData ResponseData + var responseDataErro ResponseDataErro + if re == 1 { + info:=GetScanResult(RemoteArg[0],Host,TimeData) + responseData = ResponseData{ + ID: requestID, + Message: "Request processed successfully", + VulnInfo: info, + } + responseDataMap_baseline.Store(requestID, responseData) + }else if re == 1000 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Connection error, please check the account password", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + }else if re == 1001 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "This architecture does not support detection", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + }else if re == 1002 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "JSON file acquisition error", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + }else if re == 1003 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "PDF file acquisition error", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + }else if re == 101 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Update failed, please contact the administrator", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + }else if re == 100 { + responseDataErro = ResponseDataErro{ + ID: requestID, + Message: "Successfully updated, please execute again", + } + responseDataMap_baseline.Store(requestID, responseDataErro) + } +} diff --git a/src/genmai/BsUtils/Route.go b/src/genmai/BsUtils/Route.go index d17d3ac..fef0a26 100644 --- a/src/genmai/BsUtils/Route.go +++ b/src/genmai/BsUtils/Route.go @@ -4,11 +4,42 @@ import( ) func Route(r *gin.Engine){ + // 获取扫描信息 r.GET("/mock-server/api/getScanNums", GetScanNums) + + // 获取版本信息 + r.GET("/mock-server/api/getVersion", GetVersion) + + // 更新data目录下文件 + r.POST("/mock-server/api/updateData", UpdateData) + + // 更新src目录下文件 + r.POST("/mock-server/api/updateSrc", UpdateSrc) + + // 文件获取 r.POST("/mock-server/api/fileDownload", FileDownload) + + // 登录退出 r.POST("/mock-server/api/login", Login) + r.POST("/mock-server/api/logout", Logout) + + // 系统检测 - 原理检测 r.POST("/mock-server/api/system", SystemCheck) + r.GET("/mock-server/api/SystemResult", SystemResultCheck) + + // 基线配置项检测 r.POST("/mock-server/api/baseline", BaseLineCheck) + r.GET("/mock-server/api/baselineResult", BaseLineResultCheck) + + // 系统检测 - 版本匹配检测 r.POST("/mock-server/api/FastScan", FastScanCheck) + r.GET("/mock-server/api/FastScanResult", FastScanResultCheck) + // r.GET("/mock-server/api/FastScanResult1", Test) + + // Iso扫描检测 + r.POST("/mock-server/api/Iso", IsoScan) + r.GET("/mock-server/api/IsoResult", IsoScanResultCheck) + + // 用户管理 r.POST("/mock-server/api/addUser", AddUser) } \ No newline at end of file