Compare commits
26 Commits
Author | SHA1 | Date |
---|---|---|
Dan Ballard | 7a65efaa78 | |
Sarah Jamie Lewis | 83c84b2049 | |
Sarah Jamie Lewis | 6618410cc9 | |
Sarah Jamie Lewis | 89f19928c2 | |
Sarah Jamie Lewis | 243727a131 | |
Sarah Jamie Lewis | dd0f1cd868 | |
Sarah Jamie Lewis | 5bf954f3d0 | |
Sarah Jamie Lewis | 425c3e6030 | |
Sarah Jamie Lewis | 32ea146ec0 | |
Sarah Jamie Lewis | 6321f09aad | |
Dan Ballard | 9e3fc6123b | |
Sarah Jamie Lewis | cbe687ce2e | |
Sarah Jamie Lewis | 6c0b2e2a4f | |
Sarah Jamie Lewis | 7c042334d3 | |
Sarah Jamie Lewis | c7c2259c2d | |
Sarah Jamie Lewis | c2c3c2894d | |
Sarah Jamie Lewis | 7ddf09caec | |
Sarah Jamie Lewis | 41a554a198 | |
Dan Ballard | b80db89284 | |
Sarah Jamie Lewis | 20dc170a78 | |
Sarah Jamie Lewis | 267e79368e | |
Sarah Jamie Lewis | f93616615a | |
Sarah Jamie Lewis | 3e9c9c3b70 | |
Sarah Jamie Lewis | f60fbfc3d5 | |
Sarah Jamie Lewis | f32ad741e0 | |
Sarah Jamie Lewis | a453ca9dc8 |
23
.drone.yml
23
.drone.yml
|
@ -5,15 +5,20 @@ name: linux-android-windows-test
|
|||
|
||||
steps:
|
||||
- name: fetch
|
||||
image: golang:1.19.1
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
commands:
|
||||
- go install honnef.co/go/tools/cmd/staticcheck@latest
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/tor
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
||||
- chmod a+x tor
|
||||
- go install go.uber.org/nilaway/cmd/nilaway@latest
|
||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/branch/master/tor/tor-0.4.8.9-linux-x86_64.tar.gz -O tor.tar.gz
|
||||
- tar -xzf tor.tar.gz
|
||||
- chmod a+x Tor/tor
|
||||
- export PATH=$PWD/Tor/:$PATH
|
||||
- export LD_LIBRARY_PATH=$PWD/Tor/
|
||||
- tor --version
|
||||
- export GO111MODULE=on
|
||||
- git fetch --tags
|
||||
- go mod download
|
||||
- echo `git describe --tags` > VERSION
|
||||
|
@ -21,7 +26,7 @@ steps:
|
|||
- export GOSUMDB="off"
|
||||
|
||||
- name: build-linux
|
||||
image: openpriv/golangxarm:1.19.1
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
@ -31,7 +36,7 @@ steps:
|
|||
- make linux
|
||||
|
||||
- name: build-android
|
||||
image: openpriv/android-go-mobile:2023.02
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
volumes:
|
||||
- name: deps
|
||||
path: /go
|
||||
|
@ -44,7 +49,7 @@ steps:
|
|||
- make android
|
||||
|
||||
- name: build-windows
|
||||
image: openpriv/mingw-go:2023.01
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
environment:
|
||||
GOPATH: /go
|
||||
volumes:
|
||||
|
@ -55,7 +60,7 @@ steps:
|
|||
- make windows
|
||||
|
||||
- name: deploy-buildfiles
|
||||
image: kroniak/ssh-client
|
||||
image: openpriv/go-cross-compile:2024.02
|
||||
pull: if-not-exists
|
||||
environment:
|
||||
BUILDFILES_KEY:
|
||||
|
@ -146,7 +151,7 @@ steps:
|
|||
status: [ success ]
|
||||
commands:
|
||||
- echo $BUILDFILES_KEY > ~/id_rsab64
|
||||
- base64 -d ~/id_rsab64 > ~/id_rsa
|
||||
- base64 -d -i ~/id_rsab64 -o ~/id_rsa
|
||||
- chmod 400 ~/id_rsa
|
||||
- export DIR=libCwtch-autobindings-`cat COMMIT_DATE`-`cat VERSION`
|
||||
- mkdir -p $DIR
|
||||
|
|
6
Makefile
6
Makefile
|
@ -48,20 +48,20 @@ libCwtch.x.so: lib.go
|
|||
./switch-ffi.sh
|
||||
mkdir -p build/linux
|
||||
ifeq ($(ARCH),x86_64)
|
||||
env CGO_ENABLED=1 CC=$(ARM_X_CC) GOARCH=arm64 go build -trimpath -ldflags "-buildid=autobindings-v0.0.3-22-g20065b2 -X main.buildVer=autobindings-v0.0.3-22-g20065b2 -X main.buildDate=2023-05-01-21-41" -buildmode c-shared -o libCwtch.x.so
|
||||
env CGO_ENABLED=1 CC=$(ARM_X_CC) GOARCH=arm64 go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x.so
|
||||
mv libCwtch.x.so build/linux/libCwtch.arm64.so
|
||||
mv libCwtch.x.h build/linux/libCwtch.h
|
||||
endif
|
||||
|
||||
libCwtch.x64.dylib: lib.go
|
||||
./switch-ffi.sh
|
||||
go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x64.dylib
|
||||
env CGO_CFLAGS="-mmacosx-version-min=10.12" CGO_LDFLAGS="-mmacosx-version-min=10.12" GOARCH=amd64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=autobindings-$(shell git describe --tags) -X main.buildVer=autobindings-$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.x64.dylib
|
||||
mkdir -p build/macos
|
||||
mv libCwtch.x64.dylib build/macos/
|
||||
|
||||
libCwtch.arm64.dylib: lib.go
|
||||
./switch-ffi.sh
|
||||
env GOARCH=arm64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=$(shell git describe --tags) -X main.buildVer=$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.arm64.dylib
|
||||
env CGO_CFLAGS="-mmacosx-version-min=10.12" CGO_LDFLAGS="-mmacosx-version-min=10.12" GOARCH=arm64 GOOS=darwin CGO_ENABLED=1 go build -trimpath -ldflags "-buildid=$(shell git describe --tags) -X main.buildVer=$(shell git describe --tags) -X main.buildDate=$(shell git log -1 --format=%cd --date=format:%G-%m-%d-%H-%M)" -buildmode c-shared -o libCwtch.arm64.dylib
|
||||
mkdir -p build/macos
|
||||
mv libCwtch.arm64.dylib build/macos/
|
||||
|
||||
|
|
|
@ -96,7 +96,9 @@ func main() {
|
|||
case "profile":
|
||||
generatedBindings = generateProfileFunction(generatedBindings, fName, args)
|
||||
case "(json)profile":
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args)
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args, false)
|
||||
case "(json-err)profile":
|
||||
generatedBindings = generateJsonProfileFunction(generatedBindings, fName, args, true)
|
||||
case "@profile-experiment":
|
||||
experiment := args[0]
|
||||
generatedBindings = generateExperimentalProfileFunction(generatedBindings, experiment, fName, args[1:])
|
||||
|
@ -146,6 +148,10 @@ func intArgPrototype(varName string) (string, string, string, string) {
|
|||
return fmt.Sprintf(`%s C.int`, ToSnakeCase(varName)), fmt.Sprintf(`int(%v)`, ToSnakeCase(varName)), fmt.Sprintf(`%v int`, varName), varName
|
||||
}
|
||||
|
||||
func uintArgPrototype(varName string) (string, string, string, string) {
|
||||
return fmt.Sprintf(`%s C.uint`, ToSnakeCase(varName)), fmt.Sprintf(`int(%v)`, ToSnakeCase(varName)), fmt.Sprintf(`%v int`, varName), varName
|
||||
}
|
||||
|
||||
func conversationArgPrototype(varName string) (string, string, string, string) {
|
||||
return intArgPrototype(varName)
|
||||
}
|
||||
|
@ -235,7 +241,7 @@ func mapArgs(argsTypes []string) (string, string, string, string) {
|
|||
gUse = append(gUse, c4)
|
||||
case "int":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic bool arg must have have e.g. bool:<name>\n")
|
||||
fmt.Printf("generic int arg must have have e.g. int:<name>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
c1, c2, c3, c4 := intArgPrototype(argTypeParts[1])
|
||||
|
@ -243,6 +249,20 @@ func mapArgs(argsTypes []string) (string, string, string, string) {
|
|||
c2GoArgs = append(c2GoArgs, c2)
|
||||
goSpec = append(goSpec, c3)
|
||||
gUse = append(gUse, c4)
|
||||
case "uint":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic uint arg must have have e.g. uint:<name>\n")
|
||||
os.Exit(1)
|
||||
}
|
||||
c1, c2, c3, c4 := uintArgPrototype(argTypeParts[1])
|
||||
cArgs = append(cArgs, c1)
|
||||
c2GoArgs = append(c2GoArgs, c2)
|
||||
goSpec = append(goSpec, c3)
|
||||
// because of java/kotlin/android/gomobile inability to recognize unsigned integers
|
||||
// we need to pretent this is a signed interface...so do the final cast here...
|
||||
// this will cause bad behavior if a negative number is passed through the java
|
||||
// interface...so...don't do that...
|
||||
gUse = append(gUse, fmt.Sprintf("uint(%s)", c4))
|
||||
case "string":
|
||||
if len(argTypeParts) != 2 {
|
||||
fmt.Printf("generic string arg must have have e.g. string:<name>\n")
|
||||
|
@ -364,7 +384,7 @@ func {{FNAME}}({{GO_ARGS_SPEC}}) {
|
|||
return bindings
|
||||
}
|
||||
|
||||
func generateJsonProfileFunction(bindings string, name string, argsTypes []string) string {
|
||||
func generateJsonProfileFunction(bindings string, name string, argsTypes []string, handleErr bool) string {
|
||||
appPrototype := `
|
||||
//export c_{{FNAME}}
|
||||
func c_{{FNAME}}({{C_ARGS}}) *C.char {
|
||||
|
@ -374,14 +394,26 @@ func c_{{FNAME}}({{C_ARGS}}) *C.char {
|
|||
func {{FNAME}}({{GO_ARGS_SPEC}}) string {
|
||||
cwtchProfile := application.GetPeer(profile)
|
||||
if cwtchProfile != nil {
|
||||
return cwtchProfile.{{LIBNAME}}({{GO_ARG}})
|
||||
{{HANDLE_FUNC}}
|
||||
}
|
||||
return ""
|
||||
}
|
||||
`
|
||||
|
||||
noErrorPrototype := `return cwtchProfile.{{LIBNAME}}({{GO_ARG}})`
|
||||
withErrorPrototype := `res,err := cwtchProfile.{{LIBNAME}}({{GO_ARG}})
|
||||
if err != nil {
|
||||
log.Errorf("could not {{FNAME}} %v", err)
|
||||
}
|
||||
return res`
|
||||
functionPrototype := noErrorPrototype
|
||||
if handleErr {
|
||||
functionPrototype = withErrorPrototype
|
||||
}
|
||||
|
||||
cArgs, c2GoArgs, goSpec, gUse := mapArgs(argsTypes)
|
||||
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{HANDLE_FUNC}}", functionPrototype)
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{FNAME}}", strings.TrimPrefix(name, "Enhanced"))
|
||||
appPrototype = strings.ReplaceAll(appPrototype, "{{LIBNAME}}", name)
|
||||
// We need to prepend a set of profile handle arguments...
|
||||
|
@ -407,7 +439,10 @@ func {{FNAME}}({{GO_ARGS_SPEC}}) {
|
|||
if cwtchProfile != nil {
|
||||
functionality := {{EXPERIMENT}}.FunctionalityGate()
|
||||
if functionality != nil {
|
||||
functionality.{{LIBNAME}}(cwtchProfile, {{GO_ARG}})
|
||||
err := functionality.{{LIBNAME}}(cwtchProfile, {{GO_ARG}})
|
||||
if err != nil {
|
||||
log.Errorf("error calling experimental feature {{FNAME}}: %v", err)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
4
go.mod
4
go.mod
|
@ -1,9 +1,9 @@
|
|||
module git.openprivacy.ca/cwtch.im/cwtch-autobindings
|
||||
|
||||
go 1.19
|
||||
go 1.20
|
||||
|
||||
require (
|
||||
cwtch.im/cwtch v0.23.0
|
||||
cwtch.im/cwtch v0.27.0
|
||||
git.openprivacy.ca/cwtch.im/server v1.4.5
|
||||
git.openprivacy.ca/openprivacy/connectivity v1.11.0
|
||||
git.openprivacy.ca/openprivacy/log v1.0.3
|
||||
|
|
14
go.sum
14
go.sum
|
@ -1,6 +1,6 @@
|
|||
cwtch.im/cwtch v0.18.0/go.mod h1:StheazFFY7PKqBbEyDVLhzWW6WOat41zV0ckC240c5Y=
|
||||
cwtch.im/cwtch v0.23.0 h1:y0haqmKmkoPU2RfmIUjAmEQNf2dx5PVBbHvLkeI6p+4=
|
||||
cwtch.im/cwtch v0.23.0/go.mod h1:o8uZBYjDS1DEHftxdYl91iMQZ2WDxlajM7Pa0ScfviI=
|
||||
cwtch.im/cwtch v0.27.0 h1:MkNIZ+pT5ZwiGlKHk20GMUTlzBsmCWJEibbj6hr+WHw=
|
||||
cwtch.im/cwtch v0.27.0/go.mod h1:A3i92aFuhyHI2DYO2Qnvl5iqEw0Cox22pdiypHnMOy4=
|
||||
filippo.io/edwards25519 v1.0.0-rc.1/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
filippo.io/edwards25519 v1.0.0 h1:0wAIcmJUqRdI8IJ/3eGi5/HwXZWPujYXXlkrQogz0Ek=
|
||||
filippo.io/edwards25519 v1.0.0/go.mod h1:N1IkdkCkiLB6tki+MYJoSx2JTY9NUlxZE7eHn5EwJns=
|
||||
|
@ -92,17 +92,12 @@ golang.org/x/crypto v0.0.0-20201012173705-84dcc777aaee/go.mod h1:LzIPMQfyMNhhGPh
|
|||
golang.org/x/crypto v0.0.0-20210921155107-089bfa567519/go.mod h1:GvvjBRRGRdwPK5ydBHafDWAxML/pGHZbMvKqRZ5+Abc=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d h1:3qF+Z8Hkrw9sOhrFHti9TlB1Hkac1x+DNRkv0XQiFjo=
|
||||
golang.org/x/crypto v0.0.0-20220826181053-bd7e27e6170d/go.mod h1:IxCIyHEi3zRg3s0A5j5BB6A9Jmi73HwBIUl50j+osU4=
|
||||
golang.org/x/crypto v0.12.0/go.mod h1:NF0Gs7EO5K4qLn+Ylc+fih8BSTeIjAP05siRnAh98yw=
|
||||
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda h1:O+EUvnBNPwI4eLthn8W5K+cS8zQZfgTABPLNm6Bna34=
|
||||
golang.org/x/mobile v0.0.0-20230531173138-3c911d8e3eda/go.mod h1:aAjjkJNdrh3PMckS4B10TGS2nag27cbKR1y2BpUxsiY=
|
||||
golang.org/x/mobile v0.0.0-20230818142238-7088062f872d h1:Ouem7YgI783/xoG5NZUHbg/ggHFOutUUoq1ZRlCCTbM=
|
||||
golang.org/x/mobile v0.0.0-20230818142238-7088062f872d/go.mod h1:kQNMt2gXlYXNazoSeytBi7knmDN7YS/JzMKFYxgoNxc=
|
||||
golang.org/x/mod v0.3.0/go.mod h1:s0Qsj1ACt9ePp/hMypM3fl4fZqREWJwdYDEqhRiZZUA=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220106191415-9b9b3d81d5e3/go.mod h1:3p9vT2HGsQu2K1YbXdKPJLVgG5VJdoTa1poYQBtP1AY=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4 h1:6zppjxzCulZykYSLyVDYbneBfbaBIQPYMevg0bEwv2s=
|
||||
golang.org/x/mod v0.6.0-dev.0.20220419223038-86c51ed26bb4/go.mod h1:jJ57K6gSWd91VN4djpZkiMVwK6gcyfeH4XE8wZrZaV4=
|
||||
golang.org/x/mod v0.12.0 h1:rmsUpXtvNzj340zd98LZ4KntptpfRHwpFOHG188oHXc=
|
||||
golang.org/x/mod v0.12.0/go.mod h1:iBbtSCu2XBx23ZKBPSOrRkjjQPZFPuis4dIYUhu/chs=
|
||||
golang.org/x/net v0.0.0-20180906233101-161cd47e91fd/go.mod h1:mL1N/T3taQHkDXs73rZJwtUhF3w3ftmwwsq0BUmARs4=
|
||||
golang.org/x/net v0.0.0-20190404232315-eb5bcb51f2a3/go.mod h1:t9HGtf8HONx5eT2rtn7q6eTqICYqUVnKs3thJo3Qplg=
|
||||
golang.org/x/net v0.0.0-20190620200207-3b0461eec859/go.mod h1:z5CRVTTTmAJ677TzLLGU+0bjPO0LkuOLi4/5GtJWs/s=
|
||||
|
@ -117,7 +112,6 @@ golang.org/x/net v0.0.0-20220225172249-27dd8689420f/go.mod h1:CfG3xpIq0wQ8r1q4Su
|
|||
golang.org/x/net v0.0.0-20220425223048-2871e0cb64e4/go.mod h1:CfG3xpIq0wQ8r1q4Su4UZFWDARRcnwPjda9FqA0JpMk=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b h1:ZmngSVLe/wycRns9MKikG9OWIEjGcGAkacif7oYQaUY=
|
||||
golang.org/x/net v0.0.0-20220826154423-83b083e8dc8b/go.mod h1:YDH+HFinaLZZlnHAfSS6ZXJJ9M9t4Dl22yv3iI2vPwk=
|
||||
golang.org/x/net v0.14.0/go.mod h1:PpSgVXXLK0OxS0F31C1/tv6XNguvCrnXIDrFMspZIUI=
|
||||
golang.org/x/sync v0.0.0-20180314180146-1d60e4601c6f/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20190423024810-112230192c58/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
golang.org/x/sync v0.0.0-20201020160332-67f06af15bc9/go.mod h1:RxMgew5VJxzue5/jJTE5uejpjVlOe/izrB70Jof72aM=
|
||||
|
@ -143,8 +137,6 @@ golang.org/x/sys v0.0.0-20220422013727-9388b58f7150/go.mod h1:oPkhp1MJrh7nUepCBc
|
|||
golang.org/x/sys v0.0.0-20220728004956-3c1f35247d10/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64 h1:UiNENfZ8gDvpiWw7IpOMQ27spWmThO1RwwdQVbJahJM=
|
||||
golang.org/x/sys v0.0.0-20220825204002-c680a09ffe64/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/sys v0.11.0 h1:eG7RXZHdqOJ1i+0lgLgCpSXAp6M3LYlAo6osgSi0xOM=
|
||||
golang.org/x/sys v0.11.0/go.mod h1:oPkhp1MJrh7nUepCBck5+mAzfO9JrbApNNgaTdGDITg=
|
||||
golang.org/x/term v0.0.0-20201126162022-7de9c90e9dd1/go.mod h1:bj7SfCRtBDWHUb9snDiAeCFNEtKQo2Wmx5Cou7ajbmo=
|
||||
golang.org/x/term v0.0.0-20210927222741-03fcf44c2211/go.mod h1:jbD1KX2456YbFQfuXm/mYQcufACuNUgVhRMnK/tPxf8=
|
||||
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
|
||||
|
@ -158,8 +150,6 @@ golang.org/x/tools v0.0.0-20201224043029-2b0845dc783e/go.mod h1:emZCQorbCU4vsT4f
|
|||
golang.org/x/tools v0.1.10/go.mod h1:Uh6Zz+xoGYZom868N8YTex3t7RhtHDBrE8Gzo9bV56E=
|
||||
golang.org/x/tools v0.1.12 h1:VveCTK38A2rkS8ZqFY25HIDFscX5X9OoEhJd3quQmXU=
|
||||
golang.org/x/tools v0.1.12/go.mod h1:hNGJHUnrk76NpqgfD5Aqm5Crs+Hm0VOH/i9J2+nxYbc=
|
||||
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60 h1:o4bs4seAAlSiZQAZbO6/RP5XBCZCooQS3Pgc0AUjWts=
|
||||
golang.org/x/tools v0.12.1-0.20230818130535-1517d1a3ba60/go.mod h1:Sc0INKfu04TlqNoRA1hgpFZbhYXHPr4V5DzpSBTPqQM=
|
||||
golang.org/x/xerrors v0.0.0-20190717185122-a985d3407aa7/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191011141410-1b5146add898/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
golang.org/x/xerrors v0.0.0-20191204190536-9bdfabe68543/go.mod h1:I/5z698sn9Ka8TeJc9MKroUUfqBBauWjQqLJ2OPfmY0=
|
||||
|
|
27
quality.sh
27
quality.sh
|
@ -3,22 +3,29 @@
|
|||
echo "Checking code quality (you want to see no output here)"
|
||||
echo ""
|
||||
|
||||
echo "Vetting:"
|
||||
go vet generate/*
|
||||
|
||||
echo ""
|
||||
echo "Linting:"
|
||||
echo "Running staticcheck..."
|
||||
|
||||
staticcheck ./generate
|
||||
staticcheck lib.go
|
||||
staticcheck ./utils/*
|
||||
|
||||
# In the future we should remove include-pkgs. However, there are a few false positives in the overall go stdlib that make this
|
||||
# too noisy right now, specifically assigning nil to initialize slices (safe), and using go internal context channels assigned
|
||||
# nil (also safe).
|
||||
# We also have one file infinite_channel.go written in a way that static analysis cannot reason about easily. So it is explictly
|
||||
# ignored.
|
||||
echo "Running nilaway..."
|
||||
nilaway -include-pkgs="git.openprivacy.ca/cwtch.im/cwtch-autobindings,cwtch.im/cwtch,cwtch.im/tapir,git.openprivacy.ca/openprivacy/connectivity" -exclude-errors-in-files="./templates/lib_template.go" -exclude-file-docstrings="nolint:nilaway" lib.go
|
||||
nilaway -include-pkgs="git.openprivacy.ca/cwtch.im/cwtch-autobindings,cwtch.im/cwtch,cwtch.im/tapir,git.openprivacy.ca/openprivacy/connectivity" -exclude-errors-in-files="./templates/lib_template.go" -exclude-file-docstrings="nolint:nilaway" ./utils/
|
||||
|
||||
echo "Time to format"
|
||||
gofmt -l -s -w .
|
||||
gofmt -l -s -w ./utils/*
|
||||
gofmt -l -s -w ./generate/*
|
||||
|
||||
# ineffassign (https://github.com/gordonklaus/ineffassign)
|
||||
echo "Checking for ineffectual assignment of errors (unchecked errors...)"
|
||||
ineffassign .
|
||||
# echo "Checking for ineffectual assignment of errors (unchecked errors...)"
|
||||
# ineffassign .
|
||||
|
||||
# misspell (https://github.com/client9/misspell/cmd/misspell)
|
||||
echo "Checking for misspelled words..."
|
||||
misspell . | grep -v "testing/" | grep -v "vendor/" | grep -v "go.sum" | grep -v ".idea"
|
||||
# echo "Checking for misspelled words..."
|
||||
# misspell . | grep -v "testing/" | grep -v "vendor/" | grep -v "go.sum" | grep -v ".idea"
|
||||
|
|
10
spec
10
spec
|
@ -3,6 +3,7 @@
|
|||
# Peer Engine
|
||||
app ActivatePeerEngine profile
|
||||
app DeactivatePeerEngine profile
|
||||
app ConfigureConnections profile bool:listen bool:peers bool:servers
|
||||
|
||||
# Profile Management
|
||||
app CreateProfile name password bool:autostart
|
||||
|
@ -20,6 +21,9 @@ profile BlockConversation conversation
|
|||
profile UnblockConversation conversation
|
||||
profile DeleteConversation conversation
|
||||
profile PeerWithOnion string:handle
|
||||
profile DisconnectFromPeer string:handle
|
||||
(json-err)profile EnhancedGetConversationAccessControlList conversation
|
||||
profile EnhancedUpdateConversationAccessControlList conversation string:json
|
||||
|
||||
# Search
|
||||
(json)profile SearchConversations string:pattern
|
||||
|
@ -28,17 +32,19 @@ profile PeerWithOnion string:handle
|
|||
(json)profile EnhancedSendMessage conversation string:msg
|
||||
(json)profile EnhancedGetMessageById conversation message
|
||||
(json)profile EnhancedGetMessageByContentHash conversation string:contentHash
|
||||
(json)profile EnhancedGetMessages conversation int:index int:count
|
||||
(json)profile EnhancedGetMessages conversation int:index uint:count
|
||||
(json)profile EnhancedSendInviteMessage conversation conversation:target
|
||||
profile UpdateMessageAttribute conversation channel message string:attributeKey string:attributeValue
|
||||
|
||||
# Group Management
|
||||
profile StartGroup string:name string:server
|
||||
profile QueueJoinServer string:handle
|
||||
profile DisconnectFromServer string:handle
|
||||
|
||||
## Server List Management...
|
||||
import "cwtch.im/cwtch/functionality/servers"
|
||||
@profile-experiment PublishServerUpdate servers
|
||||
@profile-experiment GetServerInfoList servers
|
||||
@profile-experiment GetServerInfo servers string:serverOnion
|
||||
@profile-experiment DeleteServerInfo servers string:serverOnion
|
||||
|
||||
# Filesharing Management
|
||||
|
|
|
@ -22,6 +22,7 @@ import (
|
|||
"runtime"
|
||||
"runtime/pprof"
|
||||
"strings"
|
||||
"strconv"
|
||||
"time"
|
||||
mrand "math/rand"
|
||||
"crypto/rand"
|
||||
|
@ -189,7 +190,6 @@ func _startCwtch(appDir string, torPath string) {
|
|||
log.Infof("libcwtch-go application launched")
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{}))
|
||||
application.QueryACNVersion()
|
||||
application.LoadProfiles(app.DefactoPasswordForUnencryptedProfiles)
|
||||
|
||||
{{EXPERIMENT_REGISTER}}
|
||||
|
||||
|
@ -247,7 +247,7 @@ func ReconnectCwtchForeground() {
|
|||
|
||||
settingsJson, _ := json.Marshal(application.ReadSettings())
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.UpdateGlobalSettings, map[event.Field]string{event.Data: string(settingsJson)}))
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{}))
|
||||
application.GetPrimaryBus().Publish(event.NewEvent(settings.CwtchStarted, map[event.Field]string{utils.ReloadEvent: event.True}))
|
||||
application.QueryACNStatus()
|
||||
application.QueryACNVersion()
|
||||
}
|
||||
|
@ -314,6 +314,8 @@ func SetProfileAttribute(profileOnion string, key string, value string) {
|
|||
profile.SetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.ProfileStatus, value)
|
||||
} else if zone == attr.ProfileZone && key == constants.PeerAutostart {
|
||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAutostart, value)
|
||||
} else if zone == attr.ProfileZone && key == constants.PeerAppearOffline {
|
||||
profile.SetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline, value)
|
||||
} else {
|
||||
log.Errorf("attempted to set an attribute with an unknown zone: %v", key)
|
||||
}
|
||||
|
@ -440,7 +442,6 @@ const (
|
|||
|
||||
func buildACN(globalSettings settings.GlobalSettings, torPath string, appDir string) (connectivity.ACN, settings.GlobalSettings, error) {
|
||||
|
||||
mrand.Seed(int64(time.Now().Nanosecond()))
|
||||
socksPort := mrand.Intn(1000) + 9600
|
||||
controlPort := socksPort + 1
|
||||
|
||||
|
@ -469,7 +470,30 @@ func buildACN(globalSettings settings.GlobalSettings, torPath string, appDir str
|
|||
// Override Ports if on Tails...
|
||||
if cwtchTails := os.Getenv("CWTCH_TAILS"); strings.ToLower(cwtchTails) == "true" {
|
||||
log.Infof("CWTCH_TAILS environment variable set... overriding tor config...")
|
||||
|
||||
controlPort = 9051
|
||||
|
||||
// In tails 5.13 the control port was changed to 951
|
||||
// so read the Tails Version File and if it exists...
|
||||
b, err := os.ReadFile("/etc/amnesia/version")
|
||||
if err == nil {
|
||||
// the file should start with the version followed
|
||||
// by a space...
|
||||
versionEnd := strings.Index(string(b), " ")
|
||||
versionStr := string(b)[:versionEnd]
|
||||
version, err := strconv.ParseFloat(versionStr, 64)
|
||||
if err == nil {
|
||||
log.Infof("Confirming Tails Version: %v", version)
|
||||
// assert the control port if we are at the dedicated version...
|
||||
// we know this change happened sometime after 5.11
|
||||
if version >= 5.13 {
|
||||
controlPort = 951
|
||||
}
|
||||
} else {
|
||||
log.Errorf("Unable to confirm Tails version. CWTCH_TAILS options may not function correctly.")
|
||||
}
|
||||
}
|
||||
|
||||
socksPort = 9050
|
||||
globalSettings.CustomControlPort = controlPort
|
||||
globalSettings.CustomSocksPort = socksPort
|
||||
|
|
|
@ -145,9 +145,15 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
|
||||
// Start up the Profile
|
||||
if acnStatus == 100 {
|
||||
autostart, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants2.PeerAutostart)
|
||||
autostart, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAutostart)
|
||||
appearOffline, appearOfflineExists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline)
|
||||
if !exists || autostart == "true" {
|
||||
eh.app.ActivatePeerEngine(onion)
|
||||
if appearOfflineExists && appearOffline == "true" {
|
||||
// don't configure any connections...
|
||||
} else {
|
||||
eh.app.ConfigureConnections(onion, true, true, true)
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -161,6 +167,13 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
}
|
||||
e.Data["autostart"] = autostart
|
||||
|
||||
appearOffline, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.ProfileZone, constants.PeerAppearOffline)
|
||||
// legacy profiles should not appearOffline by default
|
||||
if !exists {
|
||||
appearOffline = "false"
|
||||
}
|
||||
e.Data["appearOffline"] = appearOffline
|
||||
|
||||
// Name always exists
|
||||
e.Data[constants.Name], _ = profile.GetScopedZonedAttribute(attr.PublicScope, attr.ProfileZone, constants.Name)
|
||||
e.Data[constants2.DefaultProfilePicture] = RandomProfileImage(onion)
|
||||
|
@ -187,7 +200,8 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
if conversationInfo.IsServer() {
|
||||
groupHandler := servers.FunctionalityGate()
|
||||
if err == nil {
|
||||
knownServers = append(knownServers, groupHandler.GetServerInfo(profile, conversationInfo.Handle))
|
||||
serverInfo, _ := groupHandler.GetServerInfo(profile, conversationInfo.Handle)
|
||||
knownServers = append(knownServers, serverInfo)
|
||||
}
|
||||
continue
|
||||
}
|
||||
|
@ -210,7 +224,7 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
cpicPath = RandomGroupImage(conversationInfo.Handle)
|
||||
defaultPath = RandomGroupImage(conversationInfo.Handle)
|
||||
} else {
|
||||
cpicPath = GetProfileImage(profile, conversationInfo, settings.DownloadPath)
|
||||
cpicPath = eh.GetProfileImage(profile, conversationInfo, settings.DownloadPath)
|
||||
defaultPath = RandomProfileImage(conversationInfo.Handle)
|
||||
}
|
||||
|
||||
|
@ -319,15 +333,17 @@ func (eh *EventHandler) handleAppBusEvent(e *event.Event) string {
|
|||
return string(json)
|
||||
}
|
||||
|
||||
func GetProfileImage(profile peer.CwtchPeer, conversationInfo *model.Conversation, basepath string) string {
|
||||
fileKey, err := profile.GetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.CustomProfileImageKey)))
|
||||
if err == nil {
|
||||
if value, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey)); exists && value == event.True {
|
||||
fp, _ := filesharing.GenerateDownloadPath(basepath, fileKey, true)
|
||||
// check if the file exists...if it does then set the path...
|
||||
if _, err := os.Stat(fp); err == nil {
|
||||
image, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey))
|
||||
return image
|
||||
func (eh *EventHandler) GetProfileImage(profile peer.CwtchPeer, conversationInfo *model.Conversation, basepath string) string {
|
||||
if eh.app.IsFeatureEnabled(constants.ImagePreviewsExperiment) {
|
||||
fileKey, err := profile.GetConversationAttribute(conversationInfo.ID, attr.PublicScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants.CustomProfileImageKey)))
|
||||
if err == nil {
|
||||
if value, exists := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.complete", fileKey)); exists && value == event.True {
|
||||
fp, _ := filesharing.GenerateDownloadPath(basepath, fileKey, true)
|
||||
// check if the file exists...if it does then set the path...
|
||||
if _, err := os.Stat(fp); err == nil {
|
||||
image, _ := profile.GetScopedZonedAttribute(attr.LocalScope, attr.FilesharingZone, fmt.Sprintf("%s.path", fileKey))
|
||||
return image
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -343,6 +359,10 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
log.Errorf("eh.app == nil in handleProfileEvent... this shouldnt happen?")
|
||||
} else {
|
||||
profile := eh.app.GetPeer(ev.Profile)
|
||||
if profile == nil {
|
||||
log.Errorf("something has gone very wrong. profile is nil in handleProfileEvent")
|
||||
return ""
|
||||
}
|
||||
log.Debugf("New Profile Event to Handle: %v", ev)
|
||||
switch ev.Event.EventType {
|
||||
case event.NewMessageFromPeer: //event.TimestampReceived, event.RemotePeer, event.Data
|
||||
|
@ -352,7 +372,7 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
if ci != nil && err == nil {
|
||||
ev.Event.Data[event.ConversationID] = strconv.Itoa(ci.ID)
|
||||
profile.SetConversationAttribute(ci.ID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
ev.Event.Data[constants2.Picture] = GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
ev.Event.Data[constants2.Picture] = eh.GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
} else {
|
||||
// TODO This Conversation May Not Exist Yet...But we are not in charge of creating it...
|
||||
log.Errorf("todo wait for contact to be added before processing this event...")
|
||||
|
@ -381,13 +401,17 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
ev.Event.Data["Nick"] = ev.Event.Data["RemotePeer"]
|
||||
}
|
||||
}
|
||||
ev.Event.Data[constants2.Picture] = GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
ev.Event.Data[constants2.Picture] = eh.GetProfileImage(profile, ci, eh.app.ReadSettings().DownloadPath)
|
||||
}
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
profile.SetConversationAttribute(conversationID, attr.LocalScope.ConstructScopedZonedPath(attr.ProfileZone.ConstructZonedPath(constants2.Archived)), event.False)
|
||||
|
||||
gci, _ := profile.GetConversationInfo(conversationID)
|
||||
gci, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("new message from non-existant group: %v", err)
|
||||
break
|
||||
}
|
||||
groupServer := gci.Attributes[attr.LocalScope.ConstructScopedZonedPath(attr.LegacyGroupZone.ConstructZonedPath(constants.GroupServer)).ToString()]
|
||||
state := profile.GetPeerState(groupServer)
|
||||
// if syncing, don't flood with notifications
|
||||
|
@ -406,11 +430,13 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
count, err := profile.GetChannelMessageCount(conversationID, 0)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching channel message count %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
|
||||
blocked := constants.False
|
||||
|
@ -423,7 +449,11 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
accepted = constants.True
|
||||
}
|
||||
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
acl, err := json.Marshal(conversationInfo.ACL)
|
||||
if err != nil {
|
||||
log.Errorf("received invalid ACL in conversation: %v", err)
|
||||
break
|
||||
}
|
||||
|
||||
lastMessage, _ := profile.GetMostRecentMessages(conversationID, 0, 0, 1)
|
||||
ev.Event.Data["unread"] = strconv.Itoa(count) // if this is a new contact with messages attached then by-definition these are unread...
|
||||
|
@ -443,8 +473,16 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
groupPic := RandomGroupImage(ev.Event.Data[event.GroupID])
|
||||
ev.Event.Data[constants2.Picture] = groupPic
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationInfo, _ := profile.GetConversationInfo(conversationID)
|
||||
conversationID, err := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
if err != nil {
|
||||
log.Errorf("invalid conversation id recieved %v", err)
|
||||
break
|
||||
}
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
ev.Event.Data["accessControlList"] = string(acl)
|
||||
case event.NewGroup:
|
||||
|
@ -455,51 +493,34 @@ func (eh *EventHandler) handleProfileEvent(ev *EventProfileEnvelope) string {
|
|||
groupPic := RandomGroupImage(invite.GroupID)
|
||||
ev.Event.Data[constants2.Picture] = groupPic
|
||||
|
||||
conversationID, _ := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
conversationInfo, _ := profile.GetConversationInfo(conversationID)
|
||||
acl, _ := json.Marshal(conversationInfo.ACL)
|
||||
conversationID, err := strconv.Atoi(ev.Event.Data[event.ConversationID])
|
||||
if err != nil {
|
||||
log.Errorf("invalid conversation id recieved %v", err)
|
||||
break
|
||||
}
|
||||
conversationInfo, err := profile.GetConversationInfo(conversationID)
|
||||
if err != nil {
|
||||
log.Errorf("error fetching conversation info for %v %v", conversationID, err)
|
||||
break
|
||||
}
|
||||
acl, err := json.Marshal(conversationInfo.ACL)
|
||||
ev.Event.Data["accessControlList"] = string(acl)
|
||||
if err != nil {
|
||||
log.Errorf("received invalid ACL in conversation: %v", err)
|
||||
break
|
||||
}
|
||||
} else {
|
||||
log.Errorf("received a new group event which contained an invalid invite %v. this should never happen and likely means there is a bug in cwtch. Please file a ticket @ https://git.openprivacy.ca/cwtch.im/cwtch", err)
|
||||
return ""
|
||||
}
|
||||
case event.PeerStateChange:
|
||||
cxnState := connections.ConnectionStateToType()[ev.Event.Data[event.ConnectionState]]
|
||||
|
||||
// skip events the UI doesn't act on
|
||||
if cxnState == connections.CONNECTING || cxnState == connections.CONNECTED {
|
||||
return ""
|
||||
}
|
||||
|
||||
contact, err := profile.FetchConversationInfo(ev.Event.Data[event.RemotePeer])
|
||||
|
||||
if ev.Event.Data[event.RemotePeer] == profile.GetOnion() {
|
||||
return "" // suppress events from our own profile...
|
||||
}
|
||||
|
||||
// We do not know who this is...don't send any event until we see a message from them
|
||||
// (at that point the conversation will have been created...)
|
||||
if contact == nil || err != nil || contact.ID == 0 {
|
||||
return ""
|
||||
}
|
||||
|
||||
// if we already know this state, suppress
|
||||
if knownState, exists := contactStateCache[ev.Event.Data[event.RemotePeer]]; exists && cxnState == knownState {
|
||||
return ""
|
||||
}
|
||||
contactStateCache[ev.Event.Data[event.RemotePeer]] = cxnState
|
||||
case event.ServerStateChange:
|
||||
cxnState := connections.ConnectionStateToType()[ev.Event.Data[event.ConnectionState]]
|
||||
|
||||
// skip events the UI doesn't act on
|
||||
if cxnState == connections.CONNECTING || cxnState == connections.CONNECTED {
|
||||
return ""
|
||||
}
|
||||
|
||||
// if we already know this state, suppress
|
||||
if knownState, exists := contactStateCache[ev.Event.Data[event.RemotePeer]]; exists && cxnState == knownState {
|
||||
return ""
|
||||
}
|
||||
contactStateCache[ev.Event.Data[event.RemotePeer]] = cxnState
|
||||
case event.TokenManagerInfo:
|
||||
conversations, err := profile.FetchConversations()
|
||||
|
@ -545,6 +566,10 @@ func unwrap(original *EventProfileEnvelope) *event.Event {
|
|||
|
||||
func (eh *EventHandler) startHandlingPeer(onion string) {
|
||||
eventBus := eh.app.GetEventBus(onion)
|
||||
if eventBus == nil {
|
||||
log.Errorf("could not start handling peer events .. event bus is nil")
|
||||
return
|
||||
}
|
||||
q := event.NewQueue()
|
||||
|
||||
eventBus.Subscribe(event.NetworkStatus, q)
|
||||
|
|
Loading…
Reference in New Issue