114 lines
3.0 KiB
Go
114 lines
3.0 KiB
Go
|
package main
|
||
|
|
||
|
import (
|
||
|
"encoding/json"
|
||
|
"net/http"
|
||
|
"time"
|
||
|
|
||
|
"github.com/go-acme/lego/v3/challenge"
|
||
|
"github.com/go-chi/chi"
|
||
|
)
|
||
|
|
||
|
// A Challenge has the data necessary to create an ACME DNS-01 Key Authorization Digest.
|
||
|
type Challenge struct {
|
||
|
Domain string `json:"domain"`
|
||
|
Token string `json:"token"`
|
||
|
KeyAuth string `json:"key_authorization"`
|
||
|
error chan error
|
||
|
}
|
||
|
|
||
|
type acmeProvider struct {
|
||
|
BaseURL string
|
||
|
provider challenge.Provider
|
||
|
}
|
||
|
|
||
|
func (p *acmeProvider) Present(domain, token, keyAuth string) error {
|
||
|
return p.provider.Present(domain, token, keyAuth)
|
||
|
}
|
||
|
|
||
|
func (p *acmeProvider) CleanUp(domain, token, keyAuth string) error {
|
||
|
return p.provider.CleanUp(domain, token, keyAuth)
|
||
|
}
|
||
|
|
||
|
func handleDNSRoutes(r chi.Router) {
|
||
|
r.Route("/dns", func(r chi.Router) {
|
||
|
r.Use(func(next http.Handler) http.Handler {
|
||
|
return http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
||
|
ctx := r.Context()
|
||
|
valid, _ := ctx.Value(MWKey("valid")).(bool)
|
||
|
|
||
|
if !valid {
|
||
|
// misdirection
|
||
|
time.Sleep(250 * time.Millisecond)
|
||
|
w.Write([]byte("{\"success\":true}\n"))
|
||
|
//http.Error(w, `{"error":"could not verify token"}`, http.StatusBadRequest)
|
||
|
return
|
||
|
}
|
||
|
/*
|
||
|
if nil != err2 {
|
||
|
// a little misdirection there
|
||
|
msg := `{"error":"internal server error"}`
|
||
|
http.Error(w, msg, http.StatusInternalServerError)
|
||
|
return
|
||
|
}
|
||
|
*/
|
||
|
|
||
|
next.ServeHTTP(w, r.WithContext(ctx))
|
||
|
})
|
||
|
})
|
||
|
|
||
|
r.Post("/{domain}", func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
||
|
ch := Challenge{}
|
||
|
|
||
|
// TODO prevent slow loris
|
||
|
decoder := json.NewDecoder(r.Body)
|
||
|
err := decoder.Decode(&ch)
|
||
|
if nil != err || "" == ch.Token || "" == ch.KeyAuth {
|
||
|
msg := `{"error":"expected json in the format {\"token\":\"xxx\",\"key_authorization\":\"yyy\"}"}`
|
||
|
http.Error(w, msg, http.StatusUnprocessableEntity)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
domain := chi.URLParam(r, "domain")
|
||
|
//domain := chi.URLParam(r, "*")
|
||
|
ch.Domain = domain
|
||
|
|
||
|
// TODO some additional error checking before the handoff
|
||
|
//ch.error = make(chan error, 1)
|
||
|
ch.error = make(chan error)
|
||
|
presenters <- &ch
|
||
|
err = <-ch.error
|
||
|
if nil != err || "" == ch.Token || "" == ch.KeyAuth {
|
||
|
msg := `{"error":"expected json in the format {\"token\":\"xxx\",\"key_authorization\":\"yyy\"}"}`
|
||
|
http.Error(w, msg, http.StatusUnprocessableEntity)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.Write([]byte("{\"success\":true}\n"))
|
||
|
})
|
||
|
|
||
|
// TODO ugly Delete, but whatever
|
||
|
r.Delete("/{domain}/{token}/{keyAuth}", func(w http.ResponseWriter, r *http.Request) {
|
||
|
|
||
|
ch := Challenge{
|
||
|
Domain: chi.URLParam(r, "domain"),
|
||
|
Token: chi.URLParam(r, "token"),
|
||
|
KeyAuth: chi.URLParam(r, "keyAuth"),
|
||
|
error: make(chan error),
|
||
|
//error: make(chan error, 1),
|
||
|
}
|
||
|
|
||
|
cleanups <- &ch
|
||
|
err := <-ch.error
|
||
|
if nil != err || "" == ch.Token || "" == ch.KeyAuth {
|
||
|
msg := `{"error":"expected json in the format {\"token\":\"xxx\",\"key_authorization\":\"yyy\"}"}`
|
||
|
http.Error(w, msg, http.StatusUnprocessableEntity)
|
||
|
return
|
||
|
}
|
||
|
|
||
|
w.Write([]byte("{\"success\":true}\n"))
|
||
|
})
|
||
|
})
|
||
|
}
|