partial authentication in ctl websocket

This commit is contained in:
hyung-hwan 2025-03-13 09:43:17 +09:00
parent 8105545e98
commit 4d3fb7db65
3 changed files with 39 additions and 4 deletions

View File

@ -378,6 +378,10 @@ func (auth *HttpAuthConfig) Authenticate(req *http.Request) (int, string) {
} else if rule.Action == HTTP_ACCESS_REJECT {
return http.StatusForbidden, ""
}
// HTTP_ACCESS_AUTH_REQUIRED.
// move on to authentication if enabled. acceped if disabled
break
}
}
}

View File

@ -717,9 +717,35 @@ func (ctl *server_ctl_ws) ServeWebsocket(ws *websocket.Conn) (int, error) {
var s *Server
var wg sync.WaitGroup
var sbsc *ServerEventSubscription
var status_code int
var err error
s = ctl.s
// handle authentication using the first message.
// end this task if authentication fails.
if !ctl.noauth && ctl.s.Cfg.CtlAuth != nil {
var req *http.Request
req = ws.Request()
if req.Header.Get("Authorization") == "" {
var token string
token = req.FormValue("token")
if token != "" {
// websocket doesn't actual have extra headers except a few fixed
// ones. add "Authorization" header from the query paramerer and
// compose a fake header to reuse the same Authentication() function
req.Header.Set("Authorization", fmt.Sprintf("Bearer %s", token))
}
}
status_code, _ = ctl.s.Cfg.CtlAuth.Authenticate(req)
fmt.Printf ("status code %d\n", status_code)
if status_code != http.StatusOK {
goto done
}
}
sbsc, err = s.bulletin.Subscribe("")
if err != nil { goto done }
@ -737,7 +763,7 @@ func (ctl *server_ctl_ws) ServeWebsocket(ws *websocket.Conn) (int, error) {
e, ok = <- c
if ok {
fmt.Printf ("s1: %+v\n", e)
// TODO: handle this part better
err = ctl.send_ws_data(ws, "server", fmt.Sprintf("%d,%d,%d", e.Desc.Conn, e.Desc.Route, e.Desc.Peer))
if err != nil {
// TODO: logging...
@ -756,7 +782,7 @@ ws_recv_loop:
for {
var msg []byte
err = websocket.Message.Receive(ws, &msg)
if err != nil { goto done }
if err != nil { break ws_recv_loop }
if len(msg) > 0 {
var ev json_ssh_ws_event
@ -771,11 +797,12 @@ ws_recv_loop:
}
}
done:
// Ubsubscribe() to break the internal event reception
// goroutine as well as for cleanup
s.bulletin.Unsubscribe(sbsc)
done:
ws.Close()
wg.Wait()
return http.StatusOK, err // TODO: change code...
return http.StatusOK, err
}

View File

@ -595,6 +595,10 @@ func (pxy *server_pxy_ssh_ws) connect_ssh (ctx context.Context, username string,
var out io.Reader // ooutput from target
var err error
// [NOTE]
// There is no authentication implemented for this websocket endpoint
// I suppose authentication should be done at the ssh layer.
// However, this can open doors to DoS attacks.
cc = &ssh.ClientConfig{
User: username,
Auth: []ssh.AuthMethod{ ssh.Password(password) },