Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add pwnlib.config module and documentation #893

Merged
merged 1 commit into from
Feb 13, 2017
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 4 additions & 0 deletions docs/source/config.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
:mod:`pwnlib.config` --- Pwntools Configuration File
====================================================

.. automodule:: pwnlib.config
1 change: 1 addition & 0 deletions docs/source/index.rst
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ Each of the ``pwntools`` modules is documented here.
atexception
atexit
constants
config
context
dynelf
encoders
Expand Down
1 change: 1 addition & 0 deletions pwn/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@

pwnlib.args.initialize()
pwnlib.log.install_default_handler()
pwnlib.config.initialize()

log = pwnlib.log.getLogger('pwnlib.exploit')
args = pwnlib.args.args
Expand Down
60 changes: 60 additions & 0 deletions pwnlib/config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
# -*- coding: utf-8 -*-
"""Allows per-user and per-host configuration of Pwntools settings.

The list of configurable options includes all of the logging symbols
and colors, as well as all of the default values on the global context
object.

The configuration file is read from ``~/.pwn.conf`` and ``/etc/pwn.conf``.

The configuration file is only read in ``from pwn import *`` mode, and not
when used in library mode (``import pwnlib``). To read the configuration
file in library mode, invoke :func:`.config.initialize`.

The ``context`` section supports complex types, at least as far as is
supported by ``pwnlib.util.safeeval.expr``.

::

[log]
success.symbol=😎
error.symbol=☠
info.color=blue

[context]
adb_port=4141
randomize=1
timeout=60
terminal=['x-terminal-emulator', '-e']
"""
from __future__ import absolute_import

import ConfigParser
import os

registered_configs = {}

def register_config(section, function):
"""Registers a configuration section.

Arguments:
section(str): Named configuration section
function(callable): Function invoked with a dictionary of
``{option: value}`` for the entries in the section.
"""
registered_configs[section] = function

def initialize():
"""Read the configuration files."""
from pwnlib.log import getLogger
log = getLogger(__name__)

c = ConfigParser.ConfigParser()
c.read(['/etc/pwn.conf', os.path.expanduser('~/.pwn.conf')])

for section in c.sections():
if section not in registered_configs:
log.warn("Unknown configuration section %r" % section)
continue
settings = dict(c.items(section))
registered_configs[section](settings)
19 changes: 19 additions & 0 deletions pwnlib/context/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -21,9 +21,11 @@

import socks

from pwnlib.config import register_config
from pwnlib.device import Device
from pwnlib.timeout import Timeout


_original_socket = socket.socket

class _devnull(object):
Expand Down Expand Up @@ -1343,3 +1345,20 @@ def setter(*a, **kw):
with context.local(**{k:kw.pop(k) for k,v in kw.items() if isinstance(getattr(ContextType, k, None), property)}):
return function(*a, **kw)
return setter

# Read configuration options from the context section
def update_context_defaults(section):
# Circular imports FTW!
from pwnlib.util import safeeval
from pwnlib.log import getLogger
log = getLogger(__name__)
for key, value in section.items():
if key not in ContextType.defaults:
log.warn("Unknown configuration option %r in section %r" % (key, 'context'))
continue
if isinstance(ContextType.defaults[key], (str, unicode)):
value = safeeval.expr(value)

ContextType.defaults[key] = value

register_config('context', update_context_defaults)
33 changes: 17 additions & 16 deletions pwnlib/log.py
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
import time

from pwnlib import term
from pwnlib.config import register_config
from pwnlib.context import Thread
from pwnlib.context import context
from pwnlib.exception import PwnlibException
Expand Down Expand Up @@ -132,26 +133,26 @@
}


# permit setting logging colors from a configuration file
config = os.path.expanduser('~/.pwn.conf')
if os.path.exists(config):
c = ConfigParser.ConfigParser()
c.read([config])

for section in c.sections():
if section not in _msgtype_prefixes:
def read_log_config(settings):
log = getLogger(__name__)
for key, value in settings.items():
if '.' not in key:
log.warn("Invalid configuration option %r in section %r" % (key, 'log'))
continue

for key, value in c.items(section):
if key == 'color':
try:
_msgtype_prefixes[section][0] = getattr(text, value)
except AttributeError:
pass
msgtype, key = key.split('.', 1)

if key == 'color':
current = _msgtype_prefixes[msgtype][0]
_msgtype_prefixes[msgtype][0] = getattr(text, value, current)

elif key == 'symbol':
_msgtype_prefixes[section][1] = value
elif key == 'symbol':
_msgtype_prefixes[msgtype][1] = value
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Same question.

Copy link
Member Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Done


else:
log.warn("Unknown configuration option %r in section %r" % (key, 'log'))

register_config('log', read_log_config)

# the text decoration to use for spinners. the spinners themselves can be found
# in the `pwnlib.term.spinners` module
Expand Down