From bab572a164bf1dd34c27ec7e853d17e95e92d283 Mon Sep 17 00:00:00 2001 From: erinn Date: Fri, 12 Oct 2018 18:24:22 -0700 Subject: [PATCH] adding secret cwtch group support --- main.go | 153 ++++++++++++++++++++++++++++++++++++++++++++++++++++++-- 1 file changed, 150 insertions(+), 3 deletions(-) diff --git a/main.go b/main.go index e357932..4e13299 100644 --- a/main.go +++ b/main.go @@ -16,6 +16,7 @@ import ( "io/ioutil" "sync" "cwtch.im/cwtch/peer/connections" + "math/rand" ) func driftoff() { @@ -49,9 +50,14 @@ func exitOnEnter() { } func printHelp() { + // "group" is a secret feature so please don't add it here yet fmt.Println("usage: sendafriend [command] [options]\nCommands: help, setname, info, list, add, send, receive, hide, seek") } +func printGroupHelp() { + fmt.Println("usage: sendafriend group {list, create, import, export, send, listen}") +} + func main() { if len(os.Args) < 2 { printHelp() @@ -66,7 +72,10 @@ func main() { // this is a cwtch server used only to make the "pair" command work // it is completely untrusted and only blinded information is passed through it // it can point to any ol cwtch group, as long as both people running "pair" are using the same one - inviteStr := "torv30I0zJgNiUz57gJlxFsp4PUq47WDoKNCL95GEadaLlEE=EsABCiA1MjQzYjNkNzczMjAwNzc1MDExMDI0MjJkM2NkOGNmZBIgsXZKp350ShZ2l3iqOh4ZhGJmj0Etb5QmkL5iLZno9AQaOGZxcWJkNWxrNzRnbG5zZ292aXVuNm92Z3V0MmNqY252Mm12aWdvamNuc21wd3NucTJ5ZGpmM3FkIkD5x/JNhpLVe982dE9+3mp1IEog6O8yGdrIuUs0Tb6F1Fh1J1zuv1nJBFECuzYyF1yhqNvOn9Z6MatXVi+PKQIO" + hidenseekInviteStr := "torv30I0zJgNiUz57gJlxFsp4PUq47WDoKNCL95GEadaLlEE=EsABCiA1MjQzYjNkNzczMjAwNzc1MDExMDI0MjJkM2NkOGNmZBIgsXZKp350ShZ2l3iqOh4ZhGJmj0Etb5QmkL5iLZno9AQaOGZxcWJkNWxrNzRnbG5zZ292aXVuNm92Z3V0MmNqY252Mm12aWdvamNuc21wd3NucTJ5ZGpmM3FkIkD5x/JNhpLVe982dE9+3mp1IEog6O8yGdrIuUs0Tb6F1Fh1J1zuv1nJBFECuzYyF1yhqNvOn9Z6MatXVi+PKQIO" + + // the set of servers to randomly pick from when using "sendafriend group create" + serverList := []string{"fqqbd5lk74glnsgoviun6ovgut2cjcnv2mvigojcnsmpwsnq2ydjf3qd"} var dirname, filename string if os.Getenv("SENDAFRIEND_FOLDER") != "" { @@ -228,7 +237,7 @@ func main() { os.Exit(1) } - groupId, err := ephemeralPeer.ImportGroup(inviteStr) + groupId, err := ephemeralPeer.ImportGroup(hidenseekInviteStr) if err != nil { fmt.Printf("couldn't configure the bbs settings: %v\n", err) os.Exit(1) @@ -290,7 +299,7 @@ func main() { os.Exit(1) } - groupId, err := ephemeralPeer.ImportGroup(inviteStr) + groupId, err := ephemeralPeer.ImportGroup(hidenseekInviteStr) if err != nil { fmt.Printf("couldn't configure the bbs settings: %v\n", err) os.Exit(1) @@ -315,6 +324,144 @@ func main() { } } waitGroup.Wait() + case "group": + if len(os.Args) < 3 { + printGroupHelp() + os.Exit(1) + } + + switch os.Args[2] { + default: + printGroupHelp() + case "help": + printGroupHelp() + case "list": + groups := peer.GetGroups() + for i := range groups { + g := peer.GetGroup(groups[i]) + groupName, _ := peer.GetProfile().GetCustomAttribute(g.GroupID + "_groupname") + fmt.Printf("%v <%v@%v>\n", groupName, g.GroupID, g.GroupServer) + } + case "create": + if len(os.Args) != 4 { + fmt.Println("example: sendafriend group create [groupname]") + os.Exit(1) + } + + groupId, _, err := peer.StartGroup(serverList[rand.Intn(len(serverList))]) + if err != nil { + fmt.Printf("couldn't create a group: %v\n", err) + os.Exit(1) + } + + invite, err := peer.ExportGroup(groupId) + if err != nil { + fmt.Printf("couldn't export group: %v\n", err) + os.Exit(1) + } + + peer.GetProfile().SetCustomAttribute(os.Args[3] + "_groupid", groupId) + peer.GetProfile().SetCustomAttribute(groupId + "_groupname", os.Args[3]) + + fmt.Printf("created group %v <%v> with invite: %v\n", os.Args[3], groupId, invite) + case "import": + if len(os.Args) != 5 { + fmt.Println("example: sendafriend group import [groupname] [groupstr]") + os.Exit(1) + } + + groupId, err := peer.ImportGroup(os.Args[4]) + if err != nil { + fmt.Printf("couldn't import the group: %v\n", err) + os.Exit(1) + } + + peer.GetProfile().SetCustomAttribute(os.Args[3] + "_groupid", groupId) + peer.GetProfile().SetCustomAttribute(groupId + "_groupname", os.Args[3]) + case "export": + if len(os.Args) != 4 { + fmt.Println("example: sendafriend group export [groupname") + os.Exit(1) + } + + groupId, exists := peer.GetProfile().GetCustomAttribute(os.Args[3] + "_groupid") + if !exists { + fmt.Printf("you don't seem to have a group called %v\n", os.Args[3]) + os.Exit(1) + } + + exportStr, err := peer.ExportGroup(groupId) + if err != nil { + fmt.Printf("couldn't export group: %v\n", err) + os.Exit(1) + } + + fmt.Println(exportStr) + case "send": + if len(os.Args) != 4 { + fmt.Println("example: echo \"go!\" | sendafriend group send [groupname]") + os.Exit(1) + } + + groupId, exists := peer.GetProfile().GetCustomAttribute(os.Args[3] + "_groupid") + if !exists { + fmt.Printf("you don't seem to have a group called %v\n", os.Args[3]) + os.Exit(1) + } + g := peer.GetGroup(groupId) + + reader := bufio.NewReader(os.Stdin) + message := make([]byte, 1025) + br, err := reader.Read(message) + if err != nil { + fmt.Println("error reading input") + os.Exit(1) + } + message = message[:br] + + if br > 1024 { + fmt.Println("sorry, this feature uses cwtch groups which currently only support up to 1024 byte messages") + os.Exit(1) + } + + fmt.Println("sending...") + peer.JoinServer(g.GroupServer) + mp := peer.GetServers() + for ; mp[g.GroupServer] != connections.AUTHENTICATED; mp = peer.GetServers() { + time.Sleep(time.Millisecond * 500) + } + + err = peer.SendMessageToGroup(groupId, string(message)) + if err != nil { + fmt.Printf("error sending message: %v\n", err) + os.Exit(1) + } + case "listen": + if len(os.Args) != 4 { + fmt.Println("example: sendafriend group listen [groupname]") + os.Exit(1) + } + + groupId, exists := peer.GetProfile().GetCustomAttribute(os.Args[3] + "_groupid") + if !exists { + fmt.Printf("you don't seem to have a group called %v\n", os.Args[3]) + os.Exit(1) + } + + group := peer.GetGroup(groupId) + if group == nil { + fmt.Printf("storage out of sync. please report this bug as it shouldn't have happened\n") + os.Exit(1) + } + + group.NewMessage = make(chan model.Message) + peer.JoinServer(group.GroupServer) + + for { + m := <-group.NewMessage + fmt.Printf("%v\n", m.Message) + } + } } peer.Save()