def getChild(self, path, request): request.postpath.insert(0,request.prepath.pop()) env = self.env.copy() username = request.getUser() password = request.getPassword() if username: import md5crypt authdb = list(file('/var/www/trac.htpasswd')) for ent in authdb: u, p = ent.split(':', 1) if u == username: print 'Found username', u, 'in auth db' parts = p.split('$', 2) print 'Found salt', parts[1], 'in md5' if md5crypt.md5crypt(password, parts[1]) != p: print 'It is a bad liar' username = '' else: print 'Yay victory' break else: username = '' if request.postpath == ['login']: if not username: return BasicAuthError(http.UNAUTHORIZED, "Unauthorized", "401 Authentication required", self.basicRealm) return util.Redirect("/trac/") env['REMOTE_USER'] = username return EnvableCGIThing(self.cgifile, env=env)
def login(self): if not self.username and not self.password: return True # fall back to free account elif self.username and self.password and len(self.username)>0 and len(self.password)>0: #util.info('Login user=%s, pass=*****' % self.username) #sclog.logDebug("Login start...") # get salt headers,req = self._create_request('',{'username_or_email':self.username}) sclog.logDebug("Webshare login try '%s' ..."%self._url('api/salt/')) data = util.post(self._url('api/salt/'),req,headers=headers) xml = ET.fromstring(data) if not xml.find('status').text == 'OK': #sclog.logDebug("Login end salt...") #util.error('Server returned error status, response: %s' % data) return False salt = xml.find('salt').text if salt is None: salt = '' # create hashes password = hashlib.sha1(md5crypt(self.password.encode('utf-8'), salt.encode('utf-8'))).hexdigest() digest = hashlib.md5(self.username + ':Webshare:' + self.password).hexdigest() # login headers,req = self._create_request('',{'username_or_email':self.username,'password':password,'digest':digest,'keep_logged_in':1}) data = util.post(self._url('api/login/'),req,headers=headers) xml = ET.fromstring(data) #sclog.logDebug("Login end...") if not xml.find('status').text == 'OK': #util.error('Server returned error status, response: %s' % data) return False self.token = xml.find('token').text #util.info('Login successfull') return True return False
def add(self, user, password): """ Add/overwrite a new user """ magic = 'apr1' salt = md5crypt.makesalt() newhash = md5crypt.md5crypt(password, salt, '$' + magic + '$') self.passwords[user] = newhash self.modified = True self.flush() return True
def change(self, user, password): """ Change users password """ if not self.passwords.has_key(user): return False magic, salt, encrypted = self.passwords[user][1:].split('$') newhash = md5crypt.md5crypt(password, salt, '$' + magic + '$') self.passwords[user] = newhash self.modified = True return True
def check(self, user, password): """ Check if user has password """ if not self.passwords.has_key(user): return False vals = self.passwords[user][1:].split('$') if not len(vals) == 3: raise NoMD5PasswordError() magic, salt, encrypted = vals hash = md5crypt.md5crypt(password, salt, '$' + magic + '$') return hash == self.passwords[user]
def authenticate(self, username=None, password=None): """ Authenticates against the database using crypt hash function. """ try: user = auth_models.User.objects.get(username__iexact=username) if crypt.crypt(password, user.password) == user.password or md5crypt.md5crypt(password, user.password) == user.password: # Successfully checked password, so we change it to the Django password format user.set_password(password) user.save() return user except ValueError: return None except auth_models.User.DoesNotExist: return None
def _check_userline(self, password, prefix, suffix): if suffix.startswith('$apr1$'): return suffix == md5crypt(password, suffix[6:].split('$')[0], '$apr1$') elif suffix.startswith('{SHA}'): return (suffix[5:] == sha.new(password).digest().encode('base64')[:-1]) elif crypt is None: # crypt passwords are only supported on Unix-like systems raise NotImplementedError('The "crypt" module is unavailable ' 'on this platform. Only MD5 ' 'passwords (starting with "$apr1$") ' 'are supported in the htpasswd file.') else: return suffix == crypt(password, suffix)
def htpasswd(password, salt_=None): # TODO need unit test of generating new hash if salt_ is None: salt_ = salt() if crypt is None: salt_ = "$apr1$" + salt_ if salt_.startswith("$apr1$"): return md5crypt(password, salt_[6:].split("$")[0], "$apr1$") elif salt_.startswith("{SHA}"): return "{SHA}" + sha.new(password).digest().encode("base64")[:-1] elif crypt is None: # crypt passwords are only supported on Unix-like systems raise NotImplementedError('The "crypt" module is unavailable ' "on this platform.") else: return crypt(password, salt_)
def htpasswd(password, salt_=None): # TODO need unit test of generating new hash if salt_ is None: salt_ = salt() if crypt is None: salt_ = '$apr1$' + salt_ if salt_.startswith('$apr1$'): return md5crypt(password, salt_[6:].split('$')[0], '$apr1$') elif salt_.startswith('{SHA}'): return '{SHA}' + sha1(password).digest().encode('base64')[:-1] elif crypt is None: # crypt passwords are only supported on Unix-like systems raise NotImplementedError('The "crypt" module is unavailable ' 'on this platform.') else: return crypt(password, salt_)
def login(self): if not self.username and not self.password: return True # fall back to free account elif self.username and self.password and len(self.username)>0 and len(self.password)>0: headers,req = self._create_request('',{'username_or_email':self.username}) data = util.post(self._url('api/salt/'),req,headers=headers) xml = ET.fromstring(data) if not xml.find('status').text == 'OK': return False salt = xml.find('salt').text if salt is None: salt = '' password = hashlib.sha1(md5crypt(self.password.encode('utf-8'), salt.encode('utf-8'))).hexdigest() digest = hashlib.md5(self.username + ':Webshare:' + self.password).hexdigest() headers,req = self._create_request('',{'username_or_email':self.username,'password':password,'digest':digest,'keep_logged_in':1}) data = util.post(self._url('api/login/'),req,headers=headers) xml = ET.fromstring(data) if not xml.find('status').text == 'OK': return False self.token = xml.find('token').text return True return False
def testpwd(clear_password, the_hash): magic, salt = the_hash[1:].split('$')[:2] magic = '$' + magic + '$' if (md5crypt.md5crypt(clear_password, salt, magic) == the_hash): return True return False
def userline(self, user, password): if crypt is None: return self.prefix(user) + md5crypt(password, salt(), '$apr1$') else: return self.prefix(user) + crypt(password, salt())
def crypt(self, plain): """You can override this to use your favorite one-way encryption""" import md5crypt return md5crypt.md5crypt(plain, "pw")
domains=Set() for line in data: line=line.strip() if line.find('USER')>=0: user=line[line.find('USER')+5:] if line.find('PASS')>=0: passwd=line[line.find('PASS')+5:] """if line.find("Mailbox open")>=0: if( not pairs.has_key(user)): pairs[user]=passwd""" pairs[user]=passwd for user in users: try: pwhash=md5.md5crypt(pairs[user]) except Exception: pwhash=md5.md5crypt("") domain=user.split('@')[1] domains.add(domain) maildir=domain+'/'+user.split('@')[0] local_part=user.split('@')[0] print "insert into mailbox values('%s','%s','','%s',524288000,'%s','%s',now(),now(),1);"%(user,pwhash,maildir,local_part,domain) print "insert into alias values('%s','%s','%s',now(),now(),1);"%(user,user,domain) for domain in domains: print "insert into domain values('%s','',25,25,2048,2048,'virtual',0,now(),now(),1);"%(domain) for user in users: try: print pairs[user],"\n"
def encrypt_password(password, salt = None): import md5crypt if not salt: salt = "%06d" % (1000000 * (time.time() % 1.0)) return md5crypt.md5crypt(password, salt, '$1$')
def encrypt_password(password, salt=None): import md5crypt if not salt: salt = "%06d" % (1000000 * (time.time() % 1.0)) return md5crypt.md5crypt(password, salt, '$1$')
def curphoo_process_auth(username, password, seed): # # Magic: Phase 1. Generate what seems to be a 30 # byte value (could change if base64 # ends up differently? I don't remember and I'm # tired, so use a 64 byte buffer. # magic1 = [] for char in seed: # Ignore parentheses. if char == "(" or char == ")": continue # Characters and digits verify against the challenge lookup. if char.isalpha() or char.isdigit(): magic_work = challenge_lookup.index(char) << 3 else: local_store = operand_lookup.index(char) magic1.append(magic_work | local_store) # Magic: Phase 2. Take generated magic value and # sprinkle fairy dust on the values. magic2 = [] for c in range(len(magic1) - 1, 0, -1): byte1 = magic1[c - 1] byte2 = magic1[c] byte1 *= 0xCD byte1 &= 0xFF byte1 ^= byte2 magic2.append(byte1) # Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic # key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key # plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets # into particular functions we'll later call to potentially alter the magic key. comparison_src = array("B") while len(magic2) > 0 and len(comparison_src) < 20: cl = magic2.pop() if cl > 0x7F: if cl < 0xE0: bl = (cl & 0x1F) << 6 else: bl = magic2.pop() cl = (cl & 0x0F) << 6 bl = ((bl & 0x3F) + cl) << 6 cl = magic2.pop() cl = (cl & 0x3F) + bl comparison_src.append(cl >> 8) comparison_src.append(cl & 0xFF) # Compute values for recursive function table! def find_table_depth_values(md5root, search_hash): def guesser(): yield (3, 88) # take a wild guess at what seems to be a constant for i in range(0xFFFF): for j in range(5): yield (j, i) for (j, i) in guesser(): md5object = md5root.copy() md5object.update(chr(i & 0xFF) + chr(i >> 8) + chr(j)) if md5object.digest() == search_hash: return (j, i) (table, depth) = find_table_depth_values(md5.new(comparison_src[:4]), comparison_src[4:].tostring()) # Transform magic_key_char using transform table x = comparison_src[3] << 24L | comparison_src[2] << 16 | comparison_src[1] << 8 | comparison_src[0] x = yahoo_xfrm(table, depth, x) x = yahoo_xfrm(table, depth, x) magic_key_char = chr(x & 0xFF) + chr(x >> 8 & 0xFF) + chr(x >> 16 & 0xFF) + chr(x >> 24 & 0xFF) crypt_result = md5crypt(password, "$1$_2S43d5f$") def finalstep(input, magic_key_char, table): def finalxor(hash, mask): result = array("B") for c in hash: result.append(ord(c) ^ mask) for c in range(64 - len(hash)): result.append(mask) return result.tostring() hash = md5.new(input).digest().encode("base64").translate(base64translate, "\r\n") if table >= 3: # We have to use the slow sha1 implementation to get to it's internals sha1 = pysha.new(finalxor(hash, 0x36) + magic_key_char) sha1.count[1] = sha1.count[1] - 1 else: sha1 = sha.new(finalxor(hash, 0x36) + magic_key_char) digest1 = sha1.digest() digest2 = sha.new(finalxor(hash, 0x5C) + digest1).digest() result = "" for i in range(10): # First two bytes of digest stuffed together. val = (ord(digest2[i * 2]) << 8) + ord(digest2[i * 2 + 1]) result += alphabet1[(val >> 0x0B) & 0x1F] + "=" result += alphabet2[(val >> 0x06) & 0x1F] result += alphabet2[(val >> 0x01) & 0x1F] result += delimit_lookup[val & 0x01] return result return (finalstep(password, magic_key_char, table), finalstep(crypt_result, magic_key_char, table))
def encrypt_password(password, salt=None, prefix="1"): import md5crypt if not salt: salt = "%06d" % (1000000 * (time.time() % 1.0)) return md5crypt.md5crypt(password, salt, '$%s$' % prefix)
def curphoo_process_auth(username, password, seed): # # Magic: Phase 1. Generate what seems to be a 30 # byte value (could change if base64 # ends up differently? I don't remember and I'm # tired, so use a 64 byte buffer. # magic1 = [] for char in seed: # Ignore parentheses. if char == '(' or char == ')': continue # Characters and digits verify against the challenge lookup. if char.isalpha() or char.isdigit(): magic_work = challenge_lookup.index(char) << 3 else: local_store = operand_lookup.index(char) magic1.append(magic_work | local_store) # Magic: Phase 2. Take generated magic value and # sprinkle fairy dust on the values. magic2 = [] for c in range(len(magic1) - 1, 0, -1): byte1 = magic1[c - 1] byte2 = magic1[c] byte1 *= 0xcd byte1 &= 0xff byte1 ^= byte2 magic2.append(byte1) # Magic: Phase 3. This computes 20 bytes. The first 4 bytes are used as our magic # key (and may be changed later); the next 16 bytes are an MD5 sum of the magic key # plus 3 bytes. The 3 bytes are found by looping, and they represent the offsets # into particular functions we'll later call to potentially alter the magic key. comparison_src = array('B') while len(magic2) > 0 and len(comparison_src) < 20: cl = magic2.pop() if cl > 0x7f: if cl < 0xe0: bl = (cl & 0x1f) << 6 else: bl = magic2.pop() cl = (cl & 0x0f) << 6 bl = ((bl & 0x3f) + cl) << 6 cl = magic2.pop() cl = (cl & 0x3f) + bl comparison_src.append(cl >> 8) comparison_src.append(cl & 0xff) # Compute values for recursive function table! def find_table_depth_values(md5root, search_hash): def guesser(): yield (3, 88) # take a wild guess at what seems to be a constant for i in range(0xffff): for j in range(5): yield (j, i) for (j, i) in guesser(): md5object = md5root.copy() md5object.update(chr(i & 0xff) + chr(i >> 8) + chr(j)) if md5object.digest() == search_hash: return (j, i) (table, depth) = find_table_depth_values(md5.new(comparison_src[:4]), comparison_src[4:].tostring()) # Transform magic_key_char using transform table x = comparison_src[3] << 24l | comparison_src[2] << 16 | comparison_src[ 1] << 8 | comparison_src[0] x = yahoo_xfrm(table, depth, x) x = yahoo_xfrm(table, depth, x) magic_key_char = chr(x & 0xFF) + chr(x >> 8 & 0xFF) + chr( x >> 16 & 0xFF) + chr(x >> 24 & 0xFF) crypt_result = md5crypt(password, '$1$_2S43d5f$') def finalstep(input, magic_key_char, table): def finalxor(hash, mask): result = array('B') for c in hash: result.append(ord(c) ^ mask) for c in range(64 - len(hash)): result.append(mask) return result.tostring() hash = md5.new(input).digest().encode('base64').translate( base64translate, '\r\n') if ( table >= 3 ): # We have to use the slow sha1 implementation to get to it's internals sha1 = pysha.new(finalxor(hash, 0x36) + magic_key_char) sha1.count[1] = sha1.count[1] - 1 else: sha1 = sha.new(finalxor(hash, 0x36) + magic_key_char) digest1 = sha1.digest() digest2 = sha.new(finalxor(hash, 0x5c) + digest1).digest() result = '' for i in range(10): # First two bytes of digest stuffed together. val = (ord(digest2[i * 2]) << 8) + ord(digest2[i * 2 + 1]) result += alphabet1[(val >> 0x0b) & 0x1f] + '=' result += alphabet2[(val >> 0x06) & 0x1f] result += alphabet2[(val >> 0x01) & 0x1f] result += delimit_lookup[val & 0x01] return result return (finalstep(password, magic_key_char, table), finalstep(crypt_result, magic_key_char, table))