Exemple #1
0
 def send(self, packet):
     released_lock = None
     if self.locked:
         if packet.locked == self.locked:
             tmp_debug("IO", "O => %s: %s" % (self.uid,
                                     deprotect(packet.packet)))
             try:
                 self.socket.sendall(str(packet.packet))
             except:
                 self.disconnect()
                 return None
             released_lock = self.locked
             if not self.keep_flow:
                 self.locked = 0
         else:
             # just discard, may be too old
             pass
     else:
         # on let events go
         if not packet.locked:
             tmp_debug("IO", "O => %s %s" % (self.uid,
                                     deprotect(packet.packet)))
             try:
                 self.socket.sendall(str(packet.packet))
             except:
                 self.disconnect()
         else:
             # humm, why we get that ??
             pass
     return released_lock
Exemple #2
0
def burials(self):
    apocalypse = bigtime(-10)
    for peer in self.peers:
        if peer and peer.locked and peer.logged and peer.locked < apocalypse:
            peer.locked = 0
            tmp_debug("SQUIRM", "Removing the very old lock of  %s" % \
                      peer.uid)
Exemple #3
0
 def handle_line(self):
     if self.socket:
         bytes = ''
         try:
             bytes = self.socket.recv(4096)
         except:
             pass
         if len(bytes) == 0:
             self.disconnect()
         self.buffer += bytes
     in_lines = self.buffer.split('\n')
     self.lines.extend([l + '\n' for l in in_lines[:-1]])
     self.buffer = in_lines[-1]
     for line in self.lines:
         tmp_debug("IO", "%s => O: %s" % (self.uid, deprotect(line)))
         line = line.strip()
         # if locked, we are waiting for a result
         if not self.locked:
             if line.lower().startswith('action:'):
                 self.action = \
                          Action(line[line.find(':') + 1:].strip())
             elif line == '':
                 if self.action:
                     self.locked = bigtime()
                     self.push(self.action)
                     self.action = None
             else:
                 if ':' in line:
                     k = line.split(':')[0]
                     v = line[line.find(':') + 1:].strip()
                 if self.action:
                     self.action.add_parameters({k: v})
     self.lines = []
Exemple #4
0
 def push(self, packet):
     if packet.name.lower() in STARTING_EVENTS_KEYWORDS:
         self.keep_flow = True
     p = dict(emiter=self.id, locked=self.locked,
              timestamp=time(), packet=packet)
     tmp_debug("PACKET", "%s (L:%s, KF:%s) >> %s" % (self.uid, self.locked,
                                                     self.keep_flow,
                                                     deprotect(str(p))))
     self.octopasty.in_queue.put(Packet(p))
Exemple #5
0
def logoff_user(self, packet):
    client = self.clients.get(packet.emiter)
    response = Goodbye(parameters=dict(Message="Don't panic."))
    p = dict(emiter='__internal__',
             locked=packet.locked,
             timestamp=time(),
             packet=response,
             dest=client.id)
    client.send(Packet(p))
    tmp_debug("AUTH", "'%s' logout" % packet.emiter[:packet.emiter.find('_')])
    client.disconnect()
Exemple #6
0
 def handle_line(self):
     if self.socket:
         bytes = ''
         try:
             bytes = self.socket.recv(4096)
         except:
             pass
         if len(bytes) == 0:
             self.disconnect()
         self.buffer += bytes
     in_lines = self.buffer.split('\n')
     self.lines.extend([l + '\n' for l in in_lines[:-1]])
     self.buffer = in_lines[-1]
     for line in self.lines:
         tmp_debug("IO", "%s => O: L: %s D: %s" % (
             self.uid, self.locked, deprotect(line)))
         line = line.strip()
         if line.startswith('Asterisk Call Manager'):
             self.login()
             self.lines = []
             return
         if self.locked and line.lower().startswith('response:'):
             self.response = \
                       Response(line[line.find(':') + 1:].strip())
             self.event = None
         elif line.lower().startswith('event:'):
             name = line[line.find(':') + 1:].strip()
             self.event = Event(name)
             self.response = None
         elif line == '':
             if self.response:
                 self.push(self.response)
                 self.response = None
             elif self.event:
                 if self.keep_flow:
                     self.push(self.event)
                 else:
                     self.push(self.event, locked=0)
                 self.event = None
         else:
             if ':' in line:
                 sc = line.find(':')
                 k = line[:sc].strip()
                 v = line[sc + 1:].strip()
             else:
                 k = line
                 v = None
             if self.response:
                 self.response.add_parameters({k: v})
             if self.event:
                 self.event.add_parameters({k: v})
     self.lines = []
Exemple #7
0
 def run(self):
     self.listening = True
     while self.listening:
         try:
             self.s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
             self.s.bind((self.octopasty.config.get('bind_address'),
                          int(self.octopasty.config.get('bind_port'))))
             tmp_debug("NETWORK", "Listening on %s %s" % \
                       (self.octopasty.config.get('bind_address'),
                        self.octopasty.config.get('bind_port')))
             self.s.listen(5)
             while self.listening:
                 channel, details = self.s.accept()
                 st = ServerThread(self.octopasty, channel, details)
                 st.start()
         except socket.error, e:
             if e.errno == errno.EADDRINUSE:
                 tmp_debug(
                     "NETWORK",
                     "Address already used trying to bind on %s %s" % \
                     (self.octopasty.config.get('bind_address'),
                      self.octopasty.config.get('bind_port')))
                 for timeout in range(0, LISTENING_TIMEOUT):
                     if self.listening == False:
                         break
                     sleep(1)
             elif e.errno == errno.EINVAL:
                 tmp_debug("NETWORK", "Closing server, time to sleep")
                 self.listening = False
             else:
                 tmp_debug("NETWORK", "Unknown socket error: %s" % e)
                 self.listening = False
Exemple #8
0
 def send(self, packet):
     if not self.locked:
         tmp_debug("IO", "O => %s: L: %s D: %s" % (
             self.uid,
             packet.locked,
             deprotect(packet.packet)))
         self.socket.sendall(str(packet.packet))
         if packet.packet.name.lower() in STARTING_EVENTS_KEYWORDS:
             self.keep_flow = True
             tmp_debug("PACKET", "%s Starting flow (L:%s)" % (self.uid,
                                                              self.locked))
         self.locked = packet.locked
         return self.locked
     else:
         return None
Exemple #9
0
 def push(self, packet, emiter=None, dest=None, locked=-1):
     p = dict(emiter=emiter or self.server,
              locked=locked == -1 and self.locked or locked,
              timestamp=time(),
              packet=packet)
     if dest:
         p['dest'] = dest
     tmp_debug("PACKET", "%s (L:%s, KF:%s) >> %s" % (self.uid, self.locked,
                                                     self.keep_flow,
                                                     deprotect(p)))
     self.octopasty.in_queue.put(Packet(p))
     if packet.name.lower() in STOPPING_EVENTS_KEYWORDS:
         self.keep_flow = False
     tmp_debug("PACKET", "%s Stopping flow (L:%s)" % (self.uid,
                                                      self.locked))
Exemple #10
0
def auth_user(self, emiter, locked, username, secret, wants_events):
    login_sucessfull = False
    client = self.clients.get(emiter)
    if username in self.config.get('users'):
        hashed = self.config.get('users').get(username).get('password')
        if client.authtype is None:
            if sha1(secret).hexdigest() == hashed:
                login_sucessfull = True
        elif client.authtype[0] == 'md5':
            key = client.authtype[1]
            _md5 = md5(key)
            _md5.update(self.config.get('users').get(username).get('password'))
            if secret == _md5.hexdigest():
                login_sucessfull = True
    if login_sucessfull:
        old_id = client.id
        client.id = '%s_%d' % (username, bigtime())
        self.clients.pop(old_id)
        self.clients.update({client.id: client})
        client.logged = True
        _servers = self.config.get('users').get(username).get('servers')
        _servers = [s.strip() for s in _servers.split(',')]
        if len(_servers) == 1:
            client.binded_server = _servers[0]
        else:
            client.multiple_servers = _servers
        client.wants_events = wants_events
        response = Success(parameters=dict(
            Message='Authentication accepted'))
        p = dict(emiter='__internal__',
                 locked=locked,
                 timestamp=time(),
                 packet=response,
                 dest=client.id)
        tmp_debug("AUTH", "'%s' logged successfully" % username)
        self.out_queue.put(Packet(p))
    else:
        response = Error(parameters=dict(Message='Authentication failed'))
        p = dict(emiter='__internal__',
                 locked=locked,
                 timestamp=time(),
                 packet=response,
                 dest=client.id)
        client.send(Packet(p))
        tmp_debug("AUTH", "'%s' failed to login" % username)
        client.disconnect()
Exemple #11
0
def challenge(self, emiter, locked, authtype):
    if authtype == 'md5':
        key = str(randint(100000000, 999999999))
        response = Success(parameters=dict(
            Challenge='%s' % key))
        tmp_debug("AUTH", "'%s' asked for '%s' challenge, sent '%s'" % \
                  (emiter, authtype, key))
    else:
        response = Error(parameters=dict(
            Message='Authentication type not supported'))
    client = self.clients.get(emiter)
    p = dict(emiter='__internal__',
             locked=locked,
             timestamp=time(),
             packet=response,
             dest=client.id)
    client.send(Packet(p))
    client.authtype = (authtype, key)
Exemple #12
0
 def loop(self):
     looping = True
     self.listen_clients()
     while looping:
         try:
             self.connect_servers()
             self.idle()
             readall(self)
             squirm(self)
             burials(self)
             sendall(self)
         except KeyboardInterrupt:
             for ami in self.amis.values():
                 tmp_debug("NETWORK", "Disconecting from %s" % ami.uid)
                 ami.disconnect()
                 ami.join()
             for client in self.clients.values():
                 tmp_debug("NETWORK", "Disconecting %s" % client.uid)
                 client.disconnect()
                 client.join()
             looping = False
     self.listener.stop()
     self.listener.join()
Exemple #13
0
def sendall(self):
    if not self.out_queue.empty():
        outgoing = list(self.out_queue.queue)
        self.out_queue.queue.clear()
        for packet in outgoing:
            tmp_debug("PACKET", "%s << %s" % (packet.dest, deprotect(packet)))
            if packet.dest == '__internal__':
                handle_action(self, packet)
            else:
                dest = self.get_peer(packet.dest)
                if dest:
                    # here is another place to check
                    # and requeue if necessary
                    if packet.locked != dest.locked and \
                       not dest.available:
                        self.out_queue.put(packet)
                        tmp_debug("SQUIRM", "Requeueing on output: %s" % \
                                  deprotect(packet))
                        continue
                    if not packet.locked and not dest.available:
                        self.out_queue.put(packet)
                        tmp_debug("SQUIRM", "Requeueing on output: %s" % \
                                  deprotect(packet))
                        continue
                    sent = dest.send(packet)
                    if sent:
                        if str(sent) in self.flow:
                            keep_flow = dest.keep_flow
                            if packet.packet.name.lower() in \
                                   STOPPING_EVENTS_KEYWORDS:
                                keep_flow = False
                                dest.keep_flow = False
                                dest.locked = 0
                            # then it was an answer
                            if not keep_flow:
                                self.flow.pop("%s" % sent)
                        else:
                            # then it was a query
                            self.flow["%s" % sent] = packet.emiter
                    else:
                        # Then it was an event
                        pass
Exemple #14
0
def logged_on_ami(self, _ami):
    tmp_debug("AUTH", "Logged on '%s'" % _ami)
    ami = self.amis.get(_ami)
    ami.logged = True
Exemple #15
0
def login_failed_on_ami(self, _ami):
    tmp_debug("AUTH", "Login failed on '%s'" % _ami)
Exemple #16
0
def squirm(self):
    apocalypse = time() - 10
    if not self.in_queue.empty():
        incoming = list(self.in_queue.queue)
        self.in_queue.queue.clear()
        for packet in incoming:
            tmp_debug("SQUIRM", "Processing packet %s" % deprotect(packet))
            if packet.timestamp < apocalypse:
                # not puting in the queue and just continuing
                # makes the packet go nowhere
                # TODO: figure what to do here, i was thinking about something
                # if packet.locked:
                #     dest = self.flow.get("%s" % packet.locked)
                #     if dest != '__internal__':
                #         peer = self.get_peer(dest)
                tmp_debug("SQUIRM", "Removing very old packet: %s" % packet)
                continue
            if packet.emiter == '__internal__':
                peer = self.get_peer(packet.dest)
                if peer and peer.available:
                    self.out_queue.put(packet)
                else:
                    self.in_queue.put(packet)
            else:
                if packet.locked:
                    if packet.emiter in self.connected_servers:
                        tmp_debug("SQUIRM", "Emiter is server %s" % \
                                  packet.emiter)
                        emiter = self.get_peer(packet.emiter)
                        if emiter.locked and not emiter.keep_flow:
                            emiter.locked = 0
                            tmp_debug("SQUIRM", "Unlocking emiter %s" % \
                                      emiter.uid)
                        dest = self.flow.get("%s" % packet.locked)
                        if dest:
                            if dest == '__internal__':
                                handle_action(self, packet)
                            else:
                                peer = self.get_peer(dest)
                                if peer and peer.logged:
                                    if peer.locked:
                                        if peer.locked == packet.locked:
                                            packet.dest = dest
                                            self.out_queue.put(packet)
                                        else:
                                            tmp_debug("SQUIRM",
                                                      "Requeueing packet " \
                                                      "from server: %s" % \
                                                      deprotect(packet))
                                            self.in_queue.put(packet)
                                else:
                                    # just forgot it, and stop flow if any
                                    if emiter.keep_flow:
                                        emiter.keep_flow = 0
                                        emiter.locked = 0
                        else:
                            if emiter.keep_flow:
                                emiter.keep_flow = 0
                                emiter.locked = 0
                    if packet.emiter in self.connected_clients:
                        tmp_debug("SQUIRM", "Emiter is client %s" % \
                                  packet.emiter)
                        if packet.packet.name.lower() in KEEP_INTERNAL:
                            handle_action(self, packet)
                            continue
                        client = self.get_peer(packet.emiter)
                        if client.logged:
                            cid = client.id.split('_')[0]
                            cu = self.config['users'].get(cid)
                            if cu:
                                cs = client.binded_server
                                if cs:
                                    peer = self.get_peer(cs)
                                    if peer and peer.logged:
                                        if peer.available:
                                            # server seems already available
                                            # but may be busy just after,
                                            # then we need to verify that
                                            # in outgoing packets too
                                            packet.dest = cs
                                            self.out_queue.put(packet)
                                            tmp_debug("SQUIRM",
                                                      "Packet from client " \
                                                      "pushed to queue %s" % \
                                                      deprotect(packet))
                                        else:
                                            # server seems busy
                                            self.in_queue.put(packet)
                                            tmp_debug("SQUIRM",
                                                      "Requeueing packet from "
                                                      " client: %s" % \
                                                      deprotect(packet))
                                    else:
                                        response = Error(
                                            parameters=dict(
                                                Message='Server unavailable'))
                                        p = dict(emiter=cs,
                                                 locked=packet.locked,
                                                 timestamp=time(),
                                                 packet=response,
                                                 dest=client.id)
                                        self.out_queue.put(Packet(p))
                                else:
                                    if len(client.multiple_servers):
                                        response = Error(
                                            parameters=dict(
                                                Message='Cannot send command '
                                                'to multiple servers'))
                                        p = dict(emiter='__internal__',
                                                 locked=packet.locked,
                                                 timestamp=time(),
                                                 packet=response,
                                                 dest=client.id)
                                        self.out_queue.put(Packet(p))
                        else:
                            packet.dest = '__internal__'
                            self.out_queue.put(packet)
                else:
                    # packet not locked
                    if packet.emiter in self.connected_servers:
                        # broadcast events
                        ami = self.get_peer(packet.emiter)
                        if ami.logged:
                            for client in self.connected_clients:
                                peer = self.get_peer(client)
                                if peer.binded_server == packet.emiter or \
                                   packet.emiter in peer.multiple_servers and \
                                   peer.wants_events:
                                    p = copy(packet)
                                    p.dest = client
                                    self.out_queue.put(p)
                        else:
                            # Do not remove that comment and that case
                            # it might be logged one day
                            # ami not logged, and no command before
                            # i wonder what can it be
                            pass