Merge branch 'cwtchutil' of cwtch.im/cwtch into master
This commit is contained in:
commit
b58512693d
|
@ -10,7 +10,7 @@ pipeline:
|
||||||
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
- wget https://git.openprivacy.ca/openprivacy/buildfiles/raw/master/tor/torrc
|
||||||
- chmod a+x tor
|
- chmod a+x tor
|
||||||
- go list ./... | xargs go get
|
- go list ./... | xargs go get
|
||||||
- go get -u github.com/golang/lint/golint
|
- go get -u golang.org/x/lint/golint
|
||||||
quality:
|
quality:
|
||||||
image: golang
|
image: golang
|
||||||
commands:
|
commands:
|
||||||
|
|
|
@ -529,6 +529,18 @@ func main() {
|
||||||
} else {
|
} else {
|
||||||
fmt.Printf("Error exporting group, usage: %s\n", usages[commands[0]])
|
fmt.Printf("Error exporting group, usage: %s\n", usages[commands[0]])
|
||||||
}
|
}
|
||||||
|
case "/import-group":
|
||||||
|
if len(commands) == 2 {
|
||||||
|
groupID, err := peer.ImportGroup(commands[1])
|
||||||
|
if err != nil {
|
||||||
|
fmt.Printf("Error importing group: %v\n", err)
|
||||||
|
} else {
|
||||||
|
fmt.Printf("Imported group: %s\n", groupID)
|
||||||
|
}
|
||||||
|
} else {
|
||||||
|
fmt.Printf("%v", commands)
|
||||||
|
fmt.Printf("Error importing group, usage: %s\n", usages[commands[0]])
|
||||||
|
}
|
||||||
case "/save":
|
case "/save":
|
||||||
peer.Save()
|
peer.Save()
|
||||||
case "/help":
|
case "/help":
|
||||||
|
|
|
@ -0,0 +1,186 @@
|
||||||
|
package main
|
||||||
|
|
||||||
|
import (
|
||||||
|
"bufio"
|
||||||
|
"crypto/rand"
|
||||||
|
libpeer "cwtch.im/cwtch/peer"
|
||||||
|
"fmt"
|
||||||
|
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
||||||
|
"github.com/sethvargo/go-diceware/diceware"
|
||||||
|
"golang.org/x/crypto/ed25519"
|
||||||
|
"io/ioutil"
|
||||||
|
"log"
|
||||||
|
"os"
|
||||||
|
"strconv"
|
||||||
|
"strings"
|
||||||
|
"time"
|
||||||
|
)
|
||||||
|
|
||||||
|
func convertCwtchFile(filename string, password string) {
|
||||||
|
peer, err := libpeer.LoadCwtchPeer(filename, password)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b := []byte("== ed25519v1-secret: type0 ==")
|
||||||
|
b = append(b, peer.GetProfile().Ed25519PrivateKey...)
|
||||||
|
err = ioutil.WriteFile("hs_ed25519_secret_key", b, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b = []byte("== ed25519v1-public: type0 ==")
|
||||||
|
b = append(b, peer.GetProfile().Ed25519PublicKey...)
|
||||||
|
err = ioutil.WriteFile("hs_ed25519_public_key", b, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
b = []byte(peer.GetProfile().Onion + ".onion\n")
|
||||||
|
err = ioutil.WriteFile("hostname", b, 0600)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Println("success!")
|
||||||
|
}
|
||||||
|
|
||||||
|
func convertTorFile(filename string, password string) {
|
||||||
|
log.Fatalf("this code doesn't work and can never work :( it's a math thing")
|
||||||
|
|
||||||
|
name, _ := diceware.Generate(2)
|
||||||
|
sk, err := ioutil.ReadFile("hs_ed25519_secret_key")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
sk = sk[32:]
|
||||||
|
|
||||||
|
pk, err := ioutil.ReadFile("hs_ed25519_public_key")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
pk = pk[32:]
|
||||||
|
|
||||||
|
onion, err := ioutil.ReadFile("hostname")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
onion = onion[:56]
|
||||||
|
|
||||||
|
peer, err := libpeer.NewCwtchPeer(strings.Join(name, "-"), password, filename)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("%d %d %s\n", len(peer.GetProfile().Ed25519PublicKey), len(peer.GetProfile().Ed25519PrivateKey), peer.GetProfile().Onion)
|
||||||
|
peer.GetProfile().Ed25519PrivateKey = sk
|
||||||
|
peer.GetProfile().Ed25519PublicKey = pk
|
||||||
|
peer.GetProfile().Onion = string(onion)
|
||||||
|
peer.Save()
|
||||||
|
|
||||||
|
log.Printf("success! loaded %d byte pk and %d byte sk for %s.onion\n", len(pk), len(sk), onion)
|
||||||
|
}
|
||||||
|
|
||||||
|
func vanity() {
|
||||||
|
for {
|
||||||
|
pk, sk, err := ed25519.GenerateKey(rand.Reader)
|
||||||
|
if err != nil {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
onion := utils.GetTorV3Hostname(pk)
|
||||||
|
for i := 4; i < len(os.Args); i++ {
|
||||||
|
if strings.HasPrefix(onion, os.Args[i]) {
|
||||||
|
peer, err := libpeer.NewCwtchPeer(os.Args[i], os.Args[3], onion+".cwtch")
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
peer.GetProfile().Ed25519PrivateKey = sk
|
||||||
|
peer.GetProfile().Ed25519PublicKey = pk
|
||||||
|
peer.GetProfile().Onion = onion
|
||||||
|
peer.Save()
|
||||||
|
log.Printf("found %s.onion\n", onion)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func printHelp() {
|
||||||
|
log.Println("usage: cwtchutil {help, convert-cwtch-file, convert-tor-file, changepw, vanity}")
|
||||||
|
}
|
||||||
|
|
||||||
|
func main() {
|
||||||
|
if len(os.Args) < 2 {
|
||||||
|
printHelp()
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
switch os.Args[1] {
|
||||||
|
default:
|
||||||
|
printHelp()
|
||||||
|
case "help":
|
||||||
|
printHelp()
|
||||||
|
case "convert-cwtch-file":
|
||||||
|
if len(os.Args) != 4 {
|
||||||
|
log.Println("example: cwtchutil convert-cwtch-file ~/.cwtch/profiles/11ddd78a9918c064e742d5e36a8b8fd4 passw0rd")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
convertCwtchFile(os.Args[2], os.Args[3])
|
||||||
|
case "convert-tor-file":
|
||||||
|
if len(os.Args) != 4 {
|
||||||
|
log.Println("example: cwtchutil convert-tor-file /var/lib/tor/hs1 passw0rd")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
convertTorFile(os.Args[2], os.Args[3])
|
||||||
|
case "vanity":
|
||||||
|
if len(os.Args) < 5 {
|
||||||
|
log.Println("example: cwtchutil vanity 4 passw0rd erinn openpriv")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
|
||||||
|
goroutines, err := strconv.Atoi(os.Args[2])
|
||||||
|
if err != nil {
|
||||||
|
log.Printf("first parameter after vanity should be a number\n")
|
||||||
|
os.Exit(1)
|
||||||
|
}
|
||||||
|
log.Println("searching. press ctrl+c to stop")
|
||||||
|
for i := 0; i < goroutines; i++ {
|
||||||
|
go vanity()
|
||||||
|
}
|
||||||
|
|
||||||
|
for { // run until ctrl+c
|
||||||
|
time.Sleep(time.Hour * 24)
|
||||||
|
}
|
||||||
|
case "changepw":
|
||||||
|
if len(os.Args) != 3 {
|
||||||
|
log.Fatalf("example: cwtch changepw ~/.cwtch/profiles/XXX")
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("old password: ")
|
||||||
|
reader := bufio.NewReader(os.Stdin)
|
||||||
|
pw, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
pw = pw[:len(pw)-1]
|
||||||
|
|
||||||
|
peer, err := libpeer.LoadCwtchPeer(os.Args[2], pw)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
fmt.Printf("new password: ")
|
||||||
|
newpw1, err := reader.ReadString('\n')
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
newpw1 = newpw1[:len(newpw1)-1] // fuck go with this linebreak shit ^ea
|
||||||
|
|
||||||
|
err = peer.ChangePassword(newpw1)
|
||||||
|
if err != nil {
|
||||||
|
log.Fatalf("%v", err)
|
||||||
|
}
|
||||||
|
|
||||||
|
log.Println("success!")
|
||||||
|
peer.Save()
|
||||||
|
}
|
||||||
|
}
|
|
@ -95,7 +95,7 @@ func (ppc *PeerPeerConnection) WaitTilAuthenticated() {
|
||||||
if ppc.GetState() == AUTHENTICATED {
|
if ppc.GetState() == AUTHENTICATED {
|
||||||
break
|
break
|
||||||
}
|
}
|
||||||
time.Sleep(time.Second * 5)
|
time.Sleep(time.Second * 1)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -39,6 +39,16 @@ func (psc *PeerServerConnection) GetState() ConnectionState {
|
||||||
return psc.state
|
return psc.state
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// WaitTilAuthenticated waits until the underlying connection is authenticated
|
||||||
|
func (psc *PeerServerConnection) WaitTilAuthenticated() {
|
||||||
|
for {
|
||||||
|
if psc.GetState() == AUTHENTICATED {
|
||||||
|
break
|
||||||
|
}
|
||||||
|
time.Sleep(time.Second * 1)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// Run manages the setup and teardown of a peer server connection
|
// Run manages the setup and teardown of a peer server connection
|
||||||
func (psc *PeerServerConnection) Run() error {
|
func (psc *PeerServerConnection) Run() error {
|
||||||
log.Printf("Connecting to %v", psc.Server)
|
log.Printf("Connecting to %v", psc.Server)
|
||||||
|
|
|
@ -47,6 +47,7 @@ type cwtchPeer struct {
|
||||||
// directly implement a cwtchPeer.
|
// directly implement a cwtchPeer.
|
||||||
type CwtchPeer interface {
|
type CwtchPeer interface {
|
||||||
Save() error
|
Save() error
|
||||||
|
ChangePassword(string) error
|
||||||
PeerWithOnion(string) *connections.PeerPeerConnection
|
PeerWithOnion(string) *connections.PeerPeerConnection
|
||||||
InviteOnionToGroup(string, string) error
|
InviteOnionToGroup(string, string) error
|
||||||
|
|
||||||
|
@ -154,6 +155,16 @@ func NewCwtchPeer(name string, password string, profilefile string) (CwtchPeer,
|
||||||
return cp, nil
|
return cp, nil
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func (cp *cwtchPeer) ChangePassword(password string) error {
|
||||||
|
key, salt, err := createKey(password)
|
||||||
|
if err != nil {
|
||||||
|
return err
|
||||||
|
}
|
||||||
|
cp.key = key
|
||||||
|
cp.salt = salt
|
||||||
|
return nil
|
||||||
|
}
|
||||||
|
|
||||||
// Save saves the cwtchPeer profile state to a file.
|
// Save saves the cwtchPeer profile state to a file.
|
||||||
func (cp *cwtchPeer) Save() error {
|
func (cp *cwtchPeer) Save() error {
|
||||||
cp.mutex.Lock()
|
cp.mutex.Lock()
|
||||||
|
|
|
@ -8,8 +8,8 @@ import (
|
||||||
"cwtch.im/cwtch/storage"
|
"cwtch.im/cwtch/storage"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/application"
|
"git.openprivacy.ca/openprivacy/libricochet-go/application"
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
|
"git.openprivacy.ca/openprivacy/libricochet-go/channels"
|
||||||
"log"
|
|
||||||
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
"git.openprivacy.ca/openprivacy/libricochet-go/utils"
|
||||||
|
"log"
|
||||||
)
|
)
|
||||||
|
|
||||||
// Server encapsulates a complete, compliant Cwtch server.
|
// Server encapsulates a complete, compliant Cwtch server.
|
||||||
|
|
Loading…
Reference in New Issue