Skip to content

Commit

Permalink
Merge pull request #412 from p4p1/dev
Browse files Browse the repository at this point in the history
Reworked widget code structure added progress dialog, colorpicker dialog, Logs Widget
  • Loading branch information
S4ntiagoP authored Oct 17, 2023
2 parents 9d50938 + d5fd5d5 commit f9261c6
Show file tree
Hide file tree
Showing 9 changed files with 396 additions and 8 deletions.
10 changes: 6 additions & 4 deletions client/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -68,8 +68,9 @@ set(
Include/Havoc/PythonApi/Event.h
Include/Havoc/PythonApi/HavocUi.h
Include/Havoc/PythonApi/PyAgentClass.hpp
Include/Havoc/PythonApi/PyDialogClass.hpp
Include/Havoc/PythonApi/PyWidgetClass.hpp
Include/Havoc/PythonApi/UI/PyDialogClass.hpp
Include/Havoc/PythonApi/UI/PyLoggerClass.hpp
Include/Havoc/PythonApi/UI/PyWidgetClass.hpp

# Dialogs
Include/UserInterface/Dialogs/Payload.hpp
Expand Down Expand Up @@ -155,8 +156,9 @@ set(
Source/Havoc/PythonApi/PythonApi.cpp
Source/Havoc/PythonApi/Havoc.cpp
Source/Havoc/PythonApi/HavocUi.cpp
Source/Havoc/PythonApi/PyDialogClass.cpp
Source/Havoc/PythonApi/PyWidgetClass.cpp
Source/Havoc/PythonApi/UI/PyDialogClass.cpp
Source/Havoc/PythonApi/UI/PyLoggerClass.cpp
Source/Havoc/PythonApi/UI/PyWidgetClass.cpp
Source/Havoc/PythonApi/PyDemonClass.cpp
Source/Havoc/PythonApi/Event.cpp
Source/Havoc/Havoc.cpp
Expand Down
2 changes: 2 additions & 0 deletions client/Include/Havoc/PythonApi/PythonApi.h
Original file line number Diff line number Diff line change
Expand Up @@ -45,6 +45,8 @@ namespace PythonAPI
PY_FUNCTION( OpenFileDialog )
PY_FUNCTION( SaveFileDialog )
PY_FUNCTION( QuestionDialog )
PY_FUNCTION( ColorDialog )
PY_FUNCTION( ProgressDialog )
}

namespace PyModule
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -40,11 +40,14 @@ int DialogClass_init( PPyDialogClass self, PyObject *args, PyObject *kwd

PyObject* DialogClass_exec( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_close( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_clear( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addLabel( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addButton( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addCheckbox( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addCombobox( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addLineedit( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addCalendar( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_replaceLabel( PPyDialogClass self, PyObject *args );
PyObject* DialogClass_addImage( PPyDialogClass self, PyObject *args );

#endif
43 changes: 43 additions & 0 deletions client/Include/Havoc/PythonApi/UI/PyLoggerClass.hpp
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
#ifndef HAVOC_PYLOGGERCLASS_H
#define HAVOC_PYLOGGERCLASS_H

#include <UserInterface/HavocUI.hpp>
#include <global.hpp>

#include <QGridLayout>
#include <QTextEdit>
#include <QDialog>

typedef struct
{

QWidget* window;
QGridLayout* layout;
QTextEdit* LogSection;

} PyLoggerQWindow, *PPyLoggerQWindow;

typedef struct
{
PyObject_HEAD

// Demon Info
char* title;
PPyLoggerQWindow LoggerWindow;

} PyLoggerClass, *PPyLoggerClass;

extern PyTypeObject PyLoggerClass_Type;

void LoggerClass_dealloc( PPyLoggerClass self );
PyObject* LoggerClass_new( PyTypeObject *type, PyObject *args, PyObject *kwds );
int LoggerClass_init( PPyLoggerClass self, PyObject *args, PyObject *kwds );

// Methods

PyObject* LoggerClass_setBottomTab( PPyLoggerClass self, PyObject *args );
PyObject* LoggerClass_setSmallTab( PPyLoggerClass self, PyObject *args );
PyObject* LoggerClass_addText( PPyLoggerClass self, PyObject *args );
PyObject* LoggerClass_clear( PPyLoggerClass self, PyObject *args );

#endif
Original file line number Diff line number Diff line change
Expand Up @@ -46,5 +46,8 @@ PyObject* WidgetClass_addCheckbox( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_addCombobox( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_addLineedit( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_addCalendar( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_replaceLabel( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_clear( PPyWidgetClass self, PyObject *args );
PyObject* WidgetClass_addImage( PPyWidgetClass self, PyObject *args );

#endif
76 changes: 74 additions & 2 deletions client/Source/Havoc/PythonApi/HavocUi.cpp
Original file line number Diff line number Diff line change
@@ -1,13 +1,17 @@
#include <Havoc/PythonApi/PythonApi.h>
#include <UserInterface/HavocUI.hpp>

#include <Havoc/PythonApi/PyWidgetClass.hpp>
#include <Havoc/PythonApi/PyDialogClass.hpp>
#include <Havoc/PythonApi/UI/PyWidgetClass.hpp>
#include <Havoc/PythonApi/UI/PyDialogClass.hpp>
#include <Havoc/PythonApi/UI/PyLoggerClass.hpp>

#include <QFile>
#include <QMessageBox>
#include <QFileDialog>
#include <QInputDialog>
#include <QColorDialog>
#include <QProgressDialog>
#include <QTimer>

namespace PythonAPI::HavocUI
{
Expand All @@ -18,6 +22,8 @@ namespace PythonAPI::HavocUI
{ "openfiledialog", PythonAPI::HavocUI::Core::OpenFileDialog, METH_VARARGS, "Python interface for Havoc InputDialog" },
{ "savefiledialog", PythonAPI::HavocUI::Core::SaveFileDialog, METH_VARARGS, "Python interface for Havoc InputDialog" },
{ "questiondialog", PythonAPI::HavocUI::Core::QuestionDialog, METH_VARARGS, "Python interface for Havoc InputDialog" },
{ "colordialog", PythonAPI::HavocUI::Core::ColorDialog, METH_VARARGS, "Python interface for Havoc ColorDialog" },
{ "progressdialog", PythonAPI::HavocUI::Core::ProgressDialog, METH_VARARGS, "Python interface for Havoc ColorDialog" },

{ NULL, NULL, 0, NULL }
};
Expand Down Expand Up @@ -153,6 +159,67 @@ PyObject* PythonAPI::HavocUI::Core::SaveFileDialog(PyObject *self, PyObject *arg
return PyBytes_FromString(data.toStdString().c_str());
}

PyObject* PythonAPI::HavocUI::Core::ColorDialog(PyObject *self, PyObject *args)
{
QColorDialog data = QColorDialog(HavocX::HavocUserInterface->HavocWindow);
QColor sel = data.getColor();
if (sel.isValid()) {
QString colorHex = sel.name();
return PyBytes_FromString(colorHex.toStdString().c_str());
} else {
Py_RETURN_NONE;
}
}

PyObject* PythonAPI::HavocUI::Core::ProgressDialog(PyObject *self, PyObject *args)
{
char *title = nullptr;
char *text= nullptr;
int max_num = 0;
PyObject* callable_obj = nullptr;

if( !PyArg_ParseTuple( args, "ssOi", &title, &text, &callable_obj, &max_num) )
{
Py_RETURN_NONE;
}
if ( !PyCallable_Check(callable_obj) )
{
PyErr_SetString(PyExc_TypeError, "parameter must be callable");
return NULL;
}
QProgressDialog* dialog = new QProgressDialog(title, text, 0, max_num, HavocX::HavocUserInterface->HavocWindow);
dialog->setAutoClose(false);
QTimer* timer = new QTimer();

QMainWindow::connect( timer, &QTimer::timeout, HavocX::HavocUserInterface->HavocWindow, [callable_obj, dialog, timer]() {
PyObject *pResult = PyObject_CallFunctionObjArgs(callable_obj, nullptr);

if (pResult != NULL) {
if (PyLong_Check(pResult)) {
long resultInt = PyLong_AsLong(pResult);
dialog->setValue(resultInt);
if (resultInt < 0) {
dialog->close();
timer->stop();
}
}
} else {
PyErr_SetString(PyExc_TypeError, "Function needs to return an int");
dialog->close();
timer->stop();
}
});
QPushButton *cancelButton = dialog->findChild<QPushButton *>();
QMainWindow::connect( cancelButton, &QPushButton::clicked, HavocX::HavocUserInterface->HavocWindow, [dialog, timer]() {
dialog->close();
timer->stop();
});
timer->start(max_num);
dialog->exec();

Py_RETURN_NONE;
}

PyMODINIT_FUNC PythonAPI::HavocUI::PyInit_HavocUI(void)
{
PyObject* Module = PyModule_Create2( &PythonAPI::HavocUI::PyModule::havocui, PYTHON_API_VERSION );
Expand All @@ -167,5 +234,10 @@ PyMODINIT_FUNC PythonAPI::HavocUI::PyInit_HavocUI(void)
else
PyModule_AddObject( Module, "Dialog", (PyObject*) &PyDialogClass_Type );

if ( PyType_Ready( &PyLoggerClass_Type ) < 0 )
spdlog::error( "Couldn't check if DialogClass is ready" );
else
PyModule_AddObject( Module, "Logger", (PyObject*) &PyLoggerClass_Type );

return Module;
}
Original file line number Diff line number Diff line change
Expand Up @@ -4,7 +4,7 @@
#include <structmember.h>

#include <Havoc/PythonApi/PythonApi.h>
#include <Havoc/PythonApi/PyDialogClass.hpp>
#include <Havoc/PythonApi/UI/PyDialogClass.hpp>


PyMemberDef PyDialogClass_members[] = {
Expand All @@ -19,11 +19,14 @@ PyMethodDef PyDialogClass_methods[] = {
{ "exec", ( PyCFunction ) DialogClass_exec, METH_VARARGS, "Display the window" },
{ "close", ( PyCFunction ) DialogClass_close, METH_VARARGS, "Close the window" },
{ "addLabel", ( PyCFunction ) DialogClass_addLabel, METH_VARARGS, "Insert a label in the window" },
{ "addImage", ( PyCFunction ) DialogClass_addImage, METH_VARARGS, "Insert an image in the window" },
{ "addButton", ( PyCFunction ) DialogClass_addButton, METH_VARARGS, "Insert a button in the window" },
{ "addCheckbox", ( PyCFunction ) DialogClass_addCheckbox, METH_VARARGS, "Insert a checkbox in the window" },
{ "addCombobox", ( PyCFunction ) DialogClass_addCombobox, METH_VARARGS, "Insert a checkbox in the window" },
{ "addLineedit", ( PyCFunction ) DialogClass_addLineedit, METH_VARARGS, "Insert a Line edit in the window" },
{ "addCalendar", ( PyCFunction ) DialogClass_addCalendar, METH_VARARGS, "Insert a Calendar in the window" },
{ "replaceLabel", ( PyCFunction ) DialogClass_replaceLabel, METH_VARARGS, "Replace a label with supplied text" },
{ "clear", ( PyCFunction ) DialogClass_clear, METH_VARARGS, "clear the dialog" },

{ NULL },
};
Expand Down Expand Up @@ -140,6 +143,22 @@ PyObject* DialogClass_addLabel( PPyDialogClass self, PyObject *args )
Py_RETURN_NONE;
}

PyObject* DialogClass_addImage( PPyDialogClass self, PyObject *args )
{
char *text = nullptr;

if( !PyArg_ParseTuple( args, "s", &text) )
{
Py_RETURN_NONE;
}
QPixmap img(text);
QLabel* label = new QLabel(self->DialogWindow->window);
label->setPixmap(img);
self->DialogWindow->layout->addWidget(label);

Py_RETURN_NONE;
}

PyObject* DialogClass_addButton( PPyDialogClass self, PyObject *args )
{
char *text = nullptr;
Expand Down Expand Up @@ -267,9 +286,45 @@ PyObject* DialogClass_addCalendar( PPyDialogClass self, PyObject *args )
Py_RETURN_NONE;
}

PyObject* DialogClass_replaceLabel( PPyDialogClass self, PyObject *args )
{
char* to_find = NULL;
char* to_replace= NULL;
QVBoxLayout *layout = self->DialogWindow->layout;

if( !PyArg_ParseTuple( args, "ss", &to_find, &to_replace) )
{
Py_RETURN_NONE;
}
QString targetText = QString(to_find);
for (int i = 0; i < layout->count(); ++i) {
QLayoutItem* item = layout->itemAt(i);
if (item->widget() && item->widget()->inherits("QLabel")) {
QLabel* label = qobject_cast<QLabel*>(item->widget());
if (label && label->text() == targetText) {
label->setText(to_replace);
break;
}
}
}
Py_RETURN_NONE;
}

PyObject* DialogClass_close( PPyDialogClass self, PyObject *args )
{
self->DialogWindow->window->accept();

Py_RETURN_NONE;
}

PyObject* DialogClass_clear( PPyDialogClass self, PyObject *args )
{
QVBoxLayout *layout = self->DialogWindow->layout;
QLayoutItem* item;

while ((item = layout->takeAt(0)) != nullptr) {
delete item->widget();
delete item;
}
Py_RETURN_NONE;
}
Loading

0 comments on commit f9261c6

Please sign in to comment.