refactor apparmor confinement

This commit is contained in:
ゆめ 2022-11-15 10:31:27 -06:00
parent 3857e34b52
commit 7a19a15365
15 changed files with 195 additions and 158 deletions

View file

@ -43,8 +43,7 @@ clean:
dist/%: ${CMD_DIR}/% FORCE
go build \
-ldflags "-X ${MODULE_PATH}/internal/version.Version=$(VERSION) \
-X ${MODULE_PATH}/internal/version.BuildDate=$(BUILDDATE)" \
-ldflags "-X ${MODULE_PATH}/internal/version.BuildDate=$(BUILDDATE)" \
-o $@ ${MODULE_PATH}/$<
.PHONY: build clean

View file

@ -5,8 +5,9 @@ import (
"log"
"os"
"github.com/eternal-flame-AD/go-apparmor/apparmor"
"github.com/eternal-flame-AD/go-apparmor/apparmor/magic"
"github.com/eternal-flame-AD/yoake/config"
"github.com/eternal-flame-AD/yoake/internal/apparmor"
"github.com/eternal-flame-AD/yoake/internal/comm"
"github.com/eternal-flame-AD/yoake/internal/db"
"github.com/eternal-flame-AD/yoake/server"
@ -40,26 +41,14 @@ func init() {
}
}
func changeHat() {
profile := config.Config().Listen.AppArmor.Serve
if profile != "" {
token, err := apparmor.GetMagicToken()
if err != nil {
log.Panicf("failed to get apparmor magic token: %v", err)
}
if err := apparmor.ChangeHat(profile, token); err != nil {
log.Panicf("failed to change apparmor hat: %v", err)
} else {
log.Printf("changed apparmor hat to %s", profile)
}
}
}
func main() {
listen := config.Config().Listen
Server := server.New()
if listen.Ssl.Use {
var sslCertBytes, sslKeyBytes []byte
apparmor.ExecuteInHat(listen.AppArmor.SSL, func() {
readCerts := func() {
var err error
sslCertBytes, err = os.ReadFile(listen.Ssl.Cert)
if err != nil {
@ -69,16 +58,27 @@ func main() {
if err != nil {
log.Panicf("failed to read ssl key: %v", err)
}
}, true)
}
magic, err := magic.Generate(nil)
if err != nil {
log.Panicf("failed to generate apparmor magic token: %v", err)
}
if listen.AppArmor.SSL != "" {
if err := apparmor.WithHat(listen.AppArmor.SSL, func() uint64 { return magic }, readCerts); err != nil {
log.Panicf("failed to read ssl cert/key with apparmor hat: %v", err)
}
// defensive programming, try read ssl key
if _, err := os.ReadFile(listen.Ssl.Key); err == nil {
log.Panicf("AppArmor profile set for SSL but I could still read %v!", listen.Ssl.Key)
}
} else {
readCerts()
}
log.Fatalln(server.Server.StartTLS(listen.Addr, sslCertBytes, sslKeyBytes))
log.Fatalln(Server.StartTLS(listen.Addr, sslCertBytes, sslKeyBytes))
} else {
log.Fatalln(server.Server.Start(listen.Addr))
log.Fatalln(Server.Start(listen.Addr))
}
}

View file

@ -1,11 +1,14 @@
package config
import (
"log"
"github.com/jinzhu/configor"
"github.com/labstack/echo/v4/middleware"
)
type C struct {
parsed bool
Hosts map[string]string
Listen struct {
Addr string
@ -69,6 +72,9 @@ var parsedC C
var c C
func Config() C {
if !c.parsed {
log.Panicln("Config() called without calling ParseConfig() first")
}
return c
}
@ -81,5 +87,6 @@ func MockConfig(freshEnv bool, wrapper func(deployedC *C)) {
func ParseConfig(files ...string) {
configor.Load(&parsedC, files...)
parsedC.parsed = true
c = parsedC
}

10
go.mod
View file

@ -24,17 +24,20 @@ require (
github.com/cespare/xxhash/v2 v2.1.1 // indirect
github.com/dgraph-io/badger/v3 v3.2103.4 // indirect
github.com/dgraph-io/ristretto v0.1.1 // indirect
github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5 // indirect
github.com/dustin/go-humanize v1.0.0 // indirect
github.com/eternal-flame-AD/go-apparmor v0.0.3 // indirect
github.com/gogo/protobuf v1.3.2 // indirect
github.com/golang-jwt/jwt v3.2.2+incompatible // indirect
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b // indirect
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 // indirect
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da // indirect
github.com/golang/mock v1.6.0 // indirect
github.com/golang/protobuf v1.3.1 // indirect
github.com/golang/protobuf v1.5.2 // indirect
github.com/golang/snappy v0.0.3 // indirect
github.com/google/flatbuffers v1.12.1 // indirect
github.com/gorilla/css v1.0.0 // indirect
github.com/gorilla/securecookie v1.1.1 // indirect
github.com/jsipprell/keyctl v1.0.3 // indirect
github.com/klauspost/compress v1.12.3 // indirect
github.com/labstack/gommon v0.4.0 // indirect
github.com/mattn/go-colorable v0.1.12 // indirect
@ -50,6 +53,7 @@ require (
golang.org/x/sys v0.0.0-20221010170243-090e33056c14 // indirect
golang.org/x/text v0.3.7 // indirect
golang.org/x/time v0.0.0-20220722155302-e5dcc9cfc0b9 // indirect
google.golang.org/protobuf v1.26.0 // indirect
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc // indirect
gopkg.in/yaml.v2 v2.2.2 // indirect
gopkg.in/yaml.v2 v2.4.0 // indirect
)

21
go.sum
View file

@ -32,9 +32,17 @@ github.com/dgraph-io/badger/v3 v3.2103.4/go.mod h1:4MPiseMeDQ3FNCYwRbbcBOGJLf5js
github.com/dgraph-io/ristretto v0.1.1 h1:6CWw5tJNgpegArSHpNHJKldNeq03FQCwYvfMVWajOK8=
github.com/dgraph-io/ristretto v0.1.1/go.mod h1:S1GPSBCYCIhmVNfcth17y2zZtQT6wzkzgwUve0VDWWA=
github.com/dgryski/go-farm v0.0.0-20190423205320-6a90982ecee2/go.mod h1:SqUrOPUnsFjfmXRMNPybcSiG0BgUW2AuFH8PAnS2iTw=
github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5 h1:BaeJtFDlto/NjX9t730OebRRJf2P+t9YEDz3ur18824=
github.com/duo-labs/webauthn v0.0.0-20220815211337-00c9fb5711f5/go.mod h1:Jcj7rFNlTknb18v9jpSA58BveX2LDhXqaoy+6YV1N9g=
github.com/dustin/go-humanize v1.0.0 h1:VSnTsYCnlFHaM2/igO1h6X3HA71jcobQuxemgkq4zYo=
github.com/dustin/go-humanize v1.0.0/go.mod h1:HtrtbFcZ19U5GC7JDqmcUSB87Iq5E25KnS6fMYU6eOk=
github.com/eknkc/amber v0.0.0-20171010120322-cdade1c07385/go.mod h1:0vRUJqYpeSZifjYj7uP3BG/gKcuzL9xWVV/Y+cK33KM=
github.com/eternal-flame-AD/go-apparmor v0.0.1 h1:LBWfkf/Mx0s6inwqurWC8nME7ICg4cDmh2fmOkBeenI=
github.com/eternal-flame-AD/go-apparmor v0.0.1/go.mod h1:K8VSDcvYN18uG+vsnR+3um4t6fX13Km6ci9mgQfDMg8=
github.com/eternal-flame-AD/go-apparmor v0.0.2 h1:sjDN6pyyjXBB+o+oDt6kyo2xiE8vvjZRABZ0fJEzHiE=
github.com/eternal-flame-AD/go-apparmor v0.0.2/go.mod h1:OpqESxf/LXsssooWBPzAoIAC2PtloCT1CmA+glQKYV8=
github.com/eternal-flame-AD/go-apparmor v0.0.3 h1:nFOxi6mbE8wpd5aHbSGvjbnaEjYC156IICWTteSgEIo=
github.com/eternal-flame-AD/go-apparmor v0.0.3/go.mod h1:OpqESxf/LXsssooWBPzAoIAC2PtloCT1CmA+glQKYV8=
github.com/eternal-flame-AD/yubigo v0.0.0-20221005082707-ce0c8989e8b1 h1:B+ad4UMWwNAUsZhLLQCCrEx+cfLsbf0+AbbcfG7RIv0=
github.com/eternal-flame-AD/yubigo v0.0.0-20221005082707-ce0c8989e8b1/go.mod h1:kRnqsWaIjqWNPoCV14+cxs/B9eClc0hKL/I2a3LKOQ4=
github.com/fsnotify/fsnotify v1.4.7/go.mod h1:jwhsz4b93w/PPRr/qN1Yymfu8t87LnFCMoQvtojpjFo=
@ -46,12 +54,17 @@ github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b h1:VKtxabqXZkF25pY9ekf
github.com/golang/glog v0.0.0-20160126235308-23def4e6c14b/go.mod h1:SBH7ygxi8pfUlaOkMMuAQtPIUF8ecWP5IEl/CR7VP2Q=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6 h1:ZgQEtGgCBiWRM39fZuwSd1LwSqqSW0hOdXCYYDX0R3I=
github.com/golang/groupcache v0.0.0-20190702054246-869f871628b6/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da h1:oI5xCqsCo564l8iNU+DwB5epxmsaqB+rhGL0m5jtYqE=
github.com/golang/groupcache v0.0.0-20210331224755-41bb18bfe9da/go.mod h1:cIg4eruTrX1D+g88fzRXU5OdNfaM+9IcxsU14FzY7Hc=
github.com/golang/mock v1.1.1/go.mod h1:oTYuIxOrZwtPieC+H1uAHpcLFnEyAGVDL/k47Jfbm0A=
github.com/golang/mock v1.6.0 h1:ErTB+efbowRARo13NNdxyJji2egdxLGQhRaY+DUumQc=
github.com/golang/mock v1.6.0/go.mod h1:p6yTPP+5HYm5mzsMV8JkE6ZKdX+/wYM6Hr+LicevLPs=
github.com/golang/protobuf v1.2.0/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.3.1 h1:YF8+flBXS5eO826T4nzqPrxfhQThhXl0YzfuUPu4SBg=
github.com/golang/protobuf v1.3.1/go.mod h1:6lQm79b+lXiMfvg/cZm0SGofjICqVBUtrP5yJMmIC1U=
github.com/golang/protobuf v1.5.0/go.mod h1:FsONVRAS9T7sI+LIUmWTfcYkHO4aIWwzhcaSAoJOfIk=
github.com/golang/protobuf v1.5.2 h1:ROPKBNFfQgOUMifHyP+KYbvpjbdoFNs+aK7DXlji0Tw=
github.com/golang/protobuf v1.5.2/go.mod h1:XVQd3VNwM+JqD3oG2Ue2ip4fOMUkwXdXDdiuN0vRsmY=
github.com/golang/snappy v0.0.3 h1:fHPg5GQYlCeLIPB9BZqMVR5nR9A+IM5zcgeTdjMYmLA=
github.com/golang/snappy v0.0.3/go.mod h1:/XxbfmMg8lxefKM7IXC3fBNl/7bRcc72aCRzEWrmP2Q=
github.com/gomarkdown/markdown v0.0.0-20221013030248-663e2500819c h1:iyaGYbCmcYK0Ja9a3OUa2Fo+EaN0cbLu0eKpBwPFzc8=
@ -60,6 +73,7 @@ github.com/google/flatbuffers v1.12.1 h1:MVlul7pQNoDzWRLTw5imwYsl+usrS1TXG2H4jg6
github.com/google/flatbuffers v1.12.1/go.mod h1:1AeVuKshWv4vARoZatz6mlQ0JxURH0Kv5+zNeJKJCa8=
github.com/google/go-cmp v0.3.0/go.mod h1:8QqcDgzrUqlUb/G2PQTWiueGozuR1884gddMywk6iLU=
github.com/google/go-cmp v0.5.4/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/google/go-cmp v0.5.5/go.mod h1:v8dTdLbMG2kIc/vJvl+f65V22dbkXbowE6jgT/gNBxE=
github.com/gorilla/context v1.1.1 h1:AWwleXJkX/nhcU9bZSnZoi3h/qGYqQAGhq6zZe/aQW8=
github.com/gorilla/context v1.1.1/go.mod h1:kBGZzfjB9CEq2AlWe17Uuf7NDRt0dE0s8S51q0aT7Yg=
github.com/gorilla/css v1.0.0 h1:BQqNyPTi50JCFMTw/b67hByjMVXZRwGha6wxVGkeihY=
@ -72,6 +86,8 @@ github.com/hashicorp/hcl v1.0.0/go.mod h1:E5yfLk+7swimpb2L/Alb/PJmXilQ/rhwaUYs4T
github.com/inconshreveable/mousetrap v1.0.0/go.mod h1:PxqpIevigyE2G7u3NXJIT2ANytuPF1OarO4DADm73n8=
github.com/jinzhu/configor v1.2.1 h1:OKk9dsR8i6HPOCZR8BcMtcEImAFjIhbJFZNyn5GCZko=
github.com/jinzhu/configor v1.2.1/go.mod h1:nX89/MOmDba7ZX7GCyU/VIaQ2Ar2aizBl2d3JLF/rDc=
github.com/jsipprell/keyctl v1.0.3 h1:o72tppb3ZhP5B/v9FGUtMqJWx+S1Gs0elQ7AZmiNhsM=
github.com/jsipprell/keyctl v1.0.3/go.mod h1:64s6WpBtruURX3w8W/vhWj1/uh+nOm7vUXSJlK5+KMs=
github.com/kisielk/errcheck v1.5.0/go.mod h1:pFxgyoBC7bSaBwPgfKdkLd5X25qrDl4LWUI2bnpBCr8=
github.com/kisielk/gotool v1.0.0/go.mod h1:XhKaO+MFFWcvkIS/tQcRk01m1F5IRFswLeQ+oQHNcck=
github.com/klauspost/compress v1.12.3 h1:G5AfA94pHPysR56qqrkO2pxEexdDzrpFJ6yt/VqWxVU=
@ -221,6 +237,9 @@ google.golang.org/genproto v0.0.0-20180817151627-c66870c02cf8/go.mod h1:JiN7NxoA
google.golang.org/genproto v0.0.0-20190425155659-357c62f0e4bb/go.mod h1:VzzqZJRnGkLBvHegQrXjBqPurQTc5/KpmUdxsrq26oE=
google.golang.org/grpc v1.19.0/go.mod h1:mqu4LbDTu4XGKhr4mRzUsmM4RtVoemTSY81AxZiDr8c=
google.golang.org/grpc v1.20.1/go.mod h1:10oTOabMzJvdu6/UiuZezV6QK5dSlG84ov/aaiqXj38=
google.golang.org/protobuf v1.26.0-rc.1/go.mod h1:jlhhOSvTdKEhbULTjvd4ARK9grFBp09yW+WbY/TyQbw=
google.golang.org/protobuf v1.26.0 h1:bxAC2xTBsZGibn2RTntX0oH50xLsqy1OxA9tTL3p/lk=
google.golang.org/protobuf v1.26.0/go.mod h1:9q0QmTI4eRPtz6boOQmLYwt+qCgq0jsYwAQnmE0givc=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc h1:2gGKlE2+asNV9m7xrywl36YYNnBG5ZQ0r/BOOxqPpmk=
gopkg.in/alexcesaro/quotedprintable.v3 v3.0.0-20150716171945-2caba252f4dc/go.mod h1:m7x9LTH6d71AHyAX77c9yqWCCa3UKHcVEj9y7hAtKDk=
gopkg.in/check.v1 v0.0.0-20161208181325-20d25e280405/go.mod h1:Co6ibVJAznAaIkqp8huTwlJQCZ016jof/cbN4VW5Yz0=
@ -231,6 +250,8 @@ gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df h1:n7WqCuqOuCbNr617RXOY0AW
gopkg.in/gomail.v2 v2.0.0-20160411212932-81ebce5c23df/go.mod h1:LRQQ+SO6ZHR7tOkpBDuZnXENFzX8qRjMDMyPD6BRkCw=
gopkg.in/yaml.v2 v2.2.2 h1:ZCJp+EgiOT7lHqUV2J862kp8Qj64Jo6az82+3Td9dZw=
gopkg.in/yaml.v2 v2.2.2/go.mod h1:hI93XBmqTisBFMUTm0b8Fm+jr3Dg1NNxqwp+5A1VGuI=
gopkg.in/yaml.v2 v2.4.0 h1:D8xgwECY7CYvx+Y2n4sBz93Jn9JRvxdiyyo8CTfuKaY=
gopkg.in/yaml.v2 v2.4.0/go.mod h1:RDklbk79AGWmwhnvt/jBztapEOGDOx6ZbXqjP6csGnQ=
gopkg.in/yaml.v3 v3.0.0-20200313102051-9f266ea9e77c/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.0-20210107192922-496545a6307b/go.mod h1:K4uyk7z7BCEPqu6E+C64Yfv1cQ7kz7rIZviUmN+EgEM=
gopkg.in/yaml.v3 v3.0.1 h1:fxVm/GzAzEWqLHuvctI91KS9hhNmmWOoWu0XTYJS7CA=

View file

@ -1,65 +0,0 @@
package apparmor
import (
// #cgo LDFLAGS: -lapparmor
// #include "./apparmor.h"
"C"
)
import (
"runtime"
"syscall"
"unsafe"
)
func ChangeHat(subprofile string, magicToken uint64) error {
var ret uintptr
if subprofile != "" {
subProfileC := C.CString(subprofile)
defer C.free(unsafe.Pointer(subProfileC))
ret = uintptr(C.go_aa_change_hat(subProfileC, C.ulong(magicToken)))
} else {
ret = uintptr(C.go_aa_change_hat(nil, C.ulong(magicToken)))
}
if ret != 0 {
return syscall.Errno(ret)
}
return nil
}
func ExecuteInHat(subprofile string, fn func(), lockThread bool) error {
if subprofile == "" {
fn()
return nil
}
if lockThread {
runtime.LockOSThread()
defer runtime.UnlockOSThread()
}
token, err := GetMagicToken()
if err != nil {
return err
}
if err := ChangeHat(subprofile, token); err != nil {
return err
}
fn()
return ChangeHat("", token)
}
func ChangeProfile(subprofile string) error {
var ret uintptr
if subprofile != "" {
subProfileC := C.CString(subprofile)
defer C.free(unsafe.Pointer(subProfileC))
ret = uintptr(C.go_aa_change_profile(subProfileC))
} else {
ret = uintptr(C.go_aa_change_profile(nil))
}
if ret != 0 {
return syscall.Errno(ret)
}
return nil
}

View file

@ -1,21 +0,0 @@
#include "./apparmor.h"
int go_aa_change_hat(const char *hat, unsigned long magic)
{
int ret = aa_change_hat(hat, magic);
if (ret < 0)
{
return errno;
}
return 0;
}
int go_aa_change_profile(const char *profile)
{
int ret = aa_change_profile(profile);
if (ret < 0)
{
return errno;
}
return 0;
}

View file

@ -1,8 +0,0 @@
#include <stdio.h>
#include <stdlib.h>
#include <errno.h>
#include <sys/apparmor.h>
int go_aa_change_hat(const char *hat, unsigned long magic);
int go_aa_change_profile(const char *profile);

View file

@ -1,17 +0,0 @@
package apparmor
import (
"crypto/rand"
"fmt"
)
func GetMagicToken() (uint64, error) {
var buf [64 / 8]byte
if _, err := rand.Read(buf[:]); err != nil {
return 0, fmt.Errorf("failed to generate magic token: %v", err)
}
return uint64(buf[0])<<56 | uint64(buf[1])<<48 |
uint64(buf[2])<<40 | uint64(buf[3])<<32 |
uint64(buf[4])<<24 | uint64(buf[5])<<16 |
uint64(buf[6])<<8 | uint64(buf[7]), nil
}

View file

@ -0,0 +1,43 @@
package util
import (
"fmt"
"log"
"os"
"strings"
"github.com/eternal-flame-AD/go-apparmor/apparmor"
"github.com/labstack/echo/v4"
)
type AAConMiddlewareEnforcer func(label string, mode string) (exit int, err error)
func AAConMiddleware(enforce AAConMiddlewareEnforcer) echo.MiddlewareFunc {
return func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
label, mode, err := apparmor.AAGetCon()
if err != nil {
log.Printf("failed to get apparmor label: %v", err)
label = "[ERROR]"
}
var sanitizedLabel string
if idx := strings.Index(label, "//"); idx == -1 {
sanitizedLabel = "//"
} else {
sanitizedLabel = label[idx:]
}
c.Response().Header().Set("X-App-Con", fmt.Sprintf("%s (%s)", sanitizedLabel, mode))
if enforce != nil {
if exitCode, err := enforce(label, mode); err != nil {
if exitCode == 0 {
c.Response().After(func() {
os.Exit(exitCode)
})
}
return err
}
}
return next(c)
}
}
}

View file

@ -1,6 +1,14 @@
package version
import "runtime/debug"
var (
Version = "unknown"
Version = func() string {
info, ok := debug.ReadBuildInfo()
if !ok {
return "unknown"
}
return info.Main.Version
}()
BuildDate = "unknown"
)

View file

@ -1,10 +1,14 @@
package server
import (
"errors"
"log"
"strings"
"github.com/eternal-flame-AD/go-apparmor/apparmor"
"github.com/eternal-flame-AD/go-apparmor/apparmor/magic"
"github.com/eternal-flame-AD/yoake/config"
"github.com/eternal-flame-AD/yoake/internal/apparmor"
"github.com/eternal-flame-AD/yoake/internal/util"
"github.com/labstack/echo/v4"
)
@ -14,25 +18,58 @@ type (
}
)
var Server = echo.New()
var hosts = map[string]*Host{}
func init() {
hatChanged := false
Server.Any("/*", func(c echo.Context) (err error) {
if !hatChanged {
appArmor := config.Config().Listen.AppArmor
if appArmor.Serve != "" {
if key, err := apparmor.GetMagicToken(); err != nil {
return err
} else {
if err := apparmor.ChangeHat(appArmor.Serve, key); err != nil {
return err
}
}
}
hatChanged = true
func New() *echo.Echo {
var Server = echo.New()
hatServe := config.Config().Listen.AppArmor.Serve
if hatServe != "" {
store, err := magic.NewKeyring(nil)
if err != nil {
log.Panicf("failed to initialize magic token store: %v", err)
}
if magic, err := magic.Generate(nil); err != nil {
log.Panicf("failed to generate apparmor magic token: %v", err)
} else {
if err := store.Set(magic); err != nil {
log.Panicf("failed to store apparmor magic token: %v", err)
}
}
hatMagic := func() uint64 {
magic, err := store.Get()
if err != nil {
log.Panicf("failed to get magic token: %v", err)
}
return magic
}
Server.Pre(func(next echo.HandlerFunc) echo.HandlerFunc {
return func(c echo.Context) error {
var err error
if errAppArmor := apparmor.WithHat(hatServe, hatMagic, func() {
err = next(c)
}); errAppArmor != nil {
c.Logger().Errorf("apparmor error: %v", errAppArmor)
return errors.New("apparmor process transition error")
}
return err
}
})
aaEnforcer := util.AAConMiddleware(func(label string, mode string) (exit int, err error) {
if !strings.HasSuffix(label, "//"+hatServe) {
return 1, errors.New("apparmor process transition error")
}
return 0, nil
})
Server.Pre(aaEnforcer)
Server.Use(aaEnforcer)
for _, h := range hosts {
h.Echo.Pre(aaEnforcer)
h.Echo.Use(aaEnforcer)
}
}
Server.Any("/*", func(c echo.Context) (err error) {
req := c.Request()
res := c.Response()
host := hosts[strings.ToLower(req.Host)]
@ -40,13 +77,17 @@ func init() {
if host == nil {
host = hosts[""]
if host == nil {
return echo.ErrNotFound
err = echo.ErrNotFound
return
}
}
host.Echo.ServeHTTP(res, req)
return
})
return Server
}
func RegisterHostname(hostname string, h *Host) {

View file

@ -7,6 +7,7 @@ import (
"regexp"
"strconv"
"github.com/eternal-flame-AD/go-apparmor/apparmor"
"github.com/eternal-flame-AD/yoake/internal/auth"
"github.com/labstack/echo/v4"
"github.com/labstack/echo/v4/middleware"
@ -14,9 +15,10 @@ import (
type logEntry struct {
middleware.RequestLoggerValues
Categories []string
CleanPath string
Auth auth.RequestAuth
Categories []string
CleanPath string
AppArmorCon string
Auth auth.RequestAuth
}
func processLoggerValues(c echo.Context, values middleware.RequestLoggerValues) logEntry {
@ -26,11 +28,20 @@ func processLoggerValues(c echo.Context, values middleware.RequestLoggerValues)
logSetRequestCategory(c, fmt.Sprintf("status_%s", statusString))
statusString[i] = 'x'
}
aaCon := ""
label, mode, err := apparmor.AAGetCon()
if err != nil {
aaCon = fmt.Sprintf("error: %s", err)
} else {
aaCon = fmt.Sprintf("%s (%s)", label, mode)
}
return logEntry{
RequestLoggerValues: values,
Categories: logGetCategories(c),
CleanPath: path.Clean(c.Request().URL.Path),
Auth: auth.GetRequestAuth(c),
AppArmorCon: aaCon,
}
}

View file

@ -4,7 +4,15 @@
{{ $num_visited := (get $session "num_visited") }}
{{ if not $num_visited }}{{ $num_visited = 0 }} {{ end }}
{{ set $session "num_visited" (math "argv(1) + 1" $num_visited) }}
<Response>
{{ if $src := (invoke "FormValue" .C "ForwardedFrom") }}
{{ if eq $src "+15122993080" }}
<Redirect method="POST">/twilio/voice/voicemail.xml></Redirect>
{{ end }}
{{ end }}
<Say voice="alice" language="en-US">This is Anne!</Say>
<Redirect method="POST">/twilio/voice/menu.xml</Redirect>
</Response>

View file

@ -0,0 +1,6 @@
{{ template "/twilio/head.tpl.xml" . }}
<Response>
<!-- TODO: finish -->
<Hangup />
</Response>