Closed bodgit closed 6 years ago
I've started trying to use these new calls and I've found I need to call sspi.QueryContextAttributes()
with _SECPKG_ATTR_SIZES
to work out how large a buffer I need to be able to store the signature I'm about make.
The schannel
package has all of the various constants defined as well as functions in schannel/attribute.go
to query some of the other _SECPKG_ATTR_*
values but AFAIK these can't be called with my negotiate.ClientContext
. Do some of these functions perhaps need shuffling about? I was thinking that it might make sense to move the main function to the sspi
package and then add thin wrappers to each of the relevant SSP.
For example, define in sspi
:
const (
_SECPKG_ATTR_SIZES = 0
)
type _SecPkgContext_Sizes struct {
MaxToken uint32
MaxSignature uint32
BlockSize uint32
SecurityTrailer uint32
}
func (c *Context) Sizes() (uint32, uint32, uint32, uint32, error) {
var s _SecPkgContext_Sizes
ret := QueryContextAttributes(c.Handle, _SECPKG_ATTR_SIZES, (*byte)(unsafe.Pointer(&s)))
if ret != SEC_E_OK {
return 0, 0, 0, 0, ret
}
return s.MaxToken, s.MaxSignature, s.BlockSize, s.SecurityTrailer, nil
}
And then in sspi.negotiate
just have:
func (c *ClientContext) Sizes() (uint32, uint32, uint32, uint32, error) {
return sspi.Sizes(c.sctxt)
}
func (c *ServerContext) Sizes() (uint32, uint32, uint32, uint32, error) {
return sspi.Sizes(c.sctxt)
}
etc.
For example, define in sspi:
const ( _SECPKG_ATTR_SIZES = 0 )
I don't think SECPKG_ATTR_SIZES is part of SSPI. I think it (and others) are part of schannel Microsoft package. Just copy bits that you need into your code. Will that work for you?
Alex
I don't think SECPKG_ATTR_SIZES is part of SSPI. I think it (and others) are part of schannel Microsoft package.
If you compare the documentation for QueryContextAttributes
between say the negotiate version and the schannel version you can see the list of attributes implemented by both. The schannel version for example implements the SECPKG_ATTR_STREAM_SIZES
attribute but the negotiate version doesn't, however both implement the SECPKG_ATTR_SIZES
attribute. So I think it would make sense to move these to the base SSPI package and then add the wrappers to each security package where that particular attribute is implemented, thankfully the docs should make this straightforward.
Just copy bits that you need into your code. Will that work for you?
Unfortunately golang prohibits me from accessing the negotiate.ClientContext.sctxt
member so I can't do much from outside of your SSPI package.
Happy to extend this PR if you want.
This last commit adds everything that I needed to get things working. I added an exported NewSecBufferDesc
function based on the unexported version in the schannel
package as that seemed useful to have and added MakeSignature
and VerifySignature
functions to the negotiate
package, (according to the docs this isn't supported by the Schannel SSP so I've not added them there).
The library that I've written is here: https://github.com/bodgit/tsig which allows me to do GSS-TSIG signed dynamic DNS updates (primarily to Windows servers) from either Windows clients using SSPI, or from non-Windows clients using GSSAPI). The negotiate handshake itself is performed over DNS using TKEY records.
Fixed. Incidentally, I noticed the testContextExpiry
test always fails for me; the context expiry always seems to be around 5 minutes rather than longer than an hour.
Incidentally, I noticed the testContextExpiry test always fails for me; the context expiry always seems to be around 5 minutes rather than longer than an hour.
I don't have much free time to spend investigating bugs in this packages, but changes are welcome.
Alex
I'm in the process of making some existing GSSAPI code use your SSPI library on Windows. I've used your Negotiate library to establish a context successfully however I now need to use
MakeSignature
&VerifySignature
and noticed they weren't present.This PR is the result of me updating
syscall.go
and runninggo generate
. I'm not quite sure how/where I'm going to use these either adding them somewhere to your Negotiate library or just calling them from my side with the established context but this should be a start.