From 586bb9091f7219436f65c8e8d9e10f746f1c9f02 Mon Sep 17 00:00:00 2001 From: "carlos.moura" Date: Wed, 1 Apr 2020 15:57:41 -0300 Subject: [PATCH 1/4] aplying security fix in master --- networkapi/settings.py | 2 +- scripts/docker/netapi.env | 2 ++ 2 files changed, 3 insertions(+), 1 deletion(-) diff --git a/networkapi/settings.py b/networkapi/settings.py index a4770eb4d..c73e1c3e3 100644 --- a/networkapi/settings.py +++ b/networkapi/settings.py @@ -265,7 +265,7 @@ def local_files(path): ADMIN_MEDIA_PREFIX = '/media/' # Make this unique, and don't share it with anybody. -SECRET_KEY = 'ry@zgop%w80_nu83#!tbz)m&7*i@1)d-+ki@5^d#%6-&^216sg' +SECRET_KEY = os.getenv('DJANGO_SECRET_KEY', '') VLAN_CACHE_TIME = None EQUIPMENT_CACHE_TIME = None diff --git a/scripts/docker/netapi.env b/scripts/docker/netapi.env index 7098f307e..81489385d 100644 --- a/scripts/docker/netapi.env +++ b/scripts/docker/netapi.env @@ -37,3 +37,5 @@ NETWORKAPI_LOG_FILE=/tmp/networkapi.log GUNICORN_DAEMONIZED=0 NETWORKAPI_SDN_CTRL=netapi_odl + +DJANGO_SECRET_KEY=ry@zgop%w80_nu83#!tbz)m&7*i@1)d-+ki@5^d#%6-&^216sg From 9a4b507233347a4c9913c2f0e1aa1faab53ec76a Mon Sep 17 00:00:00 2001 From: "carlos.moura" Date: Thu, 9 Apr 2020 18:21:16 -0300 Subject: [PATCH 2/4] adding authapi in authentication process --- networkapi/usuario/models.py | 44 ++++++++++++++++++++++++++++++++++++ 1 file changed, 44 insertions(+) diff --git a/networkapi/usuario/models.py b/networkapi/usuario/models.py index 6d4f26aeb..67a6ce4a5 100644 --- a/networkapi/usuario/models.py +++ b/networkapi/usuario/models.py @@ -17,6 +17,10 @@ import hashlib import logging +import requests +import socket +import tempfile +import os import ldap from django.core.exceptions import MultipleObjectsReturned @@ -219,6 +223,46 @@ def get_enabled_user(self, username, password): except Exception as ERROR: self.log.error(ERROR) + # AuthAPI authentication + try: + use_authapi = convert_string_or_int_to_boolean(get_value('use_authapi')) + + if use_authapi: + + pswd_authapi = Usuario.encode_password(password) + user = Usuario.objects.prefetch_related('grupos').get(user=username, pwd=pswd_authapi, ativo=1) + + authapi_info = dict( + mail=user.email, + password=password, + src=socket.gethostbyname(socket.gethostname()) + ) + + endpoint_ssl_cert = get_value('endpoint_ssl_cert') + ssl_cert = requests.get(endpoint_ssl_cert) + + if ssl_cert.status_code == 200: + + cert = tempfile.NamedTemporaryFile(delete=False) + cert.write(ssl_cert.text) + cert.close() + + response = requests.post(get_value('authapi_url'), json=authapi_info, verify=cert.name) + + os.unlink(cert.name) + + if response.status_code == 200: + return user + self.log.debug('This authentication uses AuthAPI for user \'%s\'' % username) + else: + self.log.debug('Error getting user from AuthAPI. Trying authentication with LDAP') + + else: + self.log.debug('Error getting SSL certificate from \'%s\'' % endpoint_ssl_cert) + + except Exception as ERROR: + self.log.error(ERROR) + try: use_ldap = convert_string_or_int_to_boolean( get_value('use_ldap')) From 68c08414bc30cbe712815bb0cacae10597a4cf37 Mon Sep 17 00:00:00 2001 From: "carlos.moura" Date: Thu, 9 Apr 2020 18:34:54 -0300 Subject: [PATCH 3/4] adding vlan name special character verification and fix PEP8 from files --- networkapi/util/__init__.py | 24 ++++++++++-- networkapi/vlan/models.py | 37 +++++++++++++++++++ .../vlan/resource/NetworkTypeResource.py | 6 +++ .../vlan/resource/VlanAllocateIPv6Resorce.py | 6 +++ .../vlan/resource/VlanAllocateResource.py | 6 +++ networkapi/vlan/resource/VlanEditResource.py | 6 +++ .../vlan/resource/VlanInsertResource.py | 6 +++ networkapi/vlan/resource/VlanResource.py | 6 +++ 8 files changed, 94 insertions(+), 3 deletions(-) diff --git a/networkapi/util/__init__.py b/networkapi/util/__init__.py index ef026004e..091880d53 100644 --- a/networkapi/util/__init__.py +++ b/networkapi/util/__init__.py @@ -221,6 +221,21 @@ def is_valid_string_minsize(param, minsize=None, required=True): return True +def is_valid_vlan_name(vlan_name): + """Checks if the parameter is a valid string for Vlan's name, without special characters and breaklines + @param vlan_name: Value to be validated. + @return True if the parameter hasn't a special character, or False otherwise. + """ + + if vlan_name is None or vlan_name == '': + return False + + regex_for_breakline = re.compile('\r|\n\r|\n') + regex_for_special_characters = re.compile('[@_!#$%^&*()<>?/\\\|}{~:]') + + return False if regex_for_breakline.search(vlan_name) or regex_for_special_characters.search(vlan_name) else True + + def is_valid_boolean_param(param, required=True): """Checks if the parameter is a valid boolean. @@ -286,7 +301,8 @@ def is_valid_uri(param): def is_valid_text(param, required=True): - """Checks if the parameter is a valid field text and should follow the format of [A-Za-z] and special characters hyphen and underline. + """Checks if the parameter is a valid field text and should follow the format of [A-Za-z] + and special characters hyphen and underline. @param param: Value to be validated. @param required: Check if the value can be None @@ -305,7 +321,8 @@ def is_valid_text(param, required=True): def is_valid_pool_identifier_text(param, required=True): - """Checks if the parameter is a valid field text and should follow the format of [A-Za-z] and special characters hyphen and underline. + """Checks if the parameter is a valid field text and should follow the format of [A-Za-z] + and special characters hyphen and underline. @param param: Value to be validated. @param required: Check if the value can be None @@ -324,7 +341,8 @@ def is_valid_pool_identifier_text(param, required=True): def is_valid_option(param): - """Checks if the parameter is a valid field text and 0-9 and should follow the format of [A-Za-z] and special characters hyphen, underline and point. + """Checks if the parameter is a valid field text and 0-9 and should follow the format of [A-Za-z] + and special characters hyphen, underline and point. @param param: Value to be validated. diff --git a/networkapi/vlan/models.py b/networkapi/vlan/models.py index e4eba5e0d..7b6e6c214 100644 --- a/networkapi/vlan/models.py +++ b/networkapi/vlan/models.py @@ -2,6 +2,7 @@ from __future__ import with_statement import logging +import re from _mysql_exceptions import OperationalError from django.core.exceptions import ObjectDoesNotExist @@ -114,6 +115,14 @@ def __init__(self, cause, message=None): VlanError.__init__(self, cause, message) +class VlanNameInvalid(VlanError): + + """Retorna exceção porque o nome da VLAN tem caracter especial ou quebra de linha.""" + + def __init__(self, cause, message=None): + VlanError.__init__(self, cause, message) + + class VlanACLDuplicatedError(VlanError): """Retorna exceção porque já existe uma VLAN cadastrada com o mesmo nome de arquivo ACL.""" @@ -405,6 +414,16 @@ def search_vlan_numbers(self, environment_id, min_num, max_num): self.log.error(u'Failure to search the Vlans.') raise VlanError(e, u'Failure to search the Vlans.') + def valid_vlan_name(self, name): + + if name is None or name == '': + return False + + regex_for_breakline = re.compile('\r|\n\r|\n') + regex_for_special_characters = re.compile('[@_!#$%^&*()<>?/\\\|}{~:]') + + return False if regex_for_breakline.search(name) or regex_for_special_characters.search(name) else True + def search(self, environment_id=None): try: v = Vlan.objects.all() @@ -567,6 +586,11 @@ def create_new(self, authenticated_user, min_num_01, max_num_01, min_num_02, max @return: nothing """ + + # Validate Name VLAN + if not self.valid_vlan_name(self.nome): + raise VlanNameInvalid(None, 'Name VLAN can not have special characters or breakline.') + if self.nome is not None: self.nome = self.nome.upper() @@ -626,6 +650,11 @@ def create(self, authenticated_user, min_num_01, max_num_01, min_num_02, max_num @raise VlanError: Erro não esperado ao executar o save. """ + + # Validate Name VLAN + if not self.valid_vlan_name(self.nome): + raise VlanNameInvalid(None, 'Name VLAN can not have special characters or breakline.') + if self.nome is not None: self.nome = self.nome.upper() @@ -804,6 +833,10 @@ def insert_vlan(self, authenticated_user): raise VlanNameDuplicatedError( None, 'Name VLAN can not be duplicated in the environment.') + # Validate Name VLAN + if not self.valid_vlan_name(self.nome): + raise VlanNameInvalid(None, 'Name VLAN can not have special characters or breakline.') + try: return self.save() @@ -1010,6 +1043,10 @@ def validate_v3(self): self.log.error(msg) raise VlanErrorV3(msg) + if not self.valid_vlan_name(self.nome): + msg = 'Name VLAN can not have special characters or breakline.' + raise VlanErrorV3(msg) + # Validate Number of vlan in environment related equips = self.get_eqpt() diff --git a/networkapi/vlan/resource/NetworkTypeResource.py b/networkapi/vlan/resource/NetworkTypeResource.py index 998c8e8ed..ee58042d8 100644 --- a/networkapi/vlan/resource/NetworkTypeResource.py +++ b/networkapi/vlan/resource/NetworkTypeResource.py @@ -30,6 +30,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import NetTypeUsedByNetworkError from networkapi.vlan.models import NetworkTypeNameDuplicatedError from networkapi.vlan.models import NetworkTypeNotFoundError @@ -108,6 +109,11 @@ def handle_post(self, request, user, *args, **kwargs): net_type = TipoRede(tipo_rede=name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + try: TipoRede.get_by_name(net_type.tipo_rede) raise NetworkTypeNameDuplicatedError( diff --git a/networkapi/vlan/resource/VlanAllocateIPv6Resorce.py b/networkapi/vlan/resource/VlanAllocateIPv6Resorce.py index 26c3bc613..18e0cd7f6 100644 --- a/networkapi/vlan/resource/VlanAllocateIPv6Resorce.py +++ b/networkapi/vlan/resource/VlanAllocateIPv6Resorce.py @@ -37,6 +37,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import NetworkTypeNotFoundError from networkapi.vlan.models import TipoRede from networkapi.vlan.models import Vlan @@ -90,6 +91,11 @@ def handle_post(self, request, user, *args, **kwargs): self.log.error(u'Parameter name is invalid. Value: %s.', name) raise InvalidValueError(None, 'name', name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + # Description can NOT be greater than 200 if not is_valid_string_minsize(description, 3, False) or not is_valid_string_maxsize(description, 200, False): self.log.error( diff --git a/networkapi/vlan/resource/VlanAllocateResource.py b/networkapi/vlan/resource/VlanAllocateResource.py index 0aa228a36..d301ddbad 100644 --- a/networkapi/vlan/resource/VlanAllocateResource.py +++ b/networkapi/vlan/resource/VlanAllocateResource.py @@ -36,6 +36,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import Vlan from networkapi.vlan.models import VlanError from networkapi.vlan.models import VlanNameDuplicatedError @@ -92,6 +93,11 @@ def handle_post(self, request, user, *args, **kwargs): self.log.error(u'Parameter name is invalid. Value: %s.', name) raise InvalidValueError(None, 'name', name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + # Description can NOT be greater than 200 if not is_valid_string_minsize(description, 3, False) or not is_valid_string_maxsize(description, 200, False): self.log.error( diff --git a/networkapi/vlan/resource/VlanEditResource.py b/networkapi/vlan/resource/VlanEditResource.py index 80060f227..4b62bd9ec 100644 --- a/networkapi/vlan/resource/VlanEditResource.py +++ b/networkapi/vlan/resource/VlanEditResource.py @@ -38,6 +38,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import Vlan from networkapi.vlan.models import VlanACLDuplicatedError from networkapi.vlan.models import VlanError @@ -118,6 +119,11 @@ def handle_post(self, request, user, *args, **kwargs): self.log.error(u'Parameter name is invalid. Value: %s', name) raise InvalidValueError(None, 'name', name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + p = re.compile('^[A-Z0-9-_]+$') m = p.match(name) diff --git a/networkapi/vlan/resource/VlanInsertResource.py b/networkapi/vlan/resource/VlanInsertResource.py index c82da3895..09c5971c6 100644 --- a/networkapi/vlan/resource/VlanInsertResource.py +++ b/networkapi/vlan/resource/VlanInsertResource.py @@ -42,6 +42,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import Vlan from networkapi.vlan.models import VlanACLDuplicatedError from networkapi.vlan.models import VlanError @@ -117,6 +118,11 @@ def handle_post(self, request, user, *args, **kwargs): self.log.error(u'Parameter name is invalid. Value: %s', name) raise InvalidValueError(None, 'name', name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + if not network_ipv4 or not str(network_ipv4).isdigit(): self.log.error( u'Parameter network_ipv4 is invalid. Value: %s.', network_ipv4) diff --git a/networkapi/vlan/resource/VlanResource.py b/networkapi/vlan/resource/VlanResource.py index 6045edaa6..7bfa64dac 100644 --- a/networkapi/vlan/resource/VlanResource.py +++ b/networkapi/vlan/resource/VlanResource.py @@ -49,6 +49,7 @@ from networkapi.util import is_valid_int_greater_zero_param from networkapi.util import is_valid_string_maxsize from networkapi.util import is_valid_string_minsize +from networkapi.util import is_valid_vlan_name from networkapi.vlan.models import NetworkTypeNotFoundError from networkapi.vlan.models import TipoRede from networkapi.vlan.models import Vlan @@ -114,6 +115,11 @@ def handle_post(self, request, user, *args, **kwargs): self.log.error(u'Parameter nome is invalid. Value: %s.', name) raise InvalidValueError(None, 'nome', name) + if not is_valid_vlan_name(name): + self.log.error( + u'Parameter %s is invalid because is using special characters and/or breaklines.', name) + raise InvalidValueError(None, 'name', name) + # Description can NOT be greater than 200 if not is_valid_string_minsize(description, 3, False) or not is_valid_string_maxsize(description, 200, False): self.log.error( From c48e68816f5a71a88be5d0003a1e240cd22f628e Mon Sep 17 00:00:00 2001 From: "carlos.moura" Date: Tue, 28 Apr 2020 18:18:54 -0300 Subject: [PATCH 4/4] allow underscore in vlan name --- networkapi/util/__init__.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/networkapi/util/__init__.py b/networkapi/util/__init__.py index 091880d53..8e92c5d3a 100644 --- a/networkapi/util/__init__.py +++ b/networkapi/util/__init__.py @@ -231,7 +231,7 @@ def is_valid_vlan_name(vlan_name): return False regex_for_breakline = re.compile('\r|\n\r|\n') - regex_for_special_characters = re.compile('[@_!#$%^&*()<>?/\\\|}{~:]') + regex_for_special_characters = re.compile('[@!#$%^&*()<>?/\\\|}{~:]') return False if regex_for_breakline.search(vlan_name) or regex_for_special_characters.search(vlan_name) else True