def bye(my_socket, login): msg = 'BYE sip:%s SIP/2.0\r\n\r\n' % (login) data = connect_to_proxy(msg, my_socket) if '200 OK' in data: os.system('killall mp32rtp 2> /dev/null') os.system('killall vlc 2> /dev/null') write_log(config_dict, 'Finishing...\n\r')
def handle(self): error_occurred = True self.users_dict = file2dict(database_path) clean_clients(self.users_dict) methods = {'REGISTER': self.register, 'INVITE': self.invite, 'ACK': self.ack, 'BYE': self.bye} while 1: msg_recv = self.rfile.read().decode('utf-8') if not msg_recv: break ip, port = msg_info(self.client_address, msg_recv) try: method = check_format(msg_recv) if not method in methods: raise SipCodeException(405) else: print(method, 'received') methods[method](msg_recv, ip, port) error_occurred = False except SipCodeException as sipcode: msg = sipcode.code if error_occurred: self.wfile.write(msg.encode('utf-8')) write_log(config_dict, 'Sent to', ip, port, msg) dict2file(database_path, self.users_dict)
def sent_to_uaserver(msg_recv, users_dict): login = msg_recv.split()[1].split(':')[1] if not login in users_dict: raise SipCodeException(404) ip_to_send = users_dict[login]['ip'] port_to_send = int(users_dict[login]['port']) msg_recv = add_proxy_header(msg_recv) my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) my_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) my_socket.connect((ip_to_send, port_to_send)) my_socket.send(bytes(msg_recv, 'utf-8')) write_log(config_dict, 'Sent to', ip_to_send, port_to_send, msg_recv) try: data = my_socket.recv(1024).decode('utf-8') my_socket.close() except: my_socket.close() raise SipCodeException(603) write_log(config_dict, 'Received from', ip_to_send, port_to_send, data) data = add_proxy_header(data) return data
def bye(self, msg_recv, ip, port): if is_valid_bye(msg_recv, ip, self.sending_rtp_dict): data = sent_to_uaserver(msg_recv, self.users_dict) self.wfile.write(bytes(data, 'utf-8')) write_log(config_dict, 'Sent to', ip, port, data) else: raise SipCodeException(403)
def register(my_socket, expires): write_log(config_dict, 'Starting...') username = config_dict['account']['username'] port_uas = config_dict['uaserver']['puerto'] msg = 'REGISTER sip:%s:%s SIP/2.0\r\n' % (username, port_uas) msg += 'Expires: %s\r\n\r\n' % (expires) data = connect_to_proxy(msg, my_socket) if 'Unauthorized' in data.split(): nonce = data.split()[-1].split('=')[-1].strip('"') passwd = config_dict['account']['passwd'] response = get_hash(nonce, passwd) resp = '\r\nAuthorization: Digest response="%s"\r\n' % (response) msg = msg.replace('\r\n', resp, 1) connect_to_proxy(msg, my_socket)
def connect_to_proxy(msg, my_socket, ack=False): ip_server = config_dict['regproxy']['ip'] port = int(config_dict['regproxy']['puerto']) my_socket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1) my_socket.connect((ip_server, port)) my_socket.send(bytes(msg, 'utf-8')) write_log(config_dict, 'Sent to', ip_server, port, msg) if not ack: data = my_socket.recv(1024).decode('utf-8') write_log(config_dict, 'Received from', ip_server, port, data) for code in SipCodeException.codes: if SipCodeException.codes[code] in data: print(SipCodeException.codes[code], 'received') return data
def register(self, msg_recv, ip, port): login, port_uas, expires = check_register(msg_recv) passwd_dict = file2dict(passwdpath) if not login in passwd_dict: raise SipCodeException(404) elif not 'Authorization:' in msg_recv: nonce = str(random.randrange(10**22)) passwd_dict[login]['last_nonce'] = nonce dict2file(passwdpath, passwd_dict) msg = 'SIP/2.0 401 Unauthorized\r\n' msg += 'WWW-Authenticate: Digest nonce="%s"\r\n\r\n' % (nonce) else: nonce = passwd_dict[login]['last_nonce'] passwd = passwd_dict[login]['passwd'] response = get_hash(nonce, passwd) user_response = msg_recv.split('=')[-1].split()[0].strip('"') if user_response != response: raise SipCodeException(401) msg = 'SIP/2.0 200 OK\r\n\r\n' if expires != 0: if login in self.users_dict: raise SipCodeException(409) exp_t = expires + time.time() self.users_dict[login] = {'ip': ip, 'port': port_uas, 'register date': time.time(), 'expires date': exp_t} elif expires == 0: if login in self.users_dict: del self.users_dict[login] self.wfile.write(msg.encode('utf-8')) write_log(config_dict, 'Sent to', ip, port, msg)
def main(): if len(sys.argv) != 4: sys.exit('Usage: python uaclient.py config method option') else: config = sys.argv[1] method = sys.argv[2] option = sys.argv[3] global config_dict config_dict = uaserver.get_tags(config, uaserver.ConfigHandler) return method, option if __name__ == '__main__': methods = {'REGISTER': register, 'INVITE': invite, 'BYE': bye} method, option = main() try: my_socket = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) methods[method](my_socket, option) except KeyError: print('Usage: python uaclient.py config method option') except ConnectionRefusedError: ip_server = config_dict['regproxy']['ip'] port = config_dict['regproxy']['puerto'] error = 'Error: No server listening at %s port %s' % (ip_server, port) write_log(config_dict, error) my_socket.close()
def msg_info(client_address, msg_recv): ip = client_address[0] port = client_address[1] write_log(config_dict, 'Received from', ip, port, msg_recv) return ip, port
data = sent_to_uaserver(msg_recv, self.users_dict) self.wfile.write(bytes(data, 'utf-8')) write_log(config_dict, 'Sent to', ip, port, data) else: raise SipCodeException(403) def main(): if len(sys.argv) != 2: sys.exit('Usage: python3 proxy_registrar.py config') else: config = sys.argv[1] global config_dict, passwdpath, database_path config_dict = uaserver.get_tags(config, uaserver.ConfigHandler, proxy=True) passwdpath = config_dict['database']['passwdpath'] database_path = config_dict['database']['path'] name_server = config_dict['server']['name'] ip = config_dict['server']['ip'] port = int(config_dict['server']['puerto']) return name_server, ip, port if __name__ == '__main__': name_server, ip, port = main() write_log(config_dict, 'Starting') print('Server %s listening at port %s' % (name_server, port)) serv = socketserver.UDPServer((ip, port), SIPPRHandler) serv.serve_forever() write_log(config_dict, 'Finishing\n\r')