package server import ( "crypto/rsa" "encoding/json" "git.openprivacy.ca/openprivacy/libricochet-go/utils" "io/ioutil" "log" "sync" ) // 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 { LogMetricsToFile bool `json:"logMetricsToFile"` 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) } // newConfig generates a simple config with defaults. Unmarshal will return them if they aren't specified func newConfig() *Config { config := Config{} config.MaxBufferLines = 100000 config.ServerReporting.LogMetricsToFile = false return &config } // LoadConfig loads a Config from a json file specified by filename func LoadConfig(filename string) *Config { config := newConfig() raw, err := ioutil.ReadFile(filename) if err == nil { err = json.Unmarshal(raw, &config) if err != nil { log.Println("Error reading config: ", err) } } configAutoPopulate(config) // Always save (first time generation, new version with new variables populated) config.Save(filename) return config } // Auto populate required values if missing and save func configAutoPopulate(config *Config) { if config.PrivateKeyBytes == "" { config.generatePrivateKey() } if config.ServerReporting.PeerPrivateKey == "" { config.generatePeerPrivateKey() } } 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() }