mirror of
https://github.com/XZB-1248/Spark
synced 2025-10-23 15:43:22 +08:00
initial commit
This commit is contained in:
184
server/handler/generate.go
Normal file
184
server/handler/generate.go
Normal file
@@ -0,0 +1,184 @@
|
||||
package handler
|
||||
|
||||
import (
|
||||
"Spark/modules"
|
||||
"Spark/server/common"
|
||||
"Spark/server/config"
|
||||
"Spark/utils"
|
||||
"bytes"
|
||||
"encoding/hex"
|
||||
"errors"
|
||||
"fmt"
|
||||
"github.com/gin-gonic/gin"
|
||||
"math/big"
|
||||
"net/http"
|
||||
"strconv"
|
||||
"strings"
|
||||
)
|
||||
|
||||
type clientCfg struct {
|
||||
Secure bool `json:"secure"`
|
||||
Host string `json:"host"`
|
||||
Port int `json:"port"`
|
||||
Path string `json:"path"`
|
||||
UUID string `json:"uuid"`
|
||||
Key string `json:"key"`
|
||||
}
|
||||
|
||||
var (
|
||||
errTooLargeEntity = errors.New(`length of data can not excess buffer size`)
|
||||
)
|
||||
|
||||
//func init() {
|
||||
// clientUUID := utils.GetUUID()
|
||||
// clientKey, _ := common.EncAES(clientUUID, append([]byte("XZB_Spark"), bytes.Repeat([]byte{25}, 24-9)...))
|
||||
// cfg, _ := genConfig(clientCfg{
|
||||
// Secure: false,
|
||||
// Host: "47.102.136.182",
|
||||
// Port: 1025,
|
||||
// Path: "/",
|
||||
// UUID: hex.EncodeToString(clientUUID),
|
||||
// Key: hex.EncodeToString(clientKey),
|
||||
// })
|
||||
// output := ``
|
||||
// temp := hex.EncodeToString(cfg)
|
||||
// for i := 0; i < len(temp); i += 2 {
|
||||
// output += `\x` + temp[i:i+2]
|
||||
// }
|
||||
// ioutil.WriteFile(`./Client.cfg`, []byte(output), 0755)
|
||||
//}
|
||||
|
||||
func checkClient(ctx *gin.Context) {
|
||||
var form struct {
|
||||
OS string `json:"os" yaml:"os" form:"os" binding:"required"`
|
||||
Arch string `json:"arch" yaml:"arch" form:"arch" binding:"required"`
|
||||
Host string `json:"host" yaml:"host" form:"host" binding:"required"`
|
||||
Port uint16 `json:"port" yaml:"port" form:"port" binding:"required"`
|
||||
Path string `json:"path" yaml:"path" form:"path" binding:"required"`
|
||||
Secure string `json:"secure" yaml:"secure" form:"secure"`
|
||||
}
|
||||
if err := ctx.ShouldBind(&form); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, modules.Packet{Code: -1, Msg: `参数不完整`})
|
||||
return
|
||||
}
|
||||
_, err := common.BuiltFS.Open(fmt.Sprintf(`/%v_%v`, form.OS, form.Arch))
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusNotFound, modules.Packet{Code: 1, Msg: `该系统或架构的客户端尚未编译`})
|
||||
return
|
||||
}
|
||||
_, err = genConfig(clientCfg{
|
||||
Secure: form.Secure == `true`,
|
||||
Host: form.Host,
|
||||
Port: int(form.Port),
|
||||
Path: form.Path,
|
||||
UUID: strings.Repeat(`FF`, 16),
|
||||
Key: strings.Repeat(`FF`, 32),
|
||||
})
|
||||
if err != nil {
|
||||
if err == errTooLargeEntity {
|
||||
ctx.JSON(http.StatusRequestEntityTooLarge, modules.Packet{Code: 1, Msg: `配置信息过长`})
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusInternalServerError, modules.Packet{Code: 1, Msg: `配置文件生成失败`})
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusOK, modules.Packet{Code: 0})
|
||||
}
|
||||
|
||||
func generateClient(ctx *gin.Context) {
|
||||
var form struct {
|
||||
OS string `json:"os" yaml:"os" form:"os" binding:"required"`
|
||||
Arch string `json:"arch" yaml:"arch" form:"arch" binding:"required"`
|
||||
Host string `json:"host" yaml:"host" form:"host" binding:"required"`
|
||||
Port uint16 `json:"port" yaml:"port" form:"port" binding:"required"`
|
||||
Path string `json:"path" yaml:"path" form:"path" binding:"required"`
|
||||
Secure string `json:"secure" yaml:"secure" form:"secure"`
|
||||
}
|
||||
if err := ctx.ShouldBind(&form); err != nil {
|
||||
ctx.JSON(http.StatusBadRequest, modules.Packet{Code: -1, Msg: `参数不完整`})
|
||||
return
|
||||
}
|
||||
tpl, err := common.BuiltFS.Open(fmt.Sprintf(`/%v_%v`, form.OS, form.Arch))
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusNotFound, modules.Packet{Code: 1, Msg: `该系统或架构的客户端尚未编译`})
|
||||
return
|
||||
}
|
||||
clientUUID := utils.GetUUID()
|
||||
clientKey, err := common.EncAES(clientUUID, config.Config.StdSalt)
|
||||
if err != nil {
|
||||
ctx.JSON(http.StatusInternalServerError, modules.Packet{Code: 1, Msg: `配置文件生成失败`})
|
||||
return
|
||||
}
|
||||
cfgBytes, err := genConfig(clientCfg{
|
||||
Secure: form.Secure == `true`,
|
||||
Host: form.Host,
|
||||
Port: int(form.Port),
|
||||
Path: form.Path,
|
||||
UUID: hex.EncodeToString(clientUUID),
|
||||
Key: hex.EncodeToString(clientKey),
|
||||
})
|
||||
if err != nil {
|
||||
if err == errTooLargeEntity {
|
||||
ctx.JSON(http.StatusRequestEntityTooLarge, modules.Packet{Code: 1, Msg: `配置信息过长`})
|
||||
return
|
||||
}
|
||||
ctx.JSON(http.StatusInternalServerError, modules.Packet{Code: 1, Msg: `配置文件生成失败`})
|
||||
return
|
||||
}
|
||||
ctx.Header(`Accept-Ranges`, `none`)
|
||||
ctx.Header(`Content-Transfer-Encoding`, `binary`)
|
||||
ctx.Header(`Content-Type`, `application/octet-stream`)
|
||||
if stat, err := tpl.Stat(); err == nil {
|
||||
ctx.Header(`Content-Length`, strconv.FormatInt(stat.Size(), 10))
|
||||
}
|
||||
if form.OS == `windows` {
|
||||
ctx.Header(`Content-Disposition`, `attachment; filename=client.exe;`)
|
||||
} else {
|
||||
ctx.Header(`Content-Disposition`, `attachment; filename=client;`)
|
||||
}
|
||||
cfgBuffer := bytes.Repeat([]byte{'\x19'}, 384)
|
||||
prevBuffer := make([]byte, 0)
|
||||
for {
|
||||
thisBuffer := make([]byte, 1024)
|
||||
n, err := tpl.Read(thisBuffer)
|
||||
thisBuffer = thisBuffer[:n]
|
||||
tempBuffer := append(prevBuffer, thisBuffer...)
|
||||
bufIndex := bytes.Index(tempBuffer, cfgBuffer)
|
||||
if bufIndex > -1 {
|
||||
tempBuffer = bytes.Replace(tempBuffer, cfgBuffer, cfgBytes, -1)
|
||||
}
|
||||
ctx.Writer.Write(tempBuffer[:len(prevBuffer)])
|
||||
prevBuffer = tempBuffer[len(prevBuffer):]
|
||||
if err != nil {
|
||||
break
|
||||
}
|
||||
}
|
||||
if len(prevBuffer) > 0 {
|
||||
ctx.Writer.Write(prevBuffer)
|
||||
prevBuffer = []byte{}
|
||||
}
|
||||
}
|
||||
|
||||
func genConfig(cfg clientCfg) ([]byte, error) {
|
||||
data, err := utils.JSON.Marshal(cfg)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
key := utils.GetUUID()
|
||||
data, err = common.EncAES(data, key)
|
||||
if err != nil {
|
||||
return nil, err
|
||||
}
|
||||
final := append(key, data...)
|
||||
if len(final) > 384-2 {
|
||||
return nil, errTooLargeEntity
|
||||
}
|
||||
dataLen := big.NewInt(int64(len(final))).Bytes()
|
||||
dataLen = append(bytes.Repeat([]byte{'\x00'}, 2-len(dataLen)), dataLen...)
|
||||
|
||||
final = append(dataLen, final...)
|
||||
for len(final) < 384 {
|
||||
final = append(final, utils.GetUUID()...)
|
||||
}
|
||||
return final[:384], nil
|
||||
}
|
Reference in New Issue
Block a user