2020-09-27 03:23:58 -04:00
|
|
|
package config
|
|
|
|
|
|
|
|
import (
|
2020-10-07 11:25:56 -04:00
|
|
|
`errors`
|
|
|
|
`fmt`
|
|
|
|
`reflect`
|
|
|
|
`strings`
|
2020-09-27 03:23:58 -04:00
|
|
|
)
|
|
|
|
|
|
|
|
var err error
|
|
|
|
|
2020-10-07 11:25:56 -04:00
|
|
|
// TODO: Match block validation
|
|
|
|
|
|
|
|
// Have I mentioned how dumb golang is yet? The following methods share 90% of the same code,
|
|
|
|
// but ironically delegating that to a separate function is going to be even more of a PITA for now
|
|
|
|
// than just maintaining two separate methods.
|
|
|
|
// How dumb.
|
|
|
|
|
|
|
|
// Validate validates the actual struct of an SshdConf itself, ensuring that certain list fields contain
|
|
|
|
// valid item(s). It collects all found issues in allErr.
|
|
|
|
func (c *SshdConf) Validate() (validConf bool, allErr []error) {
|
|
|
|
// Set the default as true.
|
|
|
|
// We set it on false on first failed validation and keep going.
|
|
|
|
validConf = true
|
|
|
|
fields := reflect.TypeOf(c)
|
|
|
|
values := reflect.ValueOf(c)
|
|
|
|
for i := 0; i < fields.NumField(); i++ {
|
|
|
|
field := fields.Field(i)
|
|
|
|
value := values.Field(i)
|
|
|
|
var validField bool
|
|
|
|
n := field.Name
|
|
|
|
single, isSingle := validSshdSingleVals[n]
|
|
|
|
multi, isMulti := validSshdMultiVals[n]
|
|
|
|
if isSingle {
|
|
|
|
v := value.String()
|
|
|
|
for _, x := range single {
|
|
|
|
if v == x {
|
|
|
|
validField = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !validField {
|
|
|
|
validConf = false
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value %v is not allowed; must be ONE of: %v",
|
|
|
|
n, v, single,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
|
|
|
}
|
|
|
|
} else if isMulti {
|
|
|
|
// These are all []strings if the field name is in validSshdMultiVals.
|
|
|
|
// But golang is still dumb and has no way of serializing directly, so here comes the hackery.
|
|
|
|
v, ok := value.Interface().([]string)
|
|
|
|
if !ok {
|
|
|
|
validConf = false
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value %v was not able to be parsed as a []string",
|
|
|
|
n, v,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
|
|
|
}
|
|
|
|
var invalidSlice []string
|
|
|
|
for _, vStr := range v {
|
|
|
|
validItem := false
|
|
|
|
for _, strip := range sshdStripPre {
|
|
|
|
if n == strip {
|
|
|
|
for _, c := range []string{"+", "-", "^"} {
|
|
|
|
vStr = strings.TrimPrefix(vStr, c)
|
|
|
|
}
|
|
|
|
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, x := range multi {
|
|
|
|
if vStr == x {
|
|
|
|
validItem = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !validItem {
|
|
|
|
invalidSlice = append(invalidSlice, vStr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, x := range invalidSlice {
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value item %v is not valid; it must be one or more of %v",
|
|
|
|
n, x, multi,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
2020-10-07 11:25:56 -04:00
|
|
|
return validConf, allErr
|
|
|
|
}
|
|
|
|
|
|
|
|
// Validate validates the actual struct of an SshConf itself, ensuring that certain list fields contain
|
|
|
|
// valid item(s). It collects all found issues in allErr.
|
|
|
|
func (c *SshConf) Validate() (validConf bool, allErr []error) {
|
|
|
|
// Set the default as true.
|
|
|
|
// We set it on false on first failed validation and keep going.
|
|
|
|
validConf = true
|
|
|
|
fields := reflect.TypeOf(c)
|
|
|
|
values := reflect.ValueOf(c)
|
|
|
|
for i := 0; i < fields.NumField(); i++ {
|
|
|
|
field := fields.Field(i)
|
|
|
|
value := values.Field(i)
|
|
|
|
var validField bool
|
|
|
|
n := field.Name
|
|
|
|
single, isSingle := validSshSingleVals[n]
|
|
|
|
multi, isMulti := validSshMultiVals[n]
|
|
|
|
if isSingle {
|
|
|
|
v := value.String()
|
|
|
|
for _, x := range single {
|
|
|
|
if v == x {
|
|
|
|
validField = true
|
|
|
|
break
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !validField {
|
|
|
|
validConf = false
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value %v is not allowed; must be ONE of: %v",
|
|
|
|
n, v, single,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
|
|
|
}
|
|
|
|
} else if isMulti {
|
|
|
|
// These are all []strings if the field name is in validSshMultiVals.
|
|
|
|
// But golang is still dumb and has no way of serializing directly, so here comes the hackery.
|
|
|
|
v, ok := value.Interface().([]string)
|
|
|
|
if !ok {
|
|
|
|
validConf = false
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value %v was not able to be parsed as a []string",
|
|
|
|
n, v,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
|
|
|
}
|
|
|
|
var invalidSlice []string
|
|
|
|
for _, vStr := range v {
|
|
|
|
validItem := false
|
|
|
|
for _, strip := range sshStripPre {
|
|
|
|
if n == strip {
|
|
|
|
for _, c := range []string{"+", "-", "^"} {
|
|
|
|
vStr = strings.TrimPrefix(vStr, c)
|
|
|
|
}
|
2020-09-27 03:23:58 -04:00
|
|
|
|
2020-10-07 11:25:56 -04:00
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, x := range multi {
|
|
|
|
if vStr == x {
|
|
|
|
validItem = true
|
|
|
|
}
|
|
|
|
}
|
|
|
|
if !validItem {
|
|
|
|
invalidSlice = append(invalidSlice, vStr)
|
|
|
|
}
|
|
|
|
}
|
|
|
|
for _, x := range invalidSlice {
|
|
|
|
e := fmt.Sprintf(
|
|
|
|
"field %v: value item %v is not valid; it must be one or more of %v",
|
|
|
|
n, x, multi,
|
|
|
|
)
|
|
|
|
allErr = append(allErr, errors.New(e))
|
|
|
|
}
|
|
|
|
}
|
|
|
|
}
|
|
|
|
return validConf, allErr
|
2020-09-27 03:23:58 -04:00
|
|
|
}
|