def init_cred(self, call, target="nfs@jupiter", source=None, oid=None): # STUB - need intelligent way to set defaults good_major = [gssapi.GSS_S_COMPLETE, gssapi.GSS_S_CONTINUE_NEEDED] p = Packer() up = GSSUnpacker('') # Set target (of form nfs@SERVER) target = gssapi.Name(target, gssapi.NT_HOSTBASED_SERVICE) # Set source (of form USERNAME) if source is not None: source = gssapi.Name(source, gssapi.NT_USER_NAME) gss_cred = gssapi.Credential(gssapi.INITIATE, source.ptr) # XXX else: # Just use default cred gss_cred = None context = gssapi.Context() token = None handle = '' proc = RPCSEC_GSS_INIT while True: # Call initSecContext. If it returns COMPLETE, we are done. # If it returns CONTINUE_NEEDED, we must send d['token'] # to the target, which will run it through acceptSecContext, # and give us back a token we need to send through initSecContext. # Repeat as necessary. token = context.init(target, token, gss_cred) if context.open: # XXX if res.major == CONTINUE there is a bug in library code # STUB - now what? Just use context? # XXX need to use res.seq_window # XXX - what if handle still '' ? self._add_context(context, handle) break # Send token to target using protocol of RFC 2203 sect 5.2.2 credinfo = CredInfo(self, context=handle, gss_proc=proc) proc = RPCSEC_GSS_CONTINUE_INIT p.reset() p.pack_opaque(token) header, reply = call(p.get_buffer(), credinfo) up.reset(reply) res = up.unpack_rpc_gss_init_res() up.done() # res now holds relevent output from target's acceptSecContext call if res.gss_major not in good_major: raise gssapi.Error(res.gss_major, res.gss_minor) handle = res.handle # Should not change between calls token = res.gss_token # This needs to be sent to initSecContext return CredInfo(self, context=handle)