{"action":"created","issue":{"url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/1311","labels_url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/1311/labels{/name}","comments_url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/1311/comments","events_url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/1311/events","html_url":"https://github.com/FreeRADIUS/freeradius-server/issues/1311","id":110231235,"number":1311,"title":"EAP loop detection prevents TLS-tunneled sessions from using a pool's virtual fallback server","user":{"login":"skids","id":59003,"avatar_url":"https://avatars.githubusercontent.com/u/59003?v=3","gravatar_id":"","url":"https://api.github.com/users/skids","html_url":"https://github.com/skids","followers_url":"https://api.github.com/users/skids/followers","following_url":"https://api.github.com/users/skids/following{/other_user}","gists_url":"https://api.github.com/users/skids/gists{/gist_id}","starred_url":"https://api.github.com/users/skids/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skids/subscriptions","organizations_url":"https://api.github.com/users/skids/orgs","repos_url":"https://api.github.com/users/skids/repos","events_url":"https://api.github.com/users/skids/events{/privacy}","received_events_url":"https://api.github.com/users/skids/received_events","type":"User","site_admin":false},"labels":[],"state":"closed","locked":false,"assignee":null,"milestone":null,"comments":6,"created_at":"2015-10-07T13:57:09Z","updated_at":"2015-10-09T14:33:46Z","closed_at":"2015-10-07T14:58:49Z","body":"(Sorry I couldn't get to this pre-3.0.10, time just did not allow.)\r\n\r\nFallback servers (which must be virtual) cannot serve tunneled requests because,\r\nthey false-detect an EAP loop.  To reproduce, take the stock configuration and make\r\nthese changes:\r\n\r\nproxy.conf:\r\n1) set the home server's port to something ridiculous to emulate it being down\r\n2) Activate/define the virtual.example.com home_server and server sections.\r\n    Note you can't just use the commented out text since it has bitrotted: the\r\n    default server has a listen stanza in it now which will self-conflict.\r\n3) remove the suffix calls from virtual.example.com just to eliminate any\r\n    possibility that a second suffix realm route after fallback is to blame (same results\r\n    either way)\r\n4) uncomment/activate virtual.example.com as the fallback for the my_auth_failover\r\n    pool\r\n5)  In inner tunnel auth update control { &Cleartext-Password := testing123 } for a quick\r\n    and dirty test user\r\n6) make an eapol-test template file:\r\nnetwork={\r\n        ssid=\"example\"\r\n        key_mgmt=WPA-EAP\r\n        eap=PEAP\r\n        identity=\"iiiiii\"\r\n        anonymous_identity=\"oooooo\"\r\n        password=\"pppppp\"\r\n        phase1=\"peaplabel=0\"\r\n        phase2=\"auth=MSCHAPV2\"\r\n}\r\n7) Make a script to use it:\r\n\r\n#!/bin/sh\r\n\r\nEAPOL_TEST='/sbin/eapol_test'\r\nTESTPWD=\"testing123\"\r\n\r\necho -n \"Test1...\"\r\ncat eapol_test_peap_mschap.conf | perl -pne 's/oooooo/anon\\@example.com/; s/iiiiii/buguser\\@example.com/; s/pppppp/'$TESTPWD'/;' > eapol_test_scratch.conf\r\n$EAPOL_TEST -c eapol_test_scratch.conf -a 127.0.0.1 -p 1812 -s testing123 -Md4:00:00:00:00:01 -N4:x:0x7f000001 -N30:s:00-01-02-03-04-03:example\r\n#| grep -q 'MS-MPPE-Recv-Key' && echo \"win.\" || echo \"FAIL!\"\r\necho -n > eapol_test_scratch.conf\r\n\r\n8) Run the script once, wait for the server with the bogus port to be declared dead, then\r\nrun it again.  In the below ouput the session starting at number (14) eventually\r\nfails at '(21) eap: Multiple levels of TLS nesting is invalid' (which as an aside should\r\nprobably be a colorized error message.)\r\n\r\nDebug output at\r\nhttps://gist.github.com/skids/17869d1a528c8134959a\r\n\r\nOther folks have managed to get themselves into this pickle before but may have been doing\r\nsomething unusual -- I don't think it's very unusual to want a fallback server, though, and those are required to be virtual.  Here are links to old ML threads:\r\n\r\n   http://lists.freeradius.org/pipermail/freeradius-users/2008-October/032231.html\r\n   http://marc.info/?l=freeradius-users&m=127242177232523&w=2\r\n\r\n"},"comment":{"url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/comments/146889351","html_url":"https://github.com/FreeRADIUS/freeradius-server/issues/1311#issuecomment-146889351","issue_url":"https://api.github.com/repos/FreeRADIUS/freeradius-server/issues/1311","id":146889351,"user":{"login":"skids","id":59003,"avatar_url":"https://avatars.githubusercontent.com/u/59003?v=3","gravatar_id":"","url":"https://api.github.com/users/skids","html_url":"https://github.com/skids","followers_url":"https://api.github.com/users/skids/followers","following_url":"https://api.github.com/users/skids/following{/other_user}","gists_url":"https://api.github.com/users/skids/gists{/gist_id}","starred_url":"https://api.github.com/users/skids/starred{/owner}{/repo}","subscriptions_url":"https://api.github.com/users/skids/subscriptions","organizations_url":"https://api.github.com/users/skids/orgs","repos_url":"https://api.github.com/users/skids/repos","events_url":"https://api.github.com/users/skids/events{/privacy}","received_events_url":"https://api.github.com/users/skids/received_events","type":"User","site_admin":false},"created_at":"2015-10-09T14:33:45Z","updated_at":"2015-10-09T14:33:45Z","body":"I did try out this:\r\n\r\n    if (handler->request->parent\r\n            && handler->request->parent->parent\r\n            && !handler->request->parent->parent->home_server) \r\n\r\n...and that \"worked\", but I'm unsure how to test to see if it still blocks\r\nactual EAP loops.\r\n\r\nAlso a tangentially related thing which I can open a separate issue on if it is\r\nnot just an obvious fix.  fr_state_get_vps destructively move-copies\r\nattributes out of the cached state list.  In certain situations where a request\r\nproxies back to the same process, the state list will be found-but-empty on the\r\nsecond time in.  This seems to fix that issue, and the server does seem to delete\r\nthe entries later on as appropriate:\r\n\r\n    @@ -401,4 +401,4 @@ void fr_state_get_vps(REQUEST *request, RADIUS_PACKET *packet)\r\n            if (entry) {\r\n    -               fr_pair_list_mcopy_by_num(request, &request->state, &entry->vps, 0, 0, TAG_ANY);\r\n    -               RDEBUG2(\"session-state: Found cached attributes\");\r\n    +               request->state = fr_pair_list_copy(request, entry->vps);\r\n    +               RDEBUG2(\"session-state: Found cached attributes %p\", entry);\r\n                    rdebug_pair_list(L_DBG_LVL_1, request, request->state, NULL);\r\n\r\n\r\n   \r\n\r\nAnd, while I was trying that out, I noticed that fr_pair_list_copy_by_num is not\r\nchecking the documented 0 wildcard condition on attr and it neither documents nor\r\nchecks for a wildcard on vendor -- some code may relay on the latter, and both may be\r\nintentional, in which case the docs in the comments just need to remove the wildcard.\r\n"}}