8ceef64c6679d5afcb819295339f2c872bebdeb7
[epoint] / epoint-server.go
1 package main
2
3 import (
4         "crypto/openpgp"
5         "epoint/logic"
6         "fmt"
7         "log"
8         "net/http"
9         "os"
10 )
11
12 const (
13         port    = ":8080"
14         rootdir = "teststore"
15         seckey  = "./key.sec"
16 )
17
18 var serverkey *openpgp.Entity
19
20 // todo: http header limit: 64K, body limit: 64K
21
22 // getPubkey(db, fpr) (pk, err)
23 // putPubkey(db, fpr, pk) (err)
24 // getDraft(db, id) (draft, err)
25 // putDraft(db, id, draft) (err)
26
27 // getCert(db, id) (cert, err)
28 // putCert(db, id, cert) (err)
29 // getCertBySerial(db, fpr, sn) (cert, err)
30 // getCertByFpr(db, fpr) (cert, err)
31
32 // todo: update cert (inc serial..)
33
34 // Dummy initialization of serverkey
35 func initkey() (err error) {
36         f, err := os.Open(seckey)
37         if err != nil {
38                 return
39         }
40         keys, err := openpgp.ReadKeyRing(f)
41         if err != nil {
42                 f.Close()
43                 return
44         }
45         err = f.Close()
46         if err != nil {
47                 return
48         }
49         serverkey = keys[0]
50         err = os.MkdirAll(rootdir, 0755)
51         if err != nil {
52                 return
53         }
54         f, err = os.Create(rootdir + "/serverkey")
55         if err != nil {
56                 return
57         }
58         err = serverkey.Serialize(f)
59         if err != nil {
60                 return
61         }
62         // TODO: make sure pubkey is replicated and available
63         err = f.Sync()
64         if err != nil {
65                 return
66         }
67         err = f.Close()
68         return
69 }
70
71 func defaultHandler(w http.ResponseWriter, r *http.Request) {
72         log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
73         fmt.Fprintf(w, "not implemented: %s %s\n", r.Method, r.URL.Raw)
74 }
75
76 func submitHandler(w http.ResponseWriter, r *http.Request) {
77         log.Printf("%s %s %s\n", r.RemoteAddr, r.Method, r.URL.Raw)
78         draft := r.FormValue("draft")
79         debit := r.FormValue("debit")
80         if len(draft) > 0 {
81                 cert, err := logic.EvalDraft([]byte(draft), serverkey)
82                 if err != nil {
83                         log.Printf("eval draft fail: %s", err)
84                         fmt.Fprintf(w, "eval draft fail: %s\n", err)
85                 } else {
86                         w.Write(cert)
87                 }
88         } else if len(debit) > 0 {
89                 cert, err := logic.EvalDebitCert([]byte(debit), serverkey)
90                 if err != nil {
91                         log.Printf("eval debit fail: %s", err)
92                         fmt.Fprintf(w, "eval debit fail: %s\n", err)
93                 } else {
94                         w.Write(cert)
95                 }
96         } else {
97                 fmt.Fprintf(w, "expected draft or debit param, got: %s %s\n", r.Method, r.URL.Raw)
98         }
99 }
100
101 func main() {
102         err := initkey()
103         if err != nil {
104                 log.Fatal(err)
105         }
106         err = logic.Init()
107         if err != nil {
108                 log.Fatal(err)
109         }
110
111         http.HandleFunc("/", defaultHandler)
112
113         // queries
114         http.HandleFunc("/serverkey", func(w http.ResponseWriter, r *http.Request) {
115                 http.ServeFile(w, r, rootdir+"/serverkey")
116         })
117 //      http.HandleFunc("/status", defaultHandler)
118 //      http.HandleFunc("/pubkey", defaultHandler)
119 //      http.HandleFunc("/daft", defaultHandler)
120 //      http.HandleFunc("/cert", defaultHandler)
121
122         // actions
123         // withdraw, draw, deposit, process, clear
124         http.HandleFunc("/submit", submitHandler)
125
126         log.Printf("start service, server id: %X\n", serverkey.PrimaryKey.Fingerprint)
127         log.Fatal(http.ListenAndServe(port, nil))
128 }