refactoring

This commit is contained in:
Zack Scholl 2019-11-12 11:03:34 -08:00
parent 797440fa5d
commit 4ab3ebea3e

View File

@ -10,8 +10,7 @@ import (
"github.com/gorilla/websocket"
"github.com/pion/webrtc/v2"
"github.com/schollz/croc/v7/src/compress"
"github.com/schollz/croc/v7/src/crypt"
"github.com/schollz/croc/v7/src/box"
log "github.com/schollz/logger"
"github.com/schollz/pake/v2"
)
@ -66,44 +65,6 @@ type WebsocketMessage struct {
Payload string
}
// SendWebsocketMessage communicates using base64
func (c *Client) SendWebsocketMessage(wsmsg WebsocketMessage, encrypt bool) (err error) {
var b []byte
if encrypt {
b, err = c.Bundle(wsmsg)
} else {
b, err = json.Marshal(wsmsg)
if err != nil {
log.Error(err)
return
}
}
bd := base64.StdEncoding.EncodeToString(b)
err = c.ws.WriteMessage(1, []byte(bd))
return
}
// ReceiveWebsocketMessage communicates using base64
func (c *Client) ReceiveWebsocketMessage(decrypt bool) (wsmsg WebsocketMessage, err error) {
_, msg, err := c.ws.ReadMessage()
if err != nil {
log.Error(err)
return
}
b, err := base64.StdEncoding.DecodeString(string(msg))
if decrypt {
err = c.Unbundle(b, &wsmsg)
if err != nil {
log.Error(err)
return
}
} else {
err = json.Unmarshal(b, &wsmsg)
}
return
}
// New establishes a new connection for transferring files between two instances.
func New(ops Options) (c *Client, err error) {
c = new(Client)
@ -123,176 +84,176 @@ func New(ops Options) (c *Client, err error) {
return
}
// initialize pake
if c.IsOfferer {
c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond)
} else {
c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond)
}
if err != nil {
return
}
// // initialize pake
// if c.IsOfferer {
// c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond)
// } else {
// c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond)
// }
// if err != nil {
// return
// }
if c.IsOfferer {
// offerer sends the first pake
c.SendWebsocketMessage(WebsocketMessage{
Message: "pake",
Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()),
}, false)
} else {
// answerer receives the first pake
err = c.getPAKE(true)
if err != nil {
log.Error(err)
return
}
}
// if c.IsOfferer {
// // offerer sends the first pake
// c.SendWebsocketMessage(WebsocketMessage{
// Message: "pake",
// Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()),
// }, false)
// } else {
// // answerer receives the first pake
// err = c.getPAKE(true)
// if err != nil {
// log.Error(err)
// return
// }
// }
// one more exchange to finish (offerer must send)
err = c.getPAKE(c.IsOfferer)
if err != nil {
log.Error(err)
return
}
log.Debug(c.Pake.SessionKey())
// // one more exchange to finish (offerer must send)
// err = c.getPAKE(c.IsOfferer)
// if err != nil {
// log.Error(err)
// return
// }
// log.Debug(c.Pake.SessionKey())
// generate the session key for encryption
pakeSessionKey, err := c.Pake.SessionKey()
if err != nil {
log.Error(err)
return
}
c.Key, err = crypt.New(pakeSessionKey, []byte(c.Options.SharedSecret))
if err != nil {
log.Error(err)
return
}
// // generate the session key for encryption
// pakeSessionKey, err := c.Pake.SessionKey()
// if err != nil {
// log.Error(err)
// return
// }
// c.Key, err = crypt.New(pakeSessionKey, []byte(c.Options.SharedSecret))
// if err != nil {
// log.Error(err)
// return
// }
// create webrtc connection
finished := make(chan error, 1)
c.rtc, err = c.CreateOfferer(finished)
if err != nil {
log.Error(err)
}
// // create webrtc connection
// finished := make(chan error, 1)
// c.rtc, err = c.CreateOfferer(finished)
// if err != nil {
// log.Error(err)
// }
offer, err := c.rtc.CreateOffer(nil)
if err != nil {
log.Error(err)
return
}
if c.IsOfferer {
// Now, create an offer
err = c.rtc.SetLocalDescription(offer)
if err != nil {
log.Error(err)
return
}
// offer, err := c.rtc.CreateOffer(nil)
// if err != nil {
// log.Error(err)
// return
// }
// if c.IsOfferer {
// // Now, create an offer
// err = c.rtc.SetLocalDescription(offer)
// if err != nil {
// log.Error(err)
// return
// }
// bundle it and send it over
var offerJSON []byte
offerJSON, err = json.Marshal(offer)
if err != nil {
log.Error(err)
}
err = c.SendWebsocketMessage(
WebsocketMessage{
Message: "offer",
Payload: base64.StdEncoding.EncodeToString(offerJSON),
},
true,
)
if err != nil {
log.Error(err)
return
}
// // bundle it and send it over
// var offerJSON []byte
// offerJSON, err = json.Marshal(offer)
// if err != nil {
// log.Error(err)
// }
// err = c.SendWebsocketMessage(
// WebsocketMessage{
// Message: "offer",
// Payload: base64.StdEncoding.EncodeToString(offerJSON),
// },
// true,
// )
// if err != nil {
// log.Error(err)
// return
// }
// wait for the answer
var wsmsg WebsocketMessage
wsmsg, err = c.ReceiveWebsocketMessage(true)
// // wait for the answer
// var wsmsg WebsocketMessage
// wsmsg, err = c.ReceiveWebsocketMessage(true)
var payload []byte
payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload)
err = setRemoteDescription(c.rtc, payload)
if err != nil {
log.Error(err)
return
}
} else {
// wait for the offer
var wsmsg WebsocketMessage
wsmsg, err = c.ReceiveWebsocketMessage(true)
// var payload []byte
// payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload)
// err = setRemoteDescription(c.rtc, payload)
// if err != nil {
// log.Error(err)
// return
// }
// } else {
// // wait for the offer
// var wsmsg WebsocketMessage
// wsmsg, err = c.ReceiveWebsocketMessage(true)
var payload []byte
payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload)
err = setRemoteDescription(c.rtc, payload)
if err != nil {
log.Error(err)
return
}
// var payload []byte
// payload, err = base64.StdEncoding.DecodeString(wsmsg.Payload)
// err = setRemoteDescription(c.rtc, payload)
// if err != nil {
// log.Error(err)
// return
// }
var answer webrtc.SessionDescription
answer, err = c.rtc.CreateAnswer(nil)
if err != nil {
log.Error(err)
return
}
err = c.rtc.SetLocalDescription(answer)
if err != nil {
log.Error(err)
return
}
// var answer webrtc.SessionDescription
// answer, err = c.rtc.CreateAnswer(nil)
// if err != nil {
// log.Error(err)
// return
// }
// err = c.rtc.SetLocalDescription(answer)
// if err != nil {
// log.Error(err)
// return
// }
// bundle it and send it over
var answerJSON []byte
answerJSON, err = json.Marshal(answer)
if err != nil {
log.Error(err)
}
err = c.SendWebsocketMessage(
WebsocketMessage{
Message: "answer",
Payload: base64.StdEncoding.EncodeToString(answerJSON),
},
true,
)
if err != nil {
log.Error(err)
return
}
// // bundle it and send it over
// var answerJSON []byte
// answerJSON, err = json.Marshal(answer)
// if err != nil {
// log.Error(err)
// }
// err = c.SendWebsocketMessage(
// WebsocketMessage{
// Message: "answer",
// Payload: base64.StdEncoding.EncodeToString(answerJSON),
// },
// true,
// )
// if err != nil {
// log.Error(err)
// return
// }
}
// }
err = <-finished
// err = <-finished
return
}
func (c *Client) getPAKE(keepSending bool) (err error) {
// answerer receives the first pake
p, err := c.ReceiveWebsocketMessage(false)
if err != nil {
log.Error(err)
return
}
payload, err := base64.StdEncoding.DecodeString(p.Payload)
if err != nil {
log.Error(err)
return
}
log.Debugf("payload: %s", payload)
err = c.Pake.Update(payload)
if err != nil {
log.Error(err)
return
}
if keepSending {
// sends back PAKE bytes
err = c.SendWebsocketMessage(WebsocketMessage{
Message: "pake",
Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()),
}, false)
}
return
}
// func (c *Client) getPAKE(keepSending bool) (err error) {
// // answerer receives the first pake
// p, err := c.ReceiveWebsocketMessage(false)
// if err != nil {
// log.Error(err)
// return
// }
// payload, err := base64.StdEncoding.DecodeString(p.Payload)
// if err != nil {
// log.Error(err)
// return
// }
// log.Debugf("payload: %s", payload)
// err = c.Pake.Update(payload)
// if err != nil {
// log.Error(err)
// return
// }
// if keepSending {
// // sends back PAKE bytes
// err = c.SendWebsocketMessage(WebsocketMessage{
// Message: "pake",
// Payload: base64.StdEncoding.EncodeToString(c.Pake.Bytes()),
// }, false)
// }
// return
// }
// Send will send the specified file
func (c *Client) Send(options TransferOptions) (err error) {
@ -315,25 +276,66 @@ func (c *Client) connectToRelay() (err error) {
}
log.Debugf("connected and sending first message")
c.SendWebsocketMessage(WebsocketMessage{
Message: "offerer",
}, false)
wsmsg, err := c.ReceiveWebsocketMessage(false)
bundled, err := box.Bundle(WebsocketMessage{
Message: "you are offerer",
}, c.Key)
if err != nil {
log.Debug("read:", err)
log.Error(err)
return
}
log.Debugf("recv: %s", wsmsg)
if wsmsg.Message == "offerer" {
c.IsOfferer = true
c.ws.WriteJSON(WebsocketMessage{
Message: "answerer",
})
} else if wsmsg.Message == "answerer" {
c.IsOfferer = false
} else {
err = fmt.Errorf("got bad message: %+v", wsmsg)
err = c.ws.WriteMessage(1, []byte(bundled))
if err != nil {
log.Error(err)
return
}
for {
var wsmsg, wsreply WebsocketMessage
var msg []byte
_, msg, err = c.ws.ReadMessage()
if err != nil {
log.Debug("read:", err)
return
}
err = box.Unbundle(string(msg), c.Key, &wsmsg)
log.Debugf("recv: %s", wsmsg.Message)
if wsmsg.Message == "you are offerer" {
c.IsOfferer = true
c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 0, elliptic.P521(), 1*time.Microsecond)
wsreply.Message = "you are answerer"
} else if wsmsg.Message == "you are answerer" {
c.IsOfferer = false
c.Pake, err = pake.Init([]byte(c.Options.SharedSecret), 1, elliptic.P521(), 1*time.Microsecond)
wsreply.Message = "pake1"
wsreply.Payload = base64.StdEncoding.EncodeToString(c.Pake.Bytes())
} else if wsmsg.Message == "pake2" || wsmsg.Message == "pake3" {
var pakeBytes []byte
pakeBytes, err = base64.StdEncoding.DecodeString(wsreply.Payload)
if err != nil {
log.Error(err)
return
}
err = c.Pake.Update(pakeBytes)
if err != nil {
log.Error(err)
return
}
if wsmsg.Message == "pake2" {
wsreply.Message = "pake3"
wsreply.Payload = base64.StdEncoding.EncodeToString(c.Pake.Bytes())
}
} else {
log.Debug("unknown")
}
if wsmsg.Message != "" {
var bundled string
bundled, err = box.Bundle(wsreply, c.Key)
err = c.ws.WriteMessage(1, []byte(bundled))
if err != nil {
log.Error(err)
return
}
}
}
return
}
@ -412,10 +414,10 @@ func (c *Client) CreateOfferer(finished chan<- error) (pc *webrtc.PeerConnection
for {
its++
msg, _ := c.Bundle(WebsocketMessage{
msg, _ := box.Bundle(WebsocketMessage{
Message: fmt.Sprintf("%d", its),
})
err2 := sendData(msg)
}, c.Key)
err2 := sendData([]byte(msg))
if err2 != nil {
finished <- err2
return
@ -439,7 +441,7 @@ func (c *Client) CreateOfferer(finished chan<- error) (pc *webrtc.PeerConnection
// Register the OnMessage to handle incoming messages
dc.OnMessage(func(dcMsg webrtc.DataChannelMessage) {
var wsmsg WebsocketMessage
err := c.Unbundle(dcMsg.Data, &wsmsg)
err = box.Unbundle(string(dcMsg.Data), c.Key, &wsmsg)
if err == nil {
log.Debugf("wsmsg: %+v", wsmsg)
} else {