174 lines
5.3 KiB
Go
174 lines
5.3 KiB
Go
package client
|
|
|
|
import (
|
|
"fmt"
|
|
"time"
|
|
|
|
"forge.redroom.link/yves/meowlib"
|
|
"github.com/google/uuid"
|
|
"google.golang.org/protobuf/proto"
|
|
)
|
|
|
|
type InternalServer struct {
|
|
ServerData meowlib.Server `json:"server_data,omitempty"`
|
|
Presence bool `json:"presence,omitempty"`
|
|
LastCheck time.Time `json:"last_check,omitempty"`
|
|
Uptime time.Duration `json:"uptime,omitempty"`
|
|
Login string `json:"login,omitempty"`
|
|
Password string `json:"password,omitempty"`
|
|
Me meowlib.KeyPair `json:"me,omitempty"`
|
|
Country string `json:"country,omitempty"`
|
|
AllowedDelay int `json:"allowed_delay,omitempty"`
|
|
}
|
|
|
|
type InternalServerList struct {
|
|
Name string
|
|
Servers []InternalServer
|
|
}
|
|
|
|
func InternalServerFromUrl(url string) *InternalServer {
|
|
var is InternalServer
|
|
is.ServerData.Url = url
|
|
return &is
|
|
}
|
|
|
|
func InternalServerFromServer(server *meowlib.Server) *InternalServer {
|
|
var is InternalServer
|
|
is.ServerData = *server
|
|
is.Me = meowlib.NewKeyPair()
|
|
return &is
|
|
}
|
|
|
|
func (sl *InternalServerList) AddUrls(urls []string) {
|
|
for _, url := range urls {
|
|
sl.Servers = append(sl.Servers, *InternalServerFromUrl(url))
|
|
}
|
|
}
|
|
|
|
// AsymEncryptMessage prepares a message to send to a specific internal server
|
|
func (ints *InternalServer) AsymEncryptMessage(Message []byte) (*meowlib.EncryptedMessage, error) {
|
|
var enc *meowlib.EncryptedMessage
|
|
enc, err := meowlib.AsymEncryptAndSign(ints.ServerData.PublicKey, ints.Me.Private, Message)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
return nil, err
|
|
}
|
|
return enc, err
|
|
}
|
|
|
|
// AsymDecryptMessage reads a message from a specific internal server
|
|
func (ints *InternalServer) AsymDecryptMessage(Message []byte, Signature []byte) (DecryptedMessage []byte, err error) {
|
|
DecryptedMessage, err = meowlib.AsymDecryptAndCheck(ints.Me.Private, ints.ServerData.PublicKey, Message, Signature)
|
|
if err != nil {
|
|
fmt.Println(err.Error())
|
|
return nil, err
|
|
}
|
|
return DecryptedMessage, err
|
|
}
|
|
|
|
// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array
|
|
func (ints *InternalServer) BuildToServerMessageFromUserMessage(usermsg *meowlib.PackedUserMessage) *meowlib.ToServerMessage {
|
|
var msg meowlib.ToServerMessage
|
|
msg.Uuid = uuid.New().String()
|
|
msg.Type = "1"
|
|
msg.From = ints.Me.Public
|
|
msg.Messages = append(msg.Messages, usermsg)
|
|
return &msg
|
|
}
|
|
|
|
// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array
|
|
func (ints *InternalServer) BuildMessageSendingMessage(usermsg *meowlib.PackedUserMessage) ([]byte, error) {
|
|
msg := ints.BuildToServerMessageFromUserMessage(usermsg)
|
|
out, err := proto.Marshal(msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array
|
|
func (ints *InternalServer) BuildMessageRequestMessage(lookupKeys []string) ([]byte, error) {
|
|
var msg meowlib.ToServerMessage
|
|
msg.Uuid = uuid.New().String()
|
|
msg.Type = "1"
|
|
msg.From = ints.Me.Public
|
|
|
|
out, err := proto.Marshal(&msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
// Creates a basic message to server from a single packed user message and returns it as protobuf serialized byte array
|
|
func (ints *InternalServer) BuildToServerMessageInvitation(invitation *meowlib.ContactCard, password string, timeout int, urllen int) (*meowlib.ToServerMessage, error) {
|
|
var msg meowlib.ToServerMessage
|
|
var inv meowlib.Invitation
|
|
payload, err := invitation.Compress()
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
msg.Type = "1"
|
|
msg.From = ints.Me.Public
|
|
inv.Password = password
|
|
inv.Timeout = int32(timeout)
|
|
inv.Idlen = int32(urllen)
|
|
inv.Payload = payload
|
|
msg.Invitation = &inv
|
|
return &msg, nil
|
|
}
|
|
|
|
func (ints *InternalServer) PackServerMessage(payload []byte, signature []byte) (protoPackedMessage []byte, err error) {
|
|
var msg meowlib.PackedServerMessage
|
|
msg.From = ints.Me.Public
|
|
msg.Payload = payload
|
|
msg.Signature = signature
|
|
out, err := proto.Marshal(&msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return out, nil
|
|
}
|
|
|
|
func (ints *InternalServer) UnPackServerMessage(protoPackedMessage []byte) (payload []byte, signature []byte, err error) {
|
|
msg := &meowlib.PackedServerMessage{}
|
|
if err := proto.Unmarshal(protoPackedMessage, msg); err != nil {
|
|
return nil, nil, err
|
|
}
|
|
return msg.Payload, msg.Signature, nil
|
|
}
|
|
|
|
func (srv *InternalServer) ProcessOutboundMessage(toServerMessage *meowlib.ToServerMessage) ([]byte, error) {
|
|
byteToServerMessage, err := proto.Marshal(toServerMessage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Encrypting it
|
|
encToServer, err := srv.AsymEncryptMessage(byteToServerMessage)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
// Packing it
|
|
protoPackedServerMsg, err := srv.PackServerMessage(encToServer.Data, encToServer.Signature)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
return protoPackedServerMsg, nil
|
|
}
|
|
|
|
func (srv *InternalServer) ProcessInboundServerResponse(msg []byte) (*meowlib.FromServerMessage, error) {
|
|
fsmsg := &meowlib.FromServerMessage{}
|
|
payload, signature, err := srv.UnPackServerMessage(msg)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
decrypted, err := srv.AsymDecryptMessage(payload, signature)
|
|
if err != nil {
|
|
return nil, err
|
|
}
|
|
if err := proto.Unmarshal(decrypted, fsmsg); err != nil {
|
|
return nil, err
|
|
}
|
|
return fsmsg, nil
|
|
}
|