def expired(daynumber, timestamp, validity): """Given the length of time a password is valid for, it checks if a daynumber/timestamp tuple is still valid. validity should be an integer tuple (DAYS, HOURS, MINUTES). Returns True for valid or False for invalid. Needs the dateutils module to get the current daynumber. >>> a, b, c = returndate() >>> today = daycount(a, b, c) >>> h, m = return_now() >>> expired(today, (h, m-2), (0,0,1)) False >>> expired(today, (h, m-2), (0,0,10)) True >>> expired(today, (h-2, m-2), (0,1,10)) False >>> expired(today-1, (h-2, m-2), (1,1,10)) False >>> expired(today-1, (h-2, m-2), (2,1,10)) True >>> """ if not DATEIN: raise ImportError("Need the dateutils module to use the 'expired' function.") h1, m1 = timestamp # h1, m1 are the hours and minutes of the timestamp d2, h2, m2 = validity # validity is how long the timestamp is valid for a, b, c = returndate() today = daycount(a, b, c) # today is number representing the julian day number of today h, m = return_now() # h, m are the hours and minutes of time now h1 = h1 + h2 m1 = m1 + m2 daynumber = daynumber + d2 # so we need to test if today, h, m are greater than daynumber, h1, m1 # But first we need to adjust because we might currently have hours above 23 and minutes above 59 while m1 > 59: h1 += 1 m1 -= 60 while h1 > 23: daynumber += 1 h1 -= 24 daynumber += d2 if today > daynumber: return False if today < daynumber: return True if h > h1: # same day return False if h < h1: return True if m > m1: # same hour return False else: return True
def savedetails(userdir, formdict, action=None): """ Given the form from a validated new login, it saves the details to the temporary store. It also cleans up any out of date ones that haven't been used. """ from dateutils import returndate, daycount from dataenc import pass_enc # tempstore = ConfigObj(userdir + 'temp.ini') if action: formdict['action'] = action year, month, day = returndate() today = daycount(year, month, day) # for section in tempstore: if section[4:].isdigit(): if int(section[4:]) > today + 30: name = tempstore[section]['username'] tempstore['pending'].remove(name) del tempstore[section] # ran = randomstring(4) while tempstore.has_key(ran+str(today)): ran = randomstring(4) key = ran+str(today) tempstore[key] = {} store = tempstore[key] for entry in formdict: if entry == 'pass1' or entry == 'pass2': store['password'] = formdict[entry] elif entry == 'login': pass else: store[entry] = formdict[entry] if not tempstore.has_key('pending'): tempstore['pending'] = [] tempstore['pending'].append(formdict['username']) tempstore.write() return pass_enc(key, timestamp=True, daynumber=True)
def savedetails(userdir, formdict, action=None): """ Given the form from a validated new login, it saves the details to the temporary store. It also cleans up any out of date ones that haven't been used. """ from dateutils import returndate, daycount from dataenc import pass_enc # tempstore = ConfigObj(userdir + 'temp.ini') if action: formdict['action'] = action year, month, day = returndate() today = daycount(year, month, day) # for section in tempstore: if section[4:].isdigit(): if int(section[4:]) > today + 30: name = tempstore[section]['username'] tempstore['pending'].remove(name) del tempstore[section] # ran = randomstring(4) while tempstore.has_key(ran + str(today)): ran = randomstring(4) key = ran + str(today) tempstore[key] = {} store = tempstore[key] for entry in formdict: if entry == 'pass1' or entry == 'pass2': store['password'] = formdict[entry] elif entry == 'login': pass else: store[entry] = formdict[entry] if not tempstore.has_key('pending'): tempstore['pending'] = [] tempstore['pending'].append(formdict['username']) tempstore.write() return pass_enc(key, timestamp=True, daynumber=True)
def expired(daynumber, timestamp, validity): """Given the length of time a password is valid for, it checks if a daynumber/timestamp tuple is still valid. validity should be an integer tuple (DAYS, HOURS, MINUTES). Returns True for valid or False for invalid. Needs the dateutils module to get the current daynumber. >>> a, b, c = returndate() >>> today = daycount(a, b, c) >>> h, m = return_now() >>> expired(today, (h, m-2), (0,0,1)) False >>> expired(today, (h, m-2), (0,0,10)) True >>> expired(today, (h-2, m-2), (0,1,10)) False >>> expired(today-1, (h-2, m-2), (1,1,10)) False >>> expired(today-1, (h-2, m-2), (2,1,10)) True >>> """ if not DATEIN: raise ImportError( "Need the dateutils module to use the 'expired' function.") h1, m1 = timestamp # h1, m1 are the hours and minutes of the timestamp d2, h2, m2 = validity # validity is how long the timestamp is valid for a, b, c = returndate() today = daycount(a, b, c) # today is number representing the julian day number of today h, m = return_now() # h, m are the hours and minutes of time now h1 = h1 + h2 m1 = m1 + m2 daynumber = daynumber + d2 # so we need to test if today, h, m are greater than daynumber, h1, m1 # But first we need to adjust because we might currently have hours above 23 and minutes above 59 while m1 > 59: h1 += 1 m1 -= 60 while h1 > 23: daynumber += 1 h1 -= 24 daynumber += d2 if today > daynumber: return False if today < daynumber: return True if h > h1: # same day return False if h < h1: return True if m > m1: # same hour return False else: return True
def pass_enc(instring, indict=None, **keywargs): """Returns an ascii version of an SHA hash or a string, with the date/time stamped into it. e.g. For ascii safe storing of password hashes. It also accepts the following keyword args (or a dictionary conatining the following keys). (Keywords shown - with default values). lower = False, sha_hash = False, daynumber = None, timestamp = None, endleave = False Setting lower to True makes instring lowercase before hashing/encoding. If sha_hash is set to True then instead of the actual string passed in being encoded, it's SHA hash is encoded. (In either case the string can contain any binary data). If a daynumber is passed in then the daynumber will be encoded into the returned string. (daynumber is an integer representing the 'Julian day number' of a date - see the dateutils module). This can be used as a 'datestamp' for the generated code and you can detect anyone reusing old codes this way. If 'daynumber' is set to True then today's daynumber will automatically be used. (dateutils module required - otherwise it will be ignored). Max allowed value for daynumber is 16777215 (9th May 41222) (so daynumber can be any integer from 1 to 16777215 that you want to 'watermark' the hash with could be used as a session ID for a CGI for example). If a timestamp is passed in it should either be timestamp = True meanining use 'now'. Or it should be a tuple (HOUR, MINUTES). HOUR should be an integer 0-23 MINUTES should be an integer 0-59 The time and date stamp is *binary* interleaved, before encoding, into the data. If endleave is set to True then the timestamp is interleaved more securely. Shouldn't be necessary in practise because the stamp is so short and we subsequently encode using table_enc. If the string is long this will slow down the process - because we interleave twice. """ if indict == None: indict = {} arglist = { 'lower': False, 'sha_hash': False, 'daynumber': None, 'timestamp': None, 'endleave': False } if not indict and keywargs: # if keyword passed in instead of a dictionary - we use that indict = keywargs for keyword in arglist: # any keywords not specified we use the default if not indict.has_key(keyword): indict[keyword] = arglist[keyword] if indict['lower']: # keyword lower :-) instring = instring.lower() if indict['sha_hash']: instring = hashlib.sha1(instring).digest() if indict['daynumber'] == True: if not DATEIN: indict['daynumber'] = None else: a, b, c = returndate() indict['daynumber'] = daycount(a, b, c) # set the daycount to today if indict['timestamp'] == True: if not DATEIN: indict['timestamp'] = None else: indict['timestamp'] = return_now() # set the time to now. datestamp = makestamp(indict['daynumber'], indict['timestamp']) if len(instring) == len(datestamp): instring = instring + '&mjf-end;' # otherwise we can't tell which is which when we unleave them later :-) outdata = binleave(instring, datestamp, indict['endleave']) return table_enc(outdata) # do the encoding of the actual string
def pass_enc(instring, indict=None, **keywargs): """Returns an ascii version of an SHA hash or a string, with the date/time stamped into it. e.g. For ascii safe storing of password hashes. It also accepts the following keyword args (or a dictionary conatining the following keys). (Keywords shown - with default values). lower = False, sha_hash = False, daynumber = None, timestamp = None, endleave = False Setting lower to True makes instring lowercase before hashing/encoding. If sha_hash is set to True then instead of the actual string passed in being encoded, it's SHA hash is encoded. (In either case the string can contain any binary data). If a daynumber is passed in then the daynumber will be encoded into the returned string. (daynumber is an integer representing the 'Julian day number' of a date - see the dateutils module). This can be used as a 'datestamp' for the generated code and you can detect anyone reusing old codes this way. If 'daynumber' is set to True then today's daynumber will automatically be used. (dateutils module required - otherwise it will be ignored). Max allowed value for daynumber is 16777215 (9th May 41222) (so daynumber can be any integer from 1 to 16777215 that you want to 'watermark' the hash with could be used as a session ID for a CGI for example). If a timestamp is passed in it should either be timestamp = True meanining use 'now'. Or it should be a tuple (HOUR, MINUTES). HOUR should be an integer 0-23 MINUTES should be an integer 0-59 The time and date stamp is *binary* interleaved, before encoding, into the data. If endleave is set to True then the timestamp is interleaved more securely. Shouldn't be necessary in practise because the stamp is so short and we subsequently encode using table_enc. If the string is long this will slow down the process - because we interleave twice. """ if indict == None: indict = {} arglist = {'lower' : False, 'sha_hash' : False, 'daynumber' : None, 'timestamp' : None, 'endleave' : False} if not indict and keywargs: # if keyword passed in instead of a dictionary - we use that indict = keywargs for keyword in arglist: # any keywords not specified we use the default if not indict.has_key(keyword): indict[keyword] = arglist[keyword] if indict['lower']: # keyword lower :-) instring = instring.lower() if indict['sha_hash']: instring = hashlib.sha1(instring).digest() if indict['daynumber'] == True: if not DATEIN: indict['daynumber'] = None else: a,b,c = returndate() indict['daynumber'] = daycount(a,b,c) # set the daycount to today if indict['timestamp']== True: if not DATEIN: indict['timestamp'] = None else: indict['timestamp'] = return_now() # set the time to now. datestamp = makestamp(indict['daynumber'], indict['timestamp']) if len(instring) == len(datestamp): instring = instring + '&mjf-end;' # otherwise we can't tell which is which when we unleave them later :-) outdata = binleave(instring, datestamp, indict['endleave']) return table_enc(outdata) # do the encoding of the actual string