Beispiel #1
0
 def aggregate(self, replies):
     results = [
         ami.AMI_Message([
             ('Response', 'Success'),
             ('EventList', 'start'),  # Note: lower-case "s"
             ('Message', 'Peer status list will follow')
         ])
     ]
     for name, ami_messages in replies.iteritems():
         if len(ami_messages) < 2:
             bubble.log.error("From %s, IAXpeers action reply is too short",
                              name)
             continue
         if ami_messages[0].get('Response') != 'Success':
             bubble.log.error("From %s, IAXpeers action failed", name)
             continue
         if ami_messages[-1].get('Event') != 'PeerlistComplete':
             bubble.log.error("From %s, IAXpeers events do not complete",
                              name)
             continue
         value = ami_messages[-1].get('ListItems')
         if not (value and value.isdigit()
                 and int(value) == len(ami_messages) - 2):
             bubble.log.error(
                 "From %s, IAXpeersComplete has invalid ListItems", name)
             continue
         results += ami_messages[1:-1]
     results.append(
         ami.AMI_Message([
             ('Event', 'PeerlistComplete'),
             ('EventList', 'Complete'),  # Note: upper-case "C".
             ('ListItems', str(len(results) - 1))
         ]))
     return results
Beispiel #2
0
 def aggregate(self, replies):
     results = [
         ami.AMI_Message([('Response', 'Success'),
                          ('Message', 'Channel status will follow')])
     ]
     for name, ami_messages in replies.iteritems():
         if len(ami_messages) < 2:
             bubble.log.error("From %s, Status action reply is too short",
                              name)
             continue
         if ami_messages[0].get('Response') != 'Success':
             bubble.log.error("From %s, Status action failed", name)
             continue
         if ami_messages[-1].get('Event') != 'StatusComplete':
             bubble.log.error("From %s, Status events do not complete",
                              name)
             continue
         value = ami_messages[-1].get('Items')
         if not (value and value.isdigit()
                 and int(value) == len(ami_messages) - 2):
             bubble.log.error("From %s, StatusComplete has invalid Items",
                              name)
             continue
         results += ami_messages[1:-1]
     results.append(
         ami.AMI_Message([('Event', 'StatusComplete'),
                          ('Items', str(len(results) - 1))]))
     return results
Beispiel #3
0
    def broadcast(self, client, ami_message, server_names):
        def deny(diagnostic):
            bubble.log.user("Login failed: %s.", diagnostic)
            return ami.AMI_Message([('Response', 'Error'),
                                    ('Message', "Authentication refused")])

        # Validate login.
        if client.user is not None:
            bubble.log.user("Already authenticated.")
            return ami.AMI_Message([('Response', 'Success'),
                                    ('Message', "Already authenticated")])
        username = ami_message.get('Username')
        user = client.config.users.get(username)
        if user is None:
            return deny("Unknown username.")
        secret = ami_message.get('Secret')
        password = user.password
        if client.challenge is None:
            if (hashlib.md5(secret).hexdigest() != password
                    and hashlib.sha1(secret).hexdigest() != password):
                return deny("Password does not match.")
        elif hashlib.md5(client.challenge + secret) != password:
            return deny("Challenge was not successful.")
        if not (client.address is None or user.acl is None):
            for check, mask in user.acl:
                ip = struct.unpack('!I', socket.inet_ntoa(client.address))[0]
                if (ip ^ check) & mask == 0:
                    break
            else:
                return deny("Access not allowed from this IP.")

        # Listen to random events from all servers; launch them as needed.
        show_events = ami_message.get_lower('Events') != 'off'
        if show_events:
            events_forwarder = self.Events_Forwarder(suffix=None)
            events_forwarder.configure(user.event_filter, client.writer)
        client.server_names = []
        for name in user.servers:
            server = ami.Server.registry.get(name)
            if server is None:
                server = ami.Server()
                if show_events:
                    server.add_to_output_bus(events_forwarder)
                server.configure(client.config.servers[name])
                # FIXME: What if Asterisk refuses to reply?
            elif show_events:
                server.add_to_output_bus(events_forwarder)
            client.server_names.append(name)

        # Login is successful!
        client.user = user
        bubble.log.info("%s logged in user %s.", client, user.name)
        return ami.AMI_Message([('Response', 'Success'),
                                ('Message', "Authentication accepted")])
Beispiel #4
0
    def broadcast(self, client, ami_message, server_names):

        if client.user is not None:
            bubble.log.user("Already authenticated.")
            return ami.AMI_Message([('Response', 'Success'),
                                    ('Message', "Already authenticated")])

        if ami_message.get_lower('AuthType') != 'md5':
            bubble.log.user("Authentication type not supported.")
            return ami.AMI_Message([('Response', 'Error'),
                                    ('Message',
                                     "Authentication type not supported")])

        client.challenge = str(random.randint(100000000, 999999999))
        return ami.AMI_Message([('Response', 'Success'),
                                ('Challenge', client.challenge)])
Beispiel #5
0
 def aggregate(self, replies):
     results = [
         ami.AMI_Message([('Response', 'Success'),
                          ('Message', 'Channel status will follow')])
     ]
     for name, ami_messages in replies.iteritems():
         if len(ami_messages) < 2:
             bubble.log.error(
                 "From %s, QueueStatus action reply is too short", name)
             continue
         if ami_messages[0].get('Response') != 'Success':
             bubble.log.error("From %s, QueueStatus action failed", name)
             continue
         if ami_messages[-1].get('Event') != 'QueueStatusComplete':
             bubble.log.error("From %s, QueueStatus events do not complete",
                              name)
             continue
         results += ami_messages[1:-1]
     results.append(ami.AMI_Message([('Event', 'QueueStatusComplete')]))
     return results
Beispiel #6
0
 def broadcast(self, client, ami_message, server_names):
     accepting = set()
     for name in server_names:
         server = ami.Server.registry.get(name)
         if server:
             accepting |= set(server.accepting)
     response = ami.AMI_Message([('Response', 'Success')])
     has_octopasty = 'octopasty' in client.user.privileges
     for key, maker in sorted(ami.manager_actions.items()):
         if not (issubclass(maker, Manager_Action) or maker in accepting):
             continue
         privileges = maker.privileges
         # Actions with octopasty among privileges are invisible,
         # save for user having octopasty privilege.
         if privileges is not None and 'octopasty' in privileges:
             if not has_octopasty:
                 continue
         response[maker.name] = (
             '%s  (Priv: %s)' % (
                 maker.summary,
                 # Looking like Asterisk even where it is wrong :-).
                 ','.join(privileges) if privileges else '<none>'))
     return response
Beispiel #7
0
 def broadcast(self, client, ami_message, server_names):
     # Asterisk would use:
     #message = "Thanks for all the fish."
     # Octopasty prefers:
     message = "Don't panic."
     return ami.AMI_Message([('Response', 'Goodbye'), ('Message', message)])
Beispiel #8
0
 def deny(diagnostic):
     bubble.log.user("Login failed: %s.", diagnostic)
     return ami.AMI_Message([('Response', 'Error'),
                             ('Message', "Authentication refused")])