관리-도구
편집 파일: htpasswd.py
# coding=utf-8 # Copyright © Cloud Linux GmbH & Cloud Linux Software, Inc 2010-2019 All Rights Reserved # # Licensed under CLOUD LINUX LICENSE AGREEMENT # http://cloudlinux.com/docs/LICENSE.TXT import base64 import hashlib import os __author__ = "Eli Carter" class HtpasswdDoesNotExists(Exception): pass class HtpasswdFile(object): """ A class for manipulating htpasswd files. """ def __init__(self, filename, create=False): self.entries = [] self.filename = filename if not create: if os.path.exists(self.filename): self.load() else: raise HtpasswdDoesNotExists(f"{self.filename} does not exist") def load(self): """ Read the htpasswd file into memory. """ self.entries = [] with open(self.filename, 'r', encoding='utf-8') as f: for line in f: username, pwhash = line.split(':') entry = [username, pwhash.rstrip()] self.entries.append(entry) def save(self): """ Write the htpasswd file to disk """ with open(self.filename, 'w', encoding='utf-8') as f: for entry in self.entries: f.write(f"{entry[0]}:{entry[1]}\n") def update(self, username, password): """ Replace the entry for the given user, or add it if new. """ # Generate a random salt salt = os.urandom(16) # Hash the password using PBKDF2 with HMAC-SHA256 pwhash = hashlib.pbkdf2_hmac('sha256', password.encode('utf-8'), salt, 100000) # Store the salt along with the hash to use it during password verification stored_password = base64.b64encode(salt + pwhash).decode('utf-8') # Find matching entries matching_entries = [entry for entry in self.entries if entry[0] == username] if matching_entries: matching_entries[0][1] = stored_password else: self.entries.append([username, stored_password]) def delete(self, username): """ Remove the entry for the given user. """ self.entries = [entry for entry in self.entries if entry[0] != username]