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
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
|
package main
import (
"encoding/base64"
"flag"
"fmt"
"html/template"
"io/ioutil"
"log"
"net/http"
"os"
"strings"
"github.com/gorilla/mux"
)
var (
port *int // port the http server listens on
usernames []string // list of usernames
currentVpnRemotePort *int
)
// Credentials stores user credentials
type Credentials struct {
Username string
Accesscode string
Hostname string
}
func registerHTTPFlags() {
port = flag.Int("port", 8081, "The port the http server should listen on")
currentVpnRemotePort = flag.Int("initialVPNPort", 1194, "the initial vpn port")
}
func setupHTTPServer() http.Server {
r := mux.NewRouter()
r.HandleFunc("/", indexHandler)
r.HandleFunc("/register", registerGetHandler).Methods("GET")
r.HandleFunc("/register", registerPostHandler).Methods("POST")
r.HandleFunc("/credentials", credentialsGetHandler).Methods("GET")
return http.Server{
Addr: fmt.Sprintf("0.0.0.0:%d", *port),
Handler: r,
}
}
// Host of the index file
func indexHandler(w http.ResponseWriter, r *http.Request) {
readFileToReponse(w, "/index.html")
}
// Read register page
func registerGetHandler(w http.ResponseWriter, r *http.Request) {
readFileToReponse(w, "/register.html")
}
// Process a registration
func registerPostHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
username := r.Form.Get("username")
// test if the username has already been chosen
if !isUniq(username) {
log.Println("redirecting to usernameTaken")
usernameTakenGetHandler(w, r)
return
}
if !isValid(username) {
return
}
// add the new username to the list of usernames
usernames = append(usernames, username)
// generate a new accesscode
accesscode := newAccessCode(16)
log.Printf("Generated a new AccessCode for user \"%s\": \"%s\"", username, accesscode)
// generate a new companion
spawnCompanion(username, accesscode)
log.Println("---")
log.Println("Done generating the containers, filling the credentials page using a template")
usernameBytes := []byte(username)
usernameBase64 := base64.StdEncoding.EncodeToString(usernameBytes)
accesscodeBytes := []byte(accesscode)
accesscodeBase64 := base64.StdEncoding.EncodeToString(accesscodeBytes)
// insert the username and the accesscode into the http request parameters
r.Form["username"] = []string{usernameBase64}
r.Form["accesscode"] = []string{accesscodeBase64}
credentialsGetHandler(w, r)
}
func usernameTakenGetHandler(w http.ResponseWriter, r *http.Request) {
log.Println("[usernameTaken]")
readFileToReponse(w, "/usernameTaken.html")
}
func isUniq(username string) bool {
for _, user := range usernames {
if username == user {
return false
}
}
return true
}
func isValid(username string) bool {
if username == "traefik" || username == "register" {
return false
}
return true
}
func readFileToReponse(w http.ResponseWriter, path string) {
requestedFile := strings.Replace(path, "..", "", -1)
contents, readError := ioutil.ReadFile(fmt.Sprintf("hosted/%s", requestedFile))
if readError != nil {
w.Write([]byte(fmt.Sprintf("unable to read %s", requestedFile)))
} else {
w.Write([]byte(contents))
}
}
func credentialsGetHandler(w http.ResponseWriter, r *http.Request) {
r.ParseForm()
usernameBase64 := r.Form.Get("username")
username, err := base64.StdEncoding.DecodeString(usernameBase64)
if err != nil {
fmt.Println("error decoding username base64:", err)
}
accesscodeBase64 := r.Form.Get("accesscode")
accesscode, err := base64.StdEncoding.DecodeString(accesscodeBase64)
if err != nil {
fmt.Println("error decoding accesscode base64:", err)
}
log.Println("[ ] Credentials GET Handler")
log.Println("%#v", r.Form)
log.Printf("username: %s", username)
log.Printf("accesscode: %s", accesscode)
// create a new template reading the credentials template file
// the template then gets executed inserting the username and the accesscode
log.Println("creating new template")
t := template.New("")
log.Println("parsing template file")
t, err = t.ParseFiles("./hosted/credentials.html")
if err != nil {
log.Println(err)
}
log.Println("creating a credentials struct")
creds := Credentials{
Username: string(username),
Accesscode: string(accesscode),
Hostname: string(os.Getenv("HOSTNAME")),
}
log.Println("executing the template")
t.ExecuteTemplate(w, "credentials", creds)
log.Println("done executing the template")
}
|