Graft WiiSOAP to EC's expected request behaviour (#12)

* Update module repo path

* Use SOAPAction for request interpretation
This commit is contained in:
Spotlight 2020-07-27 21:10:36 -05:00 committed by GitHub
parent f0c243bc9c
commit 0e3490357d
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 33 additions and 27 deletions

2
.gitignore vendored Normal file
View File

@ -0,0 +1,2 @@
.idea
config.xml

7
go.mod
View File

@ -1,8 +1,5 @@
module github.com/Apfel/WiiSOAP module github.com/morenatsu-net/WiiSOAP
go 1.12 go 1.12
require ( require github.com/go-sql-driver/mysql v1.5.0
github.com/go-sql-driver/mysql v1.4.1
google.golang.org/appengine v1.6.5 // indirect
)

13
go.sum
View File

@ -1,11 +1,2 @@
github.com/go-sql-driver/mysql v1.4.1 h1:g24URVg0OFbNUTx9qqY1IRZ9D9z3iPyi5zKhQZpNwpA= github.com/go-sql-driver/mysql v1.5.0 h1:ozyZYNQW3x3HtqT1jira07DN2PArx2v7/mN66gGcHOs=
github.com/go-sql-driver/mysql v1.4.1/go.mod h1:zAC/RDZ24gD3HViQzih4MyKcchzm+sOG5ZlKdlhCg5w= github.com/go-sql-driver/mysql v1.5.0/go.mod h1:DCzpHaOWr8IXmIStZouvnhqoel9Qv2LBy8hT2VhHyBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
golang.org/x/crypto v0.0.0-20190308221718-c2843e01d9a2/go.mod h1:djNgcEr1/C05ACkg1iLfiJU5Ep61QUkGW8qpdssI0+w=
golang.org/x/net v0.0.0-20190603091049-60506f45cf65/go.mod h1:HSz+uSET+XFnRR8LxR5pz3Of3rY3CfYBVs4xY44aLks=
golang.org/x/sys v0.0.0-20190215142949-d0b11bdaac8a/go.mod h1:STP8DvDyc/dI5b8T5hshtkjS+E42TnysNCUPdjciGhY=
golang.org/x/text v0.3.0/go.mod h1:NqM8EUOU14njkJ3fqMW+pc6Ldnwhi/IjpwHt7yyuwOQ=
golang.org/x/text v0.3.2/go.mod h1:bEr9sfX3Q8Zfm5fL9x+3itogRgK3+ptLWKqgva+5dAk=
golang.org/x/tools v0.0.0-20180917221912-90fa682c2a6e/go.mod h1:n7NCudcB/nEzxVGmLbDWY5pfWTLqBcC2KZ6jyYvM4mQ=
google.golang.org/appengine v1.6.5 h1:tycE03LOZYQNhDpS27tcQdAzLCVMaj7QT2SXxebnpCM=
google.golang.org/appengine v1.6.5/go.mod h1:8WjMMxjGQR8xUklV/ARdw2HLXBOI7O7uCIDZVag1xfc=

38
main.go
View File

@ -24,8 +24,8 @@ import (
"io/ioutil" "io/ioutil"
"log" "log"
"net/http" "net/http"
"os"
"strconv" "strconv"
"strings"
"time" "time"
_ "github.com/go-sql-driver/mysql" _ "github.com/go-sql-driver/mysql"
@ -50,14 +50,10 @@ func main() {
fmt.Println("WiiSOAP 0.2.6 Kawauso\n[i] Reading the Config...") fmt.Println("WiiSOAP 0.2.6 Kawauso\n[i] Reading the Config...")
// Check the Config. // Check the Config.
configfile, err := os.Open("./config.xml") ioconfig, err := ioutil.ReadFile("./config.xml")
checkError(err)
ioconfig, err := ioutil.ReadAll(configfile)
checkError(err) checkError(err)
CON := Config{} CON := Config{}
err = xml.Unmarshal([]byte(ioconfig), &CON) err = xml.Unmarshal(ioconfig, &CON)
//fmt.Println(CON)
// ^ Printing this shows the password in the commandline, which may be insecure. ^
checkError(err) checkError(err)
fmt.Println("[i] Initializing core...") fmt.Println("[i] Initializing core...")
@ -73,13 +69,17 @@ func main() {
// Start the HTTP server. // Start the HTTP server.
fmt.Printf("Starting HTTP connection (%s)...\nNot using the usual port for HTTP?\nBe sure to use a proxy, otherwise the Wii can't connect!\n", CON.Address) fmt.Printf("Starting HTTP connection (%s)...\nNot using the usual port for HTTP?\nBe sure to use a proxy, otherwise the Wii can't connect!\n", CON.Address)
http.HandleFunc("/", handler) // each request calls handler http.HandleFunc("/ecs/services/ECommerceSOAP", handler) // each request calls handler
log.Fatal(http.ListenAndServe(CON.Address, nil)) log.Fatal(http.ListenAndServe(CON.Address, nil))
// From here on out, all special cool things should go into the handler function. // From here on out, all special cool things should go into the handler function.
} }
func handler(w http.ResponseWriter, r *http.Request) { func handler(w http.ResponseWriter, r *http.Request) {
// Figure out the action to handle via header.
action := r.Header.Get("SOAPAction")
action = parseAction(action, "ecs")
// Get a sexy new timestamp to use. // Get a sexy new timestamp to use.
timestampnano := strconv.FormatInt(time.Now().UTC().Unix(), 10) timestampnano := strconv.FormatInt(time.Now().UTC().Unix(), 10)
timestamp := timestampnano + "000" timestamp := timestampnano + "000"
@ -87,14 +87,13 @@ func handler(w http.ResponseWriter, r *http.Request) {
fmt.Println("[!] Incoming request.") fmt.Println("[!] Incoming request.")
body, err := ioutil.ReadAll(r.Body) body, err := ioutil.ReadAll(r.Body)
if err != nil { if err != nil {
http.Error(w, "[x] Error reading request body...", http.StatusInternalServerError) http.Error(w, "Error reading request body...", http.StatusInternalServerError)
} }
// The switch converts the HTTP Body of the request into a string. There is no need to convert the cases to byte format. // The switch converts the HTTP Body of the request into a string. There is no need to convert the cases to byte format.
switch string(body) { switch action {
// TODO: Make the case functions cleaner. (e.g. Should the response be a variable?) // TODO: Make the case functions cleaner. (e.g. Should the response be a variable?)
// TODO: Update the responses so that they query the SQL Database for the proper information (e.g. Device Code, Token, etc). // TODO: Update the responses so that they query the SQL Database for the proper information (e.g. Device Code, Token, etc).
// TODO: Use Strings.Contains otherwise the program assumes that the whole request MUST only be the keyword.
case "CheckDeviceStatus": case "CheckDeviceStatus":
fmt.Println("CDS.") fmt.Println("CDS.")
@ -363,3 +362,20 @@ func handler(w http.ResponseWriter, r *http.Request) {
// TODO: Add NUS and CAS SOAP to the case list. // TODO: Add NUS and CAS SOAP to the case list.
fmt.Println("[!] End of Request." + "\n") fmt.Println("[!] End of Request." + "\n")
} }
func namespaceForType(service string) string {
return "urn:" + service + ".wsapi.broadon.com"
}
// Expected contents are along the lines of "urn:ecs.wsapi.broadon.com/CheckDeviceStatus"
func parseAction(original string, service string) string {
prefix := namespaceForType(service) + "/"
stripped := strings.Replace(original, prefix, "", 1)
if stripped == original {
// This doesn't appear valid.
return ""
} else {
return stripped
}
}