Added sesame feature

This commit is contained in:
Daniel Perna 2018-01-25 00:25:46 +01:00
parent 4ffe967b25
commit 76d227b274
4 changed files with 39 additions and 17 deletions

View file

@ -64,7 +64,9 @@ Set this variable to `True` to enable Git integration. This feature requires [Gi
To push local commits to a remote repository, you have to add the remote manually: `git remote add origin ssh://somehost:/user/repo.git`
Verify, that the user that is running the configurator is allowed to push without any interaction (by using SSH PubKey authentication for example).
#### DIRSFIRST (bool)
if set to `true`, directories will be displayed at the top
If set to `true`, directories will be displayed at the top.
#### SESAME (string)
If set to _somesecretkeynobodycanguess_, you can browse to `https://your.configurator:3218/somesecretkeynobodycanguess` from any IP, and it will be removed from the `BANNED_IPS` list (in case it has been banned before) and added to the `ALLOWED_NETWORKS` list. Once the request has been processed you will automatically be redirected to the configurator. Think of this as dynamically allowing access from untrusted IPs by providing a secret key (_open sesame!_). Keep in mind, that once the IP has been added, you will either have to restart the configurator or manually remove the IP through the _Newwork status_ to revoke access.
__Note regarding `ALLOWED_NETWORKS`, `BANNED_IPS` and `BANLIMIT`__:
The way this is implemented works in the following order:

View file

@ -1,8 +1,10 @@
Version 0.2.5 (2018-)
Version 0.2.5 (2018-01-25)
- Added warning-logs for access failure @danielperna84
- Added transparency to whitespace characters @danielperna84
- Using external repository for Docker @Munsio
- Modify BANNED_IPS and ALLOWED_NETWORKS at runtime @danielperna84
- Use relative paths in webserver @danielperna84
- Added "Sesame" feature @danielperna84
Version 0.2.4 (2018-01-02)
- Added YAML linting @AtoxIO

View file

@ -27,10 +27,11 @@ from urllib.parse import urlparse, parse_qs, unquote
### Some options for you to change
LISTENIP = "0.0.0.0"
LISTENPORT = 3218
# Set BASEPATH to something like "/home/hass/.homeassistant/" if you're not running the
# configurator from that path
# Set BASEPATH to something like "/home/hass/.homeassistant/" if you're not
# running the configurator from that path
BASEPATH = None
# Set the paths to a certificate and the key if you're using SSL, e.g "/etc/ssl/certs/mycert.pem"
# Set the paths to a certificate and the key if you're using SSL,
# e.g "/etc/ssl/certs/mycert.pem"
SSL_CERTIFICATE = None
SSL_KEY = None
# Set the destination where the HASS API is reachable
@ -38,24 +39,27 @@ HASS_API = "http://127.0.0.1:8123/api/"
# If a password is required to access the API, set it in the form of "password"
# if you have HA ignoring SSL locally this is not needed if on same machine.
HASS_API_PASSWORD = None
# To enable authentication, set the credentials in the form of "username:password"
# Enable authentication, set the credentials in the form of "username:password"
CREDENTIALS = None
# Limit access to the configurator by adding allowed IP addresses / networks to the list,
# e.g ALLOWED_NETWORKS = ["192.168.0.0/24", "172.16.47.23"]
# Limit access to the configurator by adding allowed IP addresses / networks to
# the list, e.g ALLOWED_NETWORKS = ["192.168.0.0/24", "172.16.47.23"]
ALLOWED_NETWORKS = []
# List of statically banned IP addresses, e.g. ["1.1.1.1", "2.2.2.2"]
BANNED_IPS = []
# Ban IPs after n failed login attempts. Restart service to reset banning. The default
# of `0` disables this feature.
# Ban IPs after n failed login attempts. Restart service to reset banning.
# The default of `0` disables this feature.
BANLIMIT = 0
# Enable git integration. GitPython (https://gitpython.readthedocs.io/en/stable/) has
# to be installed.
# Enable git integration.
# GitPython (https://gitpython.readthedocs.io/en/stable/) has to be installed.
GIT = False
# Files to ignore in the UI. A good example list that cleans up the UI is
# [".*", "*.log", "deps", "icloud", "*.conf", "*.json", "certs", "__pycache__"]
IGNORE_PATTERN = []
# if DIRSFIRST is set to `true`, directories will be displayed at the top
DIRSFIRST = False
# Sesame token. Browse to the configurator URL + /secrettoken to unban your
# client IP and add it to the list of allowed IPs.
SESAME = None
### End of options
LOGLEVEL = logging.INFO
@ -63,7 +67,8 @@ LOG = logging.getLogger(__name__)
LOG.setLevel(LOGLEVEL)
SO = logging.StreamHandler(sys.stdout)
SO.setLevel(LOGLEVEL)
SO.setFormatter(logging.Formatter('%(levelname)s:%(asctime)s:%(name)s:%(message)s'))
SO.setFormatter(
logging.Formatter('%(levelname)s:%(asctime)s:%(name)s:%(message)s'))
LOG.addHandler(SO)
RELEASEURL = "https://api.github.com/repos/danielperna84/hass-configurator/releases/latest"
VERSION = "0.2.4"
@ -3092,8 +3097,8 @@ def signal_handler(sig, frame):
def load_settings(settingsfile):
global LISTENIP, LISTENPORT, BASEPATH, SSL_CERTIFICATE, SSL_KEY, HASS_API, \
HASS_API_PASSWORD, CREDENTIALS, ALLOWED_NETWORKS, BANNED_IPS, BANLIMIT, DEV, \
IGNORE_PATTERN, DIRSFIRST
HASS_API_PASSWORD, CREDENTIALS, ALLOWED_NETWORKS, BANNED_IPS, BANLIMIT, \
DEV, IGNORE_PATTERN, DIRSFIRST, SESAME
try:
if os.path.isfile(settingsfile):
with open(settingsfile) as fptr:
@ -3112,6 +3117,7 @@ def load_settings(settingsfile):
DEV = settings.get("DEV", DEV)
IGNORE_PATTERN = settings.get("IGNORE_PATTERN", IGNORE_PATTERN)
DIRSFIRST = settings.get("DIRSFIRST", DIRSFIRST)
SESAME = settings.get("SESAME", SESAME)
except Exception as err:
LOG.warning(err)
LOG.warning("Not loading static settings")
@ -3219,10 +3225,21 @@ class RequestHandler(BaseHTTPRequestHandler):
self.wfile.write(bytes("Policy not fulfilled", "utf8"))
def do_GET(self):
req = urlparse(self.path)
if SESAME:
if req.path.endswith("/%s" % SESAME):
if self.client_address[0] not in ALLOWED_NETWORKS:
ALLOWED_NETWORKS.append(self.client_address[0])
if self.client_address[0] in BANNED_IPS:
BANNED_IPS.remove(self.client_address[0])
url = req.path[:req.path.rfind(SESAME)]
self.send_response(302)
self.send_header('Location', url)
self.end_headers()
return
if not check_access(self.client_address[0]):
self.do_BLOCK()
return
req = urlparse(self.path)
query = parse_qs(req.query)
self.send_response(200)
if req.path.endswith('/api/file'):

View file

@ -11,5 +11,6 @@
"BANNED_IPS": [],
"BANLIMIT": 0,
"IGNORE_PATTERN": [],
"DIRSFIRST": false
"DIRSFIRST": false,
"SESAME": null
}