Confirm webhook is from a trusted source (fix #16)

This commit is contained in:
Noah 2024-04-16 11:36:51 -05:00
parent 70fffcd25b
commit 20b955231b
2 changed files with 50 additions and 9 deletions

View File

@ -12,6 +12,7 @@ import (
type Configuration struct { type Configuration struct {
port int64 port int64
sites_dir string sites_dir string
trusted_servers []string
matrix struct { matrix struct {
homeserver string homeserver string
username string username string
@ -91,12 +92,30 @@ func parseConfig(path string, config *Configuration) {
panic(err) panic(err)
} }
// Trusted servers
var trusted_servers lua.LValue
getTableFromTable(L, table, "trusted_servers", &trusted_servers) // Get the 'trusted_servers' table
// Make sure 'config.trusted_servers' is of type 'table'
if trusted_servers_type := trusted_servers.Type().String(); trusted_servers_type != "table" &&
trusted_servers_type != "nil" {
log.Fatalf("config.trusted_servers is of type : '%s', not 'table'", trusted_servers_type)
} else if trusted_servers_type != "nil" { // If type is not nil (has to be table or it would've been caught already)
for i := 1; i <= L.ObjLen(trusted_servers); i++ { // Loop through every trusted server
lv := L.GetTable(trusted_servers, lua.LNumber(i))
if text, ok := lv.(lua.LString); ok { // Value is string
config.trusted_servers = append(config.trusted_servers, string(text))
} else if _, ok := lv.(*lua.LNilType); !ok { // Value is not a string, and is not nil
log.Fatalf("config.trusted_servers[%d] is of type : '%s', not 'string'", i, lv.Type().String())
}
}
}
// Matrix config // Matrix config
var matrix lua.LValue var matrix lua.LValue
getTableFromTable(L, table, "matrix", &matrix) // Get the 'matrix' sub table getTableFromTable(L, table, "matrix", &matrix) // Get the 'matrix' table
// Make sure 'config.matrix' is of type 'table' // Make sure 'config.matrix' is of type 'table'
if matrix_type := matrix.Type().String(); matrix_type != "table" && matrix_type != "nil" { if matrix_type := matrix.Type().String(); matrix_type != "table" && matrix_type != "nil" {
log.Fatalf("config.matrix is of type : '%s', not 'table'", matrix.Type().String()) log.Fatalf("config.matrix is of type : '%s', not 'table'", matrix_type)
} else if matrix_type != "nil" { } else if matrix_type != "nil" {
if _, err := getBoolFromTable(L, matrix, "disabled", &config.matrix.disabled); err != nil { if _, err := getBoolFromTable(L, matrix, "disabled", &config.matrix.disabled); err != nil {
panic(err) panic(err)

26
main.go
View File

@ -4,10 +4,12 @@ package main
import ( import (
"encoding/json" "encoding/json"
"fmt" "fmt"
"github.com/akamensky/argparse"
"log" "log"
"net/http" "net/http"
"os" "os"
"strings"
"github.com/akamensky/argparse"
) )
// Circle emoji storage. // Circle emoji storage.
@ -109,15 +111,35 @@ func main() {
configuration.matrix.disabled = *disable_matrix || configuration.matrix.disabled configuration.matrix.disabled = *disable_matrix || configuration.matrix.disabled
http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Webhook receiver http.HandleFunc("/", func(w http.ResponseWriter, r *http.Request) { // Webhook receiver
log.Print("Recieved request!")
var data map[string]interface{} var data map[string]interface{}
err := json.NewDecoder(r.Body).Decode(&data) err := json.NewDecoder(r.Body).Decode(&data)
if err != nil { if err != nil {
log.Panic(err) log.Panic(err)
return return
} }
check_ips := []string{ // IPs of client to check against trusted_servers
strings.Split(r.RemoteAddr, ":")[0],
r.Header.Get("x-forwarded-for"),
}
found_trusted_server := false
for _, server := range configuration.trusted_servers {
if found_trusted_server {
break
}
for _, ip := range check_ips {
if ip == server {
log.Printf("Request IP matches a trusted server (%s)", ip)
go handler(data) // Run the handler go handler(data) // Run the handler
fmt.Fprint(w, "Received!") fmt.Fprint(w, "Received!")
found_trusted_server = true
break
}
}
}
if !found_trusted_server {
log.Print("Request IP doesn't match a trusted server! Dropping...")
}
}) })
// Attempt to create sites_dir // Attempt to create sites_dir
if exists, _ := fileExists(configuration.sites_dir); !exists { if exists, _ := fileExists(configuration.sites_dir); !exists {