gokrb5: OID of MechToken does not match the first in the MechTypeList?

Hello! I am little bit confused and need some advice.

In my Golang (version go1.11.5 linux/amd64) application I am trying to use this library to create SSO (single sign on) authorization by Kerberos and Active Directory.

I have several things:

  1. SPN name for my microservice.
  2. krb5.keytab for my microservice.
  3. krb5.conf file for kerberos client where I set REALM and KDC information.

As you can see my main.go file looks pretty simple:

func main() {
    l := log.New(os.Stderr, "", log.Ldate|log.Ltime|log.Lshortfile)

    kt, err := keytab.Load("./configurations/krb5.keytab"); if err != nil {
        l.Fatalf("Error on \"keytab.Load\": %v", err)
    }

    mux := http.NewServeMux()

    mux.Handle("/", spnego.SPNEGOKRB5Authenticate(http.HandlerFunc(controllers.GetInformation), kt, service.Logger(l)))

    log.Fatal(http.ListenAndServe(":8000", mux))
}

This code raise such ERROR:

2019/04/11 20:07:54 spnego.go:95: 172.28.88.133:2359 - SPNEGO validation error: defective token detected: OID of MechToken does not match the first in the MechTypeList
2019/04/11 20:07:54 spnego.go:95: 172.28.88.133:2359 - SPNEGO Kerberos authentication failed

OID looks like this: 1.2.840.113554.1.2.2

My MechTypeList looks like this:

MechTypeList{true false {[1.2.840.48018.1.2.2 1.2.840.113554.1.2.2 1.3.6.1.4.1.311.2.2.30 1.3.6.1.4.1.311.2.2.10] {[] 0} [96 130 6 130 6 9 42 134 72 ***] [] <nil> <nil>} {0 [] [] <nil> <nil>} <nil> <nil>}

It seems like MechToken comparison failes. What’s wrong happens? What can you advice for fix this problem? Let my know if you need some additional information.

About this issue

  • Original URL
  • State: closed
  • Created 5 years ago
  • Comments: 22 (13 by maintainers)

Commits related to this issue

Most upvoted comments

Hi all, sorry for being away for a while. I hope to start looking into this again but it may take me a while to get back up to speed so please be patient. I also need to fix the integration test automation that no longer seems to run.

Thanks for the contributions. I want to make sure that we solve this in the right way with regards to the RFCs etc. Therefore I want to get a good understanding of what is going on here and what has been contributed so that we produce the correct long term solution and not just a work around.

Thanks.

If anyone is interested, I have made fixes for these two issues

I have made a branch with both fixes: https://github.com/jgiannuzzi/gokrb5/tree/compatibility_fixes

To use it, you can either add this to your Gopkg.toml (if you use dep):

[[constraint]]
  name = "gopkg.in/jcmturner/gokrb5.v7"
  source = "github.com/jgiannuzzi/gokrb5"
  branch = "compatibility_fixes"

or add this to your go.mod (if you use Go modules):

replace gopkg.in/jcmturner/gokrb5.v7 => github.com/jgiannuzzi/gokrb5 v7.2.5-0.20191023085252-766f96a24b2b+incompatible

I merged in #353 for this.

Thanks @jgiannuzzi this is really useful. My view is that Windows 2000 is so old and isn’t supported by MS any more so I don’t see that we should be supporting it either.

As you suggest it would make sense to add to the unmarshal at… https://github.com/jcmturner/gokrb5/blob/8a3a3d700460d6dee4e98b6c06bf26296d2fd2c8/spnego/krb5Token.go#L67-L73 a check that this OID is 1.2.840.113554.1.2.2

@jcmturner just checking if you’ve had time to review any of this? It seems you’ve been off the radar for a bit in terms of this repo - which I understand that life gets in the way. However, without a fix to this here I’ll need to fork and apply changes to my own copy of this package and that’s something I’d rather not do 😃

I’m having the same problem as @NogerbekNurzhan and @BryceDFisher.

RFC4178 states:

If either the initiator’s preferred mechanism is not accepted by the target or this mechanism is accepted but is not the acceptor’s most preferred mechanism (i.e., the MIC token exchange as described in Section 5 is required), GSS_Accept_sec_context() indicates GSS_S_CONTINUE_NEEDED. The acceptor MUST output a negotiation token containing a request-mic state.

So, if I understand it correctly, sending negotiation token with negstate=request-mic is not implemented in spnego.SPNEGOKRB5Authenticate. My current solution is to check message of status returned by nego.AcceptSecContext(&st) in handler, and if it is equal to "OID of MechToken does not match the first in the MechTypeList", then handler should send response token with following fields:

spnego.NegTokenResp{
	NegState:      3, // request-mic
	SupportedMech: gssapi.OID(gssapi.OIDKRB5),
	MechListMIC:   /* result of asn1.Marshal(st.NegTokenInit.MechTypes) */,
}

But this solution is far from perfect, and as @BryceDFisher noted, it looks like there those types can be used interchangeably (I tried to comment the equality check in spnego/negotiationToken.go and it worked), so there is no need in another negotiation round in this case.