Netgate Discussion Forum
    • Categories
    • Recent
    • Tags
    • Popular
    • Users
    • Search
    • Register
    • Login

    Captive portal manual logout page address

    Scheduled Pinned Locked Moved Captive Portal
    105 Posts 15 Posters 57.5k Views
    Loading More Posts
    • Oldest to Newest
    • Newest to Oldest
    • Most Votes
    Reply
    • Reply as topic
    Log in to reply
    This topic has been deleted. Only users with topic management privileges can see it.
    • D
      Dario Palmisano
      last edited by

      Hello Everybody,

      I am using pfSense latest version (2.1.3).

      As most of the browsers disable popup window, I would like to know if it is already implemented (by pfSense) a web page to disconnect (manually) a captive portal client and what is the address to specify in the  browser.

      In the forum I found many contributions (for older version) that allowed me to produce my script that works fine, but I would much prefer to use the version implemented in pfSense (if available).

      If found an interesting web page (/var/etc/captiveportal-ZONE_NAME-logout.html), but I did not understand how to access it for my need.

      Thanks in advance for any hint on sorting this out

      Best regards

      Dario

      1 Reply Last reply Reply Quote 0
      • GertjanG
        Gertjan
        last edited by

        @Dario:

        ….

        If found an interesting web page (/var/etc/captiveportal-ZONE_NAME-logout.html), but I did not understand how to access it for my need.
        ....

        This file is being generated by /etc/inc/captiveportal.inc and is the script that opens the popup (if checked in the captive portal settings).
        You can even upload you own log out page (last options on the portal config setttings file).

        But ….. as you can see in the code, its not enough to propose an URL to have the user being logged out.
        Like, for me: https://portal.brit-hotel-fumel.net:8001/&logout_id=xxxx&zonecp=yyyy
        The session ID xxx has also to set so the user actually gets logged out.
        The zonecp yyy needs to set et also.

        This means that some information HAS to be communicated to the connected user so he can logout.

        And, of course, this can only be done when the user accepts a popup or a new browser page when logging in.

        If logging out is important to you:
        WARN the user that he HAS to accepts popup - and that the user shouldn't logging before popus are shown …. or otherwise he will stay logged in just untill the idle-time out** kick in - or the hard time out is expired.

        ** idle-time out works but ..... PC's keep sending out "ethernet information" even if the user isn't doing anything on the net. The only GOOD way to use the idle-time out is actually deactivating the network device (typically the Wifi net work card) and this isn't really an option for an ordinary user.

        Normally, if you do net sell your portal access time, you just put idle time to +/- one hours (60 minutes) so that user that get out of the wifi network (lost connection) are logged out automatically.

        If not, popus should work on the user (client) side
        AND
        They should NOT 'loose' or 'close' the popup windows so they actually CAN logout.

        A plan B would be: ask the user to give valid mail address - and mail the logout link to him. (some coding needs to be done).

        No "help me" PM's please. Use the forum, the community will thank you.
        Edit : and where are the logs ??

        1 Reply Last reply Reply Quote 0
        • GertjanG
          Gertjan
          last edited by

          Humm.

          I just started thinking about plan C:

          I could create a "logout page" here: /usr/local/captiveportal/logout.php

          When a portal visitor is visiting this page, the PHP code/script could find out what the visitor's IP and MAC is. Its a question of searching in the 'portal maintenance/database files' that the portal code is using.
          The visitors session ID can be found easily with the help of the know info (IP and MAC) and some functions in /etc/inc/captiveportal.inc

          Then, call
          captiveportal_disconnect_client($sessionid, 1, $logoutReason = "User LOGOUT itself !!")
          and done, the visitor logged out itself !

          The advantage of the approach is:
          When  the user logs in, you could show an easy to remember URL, like
          https://portal.brit-hotel-fumel.net/logout.php
          (I'm using the https acces with certificat - your URL might be an IP)
          (propose also a html version of this page)

          Just advise/ask the portal visitor to BOOKMARK this page - or have it noted - Ctrl-C it - or print it on your voucher, or mention it on a site somewhere - have the message passed by radio or tele.

          A sub solution could be: modify the existing /usr/local/captiveportal/index.php file, with some logic that detects that a user is already logged in, so it will ask the portal visitor if he want to logout. If NOT, redirect (drop) the portal visitor 'elsewhere' on the net.
          In my case, visiting
          https://portal.brit-hotel-fumel.net
          will do the job.

          No "help me" PM's please. Use the forum, the community will thank you.
          Edit : and where are the logs ??

          B 1 Reply Last reply Reply Quote 1
          • GertjanG
            Gertjan
            last edited by

            @Gertjan:

            ….
            In my case, re-visiting
            https://portal.brit-hotel-fumel.net
            will do the job.

            I implemented this.
            Re-visiting the portal 'login' page after a you gained access to the net will show you a new screen that proposes you to disconnect.

            I modified:
            /usr/local/captiveportal/index.php
            => added 4 lines
            /etc/inc/captiveportal.php
            => added a new function and modified function portal_reply_page()

            Created:
            /var/etc/captiveportal_cpzone-already-connected.html
            => this file should be auto-created when starting the portal - as the other portal html files
            => I'll do this later.

            I have activated this patch to our live network - our clients will test it. I see how it works.

            If needed, I can post the code here.

            Btw: this new way of disconnecting doesn't need the default popup page (often being suppressed by the client's browser).
            You just mention on the main login page that the client can re-visit the login page again to disconnect.
            Smart client will bookmark this URL for later 'disconnecting' use  ;)

            edit: I'm using 2.1.3-RELEASE (amd64) - built on Thu May 01 15:52:13 EDT 2014 - FreeBSD 8.3-RELEASE-p16

            This works fine when using the local pfSense user Manager.
            What needs to be done:

            1. Testing with Radius Authentication setup
            2. Testing when using 'vouchers' - but I'm sure sure if this is usefull, as vouchers propose time-limited connections - loging-out doesn't seem useful to me (maybe I'm wrong)
            3. Testing against 'Pass-through MAC Auto Entry' - although this authentification system already has a disconnecting function (see below).

            As said on the Captive Portal main settings page:

            To remove the passthrough MAC entry you either have to log in and remove it manually from the Pass-through MAC tab or send a POST from another system to remove it. If this is enabled, RADIUS MAC authentication cannot be used. Also, the logout window will not be shown

            The mentioned "POST from another system to remove it" could be the portal user itself (?)

            No "help me" PM's please. Use the forum, the community will thank you.
            Edit : and where are the logs ??

            1 Reply Last reply Reply Quote 0
            • L
              lsense
              last edited by

              I had a different approach:

              • host override in dns forwarder :    logout.me -> 1.1.1.1
              • modify capture of 1.1.1.1 in ipfw : it gets always redirected, even if authenticated
              • user gets a cookie with session id.
              • modify index.php to check if redirection url is http://logout.me and check session cookie (you have to auth again to logout if you close the browser but not just the popup.)

              p.s.1 If I'm not wrong in your solution if I spoof my IP/mac I could logout other people by accessing your logout php.

              p.s.2 yes, I know: I should use https captive portal because others my intercept my session logout cookie..

              1 Reply Last reply Reply Quote 0
              • GertjanG
                Gertjan
                last edited by

                Thanks for the ideas and security issue.

                Your right, I added to /usr/local/captiveportal/index.php (end of the file):

                } else if (already_connected($clientip, $clientmac)) {
                	/* display already connected page - offer logout */
                 	portal_reply_page($redirurl, "already_connected",null,$clientmac,$clientip);
                } else
                	/* display captive portal page */
                	portal_reply_page($redirurl, "login",null,$clientmac,$clientip);
                
                ob_flush();
                
                ?>
                

                In /etc/inc/captiveportal.inc:

                ...
                	function already_connected($clientip, $clientmac) {
                	global $cpzone;
                
                	if (($clientip != "") && ($clientmac != "")) {
                		$query = "WHERE ip = '{$clientip}' AND mac = '{$clientmac}'";
                		$cpdb = captiveportal_read_db($query);
                		/* Lookup the $sessionid */
                		foreach ($cpdb as $cpentry) {
                			if (($cpentry[2] == $clientip) && ($cpentry[3] == $clientmac))
                				return $cpentry[5];
                			}
                			return false;
                		} else
                			return false;
                	}
                ...
                
                

                @lsense:

                • user gets a cookie with session id.

                This means a cookie will be communicated to the browser when the portal clients succeeds authentication ?
                edit: btw, from where did you send the cookie ? From /etc/inc/captiveportal.inc : end of function portal_allow() ?
                If so, when:
                @lsense:

                • modify index.php to check if redirection url is http://logout.me and check session cookie (you have to auth again to logout if you close the browser but not just the popup.)

                then correct, the session gets reused!
                @/etc/inc/captiveportal.inc:

                CONCURRENT LOGIN - REUSING OLD SESSION

                No need to do what my function function already_connected($clientip, $clientmac) does !
                Good idea ! I'll implement that.

                p.s.1 If I'm not wrong in your solution if I spoof my IP/mac I could logout other people by accessing your logout php.

                Yes, true.
                The impostor and real client will be thrown of the portal. Authentication will be needed to regain access again.
                Normally, if the impostor has the IP and MAC, other troubles will happen ;)

                p.s.2 yes, I know: I should use https captive portal because others my intercept my session logout cookie..

                I use a (free) certificate from startssl for more then a year now. Just to protect the login sequences. I didn't had much feedback from portal clients who had login problems.

                No "help me" PM's please. Use the forum, the community will thank you.
                Edit : and where are the logs ??

                1 Reply Last reply Reply Quote 0
                • D
                  Dario Palmisano
                  last edited by

                  Gertjan very good ideas and thanks for the detailed descriptions,

                  I would really like to have a chance to see your complete implementation, because it seems much simpler and well integrated than mine.

                  A further question: is it possible to ask the developers to include such a functionality in a pfsense future release?

                  Looking in the forum it will be very appreciated!

                  Thanks and regards

                  1 Reply Last reply Reply Quote 0
                  • GertjanG
                    Gertjan
                    last edited by

                    My files, right now:
                    Upload these two files with the FileManager available in the Captive Portal:
                    style.css - http://pastebin.com/LqLx9G5f
                    already-connected.html  - http://pastebin.com/p8GRpuHQ

                    These two file will be available in /var/db/cpelements as:
                    captiveportal-style.css
                    captiveportal-already-connected.html

                    Modify these files:
                    Te entire file: /usr/local/captiveportal/index.php - http://pastebin.com/jgDrEvpP

                    /etc/inc/captiveportal.php :
                    Replace the function portal_reply_page(…) for this one http://pastebin.com/mUzp4q3g

                    Just above this new function portal_reply_page(...), add this new function already_connected(...) - http://pastebin.com/emQgMQp8

                    How it work:
                    At the very end of /usr/local/captiveportal/index.php - if the visitor isn't logged in yet, the login page will be show (line 237 : /* display captive portal page */).
                    Just before, this test is added:

                    } else if (already_connected($clientip, $clientmac)) {
                    	/* display already connected page - offer logout */
                     	portal_reply_page($redirurl, "already_connected",null,$clientmac,$clientip)
                    

                    The test uses $clientip and $clientmac, which should be known at that moment.
                    already_connected($clientip, $clientmac) is the function that you added to /etc/inc/captiveportal.php, and looks up the users $sessionid in captive portal logged in user database.
                    It should return a $sessionid.
                    If it does, then  portal_reply_page(…) is being called with a new parameter, like this:
                    portal_reply_page($redirurl, "already_connected",null,$clientmac,$clientip).

                    I modified portal_reply_page(..) somewhat so it can handle the new "already_connected".
                    portal_reply_page(..) will, again, lookup the users $sessionid  and then include our logout page:

                    $htmltext = get_include_contents("{$g['captiveportal_path']}/captiveportal-already-connected.html");
                    

                    (this is the file you uploaded with the filemanager).

                    Note: below, in portal_reply_page(..), I added these:

                    	$htmltext = str_replace("\$PORTAL_SESSION\$", htmlspecialchars($sessionid), $htmltext);
                    

                    and

                    	$htmltext = str_replace("#PORTAL_SESSION#", htmlspecialchars($sessionid), $htmltext);
                    

                    this was for debugging issues.

                    What I didn't test:
                    I use https portal login - I didn't test http login (I guess it should work).

                    I can't implement right now is what lsense did: when the user logs in, send over a persistent (encoded) cookie with the visitors IP, MAC and session ID. This way, things could be more safe and easy to implement. (Portal visitors should accept cookies if they want t logout, of course …)
                    But, right now, these variables are send over my secured https connection  (my logout page is SSL secured).

                    I mentionned in my login page, this one {$g['varetc_path']}/captiveportal_{$cpzone}.html" :

                    
                    You can disconnect yourself.
                    
                    				To do so, visit this page again:
                    
                    				[#PORTAL_ACTION#](#PORTAL_ACTION#)
                    
                    Click on the link to open it already in a new window
                    
                    Note:
                    I only use the local User Manager, build in pfSense.
                    I haven't test other login possibilities like Radius,  Pass-through credits allowed per MAC address and Vouchers. I will test the last two as soon as I have some time.
                    
                    Pass-through MAC Auto Entry has its own 'logout' possibility.
                    
                    PS: I copied files and functions from my running portal pfsense box.
                    It 'should' work.
                    Be ready, thought, to debug if needed.
                    Keep safe copies of the files you modify:
                    /usr/local/captiveportal/index.php
                    /etc/inc/captiveportal.php
                    
                    

                    No "help me" PM's please. Use the forum, the community will thank you.
                    Edit : and where are the logs ??

                    1 Reply Last reply Reply Quote 0
                    • L
                      lsense
                      last edited by

                      @Gertjan:

                      This means a cookie will be communicated to the browser when the portal clients succeeds authentication ?
                      edit: btw, from where did you send the cookie ? From /etc/inc/captiveportal.inc : end of function portal_allow() ?
                      If so, when:
                      @lsense:

                      • modify index.php to check if redirection url is http://logout.me and check session cookie (you have to auth again to logout if you close the browser but not just the popup.)

                      then correct, the session gets reused!

                      I set logout cookie in /etc/inc/captiveportal.inc function portal_allow() as simply as:

                      
                      /* set logout cookie */	
                      setcookie("logout", $sessionid);
                      
                      

                      then in /usr/local/captiveportal/index.php:

                      
                      ...
                      else if ($redirurl == 'http://logout.me/') {
                      	if (isset($_COOKIE["logout"])) {
                      		$logoutcookie = $_COOKIE["logout"];
                      		setcookie("logout", "", time() - 3600);
                      		echo << <eod<br><title>Disconnected</title>
                      
                       **Disconnected.** 
                      
                      EOD;
                      		captiveportal_disconnect_client($logoutcookie);
                      	}
                      	else {
                      	captiveportal_logportalauth('failed, missing cookie: reauth',$clientmac,$clientip,"LOGOUT");
                      	portal_reply_page($redirurl, "login",null,$clientmac,$clientip);
                      	}
                      }</eod<br> 
                      
                      1 Reply Last reply Reply Quote 0
                      • GertjanG
                        Gertjan
                        last edited by

                        As lsesne proposes, I have it working with cookies now.
                        No more IP and MAC posting.

                        Note: If portal visitor doesn't like cookies (read: he won't be doing much on the Internet) the discussed  logging method won't work.

                        edit: lol: I was just posting the above when lsesne posted.
                        I created and destroyed the cookie in the same places !!

                        I destroyed like this:

                        No "help me" PM's please. Use the forum, the community will thank you.
                        Edit : and where are the logs ??

                        1 Reply Last reply Reply Quote 0
                        • GertjanG
                          Gertjan
                          last edited by

                          Here are my modifications that work with cookies:

                          Modify these files:
                          The entire file: /usr/local/captiveportal/index.php : http://pastebin.com/yJirfya6 (includes latest updates from https://github.com/pfsense/pfsense/commit/1b244d3828e83d3c1677d88d5c6bfcb34debac83 )

                          /etc/inc/captiveportal.php :

                          1. Replace the entire function portal_reply_page(…) with this one : http://pastebin.com/wjWXea06

                          2. Just above this new function portal_reply_page(…), add this new function already_connected(…) : http://pastebin.com/x3fxwEf8

                          3. Replace the entire function portal_allow(…) with this one : http://pastebin.com/ivzjTuns

                          And:
                          Upload these two files with the FileManager available in the Captive Portal:
                          style.css - http://pastebin.com/LqLx9G5f
                          already-connected.html  - http://pastebin.com/p8GRpuHQ

                          No "help me" PM's please. Use the forum, the community will thank you.
                          Edit : and where are the logs ??

                          1 Reply Last reply Reply Quote 0
                          • C
                            CrackBlue
                            last edited by

                            @Gertjan:

                            Here are my modifications that work with cookies:

                            Modify these files:
                            The entire file: /usr/local/captiveportal/index.php : http://pastebin.com/yJirfya6 (includes latest updates from https://github.com/pfsense/pfsense/commit/1b244d3828e83d3c1677d88d5c6bfcb34debac83 )

                            /etc/inc/captiveportal.php :

                            1. Replace the entire function portal_reply_page(…) with this one : http://pastebin.com/wjWXea06

                            2. Just above this new function portal_reply_page(…), add this new function already_connected(…) : http://pastebin.com/x3fxwEf8

                            3. Replace the entire function portal_allow(…) with this one : http://pastebin.com/ivzjTuns

                            And:
                            Upload these two files with the FileManager available in the Captive Portal:
                            style.css - http://pastebin.com/LqLx9G5f
                            already-connected.html  - http://pastebin.com/p8GRpuHQ

                            Any new updates on pastebin? it seems that pastebin has already removed the entries…

                            1 Reply Last reply Reply Quote 0
                            • GertjanG
                              Gertjan
                              last edited by

                              Sorry.

                              …. I've updated to the latest pfSense without any 'copies' of the modified files mentioned above.

                              :(

                              No "help me" PM's please. Use the forum, the community will thank you.
                              Edit : and where are the logs ??

                              1 Reply Last reply Reply Quote 0
                              • GertjanG
                                Gertjan
                                last edited by

                                Here are my modifications that work with cookies:

                                Please note : I use the https version of the captive portal with a valid (startssl.com certificat) (I don't know if this is important).
                                Right now, (January 2015) this setup works on one of my pfSense installations (an hotel).
                                I'm using a nearly clean, original "2.1.5-RELEASE (amd64) built on Mon Aug 25 07:44:45 EDT 2014".

                                edit: these pastebin.org files are locked 'forever' - keep in mind that used to work with 2.1.5 - They might need some re-coding for 2.2.

                                File: /usr/local/captiveportal/index.php : http://pastebin.com/scYuKTyw - index.php - compare and modify last ~ 15 lines
                                Basically, this parted gets inserted:

                                } else if ((isset($_COOKIE['cookie_portal']) && already_connected($_COOKIE['cookie_portal'])))
                                        /* if we have a valid session, display already connected page - offer logout */
                                        portal_reply_page($redirurl, "already_connected",null,$clientmac,$clientip);
                                

                                File /etc/inc/captiveportal.php :

                                1. Replace the entire function portal_reply_page(…) with this one : http://pastebin.com/piamkhNB

                                2. Just above this new function portal_reply_page(...), add this new function already_connected(…) : http://pastebin.com/CFatytZ9

                                3. Replace the entire function portal_allow(…) with this one : http://pastebin.com/jDHVaNwf (actually, I just added nearly at the bottom one line:

                                	setcookie("cookie_portal", $sessionid);	
                                

                                And:
                                Upload these two files with the FileManager available in the Captive Portal:
                                style.css - http://pastebin.com/MqwEcxVP (this file will be called and used as captiveportal-style.css when uploaded)
                                xxxxxxx-already-connected.html  - http://pastebin.com/PUyQvAuv (this file will be called and used as "captiveportal-xxxxxxx-already-connected.html" when uploaded)

                                You probably have to change the first part of the last file name = "xxxxxxx" in xxxxxxx-already-connected.html
                                Edit your instance (zone) of your captive portal. You will find the wanted parted in the URL:
                                Example, mine is showing this:
                                http://192.168.1.1/services_captiveportal.php?zone=xxxxxxx
                                (Note: my first and unique Captive portal zone is being called "ZONE1" - that's NOT the part we wanted)

                                Btw: @lsense, if you are there:

                                • host override in dns forwarder :    logout.me -> 1.1.1.1

                                Ok, done.

                                • modify capture of 1.1.1.1 in ipfw : it gets always redirected, even if authenticated

                                Could you detail this please ? What is de ipfw rule ? Injected where ?

                                No "help me" PM's please. Use the forum, the community will thank you.
                                Edit : and where are the logs ??

                                1 Reply Last reply Reply Quote 0
                                • E
                                  EMWEE
                                  last edited by

                                  So i cant get this to work. I do get a cookie on the devices but i do not get redirected to the logout page.

                                  My index.php looks like this:

                                  } else if ($_POST['accept'] && $clientip && $cpcfg['auth_method'] == "none") {
                                          captiveportal_logportalauth("unauthenticated",$clientmac,$clientip,"ACCEPT");
                                          portal_allow($clientip, $clientmac, "unauthenticated");

                                  } else if (already_connected($clientip, $clientmac)) {
                                          /* display already connected page - offer logout */
                                          portal_reply_page($redirurl, "already_connected",null,$clientmac,$clientip);

                                  } else
                                          /* display captive portal page */
                                          portal_reply_page($redirurl, "login",null,$clientmac,$clientip);

                                  ob_flush();

                                  ?>

                                  Any ideas?

                                  1 Reply Last reply Reply Quote 0
                                  • GertjanG
                                    Gertjan
                                    last edited by

                                    I detailed this index.php - by putting the whole file on pastbin.com

                                    File: /usr/local/captiveportal/index.php : http://pastebin.com/scYuKTyw - index.php

                                    Just replace the one you have right now.

                                    Be careful : 2.1.5 only !!
                                    edit have it also working on 2.2 now.

                                    No "help me" PM's please. Use the forum, the community will thank you.
                                    Edit : and where are the logs ??

                                    1 Reply Last reply Reply Quote 0
                                    • E
                                      EMWEE
                                      last edited by

                                      Thanks for your reply. I see that I missed the part for checking for a cookie (my php skills are kinda low).

                                      I'll try this tommorow on a 2.1.5 box.

                                      If I may ask you another question: where do you put your " cookie destroy" code.

                                      1 Reply Last reply Reply Quote 0
                                      • GertjanG
                                        Gertjan
                                        last edited by

                                        @EMWEE:

                                        ….
                                        If I may ask you another question: where do you put your " cookie destroy" code.

                                        I don't  :) (I stopped doing so).

                                        If you want to destroy it, have a look at the index.php
                                        Look for this line:

                                        captiveportal_disconnect_client($_POST['logout_id']);
                                        

                                        $_POST['logout_id']

                                        will be the $session_id.
                                        Just before that line, if you like, you can destroy your cookie. edit: wrong ! had to put that code higher up - before the 'logged-out-windows' is being send - see line 121-124 in index.php : http://pastebin.com/scYuKTyw
                                        Or do what lsense proposed here : https://forum.pfsense.org/index.php?topic=77143.msg422179#msg422179

                                        But, what happens if you don't ?
                                        Ones disconnected, the session Id will be 'non-existent' (its a big random number).
                                        So, it can't be reused to re-disconnect, neither disconnect some one else (remember: you have to have the same IP and same sessions Id to interact with a session from some one else).
                                        Anyway, to access the disconnect function, you have to have a valid session first.

                                        As said before: I use a https portal login page - with a real certificate (a valid one, guaranteed by StartSSL) - so sniffing the initial  login from some one else isn't an easy thing to do.

                                        Important : if you want to debug this kind of stuff, do not use 'echo' all over the place, use this function:

                                        captiveportal_logportalauth($text1,$text2,$text3, $text4);
                                        

                                        Have a loot at http://pastebin.com/jDHVaNwf to see examples how t use it.

                                        Just drop some captiveportal_logportalauth($text1,$text2,$text3, $text4); on strategic places to see what is getting reached when.

                                        No "help me" PM's please. Use the forum, the community will thank you.
                                        Edit : and where are the logs ??

                                        1 Reply Last reply Reply Quote 0
                                        • E
                                          EMWEE
                                          last edited by

                                          Thanks GertJan, got it working now :)

                                          1 Reply Last reply Reply Quote 0
                                          • GertjanG
                                            Gertjan
                                            last edited by

                                            I'll give it a try to 'backport' all this to pfSense 2.2 Release.
                                            I'm pretty sure its possible.

                                            No "help me" PM's please. Use the forum, the community will thank you.
                                            Edit : and where are the logs ??

                                            1 Reply Last reply Reply Quote 0
                                            • First post
                                              Last post
                                            Copyright 2025 Rubicon Communications LLC (Netgate). All rights reserved.