Tuesday 21 May 2013

Creating a WebServices Proxy Wrapper for Checkmarx’s CxWebService

Now that we have the an API to create proxies (see Creating an API to create the WebServices Proxy Wrapper classes/asmx files) its time to create the proxy I really need, which is the Checkmarx webservice responsible for (amongst other things) returning security guidance (see Adding O2's CSharp REPL to the Checkmarx main WebService for more details)

Currently I have the latest version of Checkmarx installed on my dev box, which uses the UltraDev web server:

image

The one we want to wrap is the CxWebService one:

image

which is available at the http://localhost/CxWebInterface/ address:

image

with the wsdl available at: http://localhost/CxWebInterface/CxWebService.asmx?WSDL

image

There is already an API in the O2.Platform.Scripts that can be used to programmatically create the WSDL, so lets use it :)

image

The wsdl is created on line 6, and on line 7 it is shown on a code editor:

image

Once we have the wsdl we just need to use the API_ASMX_Proxy (described here) to create the proxy class:

image

In the script above:
  • lines 2-5    : create a gui with a folder viewer and WebBrowser
  • lines 7-10  : webservice settings and location
  • line 12      : create c# for wsdl file (cached so that it is only done once)
  • line 14      : create proxy files
  • line 16      : refresh folder viewer
  • line 17      : open url in web browser
  • lines 20-22: file imports and extra using reference
After execution this is what my dev Gui looks like (with the script shown above in the middle, and the folderviewer+browser shown at the top):

image

If we open the CxWebService.asmx we can see the wsdl generation worked:

image

and if we open the _WebMethod_CxPortalWebService.cs file from the App_Code folder, we can see the auto-generated proxy file:

image

OK, let’s see this in action :)

First a little trick to make sure that all our traffic goes trough Fiddler.

I changed the original WSDL location to the http://local path (which is an extra mapping I have on my drivers\etc\hosts file, that points to 127.0.0.1)

image

Once that is set, I re executed the script, and had these 4 entries on fiddler:

image

I then clicked on the CxWebService.asmx link (top right browser window) and chose one method at random (like the CancelScan)

image 

Next I entered some dummy values in the WebServices test GUI

image

Clicked on Invoke and got this result:

image 

If we go back to Fiddler, we can see two requests:

image

The first is the call to the proxied WebService WebMethod:

image

the 2nd is the one to the real WebService WebMethod:

image

Note that this 2nd request was sent using SOAP, so it should be easier to read like this.

image

so far so good :)

Next let’s try to login using the CxAudit tool (the client side, desktop-running tool):

 image

click on Details:

image

and replace the Server Address with our proxied web services location.

Then enter a password and click on Login

image

And we are logged in :)

image

with fiddler showing a pair of calls for each request made by CxAudit

image

which for reference, the first pair  was to the Login WebService method:

image

and the 2nd one to GetProjectsWithScans 

image

And just to make sure all works ok, I selected a project, chose a rule pack, and clicked Scan

image

which generated a number of paired-up web services requests:

image

with the results showing up ok :)

image

 If we now chose an Query Name and click on the Show Description menu option, we can see the default CheckMarx guidance:

image

and if we look at fiddler we will have 2 new web services requests

image

to GetQueryDescription:

image

which is the method we need to change at our web services proxy (and replace with TeamMentor Guidance)

but that is the topic for the next post …


Tip: Using VisualStudio to debug and develop the proxied code:

To debug the generated code (and in case you prefer VisualStudio development), you can open the web root in visualStudio:

image

set breakpoints:

image

and debug/write the code right here:

image

I used this to quickly debug an issue I had.

Notice the difference between the request above and this one:

image

Basically the applicationCredentials object was not being populated....

This happened because there was missing / in the Namepace

i.e. it was:

image

and it needs to be:

image

this actually feels like a little bug inside the .Net Framework, since if we remove the Namespace:

image

we get this error:

image

and no hit on the Login breakpoint

Anyway, the solution is to rebuild the proxied files with the fix

image