checker-kerberos/checker/errors.go

48 lines
1.4 KiB
Go

package checker
import (
"errors"
"strconv"
"strings"
"github.com/jcmturner/gokrb5/v8/iana/errorcode"
"github.com/jcmturner/gokrb5/v8/messages"
)
// krbErrorInfo extracts a Kerberos error code (and its short name) from an
// error returned by gokrb5. Direct KRBError values are matched via
// errors.As; otherwise the error string is parsed, since gokrb5 also
// returns wrapped krberror.Krberror values that carry the code only inside
// their formatted message. ok is false when no code could be extracted.
func krbErrorInfo(err error) (code int32, name string, ok bool) {
if err == nil {
return 0, "", false
}
var krbErr messages.KRBError
if errors.As(err, &krbErr) {
return krbErr.ErrorCode, errorcodeName(krbErr.ErrorCode), true
}
msg := err.Error()
if _, after, found := strings.Cut(msg, "KRB Error: ("); found {
if c, _, found := strings.Cut(after, ")"); found {
if n, perr := strconv.Atoi(c); perr == nil {
return int32(n), errorcodeName(int32(n)), true
}
}
}
return 0, "", false
}
// errorcodeName returns the short symbolic name of a Kerberos error code
// (e.g. "KDC_ERR_PREAUTH_REQUIRED"), trimming the numeric/textual padding
// gokrb5 wraps around it.
func errorcodeName(code int32) string {
s := errorcode.Lookup(code)
if _, after, ok := strings.Cut(s, ") "); ok {
s = after
}
if before, _, ok := strings.Cut(s, " "); ok {
s = before
}
return s
}