0
0
Fork 0
mirror of https://github.com/schollz/croc.git synced 2025-10-11 13:21:00 +02:00

reorganized files

This commit is contained in:
Zack Scholl 2018-06-30 06:03:15 -07:00
parent 59fc697b4f
commit 0ab25185d3
4 changed files with 179 additions and 141 deletions

View file

@ -8,8 +8,6 @@ import (
"net/url"
"os"
"os/signal"
"path"
"path/filepath"
"strconv"
"strings"
"sync"
@ -19,7 +17,6 @@ import (
"github.com/gorilla/websocket"
"github.com/pkg/errors"
"github.com/schollz/croc/src/pake"
tarinator "github.com/schollz/tarinator-go"
)
func (c *Croc) client(role int, codePhrase string, fname ...string) (err error) {
@ -231,8 +228,9 @@ func (c *Croc) processState(ws *websocket.Conn, cd channelData) (err error) {
c.cs.channel.Update = false
}
}
if c.cs.channel.Role == 0 && c.cs.channel.Pake.IsVerified() && !c.cs.channel.notSentMetaData {
if c.cs.channel.Role == 0 && c.cs.channel.Pake.IsVerified() && !c.cs.channel.notSentMetaData && !c.cs.channel.filesReady {
go c.getFilesReady(ws)
c.cs.channel.filesReady = true
}
// process the client state
@ -267,74 +265,6 @@ func (c *Croc) processState(ws *websocket.Conn, cd channelData) (err error) {
return
}
func (c *Croc) getFilesReady(ws *websocket.Conn) (err error) {
c.cs.Lock()
defer c.cs.Unlock()
c.cs.channel.notSentMetaData = true
// send metadata
// wait until data is ready
for {
if c.cs.channel.fileMetaData.Name != "" {
break
}
c.cs.Unlock()
time.Sleep(10 * time.Millisecond)
c.cs.Lock()
}
// get passphrase
var passphrase []byte
passphrase, err = c.cs.channel.Pake.SessionKey()
if err != nil {
return
}
// encrypt file data
err = encryptFile(path.Join(c.cs.channel.fileMetaData.Path, c.cs.channel.fileMetaData.Name), c.cs.channel.fileMetaData.Name+".enc", passphrase)
if err != nil {
return
}
c.cs.channel.fileMetaData.IsEncrypted = true
// split into pieces to send
if err = splitFile(c.cs.channel.fileMetaData.Name+".enc", len(c.cs.channel.Ports)); err != nil {
return
}
// remove the file now since we still have pieces
if err = os.Remove(c.cs.channel.fileMetaData.Name + ".enc"); err != nil {
return
}
// remove compressed archive
if c.cs.channel.fileMetaData.IsDir {
log.Debug("removing archive: " + c.cs.channel.fileMetaData.Name)
if err = os.Remove(c.cs.channel.fileMetaData.Name); err != nil {
return
}
}
// encrypt meta data
var metaDataBytes []byte
metaDataBytes, err = json.Marshal(c.cs.channel.fileMetaData)
if err != nil {
return
}
c.cs.channel.EncryptedFileMetaData = encrypt(metaDataBytes, passphrase)
c.cs.channel.Update = true
log.Debugf("updating channel")
errWrite := ws.WriteJSON(c.cs.channel)
if errWrite != nil {
log.Error(errWrite)
}
c.cs.channel.Update = false
go func() {
// encrypt the files
// TODO
c.cs.Lock()
c.cs.channel.fileReady = true
c.cs.Unlock()
}()
return
}
func (c *Croc) spawnConnections(ws *websocket.Conn, role int) (err error) {
err = c.dialUp(ws)
if err == nil {
@ -365,8 +295,19 @@ func (c *Croc) dialUp(ws *websocket.Conn) (err error) {
role := c.cs.channel.Role
c.cs.Unlock()
errorChan := make(chan error, len(ports))
// generate a receive filename
var f *os.File
f, err = ioutil.TempFile(".", "croc-received")
if err != nil {
return
}
receiveFileName := f.Name()
f.Close()
os.Remove(receiveFileName)
for i, port := range ports {
go func(channel, uuid, port string, i int, errorChan chan error) {
go func(channel, uuid, port string, i int, errorChan chan error, receiveFileName string) {
if i == 0 {
log.Debug("dialing up")
}
@ -411,7 +352,7 @@ func (c *Croc) dialUp(ws *websocket.Conn) (err error) {
time.Sleep(10 * time.Millisecond)
}
c.cs.RLock()
filename := c.cs.channel.fileMetaData.Name + ".enc." + strconv.Itoa(i)
c.cs.RUnlock()
if role == 0 {
log.Debug("send file")
@ -425,6 +366,7 @@ func (c *Croc) dialUp(ws *websocket.Conn) (err error) {
time.Sleep(10 * time.Millisecond)
}
log.Debug("sending file")
filename := c.crocFileEncrypted + "." + strconv.Itoa(i)
err = sendFile(filename, i, connection)
} else {
go func() {
@ -441,11 +383,11 @@ func (c *Croc) dialUp(ws *websocket.Conn) (err error) {
c.cs.Unlock()
log.Debug("receive file")
}()
err = receiveFile(filename, i, connection)
receiveFileName += "." + strconv.Itoa(i)
err = receiveFile(receiveFileName, i, connection)
}
errorChan <- err
}(channel, uuid, port, i, errorChan)
}(channel, uuid, port, i, errorChan, receiveFileName)
}
// collect errors
@ -462,67 +404,6 @@ func (c *Croc) dialUp(ws *websocket.Conn) (err error) {
return
}
func (c *Croc) processFile(fname string) (err error) {
fd := FileMetaData{}
// first check if it is stdin
if fname == "stdin" {
var f *os.File
f, err = ioutil.TempFile(".", "croc-stdin-")
if err != nil {
return
}
_, err = io.Copy(f, os.Stdin)
if err != nil {
return
}
fname = f.Name()
err = f.Close()
if err != nil {
return
}
fd.DeleteAfterSending = true
}
fname = filepath.Clean(fname)
// check wether the file is a dir
info, err := os.Stat(fname)
if err != nil {
return
}
fd.Path, fd.Name = filepath.Split(fname)
if info.Mode().IsDir() {
// tar folder
err = tarinator.Tarinate([]string{fname}, fd.Name+".tar")
if err != nil {
log.Error(err)
return
}
fd.Name = fd.Name + ".tar"
fd.Path = "."
fd.IsDir = true
fname = path.Join(fd.Path, fd.Name)
}
fd.Hash, err = hashFile(fname)
if err != nil {
log.Error(err)
return err
}
fd.Size, err = fileSize(fname)
if err != nil {
err = errors.Wrap(err, "could not determine filesize")
log.Error(err)
return err
}
c.cs.Lock()
defer c.cs.Unlock()
c.cs.channel.fileMetaData = fd
return
}
func receiveFile(filename string, id int, connection net.Conn) error {
log.Debug("waiting for chunk size from sender")
fileSizeBuffer := make([]byte, 10)

151
src/files.go Normal file
View file

@ -0,0 +1,151 @@
package croc
import (
"encoding/json"
"io"
"io/ioutil"
"os"
"path"
"path/filepath"
"time"
log "github.com/cihub/seelog"
"github.com/gorilla/websocket"
"github.com/pkg/errors"
)
func (c *Croc) processFile(src string) (err error) {
fd := FileMetaData{}
// pathToFile and filename are the files that should be used internally
var pathToFile, filename string
// first check if it is stdin
if src == "stdin" {
var f *os.File
f, err = ioutil.TempFile(".", "croc-stdin-")
if err != nil {
return
}
_, err = io.Copy(f, os.Stdin)
if err != nil {
return
}
pathToFile = "."
filename = f.Name()
err = f.Close()
if err != nil {
return
}
// fd.Name is what the user will see
fd.Name = "stdin"
fd.DeleteAfterSending = true
} else {
pathToFile, filename = filepath.Split(filepath.Clean(src))
fd.Name = filename
}
// check wether the file is a dir
info, err := os.Stat(path.Join(pathToFile, filename))
if err != nil {
return
}
fd.IsDir = info.Mode().IsDir()
// zip file
c.crocFile, err = zipFile(path.Join(pathToFile, filename), c.UseCompression)
fd.IsCompressed = c.UseCompression
fd.Hash, err = hashFile(c.crocFile)
if err != nil {
log.Error(err)
return err
}
fd.Size, err = fileSize(c.crocFile)
if err != nil {
err = errors.Wrap(err, "could not determine filesize")
log.Error(err)
return err
}
c.cs.Lock()
defer c.cs.Unlock()
c.cs.channel.fileMetaData = fd
return
}
func (c *Croc) getFilesReady(ws *websocket.Conn) (err error) {
c.cs.Lock()
defer c.cs.Unlock()
log.Debug("getting files ready")
c.cs.channel.notSentMetaData = true
// send metadata
// wait until data is ready
for {
if c.cs.channel.fileMetaData.Name != "" {
break
}
c.cs.Unlock()
time.Sleep(10 * time.Millisecond)
c.cs.Lock()
}
// get passphrase
var passphrase []byte
passphrase, err = c.cs.channel.Pake.SessionKey()
if err != nil {
return
}
// encrypt file data
// create temporary filename
var f *os.File
f, err = ioutil.TempFile(".", "croc-encrypted")
if err != nil {
return
}
c.crocFileEncrypted = f.Name()
f.Close()
os.Remove(c.crocFileEncrypted)
err = encryptFile(c.crocFile, c.crocFileEncrypted, passphrase)
if err != nil {
return
}
// remove the unencrypted versoin
if err = os.Remove(c.crocFile); err != nil {
return
}
c.cs.channel.fileMetaData.IsEncrypted = true
// split into pieces to send
log.Debugf("splitting %s", c.crocFileEncrypted)
if err = splitFile(c.crocFileEncrypted, len(c.cs.channel.Ports)); err != nil {
return
}
// remove the file now since we still have pieces
if err = os.Remove(c.crocFileEncrypted); err != nil {
return
}
// encrypt meta data
var metaDataBytes []byte
metaDataBytes, err = json.Marshal(c.cs.channel.fileMetaData)
if err != nil {
return
}
c.cs.channel.EncryptedFileMetaData = encrypt(metaDataBytes, passphrase)
c.cs.channel.Update = true
log.Debugf("updating channel")
errWrite := ws.WriteJSON(c.cs.channel)
if errWrite != nil {
log.Error(errWrite)
}
c.cs.channel.Update = false
go func() {
// encrypt the files
// TODO
c.cs.Lock()
c.cs.channel.fileReady = true
c.cs.Unlock()
}()
return
}

View file

@ -30,6 +30,11 @@ type Croc struct {
// cs keeps the client state
cs clientState
// crocFile is the name of the file that is prepared to sent
crocFile string
// crocFileEncrypted is the name of the encrypted file
crocFileEncrypted string
}
// Init will initialize the croc relay
@ -60,11 +65,9 @@ type clientState struct {
}
type FileMetaData struct {
TempName string
Name string
Size int
Hash string
Path string
IsDir bool
IsEncrypted bool
IsCompressed bool
@ -122,6 +125,9 @@ type channelData struct {
fileMetaData FileMetaData
notSentMetaData bool
finishedHappy bool
filesReady 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

View file

@ -81,7 +81,7 @@ func zipFile(fname string, compress bool) (writtenFilename string, err error) {
defer os.Chdir(curdir)
os.Chdir(pathtofile)
newfile, err := ioutil.TempFile("/tmp/", "croc")
newfile, err := ioutil.TempFile(".", "croc-unencrypted")
if err != nil {
log.Error(err)
return