150 lines
3.6 KiB
Go
150 lines
3.6 KiB
Go
|
package main
|
||
|
|
||
|
import "C"
|
||
|
import (
|
||
|
"crypto/rand"
|
||
|
"cwtch.im/cwtch/app"
|
||
|
"cwtch.im/cwtch/event"
|
||
|
"cwtch.im/cwtch/peer"
|
||
|
"encoding/json"
|
||
|
"fmt"
|
||
|
|
||
|
"encoding/base64"
|
||
|
"git.openprivacy.ca/openprivacy/connectivity/tor"
|
||
|
"git.openprivacy.ca/openprivacy/log"
|
||
|
mrand "math/rand"
|
||
|
"os"
|
||
|
"path"
|
||
|
"path/filepath"
|
||
|
"time"
|
||
|
)
|
||
|
|
||
|
var application app.Application
|
||
|
var acnQueue event.Queue
|
||
|
var contactEventsQueue event.Queue
|
||
|
|
||
|
//export HelloWorld
|
||
|
func HelloWorld(a C.int, b C.int) C.int {
|
||
|
return a+b
|
||
|
}
|
||
|
|
||
|
//export StartCwtch
|
||
|
func StartCwtch(dir_c *C.char, len C.int) {
|
||
|
dir := C.GoStringN(dir_c, len)
|
||
|
log.SetLevel(log.LevelDebug)
|
||
|
log.Infof("Loading Cwtch Directory %v", dir)
|
||
|
|
||
|
mrand.Seed(int64(time.Now().Nanosecond()))
|
||
|
port := mrand.Intn(1000) + 9600
|
||
|
controlPort := port + 1
|
||
|
|
||
|
// generate a random password (actually random, stored in memory, for the control port)
|
||
|
key := make([]byte, 64)
|
||
|
_, err := rand.Read(key)
|
||
|
if err != nil {
|
||
|
panic(err)
|
||
|
}
|
||
|
|
||
|
log.Infof("making directory %v", dir)
|
||
|
os.MkdirAll(path.Join(dir, "/.tor","tor"),0700)
|
||
|
tor.NewTorrc().WithSocksPort(port).WithOnionTrafficOnly().WithControlPort(controlPort).WithHashedPassword(base64.StdEncoding.EncodeToString(key)).Build(filepath.Join(dir, ".tor", "tor", "torrc"))
|
||
|
acn, err := tor.NewTorACNWithAuth(path.Join(dir, "/.tor"), "", controlPort, tor.HashedPasswordAuthenticator{base64.StdEncoding.EncodeToString(key)})
|
||
|
if err != nil {
|
||
|
log.Errorf("\nError connecting to Tor: %v\n", err)
|
||
|
}
|
||
|
//acn.WaitTillBootstrapped()
|
||
|
|
||
|
|
||
|
newApp := app.NewApp(acn, dir)
|
||
|
id := mrand.Int31()
|
||
|
acnQueue = event.NewQueue()
|
||
|
newApp.GetPrimaryBus().Subscribe(event.ACNStatus, acnQueue)
|
||
|
peer.DefaultEventsToHandle = []event.Type{
|
||
|
event.EncryptedGroupMessage,
|
||
|
event.NewMessageFromPeer,
|
||
|
event.PeerAcknowledgement,
|
||
|
event.NewGroupInvite,
|
||
|
event.PeerError,
|
||
|
event.SendMessageToGroupError,
|
||
|
event.NewGetValMessageFromPeer,
|
||
|
event.PeerStateChange,
|
||
|
}
|
||
|
newApp.LoadProfiles("awesome")
|
||
|
newApp.LaunchPeers()
|
||
|
application = newApp
|
||
|
log.Infof("Providing Handle %v", id)
|
||
|
}
|
||
|
|
||
|
//export ACNEvents
|
||
|
func ACNEvents() *C.char {
|
||
|
select {
|
||
|
case event := <- acnQueue.OutChan():
|
||
|
return C.CString(fmt.Sprintf("%v", event))
|
||
|
default:
|
||
|
return C.CString("")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
//export NextEvent
|
||
|
func NextEvent() {
|
||
|
|
||
|
}
|
||
|
|
||
|
//export GetProfiles
|
||
|
func GetProfiles() *C.char {
|
||
|
profiles := application.ListPeers()
|
||
|
jsonBytes,_ := json.Marshal(profiles)
|
||
|
return C.CString(string(jsonBytes))
|
||
|
}
|
||
|
|
||
|
type Contact struct {
|
||
|
Name string `json:"name"`
|
||
|
Onion string `json:"onion"`
|
||
|
Status string `json:"status"`
|
||
|
}
|
||
|
|
||
|
//export GetContacts
|
||
|
func GetContacts(onion_ptr *C.char, onion_len C.int) *C.char {
|
||
|
|
||
|
onion := C.GoStringN(onion_ptr, onion_len)
|
||
|
log.Infof("Get Contacts for %v", onion)
|
||
|
peer := application.GetPeer(onion)
|
||
|
|
||
|
contactEventsQueue = event.NewQueue()
|
||
|
application.GetEventBus(onion).Subscribe(event.PeerStateChange, contactEventsQueue)
|
||
|
|
||
|
var contacts []Contact
|
||
|
for _,contact := range peer.GetContacts() {
|
||
|
contactInfo := peer.GetContact(contact)
|
||
|
log.Infof("contactInfo %v", contactInfo)
|
||
|
contacts = append(contacts, Contact{Name: contactInfo.Name, Onion: contactInfo.Onion, Status: contactInfo.State})
|
||
|
}
|
||
|
|
||
|
byte,_ := json.Marshal(contacts)
|
||
|
return C.CString(string(byte))
|
||
|
}
|
||
|
|
||
|
|
||
|
|
||
|
//export SelectProfile
|
||
|
func SelectProfile(onion_ptr *C.char, onion_len C.int) *C.char {
|
||
|
onion := C.GoStringN(onion_ptr, onion_len)
|
||
|
log.Infof("Select Profile: %v", onion)
|
||
|
contactEventsQueue = event.NewQueue()
|
||
|
application.GetEventBus(onion).Subscribe(event.PeerStateChange, contactEventsQueue)
|
||
|
return C.CString("")
|
||
|
}
|
||
|
|
||
|
//export ContactEvents
|
||
|
func ContactEvents() *C.char {
|
||
|
select {
|
||
|
case event := <- contactEventsQueue.OutChan():
|
||
|
return C.CString(fmt.Sprintf("%v", event))
|
||
|
default:
|
||
|
return C.CString("")
|
||
|
}
|
||
|
}
|
||
|
|
||
|
func main() {
|
||
|
|
||
|
}
|