Fix dashboard logout button and py3.8 removed hmac.new digestmod (#1156)

* Fix dashboard logout button and py3.8 removed hmac.new digestmod

* Just use SHA256

No reason to use HMAC here, as authenticity is not an issue

* Wrong branch

* Clenaup
This commit is contained in:
Otto Winter 2020-07-24 11:10:09 +02:00 committed by GitHub
parent 50cf57affb
commit c030be4d3f
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23
3 changed files with 21 additions and 6 deletions

View file

@ -30,6 +30,7 @@ from esphome.helpers import mkdir_p, get_bool_env, run_system_command
from esphome.storage_json import EsphomeStorageJSON, StorageJSON, \ from esphome.storage_json import EsphomeStorageJSON, StorageJSON, \
esphome_storage_path, ext_storage_path, trash_storage_path esphome_storage_path, ext_storage_path, trash_storage_path
from esphome.util import shlex_quote, get_serial_ports from esphome.util import shlex_quote, get_serial_ports
from .util import password_hash
# pylint: disable=unused-import, wrong-import-order # pylint: disable=unused-import, wrong-import-order
from typing import Optional # noqa from typing import Optional # noqa
@ -42,7 +43,7 @@ _LOGGER = logging.getLogger(__name__)
class DashboardSettings: class DashboardSettings:
def __init__(self): def __init__(self):
self.config_dir = '' self.config_dir = ''
self.password_digest = '' self.password_hash = ''
self.username = '' self.username = ''
self.using_password = False self.using_password = False
self.on_hassio = False self.on_hassio = False
@ -55,7 +56,7 @@ class DashboardSettings:
self.username = args.username or os.getenv('USERNAME', '') self.username = args.username or os.getenv('USERNAME', '')
self.using_password = bool(password) self.using_password = bool(password)
if self.using_password: if self.using_password:
self.password_digest = hmac.new(password.encode()).digest() self.password_hash = password_hash(password)
self.config_dir = args.configuration[0] self.config_dir = args.configuration[0]
@property @property
@ -82,8 +83,11 @@ class DashboardSettings:
if username != self.username: if username != self.username:
return False return False
password = hmac.new(password.encode()).digest() # Compare password in constant running time (to prevent timing attacks)
return username == self.username and hmac.compare_digest(self.password_digest, password) return hmac.compare_digest(
self.password_hash,
password_hash(password)
)
def rel_path(self, *args): def rel_path(self, *args):
return os.path.join(self.config_dir, *args) return os.path.join(self.config_dir, *args)
@ -446,7 +450,7 @@ class MainRequestHandler(BaseHandler):
entries = _list_dashboard_entries() entries = _list_dashboard_entries()
self.render("templates/index.html", entries=entries, begin=begin, self.render("templates/index.html", entries=entries, begin=begin,
**template_args()) **template_args(), login_enabled=settings.using_auth)
def _ping_func(filename, address): def _ping_func(filename, address):

View file

@ -52,7 +52,9 @@
<li><a data-action="update-all" data-filename="{{ escape(config_dir) }}">Update All</a></li> <li><a data-action="update-all" data-filename="{{ escape(config_dir) }}">Update All</a></li>
<li><a data-action="edit" data-filename="secrets.yaml">Secrets Editor</a></li> <li><a data-action="edit" data-filename="secrets.yaml">Secrets Editor</a></li>
<li class="divider"></li> <li class="divider"></li>
<li><a href="{{ relative_url }}logout">Logout</a></li> {% if login_enabled %}
<li><a href="{{ relative_url }}logout">Logout</a></li>
{% end %}
</ul> </ul>
</nav> </nav>
</div> </div>

View file

@ -0,0 +1,9 @@
import hashlib
def password_hash(password: str) -> bytes:
"""Create a hash of a password to transform it to a fixed-length digest.
Note this is not meant for secure storage, but for securely comparing passwords.
"""
return hashlib.sha256(password.encode()).digest()