Files
ShotRDP/grdp/protocol/rfb/rfb.go

471 lines
11 KiB
Go

// rfb.go
package rfb
import (
"bytes"
"crypto/des"
"encoding/hex"
"errors"
"fmt"
"io"
"log"
"net"
"github.com/lunixbochs/struc"
"ShotRDP/grdp/core"
"ShotRDP/grdp/emission"
"ShotRDP/grdp/glog"
)
// ProtocolVersion
const (
RFB003003 = "RFB 003.003\n"
RFB003007 = "RFB 003.007\n"
RFB003008 = "RFB 003.008\n"
)
// SecurityType
const (
SEC_INVALID uint8 = 0
SEC_NONE uint8 = 1
SEC_VNC uint8 = 2
)
type RFBConn struct {
emission.Emitter
// The Socket connection to the client
Conn net.Conn
s *ServerInit
NbRect uint16
BitRect *BitRect
Password string
}
func NewRFBConn(s net.Conn, passwd string) *RFBConn {
fc := &RFBConn{
Emitter: *emission.NewEmitter(),
Conn: s,
BitRect: new(BitRect),
Password: passwd,
}
core.StartReadBytes(12, fc, fc.recvProtocolVersion)
return fc
}
func (fc *RFBConn) Read(b []byte) (n int, err error) {
return fc.Conn.Read(b)
}
func (fc *RFBConn) Write(data []byte) (n int, err error) {
buff := &bytes.Buffer{}
buff.Write(data)
return fc.Conn.Write(buff.Bytes())
}
func (fc *RFBConn) Close() error {
return fc.Conn.Close()
}
func (fc *RFBConn) recvProtocolVersion(s []byte, err error) {
version := string(s)
glog.Debug("RFBConn recvProtocolVersion", version, err)
if err != nil {
fc.Emit("error", err)
return
}
fc.Emit("data", version)
if version == RFB003003 {
fc.Emit("error", fmt.Errorf("%s", "Not Support RFB003003"))
return
//core.StartReadBytes(4, fc, fc.recvSecurityServer)
} else {
core.StartReadBytes(1, fc, fc.checkSecurityList)
}
}
func (fc *RFBConn) checkSecurityList(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt8(r)
glog.Debug("RFBConn recvSecurityList", result, err)
core.StartReadBytes(int(result), fc, fc.recvSecurityList)
}
func (fc *RFBConn) recvSecurityList(s []byte, err error) {
r := bytes.NewReader(s)
secLevel := SEC_VNC
for r.Len() > 0 {
result, _ := core.ReadUInt8(r)
if result == SEC_NONE || result == SEC_VNC {
secLevel = result
break
}
}
glog.Debug("RFBConn recvSecurityList", secLevel, err)
buff := &bytes.Buffer{}
core.WriteUInt8(secLevel, buff)
fc.Write(buff.Bytes())
if secLevel == SEC_VNC {
core.StartReadBytes(16, fc, fc.recvVNCChallenge)
} else {
core.StartReadBytes(4, fc, fc.recvSecurityResult)
}
}
func fixDesKeyByte(val byte) byte {
var newval byte = 0
for i := 0; i < 8; i++ {
newval <<= 1
newval += (val & 1)
val >>= 1
}
return newval
}
// fixDesKey will make sure that exactly 8 bytes is used either by truncating or padding with nulls
// The bytes are then bit mirrored and returned
func fixDesKey(key []byte) []byte {
tmp := key
buf := make([]byte, 8)
if len(tmp) <= 8 {
copy(buf, tmp)
} else {
copy(buf, tmp[:8])
}
for i := 0; i < 8; i++ {
buf[i] = fixDesKeyByte(buf[i])
}
return buf
}
func (fc *RFBConn) recvVNCChallenge(s []byte, err error) {
glog.Debug("RFBConn recvVNCChallenge", hex.EncodeToString(s), len(s), err)
key := core.UnicodeEncode(fc.Password)
bk, err := des.NewCipher(fixDesKey(key))
if err != nil {
log.Printf("Error generating authentication cipher: %s\n", err.Error())
return
}
result := make([]byte, 16)
bk.Encrypt(result, s) //Encrypt first 8 bytes
bk.Encrypt(result[8:], s[8:])
if err != nil {
fmt.Println(err)
}
fmt.Println(string(result))
fc.Write(result)
core.StartReadBytes(4, fc, fc.recvSecurityResult)
}
func (fc *RFBConn) recvSecurityResult(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt32BE(r)
glog.Debug("RFBConn recvSecurityResult", result, err)
if result == 1 {
fc.Emit("error", fmt.Errorf("%s", "Authentification failed"))
return
}
buff := &bytes.Buffer{}
core.WriteUInt8(0, buff) //share
fc.Write(buff.Bytes())
core.StartReadBytes(20, fc, fc.recvServerInit)
}
type ServerInit struct {
Width uint16 `struc:"little"`
Height uint16 `struc:"little"`
PixelFormat *PixelFormat `struc:"little"`
}
func (fc *RFBConn) recvServerInit(s []byte, err error) {
glog.Debug("RFBConn recvServerInit", len(s), err)
r := bytes.NewReader(s)
si := &ServerInit{}
si.Width, err = core.ReadUint16BE(r)
si.Height, err = core.ReadUint16BE(r)
si.PixelFormat = ReadPixelFormat(r)
glog.Infof("serverInit:%+v, %+v", si, si.PixelFormat)
fc.s = si
fc.BitRect.Pf = si.PixelFormat
core.StartReadBytes(4, fc, fc.checkServerName)
}
func (fc *RFBConn) checkServerName(s []byte, err error) {
r := bytes.NewReader(s)
result, _ := core.ReadUInt32BE(r)
glog.Debug("RFBConn recvSecurityList", result, err)
core.StartReadBytes(int(result), fc, fc.recvServerName)
}
func (fc *RFBConn) recvServerName(s []byte, err error) {
glog.Debug("RFBConn recvServerName", string(s), err)
//fc.sendPixelFormat()
fc.sendSetEncoding()
fc.sendFramebufferUpdateRequest(0, 0, 0, fc.s.Width, fc.s.Height)
fc.Emit("ready")
core.StartReadBytes(1, fc, fc.recvServerOrder)
}
func (fc *RFBConn) sendPixelFormat() {
glog.Debug("sendPixelFormat")
buff := &bytes.Buffer{}
core.WriteUInt8(0, buff)
core.WriteUInt16BE(0, buff)
core.WriteUInt8(0, buff)
err := struc.Pack(buff, NewPixelFormat())
if err != nil {
fc.Emit("error", err)
return
}
fc.Write(buff.Bytes())
}
func (fc *RFBConn) sendSetEncoding() {
glog.Debug("sendSetEncoding")
buff := &bytes.Buffer{}
core.WriteUInt8(2, buff)
core.WriteUInt8(0, buff)
core.WriteUInt16BE(1, buff)
core.WriteUInt32BE(0, buff)
fc.Write(buff.Bytes())
}
type FrameBufferUpdateRequest struct {
Incremental uint8
X uint16
Y uint16
Width uint16
Height uint16
}
func (fc *RFBConn) sendFramebufferUpdateRequest(Incremental uint8,
X uint16,
Y uint16,
Width uint16,
Height uint16) {
glog.Debug("sendFramebufferUpdateRequest")
buff := &bytes.Buffer{}
core.WriteUInt8(3, buff)
core.WriteUInt8(Incremental, buff)
core.WriteUInt16BE(X, buff)
core.WriteUInt16BE(Y, buff)
core.WriteUInt16BE(Width, buff)
core.WriteUInt16BE(Height, buff)
fc.Write(buff.Bytes())
}
func (fc *RFBConn) recvServerOrder(s []byte, err error) {
glog.Debug("RFBConn recvServerOrder", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
packetType, _ := core.ReadUInt8(r)
switch packetType {
case 0:
core.StartReadBytes(3, fc, fc.recvFrameBufferUpdateHeader)
case 2:
//TODO
case 3:
core.StartReadBytes(7, fc, fc.recvServerCutTextHeader)
default:
glog.Errorf("Unknown message type %s", packetType)
}
}
type BitRect struct {
Rects []Rectangles
Pf *PixelFormat
}
type Rectangles struct {
Rect *Rectangle
Data []byte
}
func (fc *RFBConn) recvFrameBufferUpdateHeader(s []byte, err error) {
glog.Debug("RFBConn recvFrameBufferUpdateHeader", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
core.ReadUInt8(r)
NbRect, _ := core.ReadUint16BE(r)
fc.NbRect = NbRect
fc.BitRect.Rects = make([]Rectangles, fc.NbRect)
if NbRect == 0 {
return
}
glog.Info("NbRect:", NbRect)
core.StartReadBytes(12, fc, fc.recvRectHeader)
}
type Rectangle struct {
X uint16 `struc:"little"`
Y uint16 `struc:"little"`
Width uint16 `struc:"little"`
Height uint16 `struc:"little"`
Encoding uint32 `struc:"little"`
}
func (fc *RFBConn) recvRectHeader(s []byte, err error) {
glog.Debug("RFBConn recvRectHeader", hex.EncodeToString(s), err)
r := bytes.NewReader(s)
x, err := core.ReadUint16BE(r)
y, err := core.ReadUint16BE(r)
w, err := core.ReadUint16BE(r)
h, err := core.ReadUint16BE(r)
e, err := core.ReadUInt32BE(r)
rect := &Rectangle{x, y, w, h, e}
fc.BitRect.Rects[fc.NbRect-1].Rect = rect
glog.Infof("rect:%+v, len=%d", rect, int(rect.Width)*int(rect.Height)*4)
core.StartReadBytes(int(rect.Width)*int(rect.Height)*4, fc, fc.recvRectBody)
}
func (fc *RFBConn) recvRectBody(s []byte, err error) {
glog.Debug("RFBConn recvRectBody", hex.EncodeToString(s), err)
fc.BitRect.Rects[fc.NbRect-1].Data = s
fc.NbRect--
glog.Info("fc.NbRect:", fc.NbRect)
if fc.NbRect == 0 {
fc.Emit("bitmap", fc.BitRect)
fc.sendFramebufferUpdateRequest(1, 0, 0, fc.s.Width, fc.s.Height)
core.StartReadBytes(1, fc, fc.recvServerOrder)
} else {
core.StartReadBytes(12, fc, fc.recvRectHeader)
}
}
type ServerCutTextHeader struct {
Padding [3]byte `struc:"little"`
Size uint32 `struc:"little"`
}
func (fc *RFBConn) recvServerCutTextHeader(s []byte, err error) {
glog.Debug("RFBConn recvServerCutTextHeader", string(s), err)
r := bytes.NewReader(s)
header := &ServerCutTextHeader{}
err = struc.Unpack(r, header)
if err != nil {
fc.Emit("error", err)
return
}
core.StartReadBytes(int(header.Size), fc, fc.recvServerCutTextBody)
}
func (fc *RFBConn) recvServerCutTextBody(s []byte, err error) {
glog.Debug("RFBConn recvServerCutTextBody", string(s), err)
fc.Emit("CutText", s)
core.StartReadBytes(1, fc, fc.recvServerOrder)
}
type PixelFormat struct {
BitsPerPixel uint8 `struc:"little"`
Depth uint8 `struc:"little"`
BigEndianFlag uint8 `struc:"little"`
TrueColorFlag uint8 `struc:"little"`
RedMax uint16 `struc:"little"`
GreenMax uint16 `struc:"little"`
BlueMax uint16 `struc:"little"`
RedShift uint8 `struc:"little"`
GreenShift uint8 `struc:"little"`
BlueShift uint8 `struc:"little"`
Padding uint16 `struc:"little"`
Padding1 uint8 `struc:"little"`
}
func ReadPixelFormat(r io.Reader) *PixelFormat {
p := NewPixelFormat()
p.BitsPerPixel, _ = core.ReadUInt8(r)
p.Depth, _ = core.ReadUInt8(r)
p.BigEndianFlag, _ = core.ReadUInt8(r)
p.TrueColorFlag, _ = core.ReadUInt8(r)
p.RedMax, _ = core.ReadUint16BE(r)
p.GreenMax, _ = core.ReadUint16BE(r)
p.BlueMax, _ = core.ReadUint16BE(r)
p.RedShift, _ = core.ReadUInt8(r)
p.GreenShift, _ = core.ReadUInt8(r)
p.BlueShift, _ = core.ReadUInt8(r)
p.Padding, _ = core.ReadUint16BE(r)
p.Padding1, _ = core.ReadUInt8(r)
return p
}
func NewPixelFormat() *PixelFormat {
return &PixelFormat{
32, 24, 0, 1, 65280, 65280, 65280, 16, 8, 0, 0, 0,
}
}
type RFB struct {
core.Transport
Version string
SecurityLevel uint8
ServerName string
PixelFormat *PixelFormat
NbRect int
CurrentRect *Rectangle
}
func NewRFB(t core.Transport) *RFB {
fb := &RFB{t, RFB003008, SEC_INVALID, "", NewPixelFormat(), 0, &Rectangle{}}
return fb
}
func (fb *RFB) Connect() error {
if fb.Transport == nil {
return errors.New("no transport")
}
fb.Once("data", fb.recvProtocolVersion)
return nil
}
func (fb *RFB) recvProtocolVersion(version string) {
if version != RFB003003 || version != RFB003007 || version != RFB003008 {
version = RFB003008
}
glog.Infof("version:%s", version)
b := &bytes.Buffer{}
b.WriteString(version)
fb.Write(b.Bytes())
}
type KeyEvent struct {
DownFlag uint8 `struc:"little"`
Padding uint16 `struc:"little"`
Key uint32 `struc:"little"`
}
func (fb *RFB) SendKeyEvent(k *KeyEvent) {
b := &bytes.Buffer{}
core.WriteUInt8(4, b)
core.WriteUInt8(k.DownFlag, b)
core.WriteUInt16BE(k.Padding, b)
core.WriteUInt32BE(k.Key, b)
fmt.Println(b.Bytes())
fb.Write(b.Bytes())
}
type PointerEvent struct {
Mask uint8 `struc:"little"`
XPos uint16 `struc:"little"`
YPos uint16 `struc:"little"`
}
func (fb *RFB) SendPointEvent(p *PointerEvent) {
b := &bytes.Buffer{}
core.WriteUInt8(5, b)
core.WriteUInt8(p.Mask, b)
core.WriteUInt16BE(p.XPos, b)
core.WriteUInt16BE(p.YPos, b)
fmt.Println(b.Bytes())
fb.Write(b.Bytes())
}
type ClientCutText struct {
Padding uint16 `struc:"little"`
Padding1 uint8 `struc:"little"`
Size uint32 `struc:"little"`
Message string `struc:"little"`
}
func (fb *RFB) SendClientCutText(t *ClientCutText) {
b := &bytes.Buffer{}
core.WriteUInt8(6, b)
struc.Pack(b, t)
fb.Write(b.Bytes())
}