initial import
Signed-off-by: Vasiliy Tolstov <v.tolstov@selfip.ru>
This commit is contained in:
parent
befe6b8302
commit
f3a0197dd9
1
.gitignore
vendored
1
.gitignore
vendored
@ -12,3 +12,4 @@
|
|||||||
|
|
||||||
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
# Project-local glide cache, RE: https://github.com/Masterminds/glide/issues/736
|
||||||
.glide/
|
.glide/
|
||||||
|
examples/examples
|
||||||
|
17
channeltype_string.go
Normal file
17
channeltype_string.go
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Code generated by "stringer -type=ChannelType"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package spice
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _ChannelType_name = "RedChannelMainRedChannelDisplayRedChannelInputsRedChannelCursorRedChannelPlaybackRedChannelRecord"
|
||||||
|
|
||||||
|
var _ChannelType_index = [...]uint8{0, 14, 31, 47, 63, 81, 97}
|
||||||
|
|
||||||
|
func (i ChannelType) String() string {
|
||||||
|
i -= 1
|
||||||
|
if i >= ChannelType(len(_ChannelType_index)-1) {
|
||||||
|
return fmt.Sprintf("ChannelType(%d)", i+1)
|
||||||
|
}
|
||||||
|
return _ChannelType_name[_ChannelType_index[i]:_ChannelType_index[i+1]]
|
||||||
|
}
|
85
conn.go
Normal file
85
conn.go
Normal file
@ -0,0 +1,85 @@
|
|||||||
|
package spice
|
||||||
|
|
||||||
|
import (
|
||||||
|
"crypto/rand"
|
||||||
|
"crypto/rsa"
|
||||||
|
"crypto/sha1"
|
||||||
|
"crypto/x509"
|
||||||
|
"encoding/binary"
|
||||||
|
"fmt"
|
||||||
|
"net"
|
||||||
|
)
|
||||||
|
|
||||||
|
type Conn struct {
|
||||||
|
conn net.Conn
|
||||||
|
commonCAPS []Compatibily
|
||||||
|
channelCAPS []Compatibily
|
||||||
|
}
|
||||||
|
|
||||||
|
func (c *Conn) Close() error {
|
||||||
|
return c.conn.Close()
|
||||||
|
|
||||||
|
}
|
||||||
|
|
||||||
|
func Connect(conn net.Conn) (*Conn, error) {
|
||||||
|
var req RedLinkMess
|
||||||
|
var res RedLinkReply
|
||||||
|
|
||||||
|
req.Magick = RedMagick
|
||||||
|
req.VersionMajor = RedVersionMajor
|
||||||
|
req.VersionMinor = RedVersionMinor
|
||||||
|
req.Size = 18
|
||||||
|
req.ConnectionID = 0
|
||||||
|
req.ChannelType = RedChannelMain
|
||||||
|
req.ChannelID = 0
|
||||||
|
req.CommonCAPSNum = 0
|
||||||
|
req.ChannelCAPSNum = 0
|
||||||
|
req.CAPSOffset = 0
|
||||||
|
|
||||||
|
if err := binary.Write(conn, binary.LittleEndian, req); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := binary.Read(conn, binary.LittleEndian, &res); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c := &Conn{conn: conn}
|
||||||
|
|
||||||
|
var caps Compatibily
|
||||||
|
|
||||||
|
for i := uint32(0); i < res.CommonCAPSNum; i++ {
|
||||||
|
if err := binary.Read(conn, binary.LittleEndian, &caps); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.commonCAPS = append(c.commonCAPS, caps)
|
||||||
|
}
|
||||||
|
for i := uint32(0); i < res.ChannelCAPSNum; i++ {
|
||||||
|
if err := binary.Read(conn, binary.LittleEndian, &caps); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
c.channelCAPS = append(c.channelCAPS, caps)
|
||||||
|
}
|
||||||
|
cert, err := x509.ParsePKIXPublicKey(res.Pubkey[:])
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
rng := rand.Reader
|
||||||
|
crypted, err := rsa.EncryptOAEP(sha1.New(), rng, cert.(*rsa.PublicKey), []byte("test"), []byte(""))
|
||||||
|
if err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
if err := binary.Write(conn, binary.LittleEndian, crypted); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
|
||||||
|
var result LinkResult
|
||||||
|
if err := binary.Read(conn, binary.LittleEndian, &result); err != nil {
|
||||||
|
return nil, err
|
||||||
|
}
|
||||||
|
if Error(result) != RedErrorOK {
|
||||||
|
return nil, fmt.Errorf("failed to auth, code: %s", Error(result))
|
||||||
|
}
|
||||||
|
|
||||||
|
return c, nil
|
||||||
|
}
|
16
error_string.go
Normal file
16
error_string.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Code generated by "stringer -type=Error"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package spice
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _Error_name = "RedErrorOKRedErrorErrorRedErrorInvalidMagickRedErrorInvalidDataRedErrorVersionMismatchRedErrorNeedSecuredRedErrorNeedUnsecuredRedErrorPermissionDeniedRedErrorBadConnectionIDRedErrorChannelNotAvailable"
|
||||||
|
|
||||||
|
var _Error_index = [...]uint8{0, 10, 23, 44, 63, 86, 105, 126, 150, 173, 200}
|
||||||
|
|
||||||
|
func (i Error) String() string {
|
||||||
|
if i >= Error(len(_Error_index)-1) {
|
||||||
|
return fmt.Sprintf("Error(%d)", i)
|
||||||
|
}
|
||||||
|
return _Error_name[_Error_index[i]:_Error_index[i+1]]
|
||||||
|
}
|
21
examples/main.go
Normal file
21
examples/main.go
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"net"
|
||||||
|
|
||||||
|
spice "github.com/vtolstov/go-spice"
|
||||||
|
)
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
conn, err := net.Dial("tcp", "127.0.0.1:6789")
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
|
||||||
|
sp, err := spice.Connect(conn)
|
||||||
|
if err != nil {
|
||||||
|
panic(err)
|
||||||
|
}
|
||||||
|
defer sp.Close()
|
||||||
|
|
||||||
|
}
|
16
info_string.go
Normal file
16
info_string.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Code generated by "stringer -type=Info"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package spice
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _Info_name = "RedInfoGeneral"
|
||||||
|
|
||||||
|
var _Info_index = [...]uint8{0, 14}
|
||||||
|
|
||||||
|
func (i Info) String() string {
|
||||||
|
if i >= Info(len(_Info_index)-1) {
|
||||||
|
return fmt.Sprintf("Info(%d)", i)
|
||||||
|
}
|
||||||
|
return _Info_name[_Info_index[i]:_Info_index[i+1]]
|
||||||
|
}
|
84
messages.go
Normal file
84
messages.go
Normal file
@ -0,0 +1,84 @@
|
|||||||
|
package spice
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
type RedLinkMess struct {
|
||||||
|
Magick uint32
|
||||||
|
VersionMajor uint32
|
||||||
|
VersionMinor uint32
|
||||||
|
Size uint32
|
||||||
|
ConnectionID uint32
|
||||||
|
ChannelType ChannelType
|
||||||
|
ChannelID uint8
|
||||||
|
CommonCAPSNum uint32
|
||||||
|
ChannelCAPSNum uint32
|
||||||
|
CAPSOffset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *RedLinkMess) String() string {
|
||||||
|
return fmt.Sprintf("%v", msg)
|
||||||
|
}
|
||||||
|
|
||||||
|
type RedLinkReply struct {
|
||||||
|
Magick uint32
|
||||||
|
VersionMajor uint32
|
||||||
|
VersionMinor uint32
|
||||||
|
Size uint32
|
||||||
|
Error Error
|
||||||
|
Pubkey [RedTicketPubkeyBytes]byte
|
||||||
|
CommonCAPSNum uint32
|
||||||
|
ChannelCAPSNum uint32
|
||||||
|
CAPSOffset uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
func (msg *RedLinkReply) String() string {
|
||||||
|
return fmt.Sprintf("Magic:0x%x, Major: %d, Minor: %d, Size: %d, Error: %s Pubkey: %v, CommonCAPSNum: %d, ChannelCAPSNum: %d, CAPSOffset: %d", msg.Magick, msg.VersionMajor, msg.VersionMinor, msg.Size, msg.Error, msg.Pubkey, msg.CommonCAPSNum, msg.ChannelCAPSNum, msg.CAPSOffset)
|
||||||
|
}
|
||||||
|
|
||||||
|
type LinkResult uint32
|
||||||
|
|
||||||
|
type RedDataHeader struct {
|
||||||
|
Serial uint64
|
||||||
|
Type MessageType
|
||||||
|
Size uint32
|
||||||
|
SubList uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type RedSubMessageList struct {
|
||||||
|
Size uint16
|
||||||
|
SubMessages []uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type RedSubMessage struct {
|
||||||
|
Type uint16
|
||||||
|
Size uint32
|
||||||
|
}
|
||||||
|
|
||||||
|
type MessageType uint16
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ MessageType = iota
|
||||||
|
|
||||||
|
RedMigrateMsgType
|
||||||
|
RedMigrateDataMsgType
|
||||||
|
RedSetAckMsgType
|
||||||
|
RedPingMsgType
|
||||||
|
RedWaitForChannelsMsgType
|
||||||
|
RedDisconnectingMsgType
|
||||||
|
RedNotifyMsgType
|
||||||
|
|
||||||
|
RedFirstAvailMessageMsgType = 101
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ MessageType = iota
|
||||||
|
|
||||||
|
RedcAckSyncMsgType
|
||||||
|
RedcAckMsgType
|
||||||
|
RedcPongMsgType
|
||||||
|
RedcMigrateFlushMarkMsgType
|
||||||
|
RedcMigrateDataMsgType
|
||||||
|
RedcDisconnectingMsgType
|
||||||
|
|
||||||
|
RedcFirstAvailMessagemsgType = 101
|
||||||
|
)
|
63
spice.go
Normal file
63
spice.go
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
package spice
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedMagick = 1363428690 // "REDQ" in uint32 LittleEndian
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedVersionMajor uint32 = 0x2
|
||||||
|
RedVersionMinor uint32 = 0x2
|
||||||
|
)
|
||||||
|
|
||||||
|
type Compatibily uint32
|
||||||
|
|
||||||
|
//go:generate stringer -type=ChannelType
|
||||||
|
|
||||||
|
type ChannelType uint8
|
||||||
|
|
||||||
|
const (
|
||||||
|
_ = iota
|
||||||
|
RedChannelMain ChannelType = iota
|
||||||
|
RedChannelDisplay
|
||||||
|
RedChannelInputs
|
||||||
|
RedChannelCursor
|
||||||
|
RedChannelPlayback
|
||||||
|
RedChannelRecord
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=Error
|
||||||
|
|
||||||
|
type Error uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedErrorOK Error = iota
|
||||||
|
RedErrorError
|
||||||
|
RedErrorInvalidMagick
|
||||||
|
RedErrorInvalidData
|
||||||
|
RedErrorVersionMismatch
|
||||||
|
RedErrorNeedSecured
|
||||||
|
RedErrorNeedUnsecured
|
||||||
|
RedErrorPermissionDenied
|
||||||
|
RedErrorBadConnectionID
|
||||||
|
RedErrorChannelNotAvailable
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=Warn
|
||||||
|
|
||||||
|
type Warn uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedWarnGeneral Warn = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
//go:generate stringer -type=Info
|
||||||
|
|
||||||
|
type Info uint32
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedInfoGeneral Info = iota
|
||||||
|
)
|
||||||
|
|
||||||
|
const (
|
||||||
|
RedTicketPubkeyBytes = 162
|
||||||
|
)
|
16
warn_string.go
Normal file
16
warn_string.go
Normal file
@ -0,0 +1,16 @@
|
|||||||
|
// Code generated by "stringer -type=Warn"; DO NOT EDIT.
|
||||||
|
|
||||||
|
package spice
|
||||||
|
|
||||||
|
import "fmt"
|
||||||
|
|
||||||
|
const _Warn_name = "RedWarnGeneral"
|
||||||
|
|
||||||
|
var _Warn_index = [...]uint8{0, 14}
|
||||||
|
|
||||||
|
func (i Warn) String() string {
|
||||||
|
if i >= Warn(len(_Warn_index)-1) {
|
||||||
|
return fmt.Sprintf("Warn(%d)", i)
|
||||||
|
}
|
||||||
|
return _Warn_name[_Warn_index[i]:_Warn_index[i+1]]
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user