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

    Disable Concurent User Is Useless

    Scheduled Pinned Locked Moved Captive Portal
    11 Posts 5 Posters 2.0k 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.
    • DerelictD
      Derelict LAYER 8 Netgate
      last edited by

      I would just expire that voucher if you notice and actually care.

      Chattanooga, Tennessee, USA
      A comprehensive network diagram is worth 10,000 words and 15 conference calls.
      DO NOT set a source address/port in a port forward or firewall rule unless you KNOW you need it!
      Do Not Chat For Help! NO_WAN_EGRESS(TM)

      1 Reply Last reply Reply Quote 0
      • A
        ayruel
        last edited by

        @Derelict:

        I would just expire that voucher if you notice and actually care.

        U are right but isnt my server only being busy ..me too..  :(

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

          Try this :

          Open /etc/inc/captiveportal.inc
          Goto line 2251.

          You will find :

          ....
          		/* on the same ip */
          		if ($cpentry[2] == $clientip) {
          			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
          				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
          			} else {
          				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
          			}
          			$sessionid = $cpentry[5];
          			break;
          		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
          			// user logged in with an active voucher. Check for how long and calculate
          			// how much time we can give him (voucher credit - used time)
          			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
          			if ($remaining_time < 0) { // just in case.
          				$remaining_time = 0;
          			}
          
          			/* This user was already logged in so we disconnect the old one */
          			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
          			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
          			$unsetindexes[] = $cpentry[5];
          			break;
          		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
          			/* on the same username */
          ....
          

          See also line https://github.com/pfsense/pfsense/blob/9dd655a0c36b907979d497586f9789170de748de/src/etc/inc/captiveportal.inc#L2277 - the
          break;
          command on line 2277 (the github version has env 20 lines more because of the constant evolving of pfSense)
          Insert like this :

          
          		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username) && (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) ) {
          			// user logged in with an active voucher. Check for how long and calculate
          			// how much time we can give him (voucher credit - used time)
          			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
          			if ($remaining_time < 0) { // just in case.
          				$remaining_time = 0;
          			}
          
          			/* This user was already logged in so .... we do nothing because "noconcurrentlogins" is set */
          			/* See https://forum.pfsense.org/index.php?topic=147038.0 */ 
          			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
          			return 0;
          			break;
          
          

          Now, the entire foreach loop look like this :

          	foreach ($cpdb as $cpentry) {
          		if (empty($cpentry[11])) {
          			$cpentry[11] = 'first';
          		}
          		/* on the same ip */
          		if ($cpentry[2] == $clientip) {
          			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
          				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
          			} else {
          				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
          			}
          			$sessionid = $cpentry[5];
          			break;
          
          		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
          			// user logged in with an active voucher. Check for how long and calculate
          			// how much time we can give him (voucher credit - used time)
          			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
          			if ($remaining_time < 0) { // just in case.
          				$remaining_time = 0;
          			}
          
          			/* This user was already logged in so we disconnect the old one */
          			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
          			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
          			$unsetindexes[] = $cpentry[5];
          			break;
          
          		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
          			/* on the same username */
          			if (strcasecmp($cpentry[4], $username) == 0) {
          				/* This user was already logged in so we disconnect the old one */
          				captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
          				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
          				$unsetindexes[] = $cpentry[5];
          				break;
          			}
          		}
          	}
          

          The new special case is
          If vouchers are used and username is not "unauthenticated" and username is already present and noconcurrentlogins is set then the result will be :
          A log line : "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
          And a return 0; so the user will be presented a "voucher expired" message (good english for : "use your own voucher - don't borrow !!" ;)

          Be carefull : I tested this. It worked. A second login using a voucher that was already used ones - and has an session - from another device was ignored, the user will get an error page.
          Normally, the last login using a voucher will remain if "noconcurrentlogins" is set, the old, existing session, is deleted
          You wanted the FIRST session to stay up- and no further usage of the same voucher.

          So I "abused" the "noconcurrentlogins" setting somewhat making a special case for it.

          If this works for you, you have to apply this patch every time you upgrade ( and /etc/inc/captiveportal.inc gets modified/upgraded).

          edit :
          "noconcurrentlogins" should be a tri-state flag in the GUI.
          Like not set = 0 : user can login using the same identification multiple time
          Or
          Set to 1 : user can only use 1 login, the last login will have a session - earlier session using voucher or login with user and paswword will be deleted.
          Or
          Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

          Option 0 and 1 exist already - "2" will be the new one.

          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
          • A
            ayruel
            last edited by

            @Gertjan:

            Try this :

            Open /etc/inc/captiveportal.inc
            Goto line 2251.

            You will find :

            ....
            		/* on the same ip */
            		if ($cpentry[2] == $clientip) {
            			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
            			} else {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
            			}
            			$sessionid = $cpentry[5];
            			break;
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so we disconnect the old one */
            			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            			$unsetindexes[] = $cpentry[5];
            			break;
            		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
            			/* on the same username */
            ....
            

            See also line https://github.com/pfsense/pfsense/blob/9dd655a0c36b907979d497586f9789170de748de/src/etc/inc/captiveportal.inc#L2277 - the
            break;
            command on line 2277 (the github version has env 20 lines more because of the constant evolving of pfSense)
            Insert like this :

            
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username) && (isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) ) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so .... we do nothing because "noconcurrentlogins" is set */
            			/* See https://forum.pfsense.org/index.php?topic=147038.0 */ 
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
            			return 0;
            			break;
            
            

            Now, the entire foreach loop look like this :

            	foreach ($cpdb as $cpentry) {
            		if (empty($cpentry[11])) {
            			$cpentry[11] = 'first';
            		}
            		/* on the same ip */
            		if ($cpentry[2] == $clientip) {
            			if (isset($config['captiveportal'][$cpzone]['nomacfilter']) || $cpentry[3] == $clientmac) {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING OLD SESSION");
            			} else {
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - REUSING IP {$cpentry[2]} WITH DIFFERENT MAC ADDRESS {$cpentry[3]}");
            			}
            			$sessionid = $cpentry[5];
            			break;
            			
            		} elseif (($attributes['voucher']) && ($username != 'unauthenticated') && ($cpentry[4] == $username)) {
            			// user logged in with an active voucher. Check for how long and calculate
            			// how much time we can give him (voucher credit - used time)
            			$remaining_time = $cpentry[0] + $cpentry[7] - $allow_time;
            			if ($remaining_time < 0) { // just in case.
            				$remaining_time = 0;
            			}
            
            			/* This user was already logged in so we disconnect the old one */
            			captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            			captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            			$unsetindexes[] = $cpentry[5];
            			break;
            
            		} elseif ((isset($config['captiveportal'][$cpzone]['noconcurrentlogins'])) && ($username != 'unauthenticated')) {
            			/* on the same username */
            			if (strcasecmp($cpentry[4], $username) == 0) {
            				/* This user was already logged in so we disconnect the old one */
            				captiveportal_disconnect($cpentry, $radiusservers[$cpentry[11]], 13);
            				captiveportal_logportalauth($cpentry[4], $cpentry[3], $cpentry[2], "CONCURRENT LOGIN - TERMINATING OLD SESSION");
            				$unsetindexes[] = $cpentry[5];
            				break;
            			}
            		}
            	}
            

            The new special case is
            If vouchers are used and username is not "unauthenticated" and username is already present and noconcurrentlogins is set then the result will be :
            A log line : "CONCURRENT LOGIN - TERMINATING NEW SESSION - NO noconcurrentlogins !");
            And a return 0; so the user will be presented a "voucher expired" message (good english for : "use your own voucher - don't borrow !!" ;)

            Be carefull : I tested this. It worked. A second login using a voucher that was already used ones - and has an session - from another device was ignored, the user will get an error page.
            Normally, the last login using a voucher will remain if "noconcurrentlogins" is set, the old, existing session, is deleted
            You wanted the FIRST session to stay up- and no further usage of the same voucher.

            So I "abused" the "noconcurrentlogins" setting somewhat making a special case for it.

            If this works for you, you have to apply this patch every time you upgrade ( and /etc/inc/captiveportal.inc gets modified/upgraded).

            edit :
            "noconcurrentlogins" should be a tri-state flag in the GUI.
            Like not set = 0 : user can login using the same identification multiple time
            Or
            Set to 1 : user can only use 1 login, the last login will have a session - earlier session using voucher or login with user and paswword will be deleted.
            Or
            Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

            Option 0 and 1 exist already - "2" will be the new one.

            Thank So much

            I Hope this :

            Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

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

              @ayruel:

              …
              I Hope this :
              Set to 2 : user can only login ones, further logins using the same identification (voucher or login with user and paswword) will not be granted.

              Ask for a Feature request here : https://redmine.pfsense.org/projects/pfsense/issues?per_page=100&set_filter=1&tracker_id=2  ;)

              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
              • T
                tattchua
                last edited by

                Hi,

                i am using CP in a hotel environment, login with one password, eg. 222, changed weekly. USERNAME hidden for convenience.

                however, i have other "monthly subscribers" to my CP, same channel, how do i limit them to 2 or 3 devices, or even 5 devices. is it 0, 1, or 3 and so on as above?

                pfsense 2.4.4 and freeradius 3

                TQSM!

                rgds

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

                  @tattchua said in Disable Concurent User Is Useless:

                  i am using CP in a hotel environment, ..
                  how do i limit them to 2 or 3 devices, or even 5 devices. is it 0, 1, or 3 and so on as above?
                  pfsense 2.4.4 and freeradius 3

                  Same here.
                  This does it for me :

                  0_1550477745115_c7338477-609d-43ab-a2af-812f5189669a-image.png

                  Limiting for 2 (or 1 ?) login.

                  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
                  • ?
                    A Former User @Gertjan
                    last edited by

                    @Gertjan hi sir! is this still working in 2.4.4 p3? using vouchers (local database authentication) not freeradius. thanks!

                    GertjanG 1 Reply Last reply Reply Quote 0
                    • GertjanG
                      Gertjan @A Former User
                      last edited by

                      @dyobetem said in Disable Concurent User Is Useless:

                      is this still working in 2.4.4 p3?

                      Ac said, when using FreeRadius - Local database : guess not.

                      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
                      • ?
                        A Former User @Gertjan
                        last edited by

                        @Gertjan thanks and noted sir!

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