예제 #1
0
def ipa_handle_resp(x, tk, verbose=False, proc=None):
    s = data2str(x.recv(38))
    if "0023fe040108010701020103010401050101010011" in s:
        retries = 3
        while True:
            print("\tsending IPA identity(%s) at %s" %
                  (tk, time.strftime("%T")))
            try:
                x.send(IPA().id_resp(
                    IPA().identity(name=(tk + '\0').encode('utf-8'))))
                print("\tdone sending IPA identity(%s) at %s" %
                      (tk, time.strftime("%T")))
                break
            except:
                print("\tfailed sending IPA identity at", time.strftime("%T"))
                if proc:
                    print("\tproc.poll() = %r" % proc.poll())
                if retries < 1:
                    print("\tgiving up")
                    raise
                print("\tretrying (%d attempts left)" % retries)
                retries -= 1
    else:
        if (verbose):
            print("\tBSC <- NAT: ", s)
예제 #2
0
 def process_chunk(self, data):
     """
     Generic message dispatcher for IPA (sub)protocols based on protocol name, lambda default should never happen
     """
     (_, proto, extension, content) = IPA().del_header(data)
     if content is not None:
         self.dbg('IPA received %s::%s [%d/%d] %s' % (IPA().proto(proto), IPA().ext_name(proto, extension), len(data), len(content), content))
         method = getattr(self, 'handle_' + IPA().proto(proto), lambda: "protocol dispatch failure")
         method(content, proto, extension)
예제 #3
0
    def testUssdSideChannelProvider(self):
        self.vty.command("end")
        self.vty.enable()
        self.vty.command("configure terminal")
        self.vty.command("nat")
        self.vty.command("ussd-token key")
        self.vty.command("end")

        res = self.vty.verify("show ussd-connection", [
            'The USSD side channel provider is not connected and not authorized.'
        ])
        self.assertTrue(res)

        ussdSocket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        ussdSocket.connect(('127.0.0.1', 5001))
        ussdSocket.settimeout(2.0)
        print("Connected to %s:%d" % ussdSocket.getpeername())

        print("Expecting ID_GET request")
        data = ussdSocket.recv(4)
        self.assertEqual(data, b"\x00\x01\xfe\x04")

        print("Going to send ID_RESP response")
        res = ussdSocket.send(IPA().id_resp(IPA().tag_name('key' + '\0')))
        self.assertEqual(res, 11)

        # initiating PING/PONG cycle to know, that the ID_RESP message has been processed

        print("Going to send PING request")
        res = ussdSocket.send(IPA().ping())
        self.assertEqual(res, 4)

        print("Expecting PONG response")
        data = ussdSocket.recv(4)
        self.assertEqual(data, b"\x00\x01\xfe\x01")

        res = self.vty.verify(
            "show ussd-connection",
            ['The USSD side channel provider is connected and authorized.'])
        self.assertTrue(res)

        print("Going to shut down connection")
        ussdSocket.shutdown(socket.SHUT_WR)

        print("Expecting EOF")
        data = ussdSocket.recv(4)
        self.assertEqual(data, b"")

        ussdSocket.close()

        res = self.vty.verify("show ussd-connection", [
            'The USSD side channel provider is not connected and not authorized.'
        ])
        self.assertTrue(res)
예제 #4
0
    def recv_msgs(self):
        responses = {}
        data = self.sock.recv(4096)
        while (len(data)>0):
            (head, data) = IPA().split_combined(data)
            answer = Ctrl().rem_header(head).decode()
            if verbose:
                print("Got message:", answer)
            (mtype, id, msg) = answer.split(None, 2)
            id = int(id)
            rsp = {'mtype': mtype, 'id': id}
            if mtype == "ERROR":
                rsp['error'] = msg
            else:
                split = msg.split(None, 1)
                rsp['var'] = split[0]
                if len(split) > 1:
                    rsp['value'] = split[1]
                else:
                    rsp['value'] = None
            responses[id] = rsp

        if verbose:
            print("Decoded replies: ", responses)

        return responses
예제 #5
0
 def handle_UNKNOWN(self, data, proto, extension):
     """
     Default protocol handler
     """
     self.dbg(
         'IPA received message for %s (%s) protocol with attribute %s' %
         (IPA().proto(proto), proto, extension))
예제 #6
0
 def handle_OSMO(self, data, proto, extension):
     """
     Dispatcher point for OSMO subprotocols based on extension name, lambda default should never happen
     """
     method = getattr(self, 'osmo_' + IPA().ext(extension),
                      lambda: "extension dispatch failure")
     method(data)
예제 #7
0
class IPAFactory(ReconnectingClientFactory):
    """
    Generic IPA Client Factory which can be used to store state for various subprotocols and manage connections
    Note: so far we do not really need separate Factory for acting as a server due to protocol simplicity
    """
    protocol = IPACommon
    debug = False
    ccm_id = IPA().identity(unit=b'1515/0/1', mac=b'b0:0b:fa:ce:de:ad:be:ef', utype=b'sysmoBTS', name=b'StingRay', location=b'hell', sw=IPA.version.encode('utf-8'))

    def __init__(self, proto=None, debug=False, ccm_id=None):
        if proto:
            self.protocol = proto
        if debug:
            self.debug = debug
        if ccm_id:
            self.ccm_id = ccm_id

    def clientConnectionFailed(self, connector, reason):
        """
        Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
        """
        if self.debug:
            print('IPAFactory connection failed:', reason.getErrorMessage())
        ReconnectingClientFactory.clientConnectionFailed(self, connector, reason)

    def clientConnectionLost(self, connector, reason):
        """
        Only necessary for as debugging aid - if we can somehow set parent's class noisy attribute then we can omit this method
        """
        if self.debug:
            print('IPAFactory connection lost:', reason.getErrorMessage())
        ReconnectingClientFactory.clientConnectionLost(self, connector, reason)
예제 #8
0
    def create_full_IPA(self,
                        parent,
                        cells,
                        type,
                        subtype=None,
                        test=False,
                        mom=-1):
        try:
            if subtype is None: subtype = type
            for s in IPA.values():
                if s.type != type and s.type != subtype: continue
                f = tk.Frame(parent)
                c = ["#009", "#666"]
                if test: c = ["#00F", "#000"]
                l = tk.Label(f,
                             text=s.symb,
                             state=tk.DISABLED,
                             fg=c[0],
                             disabledforeground=c[1],
                             cursor="hand2",
                             font=("Noto Sans", 12))
                if not test:
                    l.config(compound=tk.BOTTOM)  # Store state of Symb
                    l.bind("<Button-1>", self.add_IPA)
                else:
                    l.bind("<Button-1>", self.play_IPA)
                l.bind("<Enter>", lambda e: self.change_IPA(e, True))
                l.bind("<Leave>", lambda e: self.change_IPA(e, False))
                l.grid()
                f.grid(column=s.col() + 1, row=s.row() + 1, sticky=s.anc())
                cells[s.row()][s.col()] = f

            return cells
        except Exception as e:
            self.throw_err("#UR_FULL" + str(mom) + "ERR", e)
예제 #9
0
 def connectionMade(self):
     """
     Keep reconnection logic working by calling routine from CCM
     Initiate CCM upon connection
     """
     print('IPA server connection made!')
     super(IPAServer, self).connectionMade()
     self.transport.write(IPA().id_get())
예제 #10
0
 def dataReceived(self, data):
     """
     Override for dataReceived from Int16StringReceiver because of inherently incompatible interpretation of length
     If default handler is used than we would always get off-by-1 error (Int16StringReceiver use equivalent of l + 2)
     """
     if len(data):
         (head, tail) = IPA().split_combined(data)
         self.process_chunk(head)
         self.dataReceived(tail)
예제 #11
0
def ipa_handle_small(x, verbose=False):
    s = data2str(x.recv(4))
    if len(s) != 4 * 2:
        raise Exception("expected to receive 4 bytes, but got %d (%r)" %
                        (len(s) / 2, s))
    if "0001fe00" == s:
        if (verbose):
            print("\tBSC <- NAT: PING?")
        x.send(IPA().pong())
    elif "0001fe06" == s:
        if (verbose):
            print("\tBSC <- NAT: IPA ID ACK")
        x.send(IPA().id_ack())
    elif "0001fe00" == s:
        if (verbose):
            print("\tBSC <- NAT: PONG!")
    else:
        if (verbose):
            print("\tBSC <- NAT: ", s)
예제 #12
0
 def connectionMade(self):
     """
     Keep reconnection logic working by calling routine from CCM
     Initiate CCM upon connection
     """
     addr = self.transport.getPeer()
     self.factory.log.info('IPA server: connection from %s:%d client' %
                           (addr.host, addr.port))
     super(IPAServer, self).connectionMade()
     self.transport.write(IPA().id_get())
예제 #13
0
 def handle_CCM(self, data, proto, msgt):
     """
     CCM (IPA Connection Management)
     Only basic logic necessary for tests is implemented (ping-pong, id ack etc)
     """
     if msgt == IPA.MSGT['ID_GET']:
         self.transport.getHandle().sendall(IPA().id_resp(self.factory.ccm_id))
         # if we call
         # self.transport.write(IPA().id_resp(self.factory.test_id))
         # instead, than we would have to also call
         # reactor.callLater(1, self.ack)
         # instead of self.ack()
         # otherwise the writes will be glued together - hence the necessity for ugly hack with 1s timeout
         # Note: this still might work depending on the IPA implementation details on the other side
         self.ack()
         # schedule PING in 4s
         reactor.callLater(4, self.ping)
     if msgt == IPA.MSGT['PING']:
         self.pong()
예제 #14
0
 def pong(self):
     self.transport.write(IPA().pong())
예제 #15
0
 def ack(self):
     self.transport.write(IPA().id_ack())