Browse Source

server now has a config file; delete profile.Save (unsued); update cwtch_peer.Save to use indented Marshal

pull/50/head
Dan Ballard 1 year ago
parent
commit
d3765fd9bb
10 changed files with 130 additions and 60 deletions
  1. +0
    -18
      model/profile.go
  2. +0
    -12
      model/profile_test.go
  3. +1
    -1
      peer/cwtch_peer.go
  4. +13
    -15
      server/app/main.go
  5. +7
    -0
      server/app/serverConfig.json.sample
  6. +7
    -12
      server/server.go
  7. +88
    -0
      server/serverConfig.go
  8. +2
    -1
      testing/cwtch_peer_server_intergration_test.go
  9. +12
    -0
      testing/quality.sh
  10. +0
    -1
      testing/tests.sh

+ 0
- 18
model/profile.go View File

@@ -5,13 +5,11 @@ import (
"crypto/rsa"
"cwtch.im/cwtch/protocol"
"encoding/asn1"
"encoding/json"
"errors"
"github.com/golang/protobuf/proto"
"github.com/s-rah/go-ricochet/utils"
"golang.org/x/crypto/ed25519"
"io"
"io/ioutil"
"strconv"
"sync"
"time"
@@ -292,19 +290,3 @@ func (p *Profile) EncryptMessageToGroup(message string, groupID string) ([]byte,
}
return nil, errors.New("group does not exist")
}

// Save makes a opy of the profile in the given file
func (p *Profile) Save(profilefile string) error {
p.lock.Lock()
defer p.lock.Unlock()
bytes, _ := json.Marshal(p)
return ioutil.WriteFile(profilefile, bytes, 0600)
}

// LoadProfile loads a saved profile from a file.
func LoadProfile(profilefile string) (*Profile, error) {
bytes, _ := ioutil.ReadFile(profilefile)
profile := new(Profile)
err := json.Unmarshal(bytes, &profile)
return profile, err
}

+ 0
- 12
model/profile_test.go View File

@@ -6,18 +6,6 @@ import (
"testing"
)

func TestProfile(t *testing.T) {
profile := GenerateNewProfile("Sarah")
err := profile.Save("./profile_test")
if err != nil {
t.Errorf("Should have saved profile, but got error: %v", err)
}
loadedProfile, err := LoadProfile("./profile_test")
if err != nil || loadedProfile.Name != "Sarah" {
t.Errorf("Issue loading profile from file %v %v", err, loadedProfile)
}
}

func TestProfileIdentity(t *testing.T) {
sarah := GenerateNewProfile("Sarah")
alice := GenerateNewProfile("Alice")


+ 1
- 1
peer/cwtch_peer.go View File

@@ -62,7 +62,7 @@ func NewCwtchPeer(name string) *CwtchPeer {
// Save saves the CwtchPeer profile state to a file.
func (cp *CwtchPeer) Save(profilefile string) error {
cp.mutex.Lock()
bytes, _ := json.Marshal(cp)
bytes, _ := json.MarshalIndent(cp, "", "\t")
err := ioutil.WriteFile(profilefile, bytes, 0600)
cp.profilefile = profilefile
cp.mutex.Unlock()


+ 13
- 15
server/app/main.go View File

@@ -2,35 +2,33 @@ package main

import (
cwtchserver "cwtch.im/cwtch/server"
"github.com/s-rah/go-ricochet/utils"
"io/ioutil"
"log"
"os"
)

const privateKeyFile = "./private_key"
const (
serverConfigFile = "serverConfig.json"
)

func checkAndGenPrivateKey(privateKeyFile string) {
if _, err := os.Stat(privateKeyFile); os.IsNotExist(err) {
log.Printf("no private key found!")
log.Printf("generating new private key...")
pk, err := utils.GeneratePrivateKey()
if err != nil {
log.Fatalf("error generating new private key: %v\n", err)
}
err = ioutil.WriteFile(privateKeyFile, []byte(utils.PrivateKeyToString(pk)), 0400)
func confirmOrCopySampleConfig() {
// if no config file, attempt to copy sample
if _, err := os.Stat(serverConfigFile); os.IsNotExist(err) {
raw, err := ioutil.ReadFile(serverConfigFile + ".sample")
if err != nil {
log.Fatalf("error writing new private key to file %s: %v\n", privateKeyFile, err)
log.Fatal("Could not read sample config to copy: ", err)
}
ioutil.WriteFile(serverConfigFile, raw, 0600)
}
}

func main() {
checkAndGenPrivateKey(privateKeyFile)
confirmOrCopySampleConfig()
serverConfig := cwtchserver.LoadConfig(serverConfigFile)

server := new(cwtchserver.Server)
log.Printf("starting cwtch server...")

// TODO load params from .cwtch/server.conf or command line flag
server.Run(privateKeyFile, 100000)
}
server.Run(serverConfig)
}

+ 7
- 0
server/app/serverConfig.json.sample View File

@@ -0,0 +1,7 @@
{
"maxBufferLines": 100000
serverReporting: {
reportingGroupId: ""
reportingServerAddr: ""
}
}

+ 7
- 12
server/server.go View File

@@ -7,27 +7,22 @@ import (
"cwtch.im/cwtch/storage"
"github.com/s-rah/go-ricochet/application"
"github.com/s-rah/go-ricochet/channels"
"github.com/s-rah/go-ricochet/utils"
"log"
)

// Server encapsulates a complete, compliant Cwtch server.
type Server struct {
app *application.RicochetApplication
config *Config
}

// Run starts a server with the given privateKey
// TODO: surface errors
func (s *Server) Run(privateKeyFile string, bufferSize int) {
func (s *Server) Run(serverConfig *Config) {
s.config = serverConfig
cwtchserver := new(application.RicochetApplication)

pk, err := utils.LoadPrivateKeyFromFile(privateKeyFile)

if err != nil {
log.Fatalf("error reading private key file: %v", err)
}

l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", pk, 9878)
l, err := application.SetupOnion("127.0.0.1:9051", "tcp4", "", s.config.PrivateKey(), 9878)

if err != nil {
log.Fatalf("error setting up onion service: %v", err)
@@ -36,7 +31,7 @@ func (s *Server) Run(privateKeyFile string, bufferSize int) {
af := application.ApplicationInstanceFactory{}
af.Init()
ms := new(storage.MessageStore)
ms.Init("cwtch.messages", bufferSize)
ms.Init("cwtch.messages", s.config.MaxBufferLines)
af.AddHandler("im.cwtch.server.listen", func(rai *application.ApplicationInstance) func() channels.Handler {
si := new(Instance)
si.Init(rai, cwtchserver, ms)
@@ -66,10 +61,10 @@ func (s *Server) Run(privateKeyFile string, bufferSize int) {
}
})

cwtchserver.Init("cwtch server for "+l.Addr().String()[0:16], pk, af, new(application.AcceptAllContactManager))
cwtchserver.Init("cwtch server for "+l.Addr().String()[0:16], s.config.PrivateKey(), af, new(application.AcceptAllContactManager))
log.Printf("cwtch server running on cwtch:%s", l.Addr().String()[0:16])
s.app = cwtchserver
cwtchserver.Run(l)
s.app.Run(l)
}

// Shutdown kills the app closing all connections and freeing all goroutines


+ 88
- 0
server/serverConfig.go View File

@@ -0,0 +1,88 @@
package server

import (
"sync"
"github.com/s-rah/go-ricochet/utils"
"io/ioutil"
"log"
"encoding/json"
"crypto/rsa"
)

// Reporting is a struct for storing a the config a server needs to be a peer, and connect to a group to report
type Reporting struct {
PeerPrivateKey string `json:"privateKey"`
ReportingGroupID string `json:"reportingGroupId"`
ReportingServerAddr string `json:"reportingServerAddr"`
}

// Config is a struct for storing basic server configuration
type Config struct {
MaxBufferLines int `json:"maxBufferLines"`
PrivateKeyBytes string `json:"privateKey"`
ServerReporting Reporting `json:"serverReporting"`
lock sync.Mutex
}

// PrivateKey returns an rsa.PrivateKey generated from the config's PrivateKeyBytes
func (config *Config) PrivateKey() *rsa.PrivateKey {
pk, err := utils.ParsePrivateKey([]byte(config.PrivateKeyBytes))
if err != nil {
log.Println("Error parsing private key: ", err)
}
return pk
}

// Save dumps the latest version of the config to a json file given by filename
func (config *Config) Save(filename string) {
config.lock.Lock()
defer config.lock.Unlock()
bytes, _ := json.MarshalIndent(config, "", "\t")
ioutil.WriteFile(filename, bytes, 0600)
}

// LoadConfig loads a Config from a json file specified by filename
func LoadConfig(filename string) *Config {
raw, err := ioutil.ReadFile(filename)
if err != nil {
log.Fatal("Could not read config: ", err)
}

config := Config{}
err = json.Unmarshal(raw, &config)

if err != nil {
log.Fatal("Error reading config: ", err)
}

if config.PrivateKeyBytes == "" {
config.generatePrivateKey()
config.Save(filename)
}
if config.ServerReporting.PeerPrivateKey == "" {
config.generatePeerPrivateKey()
config.Save(filename)
}

return &config
}

func (config *Config) generatePrivateKey() {
pk, err := utils.GeneratePrivateKey()
if err != nil {
log.Fatalf("error generating new private key: %v\n", err)
}
config.lock.Lock()
config.PrivateKeyBytes = utils.PrivateKeyToString(pk)
config.lock.Unlock()
}

func (config *Config) generatePeerPrivateKey() {
pk, err := utils.GeneratePrivateKey()
if err != nil {
log.Fatalf("error generating new peer private key: %v\n", err)
}
config.lock.Lock()
config.ServerReporting.PeerPrivateKey = utils.PrivateKeyToString(pk)
config.lock.Unlock()
}

+ 2
- 1
testing/cwtch_peer_server_intergration_test.go View File

@@ -129,7 +129,8 @@ func TestCwtchPeerIntegration(t *testing.T) {
serverAddr, _ = utils.GetOnionAddress(serverKey)
server = new(cwtchserver.Server)
fmt.Println("Starting cwtch server...")
go server.Run(localKeyfile, 100)
config := cwtchserver.Config{ PrivateKeyBytes: utils.PrivateKeyToString(serverKey), MaxBufferLines: 100, ServerReporting: cwtchserver.Reporting{ } }
go server.Run(&config)

// let tor get established
fmt.Printf("Establishing Tor hidden service: %v...\n", serverAddr)


+ 12
- 0
testing/quality.sh View File

@@ -0,0 +1,12 @@
#!/bin/sh

echo "Checking code quality (you want to see no output here)"
echo ""

echo "Vetting:"
go list ./... | xargs go vet

echo ""
echo "Linting:"

go list ./... | xargs golint

+ 0
- 1
testing/tests.sh View File

@@ -18,4 +18,3 @@ go test ${1} -coverprofile=server.cover.out -v ./server
echo "mode: set" > coverage.out && cat *.cover.out | grep -v mode: | sort -r | \
awk '{if($1 != last) {print $0;last=$1}}' >> coverage.out
rm -rf *.cover.out
go list ./... | xargs go vet

Loading…
Cancel
Save