Skip to content

Commit 4bcd041

Browse files
committed
Merge pull request #152 from gaudryc/fix_long_term_authentication_cookie_2
Fix long term authentication cookie (Part 2)
2 parents 59d9bf4 + fe5c140 commit 4bcd041

File tree

4 files changed

+52
-8
lines changed

4 files changed

+52
-8
lines changed

main/WebServer.cpp

Lines changed: 33 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -14848,7 +14848,7 @@ namespace http {
1484814848
}
1484914849

1485014850
/**
14851-
* Retrieve user session from store
14851+
* Retrieve user session from store, without remote host.
1485214852
*/
1485314853
const WebEmStoredSession CWebServer::GetSession(const std::string & sessionId) {
1485414854
//_log.Log(LOG_STATUS, "SessionStore : get...");
@@ -14858,13 +14858,27 @@ namespace http {
1485814858
_log.Log(LOG_ERROR, "SessionStore : cannot get session without id.");
1485914859
} else {
1486014860
std::vector<std::vector<std::string> > result;
14861-
result = m_sql.safe_query("SELECT SessionID, Username, AuthToken FROM UserSessions WHERE SessionID = '%q'",
14861+
result = m_sql.safe_query("SELECT SessionID, Username, AuthToken, ExpirationDate FROM UserSessions WHERE SessionID = '%q'",
1486214862
sessionId.c_str());
1486314863
if (result.size() > 0) {
1486414864
session.id = result[0][0].c_str();
1486514865
session.username = base64_decode(result[0][1]);
1486614866
session.auth_token = result[0][2].c_str();
14867-
// ExpirationDate is not used to restore the session
14867+
14868+
std::string sExpirationDate = result[0][3];
14869+
time_t now = mytime(NULL);
14870+
struct tm tm1;
14871+
localtime_r(&now, &tm1);
14872+
struct tm tExpirationDate;
14873+
tExpirationDate.tm_isdst = tm1.tm_isdst;
14874+
tExpirationDate.tm_year = atoi(sExpirationDate.substr(0, 4).c_str()) - 1900;
14875+
tExpirationDate.tm_mon = atoi(sExpirationDate.substr(5, 2).c_str()) - 1;
14876+
tExpirationDate.tm_mday = atoi(sExpirationDate.substr(8, 2).c_str());
14877+
tExpirationDate.tm_hour = atoi(sExpirationDate.substr(11, 2).c_str());
14878+
tExpirationDate.tm_min = atoi(sExpirationDate.substr(14, 2).c_str());
14879+
tExpirationDate.tm_sec = atoi(sExpirationDate.substr(17, 2).c_str());
14880+
session.expires = mktime(&tExpirationDate);
14881+
1486814882
// RemoteHost is not used to restore the session
1486914883
// LastUpdate is not used to restore the session
1487014884
}
@@ -14873,6 +14887,9 @@ namespace http {
1487314887
return session;
1487414888
}
1487514889

14890+
/**
14891+
* Save user session.
14892+
*/
1487614893
void CWebServer::StoreSession(const WebEmStoredSession & session) {
1487714894
//_log.Log(LOG_STATUS, "SessionStore : store...");
1487814895
if (session.id.empty()) {
@@ -14899,14 +14916,17 @@ namespace http {
1489914916
remote_host.c_str());
1490014917
} else {
1490114918
m_sql.safe_query(
14902-
"UPDATE UserSessions set AuthToken = '%q', ExpirationDate = '%q', RemoteHost = '%q' WHERE SessionID = '%q'",
14919+
"UPDATE UserSessions set AuthToken = '%q', ExpirationDate = '%q', RemoteHost = '%q', LastUpdate = datetime('now', 'localtime') WHERE SessionID = '%q'",
1490314920
session.auth_token.c_str(),
1490414921
szExpires,
1490514922
remote_host.c_str(),
1490614923
session.id.c_str());
1490714924
}
1490814925
}
1490914926

14927+
/**
14928+
* Remove user session and expired sessions.
14929+
*/
1491014930
void CWebServer::RemoveSession(const std::string & sessionId) {
1491114931
//_log.Log(LOG_STATUS, "SessionStore : remove...");
1491214932
if (sessionId.empty()) {
@@ -14917,6 +14937,15 @@ namespace http {
1491714937
sessionId.c_str());
1491814938
}
1491914939

14940+
/**
14941+
* Remove all expired user sessions.
14942+
*/
14943+
void CWebServer::CleanSessions() {
14944+
//_log.Log(LOG_STATUS, "SessionStore : clean...");
14945+
m_sql.safe_query(
14946+
"DELETE FROM UserSessions WHERE ExpirationDate < datetime('now', 'localtime')");
14947+
}
14948+
1492014949
} //server
1492114950
}//http
1492214951

main/WebServer.h

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -77,6 +77,7 @@ class CWebServer : public session_store
7777
const WebEmStoredSession GetSession(const std::string & sessionId);
7878
void StoreSession(const WebEmStoredSession & session);
7979
void RemoveSession(const std::string & sessionId);
80+
void CleanSessions();
8081

8182
private:
8283
void HandleCommand(const std::string &cparam, WebEmSession & session, const request& req, Json::Value &root);

webserver/cWebem.cpp

Lines changed: 12 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -902,6 +902,9 @@ void cWebem::SetZipPassword(std::string password)
902902

903903
void cWebem::SetSessionStore(session_store* sessionStore) {
904904
mySessionStore = sessionStore;
905+
if (mySessionStore != NULL) {
906+
mySessionStore->CleanSessions();
907+
}
905908
}
906909

907910
session_store* cWebem::GetSessionStore() {
@@ -1141,7 +1144,9 @@ std::string cWebemRequestHandler::generateSessionID()
11411144

11421145
std::string sessionId = GenerateMD5Hash(base64_encode((const unsigned char*)randomValue.c_str(), randomValue.size()));
11431146

1144-
//_log.Log(LOG_STATUS, "generate new session id token %s", sessionId.c_str());
1147+
#ifdef _DEBUG
1148+
_log.Log(LOG_STATUS, "generate new session id token %s", sessionId.c_str());
1149+
#endif
11451150

11461151
return sessionId;
11471152
}
@@ -1158,6 +1163,7 @@ std::string cWebemRequestHandler::generateAuthToken(const WebEmSession & session
11581163
randomValue = ss.str();
11591164

11601165
std::string authToken = base64_encode((const unsigned char*)randomValue.c_str(), randomValue.size());
1166+
11611167
#ifdef _DEBUG
11621168
_log.Log(LOG_STATUS, "generate new authentication token %s", authToken.c_str());
11631169
#endif
@@ -1411,6 +1417,7 @@ bool cWebemRequestHandler::checkAuthToken(WebEmSession & session) {
14111417
removeAuthToken(session.id);
14121418
return false;
14131419
}
1420+
14141421
#ifdef _DEBUG
14151422
//_log.Log(LOG_STATUS, "CheckAuthToken(%s_%s_%s) : user authenticated", session.id.c_str(), session.auth_token.c_str(), session.username.c_str());
14161423
#endif
@@ -1419,6 +1426,7 @@ bool cWebemRequestHandler::checkAuthToken(WebEmSession & session) {
14191426
// Restore session if user exists and session does not already exist
14201427
bool userExists = false;
14211428
session.username = storedSession.username;
1429+
session.expires = storedSession.expires;
14221430
std::vector<_tWebUserPassword>::iterator ittu;
14231431
for (ittu=myWebem->m_userpasswords.begin(); ittu!=myWebem->m_userpasswords.end(); ++ittu) {
14241432
if (ittu->Username == session.username) { // the user still exists
@@ -1427,13 +1435,15 @@ bool cWebemRequestHandler::checkAuthToken(WebEmSession & session) {
14271435
break;
14281436
}
14291437
}
1438+
14301439
if (!userExists) {
14311440
#ifdef _DEBUG
14321441
_log.Log(LOG_ERROR, "CheckAuthToken(%s_%s) : cannot restore session user not found", session.id.c_str(), session.auth_token.c_str());
14331442
#endif
14341443
removeAuthToken(session.id);
14351444
return false;
14361445
}
1446+
14371447
std::map<std::string, WebEmSession>::iterator itts = myWebem->m_sessions.find(session.id);
14381448
if (itts == myWebem->m_sessions.end()) {
14391449
#ifdef _DEBUG
@@ -1624,8 +1634,7 @@ void cWebemRequestHandler::handle_request( const std::string &sHost, const reque
16241634
if (myWebem->m_sessions[session.id].expires - 60 < atime)
16251635
{
16261636
myWebem->m_sessions[session.id].expires = atime + SESSION_TIMEOUT;
1627-
session.expires = myWebem->m_sessions[session.id].expires;
1628-
myWebem->m_sessions[session.id].auth_token = generateAuthToken(session, req); // do it after expires to save it also
1637+
myWebem->m_sessions[session.id].auth_token = generateAuthToken(myWebem->m_sessions[session.id], req); // do it after expires to save it also
16291638
send_cookie(rep, myWebem->m_sessions[session.id]);
16301639
}
16311640
}

webserver/session_store.hpp

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,7 @@ typedef struct _tWebEmStoredSession {
2020
} WebEmStoredSession;
2121

2222
/**
23-
* Gives access to the user session datastore.
23+
* Gives access to the user session store.
2424
*/
2525
class session_store {
2626
public:
@@ -38,6 +38,11 @@ class session_store {
3838
* Remove user session from store
3939
*/
4040
virtual void RemoveSession(const std::string & sessionId)=0;
41+
42+
/**
43+
* Remove expired user sessions from store
44+
*/
45+
virtual void CleanSessions()=0;
4146
};
4247

4348
}

0 commit comments

Comments
 (0)