if type(cinfo) != DictType: raise ValueError dirkeys = {} for y in cinfo.values(): if not y[1]: continue if not x['allowed'].has_key(y[1]): raise ValueError if dirkeys.has_key(y[1]): raise ValueError dirkeys[y[1]] = 1 alas = 'your file may exist elsewhere in the universe\nbut alas, not here\n' local_IPs = IP_List() local_IPs.set_intranet_addresses() def isotime(secs = None): if secs == None: secs = time() return strftime('%Y-%m-%d %H:%M UTC', gmtime(secs)) http_via_filter = re.compile(' for ([0-9.]+)\\Z') def _get_forwarded_ip(headers): if headers.has_key('http_x_forwarded_for'): header = headers['http_x_forwarded_for'] try: x, y = header.split(',') except:
class UPnPPlatformIndependent: def __init__(self): self.services = {} self.lastdiscovertime = 0 self.local_ip_list = IP_List() self.local_ip_list.set_intranet_addresses() def discover(self): maxwait = 4 req = "M-SEARCH * HTTP/1.1\r\n" req += "HOST: 239.255.255.250:1900\r\n" req += 'MAN: "ssdp:discover"\r\n' req += "MX: " + str(maxwait) + "\r\n" req += "ST: ssdp:all\r\n" req += "\r\n\r\n" try: self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.s.settimeout(maxwait + 2.0) self.s.sendto(req, ("239.255.255.250", 1900)) while True: if DEBUG: print >>sys.stderr, "upnp: discover: Wait 4 reply" rep, sender = self.s.recvfrom(1024) if DEBUG: print >>sys.stderr, "upnp: discover: Got reply from", sender repio = StringIO(rep) while True: line = repio.readline() if line == "": break if line[-2:] == "\r\n": line = line[:-2] idx = line.find(":") if idx == -1: continue key = line[:idx] key = key.lower() if key.startswith("location"): location = line[idx + 1 :].strip() desc = self.get_description(location) if desc is not None: self.services[location] = self.parse_services(desc) except: if DEBUG: print_exc() def found_wanted_services(self): for location, services in self.services.iteritems(): for service in services: if service["type"] in UPNP_WANTED_SERVICETYPES: return True return False def add_port_map(self, internalip, port, iproto="TCP"): success = False ret = self.do_soap_request("AddPortMapping", port, iproto=iproto, internalip=internalip) for srch in ret: se = srch.get_error() if se is None: success = True elif DEBUG: log("upnp::add_port_map: error:", str(se)) if not success: raise Exception, "Failed to map port" def del_port_map(self, port, iproto="TCP"): success = False ret = self.do_soap_request("DeletePortMapping", port, iproto=iproto) for srch in ret: se = srch.get_error() if se is None: success = True elif DEBUG: log("upnp::del_port_map: error:", str(se)) if not success: raise Exception, "Failed to delete port mapping" def get_ext_ip(self): ext_ip_list = [] ret = self.do_soap_request("GetExternalIPAddress") for srch in ret: se = srch.get_error() if se is None: ip = srch.get_ext_ip() if self.is_valid_ext_ip(ip): if DEBUG: log("upnp::get_ext_ip: add ip to the list:", ip) ext_ip_list.append(ip) elif DEBUG: log("upnp::get_ext_ip: not a valid ip, ignore:", ip) elif DEBUG: log("upnp::get_ext_ip: error:", str(se)) return ext_ip_list def is_valid_ext_ip(self, ip): if ip is None: return False elif not isinstance(ip, (str, unicode)): return False elif len(ip) == 0: return False elif ip == "0.0.0.0": return False elif self.local_ip_list.includes(ip): return False else: return True def do_soap_request(self, methodname, port=-1, iproto="TCP", internalip=None): for location, services in self.services.iteritems(): for service in services: if service["type"] in UPNP_WANTED_SERVICETYPES: o = urlparse(location) endpoint = o[0] + "://" + o[1] + service["url"] if DEBUG: log( "upnp::do_soap_request: methodname", methodname, "endpoint", endpoint, "port", port, "iproto", iproto, "internalip", internalip, ) headers, body = self.create_soap_request(methodname, port, iproto=iproto, internalip=internalip) if DEBUG: log("upnp::do_soap_request: headers", headers) log("upnp::do_soap_request: body", body) try: req = urllib2.Request(url=endpoint, data=body, headers=headers) f = urllib2.urlopen(req) resp = f.read() except urllib2.HTTPError as e: resp = e.fp.read() if DEBUG: print_exc() srch = SOAPResponseContentHandler(methodname) if DEBUG: log("upnp::do_soap_request: method", methodname, "response", resp) try: srch.parse(resp) except sax.SAXParseException as e: se = srch.get_error() if se is None: srch.set_error(str(e)) except Exception as e: srch.set_error(str(e)) yield srch def get_description(self, url): if DEBUG: log("upnp::get_description: url", url) try: f = urllib2.urlopen(url, timeout=5.0) data = f.read() return data except: if DEBUG: print_exc() return None def parse_services(self, desc): dch = DescriptionContentHandler() dch.parse(desc) return dch.services def create_soap_request(self, methodname, port=-1, iproto="TCP", internalip=None): headers = {} headers["Content-type"] = 'text/xml; charset="utf-8"' headers["SOAPAction"] = '"urn:schemas-upnp-org:service:WANIPConnection:1#' + methodname + '"' headers["User-Agent"] = "Mozilla/4.0 (compatible; UPnP/1.0; Windows 9x)" body = "" body += '<?xml version="1.0"?>' body += '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"' body += ' SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' body += "<SOAP-ENV:Body><m:" + methodname + ' xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1">' if methodname == "AddPortMapping": externalport = port internalport = port internalclient = internalip description = "TSEngine " + iproto + " at " + internalip + ":" + str(internalport) body += '<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>' body += ( '<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str(externalport) + "</NewExternalPort>" ) body += ( '<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + iproto + "</NewProtocol>" ) body += ( '<NewInternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str(internalport) + "</NewInternalPort>" ) body += ( '<NewInternalClient xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + internalclient + "</NewInternalClient>" ) body += '<NewEnabled xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="boolean">1</NewEnabled>' body += ( '<NewPortMappingDescription xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + description + "</NewPortMappingDescription>" ) body += '<NewLeaseDuration xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui4">0</NewLeaseDuration>' elif methodname == "DeletePortMapping": externalport = port body += '<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>' body += ( '<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str(externalport) + "</NewExternalPort>" ) body += ( '<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + iproto + "</NewProtocol>" ) body += "</m:" + methodname + "></SOAP-ENV:Body>" body += "</SOAP-ENV:Envelope>" return (headers, body)
if type(cinfo) != DictType: raise ValueError dirkeys = {} for y in cinfo.values(): if not y[1]: continue if not x['allowed'].has_key(y[1]): raise ValueError if dirkeys.has_key(y[1]): raise ValueError dirkeys[y[1]] = 1 alas = 'your file may exist elsewhere in the universe\nbut alas, not here\n' local_IPs = IP_List() local_IPs.set_intranet_addresses() def isotime(secs=None): if secs == None: secs = time() return strftime('%Y-%m-%d %H:%M UTC', gmtime(secs)) http_via_filter = re.compile(' for ([0-9.]+)\\Z') def _get_forwarded_ip(headers): if headers.has_key('http_x_forwarded_for'): header = headers['http_x_forwarded_for'] try:
class UPnPPlatformIndependent: def __init__(self): self.services = {} self.lastdiscovertime = 0 self.local_ip_list = IP_List() self.local_ip_list.set_intranet_addresses() def discover(self): maxwait = 4 req = 'M-SEARCH * HTTP/1.1\r\n' req += 'HOST: 239.255.255.250:1900\r\n' req += 'MAN: "ssdp:discover"\r\n' req += 'MX: ' + str(maxwait) + '\r\n' req += 'ST: ssdp:all\r\n' req += '\r\n\r\n' try: self.s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) self.s.settimeout(maxwait + 2.0) self.s.sendto(req, ('239.255.255.250', 1900)) while True: if DEBUG: print >> sys.stderr, 'upnp: discover: Wait 4 reply' rep, sender = self.s.recvfrom(1024) if DEBUG: print >> sys.stderr, 'upnp: discover: Got reply from', sender repio = StringIO(rep) while True: line = repio.readline() if line == '': break if line[-2:] == '\r\n': line = line[:-2] idx = line.find(':') if idx == -1: continue key = line[:idx] key = key.lower() if key.startswith('location'): location = line[idx + 1:].strip() desc = self.get_description(location) if desc is not None: self.services[location] = self.parse_services(desc) except: if DEBUG: print_exc() def found_wanted_services(self): for location, services in self.services.iteritems(): for service in services: if service['type'] in UPNP_WANTED_SERVICETYPES: return True return False def add_port_map(self, internalip, port, iproto='TCP'): success = False ret = self.do_soap_request('AddPortMapping', port, iproto=iproto, internalip=internalip) for srch in ret: se = srch.get_error() if se is None: success = True elif DEBUG: log('upnp::add_port_map: error:', str(se)) if not success: raise Exception, 'Failed to map port' def del_port_map(self, port, iproto='TCP'): success = False ret = self.do_soap_request('DeletePortMapping', port, iproto=iproto) for srch in ret: se = srch.get_error() if se is None: success = True elif DEBUG: log('upnp::del_port_map: error:', str(se)) if not success: raise Exception, 'Failed to delete port mapping' def get_ext_ip(self): ext_ip_list = [] ret = self.do_soap_request('GetExternalIPAddress') for srch in ret: se = srch.get_error() if se is None: ip = srch.get_ext_ip() if self.is_valid_ext_ip(ip): if DEBUG: log('upnp::get_ext_ip: add ip to the list:', ip) ext_ip_list.append(ip) elif DEBUG: log('upnp::get_ext_ip: not a valid ip, ignore:', ip) elif DEBUG: log('upnp::get_ext_ip: error:', str(se)) return ext_ip_list def is_valid_ext_ip(self, ip): if ip is None: return False elif not isinstance(ip, (str, unicode)): return False elif len(ip) == 0: return False elif ip == '0.0.0.0': return False elif self.local_ip_list.includes(ip): return False else: return True def do_soap_request(self, methodname, port=-1, iproto='TCP', internalip=None): for location, services in self.services.iteritems(): for service in services: if service['type'] in UPNP_WANTED_SERVICETYPES: o = urlparse(location) endpoint = o[0] + '://' + o[1] + service['url'] if DEBUG: log('upnp::do_soap_request: methodname', methodname, 'endpoint', endpoint, 'port', port, 'iproto', iproto, 'internalip', internalip) headers, body = self.create_soap_request( methodname, port, iproto=iproto, internalip=internalip) if DEBUG: log('upnp::do_soap_request: headers', headers) log('upnp::do_soap_request: body', body) try: req = urllib2.Request(url=endpoint, data=body, headers=headers) f = urllib2.urlopen(req) resp = f.read() except urllib2.HTTPError as e: resp = e.fp.read() if DEBUG: print_exc() srch = SOAPResponseContentHandler(methodname) if DEBUG: log('upnp::do_soap_request: method', methodname, 'response', resp) try: srch.parse(resp) except sax.SAXParseException as e: se = srch.get_error() if se is None: srch.set_error(str(e)) except Exception as e: srch.set_error(str(e)) yield srch def get_description(self, url): if DEBUG: log('upnp::get_description: url', url) try: f = urllib2.urlopen(url, timeout=5.0) data = f.read() return data except: if DEBUG: print_exc() return None def parse_services(self, desc): dch = DescriptionContentHandler() dch.parse(desc) return dch.services def create_soap_request(self, methodname, port=-1, iproto='TCP', internalip=None): headers = {} headers['Content-type'] = 'text/xml; charset="utf-8"' headers[ 'SOAPAction'] = '"urn:schemas-upnp-org:service:WANIPConnection:1#' + methodname + '"' headers[ 'User-Agent'] = 'Mozilla/4.0 (compatible; UPnP/1.0; Windows 9x)' body = '' body += '<?xml version="1.0"?>' body += '<SOAP-ENV:Envelope xmlns:SOAP-ENV="http://schemas.xmlsoap.org/soap/envelope/"' body += ' SOAP-ENV:encodingStyle="http://schemas.xmlsoap.org/soap/encoding/">' body += '<SOAP-ENV:Body><m:' + methodname + ' xmlns:m="urn:schemas-upnp-org:service:WANIPConnection:1">' if methodname == 'AddPortMapping': externalport = port internalport = port internalclient = internalip description = 'TSEngine ' + iproto + ' at ' + internalip + ':' + str( internalport) body += '<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>' body += '<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str( externalport) + '</NewExternalPort>' body += '<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + iproto + '</NewProtocol>' body += '<NewInternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str( internalport) + '</NewInternalPort>' body += '<NewInternalClient xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + internalclient + '</NewInternalClient>' body += '<NewEnabled xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="boolean">1</NewEnabled>' body += '<NewPortMappingDescription xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + description + '</NewPortMappingDescription>' body += '<NewLeaseDuration xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui4">0</NewLeaseDuration>' elif methodname == 'DeletePortMapping': externalport = port body += '<NewRemoteHost xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string"></NewRemoteHost>' body += '<NewExternalPort xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="ui2">' + str( externalport) + '</NewExternalPort>' body += '<NewProtocol xmlns:dt="urn:schemas-microsoft-com:datatypes" dt:dt="string">' + iproto + '</NewProtocol>' body += '</m:' + methodname + '></SOAP-ENV:Body>' body += '</SOAP-ENV:Envelope>' return (headers, body)