1

Is there a way to get a callback from the gSoap framework before a server operation is executed? I can read in the documentation that there is a callback (fserveloop) that is called immediately after a server operation is successfully completed, but not before.

The reason I need this is because the program receives requests from several sockets and one of the sockets should only allow a subset of the operations. Hence an access check needs to be performed after parsing is completed, so that we know which operation has been called, but before the operation is executed. Or maybe there is a better way of doing this?

1 Answers1

0

Is there a way to get a callback from the gSoap framework before a server operation is executed?

You could use one of the other callbacks, for example the fparse callback that is called to parse the HTTP headers. You just need to make sure that afterwards you call the original fparse callback function. Like so:

soap->user = (void*)soap->fparse; // save original callback to the user variable
soap->fparse = myfparse;          // set new callback

where

int myfparse(struct soap *soap)
{
   // call original callback
   int err = soap->user != NULL ? ((int (*)(struct soap*))soap->user)(soap) : SOAP_OK;
   if (err == SOAP_OK)
   {
      ... // your logic goes here
   }
   return err;
}

Note:

  1. You can either add the logic before the HTTP header is parsed or afterwards.
  2. You can pass data to your logic by setting soap->user to a struct with data and a member for the original fparse function pointer that you will need.
  3. The cast ((int (*)(struct soap*)) is only safe if you're using it in myfparse as shown after you've made sure to set the soap->user to the original fparse function.
Dr. Alex RE
  • 1,772
  • 1
  • 15
  • 23
  • The fparse callback does give a callback before the operation is executed and this would be a good place to perform the access control. But it seems that the XML document has not yet been parsed and which operation to call has not yet been determined. I have considered manually parsing the soap->buf but I don't really like this solution as it can be slow and might introduce security issues. – Gjermund Stensrud Jun 05 '20 at 12:58
  • I ended up using the fparse callback and then manually parse the XML document in soap-buf using libxml. Although this is leads to the document being parsed twice it is still the best option available. – Gjermund Stensrud Jun 09 '20 at 14:51
  • An alternative approach: if you want more control, then I suggest to look for the `soap_serve()` function in the generated code, typically in `soapServer.cpp`. Just copy this function and rename it, e.g. `serve`. Then add your logic to the front of the keep-alive loop (the `do-while (soap->keep_alive)` loop). Then use your renamed `serve` function instead of `soap_serve`. – Dr. Alex RE Jun 11 '20 at 21:06
  • I'm not the only one working on this project and the code is frequently regenerated as we add more functionality to the system. So altering the generated code is not a sustainable option for us. But thank you for the suggestion! – Gjermund Stensrud Jun 15 '20 at 12:36