mirror of
https://github.com/antoniomika/sish.git
synced 2025-12-24 13:37:57 +08:00
Fix console access and logs
This commit is contained in:
committed by
Antonio Mika
parent
aefb5b0822
commit
b71acec24d
@@ -64,12 +64,14 @@ func Start(state *utils.State) {
|
||||
param.Latency = param.Latency - param.Latency%time.Second
|
||||
}
|
||||
|
||||
if viper.GetString("admin-console-token") != "" && strings.Contains(param.Path, viper.GetString("admin-console-token")) {
|
||||
param.Path = strings.Replace(param.Path, viper.GetString("admin-console-token"), "[REDACTED]", 1)
|
||||
originalURI := param.Keys["originalURI"].(string)
|
||||
|
||||
if viper.GetString("admin-console-token") != "" && strings.Contains(originalURI, viper.GetString("admin-console-token")) {
|
||||
originalURI = strings.Replace(originalURI, viper.GetString("admin-console-token"), "[REDACTED]", 1)
|
||||
}
|
||||
|
||||
if viper.GetString("service-console-token") != "" && strings.Contains(param.Path, viper.GetString("service-console-token")) {
|
||||
param.Path = strings.Replace(param.Path, viper.GetString("service-console-token"), "[REDACTED]", 1)
|
||||
if viper.GetString("service-console-token") != "" && strings.Contains(originalURI, viper.GetString("service-console-token")) {
|
||||
originalURI = strings.Replace(originalURI, viper.GetString("service-console-token"), "[REDACTED]", 1)
|
||||
}
|
||||
|
||||
logLine := fmt.Sprintf("%v | %s |%s %3d %s| %13v | %15s |%s %-7s %s %s\n%s",
|
||||
@@ -79,35 +81,12 @@ func Start(state *utils.State) {
|
||||
param.Latency,
|
||||
param.ClientIP,
|
||||
methodColor, param.Method, resetColor,
|
||||
param.Path,
|
||||
originalURI,
|
||||
param.ErrorMessage,
|
||||
)
|
||||
|
||||
if viper.GetBool("log-to-client") {
|
||||
var currentListener *utils.HTTPHolder
|
||||
var secondOption *utils.HTTPHolder
|
||||
hostname := strings.Split(param.Request.Host, ":")[0]
|
||||
|
||||
state.HTTPListeners.Range(func(key, value interface{}) bool {
|
||||
locationListener := value.(*utils.HTTPHolder)
|
||||
|
||||
requestUsername, requestPassword, _ := param.Request.BasicAuth()
|
||||
parsedPassword, _ := locationListener.HTTPUrl.User.Password()
|
||||
|
||||
if hostname == locationListener.HTTPUrl.Host && strings.HasPrefix(param.Request.URL.Path, locationListener.HTTPUrl.Path) {
|
||||
secondOption = locationListener
|
||||
if requestUsername == locationListener.HTTPUrl.User.Username() && requestPassword == parsedPassword {
|
||||
currentListener = locationListener
|
||||
return false
|
||||
}
|
||||
}
|
||||
|
||||
return true
|
||||
})
|
||||
|
||||
if currentListener == nil && secondOption != nil {
|
||||
currentListener = secondOption
|
||||
}
|
||||
if viper.GetBool("log-to-client") && param.Keys["httpHolder"] != nil {
|
||||
currentListener := param.Keys["httpHolder"].(*utils.HTTPHolder)
|
||||
|
||||
if currentListener != nil {
|
||||
sshConnTmp, ok := currentListener.SSHConnections.Load(param.Keys["proxySocket"])
|
||||
@@ -126,34 +105,36 @@ func Start(state *utils.State) {
|
||||
|
||||
return logLine
|
||||
}), gin.Recovery(), func(c *gin.Context) {
|
||||
c.Set("originalURI", c.Request.RequestURI)
|
||||
c.Set("originalPath", c.Request.URL.Path)
|
||||
c.Set("originalRawPath", c.Request.URL.RawPath)
|
||||
|
||||
hostSplit := strings.Split(c.Request.Host, ":")
|
||||
hostname := hostSplit[0]
|
||||
hostIsRoot := hostname == viper.GetString("domain")
|
||||
|
||||
if (viper.GetBool("admin-console") || viper.GetBool("service-console")) && strings.HasPrefix(c.Request.URL.Path, "/_sish/") {
|
||||
state.Console.HandleRequest(hostname, hostIsRoot, c)
|
||||
if viper.GetBool("admin-console") && hostIsRoot && strings.HasPrefix(c.Request.URL.Path, "/_sish/") {
|
||||
state.Console.HandleRequest("", hostIsRoot, c)
|
||||
return
|
||||
}
|
||||
|
||||
var currentListener *utils.HTTPHolder
|
||||
var secondOption *utils.HTTPHolder
|
||||
|
||||
requestUsername, requestPassword, _ := c.Request.BasicAuth()
|
||||
exactMatch := false
|
||||
authNeeded := true
|
||||
|
||||
state.HTTPListeners.Range(func(key, value interface{}) bool {
|
||||
locationListener := value.(*utils.HTTPHolder)
|
||||
|
||||
requestUsername, requestPassword, _ := c.Request.BasicAuth()
|
||||
parsedPassword, _ := locationListener.HTTPUrl.User.Password()
|
||||
|
||||
if hostname == locationListener.HTTPUrl.Host && strings.HasPrefix(c.Request.URL.Path, locationListener.HTTPUrl.Path) {
|
||||
secondOption = locationListener
|
||||
if requestUsername == locationListener.HTTPUrl.User.Username() && requestPassword == parsedPassword {
|
||||
currentListener = locationListener
|
||||
return false
|
||||
}
|
||||
currentListener = locationListener
|
||||
|
||||
if (locationListener.HTTPUrl.User.Username() != "" && requestUsername == "") || (parsedPassword != "" && requestPassword == "") {
|
||||
c.Header("WWW-Authenticate", "Basic realm=\"sish\"")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
if requestUsername == locationListener.HTTPUrl.User.Username() && requestPassword == parsedPassword {
|
||||
exactMatch = true
|
||||
authNeeded = false
|
||||
return false
|
||||
}
|
||||
}
|
||||
@@ -161,14 +142,6 @@ func Start(state *utils.State) {
|
||||
return true
|
||||
})
|
||||
|
||||
if c.IsAborted() {
|
||||
return
|
||||
}
|
||||
|
||||
if currentListener == nil && secondOption != nil {
|
||||
currentListener = secondOption
|
||||
}
|
||||
|
||||
if currentListener == nil && hostIsRoot {
|
||||
if viper.GetBool("redirect-root") && !strings.HasPrefix(c.Request.URL.Path, "/favicon.ico") {
|
||||
c.Redirect(http.StatusFound, viper.GetString("redirect-root-location"))
|
||||
@@ -187,7 +160,37 @@ func Start(state *utils.State) {
|
||||
return
|
||||
}
|
||||
|
||||
if viper.GetBool("strip-http-path") {
|
||||
c.Set("httpHolder", currentListener)
|
||||
|
||||
if !exactMatch || authNeeded {
|
||||
c.Header("WWW-Authenticate", "Basic realm=\"sish\"")
|
||||
c.AbortWithStatus(http.StatusUnauthorized)
|
||||
return
|
||||
}
|
||||
|
||||
stripPath := viper.GetBool("strip-http-path")
|
||||
|
||||
currentListener.SSHConnections.Range(func(key, val interface{}) bool {
|
||||
sshConn := val.(*utils.SSHConnection)
|
||||
newHost := sshConn.HostHeader
|
||||
|
||||
if sshConn.StripPath != viper.GetBool("strip-http-path") {
|
||||
stripPath = sshConn.StripPath
|
||||
}
|
||||
|
||||
if newHost == "" {
|
||||
return true
|
||||
}
|
||||
|
||||
if len(hostSplit) > 1 {
|
||||
newHost = fmt.Sprintf("%s:%s", newHost, hostSplit[1])
|
||||
}
|
||||
|
||||
c.Request.Host = newHost
|
||||
return false
|
||||
})
|
||||
|
||||
if viper.GetBool("strip-http-path") && stripPath {
|
||||
c.Request.RequestURI = strings.TrimPrefix(c.Request.RequestURI, currentListener.HTTPUrl.Path)
|
||||
c.Request.URL.Path = strings.TrimPrefix(c.Request.URL.Path, currentListener.HTTPUrl.Path)
|
||||
c.Request.URL.RawPath = strings.TrimPrefix(c.Request.URL.RawPath, currentListener.HTTPUrl.Path)
|
||||
@@ -211,6 +214,11 @@ func Start(state *utils.State) {
|
||||
})
|
||||
}
|
||||
|
||||
if exactMatch && (viper.GetBool("admin-console") || viper.GetBool("service-console")) && strings.HasPrefix(c.Request.URL.Path, "/_sish/") {
|
||||
state.Console.HandleRequest(currentListener.HTTPUrl.String(), hostIsRoot, c)
|
||||
return
|
||||
}
|
||||
|
||||
reqBody, err := ioutil.ReadAll(c.Request.Body)
|
||||
if err != nil {
|
||||
log.Println("Error reading request body:", err)
|
||||
@@ -219,7 +227,7 @@ func Start(state *utils.State) {
|
||||
|
||||
c.Request.Body = ioutil.NopCloser(bytes.NewBuffer(reqBody))
|
||||
|
||||
err = forward.ResponseModifier(ResponseModifier(state, hostname, reqBody, c))(currentListener.Forward)
|
||||
err = forward.ResponseModifier(ResponseModifier(state, hostname, reqBody, c, currentListener))(currentListener.Forward)
|
||||
if err != nil {
|
||||
log.Println("Unable to set response modifier:", err)
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ func RoundTripper() *http.Transport {
|
||||
// ResponseModifier implements a response modifier for the specified request.
|
||||
// We don't actually modify any requests, but we do want to record the request
|
||||
// so we can send it to the web console.
|
||||
func ResponseModifier(state *utils.State, hostname string, reqBody []byte, c *gin.Context) func(*http.Response) error {
|
||||
func ResponseModifier(state *utils.State, hostname string, reqBody []byte, c *gin.Context, currentListener *utils.HTTPHolder) func(*http.Response) error {
|
||||
return func(response *http.Response) error {
|
||||
if viper.GetBool("admin-console") || viper.GetBool("service-console") {
|
||||
resBody, err := ioutil.ReadAll(response.Body)
|
||||
@@ -79,19 +79,20 @@ func ResponseModifier(state *utils.State, hostname string, reqBody []byte, c *gi
|
||||
requestHeaders.Add("Host", hostname)
|
||||
|
||||
data, err := json.Marshal(map[string]interface{}{
|
||||
"startTime": startTime,
|
||||
"startTimePretty": startTime.Format(viper.GetString("time-format")),
|
||||
"currentTime": currentTime,
|
||||
"requestIP": c.ClientIP(),
|
||||
"requestTime": diffTime.Round(roundTime).String(),
|
||||
"requestMethod": c.Request.Method,
|
||||
"requestUrl": c.Request.URL,
|
||||
"requestHeaders": requestHeaders,
|
||||
"requestBody": base64.StdEncoding.EncodeToString(reqBody),
|
||||
"responseHeaders": response.Header,
|
||||
"responseCode": response.StatusCode,
|
||||
"responseStatus": response.Status,
|
||||
"responseBody": base64.StdEncoding.EncodeToString(resBody),
|
||||
"startTime": startTime,
|
||||
"startTimePretty": startTime.Format(viper.GetString("time-format")),
|
||||
"currentTime": currentTime,
|
||||
"requestIP": c.ClientIP(),
|
||||
"requestTime": diffTime.Round(roundTime).String(),
|
||||
"requestMethod": c.Request.Method,
|
||||
"requestUrl": c.Request.URL,
|
||||
"originalRequestURI": c.GetString("originalURI"),
|
||||
"requestHeaders": requestHeaders,
|
||||
"requestBody": base64.StdEncoding.EncodeToString(reqBody),
|
||||
"responseHeaders": response.Header,
|
||||
"responseCode": response.StatusCode,
|
||||
"responseStatus": response.Status,
|
||||
"responseBody": base64.StdEncoding.EncodeToString(resBody),
|
||||
})
|
||||
|
||||
if err != nil {
|
||||
@@ -107,7 +108,7 @@ func ResponseModifier(state *utils.State, hostname string, reqBody []byte, c *gi
|
||||
c.Set("proxySocket", string(hostLocation))
|
||||
}
|
||||
|
||||
state.Console.BroadcastRoute(hostname, data)
|
||||
state.Console.BroadcastRoute(currentListener.HTTPUrl.String(), data)
|
||||
}
|
||||
|
||||
return nil
|
||||
|
||||
@@ -6,6 +6,7 @@ import (
|
||||
"io"
|
||||
"log"
|
||||
"net"
|
||||
"strconv"
|
||||
"strings"
|
||||
|
||||
"github.com/antoniomika/sish/utils"
|
||||
@@ -15,14 +16,17 @@ import (
|
||||
)
|
||||
|
||||
// commandSplitter is the character that terminates a prefix.
|
||||
var commandSplitter = "="
|
||||
const commandSplitter = "="
|
||||
|
||||
// proxyProtoPrefix is used when deciding what proxy protocol
|
||||
// version to use.
|
||||
var proxyProtoPrefix = "proxyproto"
|
||||
const proxyProtoPrefix = "proxyproto"
|
||||
|
||||
// hostHeaderPrefix is the host-header for a specific session.
|
||||
var hostHeaderPrefix = "host-header"
|
||||
const hostHeaderPrefix = "host-header"
|
||||
|
||||
// stripPathPrefix defines whether or not to strip the path (if enabled globally).
|
||||
const stripPathPrefix = "strip-path"
|
||||
|
||||
// handleSession handles the channel when a user requests a session.
|
||||
// This is how we send console messages.
|
||||
@@ -75,6 +79,8 @@ func handleSession(newChannel ssh.NewChannel, sshConn *utils.SSHConnection, stat
|
||||
}()
|
||||
|
||||
go func() {
|
||||
sshConn.StripPath = viper.GetBool("strip-http-path")
|
||||
|
||||
for req := range requests {
|
||||
switch req.Type {
|
||||
case "shell":
|
||||
@@ -89,6 +95,10 @@ func handleSession(newChannel ssh.NewChannel, sshConn *utils.SSHConnection, stat
|
||||
for _, commandFlag := range commandFlags {
|
||||
commandFlagParts := strings.Split(commandFlag, commandSplitter)
|
||||
|
||||
if len(commandFlagParts) < 2 {
|
||||
continue
|
||||
}
|
||||
|
||||
command, param := commandFlagParts[0], commandFlagParts[1]
|
||||
|
||||
switch command {
|
||||
@@ -104,6 +114,18 @@ func handleSession(newChannel ssh.NewChannel, sshConn *utils.SSHConnection, stat
|
||||
sshConn.HostHeader = param
|
||||
sshConn.SendMessage(fmt.Sprintf("Using host header %s for HTTP handlers", sshConn.HostHeader), true)
|
||||
}
|
||||
case stripPathPrefix:
|
||||
if sshConn.StripPath {
|
||||
stripPath, err := strconv.ParseBool(param)
|
||||
|
||||
if err != nil {
|
||||
log.Printf("Unable to detect strip path. Using configuration: %s", err)
|
||||
} else {
|
||||
sshConn.StripPath = stripPath
|
||||
}
|
||||
|
||||
sshConn.SendMessage(fmt.Sprintf("Strip path for HTTP handlers set to: %t", sshConn.StripPath), true)
|
||||
}
|
||||
}
|
||||
}
|
||||
default:
|
||||
|
||||
@@ -75,6 +75,12 @@ func handleHTTPListener(check *channelForwardMsg, stringPort string, requestMess
|
||||
log.Println("Unable to add server to balancer")
|
||||
}
|
||||
|
||||
var userPass string
|
||||
password, _ := pH.HTTPUrl.User.Password()
|
||||
if pH.HTTPUrl.User.Username() != "" || password != "" {
|
||||
userPass = fmt.Sprintf("%s:%s@", pH.HTTPUrl.User.Username(), password)
|
||||
}
|
||||
|
||||
if viper.GetBool("admin-console") || viper.GetBool("service-console") {
|
||||
routeToken := viper.GetString("service-console-token")
|
||||
sendToken := false
|
||||
@@ -108,7 +114,12 @@ func handleHTTPListener(check *channelForwardMsg, stringPort string, requestMess
|
||||
}
|
||||
}
|
||||
|
||||
consoleURL := fmt.Sprintf("%s://%s%s", scheme, pH.HTTPUrl.Host, portString)
|
||||
pathParam := ""
|
||||
if pH.HTTPUrl.Path != "/" {
|
||||
pathParam = pH.HTTPUrl.Path
|
||||
}
|
||||
|
||||
consoleURL := fmt.Sprintf("%s://%s%s%s%s", scheme, userPass, pH.HTTPUrl.Host, portString, pathParam)
|
||||
|
||||
requestMessages += fmt.Sprintf("Service console can be accessed here: %s/_sish/console?x-authorization=%s\r\n", consoleURL, routeToken)
|
||||
}
|
||||
@@ -119,12 +130,6 @@ func handleHTTPListener(check *channelForwardMsg, stringPort string, requestMess
|
||||
httpPortString = fmt.Sprintf(":%d", httpPort)
|
||||
}
|
||||
|
||||
var userPass string
|
||||
password, _ := pH.HTTPUrl.User.Password()
|
||||
if pH.HTTPUrl.User.Username() != "" || password != "" {
|
||||
userPass = fmt.Sprintf("%s:%s@", pH.HTTPUrl.User.Username(), password)
|
||||
}
|
||||
|
||||
requestMessages += fmt.Sprintf("%s: http://%s%s%s%s\r\n", aurora.BgBlue("HTTP"), userPass, pH.HTTPUrl.Host, httpPortString, pH.HTTPUrl.Path)
|
||||
|
||||
log.Printf("%s forwarding started: http://%s%s%s%s -> %s for client: %s\n", aurora.BgBlue("HTTP"), userPass, pH.HTTPUrl.Host, httpPortString, pH.HTTPUrl.Path, listenerHolder.Addr().String(), sshConn.SSHConn.RemoteAddr().String())
|
||||
|
||||
@@ -18,7 +18,7 @@
|
||||
<th scope="row" data-bind="text: startTimePretty"></th>
|
||||
<th scope="row" data-bind="text: requestIP"></th>
|
||||
<th scope="row" data-bind="text: requestMethod"></th>
|
||||
<td data-bind="text: requestUrl.Path"></td>
|
||||
<td data-bind="text: originalRequestURI"></td>
|
||||
<td data-bind="text: responseStatus"></td>
|
||||
<td data-bind="text: requestTime"></td>
|
||||
</tr>
|
||||
@@ -74,6 +74,7 @@
|
||||
this.startTimePretty = requestData.startTimePretty;
|
||||
this.requestMethod = requestData.requestMethod;
|
||||
this.requestUrl = requestData.requestUrl;
|
||||
this.originalRequestURI = requestData.originalRequestURI;
|
||||
this.responseStatus = requestData.responseStatus;
|
||||
this.requestTime = requestData.requestTime;
|
||||
this.requestIP = requestData.requestIP;
|
||||
|
||||
@@ -40,7 +40,7 @@
|
||||
|
||||
<body>
|
||||
<nav class="navbar navbar-expand-md fixed-top navbar-dark bg-primary" role="navigation">
|
||||
<a class="navbar-brand" href="/_sish/console">sish</a>
|
||||
<a class="navbar-brand" href="">sish</a>
|
||||
<button class="navbar-toggler" type="button" data-toggle="collapse" data-target="#navbar" aria-controls="navbar" aria-expanded="false" aria-label="Toggle navigation">
|
||||
<span class="navbar-toggler-icon"></span>
|
||||
</button>
|
||||
|
||||
@@ -69,6 +69,13 @@
|
||||
this.data = routeData;
|
||||
this.type = routeType;
|
||||
this.name = routeName;
|
||||
|
||||
if (this.name.indexOf("/") !== -1) {
|
||||
var routeParts = this.name.split("/");
|
||||
this.name = routeParts[0];
|
||||
this.pathname = `/${routeParts[1]}`;
|
||||
}
|
||||
|
||||
this.disconnectType = disconnectType;
|
||||
|
||||
this.disconnectRoute = function() {
|
||||
@@ -78,7 +85,7 @@
|
||||
}.bind(this);
|
||||
|
||||
this.forwardToConsole = function() {
|
||||
window.location.hostname = this.name;
|
||||
window.location.href = window.location.href.replace(window.location.hostname, this.name).replace(window.location.pathname, `${this.pathname.length > 1 ? this.pathname : ''}${window.location.pathname}`);
|
||||
}.bind(this);
|
||||
};
|
||||
|
||||
|
||||
@@ -22,6 +22,7 @@ type SSHConnection struct {
|
||||
Messages chan string
|
||||
ProxyProto byte
|
||||
HostHeader string
|
||||
StripPath bool
|
||||
Session chan bool
|
||||
CleanupHandler bool
|
||||
SetupLock *sync.Mutex
|
||||
|
||||
@@ -46,7 +46,7 @@ func NewWebConsole() *WebConsole {
|
||||
}
|
||||
|
||||
// HandleRequest handles an incoming web request, handles auth, and then routes it.
|
||||
func (c *WebConsole) HandleRequest(hostname string, hostIsRoot bool, g *gin.Context) {
|
||||
func (c *WebConsole) HandleRequest(proxyUrl string, hostIsRoot bool, g *gin.Context) {
|
||||
userAuthed := false
|
||||
userIsAdmin := false
|
||||
if (viper.GetBool("admin-console") && viper.GetString("admin-console-token") != "") && (g.Request.URL.Query().Get("x-authorization") == viper.GetString("admin-console-token") || g.Request.Header.Get("x-authorization") == viper.GetString("admin-console-token")) {
|
||||
@@ -54,7 +54,7 @@ func (c *WebConsole) HandleRequest(hostname string, hostIsRoot bool, g *gin.Cont
|
||||
userAuthed = true
|
||||
}
|
||||
|
||||
tokenInterface, ok := c.RouteTokens.Load(hostname)
|
||||
tokenInterface, ok := c.RouteTokens.Load(proxyUrl)
|
||||
if ok {
|
||||
routeToken, ok := tokenInterface.(string)
|
||||
if viper.GetBool("service-console") && ok && (g.Request.URL.Query().Get("x-authorization") == routeToken || g.Request.Header.Get("x-authorization") == routeToken) {
|
||||
@@ -63,43 +63,43 @@ func (c *WebConsole) HandleRequest(hostname string, hostIsRoot bool, g *gin.Cont
|
||||
}
|
||||
|
||||
if strings.HasPrefix(g.Request.URL.Path, "/_sish/console/ws") && userAuthed {
|
||||
c.HandleWebSocket(hostname, g)
|
||||
c.HandleWebSocket(proxyUrl, g)
|
||||
return
|
||||
} else if strings.HasPrefix(g.Request.URL.Path, "/_sish/console") && userAuthed {
|
||||
c.HandleTemplate(hostname, hostIsRoot, userIsAdmin, g)
|
||||
c.HandleTemplate(proxyUrl, hostIsRoot, userIsAdmin, g)
|
||||
return
|
||||
} else if strings.HasPrefix(g.Request.URL.Path, "/_sish/api/disconnectclient/") && userIsAdmin {
|
||||
c.HandleDisconnectClient(hostname, g)
|
||||
c.HandleDisconnectClient(proxyUrl, g)
|
||||
return
|
||||
} else if strings.HasPrefix(g.Request.URL.Path, "/_sish/api/disconnectroute/") && userIsAdmin {
|
||||
c.HandleDisconnectRoute(hostname, g)
|
||||
c.HandleDisconnectRoute(proxyUrl, g)
|
||||
return
|
||||
} else if strings.HasPrefix(g.Request.URL.Path, "/_sish/api/clients") && hostIsRoot && userIsAdmin {
|
||||
c.HandleClients(hostname, g)
|
||||
c.HandleClients(proxyUrl, g)
|
||||
return
|
||||
}
|
||||
}
|
||||
|
||||
// HandleTemplate handles rendering the console templates.
|
||||
func (c *WebConsole) HandleTemplate(hostname string, hostIsRoot bool, userIsAdmin bool, g *gin.Context) {
|
||||
func (c *WebConsole) HandleTemplate(proxyUrl string, hostIsRoot bool, userIsAdmin bool, g *gin.Context) {
|
||||
if hostIsRoot && userIsAdmin {
|
||||
g.HTML(http.StatusOK, "routes", nil)
|
||||
return
|
||||
}
|
||||
|
||||
if c.RouteExists(hostname) {
|
||||
if c.RouteExists(proxyUrl) {
|
||||
g.HTML(http.StatusOK, "console", nil)
|
||||
return
|
||||
}
|
||||
|
||||
err := g.AbortWithError(http.StatusNotFound, fmt.Errorf("cannot find connection for host: %s", hostname))
|
||||
err := g.AbortWithError(http.StatusNotFound, fmt.Errorf("cannot find connection for host: %s", proxyUrl))
|
||||
if err != nil {
|
||||
log.Println("Aborting with error", err)
|
||||
}
|
||||
}
|
||||
|
||||
// HandleWebSocket handles the websocket route.
|
||||
func (c *WebConsole) HandleWebSocket(hostname string, g *gin.Context) {
|
||||
func (c *WebConsole) HandleWebSocket(proxyUrl string, g *gin.Context) {
|
||||
conn, err := upgrader.Upgrade(g.Writer, g.Request, nil)
|
||||
if err != nil {
|
||||
log.Println(err)
|
||||
@@ -110,16 +110,16 @@ func (c *WebConsole) HandleWebSocket(hostname string, g *gin.Context) {
|
||||
Conn: conn,
|
||||
Console: c,
|
||||
Send: make(chan []byte),
|
||||
Route: hostname,
|
||||
Route: proxyUrl,
|
||||
}
|
||||
|
||||
c.AddClient(hostname, client)
|
||||
c.AddClient(proxyUrl, client)
|
||||
|
||||
go client.Handle()
|
||||
}
|
||||
|
||||
// HandleDisconnectClient handles the disconnection request for a SSH client.
|
||||
func (c *WebConsole) HandleDisconnectClient(hostname string, g *gin.Context) {
|
||||
func (c *WebConsole) HandleDisconnectClient(proxyUrl string, g *gin.Context) {
|
||||
client := strings.TrimPrefix(g.Request.URL.Path, "/_sish/api/disconnectclient/")
|
||||
|
||||
c.State.SSHConnections.Range(func(key interface{}, val interface{}) bool {
|
||||
@@ -143,7 +143,7 @@ func (c *WebConsole) HandleDisconnectClient(hostname string, g *gin.Context) {
|
||||
}
|
||||
|
||||
// HandleDisconnectRoute handles the disconnection request for a forwarded route.
|
||||
func (c *WebConsole) HandleDisconnectRoute(hostname string, g *gin.Context) {
|
||||
func (c *WebConsole) HandleDisconnectRoute(proxyUrl string, g *gin.Context) {
|
||||
route := strings.Split(strings.TrimPrefix(g.Request.URL.Path, "/_sish/api/disconnectroute/"), "/")
|
||||
encRouteName := route[1]
|
||||
|
||||
@@ -179,7 +179,7 @@ func (c *WebConsole) HandleDisconnectRoute(hostname string, g *gin.Context) {
|
||||
// HandleClients handles returning all connected SSH clients. This will
|
||||
// also go through all of the forwarded connections for the SSH client and
|
||||
// return them.
|
||||
func (c *WebConsole) HandleClients(hostname string, g *gin.Context) {
|
||||
func (c *WebConsole) HandleClients(proxyUrl string, g *gin.Context) {
|
||||
data := map[string]interface{}{
|
||||
"status": true,
|
||||
}
|
||||
@@ -252,23 +252,28 @@ func (c *WebConsole) HandleClients(hostname string, g *gin.Context) {
|
||||
|
||||
httpListeners := map[string]interface{}{}
|
||||
c.State.HTTPListeners.Range(func(key interface{}, val interface{}) bool {
|
||||
httpListener := key.(string)
|
||||
aliasAddress := val.(*HTTPHolder)
|
||||
httpHolder := val.(*HTTPHolder)
|
||||
|
||||
listenerHandlers := []string{}
|
||||
aliasAddress.SSHConnections.Range(func(key interface{}, val interface{}) bool {
|
||||
aliasAddr := key.(string)
|
||||
httpHolder.SSHConnections.Range(func(key interface{}, val interface{}) bool {
|
||||
httpAddr := key.(string)
|
||||
|
||||
for _, v := range listeners {
|
||||
if v == aliasAddr {
|
||||
listenerHandlers = append(listenerHandlers, aliasAddr)
|
||||
if v == httpAddr {
|
||||
listenerHandlers = append(listenerHandlers, httpAddr)
|
||||
}
|
||||
}
|
||||
return true
|
||||
})
|
||||
|
||||
if len(listenerHandlers) > 0 {
|
||||
httpListeners[httpListener] = listenerHandlers
|
||||
var userPass string
|
||||
password, _ := httpHolder.HTTPUrl.User.Password()
|
||||
if httpHolder.HTTPUrl.User.Username() != "" || password != "" {
|
||||
userPass = fmt.Sprintf("%s:%s@", httpHolder.HTTPUrl.User.Username(), password)
|
||||
}
|
||||
|
||||
httpListeners[fmt.Sprintf("%s%s%s", userPass, httpHolder.HTTPUrl.Hostname(), httpHolder.HTTPUrl.Path)] = listenerHandlers
|
||||
}
|
||||
|
||||
return true
|
||||
|
||||
Reference in New Issue
Block a user