diff --git a/socketserver/cmd/socketserver/socketserver.go b/socketserver/cmd/socketserver/socketserver.go index 0b0e052d..5de7a059 100644 --- a/socketserver/cmd/socketserver/socketserver.go +++ b/socketserver/cmd/socketserver/socketserver.go @@ -2,56 +2,52 @@ package main // import "bitbucket.org/stendec/frankerfacez/socketserver/cmd/sock import ( "../../internal/server" + "encoding/json" "flag" + "fmt" + "io/ioutil" "log" "net/http" + "os" ) -var origin *string = flag.String("origin", "localhost:8001", "Client-visible origin of the socket server") -var bindAddress *string = flag.String("listen", "", "Address to bind to, if different from origin") -var usessl *bool = flag.Bool("ssl", false, "Enable the use of SSL for connecting clients and backend connections") -var certificateFile *string = flag.String("crt", "ssl.crt", "CA-signed SSL certificate file") -var privateKeyFile *string = flag.String("key", "ssl.key", "SSL private key file") - -var naclKeysFile *string = flag.String("naclkey", "naclkeys.json", "Keypairs for the NaCl crypto library, for communicating with the backend.") +var configFilename *string = flag.String("config", "config.json", "Configuration file, including the keypairs for the NaCl crypto library, for communicating with the backend.") var generateKeys *bool = flag.Bool("genkeys", false, "Generate NaCl keys instead of serving requests.\nArguments: [int serverId] [base64 backendPublic]\nThe backend public key can either be specified in base64 on the command line, or put in the json file later.") func main() { flag.Parse() if *generateKeys { - GenerateKeys(*naclKeysFile) + GenerateKeys(*configFilename) return } - if *origin == "" { - log.Fatalln("--origin argument required") + confFile, err := os.Open(*configFilename) + if os.IsNotExist(err) { + fmt.Println("Error: No config file. Run with -genkeys and edit config.json") + os.Exit(3) } - if *bindAddress == "" { - bindAddress = origin + if err != nil { + log.Fatal(err) } - if (*certificateFile == "") != (*privateKeyFile == "") { - log.Fatalln("Either both --crt and --key can be provided, or neither.") + conf := &server.ConfigFile{} + confBytes, err := ioutil.ReadAll(confFile) + if err != nil { + log.Fatal(err) } - - conf := &server.Config{ - SSLKeyFile: *privateKeyFile, - SSLCertificateFile: *certificateFile, - UseSSL: *usessl, - NaclKeysFile: *naclKeysFile, - - SocketOrigin: *origin, + err = json.Unmarshal(confBytes, &conf) + if err != nil { + log.Fatal(err) } httpServer := &http.Server{ - Addr: *bindAddress, + Addr: conf.ListenAddr, } server.SetupServerAndHandle(conf, httpServer.TLSConfig, nil) - var err error if conf.UseSSL { - err = httpServer.ListenAndServeTLS(*certificateFile, *privateKeyFile) + err = httpServer.ListenAndServeTLS(conf.SSLCertificateFile, conf.SSLKeyFile) } else { err = httpServer.ListenAndServe() } @@ -63,11 +59,13 @@ func main() { func GenerateKeys(outputFile string) { if flag.NArg() < 1 { - log.Fatal("The server ID must be specified") + fmt.Println("Specify a numeric server ID after -genkeys") + os.Exit(2) } if flag.NArg() >= 2 { server.GenerateKeys(outputFile, flag.Arg(0), flag.Arg(1)) } else { server.GenerateKeys(outputFile, flag.Arg(0), "") } + fmt.Println("Keys generated. Now edit config.json") } diff --git a/socketserver/internal/server/backend.go b/socketserver/internal/server/backend.go index 9f316929..b966b354 100644 --- a/socketserver/internal/server/backend.go +++ b/socketserver/internal/server/backend.go @@ -11,7 +11,6 @@ import ( "log" "net/http" "net/url" - "os" "strconv" "strings" "sync" @@ -29,7 +28,7 @@ var serverId int var messageBufferPool sync.Pool -func SetupBackend(config *Config) { +func SetupBackend(config *ConfigFile) { backendHttpClient.Timeout = 60 * time.Second backendUrl = config.BackendUrl if responseCache != nil { @@ -41,21 +40,10 @@ func SetupBackend(config *Config) { messageBufferPool.New = New4KByteBuffer - var keys CryptoKeysBuf - file, err := os.Open(config.NaclKeysFile) - if err != nil { - log.Fatal(err) - } - dec := json.NewDecoder(file) - err = dec.Decode(&keys) - if err != nil { - log.Fatal(err) - } - var theirPublic, ourPrivate [32]byte - copy(theirPublic[:], keys.TheirPublicKey) - copy(ourPrivate[:], keys.OurPrivateKey) - serverId = keys.ServerId + copy(theirPublic[:], config.BackendPublicKey) + copy(ourPrivate[:], config.OurPrivateKey) + serverId = config.ServerId box.Precompute(&backendSharedKey, &theirPublic, &ourPrivate) } @@ -193,7 +181,7 @@ func FetchBacklogData(chatSubs []string) ([]ClientMessage, error) { func GenerateKeys(outputFile, serverId, theirPublicStr string) { var err error - output := CryptoKeysBuf{} + output := ConfigFile{} output.ServerId, err = strconv.Atoi(serverId) if err != nil { @@ -212,19 +200,16 @@ func GenerateKeys(outputFile, serverId, theirPublicStr string) { if err != nil { log.Fatal(err) } - output.TheirPublicKey = theirPublic + output.BackendPublicKey = theirPublic } - file, err := os.Create(outputFile) + fmt.Println(ourPublic, ourPrivate) + bytes, err := json.MarshalIndent(output, "", "\t") if err != nil { log.Fatal(err) } - enc := json.NewEncoder(file) - err = enc.Encode(output) - if err != nil { - log.Fatal(err) - } - err = file.Close() + fmt.Println(string(bytes)) + err = ioutil.WriteFile(outputFile, bytes, 0600) if err != nil { log.Fatal(err) } diff --git a/socketserver/internal/server/handlecore.go b/socketserver/internal/server/handlecore.go index 1f477f97..7ff9db07 100644 --- a/socketserver/internal/server/handlecore.go +++ b/socketserver/internal/server/handlecore.go @@ -6,31 +6,16 @@ import ( "errors" "fmt" "golang.org/x/net/websocket" + "html/template" "log" "net/http" "strconv" "strings" "sync" - "html/template" ) const MAX_PACKET_SIZE = 1024 -type Config struct { - // SSL/TLS - SSLCertificateFile string - SSLKeyFile string - UseSSL bool - - // NaCl keys for backend messages - NaclKeysFile string - - // Hostname of the socket server - SocketOrigin string - // URL to the backend server - BackendUrl string -} - // A command is how the client refers to a function on the server. It's just a string. type Command string @@ -85,10 +70,10 @@ var ExpectedStringAndInt = errors.New("Error: Expected array of string, int as a var ExpectedStringAndBool = errors.New("Error: Expected array of string, bool as arguments.") var ExpectedStringAndIntGotFloat = errors.New("Error: Second argument was a float, expected an integer.") -var gconfig *Config +var gconfig *ConfigFile // Create a websocket.Server with the options from the provided Config. -func setupServer(config *Config, tlsConfig *tls.Config) *websocket.Server { +func setupServer(config *ConfigFile, tlsConfig *tls.Config) *websocket.Server { gconfig = config sockConf, err := websocket.NewConfig("/", config.SocketOrigin) if err != nil { @@ -120,28 +105,36 @@ func setupServer(config *Config, tlsConfig *tls.Config) *websocket.Server { // Set up a websocket listener and register it on /. // (Uses http.DefaultServeMux .) -func SetupServerAndHandle(config *Config, tlsConfig *tls.Config, serveMux *http.ServeMux) { +func SetupServerAndHandle(config *ConfigFile, tlsConfig *tls.Config, serveMux *http.ServeMux) { sockServer := setupServer(config, tlsConfig) if serveMux == nil { serveMux = http.DefaultServeMux } serveMux.HandleFunc("/", ServeWebsocketOrCatbag(sockServer.ServeHTTP)) + serveMux.Handle("/assets", http.FileServer(nil)) // TODO serveMux.HandleFunc("/pub_msg", HBackendPublishRequest) serveMux.HandleFunc("/dump_backlog", HBackendDumpBacklog) serveMux.HandleFunc("/update_and_pub", HBackendUpdateAndPublish) } -var Catbag = template.Must(template.New(` +var Memes = template.Must(template.New("catbag").Parse(` - -