You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

138 lines
3.0 KiB
Go

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)
}