refactor apparmor confinement
This commit is contained in:
parent
3857e34b52
commit
7a19a15365
15 changed files with 195 additions and 158 deletions
3
Makefile
3
Makefile
|
@ -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
|
||||
|
|
|
@ -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))
|
||||
}
|
||||
}
|
||||
|
|
|
@ -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
10
go.mod
|
@ -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
21
go.sum
|
@ -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=
|
||||
|
|
|
@ -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
|
||||
}
|
|
@ -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;
|
||||
}
|
|
@ -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);
|
|
@ -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
|
||||
}
|
43
internal/util/apparmor_header.go
Normal file
43
internal/util/apparmor_header.go
Normal 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)
|
||||
}
|
||||
}
|
||||
}
|
|
@ -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"
|
||||
)
|
||||
|
|
|
@ -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) {
|
||||
|
|
|
@ -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,
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
@ -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>
|
6
webroot/twilio/voice/voicemail.tpl.xml
Normal file
6
webroot/twilio/voice/voicemail.tpl.xml
Normal file
|
@ -0,0 +1,6 @@
|
|||
{{ template "/twilio/head.tpl.xml" . }}
|
||||
|
||||
<Response>
|
||||
<!-- TODO: finish -->
|
||||
<Hangup />
|
||||
</Response>
|
Loading…
Reference in a new issue