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

This commit is contained in:
Dan Ballard 2018-06-18 15:57:21 -07:00
parent 0aebd647de
commit d3765fd9bb
10 changed files with 130 additions and 60 deletions

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
}

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")

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()

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()
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 generating new private key: %v\n", err)
}
err = ioutil.WriteFile(privateKeyFile, []byte(utils.PrivateKeyToString(pk)), 0400)
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)
}

View File

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

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
server/serverConfig.go Normal file
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()
}

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
testing/quality.sh Executable file
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

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