Beispiel #1
0
            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:
Beispiel #2
0
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)
Beispiel #3
0
            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:
Beispiel #4
0
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)