a35eb8027e
ensure that every integer conversion fits into the destination type, and for any unchecked ones, annotate why they are safe. additionally, any integers we pass into slice headers need to check that they are not negative. all of our allocations should check for allocation failure and return an error if there was a problem. even though an allocation just failed, we don't pre-allocate the failure because we don't want the callers to free it like they have to with the other errors we return. maybe we should just panic. Change-Id: Id4dfad802d312d35e565041efc9872453c90d793
90 lines
2.2 KiB
Go
90 lines
2.2 KiB
Go
// Copyright (C) 2019 Storj Labs, Inc.
|
|
// See LICENSE for copying information.
|
|
|
|
package main
|
|
|
|
// #include "uplink_definitions.h"
|
|
import "C"
|
|
import (
|
|
"fmt"
|
|
|
|
"storj.io/common/storj"
|
|
libuplink "storj.io/storj/lib/uplink"
|
|
)
|
|
|
|
// Project is a scoped uplink.Project
|
|
type Project struct {
|
|
scope
|
|
*libuplink.Project
|
|
}
|
|
|
|
//export open_project
|
|
// open_project opens project using uplink
|
|
func open_project(uplinkHandle C.UplinkRef, satelliteAddr *C.char, apikeyHandle C.APIKeyRef, cerr **C.char) C.ProjectRef {
|
|
uplink, ok := universe.Get(uplinkHandle._handle).(*Uplink)
|
|
if !ok {
|
|
*cerr = C.CString("invalid uplink")
|
|
return C.ProjectRef{}
|
|
}
|
|
|
|
apikey, ok := universe.Get(apikeyHandle._handle).(libuplink.APIKey)
|
|
if !ok {
|
|
*cerr = C.CString("invalid apikey")
|
|
return C.ProjectRef{}
|
|
}
|
|
|
|
scope := uplink.scope.child()
|
|
|
|
project, err := uplink.OpenProject(scope.ctx, C.GoString(satelliteAddr), apikey)
|
|
if err != nil {
|
|
*cerr = C.CString(fmt.Sprintf("%+v", err))
|
|
return C.ProjectRef{}
|
|
}
|
|
|
|
return C.ProjectRef{universe.Add(&Project{scope, project})}
|
|
}
|
|
|
|
//export project_salted_key_from_passphrase
|
|
// project_salted_key_from_passphrase returns a key generated from the given passphrase
|
|
// using a stable, project-specific salt
|
|
func project_salted_key_from_passphrase(projectHandle C.ProjectRef, passphrase *C.char, cerr **C.char) *C.uint8_t {
|
|
project, ok := universe.Get(projectHandle._handle).(*Project)
|
|
if !ok {
|
|
*cerr = C.CString("invalid project")
|
|
return nil
|
|
}
|
|
|
|
saltedKey, err := project.SaltedKeyFromPassphrase(project.ctx, C.GoString(passphrase))
|
|
if err != nil {
|
|
*cerr = C.CString(fmt.Sprintf("%+v", err))
|
|
return nil
|
|
}
|
|
|
|
ptr := C.malloc(storj.KeySize)
|
|
if ptr == nil {
|
|
*cerr = C.CString("unable to allocate")
|
|
return nil
|
|
}
|
|
|
|
key := (*storj.Key)(ptr)
|
|
copy(key[:], saltedKey[:])
|
|
return (*C.uint8_t)(ptr)
|
|
}
|
|
|
|
//export close_project
|
|
// close_project closes the project.
|
|
func close_project(projectHandle C.ProjectRef, cerr **C.char) {
|
|
project, ok := universe.Get(projectHandle._handle).(*Project)
|
|
if !ok {
|
|
*cerr = C.CString("invalid project")
|
|
return
|
|
}
|
|
universe.Del(projectHandle._handle)
|
|
defer project.cancel()
|
|
|
|
if err := project.Close(); err != nil {
|
|
*cerr = C.CString(fmt.Sprintf("%+v", err))
|
|
return
|
|
}
|
|
}
|