From 58ea27703861f9bef56f8881ec435ddd3a6462bf Mon Sep 17 00:00:00 2001 From: Pietro Bertera Date: Wed, 27 Jan 2016 01:36:48 +0100 Subject: [PATCH] ADD: NONE - Custom headers in GUI and #21 --- README.md | 62 ++++++++++++++++++++++++++++++++++++++++++++++++++----- SPLiT.py | 44 ++++++++++++++++++++++----------------- gui.py | 12 +++++++++-- proxy.py | 49 +++++++++++++++++++++++-------------------- 4 files changed, 119 insertions(+), 48 deletions(-) diff --git a/README.md b/README.md index a1b0f7e..884011e 100644 --- a/README.md +++ b/README.md @@ -11,7 +11,7 @@ SPLiT is developed with hackability in mind, the main target is to reproduce SIP - SIP Registrar with challenge authentication - SIP Stateless Proxy or Redirect server mode - SIP UDP only suppport -- SIP custom headers (via CLI only at the moment) +- SIP custom headers - Embedded SIP Multicast Plug&Play provisioining server - Embedded DHCP server with 66 and 67 options support - Embedded HTTP server @@ -107,9 +107,26 @@ On windows (in a cmd.exe prompt): --dhcp-leasesfile=DHCP_LEASESFILE DHCP leases file store -The arguments *--sip-exposedport* and *--sip-exposedip* allows you to configure the *Record-Route* added to the forwarded request. +## General options -## Adding custom headers +* ***-t*** Run the software in terminal mode withouth graphical UI, **default:** run in GUI mode +* ***-d*** Run in debug mode, very verbose, **default:** debug is disabled +* ***-i *** Binds all the service on the local IP **, default: 127.0.0.1 +* ***-l *** Wite the logs into **, **default:** no logfile, logs are sent to stdout + + +## SIP Proxy options + +* ***--sip-redirect*** Act as a SIP redirect: instead forwarding the requests reply with a SIP 302 Moved, the Contact contains the destination URI, **default:** disabled +* ***--sip-port *** Specify the SIP port to use, **default:** 5060 +* ***--sip-log *** Write the SIP log into the file **, **default:** send the messages to stdout +* ***--sip-expires *** Default registration Expires header value, default: 3600 +* ***--sip-password *** SIP password, **default:** *protected* +* ***--sip-exposedip *** IP address to report into the *Record-Route* header, **default:** the local IP address +* ***--sip-exposedport *** SIP port to report into the Record-Route* header, **default:** the local SIP port +* ***--sip-customheader *** Add a custom SIP header to all the request matching the filter defined into this option, see below, **defaut:** none + +### Adding SIP custom headers Using the switch *--sip-customheader* you can add one or more SIP headers to forwarded requests, you can filter on the SIP method and the destination URI. The *--sip-customheader* value is a strig composed by 3 token separated by the *:* character: @@ -118,9 +135,12 @@ The *--sip-customheader* value is a strig composed by 3 token separated by the * - second token must contain a valid regex, the regex is evaluated against the request SIP URI - the third token contains the SIP header (header name + header value) -### Example: +#### Example: - ./SPLiT.py -i 172.16.18.15 -d -t --sip-customheader="INVITE:^.{4,}@.*$:Alert-Info: ;info=alert-external" --sip-customheader="INVITE:^.{3,3}@.*$:Alert-Info: ;info=alert-internal" --sip-customheader="*:.*:X-Forwarded-from: SPLiT Proxy" + ./SPLiT.py -i 172.16.18.15 -d -t \ + --sip-customheader="INVITE:^.{4,}@.*$:Alert-Info: ;info=alert-external" \ + --sip-customheader="INVITE:^.{3,3}@.*$:Alert-Info: ;info=alert-internal" \ + --sip-customheader="*:.*:X-Forwarded-from: SPLiT Proxy" Using this command SPLiT will: @@ -128,6 +148,38 @@ Using this command SPLiT will: - add the custom header *Alert-Info: ;info=alert-internal* only to the *INVITE* requests sent to all the SIP URI with len lesser than 3. - add the custom header *X-Forwarded-from: SPLiT Proxy* to all the requests sent to all the SIP URI +## SIP PnP Server options + +* ***--pnp*** Enable the Plug&Play server, **default:** disabled +* ***--pnp-uri *** Plug&Play provisioning URI, **default:** *http://provisioning.snom.com/{model}/{model}.php?mac={mac}* + +## TFTP Server options + +* ***--tftp*** Enable the TFTP server, **default:** disabled +* ***--tftp-root *** TFTP server root directory: all the file and folders contained in ** will be accessible via TFTP. If an absolute path isn't provided the directory will be resolved starting from the process current path, **default:** *tftp* +* ***--tftp-port *** TFTP server port: the TFTP server will bind to the **** HTTP server root directory: all the file and folders contained in ** will be accessible via HTTP. If an absolute path isn't provided the directory will be resolved starting from the process current path, **default:** *http* +* ***--http-port *** HTTP server port: the HTTP server will bind to the **** Start address, DHCP leases will be assigned starting from **, **default:** none +* ***--dhcp-end *** End address, DHCP leases will be assigned up to the **, **default:** none +* ***--dhcp-subnetmask *** Subnet mask to provided to the DHCP clients, **default:** none +* ***--dhcp-gateway *** Gateway provided to the clients, **default:** none +* ***--dhcp-dns *** DNS server provided to the clients, **default:** none +* ***--dhcp-bcast *** Broadcast address provided to the clients, **default:** none +* ***--dhcp-fileserver *** DHCP option 66 value, **default:** none +* ***--dhcp-filename *** DHCP option 67 value, **default:** none +* ***--dhcp-leasesfile *** DHCP server will save the leases into the file specified by **, **default:** *dhcp_leases.dat* + + + # Screenshots **Main tab:** diff --git a/SPLiT.py b/SPLiT.py index 0e346b6..4916471 100755 --- a/SPLiT.py +++ b/SPLiT.py @@ -63,51 +63,51 @@ opt.add_option('--sip-password', dest='sip_password', type='string', default='protected', help='Authentication password (default: protected)') opt.add_option('--sip-exposedip', dest='sip_exposed_ip', type='string', default=None, - help='Exposed/Public IP to use into the Record-Route header') + help='Exposed/Public IP to use into the Record-Route header, default: the local IP') opt.add_option('--sip-exposedport', dest='sip_exposed_port', type='int', default=None, - help='Exposed/Public port to use into the Record-Route header') - opt.add_option('--sip-customheader', dest='custom_headers', type='string', action='append', default=None, - help='Add a custom SIP header to the forwarded request: :: 0: - self.server.main_logger.debug('Adding custom headers') - for full_header in self.server.options.custom_headers: + if len(self.server.options.sip_custom_headers) > 0: + for full_header in self.server.options.sip_custom_headers: md = rx_request_uri.search(self.data[0]) if md: method = md.group(1) uri = md.group(2) else: - self.server.main_logger.debug("SIP: Received code, ignoring") - return + self.server.main_logger.debug("SIP: Custom headers: received code, ignoring") + return function(self) + conf_header_method = full_header.split(':')[0] - conf_header_uri_r = full_header.split(':')[1] - conf_header_value = ':'.join(full_header.split(':')[2:]) - + try: + conf_header_uri_r = full_header.split(':')[1] + conf_header_value = ':'.join(full_header.split(':')[2:]) + except IndexError: + self.server.main_logger.error("SIP: Invalid custom header value: '%s'" % full_header) + continue + if conf_header_method.upper() == method.upper() or conf_header_method == '*': self.server.main_logger.debug("SIP: Matched custom method '%s' against '%s'" % (conf_header_method, method)) try: match = re.match(conf_header_uri_r, uri) except: self.server.main_logger.error("SIP: Invalid regex: '%s'" % conf_header_uri_r) - match = None - if match: + continue + if match: self.server.main_logger.debug("SIP: Matched custom header regex '%s' against '%s' URI" % (conf_header_uri_r, uri)) self.server.main_logger.debug("SIP: Adding header '%s'" % conf_header_value) self.data.insert(2, conf_header_value) @@ -552,8 +557,8 @@ def processAck(self): @add_headers @is_redirect - def processNonInvite(self): - self.server.main_logger.info("SIP: NonInvite received: %s" % self.data[0]) + def processGenericRequest(self): + self.server.main_logger.info("SIP: Request received: %s" % self.data[0]) origin = self.getOrigin() if len(origin) == 0 or not self.server.registrar.has_key(origin): self.server.main_logger.debug("SIP: Origin not found: %s" % origin) @@ -603,29 +608,29 @@ def processRequest(self): elif rx_ack.search(request_uri): self.processAck() elif rx_bye.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_cancel.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_options.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_message.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_refer.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_prack.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_update.search(request_uri): - self.processNonInvite() + self.processGenericRequest() elif rx_info.search(request_uri): #self.sendResponse("200 0K") - self.processNonInvite() + self.processGenericRequest() elif rx_subscribe.search(request_uri): - self.processNonInvite() + self.processGenericRequest() #self.sendResponse("200 0K") elif rx_publish.search(request_uri): self.sendResponse("200 0K") elif rx_notify.search(request_uri): - self.processNonInvite() + self.processGenericRequest() #self.sendResponse("200 0K") elif rx_code.search(request_uri): self.processCode()