def check_login_headers(headers): # The Cookie class is really meant to be used server side; so it has # good support for parsing Cookie headers, and generating Set-Cookie # headers. We're abusing it here to do "client-side' processing # where we need to parse Set-Cookie headers and generate Cookie headers. global login_cookie_header login_cookie = None for header, value in headers.items(): if header.lower() == "set-cookie": if login_cookie == None: login_cookie = Cookie.SimpleCookie() login_cookie.load(value) login_header = "" if login_cookie is None: return for key, morsel in login_cookie.iteritems(): if login_cookie_header is None: login_cookie_header = "" else: login_cookie_header += "; " login_cookie_header += key + "=" + morsel.coded_value # attributes in the Cookie: header are represented as $Attribute # to distinguish them from cookie names, since it's: # Cookie: name=val; attr=val; attr=val; name=val; attr=val if 'path' in morsel and morsel['path'] != '': login_cookie_header += "; $Path=" + Cookie._quote(morsel['path']) if 'domain' in morsel and morsel['domain'] != '': login_cookie_header += "; $Domain=" + Cookie._quote(morsel['domain'])
def check_login_headers(headers): # The Cookie class is really meant to be used server side; so it has # good support for parsing Cookie headers, and generating Set-Cookie # headers. We're abusing it here to do "client-side' processing # where we need to parse Set-Cookie headers and generate Cookie headers. global login_cookie_header login_cookie = None for header, value in headers.items(): if header.lower() == "set-cookie": if login_cookie == None: login_cookie = Cookie.SimpleCookie() login_cookie.load(value) login_header = "" if login_cookie is None: return for key, morsel in login_cookie.iteritems(): if login_cookie_header is None: login_cookie_header = "" else: login_cookie_header += "; " login_cookie_header += key + "=" + morsel.coded_value # attributes in the Cookie: header are represented as $Attribute # to distinguish them from cookie names, since it's: # Cookie: name=val; attr=val; attr=val; name=val; attr=val if 'path' in morsel and morsel['path'] != '': login_cookie_header += "; $Path=" + Cookie._quote(morsel['path']) if 'domain' in morsel and morsel['domain'] != '': login_cookie_header += "; $Domain=" + Cookie._quote( morsel['domain'])
def __call__(self): token = None if 'HTTP_COOKIE' in self.environ: cookie = Cookie.SimpleCookie(self.environ['HTTP_COOKIE']) if 'htsql-csrf-token' in cookie: token = cookie['htsql-csrf-token'].value secret = None try: secret = binascii.a2b_hex(token) except TypeError: pass if secret is None or len(secret) != self.csrf_secret_length: token = None header = self.environ.get('HTTP_X_HTSQL_CSRF_TOKEN') env = context.env can_read = env.can_read can_write = env.can_write if not (token and header and token == header): addon = context.app.tweak.csrf can_read = can_read and addon.allow_cs_read can_write = can_write and addon.allow_cs_write if not token: token = binascii.b2a_hex(os.urandom(self.csrf_secret_length)) path = self.environ.get('SCRIPT_NAME', '') if not path.endswith('/'): path += '/' morsel = Cookie.Morsel() morsel.set('htsql-csrf-token', token, Cookie._quote(token)) morsel['path'] = path cookie = morsel.OutputString() # FIXME: avoid state changes in the adapter. original_start_response = self.start_response def start_response(status, headers, exc=None): headers = headers+[('Set-Cookie', cookie)] return original_start_response(status, headers, exc) self.start_response = start_response with env(can_read=can_read, can_write=can_write): return super(CSRFWSGI, self).__call__()
def cookie_encode(self, val): strval = str(val) strval += ' ' * (8 - len(strval) % 8) return Cookie._quote(self.cipher.encrypt(strval))
def __setitem__(self, key, value): strval = str(value) sig = b64encode(hmac.new(self.key + str(key), strval, sha256).digest()) cval = Cookie._quote(strval + sig) self._BaseCookie__set(key, strval, cval)