Commit 7139d7f1 authored by Marco Malavolti's avatar Marco Malavolti
Browse files

Added 'IdP-Error' check_result and improved ECCS check

parent 444d21c5
......@@ -211,7 +211,8 @@ After the initial download, it is recommended that you occasionally go through t
### Configure ECCS
1. Configure ECCS properties:
* `vim eccs_properties.py` (and change it upon your needs)
* `cp $HOME/eccs/eccs_properties.py.template $HOME/eccs/eccs_properties.py`
* `vim $HOME/eccs/eccs_properties.py` (and change it upon your needs)
2. Change `PATH` by adding the virtualenv Python `bin` dir:
* CentOS:
......@@ -220,7 +221,7 @@ After the initial download, it is recommended that you occasionally go through t
```bash
# set PATH for ECCS
if [ -d "$HOME/eccs" ] ; then
if [ -d "$HOME/eccs" ]; then
PATH="$HOME/eccs/eccs-venv/bin:$PATH"
fi
```
......@@ -233,7 +234,7 @@ After the initial download, it is recommended that you occasionally go through t
```bash
# set PATH for ECCS
if [ -d "$HOME/eccs" ] ; then
if [ -d "$HOME/eccs" ]; then
PATH="$HOME/eccs/eccs-venv/bin:$PATH"
fi
```
......
......@@ -101,8 +101,8 @@ class EccsResults(Resource):
simple = True
if 'check_result' in request.args:
check_result = request.args['check_result']
if (check_result not in ['OK','Timeout','Invalid-Form','Connection-Error','No-eduGAIN-Metadata','SSL-Error','DISABLED']):
return jsonify(error="Incorrect check_result value provided. It can be 'OK','Timeout','Invalid-Form','Connection-Error','No-eduGAIN-Metadata','SSL-Error' ok 'DISABLED'")
if (check_result not in ['OK','Timeout','Invalid-Form','Connection-Error','No-eduGAIN-Metadata','SSL-Error','IdP-Error','DISABLED']):
return jsonify(error="Incorrect check_result value provided. It can be 'OK','Timeout','Invalid-Form','Connection-Error','No-eduGAIN-Metadata','SSL-Error','IdP-Error' or 'DISABLED'")
lines = []
results = []
......
import os
from datetime import date
DAY = date.today().isoformat()
ECCS_DIR = f"{os.environ['HOME']}/eccs"
PATHCHROMEDRIVER = f"{ECCS_DIR}/chromedriver"
ECCS_PYTHON = f"{ECCS_DIR}/python/bin/python3"
# Input
ECCS_INPUTDIR = f"{ECCS_DIR}/input"
ECCS_LISTIDPSURL = 'https://technical.edugain.org/api.php?action=list_eccs_idps&format=json'
ECCS_LISTIDPSFILE = f"{ECCS_INPUTDIR}/list_eccs_idps.json"
ECCS_LISTFEDSURL = 'https://technical.edugain.org/api.php?action=list_feds&opt=1&format=json'
ECCS_LISTFEDSFILE = f"{ECCS_INPUTDIR}/list_fed.json"
# Output
ECCS_OUTPUTDIR = f"{ECCS_DIR}/output"
ECCS_RESULTSLOG = f"eccs_{DAY}.log"
ECCS_HTMLDIR = f"{ECCS_DIR}/html"
# Selenium
ECCS_SELENIUMDEBUG = False
ECCS_SELENIUMLOGDIR = f"{ECCS_DIR}/selenium-logs"
ECCS_SELENIUMPAGELOADTIMEOUT = 60 #seconds (remind to change timeout seconds also on web/eccs.js)
ECCS_SELENIUMSCRIPTTIMEOUT = 60 #seconds
ECCS_REQUESTSTIMEOUT = 15 #seconds
# Logs
ECCS_LOGSDIR = f"{ECCS_DIR}/logs"
ECCS_STDOUT = f"{ECCS_LOGSDIR}/stdout_{DAY}.log"
ECCS_STDERR = f"{ECCS_LOGSDIR}/stderr_{DAY}.log"
ECCS_FAILEDCMD = f"{ECCS_LOGSDIR}/failed-cmd.sh"
ECCS_STDOUTIDP = f"{ECCS_LOGSDIR}/stdout_idp_{DAY}.log"
ECCS_STDERRIDP = f"{ECCS_LOGSDIR}/stderr_idp_{DAY}.log"
ECCS_FAILEDCMDIDP = f"{ECCS_LOGSDIR}/failed-cmd-idp.sh"
# Number of processes to run in parallel
ECCS_NUMPROCESSES = 35
# The 2 SPs that will be used to test each IdP
ECCS_SPS = [
"https://sp-demo.idem.garr.it/Shibboleth.sso/Login?entityID=",
"https://attribute-viewer.aai.switch.ch/interfederation-test/Shibboleth.sso/Login?entityID="
]
# ROBOTS.TXT
ROBOTS_USER_AGENT = "ECCS/2.0 (+https://technical.edugain.org/eccs)"
# PATTERNS
JAVASCRIPT = "x-my-okta-version"
IDPERROR = "error.has.occurred|error.occurred|Error.when.processing.authentication.request|The.system.encountered.an.error|Internal.Server.Error|403.Forbidden|Service.Unavailable|InvalidProfileConfiguration|Unexpected.System.Error|404.not.found|404.-.not.found|OpenAthens:.404|On.tapahtunut.virhe|Unhandled.exception|Bad.Gateway|Page.Not.Found|Δεν.επιτρέπεται.η.πρόσβαση|temporary.error|temporarily.unavailable|License.error|n'est.pas.gérée"
METADATAPATTERN = "Unable.to.locate(\sissuer.in|).metadata(\sfor|)|no.metadata.found|profile.is.not.configured.for.relying.party|Cannot.locate.entity|fail.to.load.unknown.provider|does.not.recognise.the.service|unable.to.load.provider|Nous.n'avons.pas.pu.(charg|charger).le.fournisseur.de service|Metadata.not.found|application.you.have.accessed.is.not.registered.for.use.with.this.service|Message.did.not.meet.security.requirements|Unsupported.Request|Not.Authorized|METADATANOTFOUND|Unknown.login.requester|is.unspecified.or.unsupported|Unknown.service.provider|Richiesta.non.supportata|Metadati.non.trovati|untrusted.provider|Unregistered.Service|Unsupported.request|UNHANDLEDEXCEPTION|Metadata.*.expired|Could.not.find.any.*.metadata.*.for|不支持的请求|l'application.n'est.pas.enregistrée|Requisição.não.suportada|トされていないリクエスト|is.not.allowed|Authorization.Failure|Pedido.não.suportado"
PASSWORDPATTERN = '<input[\s]+[^>]*(type=\s*[\'"]password[\'"]|password)[^>]*>'
REFUSEDPATTERN = '(^http)(.*\.png$)|(.*\.css$)|(.*\.js$)|(.*\.gif$)|(.*\.svg$)|(.*\.jpg$)'
# { 'reg_auth':'reason' }
FEDS_DISABLED_DICT = {
'http://www.surfconext.nl/':'Federation excluded from check',
'https://www.wayf.dk':'Federation excluded from check',
'http://feide.no/':'Federation excluded from check'
}
# { 'entityid_idp':'reason' }
IDPS_DISABLED_DICT = {
'https://idp.eie.gr/idp/shibboleth':'Disabled on 2019-04-24 because ECCS cannot check non-standard login page',
'https://edugain-proxy.igtf.net/simplesaml/saml2/idp/metadata.php':'Disabled on 2017-03-17 on request of federation operator',
'https://gn-vho.grnet.gr/idp/shibboleth':'Disabled on 2019-04-24 because basic authentication is not supported by ECCS check',
'https://wtc.tu-chemnitz.de/shibboleth':'Disabled on 2019-02-26 because ECCS cannot check non-standard login page',
'https://idp.fraunhofer.de/idp/shibboleth':'Disabled on 2017-11-24 on request of federation operator',
'https://idp.dfn-cert.de/idp/shibboleth':'Disabled on 2018-04-05 on request of federation operator',
'https://idp.cambria.ac.uk/openathens':'Disabled on 2017-10-27 on request of federation operator',
'https://login.lstonline.ac.uk/idp/pingfederate':'Disabled on 2017-02-08 on request of federation operator',
'https://indiid.net/idp/shibboleth':'Disabled on 2017-10-27 on request of federation operator',
'https://idp.nulc.ac.uk/openathens':'Disabled on 2017-10-27 on request of federation operator',
'https://lc-idp.lincolncollege.ac.uk/shibboleth':'Disabled on 2015-08-17 because uses HTTP Basic authentication, which cannot be checked reliably',
'https://idp.wnsc.ac.uk/idp/shibboleth':'Disabled on 2017-10-27 on request of federation operator',
# 'https://idp.strodes.ac.uk/shibboleth':'Disabled on 2015-08-17 because uses HTTP Basic authentication, which cannot be checked reliably',
'https://idp.uel.ac.uk/shibboleth':'Disabled on 2017-10-27 on request of federation operator',
'https://idp.ucreative.ac.uk/shibboleth':'Disabled on 2017-10-27 on request of federation operator',
'https://idp.llandrillo.ac.uk/shibboleth':'Disabled on 2017-10-27 on request of federation operator',
'https://sso.vu.lt/SSO/saml2/idp/metadata.php':'Disabled on 2018-11-02 because ECCS cannot check non-standard login page',
'https://ssl.education.lu/saml/saml2/idp/metadata.php':'Disabled on 2018-11-06 ECCS cannot check non-standard login page',
'https://sso.oktaedu.com/idp/shibboleth':'Disabled on 2021-08-12 because ECCS cannot check non-standard login page',
}
......@@ -237,10 +237,13 @@ def check_idp_response_selenium(sp,idp,test):
# Catch SSL Exceptions and block the ECCS check
except requests.exceptions.SSLError as e:
if (test): page_source = f"\nAn SSL Error occurred while opening https://{fqdn_idp}/robots.txt:\n\n{e}\n\nCheck it on SSL Labs: https://www.ssllabs.com/ssltest/analyze.html?d={fqdn_idp}"
else: page_source = f"<h1>SSL ERROR</h1><h2>An SSL error occurred for the server {fqdn_idp}:</h2><p>{e}</p><p>Check it on SSL Labs: <a href='https://www.ssllabs.com/ssltest/analyze.html?d={fqdn_idp}'>Click Here</a></p>"
store_page_source(page_source,idp,sp,test)
return (idp['entityID'],wayfless_url,check_time,"SSL-Error",webdriver_error)
if ('unable to get local issuer certificate' not in str(e)):
if (test): page_source = f"\nAn SSL Error occurred while opening https://{fqdn_idp}/robots.txt:\n\n{e}\n\nCheck it on SSL Labs: https://www.ssllabs.com/ssltest/analyze.html?d={fqdn_idp}"
else: page_source = f"<h1>SSL ERROR</h1><h2>An SSL error occurred for the server {fqdn_idp}:</h2><p>{e}</p><p>Check it on SSL Labs: <a href='https://www.ssllabs.com/ssltest/analyze.html?d={fqdn_idp}'>Click Here</a></p>"
store_page_source(page_source,idp,sp,test)
return (idp['entityID'],wayfless_url,check_time,"SSL-Error",webdriver_error)
else:
pass
# Do not consider any other Exception
except:
......@@ -271,10 +274,16 @@ def check_idp_response_selenium(sp,idp,test):
check_time = datetime.datetime.utcnow().strftime('%Y-%m-%dT%H:%M:%S') + 'Z'
driver.get(wayfless_url)
metadata_not_found = re.search(e_p.METADATAPATTERN,driver.page_source, re.I)
idp_error = re.search(e_p.IDPERROR,driver.page_source, re.I)
# Support HTTP Basic Authentication
unauthorized = re.search('401.(\D.|\s.)?Unauthorized', driver.page_source, re.I)
if (unauthorized):
if (test): pgsrc = f"\n[PAGE_SOURCE]\n{driver.page_source}\n[WAYFLESS URL]{wayfless_url} - JAVASCRIPT FOUND"
else: pgsrc = driver.page_source
stored = store_page_source(pgsrc,idp,sp,test)
if (stored):
return (idp['entityID'],wayfless_url,check_time,"OK",webdriver_error)
metadata_not_found = re.search(e_p.METADATAPATTERN,driver.page_source, re.I)
if (metadata_not_found):
if (test): pgsrc = f"\n[PAGE_SOURCE]\n{driver.page_source}\n[WAYFLESS URL]{wayfless_url} - METADATA NOT FOUND"
else: pgsrc = driver.page_source
......@@ -282,6 +291,7 @@ def check_idp_response_selenium(sp,idp,test):
if (stored):
return (idp['entityID'],wayfless_url,check_time,"No-eduGAIN-Metadata",webdriver_error)
idp_error = re.search(e_p.IDPERROR,driver.page_source, re.I)
if (idp_error):
if (test): pgsrc = f"\n[PAGE_SOURCE]\n{driver.page_source}\n[WAYFLESS URL]{wayfless_url} - IDP ERROR"
else: pgsrc = driver.page_source
......@@ -293,10 +303,12 @@ def check_idp_response_selenium(sp,idp,test):
if ('<iframe' in driver.page_source):
follow_all_nested_iframes(driver)
driver.refresh()
load_js = re.search(e_p.JAVASCRIPT, driver.page_source, re.I)
if (load_js):
driver.refresh()
WebDriverWait(driver, e_p.ECCS_SELENIUMPAGELOADTIMEOUT).until(
EC.presence_of_element_located((By.XPATH,'//input[@type="password"]'))
EC.presence_of_element_located((By.XPATH,'//input[@type="password"]|//input[@type="Password"]'))
)
if (test): pgsrc = f"\n[WAYFLESS_URL]\n{wayfless_url} - OK"
......@@ -310,7 +322,7 @@ def check_idp_response_selenium(sp,idp,test):
metadata_not_found = re.search(e_p.METADATAPATTERN,driver.page_source, re.I)
try:
input_password_found = driver.find_element(By.XPATH,'//input[@type="password"]')
input_password_found = driver.find_element(By.XPATH,'//input[@type="password"]|//input[@type="Password"]')
except NoSuchElementException as e:
# This IF is for those IdP that doesn't consuming the eduGAIN metadata and reaching Timeout
......
Markdown is supported
0% or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment