-
1
-
2
-
3
-
4
-
5
-
6
-
7
-
8
-
9
-
10
-
11
-
12
-
13
-
14
-
15
-
16
-
17
-
18
-
19
-
20
-
21
-
22
-
23
-
24
-
25
-
26
-
27
-
28
-
29
-
30
-
31
-
32
-
33
-
34
-
35
-
36
-
37
-
38
-
39
-
40
-
41
-
42
-
43
-
44
-
45
-
46
-
47
-
48
-
49
-
50
-
51
-
52
-
53
-
54
-
55
-
56
-
57
-
58
-
59
-
60
-
61
-
62
-
63
-
64
-
65
-
66
-
67
-
68
-
69
-
70
-
71
-
72
-
73
-
74
-
75
-
76
-
77
-
78
-
79
-
80
package main
import (
"crypto/ed25519"
"encoding/base64"
"encoding/gob"
"errors"
"net/http"
"os"
"strings"
)
type user struct {
dhtVal []byte
phase int64
}
var users map[string]user
// Verify that a body was signed by this ID
func verify(id string, body []byte) error {
b, err := base64.RawURLEncoding.DecodeString(id)
if err != nil {
return err
}
if len(body) < ed25519.SignatureSize {
return errors.New("body too short")
}
message := body[:len(body)-ed25519.SignatureSize]
sig := body[len(body)-ed25519.SignatureSize:]
if !ed25519.Verify(ed25519.PublicKey(b), message, sig) {
return errors.New("signature verification failed")
}
return nil
}
// Persist a user's data to disk
func persist(id string) {
writer, err := os.Open(dataDir + "/" + id + "/gob")
if err != nil {
return
}
enc := gob.NewEncoder(writer)
enc.Encode(users[id])
}
// Handle user configuration changes
func userHandler(w http.ResponseWriter, r *http.Request) {
id := r.URL.Fragment[6:]
// Resolve ID to server list
val := dhtGet(id, "")
if verify(id, val) != nil {
w.WriteHeader(http.StatusNotFound)
return
}
// Check if server list contains this server
message := string(val[:len(val)-ed25519.SignatureSize])
if !strings.Contains(message, me) {
// Delete user if they are no longer associated with this server
delete(users, id)
err := os.RemoveAll(id)
if err != nil {
w.WriteHeader(http.StatusNotFound)
return
}
w.WriteHeader(http.StatusOK)
return
}
//valSplit := strings.Split(message, "\n")
//servers := valSplit[1:len(valSplit)-1]
if _, ok := users[id]; !ok {
// Add user
users[id] = user{
dhtVal: val,
}
os.Mkdir(id, 0755)
persist(id)
}
}