PHP Session expiring and system force logout - session-timeout

When i left system is in idle mode( means inactive mode) , and when i come to access system after 1 or 2 hours, system reacts well when i use single window but when i generate recieppt through ajax and open the receipt in window.popup window then the system logs out. and redirect to login page because session expired in idle mode , even if i set the session for lifetime,
case '1':
$_SESSION['kid'] = $q4['id'];
ini_set('session.gc_maxlifetime', 100*60*60);
session_set_cookie_params(0,"/");
break;
plese help ......

ini_set('session.gc_maxlifetime', ...) should be called before session_start()

Related

Is a new process needed for a new pam(_systemd) session?

As an Experiment I am writing a small linux display manager. As references, I use lightdm, especially https://github.com/canonical/lightdm/blob/master/src/session-child.c, and the systemd documentation page https://www.freedesktop.org/wiki/Software/systemd/writing-display-managers/ .
For the start, it allways manages tty9, and restarting after logout is handled by systemd (Restart=always).
So what the program does is
show the login prompt (the "greeter" session)
start pam session for greeter
pam_authenticate the user
end pam session for greeter
start the user session.
start pam session for user
fork, switch user, cd, exec
Lightdm uses two session-child process for this, but for simplicity I tried to do it in one.
When I comment out the session start for the "greeter", like here: https://github.com/TheJonny/textdm/blob/ba32d87f23816ef78763016b4c748a0875ae93f6/src/main.rs#L86, I am able to log in and start weston (starting the X server is currently not finished). If I do use a session for the greeter (lines 86 and 126 enabled), pam_systemd fails with the debug messages
Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Asking logind to create session: uid=1001 pid=4084383 service=textdm type=wayland class=user desktop= seat=seat0 vtnr=9 tty>
Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Session limits: memory_max=n/a tasks_max=n/a cpu_weight=n/a io_weight=n/a runtime_max_sec=n/a
Feb 23 01:30:09 io textdm[4084383]: pam_systemd(textdm:session): Not creating session: Already running in a session or user slice
It does not show up in loginctl, does not set $XDG_RUNTIME_DIR, and then weston failes to start.
So my question is: can this (only) be solved by using separete processes? Is there another way to fully tear down the pam_systemd session?
(I am using the pam-client binding for rust, https://docs.rs/pam-client/0.2.0/pam_client/struct.Context.html#method.open_session should call pam_open_session() and pam_setcred(), and the drop should close the session and credentials.)
to clean up, I answer my question.
https://github.com/systemd/systemd/blob/756755d0fc5a0ef380416a54346b6438c3fb7ba5/src/login/pam_systemd.c#L1020
pam_systemd intentionally leaks a pipe file descriptor, and logind delays closing the session until this is closed, that is until the process using pam_systemd has exited.

Firebase onDisconnect() firing multiple times

Building an app with presence following the firebase docs, is there a scenario where the on-disconnect fires when the app is still connected? We see instances where the presence node shows the app as going offline and then back online within a few seconds when we aren't losing a network connection.
We are seeing on multiple embedded devices installed in the field where presence is set to false and then almost immediately right back to true and it's occurring on all the devices within a few seconds of each other. From the testing we have done and the docs online we know that if we lose internet connection on the device it takes roughly 60 seconds before the timeout on the server fires the onDisconnect() method.
We have since added code in the presence method that allows the device if it sees the presence node be set to false while the app is actually running it will reset the presence back to true. At times when this happens we get a single write back to true and that is the end of it, other times it is like the server and client are fighting each other and the node is reset to true numerous times over the course of 50-200 milliseconds. We monitor this by pushing to another node within the device GUID each time we are forcing presence back to true. This only occurs while the module is running and after it initially establishes presence.
Here is the method that we call from our various modules that are running on the device so that we can monitor the status of each of the modules at any given time.
exports.online = function (program, currentProgram) {
var programPath = process.env.FIREBASE_DEVICES + process.env.GUID + '/status/' + program
var onlinePath = process.env.FIREBASE_DEVICES + process.env.GUID + '/statusOnlineTimes/' + program
var programRef = new firebase(programPath);
var statusRef = new firebase(process.env.FIREBASE_DEVICES + process.env.GUID + '/status/bootup');
var onlineRef = new firebase(onlinePath)
amOnline.on('value', function(snapshot) {
if (snapshot.val()) {
programRef.onDisconnect().set(false);
programRef.set(true);
programRef.on('value', function(snapshot){
if (snapshot.val() == false){
programRef.set(true);
console.log('[NOTICE] Resetting', program, 'module status back to True after Fireabase set to False')
var objectToPush = {
program: program,
time: new Date().toJSON()
}
onlineRef.push(objectToPush)
}
})
if (currentProgram != undefined) {
statusRef.onDisconnect().set('Offline')
statusRef.set(currentProgram)
}
}
});
The question we have is there ever an instance where Firebase is calling the onDisconnect() method even though it really isn't losing its status? We had instances where we would see the device go offline and then back online within 60 seconds before we added the reset code. The reset code was to combat another issue we had in the field where if the power were interrupted to the device and it did not make a clean exit, the device could reboot and and reset the presence with a new UID before the timeout for the prior instance had fired. Then once the timeout fired the device would show as offline even though it was actually online.
So we were able to stop the multiple pushes that were happening when the device reconnected by adding a programRef.off() call directly before the programRef.on(...) call. What we determined to be happening is that anytime the device went online from an offline state and the amOnline.on(...) callback fired it created a new listener.
Now we are able to handle the case where a onDisconnect() fires from a earlier program PID and overwrites the currently active program with a status of offline. This seems to solve the issue we are having with the race condition of the devices in the field able to reboot and regain connection prior to the onDisconnect() firing for the instance that was not cleanly exited.
We are still having an issue where all of the devices are going off and then back online at approximately the same time (within 1-3 seconds of each other). Are there any times where Firebase resets the ./info/connected node? Because we are monitoring presence and actually logging on and off events maybe we are just catching an event that most people don't see? Or is there something that we are doing wrong?

Make Watir-webdriver to load a page for limited time and to be able to retrieve information later

I know that there are several questions related to implementation of waiting and timeouts in Watir, however I have not found an answer to my problem (which must be common). I use Watir-webdriver for testing of a page that due to AJAX implementation loads portion-by-portion for very long time (more than 5 min). I need to be able just to sample this page for a limited time (20-40 sec) and to be able to analyze the information that is loaded during this short time. However, as I know, there is no straightforward direct mechanism to tell Watir::Browser to stop. I can use the Timeout, but although my script gets the control after rescue, it is impossible to interrogate the browser and verify the information that it is able to received during the timeout window. All I can do at this point is to kill the process and restart the browser as discussed here: Make headless browser stop loading page and elsewhere.
The code below illustrates my situation. In this example I have a global timeout (30 sec) and a local timeout (15 sec) used for reading the page. It never gets to b.text call; the script just outputs the first exception after 15 sec and then it keeps waiting for the browser to be released and after the global timeout of 30 sec prints the second exception message.
Time out. Got into exception branch
Dropped to bottom rescue.
The end.
I also tried to send an 'escape' key to the browser, but any communication with it while it is in the goto method is impossible. Any tips and suggestions will be appreciated!
require 'watir-webdriver'
require 'timeout'
client = Selenium::WebDriver::Remote::Http::Default.new
client.timeout = 30 # Set the global timeout
b = Watir::Browser.new :chrome, :http_client => client
my_url = '...here is my address...'
begin
begin
Timeout::timeout(15) { b.goto my_url } # Access the page with local timeout
b.close # if all is unbelievably good and the page is loaded
rescue Exception => e
puts 'Time out. Got into exception branch'
if b.text.include? 'my_text' # NEVER GETS HERE
puts 'Yes, I see the text!'
else
puts 'I do not see the text.'
end
end
rescue Exception => e
puts 'Dropped to bottom rescue.'
end
puts 'The end.'
Watir relies on Selenium WebDriver to handle calls to the browser. At this time all browsers require that the document.readyState of the current frame return "complete" before returning control to your code.
A recent update to the webdriver specification appears to allow for the possibility of a browser driver implementing a page loading strategy that is not blocking, but it is not a requirement and is not supported at this time.
https://w3c.github.io/webdriver/webdriver-spec.html#the-page-load-strategy

How can I logout an administrator in SilverStripe 3.1.x after period of inactivity?

How do I expire the administrator session after a period of inactivity in SilverStripe 3.1.x? Is there a config option for this?
I searched and found the following code snippet, which, when placed in the Page_Controller class, works for frontend users, but totally ineffective in the administration area.
public function init() {
parent::init();
self::logoutInactiveUser();
}
public static function logoutInactiveUser() {
$inactivityLimit = 1; // in Minutes - deliberately set to 1 minute for testing purposes
$inactivityLimit = $inactivityLimit * 60; // Converted to seconds
$sessionStart = Session::get('session_start_time');
if (isset($sessionStart)){
$elapsed_time = time() - Session::get('session_start_time');
if ($elapsed_time >= $inactivityLimit) {
$member = Member::currentUser();
if($member) $member->logOut();
Session::clear_all();
$this->redirect(Director::baseURL() . 'Security/login');
}
}
Session::set('session_start_time', time());
}
After over 1 minute of inactivity, the admin user is still logged in and the session has not timed out.
For people like myself still searching for a solution to this, there's a much simpler alternative. As it turns out, the only good solution at the moment is indeed to disable LeftAndMain.session_keepalive_ping and simon_w's solution will not work precisely because of this ping. Also, disabling this ping should not cause data loss (at least not for SilverStripe 3.3+) because the user will be presented with an overlay when they attempt to submit their work. After validating their credentials, their data will be submitted to the server as usual.
Also, for anyone who (like myself) was looking for a solution on how to override the CMS ping via LeftAndMain.session_keepalive_ping using _config.yml keep reading.
Simple Fix: In your mysite/_config.php, simply add:
// Disable back-end AJAX calls to /Security/ping
Config::inst()->update('LeftAndMain', 'session_keepalive_ping', false);
This will prevent the CMS from refreshing the session which will naturally expire on it's own behind the scenes (and will not be submitted on the next request). That way, the setting you may already have in _config.yml dictating the session timeout will actually be respected and allowing you to log out a user who's been inactive in the CMS. Again, data should not be lost for the reasons mentioned in the first paragraph.
You can optionally manually override the session timeout value in mysite/_config/config.yml to help ensure it actually expires at some explicit time (e.g. 30min below):
# Set session timeout to 30min.
Session:
timeout: 1800
You may ask: Why is this necessary?
Because, while the bug (or functionality?) preventing you from overriding the LeftAndMain.session_keepalive_ping setting to false was supposedly fixed in framework PR #3272 it was actually reverted soon thereafter in PR #3275
I hope this helps anyone else confused by this situation like I was!
This works, but would love to hear from the core devs as to whether or not this is best practice.
In mysite/code I created a file called MyLeftAndMainExtension.php with the following code:
<?php
class MyLeftAndMainExtension extends Extension {
public function onAfterInit() {
self::logoutInactiveUser();
}
public static function logoutInactiveUser() {
$inactivityLimit = 1; // in Minutes - deliberately set to 1 minute for testing
$inactivityLimit = $inactivityLimit * 60; // Converted to seconds
$sessionStart = Session::get('session_start_time');
if (isset($sessionStart)){
$elapsed_time = time() - Session::get('session_start_time');
if ($elapsed_time >= $inactivityLimit) {
$member = Member::currentUser();
if($member) $member->logOut();
Session::clear_all();
Controller::curr()->redirect(Director::baseURL() . 'Security/login');
}
}
Session::set('session_start_time', time());
}
}
Then I added the following line to mysite/_config.php
LeftAndMain::add_extension('MyLeftAndMainExtension');
That seemed to do the trick. If you prefer to do it through yml, you can add this to mysite/_config/config.yml :
LeftAndMain:
extensions:
- MyLeftAndMainExtension
The Session.timeout config option is available for setting an inactivity timeout for sessions. However, setting it to anything greater than 5 minutes isn't going to work in the CMS out of the box.
Having a timeout in the CMS isn't productive, and your content managers will end up ruing the timeout. This is because it is possible (and fairly common) to be active in the CMS, while appearing inactive from the server's perspective (say, you're writing a lengthy article). As such, the CMS is designed to send a ping back to the server every 5 minutes to ensure users are logged in. While you can stop this behaviour by setting the LeftAndMain.session_keepalive_ping config option to false, I strongly recommended against doing so.

Issue with dialing REGISTERED (but offline) users

i'm facing the following scenario:
we have to local (REGISTERED) users (iOS apps pjSIP) which initiating local calls between each other.
the problem arise when one of the users (let's say user B) is closing the application few minutes after he successfully REGISTERS.
now, when user A tries to call user B we see that the INVITE is sent but we got no reply (e.g 180 ringing) from User B.
Note: when we are sending an invite to User B he get's Push notification to his device what cases him to open the app (and to Re-REGISTER)
our targets are:
1. determinate if user B (e.g the callee) is reachable before we are sending an INVITE in cases User B App is closed and his extension is still REGISTERED
2. be able to send invite to user B right after he REGISTER
we tried to solve this issue from many directions:
1.Qualify - tried to decrease the qualify time of the registersion period so user B will be UNAVAILABLE as soon as possible (and we will check the device state before we will dial) but it may cause to massive OPTIONS on our network, and it's not going to solve target #2
2.AMI Service - it can catch events like: User A Dials user B , User B is Ringing (180 Ringing) and save those statuses to ASTDB . all this logic will be prefomed before we will launch the dial.
this solution is clumsy and to cmplicated and it requires to watch yet another service
after some research i'v got to the conclusion that the most suitable solution will be to store the time of the last OPTIONS reply of each extension(requires a patch in chan_sip.c) . re-trigger sip options qualify request to user B before User A Dials . if the original value (e.g before we re-triggered the OPTIONS) is equal the value after we trigged the OPTIONS it means that User B has not replied OPTIONS.
i'm attaching the changes i'v preformed to complete this task.
i would like to know if solution for the issue is suitable and valid and of course if there is a better way to preform it.
These is the change in chan_sip (using asterisk 11.7)
i'v prefomed changes only on the following lines:
23492 to 23500
23485 /*! \brief Handle qualification responses (OPTIONS) */
23486 static void handle_response_peerpoke(struct sip_pvt *p, int resp, struct sip_request *req)
23487 {
23488 struct sip_peer *peer = /* sip_ref_peer( */ p->relatedpeer /* , "bump refcount on p, as it is being used in this function(handle_response_peerpoke)")*/ ; /* hope this is already refcounted! */
23489 int statechanged, is_reachable, was_reachable;
23490 int pingtime = ast_tvdiff_ms(ast_tvnow(), peer->ps);
23491
23492 time_t result = time(NULL);
23493 result = (int)result;
This is how should implement dialplan with the patch:
Dial(SIP/${dest},10,Rgb(check_extension,s,1));
I'm sending the call to context before inviting ( with the "b" option)
context check_extension {
s => {
Set(IS_REACHABLE=0);
Verbose(KOLA/LastQualify/${DEST}); // Display User B initial quliafy
Set(INITIAL_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // Store it
for(loop=0;${loop}<60;dialLoop=${loop}+1) { // Loop untill the qualify will be changes
System(/usr/sbin/asterisk -rx "sip qualify peer ${DEST}");
Wait(2); // we need to wait a while for a response
Set(LAST_QUALIFY=${DB(KOLA/LastQualify/${DEST})}); // set the new qualify
if (${LAST_QUALIFY} > ${INITIAL_QUALIFY}) { // if the new qualify is newer, User B is reachable
Set(IS_REACHABLE=1);
break;
}
}
if (${IS_REACHABLE} = 0) {
Verbose(Peer is not reachable);
Hangup();
}
}
}
Best option for that is not use asterisk.
Use kamailio or opensips project, it can handle thousands of options packets.
Also you HAVE rewrite your app so when it closed it UNREGISTER, as that described in sip RFC.
To summarize: you are using buggy application, and triing do on asterisk thing it not designed to(large amount of users with options). So correct answer - use correct tools for this task.

Resources