// MakeOIDBytes makes an OID encapsulating a byte slice. Note that it does not // duplicate the data, but rather it points to it directly. func (lib *Lib) MakeOIDBytes(data []byte) (*OID, error) { oid := lib.NewOID() s := C.malloc(C.gss_OID_size) // s for struct if s == nil { return nil, ErrMallocFailed } C.memset(s, 0, C.gss_OID_size) l := C.size_t(len(data)) e := C.malloc(l) // c for contents if e == nil { return nil, ErrMallocFailed } C.memmove(e, (unsafe.Pointer)(&data[0]), l) oid.C_gss_OID = C.gss_OID(s) oid.alloc = allocMalloc // because of the alignment issues I can't access o.oid's fields from go, // so invoking a C function to do the same as: // oid.C_gss_OID.length = l // oid.C_gss_OID.elements = c C.helper_gss_OID_desc_set_elements(oid.C_gss_OID, C.OM_uint32(l), e) return oid, nil }
// InitSecContext initiates a security context. Usually invoked by the client. // A Context (CtxId) describes the state at one end of an authentication // protocol. May return ErrContinueNeeded if the client is to make another // iteration of exchanging token with the service func (lib *Lib) InitSecContext(initiatorCredHandle *CredId, ctxIn *CtxId, targetName *Name, mechType *OID, reqFlags uint32, timeReq time.Duration, inputChanBindings ChannelBindings, inputToken *Buffer) ( ctxOut *CtxId, actualMechType *OID, outputToken *Buffer, retFlags uint32, timeRec time.Duration, err error) { runtime.LockOSThread() defer runtime.UnlockOSThread() // prepare the input params C_initiator := C.gss_cred_id_t(nil) if initiatorCredHandle != nil { C_initiator = initiatorCredHandle.C_gss_cred_id_t } C_mechType := C.gss_OID(nil) if mechType != nil { C_mechType = mechType.C_gss_OID } C_inputToken := C.gss_buffer_t(nil) if inputToken != nil { C_inputToken = inputToken.C_gss_buffer_t } // prepare the outputs. if ctxIn != nil { ctxCopy := *ctxIn ctxOut = &ctxCopy } else { ctxOut = lib.NewCtxId() } min := C.OM_uint32(0) actualMechType = lib.NewOID() outputToken, err = lib.MakeBuffer(allocGSSAPI) if err != nil { return nil, nil, nil, 0, 0, err } flags := C.OM_uint32(0) timerec := C.OM_uint32(0) maj := C.wrap_gss_init_sec_context(lib.Fp_gss_init_sec_context, &min, C_initiator, &ctxOut.C_gss_ctx_id_t, // used as both in and out param targetName.C_gss_name_t, C_mechType, C.OM_uint32(reqFlags), C.OM_uint32(timeReq.Seconds()), C.gss_channel_bindings_t(inputChanBindings), C_inputToken, &actualMechType.C_gss_OID, outputToken.C_gss_buffer_t, &flags, &timerec) err = lib.stashLastStatus(maj, min) if err != nil { return nil, nil, nil, 0, 0, err } if MajorStatus(maj).ContinueNeeded() { err = ErrContinueNeeded } return ctxOut, actualMechType, outputToken, uint32(flags), time.Duration(timerec) * time.Second, err }