mirror of
https://github.com/bolkedebruin/rdpgw.git
synced 2026-03-27 22:46:37 +00:00
Rework transports
This commit is contained in:
82
transport/legacy.go
Normal file
82
transport/legacy.go
Normal file
@@ -0,0 +1,82 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"bufio"
|
||||
"errors"
|
||||
"io"
|
||||
"math/rand"
|
||||
"net"
|
||||
"net/http"
|
||||
"net/http/httputil"
|
||||
"time"
|
||||
)
|
||||
|
||||
const (
|
||||
crlf = "\r\n"
|
||||
HttpOK = "HTTP/1.1 200 OK\r\n"
|
||||
)
|
||||
|
||||
type LegacyPKT struct {
|
||||
Conn net.Conn
|
||||
ChunkedReader io.Reader
|
||||
Writer *bufio.Writer
|
||||
}
|
||||
|
||||
func NewLegacy(w http.ResponseWriter) (*LegacyPKT, error) {
|
||||
hj, ok := w.(http.Hijacker)
|
||||
if ok {
|
||||
conn, rw, err := hj.Hijack()
|
||||
l := &LegacyPKT{
|
||||
Conn: conn,
|
||||
ChunkedReader: httputil.NewChunkedReader(rw.Reader),
|
||||
Writer: rw.Writer,
|
||||
}
|
||||
return l, err
|
||||
}
|
||||
|
||||
return nil, errors.New("cannot hijack connection")
|
||||
}
|
||||
|
||||
func (t *LegacyPKT) ReadPacket() (n int, p []byte, err error){
|
||||
buf := make([]byte, 4096) // bufio.defaultBufSize
|
||||
n, err = t.ChunkedReader.Read(buf)
|
||||
p = make([]byte, n)
|
||||
copy(p, buf)
|
||||
|
||||
return n, p, err
|
||||
}
|
||||
|
||||
func (t *LegacyPKT) WritePacket(b []byte) (n int, err error) {
|
||||
return t.Conn.Write(b)
|
||||
}
|
||||
|
||||
func (t *LegacyPKT) Close() error {
|
||||
return t.Conn.Close()
|
||||
}
|
||||
|
||||
// [MS-TSGU]: Terminal Services Gateway Server Protocol version 39.0
|
||||
// The server sends back the final status code 200 OK, and also a random entity body of limited size (100 bytes).
|
||||
// This enables a reverse proxy to start allowing data from the RDG server to the RDG client. The RDG server does
|
||||
// not specify an entity length in its response. It uses HTTP 1.0 semantics to send the entity body and closes the
|
||||
// connection after the last byte is sent.
|
||||
func (t *LegacyPKT) SendAccept(doSeed bool) {
|
||||
t.Writer.WriteString(HttpOK)
|
||||
t.Writer.WriteString("Date: " + time.Now().Format(time.RFC1123) + crlf)
|
||||
if !doSeed {
|
||||
t.Writer.WriteString("Content-Length: 0" + crlf)
|
||||
}
|
||||
t.Writer.WriteString(crlf)
|
||||
|
||||
if doSeed {
|
||||
seed := make([]byte, 10)
|
||||
rand.Read(seed)
|
||||
// docs say it's a seed but 2019 responds with ab cd * 5
|
||||
t.Writer.Write(seed)
|
||||
}
|
||||
t.Writer.Flush()
|
||||
}
|
||||
|
||||
func (t *LegacyPKT) Drain() {
|
||||
p := make([]byte, 32767)
|
||||
t.Conn.Read(p)
|
||||
}
|
||||
8
transport/transport.go
Normal file
8
transport/transport.go
Normal file
@@ -0,0 +1,8 @@
|
||||
package transport
|
||||
|
||||
type HttpLayer interface {
|
||||
ReadPacket() (n int, p []byte, err error)
|
||||
WritePacket(b []byte) (n int, err error)
|
||||
Close() error
|
||||
}
|
||||
|
||||
42
transport/websocket.go
Normal file
42
transport/websocket.go
Normal file
@@ -0,0 +1,42 @@
|
||||
package transport
|
||||
|
||||
import (
|
||||
"errors"
|
||||
"github.com/gorilla/websocket"
|
||||
)
|
||||
|
||||
type WSPKT struct {
|
||||
Conn *websocket.Conn
|
||||
}
|
||||
|
||||
func NewWS(c *websocket.Conn) (*WSPKT, error) {
|
||||
w := &WSPKT{Conn: c}
|
||||
return w, nil
|
||||
}
|
||||
|
||||
func (t *WSPKT) ReadPacket() (n int, b []byte, err error) {
|
||||
mt, msg, err := t.Conn.ReadMessage()
|
||||
if err != nil {
|
||||
return 0, []byte{0, 0}, err
|
||||
}
|
||||
|
||||
if mt == websocket.BinaryMessage {
|
||||
return len(msg), msg, nil
|
||||
}
|
||||
|
||||
return len(msg), msg, errors.New("not a binary packet")
|
||||
}
|
||||
|
||||
func (t *WSPKT) WritePacket(b []byte) (n int, err error) {
|
||||
err = t.Conn.WriteMessage(websocket.BinaryMessage, b)
|
||||
|
||||
if err != nil {
|
||||
return 0, err
|
||||
}
|
||||
|
||||
return len(b), nil
|
||||
}
|
||||
|
||||
func (t *WSPKT) Close() error {
|
||||
return t.Conn.Close()
|
||||
}
|
||||
Reference in New Issue
Block a user