diff --git a/args/args.go b/args/args.go index a859ea2..a495f0b 100644 --- a/args/args.go +++ b/args/args.go @@ -20,4 +20,28 @@ var confLocation = flag.String("conf", "./config.txt", "Config file to read from func GetConfLocation() (location string, set bool) { if confLocation == nil {return "", false} return *confLocation, true; +} + +/* TCP port to bind to */ +var httpPort = flag.Int("port", 11938, "Port number to bind to") +/* @return set boolean will be true if argument is not nil */ +func GetHTTPPort() (port int, set bool) { + if httpPort == nil {return -1, false} + return *httpPort, true; +} + +/* Listen on a UNIX socket */ +var socketLocation = flag.String("socket", "", "Location of UNIX socket to listen on. Setting will disable TCP.") +/* @return set boolean will be true if argument is not nil */ +func GetSocketLocation() (port string, set bool) { + if socketLocation == nil {return "", false} + return *socketLocation, true; +} + +/* Where the signal-cli binary is */ +var binaryLocation = flag.String("binary", "", "Location of the signal-cli binary.") +/* @return set boolean will be true if argument is not nil */ +func GetBinaryLocation() (port string, set bool) { + if binaryLocation == nil {return "", false} + return *binaryLocation, true; } \ No newline at end of file diff --git a/conf/conf.go b/conf/conf.go index 5356b37..fb81fb7 100644 --- a/conf/conf.go +++ b/conf/conf.go @@ -10,13 +10,14 @@ import ( "strings" ) -// import "fmt" - /* Object to handle what is in a JSON config */ type Config struct { configData map[string][]string; } +/* Default Config object */ +var GlobalConfig * Config; + /* Opens and reads a file at the path */ func NewConfig(filePath string) (newConfig *Config, err error) { // Open file @@ -30,8 +31,7 @@ func NewConfig(filePath string) (newConfig *Config, err error) { // Read lines into newConfigData scanner := bufio.NewScanner(file) for scanner.Scan() { - line := scanner.Text() - parts := strings.SplitN(line, " ", 2); + parts := strings.SplitN(scanner.Text(), " ", 2); if len(parts) != 2 {err = errors.New("Bad config file!"); return;} newConfigData[parts[0]] = append(newConfigData[parts[0]], parts[1]); } @@ -41,4 +41,21 @@ func NewConfig(filePath string) (newConfig *Config, err error) { } /* Gets a reference copy to the config data */ -func (config Config) GetConfigData() map[string][]string {return config.configData;} \ No newline at end of file +func (config * Config) GetConfigData() map[string][]string { + return config.configData; +} + +/* Returns if a bearer key is authorized for the path in this Config object + @return false for any situation that isn't a valid match */ +func (config * Config) ValidateBearerKey(bearerKey string, request string) bool { + paths, exists := config.configData[bearerKey]; + if !exists {return false} + + for _, matchTo := range paths { + if match(request, matchTo) { + return true; + } + } + + return false; +} \ No newline at end of file diff --git a/conf/regex.go b/conf/regex.go index 4a1fb0a..32524df 100644 --- a/conf/regex.go +++ b/conf/regex.go @@ -13,16 +13,8 @@ func splitPath(path string) []string { /* Attempts to match a request path to a set of whitelisted paths @return false for anything other than a valid match */ -func match(request string, matchTo []string) bool { - requestSplit := splitPath(request) - for _, matchToAttempt := range matchTo { - matchToAttemptSplit := splitPath(matchToAttempt); - if matchSegments(requestSplit, matchToAttemptSplit) { - return true; - } - } - - return false; +func match(request string, matchTo string) bool { + return matchSegments(splitPath(request), splitPath(matchTo)); } /* Returns false for anything other than a valid match */ diff --git a/http/listen.go b/http/listen.go new file mode 100644 index 0000000..3f372eb --- /dev/null +++ b/http/listen.go @@ -0,0 +1,36 @@ +package http + +/* This file handles listening to HTTP requests */ + +import ( + "signal-cli-http/conf" + + "fmt" + "log" + "net/http" +) + +func StartWebserver(port int) { + http.HandleFunc("/", getRoot) + + err := http.ListenAndServe(":"+fmt.Sprint(port), nil) + fmt.Println(err) +} + +func getRoot(w http.ResponseWriter, r *http.Request) { + // Check that Authentication header exists + authArr, ok := r.Header["Authentication"] + if (!ok) || (len(authArr) == 0) {w.WriteHeader(400); return} + bearer := authArr[0]; + + // Check that the request is allowed for the path + if !conf.GlobalConfig.ValidateBearerKey(bearer, r.URL.Path) { + w.WriteHeader(403); + return; + } + + log.Default().Print("HTTP Request: ", bearer, " " , r.URL.Path) + + // OK authentication wise + w.WriteHeader(200); +} \ No newline at end of file diff --git a/main.go b/main.go index 1e18720..006eec7 100644 --- a/main.go +++ b/main.go @@ -5,8 +5,8 @@ package main import ( "signal-cli-http/args" "signal-cli-http/conf" - - "fmt" + "signal-cli-http/http" + "log" ) @@ -14,11 +14,14 @@ func main() { // Read arguments args.Parse(); configLocation, confLocationSet := args.GetConfLocation(); - if !confLocationSet {log.Default().Print("No config value!"); return;} + if !confLocationSet {log.Default().Print("No config value!"); return} log.Default().Print("Reading config value from ", configLocation); // Set up config - config, err := conf.NewConfig(configLocation); - if err != nil {log.Default().Print("Error reading config: ", err); return;} - fmt.Println(config.GetConfigData()) + conf.GlobalConfig, _ = conf.NewConfig(configLocation); + if conf.GlobalConfig == nil {log.Default().Print("Error reading config"); return} + + port, portSet := args.GetHTTPPort(); + if !portSet {log.Default().Print("No port value!"); return;} + http.StartWebserver(port) } \ No newline at end of file diff --git a/readme.md b/readme.md index ace0a89..36814b9 100644 --- a/readme.md +++ b/readme.md @@ -7,4 +7,9 @@ Very simple HTTP frontend to [signal-cli](https://github.com/AsamK/signal-cli). Please also read the following README files for the individual modules: * [args](args/readme.md) - handles command line arguments. -* [conf](conf/readme.md) - handles the config file. \ No newline at end of file +* [conf](conf/readme.md) - handles the config file. + +Too be implemented: + +* subprocess - handles running the binaries which communicate with the daemon. +* web - handles the incoming http requests. \ No newline at end of file