package service import ( "io/ioutil" "log" "net/http" "strings" ) type Status int const ( OK Status = iota WAITING ERROR ) type HttpServer struct { manager *Manager status Status } type CreateCSRRequest struct { *BaseMessage Hostname string } type CreateCSRResponse struct { *BaseMessage CSR string `json:"csr"` } type UpdateOpenVPNConfigRequest struct { *BaseMessage Config string } type DeliverCertificateRequest struct { *BaseMessage Certificate string } func NewHttpServer(manager *Manager) *HttpServer { return &HttpServer{manager, WAITING} } func (it *HttpServer) Start() { http.HandleFunc("/", func(writer http.ResponseWriter, request *http.Request) { log.Printf("%s /", strings.ToUpper(request.Method)) writer.WriteHeader(200) writer.Write([]byte("Don't")) }) http.HandleFunc("/create-csr", func(writer http.ResponseWriter, request *http.Request) { log.Printf("%s /create-csr", strings.ToUpper(request.Method)) req := &CreateCSRRequest{ BaseMessage: &BaseMessage{""}, } err := it.verifyRequest(request, req) if err != nil { log.Printf("Error on %s %s: %s", request.Method, request.URL.Path, err) writer.WriteHeader(400) return } csr, err := it.manager.CreateCSR(req.Hostname) if err != nil { writer.WriteHeader(500) return } log.Printf("Sending CSR: %s", csr) it.writeResponse(writer, CreateCSRResponse{ BaseMessage: &BaseMessage{""}, CSR: string(csr), }) }) http.HandleFunc("/deliver-crt", func(writer http.ResponseWriter, request *http.Request) { log.Printf("%s /deliver-crt", strings.ToUpper(request.Method)) req := &DeliverCertificateRequest{ BaseMessage: &BaseMessage{""}, } err := it.verifyRequest(request, req) if err != nil { log.Printf("Error on %s %s: %s", request.Method, request.URL.Path, err) writer.WriteHeader(400) return } err = it.manager.UpdateCertificate(req.Certificate) if err != nil { writer.WriteHeader(500) return } it.manager.openVPN.Start() }) http.HandleFunc("/update-openvpn-config", func(writer http.ResponseWriter, request *http.Request) { log.Printf("%s /update-openvpn-config", strings.ToUpper(request.Method)) req := &UpdateOpenVPNConfigRequest{ BaseMessage: &BaseMessage{""}, } err := it.verifyRequest(request, req) if err != nil { log.Printf("Error on %s %s: %s", request.Method, request.URL.Path, err) writer.WriteHeader(400) return } err = it.manager.openVPN.UpdateConfig(req.Config) if err != nil { writer.WriteHeader(500) return } it.manager.openVPN.Restart() }) http.ListenAndServe(":7864", nil) } func (it *HttpServer) writeResponse(writer http.ResponseWriter, v Message) error { return EncryptAndSign(v, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), writer) } func (it *HttpServer) verifyRequest(r *http.Request, v Message) (error) { hexBody, err := ioutil.ReadAll(r.Body) if err != nil { return err } return DecryptAndVerify(hexBody, it.manager.privateKey, it.manager.CAPublicKey(), it.manager.GetServerFingerprint(), v) }