defget_pin_and_cookie_name(app): """Given an application object this returns a semi-stable 9 digit pin code and a random key. The hope is that this is stable between restarts to not make debugging particularly frustrating. If the pin was forcefully disabled this returns `None`.
Second item in the resulting tuple is the cookie name for remembering. """ pin = os.environ.get("WERKZEUG_DEBUG_PIN") rv = None num = None
# Pin was explicitly disabled if pin == "off": returnNone, None
# Pin was provided explicitly if pin isnotNoneand pin.replace("-", "").isdigit(): # If there are separators in the pin, return it directly if"-"in pin: rv = pin else: num = pin
try: # getuser imports the pwd module, which does not exist in Google # App Engine. It may also raise a KeyError if the UID does not # have a username, such as in Docker. username = getpass.getuser() except (ImportError, KeyError): username = None
mod = sys.modules.get(modname)
# This information only exists to make the cookie unique on the # computer, not as a security feature. probably_public_bits = [ username, modname, getattr(app, "__name__", app.__class__.__name__), getattr(mod, "__file__", None), ]
# This information is here to make it harder for an attacker to # guess the cookie name. They are unlikely to be contained anywhere # within the unauthenticated debug page. private_bits = [str(uuid.getnode()), get_machine_id()]
h = hashlib.md5() for bit in chain(probably_public_bits, private_bits): ifnot bit: continue ifisinstance(bit, text_type): bit = bit.encode("utf-8") h.update(bit) h.update(b"cookiesalt")
cookie_name = "__wzd" + h.hexdigest()[:20]
# If we need to generate a pin we salt it a bit more so that we don't # end up with the same value and generate out 9 digits if num isNone: h.update(b"pinsalt") num = ("%09d" % int(h.hexdigest(), 16))[:9]
# Format the pincode in groups of digits for easier remembering if # we don't have a result yet. if rv isNone: for group_size in5, 4, 3: iflen(num) % group_size == 0: rv = "-".join( num[x : x + group_size].rjust(group_size, "0") for x inrange(0, len(num), group_size) ) break else: rv = num
return rv, cookie_name
该函数如上所示。
从return rv, cookie_name 知道我们需要跟踪的是rv的变化
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15
pin = os.environ.get("WERKZEUG_DEBUG_PIN") rv = None num = None
# Pin was explicitly disabled if pin == "off": returnNone, None
# Pin was provided explicitly if pin isnotNoneand pin.replace("-", "").isdigit(): # If there are separators in the pin, return it directly if"-"in pin: rv = pin else: num = pin
h = hashlib.md5() for bit in chain(probably_public_bits, private_bits): ifnot bit: continue ifisinstance(bit, text_type): bit = bit.encode("utf-8") h.update(bit) h.update(b"cookiesalt")
cookie_name = "__wzd" + h.hexdigest()[:20] if num isNone: h.update(b"pinsalt") num = ("%09d" % int(h.hexdigest(), 16))[:9]
try: # getuser imports the pwd module, which does not exist in Google # App Engine. It may also raise a KeyError if the UID does not # have a username, such as in Docker. username = getpass.getuser() except (ImportError, KeyError): username = None
mod = sys.modules.get(modname)
# This information only exists to make the cookie unique on the # computer, not as a security feature. probably_public_bits = [ username, modname, getattr(app, "__name__", app.__class__.__name__), getattr(mod, "__file__", None), ] private_bits = [str(uuid.getnode()), get_machine_id()]
# machine-id is stable across boots, boot_id is not. for filename in"/etc/machine-id", "/proc/sys/kernel/random/boot_id": try: withopen(filename, "rb") as f: value = f.readline().strip() except IOError: continue
if value: linux += value break
# Containers share the same machine id, add some cgroup # information. This is used outside containers too but should be # relatively stable across boots. try: withopen("/proc/self/cgroup", "rb") as f: linux += f.readline().strip().rpartition(b"/")[2] except IOError: pass
if linux: return linux
# On OS X, use ioreg to get the computer's serial number. try: # subprocess may not be available, e.g. Google App Engine # https://github.com/pallets/werkzeug/issues/925 from subprocess import Popen, PIPE