ac7d03
From df5600dc012465f2f18a54aa451353f0fd9d5453 Mon Sep 17 00:00:00 2001
ac7d03
From: Simo Sorce <simo@redhat.com>
ac7d03
Date: Thu, 23 Mar 2017 17:49:27 -0400
ac7d03
Subject: [PATCH] Prevent churn on ccaches
ac7d03
ac7d03
We slice down the received cookie so that just the content that matter
ac7d03
is preserved. Thi is ok because servers can't trust anything else anyway
ac7d03
and will accept a cookie with the ancillary data missing.
ac7d03
ac7d03
By removing variable parts like the expiry component added by
ac7d03
mod_session or the Expiration or Max-Age metadata we keep only the part
ac7d03
of the cookie that changes only when a new session is generated.
ac7d03
ac7d03
This way when storing the cookie we actually add a new entry in the
ac7d03
ccache only when the session actually changes, and this prevents churn
ac7d03
on FILE based ccaches.
ac7d03
ac7d03
Related https://pagure.io/freeipa/issue/6775
ac7d03
ac7d03
Signed-off-by: Simo Sorce <simo@redhat.com>
ac7d03
Reviewed-By: Christian Heimes <cheimes@redhat.com>
ac7d03
Reviewed-By: Alexander Bokovoy <abokovoy@redhat.com>
ac7d03
---
ac7d03
 ipalib/rpc.py | 17 ++++++++++++++++-
ac7d03
 1 file changed, 16 insertions(+), 1 deletion(-)
ac7d03
ac7d03
diff --git a/ipalib/rpc.py b/ipalib/rpc.py
ac7d03
index c1ceeec197c4a9c55f303f0fd431e86adb389598..5c49bd2456b7e564043a886c840fa2678060f9e3 100644
ac7d03
--- a/ipalib/rpc.py
ac7d03
+++ b/ipalib/rpc.py
ac7d03
@@ -38,6 +38,7 @@ import os
ac7d03
 import locale
ac7d03
 import base64
ac7d03
 import json
ac7d03
+import re
ac7d03
 import socket
ac7d03
 import gzip
ac7d03
 
ac7d03
@@ -737,6 +738,20 @@ class KerbTransport(SSLTransport):
ac7d03
             self.send_content(connection, request_body)
ac7d03
             return connection
ac7d03
 
ac7d03
+    # Find all occurrences of the expiry component
ac7d03
+    expiry_re = re.compile(r'.*?(&expiry=\d+).*?')
ac7d03
+
ac7d03
+    def _slice_session_cookie(self, session_cookie):
ac7d03
+        # Keep only the cookie value and strip away all other info.
ac7d03
+        # This is to reduce the churn on FILE ccaches which grow every time we
ac7d03
+        # set new data. The expiration time for the cookie is set in the
ac7d03
+        # encrypted data anyway and will be enforced by the server
ac7d03
+        http_cookie = session_cookie.http_cookie()
ac7d03
+        # We also remove the "expiry" part from the data which is not required
ac7d03
+        for exp in self.expiry_re.findall(http_cookie):
ac7d03
+            http_cookie = http_cookie.replace(exp, '')
ac7d03
+        return http_cookie
ac7d03
+
ac7d03
     def store_session_cookie(self, cookie_header):
ac7d03
         '''
ac7d03
         Given the contents of a Set-Cookie header scan the header and
ac7d03
@@ -787,7 +802,7 @@ class KerbTransport(SSLTransport):
ac7d03
         if session_cookie is None:
ac7d03
             return
ac7d03
 
ac7d03
-        cookie_string = str(session_cookie)
ac7d03
+        cookie_string = self._slice_session_cookie(session_cookie)
ac7d03
         root_logger.debug("storing cookie '%s' for principal %s", cookie_string, principal)
ac7d03
         try:
ac7d03
             update_persistent_client_session_data(principal, cookie_string)
ac7d03
-- 
ac7d03
2.12.1
ac7d03