Пример #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)
Пример #2
0
 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():]
Пример #3
0
    def _event_rpc_call(self, msg, msg_data, pipe):
        """Deal with an incoming RPC CALL.
        
        msg is unpacked header, with length fields added.
        msg_data is raw procedure data.
        """
        """Given an RPC record, returns appropriate reply

        This is run in its own thread.
        """
        class XXX(object):
            pass
        call_info = XXX() # Store various info we need to pass to procedure
        call_info.header_size = msg.length
        call_info.payload_size = len(msg_data)
        call_info.connection = pipe
        notify = None
        try:
            # Check for reasons to DENY the call
            try:
                self._check_rpcvers(msg)
                call_info.credinfo = self._check_auth(msg, msg_data)
            except rpclib.RPCFlowContol:
                raise
            except Exception:
                log_t.warn("Problem with incoming call, returning AUTH_FAILED",
                           exc_info=True)
                raise rpclib.RPCDeniedReply(AUTH_ERROR, AUTH_FAILED)
            # Call has been ACCEPTED, now check for reasons not to succeed
            sec = call_info.credinfo.sec
            msg_data = sec.unsecure_data(msg.body.cred, msg_data)
            if not self._check_program(msg.prog):
                log_t.warn("PROG_UNAVAIL, do not support prog=%i" % msg.prog)
                raise rpclib.RPCUnsuccessfulReply(PROG_UNAVAIL)
            low, hi = self._version_range(msg.prog)
            if not self._check_version(low, hi, msg.vers):
                log_t.warn("PROG_MISMATCH, do not support vers=%i" % msg.vers)
                raise rpclib.RPCUnsuccessfulReply(PROG_MISMATCH, (low, hi))
            method = self._find_method(msg)
            if method is None:
                log_t.warn("PROC_UNAVAIL for vers=%i, proc=%i" %
                           (msg.vers, msg.proc))
                raise rpclib.RPCUnsuccessfulReply(PROC_UNAVAIL)
            # Everything looks good at this layer, time to do the call
            tuple = method(msg_data, call_info)
            if len(tuple) == 2:
                status, result = tuple
            else:
                status, result, notify = tuple
            if result is None:
                result = ''
            if not isinstance(result, basestring):
                raise TypeError("Expected string")
            # status, result = method(msg_data, call_info)
            log_t.debug("Called method, got %r, %r" % (status, result))
        except rpclib.RPCDrop:
            # Silently drop the request
            self._notify_drop()
            return
        except rpclib.RPCFlowContol, e:
            body, data = e.body()
Пример #4
0
                status, result, notify = tuple
            if result is None:
                result = ''
            if not isinstance(result, basestring):
                raise TypeError("Expected string")
            # status, result = method(msg_data, call_info)
            log_t.debug("Called method, got %r, %r" % (status, result))
        except rpclib.RPCDrop:
            # Silently drop the request
            self._notify_drop()
            return
        except rpclib.RPCFlowContol, e:
            body, data = e.body()
        except Exception:
            log_t.warn("Unexpected exception", exc_info=True)
            body, data = rpclib.RPCUnsuccessfulReply(SYSTEM_ERR).body()
        else:
            try:
                data = sec.secure_data(msg.body.cred, result)
                verf = sec.make_reply_verf(msg.body.cred, status)
                areply = accepted_reply(verf, rpc_reply_data(status, ''))
                body = reply_body(MSG_ACCEPTED, areply=areply)
            except Exception:
                body, data = rpclib.RPCUnsuccessfulReply(SYSTEM_ERR).body()
        pipe.send_reply(msg.xid, body, data)
        if notify is not None:
            notify()

    def _notify_drop(self):
        """Debugging hook called when a request is dropped."""
        log_t.warn("Dropped request")
Пример #5
0
 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)