croc/src/models.go

202 lines
5.0 KiB
Go

package croc
import (
"encoding/json"
"net"
"sync"
"time"
"github.com/briandowns/spinner"
"github.com/gorilla/websocket"
"github.com/schollz/pake"
"github.com/schollz/progressbar/v2"
)
const (
// maximum buffer size for initial TCP communication
bufferSize = 1024
)
type Croc struct {
// Options for all
Debug bool
// Options for relay
ServerPort string
CurveType string
// Options for connecting to server
TcpPorts []string
WebsocketAddress string
Timeout time.Duration
LocalOnly bool
NoLocal bool
// Options for file transfering
UseEncryption bool
UseCompression bool
AllowLocalDiscovery bool
Yes bool
Stdout bool
// private variables
// localIP address
localIP string
// is using local relay
isLocal bool
// rs relay state is only for the relay
rs relayState
// cs keeps the client state
cs clientState
bar *progressbar.ProgressBar
// crocFile is the name of the file that is prepared to sent
crocFile string
// crocFileEncrypted is the name of the encrypted file
crocFileEncrypted string
// bothConnected
bothConnected bool
// cleanupTime tells processes to close up
cleanupTime bool
normalFinish bool
}
// Init will initialize the croc relay
func Init() (c *Croc) {
c = new(Croc)
c.TcpPorts = []string{"27030", "27031", "27032", "27033"}
c.Timeout = 3 * time.Hour
c.UseEncryption = true
c.UseCompression = true
c.AllowLocalDiscovery = true
c.CurveType = "p521"
c.WebsocketAddress = "wss://croc3.schollz.com"
c.ServerPort = "8130"
c.rs.Lock()
c.rs.channel = make(map[string]*channelData)
c.rs.ips = make(map[string]string)
c.cs.channel = new(channelData)
c.cs.channel.spin = spinner.New(spinner.CharSets[9], 100*time.Millisecond)
c.rs.Unlock()
c.localIP = getLocalIP()
return
}
func (c *Croc) SetDebug(debug bool) {
if debug {
SetLogLevel("debug")
} else {
SetLogLevel("error")
}
}
type relayState struct {
ips map[string]string
channel map[string]*channelData
sync.RWMutex
}
type clientState struct {
channel *channelData
sync.RWMutex
}
type FileMetaData struct {
Name string
Size int
Hash string
IsDir bool
IsEncrypted bool
IsCompressed bool
DeleteAfterSending bool
}
type channelData struct {
// Relay actions
// Open set to true when trying to open
Open bool `json:"open"`
// Update set to true when updating
Update bool `json:"update"`
// Close set to true when closing:
Close bool `json:"close"`
// Public
// Channel is the name of the channel
Channel string `json:"channel,omitempty"`
// Pake contains the information for
// generating the session key over an insecure channel
Pake *pake.Pake `json:"pake"`
// TransferReady is set by the relaying when both parties have connected
// with their credentials
TransferReady bool `json:"transfer_ready"`
// Ports returns which TCP ports to connect to
Ports []string `json:"ports"`
// Curve is the type of elliptic curve to use
Curve string `json:"curve"`
// FileMetaData is sent after confirmed
EncryptedFileMetaData encryption `json:"encrypted_meta_data"`
// FileReceived specifies that everything was done right
FileReceived bool `json:"file_received"`
// ReadyToRead means that the recipient is ready to read
ReadyToRead bool `json:"ready_to_read"`
// Error is sent if there is an error
Error string `json:"error"`
// Addresses of the sender and recipient, as determined by the relay
Addresses [2]string `json:"addresses"`
// Sent on initialization, specific to a single user
// UUID is sent out only to one person at a time
UUID string `json:"uuid"`
// Role is the role the person will play
Role int `json:"role"`
// Private
// client parameters
// codePhrase uses the first 3 characters to establish a channel, and the rest
// to form the passphrase
codePhrase string
// passPhrase is used to generate a session key
passPhrase string
// sessionKey
sessionKey []byte
// isReady specifies whether the current client
isReady bool
fileReady bool
fileMetaData FileMetaData
notSentMetaData bool
finishedHappy bool
filesReady bool
startTransfer time.Time
transferTime time.Duration
// spin is the spinner for the recipient
spin *spinner.Spinner
waitingForConnection bool
waitingForOther bool
waitingForPake bool
waitingForRecipient bool
// ws is the connection that the client has to the relay
ws *websocket.Conn
// relay parameters
// isopen determine whether or not the channel has been opened
isopen bool
// store a UUID of the parties to prevent other parties from joining
uuids [2]string // 0 is sender, 1 is recipient
// connection information is stored when the clients do connect over TCP
connection map[string][2]net.Conn
// websocket connections
websocketConn [2]*websocket.Conn
// startTime is the time that the channel was opened
startTime time.Time
}
func (cd channelData) String2() string {
cdb, _ := json.Marshal(cd)
return string(cdb)
}