Skip to content

Commit

Permalink
Python error checking, authentication fixes.
Browse files Browse the repository at this point in the history
  • Loading branch information
psychogenic committed Jun 11, 2019
1 parent 0f1f831 commit 788da01
Show file tree
Hide file tree
Showing 4 changed files with 90 additions and 16 deletions.
1 change: 1 addition & 0 deletions src/CommChannelArdStd.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -872,6 +872,7 @@ size_t ChannelModeProg::printAccessConfigureRequest(Auth::Authenticator * auth)
PROGCHANNEL_OUTFIELD(SERIAL_UI_PROGCHANFIELD_AUTHENTICATION_START);
PROGCHANNEL_OUTFIELD(SerialUI::Auth::Request::Type::Setup);
PROGCHANNEL_OUTFIELD(SERIAL_UI_PROGCHANFIELD_AUTHENTICATION_END);
retsize += printHelpListEnd(Globals::menuStructure()->topLevelMenu());
return retsize + 3;
}
#endif
Expand Down
14 changes: 14 additions & 0 deletions src/ExternalModule.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -371,6 +371,20 @@ class ExtModuleAuthValidatorBridge : public Auth::Validator {
virtual Auth::Level::Value grantAccess(Auth::ChallengeResponse resp) {
SERIALUI_DEBUG_OUTLN("ExtModuleAuthValid.grantAccess()");
SERIALUI_DEBUG_OUTLN(resp);

// first, just check that this value is sane
PyObject * val = Py_BuildValue("(s)", resp);
if (val) {
// ok, all well
Py_DECREF(val); // get rid of this.
} else {
SERIALUI_DEBUG_OUTLN("Could not build a value with this 'challenge response'?");
if (PyErr_Occurred()) {
PyErr_Print();
}
return Auth::Level::NoAccess;
}

PyObject * retObj = SUIPyObjectsStore.callMethodOnAuthValidator("grantAccess", "(s)", resp);
if ((!retObj) || retObj == Py_None) {
SERIALUI_DEBUG_OUTLN("No ret/ret none");
Expand Down
60 changes: 48 additions & 12 deletions src/ExternalPython.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -61,6 +61,12 @@
#include <sstream>
#include <string>

#define SUIPY_CALLOBJECT_REPORTERROR() \
if (PyErr_Occurred()) { \
SERIALUI_DEBUG_OUTLN("Callobject returned error"); \
PyErr_Print(); \
}


#define OBSTORE_CALLVALIDATORONINPUTS(forId, vformat, val) \
ItemPyObjectSet inputsToNotify = inputsFor(forId); \
Expand Down Expand Up @@ -136,6 +142,8 @@ void ObjectsStore::callTriggeredOnCommands(uint8_t forId) {
PyObject * retObj = PyObject_CallMethod(*it, "triggered", "()");
if (retObj) {
Py_DECREF(retObj);
} else {
SUIPY_CALLOBJECT_REPORTERROR();
}
}
// Py_END_ALLOW_THREADS
Expand All @@ -154,6 +162,8 @@ void ObjectsStore::callTriggeredOnInputs(uint8_t forId) {
PyObject * retObj = PyObject_CallMethod(*it, "changed", "()");
if (retObj) {
Py_DECREF(retObj);
} else {
SUIPY_CALLOBJECT_REPORTERROR();
}
}

Expand Down Expand Up @@ -189,24 +199,28 @@ bool ObjectsStore::callValidatorOnInputs(uint8_t forId,
void ObjectsStore::deleteEntryFor(uint8_t forId, PyObject * obj) {

if (commands.find(forId) != commands.end()) {
/*
for (ItemPyObjectSet::iterator it = commands[forId].begin();
it != commands[forId].end(); it++) {
if (*it == obj) {
// Py_DECREF(obj);
}
}
*/

SERIALUI_DEBUG_OUTLN("Store ERASE command " << obj);
commands[forId].erase(obj);

}
if (inputs.find(forId) != inputs.end()) {
/*
for (ItemPyObjectSet::iterator it = inputs[forId].begin();
it != inputs[forId].end(); it++) {
if (*it == obj) {
// Py_DECREF(obj);
}
}
*/
SERIALUI_DEBUG_OUTLN("Store ERASE input " << obj);
// if (! obj->ob_refcnt) {
inputs[forId].erase(obj);
Expand Down Expand Up @@ -731,6 +745,8 @@ static PyObject* pysui_top(PyObject* self, PyObject* args) {
PyObject *argList = Py_BuildValue("si", topMen->key(), topMen->id());

PyObject* retVal = PyObject_CallObject((PyObject *) &SUIItemContainerType, argList);
SUIPY_CALLOBJECT_REPORTERROR();

Py_DECREF(argList);
return retVal;
}
Expand Down Expand Up @@ -1013,7 +1029,13 @@ SUIInputWrapper_isValid(SUIInputWrapperObject *self, PyObject * args) {
SERIALUI_DEBUG_OUT("input isValid() ");
if (self->callbacks[1]) {
SERIALUI_DEBUG_OUTLN("Have callback set, triggering that");
return PyObject_CallObject(self->callbacks[1], args);
PyObject * retObj = PyObject_CallObject(self->callbacks[1], args);
if (retObj) {
return retObj;
} else {
SUIPY_CALLOBJECT_REPORTERROR();
Py_RETURN_TRUE;
}
}
SERIALUI_DEBUG_OUTLN("Default isValid() triggered");

Expand All @@ -1026,7 +1048,13 @@ SUIInputWrapper_changed(SUIInputWrapperObject *self, PyObject * args) {
SERIALUI_DEBUG_OUT("input changed() ");
if (self->callbacks[0]) {
SERIALUI_DEBUG_OUTLN("Have callback set, triggering that");
return PyObject_CallObject(self->callbacks[0], nullptr);
PyObject * retObj = PyObject_CallObject(self->callbacks[0], nullptr);
if (retObj) {
return retObj;
} else {
SUIPY_CALLOBJECT_REPORTERROR();
Py_RETURN_NONE;
}
}

SERIALUI_DEBUG_OUTLN("Default changed() triggered");
Expand Down Expand Up @@ -1083,13 +1111,11 @@ static PyMethodDef SUIInputWrapper_methods[] = {
{"isValid", (PyCFunction) SUIInputWrapper_isValid, METH_VARARGS,
"Confirm whether the passed value is actually acceptable" },
{"setValidator", (PyCFunction)SUIInputWrapper_setValidator,
METH_VARARGS,
"set method triggered to validate changes" },
{ "changed", (PyCFunction) SUIInputWrapper_changed, METH_NOARGS,
"method triggered on change" },
METH_VARARGS, "set method triggered to validate changes" },
{ "changed", (PyCFunction) SUIInputWrapper_changed,
METH_NOARGS, "method triggered on change" },
{"setOnChange", (PyCFunction)SUIInputWrapper_setOnChange,
METH_VARARGS,
"set method triggered on change" },
METH_VARARGS, "set method triggered on change" },


{ NULL } /* Sentinel */
Expand Down Expand Up @@ -1177,7 +1203,13 @@ static PyObject *
SUICommandWrapper_triggered(SUICommandWrapperObject *self, PyObject * args) {
if (self->callbacks[0]) {
SERIALUI_DEBUG_OUTLN("Calling trigger override");
return PyObject_CallObject(self->callbacks[0], nullptr);
PyObject * retObj = PyObject_CallObject(self->callbacks[0], nullptr);
if (retObj) {
return retObj;
} else {
SUIPY_CALLOBJECT_REPORTERROR();
Py_RETURN_NONE;
}
} else {
SERIALUI_DEBUG_OUTLN("Default command trigger()");
}
Expand Down Expand Up @@ -1248,8 +1280,8 @@ static int SUIItemContainer_init(SUIItemContainerObject *self, PyObject *args,
SERIALUI_DEBUG_OUTLN("SUIItemContainer_init itm " << (int)self->id << " is not a container");


PyErr_SetString(PyExc_RuntimeError, "no such submenu/container");
return -1;
PyErr_SetString(PyExc_RuntimeError, "no such submenu/container");
return -1;
}
self->container = submen;

Expand All @@ -1265,16 +1297,17 @@ SUIItemContainer_children(SUIItemContainerObject *self, PyObject * args) {
PyObject * childList = PyList_New(0);

if (! childList) {
PyErr_SetString(PyExc_RuntimeError, "can't alloc new list");
Py_RETURN_NONE;
}

for (uint8_t i=0; i<numChildren; i++) {
SerialUI::Menu::Item::Item * itm = self->container->itemByIndex(i);

PyObject *argList = Py_BuildValue("si", itm->key(), itm->id());

PyObject * curObj = NULL;


switch (itm->type()) {
case SerialUI::Menu::Item::Type::Input:
// std::cerr << "create input" << std::endl;
Expand Down Expand Up @@ -1308,6 +1341,7 @@ SUIItemContainer_children(SUIItemContainerObject *self, PyObject * args) {
Py_DECREF(curObj);
// std::cerr << "APPENDED OBJ TO LIST, ref:" << curObj->ob_refcnt << std::endl;
}
SUIPY_CALLOBJECT_REPORTERROR();

/* Release the argument list. */
Py_DECREF(argList);
Expand Down Expand Up @@ -1998,6 +2032,8 @@ static PyObject* pysui_trackers(PyObject* self, PyObject* args) {
PyList_Append(myTrackers, curObj);
Py_DECREF(curObj);
// std::cerr << "APPENDED OBJ TO LIST, ref:" << curObj->ob_refcnt << std::endl;
} else {
SUIPY_CALLOBJECT_REPORTERROR();
}

/* Release the argument list. */
Expand Down
31 changes: 27 additions & 4 deletions src/includes/python/ExternalPython.h
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,12 @@
* ExternalPython.h
*
* Created on: May 11, 2019
* Author: malcalypse
* Author: Pat Deegan
*
* Part of the SerialUI project.
* Copyright (C) 2019 Pat Deegan, https://psychogenic.com
* More information on licensing and usage at
* https://devicedruid.com/
*/

#ifndef SERIALUI_SRC_INCLUDES_PYTHON_EXTERNALPYTHON_H_
Expand Down Expand Up @@ -107,7 +112,17 @@ class ObjectsStore {

}
SERIALUI_DEBUG_OUTLN("', triggering");
return PyObject_CallMethod(auth_storage, methName, format, args...);
PyObject * ret = PyObject_CallMethod(auth_storage, methName, format, args...);
if (ret) {
SERIALUI_DEBUG_OUT("Got RESP: ");
SERIALUI_DEBUG_OUTLN(ret);
} else {
SERIALUI_DEBUG_OUTLN("No RESP! Problem calling meth on authstorage");
if (PyErr_Occurred()) {
PyErr_Print();
}
}
return ret;
}

template<typename... Args> // var args
Expand Down Expand Up @@ -135,8 +150,16 @@ class ObjectsStore {

SERIALUI_DEBUG_OUTLN("', triggering");
PyObject * ret = PyObject_CallMethod(auth_validator, methName, format, args...);
SERIALUI_DEBUG_OUT("Got RESP: ");
SERIALUI_DEBUG_OUTLN(ret);

if (ret) {
SERIALUI_DEBUG_OUT("Got RESP: ");
SERIALUI_DEBUG_OUTLN(ret);
} else {
SERIALUI_DEBUG_OUTLN("No RESP! Problem calling meth on authvalidator");
if (PyErr_Occurred()) {
PyErr_Print();
}
}
return ret;
}

Expand Down

0 comments on commit 788da01

Please sign in to comment.