Click here to Skip to main content
15,878,945 members
Articles / Programming Languages / C++

RCF - Interprocess Communication for C++

Rate me:
Please Sign up or sign in to vote.
4.94/5 (147 votes)
25 Oct 2011CPOL20 min read 4.6M   8.4K   331  
A server/client IPC framework, using the C++ preprocessor as an IDL compiler.
// uncomment to enable VLD leak detection - will automatically link to required libs
//#include "vld.h"
//#include "vldapi.h"

#include <string>

#include <boost/bind.hpp>
#include <boost/function.hpp>

#include <RCF/test/TestMinimal.hpp>

#include <RCF/FilterService.hpp>
#include <RCF/Idl.hpp>
#include <RCF/RcfServer.hpp>
#include <RCF/SspiFilter.hpp>
#include <RCF/TcpEndpoint.hpp>
#include <RCF/ZlibCompressionFilter.hpp>
#include <RCF/test/TransportFactories.hpp>
#include <RCF/util/CommandLine.hpp>

#include <RCF/util/AutoBuild.hpp>

#ifdef UNICODE
#include <SF/wstring.hpp>

namespace std {

    template<typename Archive>
    void serialize(Archive &ar, std::wstring &t, const unsigned int)
    {
        RCF_ASSERT(0);
    }

}

#endif

// towupper()
#include <ctype.h>
#include <wctype.h>

namespace Test_SspiFilter {

    // TODO: auto detect the domain, and run this test with domain and without.
    bool iHaveADomain = true;

    typedef RCF::tstring tstring;

    // case insensitive comparison, for Windows user names
    bool icmpCh(char ch1, char ch2)
    {
        return toupper(ch1) == toupper(ch2);
    }

    bool icmpWch(wchar_t ch1, wchar_t ch2)
    {
        return towupper(ch1) == towupper(ch2);
    }

    bool icmp(const std::string &s1, const std::string &s2)
    {
        return
            s1.size() == s2.size() &&
            std::equal(s1.begin(), s1.end(), s2.begin(), icmpCh);
    }

#ifdef UNICODE

    bool icmp(const std::wstring &s1, const std::wstring &s2)
    {
        return
            s1.size() == s2.size() &&
            std::equal(s1.begin(), s1.end(), s2.begin(), icmpWch);
    }

#endif

    bool isSspiFilter(RCF::FilterPtr filterPtr)
    {
        return boost::dynamic_pointer_cast<RCF::SspiFilterBase>(filterPtr);
    }

    class Echo
    {
    public:
        tstring echo(const tstring &s)
        {
            return s;
        }

        tstring getUserName()
        {
            std::vector<RCF::FilterPtr>::const_iterator iter = std::find_if(
                RCF::getCurrentRcfSessionPtr()->getTransportFilters().begin(),
                RCF::getCurrentRcfSessionPtr()->getTransportFilters().end(),
                isSspiFilter);

            if (iter != RCF::getCurrentRcfSessionPtr()->getTransportFilters().end())
            {
                RCF::SspiFilterBasePtr sspiFilterPtr = boost::dynamic_pointer_cast<RCF::SspiFilterBase>(*iter);
                RCF::SspiImpersonator impersonator(sspiFilterPtr);
                bool ok = impersonator.impersonate();
                return RCF::getMyUserName();
            }
            else
            {
                return RCF::getMyUserName();
            }
        }
    };

    RCF_BEGIN(I_Echo, "I_Echo")
        RCF_METHOD_R1(tstring, echo, const tstring &)
        RCF_METHOD_R0(tstring, getUserName)
    RCF_END(I_Echo)

    typedef boost::function1<
        RCF::FilterPtr, RCF::SspiFilterBase::QualityOfProtection>
            CreateFilter;

    class CreateFilterInfo
    {
    public:
        CreateFilterInfo()
        {}

        CreateFilterInfo(
            CreateFilter createFilter,
            const tstring &username,
            const std::string &desc) :
                mCreateFilter(createFilter),
                mUsername(username),
                mDesc(desc)
        {}

        CreateFilter mCreateFilter;
        tstring mUsername;
        std::string mDesc;
    };

    RCF::FilterPtr createSspiNtlmFilter(
        const tstring &userName,
        const tstring &password,
        const tstring &domain,
        const tstring &targetName,
        RCF::SspiFilterBase::QualityOfProtection qop)
    {
        RCF_UNUSED_VARIABLE(targetName);
        return RCF::FilterPtr(
            new RCF::SspiNtlmFilter(
                userName,
                password,
                domain,
                qop));
    }

    RCF::FilterPtr createSspiKerberosFilter(
        const tstring &userName,
        const tstring &password,
        const tstring &domain,
        const tstring &targetName,
        RCF::SspiFilterBase::QualityOfProtection qop)
    {
        return RCF::FilterPtr(
            new RCF::SspiKerberosFilter(
                userName,
                password,
                domain,
                targetName,
                qop));
    }

    RCF::FilterPtr createSspiNegotiateFilter(
        const tstring &userName,
        const tstring &password,
        const tstring &domain,
        const tstring &targetName,
        RCF::SspiFilterBase::QualityOfProtection qop)
    {
        return RCF::FilterPtr(
            new RCF::SspiNegotiateFilter(
                userName,
                password,
                domain,
                targetName,
                qop));
    }

    // server side setup (which filters will be available)
    void setupTest(
        int k,
        RCF::FilterServicePtr filterServicePtr,
        std::vector<CreateFilterInfo> &factoriesOk,
        std::vector<CreateFilterInfo> &factoriesNotOk)
    {

        tstring NegotiablePackages = iHaveADomain ?
            _T("Kerberos, NTLM") :
            _T("NTLM");

        std::vector<int> filterIds;

        tstring localUsername;
        tstring localPassword;
        tstring localPasswordBad;

        tstring adUsername;
        tstring adPassword;
        tstring adPasswordBad;
        tstring adDomain;

        {
            std::string localUsername_;
            std::string localPassword_;
            std::string localPasswordBad_;

            std::string adUsername_;
            std::string adPassword_;
            std::string adPasswordBad_;
            std::string adDomain_;

            std::string whichFile = TEMP_DIR "sspi.txt";
            std::ifstream fin(whichFile.c_str());
            fin >> localUsername_;
            fin >> localPassword_;
            fin >> localPasswordBad_;
            fin >> adUsername_;
            fin >> adPassword_;
            fin >> adPasswordBad_;
            fin >> adDomain_;
            fin.close();

            localUsername        = util::toTstring(localUsername_);
            localPassword        = util::toTstring(localPassword_);
            localPasswordBad    = util::toTstring(localPasswordBad_);

            adUsername            = util::toTstring(adUsername_);
            adPassword            = util::toTstring(adPassword_);
            adPasswordBad        = util::toTstring(adPasswordBad_);
            adDomain            = util::toTstring(adDomain_);

            if (localUsername.empty() || adUsername.empty())
            {
                throw RCF::Exception("File not found: " + whichFile);
            }
        }

        tstring myUserName = RCF::getMyUserName();
        tstring myDomain = RCF::getMyDomain();
        tstring targetSpn = myDomain + _T("\\") + myUserName;

        CreateFilterInfo implicitNtlm(
            boost::bind(&createSspiNtlmFilter, _T(""), _T(""), _T(""), targetSpn, _1),
            myUserName,
            "NTLM - implicit credentials");

        CreateFilterInfo explicitNtlm(
            boost::bind(&createSspiNtlmFilter, localUsername, localPassword, _T(""), targetSpn, _1),
            localUsername,
            "NTLM - explicit credentials");

        CreateFilterInfo explicitNtlmBad(
            boost::bind(&createSspiNtlmFilter, localUsername, localPasswordBad, _T(""), targetSpn, _1),
            localUsername,
            "NTLM - incorrect explicit credentials");

        CreateFilterInfo implicitKerberos(
            boost::bind(&createSspiKerberosFilter, _T(""), _T(""), _T(""), targetSpn, _1),
            myUserName,
            "Kerberos - implicit credentials");

        CreateFilterInfo explicitKerberos(
            boost::bind(&createSspiKerberosFilter, adUsername, adPassword, adDomain, targetSpn, _1),
            localUsername,
            "Kerberos - explicit credentials");

        CreateFilterInfo explicitKerberosBad(
            boost::bind(&createSspiKerberosFilter, adUsername, adPasswordBad, adDomain, targetSpn, _1),
            localUsername,
            "Kerberos - incorrect explicit credentials");

        CreateFilterInfo implicitNegotiateNtlm(
            boost::bind(&createSspiNegotiateFilter, _T(""), _T(""), _T(""), _T(""), _1),
            myUserName,
            "Negotiate (NTLM) - implicit credentials");

        CreateFilterInfo implicitNegotiateKerberos(
            boost::bind(&createSspiNegotiateFilter, _T(""), _T(""), _T(""), targetSpn, _1),
            myUserName,
            "Negotiate (Kerberos) - implicit credentials");

        CreateFilterInfo explicitNegotiateNtlm(
            boost::bind(&createSspiNegotiateFilter, localUsername, localPassword, _T(""), _T(""), _1),
            localUsername,
            "Negotiate (NTLM) - explicit credentials");

        CreateFilterInfo explicitNegotiateKerberos(
            boost::bind(&createSspiNegotiateFilter, adUsername, adPassword, adDomain, targetSpn, _1),
            localUsername,
            "Negotiate (Kerberos) - explicit credentials");

        CreateFilterInfo explicitNegotiateNtlmBad(
            boost::bind(&createSspiNegotiateFilter, localUsername, localPasswordBad, _T(""), _T(""), _1),
            localUsername,
            "Negotiate (NTLM) - incorrect explicit credentials");

        CreateFilterInfo explicitNegotiateKerberosBad(
            boost::bind(&createSspiNegotiateFilter, adUsername, adPasswordBad, adDomain, targetSpn, _1),
            localUsername,
            "Negotiate (Kerberos) - incorrect explicit credentials ");

        switch (k)
        {
        case 0:
            // restrict authentication to Kerberos

            std::cout << "Server side - only Kerberos authentication" << std::endl;

            filterIds.clear();
            filterIds.push_back(RCF::SspiKerberosFilter::sGetFilterDescription().getId());
            filterIds.push_back(RCF::SspiNegotiateFilter::sGetFilterDescription().getId());
            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr( new RCF::SspiKerberosFilterFactory()),
                filterIds);

            if (iHaveADomain)
            {
                factoriesOk.push_back(implicitKerberos);
                factoriesOk.push_back(explicitKerberos);

                //factoriesOk.push_back(implicitNegotiateKerberos);
                //factoriesOk.push_back(explicitNegotiateKerberos);
            }
            else
            {
                factoriesNotOk.push_back(implicitKerberos);
                factoriesNotOk.push_back(explicitKerberos);
                //factoriesNotOk.push_back(implicitNegotiateKerberos);
                //factoriesNotOk.push_back(explicitNegotiateKerberos);
            }

            factoriesNotOk.push_back(implicitNtlm);
            factoriesNotOk.push_back(explicitNtlm);

            //factoriesNotOk.push_back(implicitNegotiateNtlm);
            //factoriesNotOk.push_back(explicitNegotiateNtlm);

            factoriesNotOk.push_back(explicitKerberosBad);
            factoriesNotOk.push_back(explicitNtlmBad);

            break;

        case 1:

            std::cout << "Server side - only NTLM authentication" << std::endl;

            // restrict authentication to NTLM
            filterIds.clear();
            filterIds.push_back(RCF::SspiNtlmFilter::sGetFilterDescription().getId());
            filterIds.push_back(RCF::SspiNegotiateFilter::sGetFilterDescription().getId());
            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr( new RCF::SspiNtlmFilterFactory()),
                filterIds);

            factoriesOk.push_back(implicitNtlm);
            factoriesOk.push_back(explicitNtlm);

            //factoriesOk.push_back(implicitNegotiateNtlm);
            //factoriesOk.push_back(explicitNegotiateNtlm);

            factoriesNotOk.push_back(implicitKerberos);
            factoriesNotOk.push_back(explicitKerberos);

            //factoriesNotOk.push_back(implicitNegotiateKerberos);
            //factoriesNotOk.push_back(explicitNegotiateKerberos);

            factoriesNotOk.push_back(explicitKerberosBad);
            factoriesNotOk.push_back(explicitNtlmBad);

            break;

        case 2:
            // allow either authentication (through a single Negotiate filter)

            std::cout << "Server side - NTLM or Kerberos authentication (Negotiate)" << std::endl;

            filterIds.clear();
            filterIds.push_back(RCF::SspiKerberosFilter::sGetFilterDescription().getId());
            filterIds.push_back(RCF::SspiNtlmFilter::sGetFilterDescription().getId());
            filterIds.push_back(RCF::SspiNegotiateFilter::sGetFilterDescription().getId());
            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr( new RCF::SspiNegotiateFilterFactory(NegotiablePackages)),
                filterIds);

            // TODO: can't seem to make NTLM connections here, at least not on AD system

            //factoriesOk.push_back(implicitNtlm);
            //factoriesOk.push_back(explicitNtlm);

            //factoriesOk.push_back(implicitNegotiateNtlm);
            //factoriesOk.push_back(explicitNegotiateNtlm);

            if (iHaveADomain)
            {
                 //factoriesOk.push_back(implicitKerberos);
                 //factoriesOk.push_back(explicitKerberos);
                 factoriesOk.push_back(implicitNegotiateKerberos);
                 factoriesOk.push_back(explicitNegotiateKerberos);
            }
            else
            {
                //factoriesNotOk.push_back(implicitKerberos);
                //factoriesNotOk.push_back(explicitKerberos);
                factoriesNotOk.push_back(implicitNegotiateKerberos);
                factoriesNotOk.push_back(explicitNegotiateKerberos);
            }

            factoriesNotOk.push_back(explicitKerberosBad);
            factoriesNotOk.push_back(explicitNtlmBad);
            factoriesNotOk.push_back(explicitNegotiateKerberosBad);
            factoriesNotOk.push_back(explicitNegotiateNtlmBad);

            break;

        case 3:
            // allow either authentication (through distinct filters)

            std::cout << "Server side - Kerberos or NTLM authentication (distinct)" << std::endl;

            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr( new RCF::SspiNtlmFilterFactory()));

            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr( new RCF::SspiKerberosFilterFactory()));

            filterServicePtr->addFilterFactory(
                RCF::FilterFactoryPtr(
                    new RCF::SspiNegotiateFilterFactory(NegotiablePackages)));

            factoriesOk.push_back(implicitNtlm);
            factoriesOk.push_back(explicitNtlm);

            //factoriesOk.push_back(implicitNegotiateNtlm);
            //factoriesOk.push_back(explicitNegotiateNtlm);

            if (iHaveADomain)
            {
                factoriesOk.push_back(implicitKerberos);
                factoriesOk.push_back(explicitKerberos);
                //factoriesOk.push_back(implicitNegotiateKerberos);
                //factoriesOk.push_back(explicitNegotiateKerberos);
            }
            else
            {
                factoriesNotOk.push_back(implicitKerberos);
                factoriesNotOk.push_back(explicitKerberos);
                factoriesNotOk.push_back(implicitNegotiateKerberos);
                factoriesNotOk.push_back(explicitNegotiateKerberos);
            }

            factoriesNotOk.push_back(explicitKerberosBad);
            factoriesNotOk.push_back(explicitNtlmBad);

            break;

        default:
            RCF_ASSERT(0)(k);
        }

    }

} // namespace Test_SspiFilter

int RCF_TEST_MAIN(int argc, char **argv)
{
    printTestHeader(__FILE__);

#if defined(__MINGW32__) && __GNUC__ == 3 && __GNUC_MINOR__ <= 2

    BOOST_CHECK( 1== 0 && "this test crashes on explicit-incorrect-NTLM to NTLM, with mingw 3.2 , for unknown reasons");
    return boost::exit_success;

#endif

    std::string myUserName = util::toString(RCF::getMyUserName());
    std::string myDomain = util::toString(RCF::getMyDomain());

    std::cout
        << "My user name: " << myUserName
        << std::endl
        << "My domain: " <<  myDomain
        << std::endl
        << std::endl;

    using namespace Test_SspiFilter;

    util::CommandLineOption<int> clClientTimeout(
        "timeout",
        10, "client timeout (s)");

    util::CommandLine::getSingleton().parse(argc, argv);

    tstring usernameOrig = RCF::getMyUserName();

    /*
    // This code doesn't work but it would be nice if it did.
    {
        tstring s;
        tstring s0 = _T("asdfasdf");

        RCF::FilterServicePtr filterServicePtr(new RCF::FilterService());
        RCF::FilterPtr filterPtr( new RCF::SspiNegotiateClientFilter(_T("")));
        filterServicePtr->addFilterFactory(RCF::FilterFactoryPtr( new RCF::SspiNegotiateFilterFactory()));
        filterServicePtr->addFilterFactory(RCF::FilterFactoryPtr( new RCF::SspiKerberosFilterFactory()));

        Echo echo;
        RCF::RcfServer server( RCF::TcpEndpoint(50001));
        server.bind<I_Echo>(echo);
        server.addService( RCF::ServicePtr(filterServicePtr));
        server.start();

        RcfClient<I_Echo> client( RCF::TcpEndpoint("localhost", 50001));
        client.getClientStub().setRemoteCallTimeoutMs(1000*3600);

        // not encrypted
        s = client.echo(s0);

        // kerberos
        client.getClientStub().requestTransportFilters( RCF::FilterPtr(
            new RCF::SspiKerberosFilter("towersoft\\jarl")));
        s = client.echo(s0);

        // negotiate kerberos
        client.getClientStub().requestTransportFilters( RCF::FilterPtr(
            new RCF::SspiNegotiateFilter("towersoft\\jarl")));
        s = client.echo(s0);

        // negotiate ntlm
        client.getClientStub().requestTransportFilters( RCF::FilterPtr(
            new RCF::SspiNegotiateFilter(_T(""))));
        s = client.echo(s0);
    }
    */

    // simple warm-up test (implicit NTLM authentication)
    {
        tstring s;
        tstring s0 = _T("asdfasdf");

        RCF::FilterServicePtr filterServicePtr(new RCF::FilterService());
        filterServicePtr->addFilterFactory(RCF::FilterFactoryPtr( new RCF::SspiNtlmFilterFactory()));

        Echo echo;
        RCF::RcfServer server( RCF::TcpEndpoint(50001));
        server.bind( (I_Echo*) 0, echo);
        server.addService( RCF::ServicePtr(filterServicePtr));
        server.start();

        RcfClient<I_Echo> client( RCF::TcpEndpoint("localhost", 50001));
        client.getClientStub().setRemoteCallTimeoutMs(1000*3600);

        // not encrypted
        s = client.echo(s0);

        // encrypted
        client.getClientStub().requestTransportFilters( RCF::FilterPtr(
            new RCF::SspiNtlmFilter()));

        s = _T("");
        s = client.echo(s0);
        BOOST_CHECK(s == s0);

        s = _T("");
        s = client.echo(s0);
        BOOST_CHECK(s == s0);

        s = client.getUserName();
        BOOST_CHECK(s == RCF::getMyUserName());
    }

    for (unsigned int i=0; i<RCF::getTransportFactories().size(); ++i)
    {

        RCF::TransportFactoryPtr transportFactoryPtr = RCF::getTransportFactories()[i];
        RCF::TransportPair transportPair = transportFactoryPtr->createTransports();
        RCF::ServerTransportPtr serverTransportPtr( transportPair.first );
        RCF::ClientTransportAutoPtr clientTransportAutoPtr( *transportPair.second );

        if (transportFactoryPtr->isConnectionOriented())
        {

            RCF::writeTransportTypes(std::cout, *serverTransportPtr, *clientTransportAutoPtr);

            serverTransportPtr->setMaxMessageLength(1000*10);
            clientTransportAutoPtr->setMaxMessageLength(1000*10);

            tstring s0 = _T("something special");

            Echo echo;

            for (int k=0; k<4; ++k)
            {
                RCF::FilterServicePtr filterServicePtr(new RCF::FilterService);
                std::vector<CreateFilterInfo> factoriesOk;
                std::vector<CreateFilterInfo> factoriesNotOk;
                setupTest(
                    k,
                    filterServicePtr,
                    factoriesOk,
                    factoriesNotOk);

                RCF::RcfServer server( serverTransportPtr );
                server.bind( (I_Echo*) 0, echo);
                server.addService( RCF::ServicePtr(filterServicePtr) );
                server.start();

                RcfClient<I_Echo> client( clientTransportAutoPtr->clone() );
                client.getClientStub().setRemoteCallTimeoutMs(1000*clClientTimeout);

                // no encryption or authentication
                tstring s = client.echo(s0);
                BOOST_CHECK(s0 == s);
                BOOST_CHECK(icmp(client.getUserName(), usernameOrig));

                std::cout << "Expecting to fail:" << std::endl;

                // client authentications that are supposed to fail
                for (unsigned int j=0; j<factoriesNotOk.size(); ++j)
                {
                    CreateFilter createFilter = factoriesNotOk[j].mCreateFilter;
                    tstring username = factoriesNotOk[j].mUsername;
                    std::string desc = factoriesNotOk[j].mDesc;
                    std::cout << "Testing: " << desc << std::endl;

                    // no filter
                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), usernameOrig));

                    // sspi filter
                    try
                    {
                        client.getClientStub().requestTransportFilters(
                            createFilter(RCF::SspiFilterBase::None));

                        client.echo(s0);
                        BOOST_CHECK(1==0);
                    }
                    catch(const RCF::Exception &e)
                    {
                        BOOST_CHECK(1==1);
                    }

                    // no filter
                    client.getClientStub().clearTransportFilters();
                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    // sspi filter
                    try
                    {
                        client.getClientStub().requestTransportFilters(
                            createFilter(RCF::SspiFilterBase::None));

                        client.echo(s0);
                        BOOST_CHECK(1==0);
                    }
                    catch(const RCF::Exception &e)
                    {
                        BOOST_CHECK(1==1);
                        client.getClientStub().clearTransportFilters();
                    }
                }

                std::cout << "Expecting to pass:" << std::endl;

                // client authentications that are supposed to succeed
                for (std::size_t j=0; j<factoriesOk.size(); ++j)
                {
                    CreateFilter createFilter = factoriesOk[j].mCreateFilter;
                    tstring username = factoriesOk[j].mUsername;
                    std::string desc = factoriesOk[j].mDesc;
                    std::cout << "Testing: " << desc << std::endl;

                    // sspi filter - no encryption or integrity
                    client.getClientStub().requestTransportFilters(
                        createFilter(RCF::SspiFilterBase::None));

                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    // sspi filter - encrypted
                    client.getClientStub().requestTransportFilters(
                        createFilter(RCF::SspiFilterBase::Encryption));

                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    // test reconnection
                    server.close();
                    server.start();

                    // sspi filter - still encrypted
                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    // sspi filter - integrity
                    client.getClientStub().requestTransportFilters(
                        createFilter(RCF::SspiFilterBase::Integrity));

                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    // no filters
                    client.getClientStub().clearTransportFilters();
                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), usernameOrig));

                    // sspi filter - encrypted
                    client.getClientStub().requestTransportFilters(
                        createFilter(RCF::SspiFilterBase::Encryption));

                    BOOST_CHECK(client.echo(s0) == s0);
                    BOOST_CHECK(icmp(client.getUserName(), username));

                    {
                        // try parallel sspi filtered connections
                        typedef boost::shared_ptr<RcfClient<I_Echo> > ClientPtr;
                        std::vector<ClientPtr> clients;
                        for (int j=0; j<100; ++j)
                        {
                            clients.push_back( ClientPtr(
                                new RcfClient<I_Echo>(clientTransportAutoPtr->clone())));
                        }

                        for (int j=0; j<100; ++j)
                        {
                            BOOST_CHECK( icmp(clients[i]->getUserName(), usernameOrig));
                            BOOST_CHECK( clients[i]->echo(s0) == s0 );

                            clients[i]->getClientStub().requestTransportFilters(
                                createFilter(RCF::SspiFilterBase::Encryption));

                            BOOST_CHECK( icmp(clients[i]->getUserName(), username));
                            BOOST_CHECK( clients[i]->echo(s0) == s0 );

                            clients[i]->getClientStub().clearTransportFilters();

                            BOOST_CHECK( icmp(clients[i]->getUserName(), usernameOrig));
                            BOOST_CHECK( clients[i]->echo(s0) == s0 );
                        }
                    }

#ifdef RCF_USE_ZLIB

                    // test sspi together with zlib filter
                    // TODO: factor this out and use to test all filters

                    filterServicePtr->addFilterFactory(
                        RCF::FilterFactoryPtr(
                            new RCF::ZlibStatefulCompressionFilterFactory()));

                    filterServicePtr->addFilterFactory(
                        RCF::FilterFactoryPtr(
                            new RCF::ZlibStatelessCompressionFilterFactory()));

                    std::vector<RCF::FilterPtr> filters;

                    client.getClientStub().clearTransportFilters();
                    BOOST_CHECK( client.getUserName() == usernameOrig );
                    BOOST_CHECK( client.echo(s0) == s0 );

                    filters.clear();

                    filters.push_back(
                        RCF::FilterPtr(
                            new RCF::ZlibStatefulCompressionFilter()));

                    filters.push_back(
                        createFilter(RCF::SspiFilterBase::Encryption));

                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );

                    filters.clear();

                    filters.push_back(
                        createFilter(RCF::SspiFilterBase::Encryption));

                    filters.push_back(
                        RCF::FilterPtr(
                            new RCF::ZlibStatefulCompressionFilter()));
#ifndef __BORLANDC__
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );
#endif

                    filters.clear();

                    filters.push_back(
                        RCF::FilterPtr(
                            new RCF::ZlibStatefulCompressionFilter()));

                    filters.push_back(
                        createFilter(RCF::SspiFilterBase::Encryption));

                    filters.push_back(
                        RCF::FilterPtr(
                            new RCF::ZlibStatefulCompressionFilter()));
// TODO: tests with zlib filter after sspi filter fail on borland
#ifndef __BORLANDC__
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );
#endif
                    filters.clear();
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );

                    filters.clear();
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );
#ifndef __BORLANDC__
                    filters.clear();
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );

                    filters.clear();
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    filters.push_back( createFilter(RCF::SspiFilterBase::Encryption));
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), username));
                    BOOST_CHECK( client.echo(s0) == s0 );
#endif
                    filters.clear();
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), usernameOrig));
                    BOOST_CHECK( client.echo(s0) == s0 );

                    filters.clear();
                    filters.push_back( RCF::FilterPtr( new RCF::ZlibStatefulCompressionFilter()));
                    client.getClientStub().requestTransportFilters(filters);
                    BOOST_CHECK( icmp(client.getUserName(), usernameOrig));
                    BOOST_CHECK( client.echo(s0) == s0 );

                    // TODO: test with stateless compression filter as well
                    // ...

#endif // RCF_USE_ZLIB

                }
            }
        }
    }
    return boost::exit_success;
}






By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Australia Australia
Software developer, from Sweden and now living in Canberra, Australia, working on distributed C++ applications. When he is not programming, Jarl enjoys skiing and playing table tennis. He derives immense satisfaction from referring to himself in third person.

Comments and Discussions