From e51938b617a9d1ca5c3b61f85476a516cdfe2303 Mon Sep 17 00:00:00 2001 From: Henri Date: Sat, 5 Dec 2020 14:39:44 +0100 Subject: [PATCH] Drop root privileges after binding to server port --- src/wgfrontend/setupenv.py | 17 ++++++++++------- src/wgfrontend/webapp.py | 10 +++++++++- 2 files changed, 19 insertions(+), 8 deletions(-) diff --git a/src/wgfrontend/setupenv.py b/src/wgfrontend/setupenv.py index 9d0fa05..02f6895 100644 --- a/src/wgfrontend/setupenv.py +++ b/src/wgfrontend/setupenv.py @@ -68,13 +68,18 @@ def chown(username, path): uid = pwd.getpwnam(username).pw_uid os.chown(path, uid, -1) -def drop_privileges(uid_name='nobody', gid_name='nogroup'): - """""" - if not is_root(): - raise ValueError('No privileges present to drop') +def get_uid_gid(uid_name='nobody', gid_name='nogroup'): + """Returns uid and gid for the given username and groupname""" uid = pwd.getpwnam(uid_name).pw_uid gid = grp.getgrnam(gid_name).gr_gid -# os.setgroups([]) # remove group privileges + return uid, gid + +def drop_privileges(uid_name='nobody', gid_name='nogroup'): + """Drop privileges towards the given username and groupname""" + if not is_root(): + raise ValueError('No privileges present to drop') + uid, gid = get_uid_gid(uid_name, gid_name) + os.setgroups([]) # remove group privileges os.setgid(gid) os.setuid(uid) @@ -168,8 +173,6 @@ def setup_environment(): print(f'8d) Ensuring ownership of server private key file {cfg.sslkeyfile} in case it exists.') if os.path.exists(cfg.sslkeyfile): chown(cfg.user, cfg.sslkeyfile) - print(f'9) Dropping root privileges to user/group "{cfg.user}".') - drop_privileges(cfg.user, cfg.user) print(f'Attempting to start web frontend...') return cfg diff --git a/src/wgfrontend/webapp.py b/src/wgfrontend/webapp.py index 4609773..fe03207 100644 --- a/src/wgfrontend/webapp.py +++ b/src/wgfrontend/webapp.py @@ -10,6 +10,7 @@ import string import subprocess from . import pwdtools +from . import setupenv from . import wgcfg @@ -133,7 +134,14 @@ def run_webapp(cfg): cherrypy.config.update({'server.socket_host': '0.0.0.0', 'server.socket_port': 8080, }) - cherrypy.quickstart(app, '/', app_conf) + cherrypy.tree.mount(app, config=app_conf) + if setupenv.is_root(): + # Drop privileges + uid, gid = setupenv.get_uid_gid(cfg.user, cfg.user) + cherrypy.process.plugins.DropPrivileges(cherrypy.engine, umask=0o022, uid=uid, gid=gid).subscribe() + cherrypy.engine.start() + cherrypy.engine.signals.subscribe() + cherrypy.engine.block() if __name__ == '__main__':