256 lines
6.7 KiB
Go
256 lines
6.7 KiB
Go
package profile
|
|
|
|
import (
|
|
"AdaptixServer/core/utils/logs"
|
|
isvalid "AdaptixServer/core/utils/valid"
|
|
"errors"
|
|
"os"
|
|
"strings"
|
|
)
|
|
|
|
func tlsVersionRank(v string) (int, bool) {
|
|
s := normalizeTLSVersion(v)
|
|
switch s {
|
|
case "", "DEFAULT":
|
|
return 0, true
|
|
case "TLS10", "TLS1.0":
|
|
return 10, true
|
|
case "TLS11", "TLS1.1":
|
|
return 11, true
|
|
case "TLS12", "TLS1.2":
|
|
return 12, true
|
|
case "TLS13", "TLS1.3":
|
|
return 13, true
|
|
default:
|
|
return 0, false
|
|
}
|
|
}
|
|
|
|
func normalizeTLSVersion(v string) string {
|
|
s := strings.TrimSpace(strings.ToUpper(v))
|
|
s = strings.ReplaceAll(s, "_", "")
|
|
s = strings.ReplaceAll(s, "-", "")
|
|
return s
|
|
}
|
|
|
|
func isAllowedTLSVersion(v string) bool {
|
|
s := normalizeTLSVersion(v)
|
|
switch s {
|
|
case "", "DEFAULT", "TLS10", "TLS1.0", "TLS11", "TLS1.1", "TLS12", "TLS1.2", "TLS13", "TLS1.3":
|
|
return true
|
|
default:
|
|
return false
|
|
}
|
|
}
|
|
|
|
func (p *AdaptixProfile) applyDefaults() {
|
|
if p.HttpServer == nil {
|
|
p.HttpServer = &TsHttpServer{}
|
|
}
|
|
if p.HttpServer.Error == nil {
|
|
p.HttpServer.Error = &TsHttpError{}
|
|
}
|
|
if p.HttpServer.Error.Status == 0 {
|
|
p.HttpServer.Error.Status = 404
|
|
}
|
|
if p.HttpServer.Error.Headers == nil {
|
|
p.HttpServer.Error.Headers = map[string]string{}
|
|
}
|
|
|
|
if p.HttpServer.HTTP == nil {
|
|
p.HttpServer.HTTP = &TsHTTPConfig{}
|
|
}
|
|
if p.HttpServer.HTTP.MaxHeaderBytes == 0 {
|
|
p.HttpServer.HTTP.MaxHeaderBytes = 8192
|
|
}
|
|
if p.HttpServer.HTTP.RequestTimeoutSec == 0 {
|
|
p.HttpServer.HTTP.RequestTimeoutSec = 300
|
|
}
|
|
if p.HttpServer.HTTP.RequestTimeoutMessage == "" {
|
|
p.HttpServer.HTTP.RequestTimeoutMessage = "504 Gateway Timeout"
|
|
}
|
|
|
|
if p.HttpServer.TLS == nil {
|
|
p.HttpServer.TLS = &TsTLSConfig{}
|
|
}
|
|
if p.HttpServer.TLS.MinVersion == "" {
|
|
p.HttpServer.TLS.MinVersion = "TLS1.2"
|
|
}
|
|
if p.HttpServer.TLS.MaxVersion == "" {
|
|
p.HttpServer.TLS.MaxVersion = "TLS1.3"
|
|
}
|
|
}
|
|
|
|
func (p *AdaptixProfile) prepareHttpServer() {
|
|
p.applyDefaults()
|
|
|
|
if p.HttpServer != nil && p.HttpServer.Error != nil && p.HttpServer.Error.PagePath != "" {
|
|
fileContent, err := os.ReadFile(p.HttpServer.Error.PagePath)
|
|
if err != nil {
|
|
logs.Error("", "'HttpServer.error.page': failed to read file: %v", err)
|
|
return
|
|
}
|
|
p.HttpServer.Error.PageContent = string(fileContent)
|
|
}
|
|
}
|
|
|
|
func NewProfile() *AdaptixProfile {
|
|
return new(AdaptixProfile)
|
|
}
|
|
|
|
func (p *AdaptixProfile) IsValid() error {
|
|
valid := true
|
|
|
|
p.prepareHttpServer()
|
|
|
|
if p.Server == nil {
|
|
logs.Error("", "'Teamserver' must be set")
|
|
valid = false
|
|
} else {
|
|
if p.Server.Port < 1 || 65535 < p.Server.Port {
|
|
logs.Error("", "'Teamserver.port' must be between 1 and 65535 (current is %v)", p.Server.Port)
|
|
valid = false
|
|
}
|
|
|
|
if isvalid.ValidUriString(p.Server.Endpoint) == false {
|
|
logs.Error("'Teamserver.endpoint' must be valid URI value (current is %v)", p.Server.Endpoint)
|
|
valid = false
|
|
}
|
|
|
|
if p.Server.Password == "" {
|
|
logs.Error("", "'Teamserver.password' must be set")
|
|
valid = false
|
|
}
|
|
|
|
if p.Server.Cert == "" {
|
|
logs.Error("", "'Teamserver.cert' must be set")
|
|
valid = false
|
|
} else {
|
|
_, err := os.Stat(p.Server.Cert)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
logs.Error("", "'Teamserver.cert': file does not exists")
|
|
valid = false
|
|
} else {
|
|
logs.Error("", "'Teamserver.cert': failed to stat file: %v", err)
|
|
valid = false
|
|
}
|
|
}
|
|
}
|
|
|
|
if p.Server.Key == "" {
|
|
logs.Error("", "'Teamserver.key' must be set")
|
|
valid = false
|
|
} else {
|
|
_, err := os.Stat(p.Server.Key)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
logs.Error("", "'Teamserver.key': file does not exists")
|
|
valid = false
|
|
} else {
|
|
logs.Error("", "'Teamserver.key': failed to stat file: %v", err)
|
|
valid = false
|
|
}
|
|
}
|
|
}
|
|
|
|
if p.Server.Extenders != nil {
|
|
for _, ext := range p.Server.Extenders {
|
|
if ext != "" {
|
|
_, err := os.Stat(ext)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
logs.Error("", "Extender %s: file does not exists", ext)
|
|
valid = false
|
|
} else {
|
|
logs.Error("", "Extender %s: failed to stat file: %v", ext, err)
|
|
valid = false
|
|
}
|
|
}
|
|
}
|
|
}
|
|
}
|
|
|
|
if p.Server.ATokenLive < 1 {
|
|
logs.Error("", "'Teamserver.access_token_live_hours' must be set")
|
|
valid = false
|
|
}
|
|
|
|
if p.Server.RTokenLive < 1 {
|
|
logs.Error("", "'Teamserver.refresh_token_live_hours' must be set")
|
|
valid = false
|
|
}
|
|
}
|
|
|
|
if p.HttpServer == nil {
|
|
logs.Error("", "'HttpServer' must be set")
|
|
valid = false
|
|
} else {
|
|
if p.HttpServer.Error.Status < 100 || p.HttpServer.Error.Status > 999 {
|
|
logs.Error("", "'HttpServer.error.status' must be valid HTTP status (current is %v)", p.HttpServer.Error.Status)
|
|
valid = false
|
|
}
|
|
if p.HttpServer.Error.PagePath != "" {
|
|
_, err := os.Stat(p.HttpServer.Error.PagePath)
|
|
if err != nil {
|
|
if os.IsNotExist(err) {
|
|
logs.Error("", "'HttpServer.error.page': file does not exists")
|
|
valid = false
|
|
} else {
|
|
logs.Error("", "'HttpServer.error.page': failed to stat file: %v", err)
|
|
valid = false
|
|
}
|
|
}
|
|
if p.HttpServer.Error.PageContent == "" {
|
|
logs.Error("", "'HttpServer.error.page': file is empty or cannot be read")
|
|
valid = false
|
|
}
|
|
}
|
|
if p.HttpServer.HTTP.MaxHeaderBytes < 0 {
|
|
logs.Error("", "'HttpServer.http.max_header_bytes' must be >= 0")
|
|
valid = false
|
|
}
|
|
if p.HttpServer.HTTP.ReadHeaderTimeoutSec < 0 {
|
|
logs.Error("", "'HttpServer.http.read_header_timeout_sec' must be >= 0")
|
|
valid = false
|
|
}
|
|
if p.HttpServer.HTTP.ReadTimeoutSec < 0 {
|
|
logs.Error("", "'HttpServer.http.read_timeout_sec' must be >= 0")
|
|
valid = false
|
|
}
|
|
if p.HttpServer.HTTP.WriteTimeoutSec < 0 {
|
|
logs.Error("", "'HttpServer.http.write_timeout_sec' must be >= 0")
|
|
valid = false
|
|
}
|
|
if p.HttpServer.HTTP.IdleTimeoutSec < 0 {
|
|
logs.Error("", "'HttpServer.http.idle_timeout_sec' must be >= 0")
|
|
valid = false
|
|
}
|
|
if p.HttpServer.HTTP.RequestTimeoutSec < 0 {
|
|
logs.Error("", "'HttpServer.http.request_timeout_sec' must be >= 0")
|
|
valid = false
|
|
}
|
|
|
|
if p.HttpServer.TLS.MinVersion != "" && !isAllowedTLSVersion(p.HttpServer.TLS.MinVersion) {
|
|
logs.Error("", "'HttpServer.tls.min_version' has unsupported value (current is %v)", p.HttpServer.TLS.MinVersion)
|
|
valid = false
|
|
}
|
|
if p.HttpServer.TLS.MaxVersion != "" && !isAllowedTLSVersion(p.HttpServer.TLS.MaxVersion) {
|
|
logs.Error("", "'HttpServer.tls.max_version' has unsupported value (current is %v)", p.HttpServer.TLS.MaxVersion)
|
|
valid = false
|
|
}
|
|
|
|
minRank, okMin := tlsVersionRank(p.HttpServer.TLS.MinVersion)
|
|
maxRank, okMax := tlsVersionRank(p.HttpServer.TLS.MaxVersion)
|
|
if okMin && okMax && minRank != 0 && maxRank != 0 && minRank > maxRank {
|
|
logs.Error("", "'HttpServer.tls.min_version' must be <= 'HttpServer.tls.max_version' (current is %v > %v)", p.HttpServer.TLS.MinVersion, p.HttpServer.TLS.MaxVersion)
|
|
valid = false
|
|
}
|
|
}
|
|
|
|
if valid {
|
|
return nil
|
|
}
|
|
return errors.New("Invalid profile\n")
|
|
}
|