From 616300decb4ea9b8731536c7400f35ab8dbd4f37 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Adolfo=20G=C3=B3mez?= Date: Tue, 16 Apr 2013 10:05:42 +0000 Subject: [PATCH] * Added all network recognition cases * Added test to network recognition (should have started to do Unit tests a long ago, but... :-) ) --- .../org.eclipse.core.resources.prefs | 3 + server/src/uds/core/auths/auth.py | 2 +- server/src/uds/core/util/net.py | 57 +++++++++++--- server/src/uds/tests/__init__.py | 34 ++++++++ server/src/uds/tests/core/__init__.py | 34 ++++++++ server/src/uds/tests/core/util/__init__.py | 1 + server/src/uds/tests/core/util/net.py | 78 +++++++++++++++++++ 7 files changed, 199 insertions(+), 10 deletions(-) create mode 100644 server/src/uds/tests/__init__.py create mode 100644 server/src/uds/tests/core/__init__.py create mode 100644 server/src/uds/tests/core/util/__init__.py create mode 100644 server/src/uds/tests/core/util/net.py diff --git a/server/.settings/org.eclipse.core.resources.prefs b/server/.settings/org.eclipse.core.resources.prefs index 744e22b0b..281fb3509 100644 --- a/server/.settings/org.eclipse.core.resources.prefs +++ b/server/.settings/org.eclipse.core.resources.prefs @@ -171,6 +171,9 @@ encoding//src/uds/services/Vmware_enterprise/client/Exceptions.py=utf-8 encoding//src/uds/services/Vmware_enterprise/client/Server.py=utf-8 encoding//src/uds/services/Vmware_enterprise/client/Task.py=utf-8 encoding//src/uds/services/__init__.py=utf-8 +encoding//src/uds/tests/__init__.py=utf-8 +encoding//src/uds/tests/core/__init__.py=utf-8 +encoding//src/uds/tests/core/util/net.py=utf-8 encoding//src/uds/transports/HTML5RDP/HTML5RDP.py=utf-8 encoding//src/uds/transports/HTML5RDP/__init__.py=utf-8 encoding//src/uds/transports/NX/NXTransport.py=utf-8 diff --git a/server/src/uds/core/auths/auth.py b/server/src/uds/core/auths/auth.py index ab6d7fd6f..4d60bcc89 100644 --- a/server/src/uds/core/auths/auth.py +++ b/server/src/uds/core/auths/auth.py @@ -189,7 +189,7 @@ def authInfoUrl(authenticator): Helper method, so we can get the info url for an authenticator ''' from django.core.urlresolvers import reverse - if type(authenticator) is str: + if isinstance(authenticator,unicode) or isinstance(authenticator, str): name = authenticator else: name = authenticator.name diff --git a/server/src/uds/core/util/net.py b/server/src/uds/core/util/net.py index f0c99e6d4..a40f4a62f 100644 --- a/server/src/uds/core/util/net.py +++ b/server/src/uds/core/util/net.py @@ -39,8 +39,8 @@ from exceptions import ValueError reCIDR = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})/([0-9]{1,2})$') reMask = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})netmask([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$') re1Asterisk = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.\*$') -re2Asterisk = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.\*(\.\*)?$') -re3Asterisk = re.compile('^([0-9]{1,3})\.\*(\.\*)?(\.\*)?$') +re2Asterisk = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.\*\.?\*?$') +re3Asterisk = re.compile('^([0-9]{1,3})\.\*\.?\*?\.?\*?$') reRange = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})-([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$') reHost = re.compile('^([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})\.([0-9]{1,3})$') @@ -84,6 +84,9 @@ def networksFromString(strNets, allowMultipleNetworks = True): If allowMultipleNetworks is True, it allows ',' and ';' separators (and, ofc, more than 1 network) Returns a list of networks tuples in the form [(start1, end1), (start2, end2) ...] ''' + + inputString = strNets + def check(*args): for n in args: if int(n) < 0 or int(n) > 255: @@ -103,14 +106,18 @@ def networksFromString(strNets, allowMultipleNetworks = True): v |= 1<<(31-n) return v - nets = strNets.replace(' ', '') if allowMultipleNetworks is True: res = [] - for strNet in re.split('[;,]',nets): + for strNet in re.split('[;,]', strNets): if strNet != '': res.append(networksFromString(strNet, False)) return res + strNets = strNets.replace(' ', '') + + if strNets == '*': + return (0, 4294967295) + try: # Test patterns m = reCIDR.match(strNets) @@ -127,16 +134,48 @@ def networksFromString(strNets, allowMultipleNetworks = True): m = reMask.match(strNets) if m is not None: check(*m.groups()) - val = toNum(*(m.group(i+1) for i in xrange(4))) - bits = toNum(*(m.group(i+5) for i in xrange(4))) + val = toNum(*(m.groups()[0:4])) + bits = toNum(*(m.groups()[4:8])) noBits = ~bits & 0xffffffff return (val&bits, val|noBits) + + m = reRange.match(strNets) + if m is not None: + check(*m.groups()) + val = toNum(*(m.groups()[0:4])) + val2 = toNum(*(m.groups()[4:8])) + if val2 < val: + raise Exception() + return (val, val2) + + m = reHost.match(strNets) + if m is not None: + check(*m.groups()) + val = toNum(*m.groups()) + return (val, val) + + for v in ((re1Asterisk, 3), (re2Asterisk, 2), (re3Asterisk, 1)): + m = v[0].match(strNets) + if m is not None: + check(*m.groups()) + val = toNum(*(m.groups()[0:v[1]+1])) + bits = maskFromBits(v[1]*8) + noBits = ~bits & 0xffffffff + return (val&bits, val|noBits) # No pattern recognized, invalid network raise Exception() except: - raise ValueError(nets) - + raise ValueError(inputString) - \ No newline at end of file +def ipInNetwork(ip, network): + if isinstance(ip,unicode) or isinstance(ip,str): + ip = ipToLong(ip) + if isinstance(network,unicode) or isinstance(network,str): + network = networksFromString(network) + + for net in network: + if ip >= net[0] and ip <= net[1]: + return True + return False diff --git a/server/src/uds/tests/__init__.py b/server/src/uds/tests/__init__.py new file mode 100644 index 000000000..ee97ef2d1 --- /dev/null +++ b/server/src/uds/tests/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2012 Virtual Cable S.L. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Virtual Cable S.L. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +''' +.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com +''' + +from core import * \ No newline at end of file diff --git a/server/src/uds/tests/core/__init__.py b/server/src/uds/tests/core/__init__.py new file mode 100644 index 000000000..3b4f48a14 --- /dev/null +++ b/server/src/uds/tests/core/__init__.py @@ -0,0 +1,34 @@ +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2012 Virtual Cable S.L. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Virtual Cable S.L. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + +''' +.. moduleauthor:: Adolfo Gómez, dkmaster at dkmon dot com +''' + +from util import * \ No newline at end of file diff --git a/server/src/uds/tests/core/util/__init__.py b/server/src/uds/tests/core/util/__init__.py new file mode 100644 index 000000000..1355a713f --- /dev/null +++ b/server/src/uds/tests/core/util/__init__.py @@ -0,0 +1 @@ +from net import * \ No newline at end of file diff --git a/server/src/uds/tests/core/util/net.py b/server/src/uds/tests/core/util/net.py new file mode 100644 index 000000000..13c5e48ff --- /dev/null +++ b/server/src/uds/tests/core/util/net.py @@ -0,0 +1,78 @@ +# -*- coding: utf-8 -*- + +# +# Copyright (c) 2012 Virtual Cable S.L. +# All rights reserved. +# +# Redistribution and use in source and binary forms, with or without modification, +# are permitted provided that the following conditions are met: +# +# * Redistributions of source code must retain the above copyright notice, +# this list of conditions and the following disclaimer. +# * Redistributions in binary form must reproduce the above copyright notice, +# this list of conditions and the following disclaimer in the documentation +# and/or other materials provided with the distribution. +# * Neither the name of Virtual Cable S.L. nor the names of its contributors +# may be used to endorse or promote products derived from this software +# without specific prior written permission. +# +# THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS "AS IS" +# AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE +# IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE +# DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT HOLDER OR CONTRIBUTORS BE LIABLE +# FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL +# DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR +# SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER +# CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, +# OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE +# OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + + +''' +@author: Adolfo Gómez, dkmaster at dkmon dot com +''' + +from __future__ import unicode_literals + +from django.utils import unittest +import uds.core.util.net + +class NetTestCase(unittest.TestCase): + + def testNetworkFromString(self): + for n in ( ('*', 0, 4294967295), + ('192.168.0.1', 3232235521, 3232235521), + ('192.168.0.*', 3232235520, 3232235775), + ('192.168.*.*', 3232235520, 3232301055), + ('192.168.*', 3232235520, 3232301055), + ('192.*.*.*', 3221225472, 3238002687), + ('192.*.*', 3221225472, 3238002687), + ('192.*', 3221225472, 3238002687), + ('192.168.0.1 netmask 255.255.255.0', 3232235520, 3232235775), + ('192.168.0.1/8', 3221225472, 3238002687), + ('192.168.0.1/28', 3232235520, 3232235535), + ('192.168.0.1-192.168.0.87', 3232235521, 3232235607), + ('192.168.0.1 netmask 255.255.255.0', 3232235520, 3232235775), + ): + try: + nets = uds.core.util.net.networksFromString(n[0]) + self.assertEqual(len(nets), 1, 'Incorrect number of network returned from {0}'.format(n[0])) + self.assertEquals(nets[0][0], n[1], 'Incorrect network start value for {0}'.format(n[0])) + self.assertEquals(nets[0][1], n[2], 'Incorrect network end value for {0}'.format(n[0])) + + nets = uds.core.util.net.networksFromString(n[0],False) + self.assertEqual(len(nets), 2, 'Incorrect number of network returned from {0}'.format(n[0])) + self.assertEquals(nets[0], n[1], 'Incorrect network start value for {0}'.format(n[0])) + self.assertEquals(nets[1], n[2], 'Incorrect network end value for {0}'.format(n[0])) + except Exception as e: + raise Exception('Value Error: ' + str(e) + '. Input string: ' + n[0]) + + + for n in ('192.168.0', '192.168.0.5-192.168.0.3', 'no net'): + with self.assertRaises(uds.core.util.net.ValueError): + uds.core.util.net.networksFromString(n) + + self.assertEquals(True, uds.core.util.net.ipInNetwork('192.168.0.5', '192.168.0.0/24')) + self.assertEquals(True, uds.core.util.net.ipInNetwork(1000, [(0, 4294967295)])) + +