]> www.infradead.org Git - users/dwmw2/openconnect.git/commitdiff
add test path including frmSelectRoles
authorDaniel Lenski <dlenski@gmail.com>
Fri, 2 Apr 2021 07:57:14 +0000 (00:57 -0700)
committerDaniel Lenski <dlenski@gmail.com>
Fri, 2 Apr 2021 08:59:53 +0000 (01:59 -0700)
frmSelectRoles is a "form" that sort of acts like a realm dropdown except that…

(1) It comes AFTER the credentials have been submitted (¯\_(ツ)_/¯)
(2) It doesn't actually contain any form fields. It only contains links to
    a small number of role choices. It then redirects to 'GET login.cgi'.
    Inane, but apparently used in the real world. See examples at:
    https://gitlab.gnome.org/GNOME/NetworkManager-openconnect/-/issues/30#note_988366

Signed-off-by: Daniel Lenski <dlenski@gmail.com>
tests/fake-juniper-server.py
tests/juniper-auth

index 4cbb0562fd296a84dd1ee198d6a1cdcfbe11e3e0..79cec8affe00e3ccbff19f85b99502c7b50c5db1 100755 (executable)
@@ -76,9 +76,11 @@ def check_form_against_session(*fields, use_query=False):
 @app.route('/')
 def root():
     realms = request.args.get('realms')
+    roles = request.args.get('roles')
     confirm = bool(request.args.get('confirm'))
     token_form = request.args.get('token_form')
     session.update(step='initial-GET', realms=realms and realms.split(','),
+                   roles=roles and roles.split(','),
                    confirm=confirm, token_form=token_form)
     # print(session)
     return redirect(url_for('frmLogin'))
@@ -113,6 +115,7 @@ def frmLogin_post():
     realms = session.get('realms')
     confirm = session.get('confirm')
     token_form = session.get('token_form')
+    roles = session.get('roles')
     if realms:
         assert 0 <= int(request.form.get('realm',-1)) < len(realms)
     session.update(step='POST-login', username=request.form.get('username'),
@@ -134,12 +137,44 @@ def frmLogin_post():
         return redirect(url_for('frm2FA'))
     elif need_confirm:
         return redirect(url_for('frmConfirmation'))
+    elif roles:
+        return redirect(url_for('frmSelectRoles'))
     else:
         resp = redirect(url_for('webtop'))
         resp.set_cookie('DSID', cookify(dict(session)))
         return resp
 
 
+# frmSelectRoles
+# This is some insane post-login realm-ish select-y thing
+@app.route('/dana-na/auth/url_default/select_role.cgi')
+def frmSelectRoles():
+    session.update(step='GET-frmSelectRoles')
+    roles = session.get('roles')
+    dest = url_for('frmSelectRoles_AFTER')
+    roles = '\n'.join('<tr><td><a href="%s?role=%d">%s</a></td></tr>' % (dest, nn, role) for (nn, role) in enumerate(roles))
+    return '''
+<html><body><form name="frmSelectRoles">
+<table id="TABLE_SelectRole_1">
+<tr><td>You have access to the following roles:</td></tr>
+%s
+<tr><td>Each role allows you to access certain resources.  Click on the role you want to join for this session.  Please contact your administrator if you need help choosing a role.</td></tr>
+</table>
+</form></body></form>''' % roles
+
+
+# Note the URL is shared with the frmLogin POST URL... so weird
+@app.route('/dana-na/auth/url_default/login.cgi', methods=['GET'])
+def frmSelectRoles_AFTER():
+    roles = session.get('roles')
+    assert roles
+    assert 0 <= int(request.args.get('role',-1)) < len(roles)
+    session.update(step='AFTER-frmSelectRoles', role=request.form.get('role'))
+    resp = redirect(url_for('webtop'))
+    resp.set_cookie('DSID', cookify(dict(session)))
+    return resp
+
+
 # 2FA forms (frmDefender, frmNextToken, or frmTotpToken)
 # This redirects back to frmLogin_POST
 @app.route('/dana-na/auth/url_default/token.cgi')
index 75339721e37f86b11c9004e4e331236300a68391..f985df2a89df7242d2569117da68d360b822bf85 100755 (executable)
@@ -70,6 +70,14 @@ echo -n "frmLogin with username/password → frmNextToken"
 ( echo "test" | LD_PRELOAD=libsocket_wrapper.so $OPENCONNECT --protocol=nc -q $ADDRESS:443/?token_form=frmNextToken -u test $FAKE_TOKEN $FINGERPRINT --cookieonly >/dev/null 2>&1) ||
     fail $PID "Could not receive cookie from fake Juniper server"
 
+ok
+
+# only one role because we don't have a way to auto-fill this
+# (TODO: make --authgroup fill in the role instead, if there's no realm?)
+echo -n "frmLogin with username/password → frmConfirmation → frmSelectRoles"
+( echo "test" | LD_PRELOAD=libsocket_wrapper.so $OPENCONNECT --protocol=nc -q "$ADDRESS:443/?confirm=1&roles=only_one_role" -u test $FINGERPRINT --cookieonly >/dev/null 2>&1) ||
+    fail $PID "Could not receive cookie from fake Juniper server"
+
 echo ok
 
 echo -n "frmLogin with username/password, then proceeding to tunnel stage... "