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
|
||||
.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…
x
Reference in New Issue
Block a user