about summary refs log tree commit diff
diff options
context:
space:
mode:
-rw-r--r--src/challenge.go4
-rw-r--r--src/http.go51
-rw-r--r--src/seed.go6
3 files changed, 60 insertions, 1 deletions
diff --git a/src/challenge.go b/src/challenge.go
index a1f9893..38cffee 100644
--- a/src/challenge.go
+++ b/src/challenge.go
@@ -4,6 +4,8 @@ type Challenge struct {
 	Name string
 	Description string
 	Flag string // this should never leave the server
+	FoundFlag bool
+	FlagTries uint
 	Container string // this could, but is not required as well
 	Category string
 }
@@ -12,6 +14,7 @@ type StrippedChallenge struct {
 	Name string `json:"name"`
 	Description string `json:"description"`
 	Category string `json:"category"`
+	FoundFlag bool `json:"foundFlag"`
 }
 
 func stripChallenge(c Challenge) (StrippedChallenge) {
@@ -19,5 +22,6 @@ func stripChallenge(c Challenge) (StrippedChallenge) {
 		Name: c.Name,
 		Description: c.Description,
 		Category: c.Category,
+		FoundFlag: c.FoundFlag,
 	}
 }
diff --git a/src/http.go b/src/http.go
index 2f25a38..210d8b3 100644
--- a/src/http.go
+++ b/src/http.go
@@ -9,6 +9,8 @@ import (
 	"io/ioutil"
 	"time"
 	"log"
+	"encoding/json"
+	"strconv"
 )
 
 var (
@@ -28,6 +30,7 @@ func runHTTPServer() (error) {
 	r.HandleFunc("/login", loginPostHandler).Methods("POST")
 	r.HandleFunc("/logout", logoutHandler).Methods("POST")
 	r.HandleFunc("/api/getChallenges", getChallengesHandler).Methods("GET")
+	r.HandleFunc("/api/submitFlag", submitFlagHandler).Methods("POST")
 
 	address := fmt.Sprintf(":%d", *port)
 	return http.ListenAndServe(address, r)
@@ -162,3 +165,51 @@ func getChallengesHandler(w http.ResponseWriter, r *http.Request) {
 		}
 	}
 }
+
+func submitFlagHandler(w http.ResponseWriter, r *http.Request) {
+	r.ParseForm()
+	challengeName := r.Form.Get("challengeName")
+	flag := r.Form.Get("flag")
+	session, cookieNotFoundError := r.Cookie("session")
+
+	if cookieNotFoundError != nil || !isValidSession(session.Value) {
+		// either no session cookie found, or it contains an invalid session token. Redirect.
+		http.Redirect(w, r, "/login", http.StatusTemporaryRedirect)
+	} else {
+		// valid session token found, now search for the requested challenge
+
+		foundChallenge := false
+		correctFlag := false
+
+		// try to find our challenge
+		for index, challenge := range challenges {
+			if challenge.Name == challengeName {
+				// found challenge, check flags
+				foundChallenge = true
+
+				if challenge.Flag == flag {
+					// our user found the flag \o/
+					challenges[index].FoundFlag = true
+					correctFlag = true
+				} else {
+					// ow, bummer :(
+					challenge.FlagTries++
+				}
+				break
+			}
+		}
+
+		// if we didn't find the challenge, write an error message
+		errorString := ""
+		if !foundChallenge {
+			errorString = "no such challenge"
+		}
+
+		// inform our client
+		jsonAnswer, _ := json.Marshal(map[string]string{
+			"correctFlag": strconv.FormatBool(correctFlag),
+			"error": errorString,
+		})
+		w.Write([]byte(jsonAnswer))
+	}
+}
diff --git a/src/seed.go b/src/seed.go
index 8256929..fde4265 100644
--- a/src/seed.go
+++ b/src/seed.go
@@ -52,6 +52,8 @@ func readSeedFile(path string) ([]Challenge) {
 				Name: name,
 				Description: desc,
 				Flag: flag,
+				FoundFlag: false,
+				FlagTries: 0,
 				Container: cont,
 				Category: category,
 			})
@@ -81,6 +83,8 @@ func generateJSONFromChallenges() (string, error) {
 		strippedChallenges = append(strippedChallenges, stripChallenge(challenge))
 	}
 
-	marshalled, marshalError := json.Marshal(strippedChallenges)
+	marshalled, marshalError := json.Marshal(map[string][]StrippedChallenge{
+		"challenges": strippedChallenges,
+	})
 	return string(marshalled), marshalError
 }