Skip to content

Commit

Permalink
Implement encryption of IBB sending as well
Browse files Browse the repository at this point in the history
  • Loading branch information
olabiniV2 committed Jun 14, 2020
1 parent 78ddcd9 commit d9be439
Show file tree
Hide file tree
Showing 4 changed files with 38 additions and 17 deletions.
2 changes: 1 addition & 1 deletion session/filetransfer/encryption.go
Expand Up @@ -49,7 +49,7 @@ func generateEncryptionParameters(enabled bool, genKey func() []byte, keyType st
return nil
}

func (enc *encryptionParameters) wrapForSending(data io.Writer) (io.Writer, func()) {
func (enc *encryptionParameters) wrapForSending(data io.WriteCloser) (io.WriteCloser, func()) {
if enc == nil {
return data, func() {}
}
Expand Down
40 changes: 29 additions & 11 deletions session/filetransfer/ibb_send.go
Expand Up @@ -45,6 +45,31 @@ func ibbSendDoWithBlockSize(ctx *sendContext, blocksize int) {
})
}

func ibbReadAndWrite(ctx *sendContext) io.ReadCloser {
f, err := os.Open(ctx.file)
if err != nil {
ctx.onError(err)
return nil
}

r, w := io.Pipe()
w2 := base64.NewEncoder(base64.StdEncoding, w)
w3, beforeFinish := ctx.enc.wrapForSending(w2)

go func() {
_, err = io.Copy(w3, f)
if err != nil && err != errLocalCancel {
ctx.onError(err)
}

beforeFinish()

_ = w3.Close()
}()

return r
}

func ibbSendChunk(ctx *sendContext, r io.ReadCloser, buffer []byte, seq uint16) bool {
if ctx.weWantToCancel {
_, _, _ = ctx.s.Conn().SendIQ(ctx.peer, "set", data.IBBClose{Sid: ctx.sid})
Expand All @@ -58,13 +83,10 @@ func ibbSendChunk(ctx *sendContext, r io.ReadCloser, buffer []byte, seq uint16)

n, err := r.Read(buffer)
if n > 0 {
// TODO: here, we need to optionally do the encryption etc
encdata := base64.StdEncoding.EncodeToString(buffer[:n])

rpl, _, e := ctx.s.Conn().SendIQ(ctx.peer, "set", data.IBBData{
Sid: ctx.sid,
Sequence: seq,
Base64: encdata,
Base64: string(buffer[:n]),
})
if e != nil {
ctx.onError(e)
Expand All @@ -75,9 +97,7 @@ func ibbSendChunk(ctx *sendContext, r io.ReadCloser, buffer []byte, seq uint16)
go trackResultOfSend(ctx, rpl)
}
if err == io.EOF {
// TODO: here, for encryption, we need to send the mac key and wait for result of mac key write
closeAndIgnore(r)
// TODO[LATER]: we ignore the result of this close - maybe we should react to it in some way, if it reports failure from the other side
_, _, _ = ctx.s.Conn().SendIQ(ctx.peer, "set", data.IBBClose{Sid: ctx.sid})
ctx.onFinish()
return false
Expand Down Expand Up @@ -125,15 +145,13 @@ func ibbSendChunks(ctx *sendContext, r io.ReadCloser, buffer []byte, seq uint16)
}

func ibbSendStartTransfer(ctx *sendContext, blockSize int) {
// TODO: for encryption, this is probably the right place to create the MAC and AES thingies
seq := uint16(0)
buffer := make([]byte, blockSize)
f, err := os.Open(ctx.file)
if err != nil {
ctx.onError(err)
r := ibbReadAndWrite(ctx)
if r == nil {
return
}
ibbSendChunks(ctx, f, buffer, seq)
ibbSendChunks(ctx, r, buffer, seq)
}

func ibbReceivedClose(ctx *sendContext) {
Expand Down
10 changes: 6 additions & 4 deletions session/filetransfer/iq.go
Expand Up @@ -38,12 +38,14 @@ func InitIQ(s access.Session, stanza *data.ClientIQ, si data.SI) (ret interface{
acceptResult := make(chan *string)
go waitForFileTransferUserAcceptance(stanza, si, acceptResult, ctx)

// TODO: in this case, it seems to make sense that stanza.From HAS to contain a resource
// If not, we're dealing with either a bad server or a weird other condition
// However, we should probably still validate this somewhere, since the code right now will crash
peer, ok := jid.Parse(stanza.From).(jid.WithResource)
if !ok {
s.Warn(fmt.Sprintf("Stanza sender doesn't contain resource - this shouldn't happen: %v", stanza.From))
return nil, "", false
}

s.PublishEvent(events.FileTransfer{
Peer: jid.R(stanza.From),
Peer: peer,
Mime: si.File.Hash,
DateLastModified: si.File.Date,
Name: si.File.Name,
Expand Down
3 changes: 2 additions & 1 deletion session/filetransfer/send_dir.go
Expand Up @@ -74,7 +74,8 @@ func (ctx *sendContext) sendSIData(profile, file string, isDir bool) data.SI {
profile = encryptedTransferProfile
}

// TODO: Add Date and Hash here later?
// We probably DON'T want to add date and hash here, since that leaks
// potentially unencrypted information about the file being transferred
si := data.SI{
ID: ctx.sid,
Profile: profile,
Expand Down

0 comments on commit d9be439

Please sign in to comment.