Secure Communication Module User’s Guide : PART III HTTPS Package : Chapter 8 Callbacks
Chapter 8 Callbacks
Supplying Your Own Callbacks
This section explains how to write your own certificate name check callback and certificate name mismatch callback, as mentioned in “Using the Security Callbacks.”
NOTE >> Callbacks are implemented using functors. See Chapter 8, “The Functor Package,” in the Threads Module User’s Guide for more information.
Writing a Callback
As you write the callback functions, keep the required function signatures in mind. You can add additional parameters as callee data as described in Chapter 8, “The Functor Package,” in the Threads Module User’s Guide.
NOTE >> Rogue Wave does not provide technical support for writing callbacks. The functions in the HTTPS package that set the callback are provided for convenience only.
To use your callback, you will:
1. Create an appropriate functor that wraps your function and passes in any necessary data. For example, you could pass in a handle to your windowing system to pop up a message box from the callback.
2. Call either RWHttpsSecurityManager::setNameCheckCallback() or RWHttpsSecurityManager::setNameMismatchCallback() and pass your functor as the argument.
NOTE >> A certificate name check callback must return true if the name in the server’s certificate is the same as the name of the host, and false if the names are different.
Example 12 adds callback functions to Example 10. (See “Getting Started with HTTPS.”)
This example uses utility functions provided in util.h.
Example 12 – Supplying a Callback
// File: examples/https/manual/CallbackExample.cpp
 
#include <rw/itc/RWTIOUResult.h>
#include <rw/internet/RWURL.h>
#include <rw/network/RWWinSockInfo.h>
#include <rw/secsock/RWSecureSocketPackageInit.h>
#include <rw/secsock/RWSecureSocketContext.h>
#include <rw/http/RWHttpAgent.h>
#include <rw/http/RWHttpReply.h>
#include <rw/https/RWHttpsSecurityManager.h>
#include <rw/functor/RWTFunctor.h>
 
# include <iostream>
using std::cout;
using std::cerr;
using std::endl;
 
#include <../httpsexampledefs.h>
#include <../util.h>
 
bool myCertificateNameCheckCallback(RWCString host, RWX509Certificate cert);
{
cout << “My Certificate Name Check Function called!” << endl;
 
// This function should return true if the names match and false
// if they don’t.
 
// We return false every time to ensure the Name Mismatch
// Callback gets called. (Example purposes only. Don’t do this!)
 
return false;
 
}
 
void myCertificateNameMismatchCallback(RWCString host, RWX509Certificate cert);
{
cout << “My Certificate Name Mismatch Function called!” << endl;
}
 
int main(int argc, char** argv)
{
RWWinSockInfo info;
RWSecureSocketPackageInit secsockInit;
 
#if defined(RW_SECSOCK_RNG_NEEDS_SEEDING)
RWSecureSocketPackageInit::seedRNGFromFile(SEED_DATA_FILE);
#endif
 
int port = parseCommandLine(argc, argv);
 
RWSecureSocketContext context;
context.prepareToAuthenticate(TRUSTED_CERTS_FILE);
 
RWHttpsSecurityManager::setAgentContext(context);
 
RWHttpsNameCheckCallback nccFunctor =
myCertificateNameCheckCallback; //1
 
RWHttpsSecurityManager::setNameCheckCallback(nccFunctor); //2
 
RWHttpsNameMismatchCallback nmcFunctor =
myCertificateNameMismatchCallback; //3
 
RWHttpsSecurityManager::setNameMismatchCallback(nmcFunctor); //4
 
RWHttpAgent agent;
 
char urlStr[30];
sprintf(urlStr, "https://localhost:%d/", port);
RWURL url(urlStr);
RWTIOUResult<RWHttpReply> replyIOU;
 
try {
replyIOU = agent.executeGet(url);
 
RWHttpReply reply = replyIOU.redeem();
 
cout << reply.asString() << endl;
 
if(reply.is2XX()) {
cout << reply.getBody() << endl;
}
} catch(const RWxmsg& msg) {
cerr << "An unexpected exception occurred: "
<< msg.why() << endl;
return 1;
}
 
return 0;
}
 
// This example is a modification of the RWHttpSecureAgentExample
// which adds the new callback functions.
 
// The first step is to write the callback functions to do what
// you want keeping the required function signatures in mind. You
// can add additional parameters as "Callee Data" as described in
// the Threads Module User's Guide.
//1 Creates the name Check Callback functor.
//2 Directs the HTTPS package to use this functor as the name Check Callback.
//3 Creates the Name Mismatch Callback.
//4 Directs the HTTPS package to use this functor as the name Mismatch Callback.
Switching to the Default Callback
To stop using your callback, call one of these set functions:
RWHttpsSecurityManager::setNameCheckCallback()
RWHttpsSecurityManager::setNameMismatchCallback() with a functor that does not have a body attached; in other words, a default constructed functor handle. See Example 13.
Example 13 – Switching to the Default Callback
RWHttpsNameMismatchCallback functor;
RWHttpsSecurityManager::setNameMismatchCallback (functor);