1
0
mirror of https://github.com/dkmstr/openuds.git synced 2025-03-12 04:58:34 +03:00

upgraded regexldap and saml field processor to admit:

* : as a "prependable" to the attribute value
* +, to join several fields (must be fields with 0 o 1 elements only) into an single value
This commit is contained in:
Adolfo Gómez García 2023-06-13 17:11:39 +02:00
parent 70c8a296ca
commit 7fd2d1162d
No known key found for this signature in database
GPG Key ID: DD1ABF20724CDA23
2 changed files with 63 additions and 11 deletions

View File

@ -282,14 +282,46 @@ class RegexLdap(auths.Authenticator):
attr = line[:equalPos]
else:
attr = line
res.append(attr)
# If + is present, we must split it
if '+' in attr:
for a in attr.split('+'):
if a not in res:
res.append(a)
elif ':' in attr:
res.append(attr.split(':')[0])
else:
if attr not in res:
res.append(attr)
return res
def __processField(
self, field: str, attributes: typing.MutableMapping[str, typing.Any]
) -> typing.List[str]:
res: typing.List[str] = []
logger.debug('Attributes: %s', attributes)
def getAttr(attrName: str) -> typing.List[str]:
def asList(val: typing.Any) -> typing.List[str]:
if isinstance(val, list):
return val
return [val]
if '+' in attrName:
attrList = attrName.split('+')
# Check all attributes are present, and has only one value
if not all([len(attributes.get(a, [])) <= 1 for a in attrList]):
logger.warning('Attribute %s do not has exactly one value, skipping %s', attrName, line)
return []
val = [''.join([asList(attributes.get(a, ['']))[0] for a in attrList])]
elif ':' in attrName:
# Prepend the value after : to value before :
attr, prependable = attrName.split(':')
val = [prependable + a for a in asList(attributes.get(attr, []))]
else:
val = asList(attributes.get(attrName, []))
return val
logger.debug('******** Attributes: %s', attributes)
for line in field.splitlines():
equalPos = line.find('=')
if (
@ -301,15 +333,13 @@ class RegexLdap(auths.Authenticator):
# if pattern do not have groups, define one with complete pattern (i.e. id=.* --> id=(.*))
if pattern.find('(') == -1:
pattern = '(' + pattern + ')'
val = attributes.get(attr, [])
if not isinstance(val, list): # May we have a single value
val = [val]
val = getAttr(attr)
logger.debug('Pattern: %s', pattern)
for v in val:
try:
logger.debug('Pattern: %s on value %s', pattern, v)
searchResult = re.search(
pattern, v, re.IGNORECASE
) # @UndefinedVariable
@ -317,7 +347,7 @@ class RegexLdap(auths.Authenticator):
continue
logger.debug("Found against %s: %s ", v, searchResult.groups())
res.append(''.join(searchResult.groups()))
except Exception: # nosec
except Exception: # nosec: If not a valid regex, just ignore it
pass # Ignore exceptions here
logger.debug('Res: %s', res)
return res
@ -343,12 +373,14 @@ class RegexLdap(auths.Authenticator):
'userNameAttr': self._userNameAttr,
'altClass': self._altClass,
'mfaAttr': self._mfaAttr,
'verifySsl': gui.fromBool(self._verifySsl),
'certificate': self._certificate,
}
def marshal(self) -> bytes:
return '\t'.join(
[
'v4',
'v5',
self._host,
self._port,
gui.fromBool(self._ssl),

View File

@ -546,6 +546,24 @@ class SAMLAuthenticator(auths.Authenticator):
def processField(self, field: str, attributes: typing.Dict[str, typing.List]) -> typing.List[str]:
res = []
def getAttr(attrName: str) -> typing.List[str]:
if '+' in attrName:
attrList = attrName.split('+')
# Check all attributes are present, and has only one value
if not all([len(attributes.get(a, [])) <= 1 for a in attrList]):
logger.warning('Attribute %s do not has exactly one value, skipping %s', attrName, line)
return []
val = [''.join([attributes.get(a, [''])[0] for a in attrList])]
elif ':' in attrName:
# Prepend the value after : to value before :
attr, prependable = attrName.split(':')
val = [prependable + a for a in attributes.get(attr, [])]
else:
val = attributes.get(attrName, [])
return val
for line in field.splitlines():
equalPos = line.find('=')
if equalPos != -1:
@ -553,11 +571,12 @@ class SAMLAuthenticator(auths.Authenticator):
# if pattern do not have groups, define one with full re
if pattern.find('(') == -1:
pattern = '(' + pattern + ')'
val = attributes.get(attr, [])
val = getAttr(attr)
for v in val:
try:
logger.debug('Pattern: %s', pattern)
logger.debug('Pattern: %s on value %s', pattern, v)
srch = re.search(pattern, v)
if srch is None:
continue
@ -567,7 +586,8 @@ class SAMLAuthenticator(auths.Authenticator):
logger.debug(e)
break
else:
res += attributes.get(line, [])
res += getAttr(line)
logger.debug('Result: %s', res)
return res
def getInfo(