Exemple #1
0
    def unsecure_data(self, cred, data):
        def pull_seqnum(blob):
            """Pulls initial seq_num off of blob, checks it, then returns data.
            """
            # blob = seq_num + data
            p.reset(blob)
            try:
                seq_num = p.unpack_uint()
            except:
                log_gss.exception("unsecure_data - unpacking seq_num")
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
            if seq_num != cred.seq_num:
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
            return p.get_buffer()[p.get_position():]

        def check_gssapi(qop):
            if qop != cred.qop:
                # XXX Not sure what error to give here
                log_gss.warn("unsecure_data: mismatched qop %i != %i" %
                             (qop, cred.qop))
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)

        cred = cred.body
        if cred.service ==  rpc_gss_svc_none or \
           cred.gss_proc in (RPCSEC_GSS_INIT, RPCSEC_GSS_CONTINUE_INIT):
            return data
        p = GSSUnpacker(data)
        context = self._get_context(cred.handle)
        try:
            if cred.service == rpc_gss_svc_integrity:
                # data = opaque[gss_seq_num+data] + opaque[checksum]
                try:
                    data = p.unpack_opaque()
                    checksum = p.unpack_opaque()
                    p.done()
                except:
                    log_gss.exception("unsecure_data - initial unpacking")
                    raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
                qop = context.verifyMIC(data, checksum)
                check_gssapi(qop)
                data = pull_seqnum(data)
            elif cred.service == rpc_gss_svc_privacy:
                # data = opaque[wrap([gss_seq_num+data])]
                try:
                    data = p.unpack_opaque()
                    p.done()
                except:
                    log_gss.exception("unsecure_data - initial unpacking")
                    raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
                # data, qop, conf = context.unwrap(data)
                data, qop = context.unwrap(data)
                check_gssapi(qop)
                data = pull_seqnum(data)
            else:
                # Can't get here, but doesn't hurt
                log_gss.error("Unknown service %i for RPCSEC_GSS" %
                              cred.service)
        except gssapi.Error, e:
            log_gss.warn("unsecure_data: gssapi call returned %s" % e.name)
            raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
Exemple #2
0
 def check_reply_verf(self, msg, call_cred, data):
     if msg.stat != MSG_ACCEPTED:
         return
     verf = msg.rbody.areply.verf
     if msg.rbody.areply.reply_data.stat != SUCCESS:
         if not self.is_NULL(verf):
             raise SecError("Bad reply verifier - expected NULL verifier")
     elif call_cred.body.gss_proc in (RPCSEC_GSS_INIT,
                                      RPCSEC_GSS_CONTINUE_INIT):
         # The painful case - we need to check against reply data
         p = GSSUnpacker(data)
         try:
             res = p.unpack_rpc_gss_init_res()
             p.done()
         except:
             log_gss.warn("Failure unpacking gss_init_res")
             raise SecError("Failure unpacking gss_init_res")
         if self.is_NULL(verf):
             if res.gss_major == GSS_S_COMPLETE:
                 raise SecError("Expected seq_window, got NULL")
         else:
             if res.gss_major != GSS_S_COMPLETE:
                 raise SecError("Expected NULL")
             # BUG - context establishment is not finished on client
             # - so how get context?  How run verifyMIC?
             # - This seems to be a protocol problem.  Just ignore for now
     else:
         p = Packer()
         p.pack_uint(call_cred.body.seq_num)
         qop = call_cred.context.verifyMIC(p.get_buffer(), verf.body)
         if qop != call_cred.body.qop:
             raise SecError("Mismatched qop")
Exemple #3
0
 def check_reply_verf(self, msg, call_cred, data):
     if msg.stat != MSG_ACCEPTED:
         return
     verf = msg.rbody.areply.verf
     if msg.rbody.areply.reply_data.stat != SUCCESS:
         if not self.is_NULL(verf):
             raise SecError("Bad reply verifier - expected NULL verifier")
     elif call_cred.body.gss_proc in (RPCSEC_GSS_INIT, RPCSEC_GSS_CONTINUE_INIT):
         # The painful case - we need to check against reply data
         p = GSSUnpacker(data)
         try:
             res = p.unpack_rpc_gss_init_res()
             p.done()
         except:
             log_gss.warn("Failure unpacking gss_init_res")
             raise SecError("Failure unpacking gss_init_res")
         if self.is_NULL(verf):
             if res.gss_major == GSS_S_COMPLETE:
                 raise SecError("Expected seq_window, got NULL")
         else:
             if res.gss_major != GSS_S_COMPLETE:
                 raise SecError("Expected NULL")
             # BUG - context establishment is not finished on client
             # - so how get context?  How run verifyMIC?
             # - This seems to be a protocol problem.  Just ignore for now
     else:
         p = Packer()
         p.pack_uint(call_cred.body.seq_num)
         qop = call_cred.context.verifyMIC(p.get_buffer(), verf.body)
         if qop != call_cred.body.qop:
             raise SecError("Mismatched qop")
Exemple #4
0
    def unsecure_data(self, cred, data):
        def pull_seqnum(blob):
            """Pulls initial seq_num off of blob, checks it, then returns data.
            """
            # blob = seq_num + data
            p.reset(blob)
            try:
                seq_num = p.unpack_uint()
            except:
                log_gss.exception("unsecure_data - unpacking seq_num")
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
            if seq_num != cred.seq_num:
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
            return p.get_buffer()[p.get_position():]

        def check_gssapi(qop):
            if qop != cred.qop:
                # XXX Not sure what error to give here
                log_gss.warn("unsecure_data: mismatched qop %i != %i" %
                             (qop, cred.qop))
                raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)

        cred = cred.body
        if cred.service ==  rpc_gss_svc_none or \
           cred.gss_proc in (RPCSEC_GSS_INIT, RPCSEC_GSS_CONTINUE_INIT):
            return data
        p = GSSUnpacker(data)
        context = self._get_context(cred.handle)
        try:
            if cred.service == rpc_gss_svc_integrity:
                # data = opaque[gss_seq_num+data] + opaque[checksum]
                try:
                    data = p.unpack_opaque()
                    checksum = p.unpack_opaque()
                    p.done()
                except:
                    log_gss.exception("unsecure_data - initial unpacking")
                    raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
                qop = context.verifyMIC(data, checksum)
                check_gssapi(qop)
                data = pull_seqnum(data)
            elif cred.service == rpc_gss_svc_privacy:
                # data = opaque[wrap([gss_seq_num+data])]
                try:
                    data = p.unpack_opaque()
                    p.done()
                except:
                    log_gss.exception("unsecure_data - initial unpacking")
                    raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
                # data, qop, conf = context.unwrap(data)
                data, qop = context.unwrap(data)
                check_gssapi(qop)
                data = pull_seqnum(data)
            else:
                # Can't get here, but doesn't hurt
                log_gss.error("Unknown service %i for RPCSEC_GSS" % cred.service)
        except gssapi.Error as e:
            log_gss.warn("unsecure_data: gssapi call returned %s" % e.name)
            raise rpclib.RPCUnsuccessfulReply(GARBAGE_ARGS)
        return data
Exemple #5
0
 def handle_gss_init(self, cred, data, first):
     p = GSSUnpacker(data)
     token = p.unpack_opaque()
     p.done()
     log_gss.debug("***ACCEPTSECCONTEXT***")
     if first:
         context = gssapi.Context()
     else:
         context = self._get_context(cred.body.handle)
     try:
         token = context.accept(token)
     except gssapi.Error, e:
         log_gss.debug("RPCSEC_GSS_INIT failed (%s, %i)!" %
                       (e.name, e.minor))
         res = rpc_gss_init_res('', e.major, e.minor, 0, '')
Exemple #6
0
 def handle_gss_init(self, cred, data, first):
     p = GSSUnpacker(data)
     token = p.unpack_opaque()
     p.done()
     log_gss.debug("***ACCEPTSECCONTEXT***")
     if first:
         context = gssapi.Context()
     else:
         context = self._get_context(cred.body.handle)
     try:
         token = context.accept(token)
     except gssapi.Error, e:
         log_gss.debug("RPCSEC_GSS_INIT failed (%s, %i)!" %
                       (e.name, e.minor))
         res = rpc_gss_init_res('', e.major, e.minor, 0, '')
Exemple #7
0
 def handle_gss_init(self, cred, data, first):
     p = GSSUnpacker(data)
     token = p.unpack_opaque()
     p.done()
     log_gss.debug("***ACCEPTSECCONTEXT***")
     if first:
         context = gssapi.Context()
     else:
         context = self._get_context(cred.body.handle)
     try:
         token = context.accept(token)
     except gssapi.Error as e:
         log_gss.debug("RPCSEC_GSS_INIT failed (%s, %i)!" %
                       (e.name, e.minor))
         res = rpc_gss_init_res('', e.major, e.minor, 0, '')
     else:
         log_gss.debug("RPCSEC_GSS_*INIT succeeded!")
         if first:
             handle = self._add_context(context)
             # XXX HACK - this ensures make_reply_verf works, but
             # is a subtle side-effect that could introduce bugs if code
             # is ever reorganized.  Currently cred is forgotten once
             # we leave here though.
             cred.body.rpc_gss_cred_vers_1_t.handle = handle
         else:
             handle = cred.body.handle
         if context.open:
             major = gssapi.GSS_S_COMPLETE
         else:
             major = gssapi.GSS_S_CONTINUE_NEEDED
         res = rpc_gss_init_res(
             handle,
             major,
             0,  # XXX can't see minor
             WINDOWSIZE,
             token)
     # Prepare response
     p = GSSPacker()
     p.pack_rpc_gss_init_res(res)
     # NOTE this is an annoying case for make_reply_verf.
     # It is the only time that you need msg_data to feed into it.
     verf = self.make_reply_verf(cred, major)
     raise rpclib.RPCSuccessfulReply(verf, p.get_buffer())
Exemple #8
0
 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)
Exemple #9
0
 def handle_gss_init(self, cred, data, first):
     p = GSSUnpacker(data)
     token = p.unpack_opaque()
     p.done()
     log_gss.debug("***ACCEPTSECCONTEXT***")
     if first:
         context = gssapi.Context()
     else:
         context = self._get_context(cred.body.handle)
     try:
         token = context.accept(token)
     except gssapi.Error as e:
         log_gss.debug("RPCSEC_GSS_INIT failed (%s, %i)!" %
                       (e.name, e.minor))
         res = rpc_gss_init_res('', e.major, e.minor, 0, '')
     else:
         log_gss.debug("RPCSEC_GSS_*INIT succeeded!")
         if first:
             handle = self._add_context(context)
             # XXX HACK - this ensures make_reply_verf works, but
             # is a subtle side-effect that could introduce bugs if code
             # is ever reorganized.  Currently cred is forgotten once
             # we leave here though.
             cred.body.rpc_gss_cred_vers_1_t.handle = handle
         else:
             handle = cred.body.handle
         if context.open:
             major = gssapi.GSS_S_COMPLETE
         else:
             major = gssapi.GSS_S_CONTINUE_NEEDED
         res = rpc_gss_init_res(handle, major, 0, # XXX can't see minor
                                WINDOWSIZE, token)
     # Prepare response
     p = GSSPacker()
     p.pack_rpc_gss_init_res(res)
     # NOTE this is an annoying case for make_reply_verf.
     # It is the only time that you need msg_data to feed into it.
     verf = self.make_reply_verf(cred, major)
     raise rpclib.RPCSuccessfulReply(verf, p.get_buffer())
Exemple #10
0
 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)
Exemple #11
0
 def unpack_cred(cred):
     p = GSSUnpacker(cred)
     py_cred = p.unpack_rpc_gss_cred_t()
     p.done()
     return py_cred
Exemple #12
0
 def unpack_cred(cred):
     p = GSSUnpacker(cred)
     py_cred = p.unpack_rpc_gss_cred_t()
     p.done()
     return py_cred