ugly server implementation without signature checks
[epoint] / epoint-server.go
diff --git a/epoint-server.go b/epoint-server.go
new file mode 100644 (file)
index 0000000..8ceef64
--- /dev/null
@@ -0,0 +1,128 @@
+package main
+
+import (
+       "crypto/openpgp"
+       "epoint/logic"
+       "fmt"
+       "log"
+       "net/http"
+       "os"
+)
+
+const (
+       port    = ":8080"
+       rootdir = "teststore"
+       seckey  = "./key.sec"
+)
+
+var serverkey *openpgp.Entity
+
+// todo: http header limit: 64K, body limit: 64K
+
+// getPubkey(db, fpr) (pk, err)
+// putPubkey(db, fpr, pk) (err)
+// getDraft(db, id) (draft, err)
+// putDraft(db, id, draft) (err)
+
+// getCert(db, id) (cert, err)
+// putCert(db, id, cert) (err)
+// getCertBySerial(db, fpr, sn) (cert, err)
+// getCertByFpr(db, fpr) (cert, err)
+
+// todo: update cert (inc serial..)
+
+// Dummy initialization of serverkey
+func initkey() (err error) {
+       f, err := os.Open(seckey)
+       if err != nil {
+               return
+       }
+       keys, err := openpgp.ReadKeyRing(f)
+       if err != nil {
+               f.Close()
+               return
+       }
+       err = f.Close()
+       if err != nil {
+               return
+       }
+       serverkey = keys[0]
+       err = os.MkdirAll(rootdir, 0755)
+       if err != nil {
+               return
+       }
+       f, err = os.Create(rootdir + "/serverkey")
+       if err != nil {
+               return
+       }
+       err = serverkey.Serialize(f)
+       if err != nil {
+               return
+       }
+       // TODO: make sure pubkey is replicated and available
+       err = f.Sync()
+       if err != nil {
+               return
+       }
+       err = f.Close()
+       return
+}
+
+func defaultHandler(w http.ResponseWriter, r *http.Request) {
+       log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
+       fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL.Raw)
+}
+
+func submitHandler(w http.ResponseWriter, r *http.Request) {
+       log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
+       draft := r.FormValue("draft")
+       debit := r.FormValue("debit")
+       if len(draft) > 0 {
+               cert, err := logic.EvalDraft([]byte(draft), serverkey)
+               if err != nil {
+                       log.Printf("eval draft fail: %s", err)
+                       fmt.Fprintf(w, "eval draft fail: %s\n", err)
+               } else {
+                       w.Write(cert)
+               }
+       } else if len(debit) > 0 {
+               cert, err := logic.EvalDebitCert([]byte(debit), serverkey)
+               if err != nil {
+                       log.Printf("eval debit fail: %s", err)
+                       fmt.Fprintf(w, "eval debit fail: %s\n", err)
+               } else {
+                       w.Write(cert)
+               }
+       } else {
+               fmt.Fprintf(w, "expected draft or debit param, got: %s %s\n", r.Method, r.URL.Raw)
+       }
+}
+
+func main() {
+       err := initkey()
+       if err != nil {
+               log.Fatal(err)
+       }
+       err = logic.Init()
+       if err != nil {
+               log.Fatal(err)
+       }
+
+       http.HandleFunc("/", defaultHandler)
+
+       // queries
+       http.HandleFunc("/serverkey", func(w http.ResponseWriter, r *http.Request) {
+               http.ServeFile(w, r, rootdir+"/serverkey")
+       })
+//     http.HandleFunc("/status", defaultHandler)
+//     http.HandleFunc("/pubkey", defaultHandler)
+//     http.HandleFunc("/daft", defaultHandler)
+//     http.HandleFunc("/cert", defaultHandler)
+
+       // actions
+       // withdraw, draw, deposit, process, clear
+       http.HandleFunc("/submit", submitHandler)
+
+       log.Printf("start service, server id: %X\n", serverkey.PrimaryKey.Fingerprint)
+       log.Fatal(http.ListenAndServe(port, nil))
+}