vendor: update github.com/t3rm1n4l/go-mega and dependencies

This is to fix a crash reported in #3140
This commit is contained in:
Nick Craig-Wood 2019-04-30 11:15:32 +01:00
parent 48c09608ea
commit 8f89b03d7b
135 changed files with 27990 additions and 605 deletions

View file

@ -336,7 +336,10 @@ func newMegaFS() *MegaFS {
func New() *Mega {
max := big.NewInt(0x100000000)
bigx, _ := rand.Int(rand.Reader, max)
bigx, err := rand.Int(rand.Reader, max)
if err != nil {
panic(err) // this should be returned, but this is a public interface
}
cfg := newConfig()
mgfs := newMegaFS()
m := &Mega{
@ -496,7 +499,10 @@ func (m *Mega) prelogin(email string) error {
if len(res[0].Salt) == 0 {
return errors.New("prelogin: no salt returned")
}
m.accountSalt = base64urldecode([]byte(res[0].Salt))
m.accountSalt, err = base64urldecode([]byte(res[0].Salt))
if err != nil {
return err
}
}
m.accountVersion = res[0].Version
@ -512,8 +518,14 @@ func (m *Mega) login(email string, passwd string) error {
email = strings.ToLower(email) // mega uses lowercased emails for login purposes
passkey := password_key(passwd)
uhandle := stringhash(email, passkey)
passkey, err := password_key(passwd)
if err != nil {
return err
}
uhandle, err := stringhash(email, passkey)
if err != nil {
return err
}
m.uh = make([]byte, len(uhandle))
copy(m.uh, uhandle)
@ -536,9 +548,11 @@ func (m *Mega) login(email string, passwd string) error {
msg[0].SessionKey = string(base64urlencode(sessionKey))
}
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return err
}
result, err = m.api_request(req)
if err != nil {
return err
}
@ -548,8 +562,14 @@ func (m *Mega) login(email string, passwd string) error {
return err
}
m.k = base64urldecode([]byte(res[0].Key))
m.k, err = base64urldecode([]byte(res[0].Key))
if err != nil {
return err
}
cipher, err := aes.NewCipher(passkey)
if err != nil {
return err
}
cipher.Decrypt(m.k, m.k)
m.sid, err = decryptSessionId([]byte(res[0].Privk), []byte(res[0].Csid), m.k)
if err != nil {
@ -634,9 +654,11 @@ func (m *Mega) GetUser() (UserResp, error) {
msg[0].Cmd = "ug"
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return res[0], err
}
result, err := m.api_request(req)
if err != nil {
return res[0], err
}
@ -654,7 +676,10 @@ func (m *Mega) GetQuota() (QuotaResp, error) {
msg[0].Xfer = 1
msg[0].Strg = 1
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return res[0], err
}
result, err := m.api_request(req)
if err != nil {
return res[0], err
@ -671,7 +696,10 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
var node, parent *Node
var err error
master_aes, _ := aes.NewCipher(m.k)
master_aes, err := aes.NewCipher(m.k)
if err != nil {
return nil, err
}
switch {
case itm.T == FOLDER || itm.T == FILE:
@ -680,43 +708,73 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
switch {
// File or folder owned by current user
case args[0] == itm.User:
buf := base64urldecode([]byte(args[1]))
buf, err := base64urldecode([]byte(args[1]))
if err != nil {
return nil, err
}
err = blockDecrypt(master_aes, buf, buf)
if err != nil {
return nil, err
}
compkey = bytes_to_a32(buf)
compkey, err = bytes_to_a32(buf)
if err != nil {
return nil, err
}
// Shared folder
case itm.SUser != "" && itm.SKey != "":
sk := base64urldecode([]byte(itm.SKey))
sk, err := base64urldecode([]byte(itm.SKey))
if err != nil {
return nil, err
}
err = blockDecrypt(master_aes, sk, sk)
if err != nil {
return nil, err
}
sk_aes, _ := aes.NewCipher(sk)
sk_aes, err := aes.NewCipher(sk)
if err != nil {
return nil, err
}
m.FS.skmap[itm.Hash] = itm.SKey
buf := base64urldecode([]byte(args[1]))
buf, err := base64urldecode([]byte(args[1]))
if err != nil {
return nil, err
}
err = blockDecrypt(sk_aes, buf, buf)
if err != nil {
return nil, err
}
compkey = bytes_to_a32(buf)
compkey, err = bytes_to_a32(buf)
if err != nil {
return nil, err
}
// Shared file
default:
k := m.FS.skmap[args[0]]
b := base64urldecode([]byte(k))
b, err := base64urldecode([]byte(k))
if err != nil {
return nil, err
}
err = blockDecrypt(master_aes, b, b)
if err != nil {
return nil, err
}
block, _ := aes.NewCipher(b)
buf := base64urldecode([]byte(args[1]))
block, err := aes.NewCipher(b)
if err != nil {
return nil, err
}
buf, err := base64urldecode([]byte(args[1]))
if err != nil {
return nil, err
}
err = blockDecrypt(block, buf, buf)
if err != nil {
return nil, err
}
compkey = bytes_to_a32(buf)
compkey, err = bytes_to_a32(buf)
if err != nil {
return nil, err
}
}
switch {
@ -726,10 +784,16 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
key = compkey
}
attr, err = decryptAttr(a32_to_bytes(key), []byte(itm.Attr))
// FIXME:
bkey, err := a32_to_bytes(key)
if err != nil {
// FIXME:
attr.Name = "BAD ATTRIBUTE"
} else {
attr, err = decryptAttr(bkey, []byte(itm.Attr))
// FIXME:
if err != nil {
attr.Name = "BAD ATTRIBUTE"
}
}
}
@ -769,15 +833,33 @@ func (m *Mega) addFSNode(itm FSNode) (*Node, error) {
switch {
case itm.T == FILE:
var meta NodeMeta
meta.key = a32_to_bytes(key)
meta.iv = a32_to_bytes([]uint32{compkey[4], compkey[5], 0, 0})
meta.mac = a32_to_bytes([]uint32{compkey[6], compkey[7]})
meta.compkey = a32_to_bytes(compkey)
meta.key, err = a32_to_bytes(key)
if err != nil {
return nil, err
}
meta.iv, err = a32_to_bytes([]uint32{compkey[4], compkey[5], 0, 0})
if err != nil {
return nil, err
}
meta.mac, err = a32_to_bytes([]uint32{compkey[6], compkey[7]})
if err != nil {
return nil, err
}
meta.compkey, err = a32_to_bytes(compkey)
if err != nil {
return nil, err
}
node.meta = meta
case itm.T == FOLDER:
var meta NodeMeta
meta.key = a32_to_bytes(key)
meta.compkey = a32_to_bytes(compkey)
meta.key, err = a32_to_bytes(key)
if err != nil {
return nil, err
}
meta.compkey, err = a32_to_bytes(compkey)
if err != nil {
return nil, err
}
node.meta = meta
case itm.T == ROOT:
attr.Name = "Cloud Drive"
@ -814,9 +896,11 @@ func (m *Mega) getFileSystem() error {
msg[0].Cmd = "f"
msg[0].C = 1
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return err
}
result, err := m.api_request(req)
if err != nil {
return err
}
@ -908,9 +992,15 @@ func (m *Mega) NewDownload(src *Node) (*Download, error) {
mac_enc := cipher.NewCBCEncrypter(aes_block, zero_iv)
m.FS.mutex.Lock()
t := bytes_to_a32(src.meta.iv)
t, err := bytes_to_a32(src.meta.iv)
m.FS.mutex.Unlock()
iv := a32_to_bytes([]uint32{t[0], t[1], t[0], t[1]})
if err != nil {
return nil, err
}
iv, err := a32_to_bytes([]uint32{t[0], t[1], t[0], t[1]})
if err != nil {
return nil, err
}
d := &Download{
m: m,
@ -992,10 +1082,17 @@ func (d *Download) DownloadChunk(id int) (chunk []byte, err error) {
}
// Decrypt the block
ctr_iv := bytes_to_a32(d.src.meta.iv)
ctr_iv, err := bytes_to_a32(d.src.meta.iv)
if err != nil {
return nil, err
}
ctr_iv[2] = uint32(uint64(chk_start) / 0x1000000000)
ctr_iv[3] = uint32(chk_start / 0x10)
ctr_aes := cipher.NewCTR(d.aes_block, a32_to_bytes(ctr_iv))
bctr_iv, err := a32_to_bytes(ctr_iv)
if err != nil {
return nil, err
}
ctr_aes := cipher.NewCTR(d.aes_block, bctr_iv)
ctr_aes.XORKeyStream(chunk, chunk)
// Update the chunk_macs
@ -1035,8 +1132,15 @@ func (d *Download) Finish() (err error) {
d.mac_enc.CryptBlocks(mac_data, v)
}
tmac := bytes_to_a32(mac_data)
if bytes.Equal(a32_to_bytes([]uint32{tmac[0] ^ tmac[1], tmac[2] ^ tmac[3]}), d.src.meta.mac) == false {
tmac, err := bytes_to_a32(mac_data)
if err != nil {
return err
}
btmac, err := a32_to_bytes([]uint32{tmac[0] ^ tmac[1], tmac[2] ^ tmac[3]})
if err != nil {
return err
}
if bytes.Equal(btmac, d.src.meta.mac) == false {
return EMACMISMATCH
}
@ -1188,12 +1292,24 @@ func (m *Mega) NewUpload(parent *Node, name string, fileSize int64) (*Upload, er
}
kbytes := a32_to_bytes(ukey[:4])
kiv := a32_to_bytes([]uint32{ukey[4], ukey[5], 0, 0})
aes_block, _ := aes.NewCipher(kbytes)
kbytes, err := a32_to_bytes(ukey[:4])
if err != nil {
return nil, err
}
kiv, err := a32_to_bytes([]uint32{ukey[4], ukey[5], 0, 0})
if err != nil {
return nil, err
}
aes_block, err := aes.NewCipher(kbytes)
if err != nil {
return nil, err
}
mac_enc := cipher.NewCBCEncrypter(aes_block, zero_iv)
iv := a32_to_bytes([]uint32{ukey[4], ukey[5], ukey[4], ukey[5]})
iv, err := a32_to_bytes([]uint32{ukey[4], ukey[5], ukey[4], ukey[5]})
if err != nil {
return nil, err
}
chunks := getChunkSizes(fileSize)
@ -1243,10 +1359,17 @@ func (u *Upload) UploadChunk(id int, chunk []byte) (err error) {
if len(chunk) != chk_size {
return errors.New("upload chunk is wrong size")
}
ctr_iv := bytes_to_a32(u.kiv)
ctr_iv, err := bytes_to_a32(u.kiv)
if err != nil {
return err
}
ctr_iv[2] = uint32(uint64(chk_start) / 0x1000000000)
ctr_iv[3] = uint32(chk_start / 0x10)
ctr_aes := cipher.NewCTR(u.aes_block, a32_to_bytes(ctr_iv))
bctr_iv, err := a32_to_bytes(ctr_iv)
if err != nil {
return err
}
ctr_aes := cipher.NewCTR(u.aes_block, bctr_iv)
enc := cipher.NewCBCEncrypter(u.aes_block, u.iv)
@ -1324,7 +1447,10 @@ func (u *Upload) Finish() (node *Node, err error) {
u.mac_enc.CryptBlocks(mac_data, v)
}
t := bytes_to_a32(mac_data)
t, err := bytes_to_a32(mac_data)
if err != nil {
return nil, err
}
meta_mac := []uint32{t[0] ^ t[1], t[2] ^ t[3]}
attr := FileAttr{u.name}
@ -1338,7 +1464,10 @@ func (u *Upload) Finish() (node *Node, err error) {
u.ukey[2] ^ meta_mac[0], u.ukey[3] ^ meta_mac[1],
u.ukey[4], u.ukey[5], meta_mac[0], meta_mac[1]}
buf := a32_to_bytes(key)
buf, err := a32_to_bytes(key)
if err != nil {
return nil, err
}
master_aes, err := aes.NewCipher(u.m.k)
if err != nil {
return nil, err
@ -1488,9 +1617,11 @@ func (m *Mega) Move(src *Node, parent *Node) error {
return err
}
request, _ := json.Marshal(msg)
request, err := json.Marshal(msg)
if err != nil {
return err
}
_, err = m.api_request(request)
if err != nil {
return err
}
@ -1515,11 +1646,17 @@ func (m *Mega) Rename(src *Node, name string) error {
}
var msg [1]FileAttrMsg
master_aes, _ := aes.NewCipher(m.k)
master_aes, err := aes.NewCipher(m.k)
if err != nil {
return err
}
attr := FileAttr{name}
attr_data, _ := encryptAttr(src.meta.key, attr)
attr_data, err := encryptAttr(src.meta.key, attr)
if err != nil {
return err
}
key := make([]byte, len(src.meta.compkey))
err := blockEncrypt(master_aes, key, src.meta.compkey)
err = blockEncrypt(master_aes, key, src.meta.compkey)
if err != nil {
return err
}
@ -1533,12 +1670,18 @@ func (m *Mega) Rename(src *Node, name string) error {
return err
}
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return err
}
_, err = m.api_request(req)
if err != nil {
return err
}
src.name = name
return err
return nil
}
// Create a directory in the filesystem
@ -1557,12 +1700,21 @@ func (m *Mega) CreateDir(name string, parent *Node) (*Node, error) {
compkey[i] = uint32(mrand.Int31())
}
master_aes, _ := aes.NewCipher(m.k)
master_aes, err := aes.NewCipher(m.k)
if err != nil {
return nil, err
}
attr := FileAttr{name}
ukey := a32_to_bytes(compkey[:4])
attr_data, _ := encryptAttr(ukey, attr)
ukey, err := a32_to_bytes(compkey[:4])
if err != nil {
return nil, err
}
attr_data, err := encryptAttr(ukey, attr)
if err != nil {
return nil, err
}
key := make([]byte, len(ukey))
err := blockEncrypt(master_aes, key, ukey)
err = blockEncrypt(master_aes, key, ukey)
if err != nil {
return nil, err
}
@ -1578,7 +1730,10 @@ func (m *Mega) CreateDir(name string, parent *Node) (*Node, error) {
return nil, err
}
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return nil, err
}
result, err := m.api_request(req)
if err != nil {
return nil, err
@ -1614,14 +1769,20 @@ func (m *Mega) Delete(node *Node, destroy bool) error {
return err
}
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return err
}
_, err = m.api_request(req)
if err != nil {
return err
}
parent := m.FS.lookup[node.hash]
parent.removeChild(node)
delete(m.FS.lookup, node.hash)
return err
return nil
}
// process an add node event
@ -1830,9 +1991,11 @@ func (m *Mega) getLink(n *Node) (string, error) {
msg[0].Cmd = "l"
msg[0].N = n.GetHash()
req, _ := json.Marshal(msg)
req, err := json.Marshal(msg)
if err != nil {
return "", err
}
result, err := m.api_request(req)
if err != nil {
return "", err
}