acme-dns/api.go

110 lines
3.4 KiB
Go
Raw Normal View History

2016-11-11 21:48:00 +07:00
package main
import (
"errors"
"fmt"
2017-01-30 17:19:22 +07:00
2016-11-26 20:42:35 +07:00
log "github.com/Sirupsen/logrus"
2017-01-30 17:19:22 +07:00
"gopkg.in/kataras/iris.v5"
2016-11-11 21:48:00 +07:00
)
2016-11-23 23:07:38 +07:00
// Serve is an authentication middlware function used to authenticate update requests
func (a authMiddleware) Serve(ctx *iris.Context) {
allowUpdate := false
2016-11-17 00:15:36 +07:00
usernameStr := ctx.RequestHeader("X-Api-User")
2016-11-13 19:50:44 +07:00
password := ctx.RequestHeader("X-Api-Key")
postData := ACMETxt{}
2016-11-13 19:50:44 +07:00
2016-11-23 22:11:31 +07:00
username, err := getValidUsername(usernameStr)
if err == nil && validKey(password) {
2016-11-13 19:50:44 +07:00
au, err := DB.GetByUsername(username)
2016-12-01 05:03:08 +07:00
if err != nil {
log.WithFields(log.Fields{"error": err.Error()}).Error("Error while trying to get user")
// To protect against timed side channel (never gonna give you up)
correctPassword(password, "$2a$10$8JEFVNYYhLoBysjAxe2yBuXrkDojBQBkVpXEQgyQyjn43SvJ4vL36")
} else {
if correctPassword(password, au.Password) {
// Password ok
// Now test for the possibly limited ranges
if DNSConf.API.UseHeader {
ips := getIPListFromHeader(ctx.RequestHeader(DNSConf.API.HeaderName))
allowUpdate = au.allowedFromList(ips)
} else {
allowUpdate = au.allowedFrom(ctx.RequestIP())
}
if allowUpdate {
// Update is allowed from remote addr
if err := ctx.ReadJSON(&postData); err == nil {
if au.Subdomain == postData.Subdomain {
ctx.Next()
return
}
} else {
// JSON error
ctx.JSON(iris.StatusBadRequest, iris.Map{"error": "bad data"})
2016-12-01 05:03:08 +07:00
return
}
}
} else {
2016-12-01 05:03:08 +07:00
// Wrong password
log.WithFields(log.Fields{"username": username}).Warning("Failed password check")
}
2016-11-13 19:50:44 +07:00
}
}
ctx.JSON(iris.StatusUnauthorized, iris.Map{"error": "unauthorized"})
}
2016-11-23 23:07:38 +07:00
func webRegisterPost(ctx *iris.Context) {
2016-11-17 00:15:36 +07:00
var regJSON iris.Map
var regStatus int
2016-12-03 15:31:15 +07:00
aTXT := ACMETxt{}
_ = ctx.ReadJSON(&aTXT)
// Create new user
2016-12-03 15:31:15 +07:00
nu, err := DB.Register(aTXT.AllowFrom)
2016-11-11 21:48:00 +07:00
if err != nil {
errstr := fmt.Sprintf("%v", err)
regJSON = iris.Map{"error": errstr}
2016-11-17 00:15:36 +07:00
regStatus = iris.StatusInternalServerError
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"error": err.Error()}).Debug("Error in registration")
2016-11-11 21:48:00 +07:00
} else {
2016-12-03 15:31:15 +07:00
regJSON = iris.Map{"username": nu.Username, "password": nu.Password, "fulldomain": nu.Subdomain + "." + DNSConf.General.Domain, "subdomain": nu.Subdomain, "allowfrom": nu.AllowFrom.ValidEntries()}
2016-11-17 00:15:36 +07:00
regStatus = iris.StatusCreated
2016-11-17 22:52:55 +07:00
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"user": nu.Username.String()}).Debug("Created new user")
2016-11-11 21:48:00 +07:00
}
2016-11-17 00:15:36 +07:00
ctx.JSON(regStatus, regJSON)
2016-11-11 21:48:00 +07:00
}
2016-11-23 23:07:38 +07:00
func webUpdatePost(ctx *iris.Context) {
2016-11-13 19:50:44 +07:00
// User auth done in middleware
2016-11-17 00:15:36 +07:00
a := ACMETxt{}
userStr := ctx.RequestHeader("X-API-User")
// Already checked in auth middlware
username, _ := getValidUsername(userStr)
// Already checked in auth middleware
_ = ctx.ReadJSON(&a)
2016-11-13 19:50:44 +07:00
a.Username = username
// Do update
2016-11-23 22:11:31 +07:00
if validSubdomain(a.Subdomain) && validTXT(a.Value) {
2016-11-13 19:50:44 +07:00
err := DB.Update(a)
if err != nil {
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"error": err.Error()}).Debug("Error while trying to update record")
2016-11-23 23:07:38 +07:00
webUpdatePostError(ctx, errors.New("internal error"), iris.StatusInternalServerError)
2016-11-11 21:48:00 +07:00
return
}
2016-11-13 19:50:44 +07:00
ctx.JSON(iris.StatusOK, iris.Map{"txt": a.Value})
} else {
2016-11-26 20:42:35 +07:00
log.WithFields(log.Fields{"subdomain": a.Subdomain, "txt": a.Value}).Debug("Bad data for subdomain")
2016-11-23 23:07:38 +07:00
webUpdatePostError(ctx, errors.New("bad data"), iris.StatusBadRequest)
2016-11-13 19:50:44 +07:00
return
2016-11-11 21:48:00 +07:00
}
}
2016-11-23 23:07:38 +07:00
func webUpdatePostError(ctx *iris.Context, err error, status int) {
2016-11-17 00:15:36 +07:00
errStr := fmt.Sprintf("%v", err)
updJSON := iris.Map{"error": errStr}
ctx.JSON(status, updJSON)
2016-11-11 21:48:00 +07:00
}