Skip to content
This repository

HTTPS clone URL

Subversion checkout URL

You can clone with HTTPS or Subversion.

Download ZIP
Browse code

merging in richo's drop privs code

  • Loading branch information...
commit 012acad4be7c7d624f9b60e7ab35c421884ab044 2 parents da22b28 + 6093a97
Andrew Moffat authored

Showing 2 changed files with 54 additions and 9 deletions. Show diff stats Hide diff stats

  1. +8 0 AUTHORS.md
  2. +46 9 focus.py
8 AUTHORS.md
Source Rendered
... ... @@ -0,0 +1,8 @@
  1 +# Authors
  2 +
  3 +* Andrew Moffat <andrew.robert.moffat@gmail.com>
  4 +
  5 +
  6 +# Contributors
  7 +
  8 +* Richo Healey <richo@psych0tik.net>
55 focus.py
@@ -331,15 +331,38 @@ def adjust_ttl_in_reply(self, reply, ttl):
331 331 def clean_up_pid():
332 332 if exists(pid_file):
333 333 logging.info("cleaning up pid file")
334   - os.remove(pid_file)
335   -
  334 + # kludge, but we can't remove the pid file anymore, since we dropped privs
  335 + h = open(pid_file, "w")
  336 + h.close()
  337 +
  338 +def get_unprivileged_uid():
  339 + if os.getuid() != os.geteuid():
  340 + return os.getuid()
  341 + elif "SUDO_UID" in os.environ:
  342 + return int(os.environ.get("SUDO_UID"))
  343 + else:
  344 + # Kludge, retains privileges
  345 + return os.getuid()
  346 +
  347 +def drop_privileges(uid, gid):
  348 + # Once everything is done, drop our privs
  349 + if cli_options.log:
  350 + with open(cli_options.log, 'r') as f:
  351 + os.fchown(f.fileno(), uid, -1)
  352 + if uid not in [os.getuid(), -1]:
  353 + os.setuid(uid)
  354 + if gid not in [os.getgid(), -1]:
  355 + os.setgid(gid)
336 356
337 357 if __name__ == "__main__":
  358 + global log
  359 +
338 360 cli_parser = OptionParser()
339 361 cli_parser.add_option("-l", "--log", dest="log", default=None)
340 362 cli_parser.add_option("-n", "--nameserver", dest="nameserver", default=None)
341 363 cli_parser.add_option("-w", "--wait", dest="wait", default=False, action="store_true")
342 364 cli_parser.add_option("-k", "--kill", dest="kill", default=False, action="store_true")
  365 + cli_parser.add_option("-u", "--uid", dest="uid", default=get_unprivileged_uid(), action="store", type=int)
343 366 cli_options, cli_args = cli_parser.parse_args()
344 367
345 368 logging.basicConfig(
@@ -353,17 +376,36 @@ def clean_up_pid():
353 376 try:
354 377 with open(pid_file, "r") as f:
355 378 pid = f.readline().strip()
  379 + if not pid: raise IOError("no pid in pid file")
356 380 log.info("sending SIGTERM to pid %s" % pid)
357 381 os.kill(int(pid), signal.SIGTERM)
358 382 exit(0)
359 383 except IOError:
360   - log.warning("Couldn't find pidfile. Please manually find and kill any existing focus.py process")
  384 + log.warning("Couldn't find pidfile or pid file was empty. Please \
  385 +manually find and kill any existing focus.py process")
361 386 exit(1)
362 387
363   - with open(pid_file, "w") as f: f.write(str(os.getpid()))
  388 + with open(pid_file, "w") as f:
  389 + # Drop ownership of the pidfile
  390 + os.fchown(f.fileno(), get_unprivileged_uid(), -1)
  391 + f.write(str(os.getpid()))
364 392 atexit.register(clean_up_pid)
365 393
366 394 config.update(load_config(config_file))
  395 + # Bind our socket before we do pretty much anything, this means we can drop
  396 + # privileges early, which is a necessaity before we start logging
  397 + #
  398 + # create our main server socket
  399 + try:
  400 + log.info("binding to %s:%d", config["bind_ip"], config["bind_port"])
  401 + server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
  402 + server.setblocking(0)
  403 + server.bind((config["bind_ip"], config["bind_port"]))
  404 +
  405 + # We're done doing things that need root, drop our privileges
  406 + finally:
  407 + drop_privileges(cli_options.uid, -1)
  408 +
367 409 refresh_blacklist()
368 410
369 411
@@ -400,11 +442,6 @@ def clean_up_pid():
400 442
401 443 log.info("loaded %d alternative nameservers: %r", len(nameservers), nameservers)
402 444
403   - # create our main server socket
404   - server = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
405   - server.setblocking(0)
406   - server.bind((config["bind_ip"], config["bind_port"]))
407   -
408 445 readers = [server]
409 446 last_cleaned_readers = 0
410 447

0 comments on commit 012acad

Please sign in to comment.
Something went wrong with that request. Please try again.