next-terminal/pkg/api/tunnel.go

182 lines
5.7 KiB
Go
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

package api
import (
"github.com/gorilla/websocket"
"github.com/labstack/echo/v4"
"github.com/sirupsen/logrus"
"next-terminal/pkg/global"
"next-terminal/pkg/guacd"
"next-terminal/pkg/model"
"path"
"strconv"
)
func TunEndpoint(c echo.Context) error {
ws, err := UpGrader.Upgrade(c.Response().Writer, c.Request(), nil)
if err != nil {
logrus.Errorf("升级为WebSocket协议失败%v", err.Error())
return err
}
width := c.QueryParam("width")
height := c.QueryParam("height")
sessionId := c.QueryParam("sessionId")
connectionId := c.QueryParam("connectionId")
intWidth, _ := strconv.Atoi(width)
intHeight, _ := strconv.Atoi(height)
configuration := guacd.NewConfiguration()
configuration.SetParameter("width", width)
configuration.SetParameter("height", height)
propertyMap := model.FindAllPropertiesMap()
var session model.Session
if len(connectionId) > 0 {
session, err = model.FindSessionByConnectionId(connectionId)
if err != nil {
return err
}
configuration.ConnectionID = connectionId
} else {
session, err = model.FindSessionById(sessionId)
if err != nil {
return err
}
if propertyMap[guacd.EnableRecording] == "true" {
configuration.SetParameter(guacd.RecordingPath, path.Join(propertyMap[guacd.RecordingPath], sessionId))
configuration.SetParameter(guacd.CreateRecordingPath, propertyMap[guacd.CreateRecordingPath])
} else {
configuration.SetParameter(guacd.RecordingPath, "")
}
configuration.Protocol = session.Protocol
switch configuration.Protocol {
case "rdp":
configuration.SetParameter("username", session.Username)
configuration.SetParameter("password", session.Password)
configuration.SetParameter("security", "any")
configuration.SetParameter("ignore-cert", "true")
configuration.SetParameter("create-drive-path", "true")
configuration.SetParameter("dpi", "96")
configuration.SetParameter("resize-method", "reconnect")
configuration.SetParameter(guacd.EnableDrive, propertyMap[guacd.EnableDrive])
configuration.SetParameter(guacd.DriveName, propertyMap[guacd.DriveName])
configuration.SetParameter(guacd.DrivePath, propertyMap[guacd.DrivePath])
configuration.SetParameter(guacd.EnableWallpaper, propertyMap[guacd.EnableWallpaper])
configuration.SetParameter(guacd.EnableTheming, propertyMap[guacd.EnableTheming])
configuration.SetParameter(guacd.EnableFontSmoothing, propertyMap[guacd.EnableFontSmoothing])
configuration.SetParameter(guacd.EnableFullWindowDrag, propertyMap[guacd.EnableFullWindowDrag])
configuration.SetParameter(guacd.EnableDesktopComposition, propertyMap[guacd.EnableDesktopComposition])
configuration.SetParameter(guacd.EnableMenuAnimations, propertyMap[guacd.EnableMenuAnimations])
configuration.SetParameter(guacd.DisableBitmapCaching, propertyMap[guacd.DisableBitmapCaching])
configuration.SetParameter(guacd.DisableOffscreenCaching, propertyMap[guacd.DisableOffscreenCaching])
configuration.SetParameter(guacd.DisableGlyphCaching, propertyMap[guacd.DisableGlyphCaching])
break
case "ssh":
if len(session.PrivateKey) > 0 && session.PrivateKey != "-" {
configuration.SetParameter("private-key", session.PrivateKey)
configuration.SetParameter("passphrase", session.Passphrase)
} else {
configuration.SetParameter("username", session.Username)
configuration.SetParameter("password", session.Password)
}
fontSize, _ := strconv.Atoi(propertyMap[guacd.FontSize])
fontSize = fontSize * 2
configuration.SetParameter(guacd.FontSize, strconv.Itoa(fontSize))
configuration.SetParameter(guacd.FontName, propertyMap[guacd.FontName])
configuration.SetParameter(guacd.ColorScheme, propertyMap[guacd.ColorScheme])
break
case "vnc":
configuration.SetParameter("password", session.Password)
configuration.SetParameter("enable-sftp", "")
break
case "telnet":
configuration.SetParameter("username", session.Username)
configuration.SetParameter("password", session.Password)
configuration.SetParameter("enable-sftp", "")
break
}
configuration.SetParameter("hostname", session.IP)
configuration.SetParameter("port", strconv.Itoa(session.Port))
}
addr := propertyMap[guacd.Host] + ":" + propertyMap[guacd.Port]
logrus.Infof("connect to %v with global: %+v", addr, configuration)
tunnel, err := guacd.NewTunnel(addr, configuration)
if err != nil {
return err
}
tun := global.Tun{
Tun: tunnel,
WebSocket: ws,
}
global.Store.Set(sessionId, &tun)
if len(session.ConnectionId) == 0 {
session.ConnectionId = tunnel.UUID
session.Width = intWidth
session.Height = intHeight
session.Recording = configuration.GetParameter(guacd.RecordingPath)
model.UpdateSessionById(&session, sessionId)
}
go func() {
sftpClient, err := CreateSftpClient(session.AssetId)
if err != nil {
CloseSessionById(sessionId, 2002, err.Error())
logrus.Errorf("创建sftp客户端失败%v", err.Error())
}
item, ok := global.Store.Get(sessionId)
if ok {
item.SftpClient = sftpClient
}
}()
go func() {
for true {
instruction, err := tunnel.Read()
if err != nil {
CloseSessionById(sessionId, 523, err.Error())
logrus.Printf("WebSocket读取错误: %v", err)
break
}
err = ws.WriteMessage(websocket.TextMessage, instruction)
if err != nil {
CloseSessionById(sessionId, 523, err.Error())
logrus.Printf("WebSocket写入错误: %v", err)
break
}
}
}()
for true {
_, message, err := ws.ReadMessage()
if err != nil {
CloseSessionById(sessionId, 523, err.Error())
logrus.Printf("隧道读取错误: %v", err)
break
}
_, err = tunnel.WriteAndFlush(message)
if err != nil {
CloseSessionById(sessionId, 523, err.Error())
logrus.Printf("隧道写入错误: %v", err)
break
}
}
return err
}