예제 #1
0
class ASN1_Object(six.with_metaclass(ASN1_Object_metaclass)):
    tag = ASN1_Class_UNIVERSAL.ANY

    def __init__(self, val):
        self.val = val

    def enc(self, codec):
        return self.tag.get_codec(codec).enc(self.val)

    def __repr__(self):
        return "<%s[%r]>" % (self.__dict__.get("name", self.__class__.__name__), self.val)  # noqa: E501

    def __str__(self):
        return self.enc(conf.ASN1_default_codec)

    def __bytes__(self):
        return self.enc(conf.ASN1_default_codec)

    def strshow(self, lvl=0):
        return ("  " * lvl) + repr(self) + "\n"

    def show(self, lvl=0):
        print(self.strshow(lvl))

    def __eq__(self, other):
        return self.val == other

    def __lt__(self, other):
        return self.val < other

    def __le__(self, other):
        return self.val <= other

    def __gt__(self, other):
        return self.val > other

    def __ge__(self, other):
        return self.val >= other

    def __ne__(self, other):
        return self.val != other
예제 #2
0
파일: cert.py 프로젝트: qbsonn/scapy
class PrivKey(six.with_metaclass(_PrivKeyFactory, object)):
    """
    Parent class for both PrivKeyRSA and PrivKeyECDSA.
    Provides common signTBSCert() and resignCert() methods.
    """

    def signTBSCert(self, tbsCert, h="sha256"):
        """
        Note that this will always copy the signature field from the
        tbsCertificate into the signatureAlgorithm field of the result,
        regardless of the coherence between its contents (which might
        indicate ecdsa-with-SHA512) and the result (e.g. RSA signing MD2).

        There is a small inheritance trick for the computation of sigVal
        below: in order to use a sign() method which would apply
        to both PrivKeyRSA and PrivKeyECDSA, the sign() methods of the
        subclasses accept any argument, be it from the RSA or ECDSA world,
        and then they keep the ones they're interested in.
        Here, t will be passed eventually to pkcs1._DecryptAndSignRSA.sign().
        """
        sigAlg = tbsCert.signature
        h = h or hash_by_oid[sigAlg.algorithm.val]
        sigVal = self.sign(raw(tbsCert), h=h, t='pkcs')
        c = X509_Cert()
        c.tbsCertificate = tbsCert
        c.signatureAlgorithm = sigAlg
        c.signatureValue = ASN1_BIT_STRING(sigVal, readable=True)
        return c

    def resignCert(self, cert):
        """ Rewrite the signature of either a Cert or an X509_Cert. """
        return self.signTBSCert(cert.tbsCertificate)

    def verifyCert(self, cert):
        """ Verifies either a Cert or an X509_Cert. """
        tbsCert = cert.tbsCertificate
        sigAlg = tbsCert.signature
        h = hash_by_oid[sigAlg.algorithm.val]
        sigVal = raw(cert.signatureValue)
        return self.verify(raw(tbsCert), sigVal, h=h, t='pkcs')
예제 #3
0
class _GenericHMAC(six.with_metaclass(_GenericHMACMetaclass, object)):
    def __init__(self, key=None):
        self.key = key

    def digest(self, tbd):
        if self.key is None:
            raise HMACError
        return hmac.new(self.key, tbd, self.hash_alg.hash_cls).digest()

    def digest_sslv3(self, tbd):
        if self.key is None:
            raise HMACError

        h = self.hash_alg()
        if h.name == "SHA":
            pad1 = SSLv3_PAD1_SHA1
            pad2 = SSLv3_PAD2_SHA1
        elif h.name == "MD5":
            pad1 = SSLv3_PAD1_MD5
            pad2 = SSLv3_PAD2_MD5
        else:
            raise HMACError("Provided hash does not work with SSLv3.")

        return h.digest(self.key + pad2 + h.digest(self.key + pad1 + tbd))
예제 #4
0
class _GenericKX(six.with_metaclass(_GenericKXMetaclass)):
    pass
예제 #5
0
class _FFDHParams(six.with_metaclass(_FFDHParamsMetaclass)):
    pass
예제 #6
0
class BERcodec_Object(six.with_metaclass(BERcodec_metaclass)):
    codec = ASN1_Codecs.BER
    tag = ASN1_Class_UNIVERSAL.ANY

    @classmethod
    def asn1_object(cls, val):
        return cls.tag.asn1_object(val)

    @classmethod
    def check_string(cls, s):
        if not s:
            raise BER_Decoding_Error(
                "%s: Got empty object while expecting tag %r" %
                (cls.__name__, cls.tag), remaining=s
            )

    @classmethod
    def check_type(cls, s):
        cls.check_string(s)
        tag, remainder = BER_id_dec(s)
        if not isinstance(tag, int) or cls.tag != tag:
            raise BER_BadTag_Decoding_Error(
                "%s: Got tag [%i/%#x] while expecting %r" %
                (cls.__name__, tag, tag, cls.tag), remaining=s
            )
        return remainder

    @classmethod
    def check_type_get_len(cls, s):
        s2 = cls.check_type(s)
        if not s2:
            raise BER_Decoding_Error("%s: No bytes while expecting a length" %
                                     cls.__name__, remaining=s)
        return BER_len_dec(s2)

    @classmethod
    def check_type_check_len(cls, s):
        l, s3 = cls.check_type_get_len(s)
        if len(s3) < l:
            raise BER_Decoding_Error("%s: Got %i bytes while expecting %i" %
                                     (cls.__name__, len(s3), l), remaining=s)
        return l, s3[:l], s3[l:]

    @classmethod
    def do_dec(cls, s, context=None, safe=False):
        if context is None:
            context = cls.tag.context
        cls.check_string(s)
        p, remainder = BER_id_dec(s)
        if p not in context:
            t = s
            if len(t) > 18:
                t = t[:15] + b"..."
            raise BER_Decoding_Error("Unknown prefix [%02x] for [%r]" %
                                     (p, t), remaining=s)
        codec = context[p].get_codec(ASN1_Codecs.BER)
        if codec == BERcodec_Object:
            # Value type defined as Unknown
            l, s = BER_num_dec(remainder)
            return ASN1_BADTAG(s[:l]), s[l:]
        return codec.dec(s, context, safe)

    @classmethod
    def dec(cls, s, context=None, safe=False):
        if not safe:
            return cls.do_dec(s, context, safe)
        try:
            return cls.do_dec(s, context, safe)
        except BER_BadTag_Decoding_Error as e:
            o, remain = BERcodec_Object.dec(e.remaining, context, safe)
            return ASN1_BADTAG(o), remain
        except BER_Decoding_Error as e:
            return ASN1_DECODING_ERROR(s, exc=e), ""
        except ASN1_Error as e:
            return ASN1_DECODING_ERROR(s, exc=e), ""

    @classmethod
    def safedec(cls, s, context=None):
        return cls.dec(s, context, safe=True)

    @classmethod
    def enc(cls, s):
        if isinstance(s, six.string_types + (bytes,)):
            return BERcodec_STRING.enc(s)
        else:
            return BERcodec_INTEGER.enc(int(s))
예제 #7
0
파일: asn1.py 프로젝트: icehawk1/scapy
class ASN1_Class(six.with_metaclass(ASN1_Class_metaclass)):
    pass
예제 #8
0
class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)):
    desc = None
    closed = 0
    nonblocking_socket = False
    read_allowed_exceptions = ()

    def __init__(self,
                 family=socket.AF_INET,
                 type=socket.SOCK_STREAM,
                 proto=0):  # noqa: E501
        self.ins = socket.socket(family, type, proto)
        self.outs = self.ins
        self.promisc = None

    def send(self, x):
        sx = raw(x)
        try:
            x.sent_time = time.time()
        except AttributeError:
            pass
        return self.outs.send(sx)

    if six.PY2:

        def _recv_raw(self, sock, x):
            """Internal function to receive a Packet"""
            pkt, sa_ll = sock.recvfrom(x)
            return pkt, sa_ll, None
    else:

        def _recv_raw(self, sock, x):
            """Internal function to receive a Packet,
            and process ancillary data.
            """
            flags_len = socket.CMSG_LEN(4096)
            timestamp = None
            pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
            if not pkt:
                return pkt, sa_ll
            for cmsg_lvl, cmsg_type, cmsg_data in ancdata:
                # Check available ancillary data
                if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA):
                    # Parse AUXDATA
                    auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data)
                    if auxdata.tp_vlan_tci != 0 or \
                            auxdata.tp_status & TP_STATUS_VLAN_VALID:
                        # Insert VLAN tag
                        tag = struct.pack("!HH", ETH_P_8021Q,
                                          auxdata.tp_vlan_tci)
                        pkt = pkt[:12] + tag + pkt[12:]
                elif cmsg_lvl == socket.SOL_SOCKET and \
                        cmsg_type == SO_TIMESTAMPNS:
                    length = len(cmsg_data)
                    if length == 16:  # __kernel_timespec
                        tmp = struct.unpack("ll", cmsg_data)
                    elif length == 8:  # timespec
                        tmp = struct.unpack("ii", cmsg_data)
                    else:
                        log_runtime.warning("Unknown timespec format.. ?!")
                        continue
                    timestamp = tmp[0] + tmp[1] * 1e-9
            return pkt, sa_ll, timestamp

    def recv_raw(self, x=MTU):
        """Returns a tuple containing (cls, pkt_data, time)"""
        return conf.raw_layer, self.ins.recv(x), None

    def recv(self, x=MTU):
        cls, val, ts = self.recv_raw(x)
        if not val or not cls:
            return
        try:
            pkt = cls(val)
        except KeyboardInterrupt:
            raise
        except Exception:
            if conf.debug_dissector:
                from scapy.sendrecv import debug
                debug.crashed_on = (cls, val)
                raise
            pkt = conf.raw_layer(val)
        if ts:
            pkt.time = ts
        return pkt

    def fileno(self):
        return self.ins.fileno()

    def close(self):
        if self.closed:
            return
        self.closed = True
        if getattr(self, "outs", None):
            if getattr(self, "ins", None) != self.outs:
                if WINDOWS or self.outs.fileno() != -1:
                    self.outs.close()
        if getattr(self, "ins", None):
            if WINDOWS or self.ins.fileno() != -1:
                self.ins.close()

    def sr(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sndrcv(self, *args, **kargs)

    def sr1(self, *args, **kargs):
        from scapy import sendrecv
        a, b = sendrecv.sndrcv(self, *args, **kargs)
        if len(a) > 0:
            return a[0][1]
        else:
            return None

    def sniff(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sniff(opened_socket=self, *args, **kargs)

    def tshark(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.tshark(opened_socket=self, *args, **kargs)

    @staticmethod
    def select(sockets, remain=conf.recv_poll_rate):
        """This function is called during sendrecv() routine to select
        the available sockets.

        :param sockets: an array of sockets that need to be selected
        :returns: an array of sockets that were selected and
            the function to be called next to get the packets (i.g. recv)
        """
        try:
            inp, _, _ = select(sockets, [], [], remain)
        except (IOError, select_error) as exc:
            # select.error has no .errno attribute
            if exc.args[0] != errno.EINTR:
                raise
        return inp, None

    def __del__(self):
        """Close the socket"""
        self.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """Close the socket"""
        self.close()
예제 #9
0
class Automaton(six.with_metaclass(Automaton_metaclass)):
    def parse_args(self, debug=0, store=1, **kargs):
        self.debug_level = debug
        self.socket_kargs = kargs
        self.store_packets = store

    def master_filter(self, pkt):
        return True

    def my_send(self, pkt):
        self.send_sock.send(pkt)

    ## Utility classes and exceptions
    class _IO_fdwrapper(SelectableObject):
        def __init__(self, rd, wr):
            if WINDOWS:
                # rd will be used for reading and sending
                if isinstance(rd, ObjectPipe):
                    self.rd = rd
                else:
                    raise OSError(
                        "On windows, only instances of ObjectPipe are externally available"
                    )
            else:
                if rd is not None and not isinstance(rd, int):
                    rd = rd.fileno()
                if wr is not None and not isinstance(wr, int):
                    wr = wr.fileno()
                self.rd = rd
                self.wr = wr

        def fileno(self):
            return self.rd

        def check_recv(self):
            return self.rd.check_recv()

        def read(self, n=65535):
            if WINDOWS:
                return self.rd.recv(n)
            return os.read(self.rd, n)

        def write(self, msg):
            if WINDOWS:
                self.rd.send(msg)
                return self.call_release()
            return os.write(self.wr, msg)

        def recv(self, n=65535):
            return self.read(n)

        def send(self, msg):
            return self.write(msg)

    class _IO_mixer(SelectableObject):
        def __init__(self, rd, wr):
            self.rd = rd
            self.wr = wr

        def fileno(self):
            if isinstance(self.rd, int):
                return self.rd
            return self.rd.fileno()

        def check_recv(self):
            return self.rd.check_recv()

        def recv(self, n=None):
            return self.rd.recv(n)

        def read(self, n=None):
            return self.recv(n)

        def send(self, msg):
            self.wr.send(msg)
            return self.call_release()

        def write(self, msg):
            return self.send(msg)

    class AutomatonException(Exception):
        def __init__(self, msg, state=None, result=None):
            Exception.__init__(self, msg)
            self.state = state
            self.result = result

    class AutomatonError(AutomatonException):
        pass

    class ErrorState(AutomatonException):
        pass

    class Stuck(AutomatonException):
        pass

    class AutomatonStopped(AutomatonException):
        pass

    class Breakpoint(AutomatonStopped):
        pass

    class Singlestep(AutomatonStopped):
        pass

    class InterceptionPoint(AutomatonStopped):
        def __init__(self, msg, state=None, result=None, packet=None):
            Automaton.AutomatonStopped.__init__(self,
                                                msg,
                                                state=state,
                                                result=result)
            self.packet = packet

    class CommandMessage(AutomatonException):
        pass

    ## Services
    def debug(self, lvl, msg):
        if self.debug_level >= lvl:
            log_interactive.debug(msg)

    def send(self, pkt):
        if self.state.state in self.interception_points:
            self.debug(3, "INTERCEPT: packet intercepted: %s" % pkt.summary())
            self.intercepted_packet = pkt
            cmd = Message(type=_ATMT_Command.INTERCEPT,
                          state=self.state,
                          pkt=pkt)
            self.cmdout.send(cmd)
            cmd = self.cmdin.recv()
            self.intercepted_packet = None
            if cmd.type == _ATMT_Command.REJECT:
                self.debug(3, "INTERCEPT: packet rejected")
                return
            elif cmd.type == _ATMT_Command.REPLACE:
                pkt = cmd.pkt
                self.debug(3,
                           "INTERCEPT: packet replaced by: %s" % pkt.summary())
            elif cmd.type == _ATMT_Command.ACCEPT:
                self.debug(3, "INTERCEPT: packet accepted")
            else:
                raise self.AutomatonError("INTERCEPT: unkown verdict: %r" %
                                          cmd.type)
        self.my_send(pkt)
        self.debug(3, "SENT : %s" % pkt.summary())

        if self.store_packets:
            self.packets.append(pkt.copy())

    ## Internals
    def __init__(self, *args, **kargs):
        external_fd = kargs.pop("external_fd", {})
        self.send_sock_class = kargs.pop("ll", conf.L3socket)
        self.recv_sock_class = kargs.pop("recvsock", conf.L2listen)
        self.started = threading.Lock()
        self.threadid = None
        self.breakpointed = None
        self.breakpoints = set()
        self.interception_points = set()
        self.intercepted_packet = None
        self.debug_level = 0
        self.init_args = args
        self.init_kargs = kargs
        self.io = type.__new__(type, "IOnamespace", (), {})
        self.oi = type.__new__(type, "IOnamespace", (), {})
        self.cmdin = ObjectPipe()
        self.cmdout = ObjectPipe()
        self.ioin = {}
        self.ioout = {}
        for n in self.ionames:
            extfd = external_fd.get(n)
            if not isinstance(extfd, tuple):
                extfd = (extfd, extfd)
            elif WINDOWS:
                raise OSError(
                    "Tuples are not allowed as external_fd on windows")
            ioin, ioout = extfd
            if ioin is None:
                ioin = ObjectPipe()
            elif not isinstance(ioin, types.InstanceType):
                ioin = self._IO_fdwrapper(ioin, None)
            if ioout is None:
                ioout = ioin if WINDOWS else ObjectPipe()
            elif not isinstance(ioout, types.InstanceType):
                ioout = self._IO_fdwrapper(None, ioout)

            self.ioin[n] = ioin
            self.ioout[n] = ioout
            ioin.ioname = n
            ioout.ioname = n
            setattr(self.io, n, self._IO_mixer(ioout, ioin))
            setattr(self.oi, n, self._IO_mixer(ioin, ioout))

        for stname in self.states:
            setattr(self, stname, _instance_state(getattr(self, stname)))

        self.parse_args(*args, **kargs)

        self.start()

    def __iter__(self):
        return self

    def __del__(self):
        self.stop()

    def _run_condition(self, cond, *args, **kargs):
        try:
            self.debug(5,
                       "Trying %s [%s]" % (cond.atmt_type, cond.atmt_condname))
            cond(self, *args, **kargs)
        except ATMT.NewStateRequested as state_req:
            self.debug(
                2, "%s [%s] taken to state [%s]" %
                (cond.atmt_type, cond.atmt_condname, state_req.state))
            if cond.atmt_type == ATMT.RECV:
                if self.store_packets:
                    self.packets.append(args[0])
            for action in self.actions[cond.atmt_condname]:
                self.debug(2, "   + Running action [%s]" % action.__name__)
                action(self, *state_req.action_args, **state_req.action_kargs)
            raise
        except Exception as e:
            self.debug(
                2, "%s [%s] raised exception [%s]" %
                (cond.atmt_type, cond.atmt_condname, e))
            raise
        else:
            self.debug(
                2, "%s [%s] not taken" % (cond.atmt_type, cond.atmt_condname))

    def _do_start(self, *args, **kargs):
        ready = threading.Event()
        threading.Thread(target=self._do_control,
                         args=(ready, ) + (args),
                         kwargs=kargs).start()
        ready.wait()

    def _do_control(self, ready, *args, **kargs):
        with self.started:
            self.threadid = threading.currentThread().ident

            # Update default parameters
            a = args + self.init_args[len(args):]
            k = self.init_kargs.copy()
            k.update(kargs)
            self.parse_args(*a, **k)

            # Start the automaton
            self.state = self.initial_states[0](self)
            self.send_sock = self.send_sock_class()
            self.listen_sock = self.recv_sock_class(**self.socket_kargs)
            self.packets = PacketList(name="session[%s]" %
                                      self.__class__.__name__)

            singlestep = True
            iterator = self._do_iter()
            self.debug(3, "Starting control thread [tid=%i]" % self.threadid)
            # Sync threads
            ready.set()
            try:
                while True:
                    c = self.cmdin.recv()
                    self.debug(5, "Received command %s" % c.type)
                    if c.type == _ATMT_Command.RUN:
                        singlestep = False
                    elif c.type == _ATMT_Command.NEXT:
                        singlestep = True
                    elif c.type == _ATMT_Command.FREEZE:
                        continue
                    elif c.type == _ATMT_Command.STOP:
                        break
                    while True:
                        state = next(iterator)
                        if isinstance(state, self.CommandMessage):
                            break
                        elif isinstance(state, self.Breakpoint):
                            c = Message(type=_ATMT_Command.BREAKPOINT,
                                        state=state)
                            self.cmdout.send(c)
                            break
                        if singlestep:
                            c = Message(type=_ATMT_Command.SINGLESTEP,
                                        state=state)
                            self.cmdout.send(c)
                            break
            except StopIteration as e:
                c = Message(type=_ATMT_Command.END, result=e.args[0])
                self.cmdout.send(c)
            except Exception as e:
                exc_info = sys.exc_info()
                self.debug(
                    3, "Transfering exception from tid=%i:\n%s" %
                    (self.threadid, traceback.format_exc(exc_info)))
                m = Message(type=_ATMT_Command.EXCEPTION,
                            exception=e,
                            exc_info=exc_info)
                self.cmdout.send(m)
            self.debug(3, "Stopping control thread (tid=%i)" % self.threadid)
            self.threadid = None

    def _do_iter(self):
        while True:
            try:
                self.debug(1, "## state=[%s]" % self.state.state)

                # Entering a new state. First, call new state function
                if self.state.state in self.breakpoints and self.state.state != self.breakpointed:
                    self.breakpointed = self.state.state
                    yield self.Breakpoint("breakpoint triggered on state %s" %
                                          self.state.state,
                                          state=self.state.state)
                self.breakpointed = None
                state_output = self.state.run()
                if self.state.error:
                    raise self.ErrorState("Reached %s: [%r]" %
                                          (self.state.state, state_output),
                                          result=state_output,
                                          state=self.state.state)
                if self.state.final:
                    raise StopIteration(state_output)

                if state_output is None:
                    state_output = ()
                elif not isinstance(state_output, list):
                    state_output = state_output,

                # Then check immediate conditions
                for cond in self.conditions[self.state.state]:
                    self._run_condition(cond, *state_output)

                # If still there and no conditions left, we are stuck!
                if (len(self.recv_conditions[self.state.state]) == 0
                        and len(self.ioevents[self.state.state]) == 0
                        and len(self.timeout[self.state.state]) == 1):
                    raise self.Stuck("stuck in [%s]" % self.state.state,
                                     state=self.state.state,
                                     result=state_output)

                # Finally listen and pay attention to timeouts
                expirations = iter(self.timeout[self.state.state])
                next_timeout, timeout_func = next(expirations)
                t0 = time.time()

                fds = [self.cmdin]
                if len(self.recv_conditions[self.state.state]) > 0:
                    fds.append(self.listen_sock)
                for ioev in self.ioevents[self.state.state]:
                    fds.append(self.ioin[ioev.atmt_ioname])
                while True:
                    t = time.time() - t0
                    if next_timeout is not None:
                        if next_timeout <= t:
                            self._run_condition(timeout_func, *state_output)
                            next_timeout, timeout_func = next(expirations)
                    if next_timeout is None:
                        remain = None
                    else:
                        remain = next_timeout - t

                    self.debug(5, "Select on %r" % fds)
                    r = select_objects(fds, remain)
                    self.debug(5, "Selected %r" % r)
                    for fd in r:
                        self.debug(5, "Looking at %r" % fd)
                        if fd == self.cmdin:
                            yield self.CommandMessage(
                                "Received command message")
                        elif fd == self.listen_sock:
                            pkt = self.listen_sock.recv(MTU)
                            if pkt is not None:
                                if self.master_filter(pkt):
                                    self.debug(3, "RECVD: %s" % pkt.summary())
                                    for rcvcond in self.recv_conditions[
                                            self.state.state]:
                                        self._run_condition(
                                            rcvcond, pkt, *state_output)
                                else:
                                    self.debug(4, "FILTR: %s" % pkt.summary())
                        else:
                            self.debug(3, "IOEVENT on %s" % fd.ioname)
                            for ioevt in self.ioevents[self.state.state]:
                                if ioevt.atmt_ioname == fd.ioname:
                                    self._run_condition(
                                        ioevt, fd, *state_output)

            except ATMT.NewStateRequested as state_req:
                self.debug(
                    2, "switching from [%s] to [%s]" %
                    (self.state.state, state_req.state))
                self.state = state_req
                yield state_req

    ## Public API
    def add_interception_points(self, *ipts):
        for ipt in ipts:
            if hasattr(ipt, "atmt_state"):
                ipt = ipt.atmt_state
            self.interception_points.add(ipt)

    def remove_interception_points(self, *ipts):
        for ipt in ipts:
            if hasattr(ipt, "atmt_state"):
                ipt = ipt.atmt_state
            self.interception_points.discard(ipt)

    def add_breakpoints(self, *bps):
        for bp in bps:
            if hasattr(bp, "atmt_state"):
                bp = bp.atmt_state
            self.breakpoints.add(bp)

    def remove_breakpoints(self, *bps):
        for bp in bps:
            if hasattr(bp, "atmt_state"):
                bp = bp.atmt_state
            self.breakpoints.discard(bp)

    def start(self, *args, **kargs):
        if not self.started.locked():
            self._do_start(*args, **kargs)

    def run(self, resume=None, wait=True):
        if resume is None:
            resume = Message(type=_ATMT_Command.RUN)
        self.cmdin.send(resume)
        if wait:
            try:
                c = self.cmdout.recv()
            except KeyboardInterrupt:
                self.cmdin.send(Message(type=_ATMT_Command.FREEZE))
                return
            if c.type == _ATMT_Command.END:
                return c.result
            elif c.type == _ATMT_Command.INTERCEPT:
                raise self.InterceptionPoint("packet intercepted",
                                             state=c.state.state,
                                             packet=c.pkt)
            elif c.type == _ATMT_Command.SINGLESTEP:
                raise self.Singlestep("singlestep state=[%s]" % c.state.state,
                                      state=c.state.state)
            elif c.type == _ATMT_Command.BREAKPOINT:
                raise self.Breakpoint("breakpoint triggered on state [%s]" %
                                      c.state.state,
                                      state=c.state.state)
            elif c.type == _ATMT_Command.EXCEPTION:
                six.reraise(c.exc_info[0], c.exc_info[1], c.exc_info[2])

    def runbg(self, resume=None, wait=False):
        self.run(resume, wait)

    def next(self):
        return self.run(resume=Message(type=_ATMT_Command.NEXT))

    __next__ = next

    def stop(self):
        self.cmdin.send(Message(type=_ATMT_Command.STOP))
        with self.started:
            # Flush command pipes
            while True:
                r = select_objects([self.cmdin, self.cmdout], 0)
                if not r:
                    break
                for fd in r:
                    fd.recv()

    def restart(self, *args, **kargs):
        self.stop()
        self.start(*args, **kargs)

    def accept_packet(self, pkt=None, wait=False):
        rsm = Message()
        if pkt is None:
            rsm.type = _ATMT_Command.ACCEPT
        else:
            rsm.type = _ATMT_Command.REPLACE
            rsm.pkt = pkt
        return self.run(resume=rsm, wait=wait)

    def reject_packet(self, wait=False):
        rsm = Message(type=_ATMT_Command.REJECT)
        return self.run(resume=rsm, wait=wait)
예제 #10
0
파일: cipher_aead.py 프로젝트: qbsonn/scapy
class _AEADCipher_TLS13(six.with_metaclass(_AEADCipherMetaclass, object)):
    """
    The hasattr(self, "pc_cls") enable support for the legacy implementation
    of GCM in the cryptography library. They should not be used, and might
    eventually be removed, with cryptography v2.0. XXX
    """
    type = "aead"

    def __init__(self, key=None, fixed_iv=None, nonce_explicit=None):
        """
        'key' and 'fixed_iv' are to be provided as strings. This IV never
        changes: it is either the client_write_IV or server_write_IV.

        Note that 'nonce_explicit' is never used. It is only a safeguard for a
        call in session.py to the TLS 1.2/ChaCha20Poly1305 case (see RFC 7905).
        """
        self.ready = {"key": True, "fixed_iv": True}
        if key is None:
            self.ready["key"] = False
            key = b"\0" * self.key_len
        if fixed_iv is None:
            self.ready["fixed_iv"] = False
            fixed_iv = b"\0" * self.fixed_iv_len

        # we use super() in order to avoid any deadlock with __setattr__
        super(_AEADCipher_TLS13, self).__setattr__("key", key)
        super(_AEADCipher_TLS13, self).__setattr__("fixed_iv", fixed_iv)

        if hasattr(self, "pc_cls"):
            self._cipher = Cipher(self.pc_cls(key),
                                  self.pc_cls_mode(fixed_iv),
                                  backend=default_backend())
        else:
            self._cipher = self.cipher_cls(key)

    def __setattr__(self, name, val):
        if name == "key":
            if self._cipher is not None:
                if hasattr(self, "pc_cls"):
                    self._cipher.algorithm.key = val
                else:
                    self._cipher._key = val
            self.ready["key"] = True
        elif name == "fixed_iv":
            self.ready["fixed_iv"] = True
        super(_AEADCipher_TLS13, self).__setattr__(name, val)

    def _get_nonce(self, seq_num):
        padlen = self.fixed_iv_len - len(seq_num)
        padded_seq_num = b"\x00" * padlen + seq_num
        return strxor(padded_seq_num, self.fixed_iv)

    def auth_encrypt(self, P, A, seq_num):
        """
        Encrypt the data, and append the computed authentication code.
        TLS 1.3 does not use additional data, but we leave this option to the
        user nonetheless.

        Note that the cipher's authentication tag must be None when encrypting.
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._tag = None
            self._cipher.mode._initialization_vector = self._get_nonce(seq_num)
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if (conf.crypto_valid_advanced
                    and isinstance(self._cipher, AESCCM)):
                res = self._cipher.encrypt(self._get_nonce(seq_num),
                                           P,
                                           A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(seq_num), P, A)
        return res

    def auth_decrypt(self, A, C, seq_num):
        """
        Decrypt the data and verify the authentication code (in this order).
        Note that TLS 1.3 is not supposed to use any additional data A.
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.
        """
        C, mac = C[:-self.tag_len], C[-self.tag_len:]
        if False in six.itervalues(self.ready):
            raise CipherError(C, mac)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce(seq_num)
            self._cipher.mode._tag = mac
            decryptor = self._cipher.decryptor()
            decryptor.authenticate_additional_data(A)
            P = decryptor.update(C)
            try:
                decryptor.finalize()
            except InvalidTag:
                raise AEADTagError(P, mac)
        else:
            try:
                if (conf.crypto_valid_advanced
                        and isinstance(self._cipher, AESCCM)):
                    P = self._cipher.decrypt(self._get_nonce(seq_num),
                                             C + mac,
                                             A,
                                             tag_length=self.tag_len)
                else:
                    if (conf.crypto_valid_advanced
                            and isinstance(self, Cipher_CHACHA20_POLY1305)):
                        A += struct.pack("!H", len(C))
                    P = self._cipher.decrypt(self._get_nonce(seq_num), C + mac,
                                             A)
            except InvalidTag:
                raise AEADTagError("<unauthenticated data>", mac)
        return P, mac

    def snapshot(self):
        c = self.__class__(self.key, self.fixed_iv)
        c.ready = self.ready.copy()
        return c
예제 #11
0
class _StreamCipher(six.with_metaclass(_StreamCipherMetaclass, object)):
    type = "stream"

    def __init__(self, key=None):
        """
        Note that we have to keep the encryption/decryption state in unique
        encryptor and decryptor objects. This differs from _BlockCipher.

        In order to do connection state snapshots, we need to be able to
        recreate past cipher contexts. This is why we feed _enc_updated_with
        and _dec_updated_with every time encrypt() or decrypt() is called.
        """
        self.ready = {"key": True}
        if key is None:
            self.ready["key"] = False
            if hasattr(self, "expanded_key_len"):
                l = self.expanded_key_len
            else:
                l = self.key_len
            key = b"\0" * l

        # we use super() in order to avoid any deadlock with __setattr__
        super(_StreamCipher, self).__setattr__("key", key)

        self._cipher = Cipher(self.pc_cls(key),
                              mode=None,
                              backend=default_backend())
        self.encryptor = self._cipher.encryptor()
        self.decryptor = self._cipher.decryptor()
        self._enc_updated_with = b""
        self._dec_updated_with = b""

    def __setattr__(self, name, val):
        """
        We have to keep the encryptor/decryptor for a long time,
        however they have to be updated every time the key is changed.
        """
        if name == "key":
            if self._cipher is not None:
                self._cipher.algorithm.key = val
                self.encryptor = self._cipher.encryptor()
                self.decryptor = self._cipher.decryptor()
            self.ready["key"] = True
        super(_StreamCipher, self).__setattr__(name, val)


    def encrypt(self, data):
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        self._enc_updated_with += data
        return self.encryptor.update(data)

    def decrypt(self, data):
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        self._dec_updated_with += data
        return self.decryptor.update(data)

    def snapshot(self):
        c = self.__class__(self.key)
        c.ready = self.ready.copy()
        c.encryptor.update(self._enc_updated_with)
        c.decryptor.update(self._dec_updated_with)
        c._enc_updated_with = self._enc_updated_with
        c._dec_updated_with = self._dec_updated_with
        return c
예제 #12
0
class _BlockCipher(six.with_metaclass(_BlockCipherMetaclass, object)):
    type = "block"

    def __init__(self, key=None, iv=None):
        self.ready = {"key": True, "iv": True}
        if key is None:
            self.ready["key"] = False
            if hasattr(self, "expanded_key_len"):
                l = self.expanded_key_len
            else:
                l = self.key_len
            key = b"\0" * l
        if iv is None or iv == "":
            self.ready["iv"] = False
            iv = b"\0" * self.block_size

        # we use super() in order to avoid any deadlock with __setattr__
        super(_BlockCipher, self).__setattr__("key", key)
        super(_BlockCipher, self).__setattr__("iv", iv)

        self._cipher = Cipher(self.pc_cls(key),
                              self.pc_cls_mode(iv),
                              backend=backend)

    def __setattr__(self, name, val):
        if name == "key":
            if self._cipher is not None:
                self._cipher.algorithm.key = val
            self.ready["key"] = True
        elif name == "iv":
            if self._cipher is not None:
                self._cipher.mode._initialization_vector = val
            self.ready["iv"] = True
        super(_BlockCipher, self).__setattr__(name, val)

    def encrypt(self, data):
        """
        Encrypt the data. Also, update the cipher iv. This is needed for SSLv3
        and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.post_build().
        """
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        encryptor = self._cipher.encryptor()
        tmp = encryptor.update(data) + encryptor.finalize()
        self.iv = tmp[-self.block_size:]
        return tmp

    def decrypt(self, data):
        """
        Decrypt the data. Also, update the cipher iv. This is needed for SSLv3
        and TLS 1.0. For TLS 1.1/1.2, it is overwritten in TLS.pre_dissect().
        If we lack the key, we raise a CipherError which contains the input.
        """
        if False in six.itervalues(self.ready):
            raise CipherError(data)
        decryptor = self._cipher.decryptor()
        tmp = decryptor.update(data) + decryptor.finalize()
        self.iv = data[-self.block_size:]
        return tmp

    def snapshot(self):
        c = self.__class__(self.key, self.iv)
        c.ready = self.ready.copy()
        return c
예제 #13
0
파일: compression.py 프로젝트: zanssa/scapy
class _GenericComp(six.with_metaclass(_GenericCompMetaclass, object)):
    pass
예제 #14
0
class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)):
    desc = None
    closed = 0

    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):  # noqa: E501
        self.ins = socket.socket(family, type, proto)
        self.outs = self.ins
        self.promisc = None

    def send(self, x):
        sx = raw(x)
        if hasattr(x, "sent_time"):
            x.sent_time = time.time()
        return self.outs.send(sx)

    def recv_raw(self, x=MTU):
        """Returns a tuple containing (cls, pkt_data, time)"""
        return conf.raw_layer, self.ins.recv(x), None

    def recv(self, x=MTU):
        cls, val, ts = self.recv_raw(x)
        if not val or not cls:
            return
        try:
            pkt = cls(val)
        except KeyboardInterrupt:
            raise
        except Exception:
            if conf.debug_dissector:
                raise
            pkt = conf.raw_layer(val)
        pkt.time = ts
        return pkt

    def fileno(self):
        return self.ins.fileno()

    def close(self):
        if self.closed:
            return
        self.closed = True
        if hasattr(self, "outs"):
            if not hasattr(self, "ins") or self.ins != self.outs:
                if self.outs and self.outs.fileno() != -1:
                    self.outs.close()
        if hasattr(self, "ins"):
            if self.ins and self.ins.fileno() != -1:
                self.ins.close()

    def sr(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sndrcv(self, *args, **kargs)

    def sr1(self, *args, **kargs):
        from scapy import sendrecv
        a, b = sendrecv.sndrcv(self, *args, **kargs)
        if len(a) > 0:
            return a[0][1]
        else:
            return None

    def sniff(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sniff(opened_socket=self, *args, **kargs)
예제 #15
0
class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)):
    desc = None
    closed = 0
    nonblocking_socket = False
    read_allowed_exceptions = ()
    auxdata_available = False

    def __init__(self, family=socket.AF_INET, type=socket.SOCK_STREAM, proto=0):  # noqa: E501
        self.ins = socket.socket(family, type, proto)
        self.outs = self.ins
        self.promisc = None

    def send(self, x):
        sx = raw(x)
        try:
            x.sent_time = time.time()
        except AttributeError:
            pass
        return self.outs.send(sx)

    if six.PY2:
        def _recv_raw(self, sock, x):
            """Internal function to receive a Packet"""
            pkt, sa_ll = sock.recvfrom(x)
            return pkt, sa_ll, None
    else:
        def _recv_raw(self, sock, x):
            """Internal function to receive a Packet,
            and process ancillary data.
            """
            timestamp = None
            if not self.auxdata_available:
                pkt, _, _, sa_ll = sock.recvmsg(x)
                return pkt, sa_ll, timestamp
            flags_len = socket.CMSG_LEN(4096)
            pkt, ancdata, flags, sa_ll = sock.recvmsg(x, flags_len)
            if not pkt:
                return pkt, sa_ll, timestamp
            for cmsg_lvl, cmsg_type, cmsg_data in ancdata:
                # Check available ancillary data
                if (cmsg_lvl == SOL_PACKET and cmsg_type == PACKET_AUXDATA):
                    # Parse AUXDATA
                    try:
                        auxdata = tpacket_auxdata.from_buffer_copy(cmsg_data)
                    except ValueError:
                        # Note: according to Python documentation, recvmsg()
                        #       can return a truncated message. A ValueError
                        #       exception likely indicates that Auxiliary
                        #       Data is not supported by the Linux kernel.
                        return pkt, sa_ll, timestamp
                    if auxdata.tp_vlan_tci != 0 or \
                            auxdata.tp_status & TP_STATUS_VLAN_VALID:
                        # Insert VLAN tag
                        tag = struct.pack(
                            "!HH",
                            ETH_P_8021Q,
                            auxdata.tp_vlan_tci
                        )
                        pkt = pkt[:12] + tag + pkt[12:]
                elif cmsg_lvl == socket.SOL_SOCKET and \
                        cmsg_type == SO_TIMESTAMPNS:
                    length = len(cmsg_data)
                    if length == 16:  # __kernel_timespec
                        tmp = struct.unpack("ll", cmsg_data)
                    elif length == 8:  # timespec
                        tmp = struct.unpack("ii", cmsg_data)
                    else:
                        log_runtime.warning("Unknown timespec format.. ?!")
                        continue
                    timestamp = tmp[0] + tmp[1] * 1e-9
            return pkt, sa_ll, timestamp

    def recv_raw(self, x=MTU):
        """Returns a tuple containing (cls, pkt_data, time)"""
        return conf.raw_layer, self.ins.recv(x), None

    def recv(self, x=MTU):
        cls, val, ts = self.recv_raw(x)
        if not val or not cls:
            return
        try:
            pkt = cls(val)
        except KeyboardInterrupt:
            raise
        except Exception:
            if conf.debug_dissector:
                from scapy.sendrecv import debug
                debug.crashed_on = (cls, val)
                raise
            pkt = conf.raw_layer(val)
        if ts:
            pkt.time = ts
        return pkt

    def fileno(self):
        return self.ins.fileno()

    def close(self):
        if self.closed:
            return
        self.closed = True
        if getattr(self, "outs", None):
            if getattr(self, "ins", None) != self.outs:
                if WINDOWS or self.outs.fileno() != -1:
                    self.outs.close()
        if getattr(self, "ins", None):
            if WINDOWS or self.ins.fileno() != -1:
                self.ins.close()

    def sr(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sndrcv(self, *args, **kargs)

    def sr1(self, *args, **kargs):
        from scapy import sendrecv
        a, b = sendrecv.sndrcv(self, *args, **kargs)
        if len(a) > 0:
            return a[0][1]
        else:
            return None

    def sniff(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sniff(opened_socket=self, *args, **kargs)

    def tshark(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.tshark(opened_socket=self, *args, **kargs)

    def _command(self, ctor_params):
        """Internal helper function for implementing the command() method.

        :param ctor_params: a dict with all parameters passed to the
            constructor of the class, where a key is the name of the
            parameter in the constructor and the value is its value
        """

        nv = []
        for name, value in six.iteritems(ctor_params):
            if value is None:
                continue
            elif hasattr(value, "__iter__"):
                try:
                    empty = len(value) == 0
                except TypeError:
                    empty = False
                if empty:
                    continue

            if name == "basecls":
                value = (
                    value.__name__
                    if hasattr(value, "__name__")
                    else value.__class__.__name__
                )
            elif hasattr(value, "command"):
                value = value.command()
            else:
                value = repr(value)
            nv.append("%s=%s" % (name, value))

        return "%s(%s)" % (type(self).__name__, ", ".join(nv))

    def command(self):
        """Returns a string representing the command you have to type to
        obtain the same socket.
        """
        raise NotImplementedError()

    @staticmethod
    def select(sockets, remain=conf.recv_poll_rate):
        """This function is called during sendrecv() routine to select
        the available sockets.

        :param sockets: an array of sockets that need to be selected
        :returns: an array of sockets that were selected and
            the function to be called next to get the packets (i.g. recv)
        """
        try:
            inp, _, _ = select(sockets, [], [], remain)
        except (IOError, select_error) as exc:
            # select.error has no .errno attribute
            if not exc.args or exc.args[0] != errno.EINTR:
                raise
        return inp, None

    def __del__(self):
        """Close the socket"""
        self.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """Close the socket"""
        self.close()
class AnsweringMachine(six.with_metaclass(ReferenceAM, object)):
    function_name = ""
    filter = None
    sniff_options = {"store": 0}
    sniff_options_list = [
        "store", "iface", "count", "promisc", "filter", "type", "prn",
        "stop_filter"
    ]
    send_options = {"verbose": 0}
    send_options_list = ["iface", "inter", "loop", "verbose"]
    send_function = staticmethod(send)

    def __init__(self, **kargs):
        self.mode = 0
        if self.filter:
            kargs.setdefault("filter", self.filter)
        kargs.setdefault("prn", self.reply)
        self.optam1 = {}
        self.optam2 = {}
        self.optam0 = {}
        doptsend, doptsniff = self.parse_all_options(1, kargs)
        self.defoptsend = self.send_options.copy()
        self.defoptsend.update(doptsend)
        self.defoptsniff = self.sniff_options.copy()
        self.defoptsniff.update(doptsniff)
        self.optsend, self.optsniff = [{}, {}]

    def __getattr__(self, attr):
        for d in [self.optam2, self.optam1]:
            if attr in d:
                return d[attr]
        raise AttributeError(attr)

    def __setattr__(self, attr, val):
        mode = self.__dict__.get("mode", 0)
        if mode == 0:
            self.__dict__[attr] = val
        else:
            [self.optam1, self.optam2][mode - 1][attr] = val

    def parse_options(self):
        pass

    def parse_all_options(self, mode, kargs):
        sniffopt = {}
        sendopt = {}
        for k in list(kargs):  # use list(): kargs is modified in the loop
            if k in self.sniff_options_list:
                sniffopt[k] = kargs[k]
            if k in self.send_options_list:
                sendopt[k] = kargs[k]
            if k in self.sniff_options_list + self.send_options_list:
                del kargs[k]
        if mode != 2 or kargs:
            if mode == 1:
                self.optam0 = kargs
            elif mode == 2 and kargs:
                k = self.optam0.copy()
                k.update(kargs)
                self.parse_options(**k)
                kargs = k
            omode = self.__dict__.get("mode", 0)
            self.__dict__["mode"] = mode
            self.parse_options(**kargs)
            self.__dict__["mode"] = omode
        return sendopt, sniffopt

    def is_request(self, req):
        return 1

    def make_reply(self, req):
        return req

    def send_reply(self, reply):
        self.send_function(reply, **self.optsend)

    def print_reply(self, req, reply):
        print("%s ==> %s" % (req.summary(), reply.summary()))

    def reply(self, pkt):
        if not self.is_request(pkt):
            return
        reply = self.make_reply(pkt)
        self.send_reply(reply)
        if conf.verb >= 0:
            self.print_reply(pkt, reply)

    def run(self, *args, **kargs):
        log_interactive.warning(
            "run() method deprecated. The instance is now callable")
        self(*args, **kargs)

    def __call__(self, *args, **kargs):
        optsend, optsniff = self.parse_all_options(2, kargs)
        self.optsend = self.defoptsend.copy()
        self.optsend.update(optsend)
        self.optsniff = self.defoptsniff.copy()
        self.optsniff.update(optsniff)

        try:
            self.sniff()
        except KeyboardInterrupt:
            print("Interrupted by user")

    def sniff(self):
        sniff(**self.optsniff)
예제 #17
0
class Pipe(six.with_metaclass(_PipeMeta, _ConnectorLogic)):
    def __init__(self, name=None):
        _ConnectorLogic.__init__(self)
        if name is None:
            name = "%s" % (self.__class__.__name__)
        self.name = name

    def _send(self, msg):
        for s in self.sinks:
            s.push(msg)

    def _high_send(self, msg):
        for s in self.high_sinks:
            s.high_push(msg)

    def _trigger(self, msg=None):
        for s in self.trigger_sinks:
            s.on_trigger(msg)

    def __repr__(self):
        ct = conf.color_theme
        s = "%s%s" % (ct.punct("<"), ct.layer_name(self.name))
        if self.sources or self.sinks:
            s += " %s" % ct.punct("[")
            if self.sources:
                s += "%s%s" % (
                    ct.punct(",").join(
                        ct.field_name(s.name)
                        for s in self.sources),  # noqa: E501
                    ct.field_value(">"))
            s += ct.layer_name("#")
            if self.sinks:
                s += "%s%s" % (ct.field_value(">"), ct.punct(",").join(
                    ct.field_name(s.name) for s in self.sinks))  # noqa: E501
            s += ct.punct("]")

        if self.high_sources or self.high_sinks:
            s += " %s" % ct.punct("[")
            if self.high_sources:
                s += "%s%s" % (
                    ct.punct(",").join(
                        ct.field_name(s.name)
                        for s in self.high_sources),  # noqa: E501
                    ct.field_value(">>"))
            s += ct.layer_name("#")
            if self.high_sinks:
                s += "%s%s" % (ct.field_value(">>"), ct.punct(",").join(
                    ct.field_name(s.name)
                    for s in self.high_sinks))  # noqa: E501
            s += ct.punct("]")

        if self.trigger_sources or self.trigger_sinks:
            s += " %s" % ct.punct("[")
            if self.trigger_sources:
                s += "%s%s" % (
                    ct.punct(",").join(
                        ct.field_name(s.name)
                        for s in self.trigger_sources),  # noqa: E501
                    ct.field_value("^"))
            s += ct.layer_name("#")
            if self.trigger_sinks:
                s += "%s%s" % (ct.field_value("^"), ct.punct(",").join(
                    ct.field_name(s.name)
                    for s in self.trigger_sinks))  # noqa: E501
            s += ct.punct("]")

        s += ct.punct(">")
        return s
class RawPcapReader(six.with_metaclass(PcapReader_metaclass)):
    """A stateful pcap reader. Each packet is returned as a string"""
    def __init__(self, filename, fdesc, magic):
        self.filename = filename
        self.f = fdesc
        if magic == b"\xa1\xb2\xc3\xd4": # big endian
            self.endian = ">"
            self.nano = False
        elif magic == b"\xd4\xc3\xb2\xa1": # little endian
            self.endian = "<"
            self.nano = False
        elif magic == b"\xa1\xb2\x3c\x4d":  # big endian, nanosecond-precision
            self.endian = ">"
            self.nano = True
        elif magic == b"\x4d\x3c\xb2\xa1":  # little endian, nanosecond-precision
            self.endian = "<"
            self.nano = True
        else:
            raise Scapy_Exception(
                "Not a pcap capture file (bad magic: %r)" % magic
            )
        hdr = self.f.read(20)
        if len(hdr)<20:
            raise Scapy_Exception("Invalid pcap file (too short)")
        vermaj, vermin, tz, sig, snaplen, linktype = struct.unpack(
            self.endian + "HHIIII", hdr
        )
        self.linktype = linktype

    def __iter__(self):
        return self

    def next(self):
        """implement the iterator protocol on a set of packets in a pcap file"""
        pkt = self.read_packet()
        if pkt == None:
            raise StopIteration
        return pkt
    __next__ = next


    def read_packet(self, size=MTU):
        """return a single packet read from the file
        
        returns None when no more packets are available
        """
        hdr = self.f.read(16)
        if len(hdr) < 16:
            return None
        sec,usec,caplen,wirelen = struct.unpack(self.endian+"IIII", hdr)
        s = self.f.read(caplen)[:size]
        return s,(sec,usec,wirelen) # caplen = len(s)


    def dispatch(self, callback):
        """call the specified callback routine for each packet read
        
        This is just a convenience function for the main loop
        that allows for easy launching of packet processing in a 
        thread.
        """
        for p in self:
            callback(p)

    def read_all(self,count=-1):
        """return a list of all packets in the pcap file
        """
        res=[]
        while count != 0:
            count -= 1
            p = self.read_packet()
            if p is None:
                break
            res.append(p)
        return res

    def recv(self, size=MTU):
        """ Emulate a socket
        """
        return self.read_packet(size=size)[0]

    def fileno(self):
        return self.f.fileno()

    def close(self):
        return self.f.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, tracback):
        self.close()
예제 #19
0
파일: cert.py 프로젝트: qbsonn/scapy
class Cert(six.with_metaclass(_CertMaker, object)):
    """
    Wrapper for the X509_Cert from layers/x509.py.
    Use the 'x509Cert' attribute to access original object.
    """

    def import_from_asn1pkt(self, cert):
        error_msg = "Unable to import certificate"

        self.x509Cert = cert

        tbsCert = cert.tbsCertificate
        self.tbsCertificate = tbsCert

        if tbsCert.version:
            self.version = tbsCert.version.val + 1
        else:
            self.version = 1
        self.serial = tbsCert.serialNumber.val
        self.sigAlg = tbsCert.signature.algorithm.oidname
        self.issuer = tbsCert.get_issuer()
        self.issuer_str = tbsCert.get_issuer_str()
        self.issuer_hash = hash(self.issuer_str)
        self.subject = tbsCert.get_subject()
        self.subject_str = tbsCert.get_subject_str()
        self.subject_hash = hash(self.subject_str)
        self.authorityKeyID = None

        self.notBefore_str = tbsCert.validity.not_before.pretty_time
        notBefore = tbsCert.validity.not_before.val
        if notBefore[-1] == "Z":
            notBefore = notBefore[:-1]
        try:
            self.notBefore = time.strptime(notBefore, "%y%m%d%H%M%S")
        except:
            raise Exception(error_msg)
        self.notBefore_str_simple = time.strftime("%x", self.notBefore)

        self.notAfter_str = tbsCert.validity.not_after.pretty_time
        notAfter = tbsCert.validity.not_after.val
        if notAfter[-1] == "Z":
            notAfter = notAfter[:-1]
        try:
            self.notAfter = time.strptime(notAfter, "%y%m%d%H%M%S")
        except:
            raise Exception(error_msg)
        self.notAfter_str_simple = time.strftime("%x", self.notAfter)

        self.pubKey = PubKey(raw(tbsCert.subjectPublicKeyInfo))

        if tbsCert.extensions:
            for extn in tbsCert.extensions:
                if extn.extnID.oidname == "basicConstraints":
                    self.cA = False
                    if extn.extnValue.cA:
                        self.cA = not (extn.extnValue.cA.val == 0)
                elif extn.extnID.oidname == "keyUsage":
                    self.keyUsage = extn.extnValue.get_keyUsage()
                elif extn.extnID.oidname == "extKeyUsage":
                    self.extKeyUsage = extn.extnValue.get_extendedKeyUsage()
                elif extn.extnID.oidname == "authorityKeyIdentifier":
                    self.authorityKeyID = extn.extnValue.keyIdentifier.val

        self.signatureValue = raw(cert.signatureValue)
        self.signatureLen = len(self.signatureValue)

    def isIssuerCert(self, other):
        """
        True if 'other' issued 'self', i.e.:
          - self.issuer == other.subject
          - self is signed by other
        """
        if self.issuer_hash != other.subject_hash:
            return False
        return other.pubKey.verifyCert(self)

    def isSelfSigned(self):
        """
        Return True if the certificate is self-signed:
          - issuer and subject are the same
          - the signature of the certificate is valid.
        """
        if self.issuer_hash == self.subject_hash:
            return self.isIssuerCert(self)
        return False

    def encrypt(self, msg, t="pkcs", h="sha256", mgf=None, L=None):
        # no ECDSA *encryption* support, hence only RSA specific keywords here
        return self.pubKey.encrypt(msg, t, h, mgf, L)

    def verify(self, msg, sig, t="pkcs", h="sha256", mgf=None, L=None):
        return self.pubKey.verify(msg, sig, t, h, mgf, L)

    def remainingDays(self, now=None):
        """
        Based on the value of notAfter field, returns the number of
        days the certificate will still be valid. The date used for the
        comparison is the current and local date, as returned by
        time.localtime(), except if 'now' argument is provided another
        one. 'now' argument can be given as either a time tuple or a string
        representing the date. Accepted format for the string version
        are:

         - '%b %d %H:%M:%S %Y %Z' e.g. 'Jan 30 07:38:59 2008 GMT'
         - '%m/%d/%y' e.g. '01/30/08' (less precise)

        If the certificate is no more valid at the date considered, then
        a negative value is returned representing the number of days
        since it has expired.

        The number of days is returned as a float to deal with the unlikely
        case of certificates that are still just valid.
        """
        if now is None:
            now = time.localtime()
        elif isinstance(now, str):
            try:
                if '/' in now:
                    now = time.strptime(now, '%m/%d/%y')
                else:
                    now = time.strptime(now, '%b %d %H:%M:%S %Y %Z')
            except:
                warning("Bad time string provided, will use localtime() instead.")
                now = time.localtime()

        now = time.mktime(now)
        nft = time.mktime(self.notAfter)
        diff = (nft - now)/(24.*3600)
        return diff

    def isRevoked(self, crl_list):
        """
        Given a list of trusted CRL (their signature has already been
        verified with trusted anchors), this function returns True if
        the certificate is marked as revoked by one of those CRL.

        Note that if the Certificate was on hold in a previous CRL and
        is now valid again in a new CRL and bot are in the list, it
        will be considered revoked: this is because _all_ CRLs are
        checked (not only the freshest) and revocation status is not
        handled.

        Also note that the check on the issuer is performed on the
        Authority Key Identifier if available in _both_ the CRL and the
        Cert. Otherwise, the issuers are simply compared.
        """
        for c in crl_list:
            if (self.authorityKeyID is not None and
                c.authorityKeyID is not None and
                    self.authorityKeyID == c.authorityKeyID):
                return self.serial in (x[0] for x in c.revoked_cert_serials)
            elif self.issuer == c.issuer:
                return self.serial in (x[0] for x in c.revoked_cert_serials)
        return False

    def export(self, filename, fmt="DER"):
        """
        Export certificate in 'fmt' format (DER or PEM) to file 'filename'
        """
        f = open(filename, "wb")
        if fmt == "DER":
            f.write(self.der)
        elif fmt == "PEM":
            f.write(self.pem)
        f.close()

    def show(self):
        print("Serial: %s" % self.serial)
        print("Issuer: " + self.issuer_str)
        print("Subject: " + self.subject_str)
        print("Validity: %s to %s" % (self.notBefore_str, self.notAfter_str))

    def __repr__(self):
        return "[X.509 Cert. Subject:%s, Issuer:%s]" % (self.subject_str, self.issuer_str)
예제 #20
0
파일: cipher_aead.py 프로젝트: qbsonn/scapy
class _AEADCipher(six.with_metaclass(_AEADCipherMetaclass, object)):
    """
    The hasattr(self, "pc_cls") tests correspond to the legacy API of the
    crypto library. With cryptography v2.0, both CCM and GCM should follow
    the else case.

    Note that the "fixed_iv" in TLS RFCs is called "salt" in the AEAD RFC 5116.
    """
    type = "aead"
    fixed_iv_len = 4
    nonce_explicit_len = 8

    def __init__(self, key=None, fixed_iv=None, nonce_explicit=None):
        """
        'key' and 'fixed_iv' are to be provided as strings, whereas the internal
        'nonce_explicit' is an integer (it is simpler for incrementation).
        /!\ The whole 'nonce' may be called IV in certain RFCs.
        """
        self.ready = {"key": True, "fixed_iv": True, "nonce_explicit": True}
        if key is None:
            self.ready["key"] = False
            key = b"\0" * self.key_len
        if fixed_iv is None:
            self.ready["fixed_iv"] = False
            fixed_iv = b"\0" * self.fixed_iv_len
        if nonce_explicit is None:
            self.ready["nonce_explicit"] = False
            nonce_explicit = 0

        if isinstance(nonce_explicit, str):
            nonce_explicit = pkcs_os2ip(nonce_explicit)

        # we use super() in order to avoid any deadlock with __setattr__
        super(_AEADCipher, self).__setattr__("key", key)
        super(_AEADCipher, self).__setattr__("fixed_iv", fixed_iv)
        super(_AEADCipher, self).__setattr__("nonce_explicit", nonce_explicit)

        if hasattr(self, "pc_cls"):
            self._cipher = Cipher(self.pc_cls(key),
                                  self.pc_cls_mode(self._get_nonce()),
                                  backend=default_backend())
        else:
            self._cipher = self.cipher_cls(key)

    def __setattr__(self, name, val):
        if name == "key":
            if self._cipher is not None:
                if hasattr(self, "pc_cls"):
                    self._cipher.algorithm.key = val
                else:
                    self._cipher._key = val
            self.ready["key"] = True
        elif name == "fixed_iv":
            self.ready["fixed_iv"] = True
        elif name == "nonce_explicit":
            if isinstance(val, str):
                val = pkcs_os2ip(val)
            self.ready["nonce_explicit"] = True
        super(_AEADCipher, self).__setattr__(name, val)

    def _get_nonce(self):
        return (self.fixed_iv +
                pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len))

    def _update_nonce_explicit(self):
        """
        Increment the explicit nonce while avoiding any overflow.
        """
        ne = self.nonce_explicit + 1
        self.nonce_explicit = ne % 2**(self.nonce_explicit_len * 8)

    def auth_encrypt(self, P, A, seq_num=None):
        """
        Encrypt the data then prepend the explicit part of the nonce. The
        authentication tag is directly appended with the most recent crypto
        API. Additional data may be authenticated without encryption (as A).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        if False in six.itervalues(self.ready):
            raise CipherError(P, A)

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = None
            encryptor = self._cipher.encryptor()
            encryptor.authenticate_additional_data(A)
            res = encryptor.update(P) + encryptor.finalize()
            res += encryptor.tag
        else:
            if isinstance(self._cipher, AESCCM):
                res = self._cipher.encrypt(self._get_nonce(),
                                           P,
                                           A,
                                           tag_length=self.tag_len)
            else:
                res = self._cipher.encrypt(self._get_nonce(), P, A)

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce_explicit()
        return nonce_explicit + res

    def auth_decrypt(self, A, C, seq_num=None, add_length=True):
        """
        Decrypt the data and authenticate the associated data (i.e. A).
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.

        Note that we add the TLSCiphertext length to A although we're supposed
        to add the TLSCompressed length. Fortunately, they are the same,
        but the specifications actually messed up here. :'(

        The 'add_length' switch should always be True for TLS, but we provide
        it anyway (mostly for test cases, hum).

        The 'seq_num' should never be used here, it is only a safeguard needed
        because one cipher (ChaCha20Poly1305) using TLS 1.2 logic in record.py
        actually is a _AEADCipher_TLS13 (even though others are not).
        """
        nonce_explicit_str, C, mac = (C[:self.nonce_explicit_len],
                                      C[self.nonce_explicit_len:-self.tag_len],
                                      C[-self.tag_len:])

        if False in six.itervalues(self.ready):
            raise CipherError(nonce_explicit_str, C, mac)

        self.nonce_explicit = pkcs_os2ip(nonce_explicit_str)
        if add_length:
            A += struct.pack("!H", len(C))

        if hasattr(self, "pc_cls"):
            self._cipher.mode._initialization_vector = self._get_nonce()
            self._cipher.mode._tag = mac
            decryptor = self._cipher.decryptor()
            decryptor.authenticate_additional_data(A)
            P = decryptor.update(C)
            try:
                decryptor.finalize()
            except InvalidTag:
                raise AEADTagError(nonce_explicit_str, P, mac)
        else:
            try:
                if isinstance(self._cipher, AESCCM):
                    P = self._cipher.decrypt(self._get_nonce(),
                                             C + mac,
                                             A,
                                             tag_length=self.tag_len)
                else:
                    P = self._cipher.decrypt(self._get_nonce(), C + mac, A)
            except InvalidTag:
                raise AEADTagError(nonce_explicit_str,
                                   "<unauthenticated data>", mac)
        return nonce_explicit_str, P, mac

    def snapshot(self):
        c = self.__class__(self.key, self.fixed_iv, self.nonce_explicit)
        c.ready = self.ready.copy()
        return c
예제 #21
0
class _AEADCipher(six.with_metaclass(_AEADCipherMetaclass, object)):
    type = "aead"

    def __init__(self, key=None, salt=None, nonce_explicit=None):
        """
        'key' and 'salt' are to be provided as strings, whereas the internal
        'nonce_explicit' is an integer (it is simpler for incrementation).
        """
        self.ready = {"key": True, "salt": True, "nonce_explicit": True}
        if key is None:
            self.ready["key"] = False
            key = b"\0" * self.key_len
        if salt is None:
            self.ready["salt"] = False
            salt = b"\0" * self.salt_len
        if nonce_explicit is None:
            self.ready["nonce_explicit"] = False
            nonce_explicit = 0

        if isinstance(nonce_explicit, str):
            nonce_explicit = pkcs_os2ip(nonce_explicit)

        # we use super() in order to avoid any deadlock with __setattr__
        super(_AEADCipher, self).__setattr__("key", key)
        super(_AEADCipher, self).__setattr__("salt", salt)
        super(_AEADCipher, self).__setattr__("nonce_explicit", nonce_explicit)

        iv = salt + pkcs_i2osp(nonce_explicit, self.nonce_explicit_len)
        self._cipher = Cipher(self.pc_cls(key),
                              self.pc_cls_mode(iv),
                              backend=default_backend())

    def __setattr__(self, name, val):
        if name == "key":
            if self._cipher is not None:
                self._cipher.algorithm.key = val
            self.ready["key"] = True
        elif name == "salt":
            iv = val + pkcs_i2osp(self.nonce_explicit, self.nonce_explicit_len)
            if self._cipher is not None:
                self._cipher.mode._initialization_vector = iv
            self.ready["salt"] = True
        elif name == "nonce_explicit":
            if isinstance(val, str):
                val = pkcs_os2ip(val)
            iv = self.salt + pkcs_i2osp(val, self.nonce_explicit_len)
            if self._cipher is not None:
                self._cipher.mode._initialization_vector = iv
            self.ready["nonce_explicit"] = True
        super(_AEADCipher, self).__setattr__(name, val)

    def _update_nonce(self):
        """
        Increment the explicit nonce while avoiding any overflow.
        """
        ne = self.nonce_explicit + 1
        self.nonce_explicit = ne % 2**(self.nonce_explicit_len * 8)

    def auth_encrypt(self, P, A):
        """
        Encrypt the data, prepend the explicit part of the nonce,
        and append the computed authentication code.
        Additional data may be authenticated without encryption (as A).

        Note that the cipher's authentication tag must be None when encrypting.
        """
        if False in six.itervalues(self.ready):
            raise CipherError, (P, A)
        self._cipher.mode._tag = None
        encryptor = self._cipher.encryptor()
        encryptor.authenticate_additional_data(A)
        res = encryptor.update(P) + encryptor.finalize()
        res += encryptor.tag

        nonce_explicit = pkcs_i2osp(self.nonce_explicit,
                                    self.nonce_explicit_len)
        self._update_nonce()
        return nonce_explicit + res

    def auth_decrypt(self, A, C, add_length=True):
        """
        Decrypt the data and verify the authentication code (in this order).
        When additional data was authenticated, it has to be passed (as A).
        If the verification fails, an AEADTagError is raised. It is the user's
        responsibility to catch it if deemed useful. If we lack the key, we
        raise a CipherError which contains the encrypted input.

        Note that we add the TLSCiphertext length to A although we're supposed
        to add the TLSCompressed length. Fortunately, they are the same,
        but the specifications actually messed up here. :'(

        The 'add_length' switch should always be True for TLS, but we provide
        it anyway (mostly for test cases, hum).
        """
        nonce_explicit_str, C, mac = (C[:self.nonce_explicit_len],
                                      C[self.nonce_explicit_len:-self.tag_len],
                                      C[-self.tag_len:])

        if False in six.itervalues(self.ready):
            raise CipherError, (nonce_explicit_str, C, mac)

        self.nonce_explicit = pkcs_os2ip(nonce_explicit_str)
        self._cipher.mode._tag = mac

        decryptor = self._cipher.decryptor()
        if add_length:
            A += struct.pack("!H", len(C))
        decryptor.authenticate_additional_data(A)

        P = decryptor.update(C)
        try:
            decryptor.finalize()
        except InvalidTag:
            raise AEADTagError, (nonce_explicit_str, P, mac)
        return nonce_explicit_str, P, mac
예제 #22
0
class SuperSocket(six.with_metaclass(_SuperSocket_metaclass)):
    desc = None
    closed = 0
    nonblocking_socket = False
    read_allowed_exceptions = ()

    def __init__(self,
                 family=socket.AF_INET,
                 type=socket.SOCK_STREAM,
                 proto=0):  # noqa: E501
        self.ins = socket.socket(family, type, proto)
        self.outs = self.ins
        self.promisc = None

    def send(self, x):
        sx = raw(x)
        try:
            x.sent_time = time.time()
        except AttributeError:
            pass
        return self.outs.send(sx)

    def recv_raw(self, x=MTU):
        """Returns a tuple containing (cls, pkt_data, time)"""
        return conf.raw_layer, self.ins.recv(x), None

    def recv(self, x=MTU):
        cls, val, ts = self.recv_raw(x)
        if not val or not cls:
            return
        try:
            pkt = cls(val)
        except KeyboardInterrupt:
            raise
        except Exception:
            if conf.debug_dissector:
                from scapy.sendrecv import debug
                debug.crashed_on = (cls, val)
                raise
            pkt = conf.raw_layer(val)
        if ts:
            pkt.time = ts
        return pkt

    def fileno(self):
        return self.ins.fileno()

    def close(self):
        if self.closed:
            return
        self.closed = True
        if getattr(self, "outs", None):
            if getattr(self, "ins", None) != self.outs:
                if WINDOWS or self.outs.fileno() != -1:
                    self.outs.close()
        if getattr(self, "ins", None):
            if WINDOWS or self.ins.fileno() != -1:
                self.ins.close()

    def sr(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sndrcv(self, *args, **kargs)

    def sr1(self, *args, **kargs):
        from scapy import sendrecv
        a, b = sendrecv.sndrcv(self, *args, **kargs)
        if len(a) > 0:
            return a[0][1]
        else:
            return None

    def sniff(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.sniff(opened_socket=self, *args, **kargs)

    def tshark(self, *args, **kargs):
        from scapy import sendrecv
        return sendrecv.tshark(opened_socket=self, *args, **kargs)

    @staticmethod
    def select(sockets, remain=conf.recv_poll_rate):
        """This function is called during sendrecv() routine to select
        the available sockets.

        :param sockets: an array of sockets that need to be selected
        :returns: an array of sockets that were selected and
            the function to be called next to get the packets (i.g. recv)
        """
        try:
            inp, _, _ = select(sockets, [], [], remain)
        except (IOError, select_error) as exc:
            # select.error has no .errno attribute
            if exc.args[0] != errno.EINTR:
                raise
        return inp, None

    def __del__(self):
        """Close the socket"""
        self.close()

    def __enter__(self):
        return self

    def __exit__(self, exc_type, exc_value, traceback):
        """Close the socket"""
        self.close()
예제 #23
0
class _GenericHash(six.with_metaclass(_GenericHashMetaclass, object)):
    def digest(self, tbd):
        return self.hash_cls(tbd).digest()
예제 #24
0
파일: cert.py 프로젝트: qbsonn/scapy
class CRL(six.with_metaclass(_CRLMaker, object)):
    """
    Wrapper for the X509_CRL from layers/x509.py.
    Use the 'x509CRL' attribute to access original object.
    """

    def import_from_asn1pkt(self, crl):
        error_msg = "Unable to import CRL"

        self.x509CRL = crl

        tbsCertList = crl.tbsCertList
        self.tbsCertList = raw(tbsCertList)

        if tbsCertList.version:
            self.version = tbsCertList.version.val + 1
        else:
            self.version = 1
        self.sigAlg = tbsCertList.signature.algorithm.oidname
        self.issuer = tbsCertList.get_issuer()
        self.issuer_str = tbsCertList.get_issuer_str()
        self.issuer_hash = hash(self.issuer_str)

        self.lastUpdate_str = tbsCertList.this_update.pretty_time
        lastUpdate = tbsCertList.this_update.val
        if lastUpdate[-1] == "Z":
            lastUpdate = lastUpdate[:-1]
        try:
            self.lastUpdate = time.strptime(lastUpdate, "%y%m%d%H%M%S")
        except:
            raise Exception(error_msg)
        self.lastUpdate_str_simple = time.strftime("%x", self.lastUpdate)

        self.nextUpdate = None
        self.nextUpdate_str_simple = None
        if tbsCertList.next_update:
            self.nextUpdate_str = tbsCertList.next_update.pretty_time
            nextUpdate = tbsCertList.next_update.val
            if nextUpdate[-1] == "Z":
                nextUpdate = nextUpdate[:-1]
            try:
                self.nextUpdate = time.strptime(nextUpdate, "%y%m%d%H%M%S")
            except:
                raise Exception(error_msg)
            self.nextUpdate_str_simple = time.strftime("%x", self.nextUpdate)

        if tbsCertList.crlExtensions:
            for extension in tbsCertList.crlExtensions:
                if extension.extnID.oidname == "cRLNumber":
                    self.number = extension.extnValue.cRLNumber.val

        revoked = []
        if tbsCertList.revokedCertificates:
            for cert in tbsCertList.revokedCertificates:
                serial = cert.serialNumber.val
                date = cert.revocationDate.val
                if date[-1] == "Z":
                    date = date[:-1]
                try:
                    revocationDate = time.strptime(date, "%y%m%d%H%M%S")
                except:
                    raise Exception(error_msg)
                revoked.append((serial, date))
        self.revoked_cert_serials = revoked

        self.signatureValue = raw(crl.signatureValue)
        self.signatureLen = len(self.signatureValue)

    def isIssuerCert(self, other):
        # This is exactly the same thing as in Cert method.
        if self.issuer_hash != other.subject_hash:
            return False
        return other.pubKey.verifyCert(self)

    def verify(self, anchors):
        # Return True iff the CRL is signed by one of the provided anchors.
        return any(self.isIssuerCert(a) for a in anchors)

    def show(self):
        print("Version: %d" % self.version)
        print("sigAlg: " + self.sigAlg)
        print("Issuer: " + self.issuer_str)
        print("lastUpdate: %s" % self.lastUpdate_str)
        print("nextUpdate: %s" % self.nextUpdate_str)
예제 #25
0
파일: fields.py 프로젝트: irl/scapy
class Field(six.with_metaclass(Field_metaclass, object)):
    """For more informations on how this work, please refer to
       http://www.secdev.org/projects/scapy/files/scapydoc.pdf
       chapter ``Adding a New Field''"""
    __slots__ = ["name", "fmt", "default", "sz", "owners"]
    islist = 0
    ismutable = False
    holds_packets = 0

    def __init__(self, name, default, fmt="H"):
        self.name = name
        if fmt[0] in "@=<>!":
            self.fmt = fmt
        else:
            self.fmt = "!" + fmt
        self.default = self.any2i(None, default)
        self.sz = struct.calcsize(self.fmt)
        self.owners = []

    def register_owner(self, cls):
        self.owners.append(cls)

    def i2len(self, pkt, x):
        """Convert internal value to a length usable by a FieldLenField"""
        return self.sz

    def i2count(self, pkt, x):
        """Convert internal value to a number of elements usable by a FieldLenField.
        Always 1 except for list fields"""
        return 1

    def h2i(self, pkt, x):
        """Convert human value to internal value"""
        return x

    def i2h(self, pkt, x):
        """Convert internal value to human value"""
        return x

    def m2i(self, pkt, x):
        """Convert machine value to internal value"""
        return x

    def i2m(self, pkt, x):
        """Convert internal value to machine value"""
        if x is None:
            x = 0
        return x

    def any2i(self, pkt, x):
        """Try to understand the most input values possible and make an internal value from them"""
        return self.h2i(pkt, x)

    def i2repr(self, pkt, x):
        """Convert internal value to a nice representation"""
        return repr(self.i2h(pkt, x))

    def addfield(self, pkt, s, val):
        """Add an internal value  to a string"""
        return s + struct.pack(self.fmt, self.i2m(pkt, val))

    def getfield(self, pkt, s):
        """Extract an internal value from a string"""
        return s[self.sz:], self.m2i(pkt,
                                     struct.unpack(self.fmt, s[:self.sz])[0])

    def do_copy(self, x):
        if hasattr(x, "copy"):
            return x.copy()
        if isinstance(x, list):
            x = x[:]
            for i in range(len(x)):
                if isinstance(x[i], BasePacket):
                    x[i] = x[i].copy()
        return x

    def __repr__(self):
        return "<Field (%s).%s>" % (",".join(x.__name__
                                             for x in self.owners), self.name)

    def copy(self):
        return copy.deepcopy(self)

    def randval(self):
        """Return a volatile object whose value is both random and suitable for this field"""
        fmtt = self.fmt[-1]
        if fmtt in "BHIQ":
            return {
                "B": RandByte,
                "H": RandShort,
                "I": RandInt,
                "Q": RandLong
            }[fmtt]()
        elif fmtt == "s":
            if self.fmt[0] in "0123456789":
                l = int(self.fmt[:-1])
            else:
                l = int(self.fmt[1:-1])
            return RandBin(l)
        else:
            warning("no random class for [%s] (fmt=%s)." %
                    (self.name, self.fmt))