Форум сайта python.su
Всем доброго времени суток.
После перебора попавшихся под руку open source XSS сканеров, понял, что того, чего хотелось бы нет. А хотелось бы хотя бы функционал Xspider.
Собственно, сканер планируется расширяемым, но не по сигнатурам, как в nikto.
В основном затачивается под XSS и SQL уязвимости. GTK GUI и консольные интерфейсы. Работа с задачами и экспорт отчётов в XML/TXT.
А теперь к вопросам :)
1. насколько удачна следующая структура размещения файлов:
spec@baza:~/projects/xcobra > tree
.
|-- tags
|-- xcobra
| |-- __init__.py
| |-- plugins
| | |-- __init__.py
| | |-- xssplugin.py
| |-- urlfinder.py
| |-- xcobra.py
`-- xcobra.py
from xcobra.xcobra import Xcobra import sys app = Xcobra() app.run()
from plugins import xssplugin plugin = xssplugin.XSSPlugin()
Отредактировано (Июнь 10, 2008 23:28:18)
Офлайн
Офлайн
про плагины уже как-то здесь обсуждалось. Я тогда рекомендовал посмотреть на решение в коде bzr. Ваша предполагаемая организация плагинов очень похожа на bzr. Советую посмотреть код.
Офлайн
Andity
Спасибо за ссылку!
bialix
Хммм, надо будет покопаться в этом “базаре” :)
Офлайн
bzrlib/plugin.py
Офлайн
bialix
Хмм, посмотрел bzrlib/plugin.py. Не совсем понравилось использование exec.
for name in plugin_names: try: exec "import bzrlib.plugins.%s" % name in {} except KeyboardInterrupt: raise except Exception, e:
Офлайн
нравится/ненравится. правильно/неправильно… забавно. вы делаете далеко идущие выводы даже не зная откуда взялся такой код. а ведь он взялся не просто так.
Офлайн
bialix, само собой я не думал, ставить себя выше разработчиков “базара”, тем более, что являюсь начинающим программистом на питоне.
Просто у меня ещё с JavaScript/Perl/PHP вызывают подозрения любые вызовы конструкций типа eval, а в данном случае exec. Это как с рекурсией.
Если есть возможность избежать подобного кода, то зачем его использовать?
В данном случае, есть специальная встроенная функция, тогда, если нет весомых причин, то зачем ею пренебрегать?
В любом случае, спасибо за советы :)
P.S. Кстати, есть предположения, почему разработчиками “базара” был выбран именно такой способ импорта?
Отредактировано (Июнь 13, 2008 19:13:09)
Офлайн
этот код появился как замена imp.load_module (см. стандартный модуль imp). Появился этот код вкупе с другим в этом модуле для того, чтобы плагины могли импортировать друг друга. Насколько я помню функция __import__ никогда не использовалась в Базаре, потому что она имеет ограниченную семантику. Почитайте help на нее.
И вообще-то функции и методы с двумя подчеркиваниями вокруг имени имеют специальный смысл в питоне. Чаще всего их переопределяют. Вобщем __import__ хоть и работает, но это не лучший выбор. Эта функция в частности возвращает самый верхний пакет в случае __import__('lib.plugins.foo') это будет lib. Вобщем не считайте ее панацеей. Для разнообразия гляньте хоть на imp.
exec хоть и выглядит страшно, но работает гораздо правильнее. Тем более что он запускается в пустом пространстве имен (exec … in {}) так что ничего вам не испортит.
статья по ссылке jenyay описывает упрощенный вариант загрузки и использования плагинов, исходя из предположения, что плагины пишутся по каким-то правилам, а также что имена модулей плагинов заранее известны. В Базаре загрузка плагина – это импортирование его кода из любого каталога под любым допустимым в питоне именем. Поэтому для поддержки загрузки плагинов в варианте exe (py2exe) я написал функцию load_from_zip. По ссылке загрузка произвольных плагинов из library.zip не рассматривается. А плавно как-то эта проблема обходится стороной. Ну вобщем и понятно: автор статьи не захотел парить себе голову сложностями.
В Базаре для плагинов используется особенность Питона: во время импорта в Питоне код модуля исполняется. Т.е. во время импорта модуль может дергать функции из основной библиотеки проекта и регистрировать какие-то новые сервисы и классы. Для поддержки этого в Базаре реализованы внутренние реестры для различных подсистем (команды, форматы репозитория, транспорты и т.п.).
Вообще тема разработки приложения с поддержкой плагинов очень отличается от традиционных закрытых и монолитных приложений. Хотя бы тем, что вы не знаете заранее какие плагины будут использоваться и что они привнесут в рантайме. Поэтому мягко говоря статья по ссылке хороша для общего развития. Но реально плагины имеют такую кучу граблей разложеных повсюду, и их все надо учитывать…
Я например несколько месяцев назад искал нормальный редактор с поддержкой возможности писать для него плагины на питоне. Фиг вам. Нормальной, удобной поддержки плагинов я не нашел.
Офлайн
По поводу __import__. Она весьма хороша, когда нужно импортировать неизвестный модуль (имя вычисляется динамически). Практически полностью эквивалентна конструкции import something (за исключением того, что ничего не добавляет в globals). sys.modules изменяются корректно. Для обхода указанных bialix сложностей использовал обертки:
def import_mod(name):
mod = __import__(name)
components = name.split('.')
for comp in components:
mod = getattr(mod, comp)
return mod
def import_name(name):
elems = name.split('.')
mod_name = ‘.’.join(elems)
name = elems
mod = __import__(mod_name, globals(), locals(), )
try:
return getattr(mod, name)
except AttributeError:
raise ImportError, ‘module %s has not attribute %s’%(mod_name, elems)
Замена __import__ - грязный хак с множеством неприятных побочных эффектов (сталкивался, поэтому и говорю). С принятием PEP 302 заменять стало не нужно (смотреть соседнюю ветку. Модуль imp предназначен главным образом для написания import hooks.
То, что вставили в базаре - съедобно. Но, ИМХО, можно и чуть элегантней. Врочем, это не тот вопрос, по которому нужно всерьез спорить. Так - тоже неплохо.
Про сложности архитектуры приложения с поддержкой плагинов в свое время уже говорили…
Офлайн