You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
59 lines
2.0 KiB
59 lines
2.0 KiB
|
2 months ago
|
package directstream
|
||
|
|
|
||
|
|
import (
|
||
|
|
"errors"
|
||
|
|
"fmt"
|
||
|
|
"net"
|
||
|
|
"strings"
|
||
|
|
"time"
|
||
|
|
)
|
||
|
|
|
||
|
|
const (
|
||
|
|
SessionEventConnected = "connected"
|
||
|
|
SessionEventDisconnected = "disconnected"
|
||
|
|
)
|
||
|
|
|
||
|
|
// SessionEvent is emitted by tera-sessiond only after a ticket-bound Direct
|
||
|
|
// Mode attachment has been authenticated. Source is the normalized client IP
|
||
|
|
// supplied by the trusted same-origin gateway.
|
||
|
|
type SessionEvent struct {
|
||
|
|
Type string `json:"type"`
|
||
|
|
Source string `json:"source"`
|
||
|
|
Timestamp time.Time `json:"timestamp"`
|
||
|
|
}
|
||
|
|
|
||
|
|
func validateSessionEvent(event SessionEvent) error {
|
||
|
|
if event.Type != SessionEventConnected && event.Type != SessionEventDisconnected {
|
||
|
|
return errors.New("direct stream session event type is invalid")
|
||
|
|
}
|
||
|
|
if net.ParseIP(strings.TrimSpace(event.Source)) == nil {
|
||
|
|
return errors.New("direct stream session event source must be an IP address")
|
||
|
|
}
|
||
|
|
if event.Timestamp.IsZero() {
|
||
|
|
return errors.New("direct stream session event timestamp is required")
|
||
|
|
}
|
||
|
|
return nil
|
||
|
|
}
|
||
|
|
|
||
|
|
// SessionEventMessage is shared by the WebSocket welcome frame and the
|
||
|
|
// authoritative per-port log writer so the operator sees the same identity
|
||
|
|
// data that is retained for the channel.
|
||
|
|
func SessionEventMessage(claims TicketClaims, event SessionEvent) string {
|
||
|
|
timestamp := event.Timestamp.UTC().Format(time.RFC3339)
|
||
|
|
if event.Type == SessionEventConnected {
|
||
|
|
return fmt.Sprintf(
|
||
|
|
"Welcome to TERA CORA-X48 PRO K\nConnected from: %s\nSerial channel: %s\nUser: %s\nAccess: %s\nSession: %s\nConnected at: %s",
|
||
|
|
event.Source, claims.Channel, claims.Actor, claims.Access, claims.SessionID, timestamp,
|
||
|
|
)
|
||
|
|
}
|
||
|
|
return fmt.Sprintf(
|
||
|
|
"TERA CORA-X48 PRO K session disconnected\nConnected from: %s\nSerial channel: %s\nUser: %s\nAccess: %s\nSession: %s\nDisconnected at: %s",
|
||
|
|
event.Source, claims.Channel, claims.Actor, claims.Access, claims.SessionID, timestamp,
|
||
|
|
)
|
||
|
|
}
|
||
|
|
|
||
|
|
func welcomeFrame(claims TicketClaims, event SessionEvent) []byte {
|
||
|
|
message := strings.ReplaceAll(SessionEventMessage(claims, event), "\n", "\r\n")
|
||
|
|
return []byte("\r\n" + message + "\r\n\r\n")
|
||
|
|
}
|