reSIProcate/DialogUsageManager  9694
certServer.cxx
Go to the documentation of this file.
00001 #ifdef WIN32
00002 #  define usleep(t) Sleep(t)
00003 #endif
00004 
00005 #if defined (HAVE_POPT_H)
00006 #include <popt.h>
00007 #endif
00008 
00009 #include <signal.h>
00010 
00011 #include "resip/stack/NameAddr.hxx"
00012 #include "resip/stack/Pkcs8Contents.hxx"
00013 #include "resip/stack/SipMessage.hxx"
00014 #include "resip/stack/Symbols.hxx"
00015 #include "resip/stack/Uri.hxx"
00016 #include "resip/stack/X509Contents.hxx"
00017 #include "resip/dum/AppDialogSet.hxx"
00018 #include "resip/dum/ClientAuthManager.hxx"
00019 #include "resip/dum/DialogUsageManager.hxx"
00020 #include "resip/dum/DumShutdownHandler.hxx"
00021 #include "resip/dum/OutOfDialogHandler.hxx"
00022 #include "resip/dum/MasterProfile.hxx"
00023 #include "resip/dum/PublicationHandler.hxx"
00024 #include "resip/dum/RegistrationHandler.hxx"
00025 #include "resip/dum/ServerPublication.hxx"
00026 #include "resip/dum/ServerSubscription.hxx"
00027 #include "resip/dum/SubscriptionHandler.hxx"
00028 #include "rutil/Log.hxx"
00029 #include "rutil/Logger.hxx"
00030 #include "rutil/Random.hxx"
00031 #include "rutil/Subsystem.hxx"
00032 
00033 #define RESIPROCATE_SUBSYSTEM Subsystem::TEST
00034 
00035 using namespace std;
00036 using namespace resip;
00037 
00038 static bool finished=false;
00039 
00040 void
00041 signalHandler(int signo)
00042 {
00043    std::cerr << "Shutting down" << endl;
00044    finished = true;
00045 }
00046 
00047 // When a publish comes in, we should let any outstanding subscriptions know
00048 // about it. 
00049 
00050 class CertSubscriptionHandler;
00051 class PrivateKeySubscriptionHandler;
00052 
00053 class CertPublicationHandler : public ServerPublicationHandler
00054 {
00055    public:
00056       CertPublicationHandler(Security& security) : mSecurity(security)
00057       {
00058       }
00059 
00060       virtual void onInitial(ServerPublicationHandle h, 
00061                              const Data& etag, 
00062                              const SipMessage& pub, 
00063                              const Contents* contents,
00064                              const SecurityAttributes* attrs, 
00065                              int expires)
00066       {
00067          add(h, contents);
00068       }
00069 
00070       virtual void onExpired(ServerPublicationHandle h, const Data& etag)
00071       {
00072          mSecurity.removeUserCert(h->getPublisher());
00073       }
00074 
00075       virtual void onRefresh(ServerPublicationHandle, 
00076                              const Data& etag, 
00077                              const SipMessage& pub, 
00078                              const Contents* contents,
00079                              const SecurityAttributes* attrs,
00080                              int expires)
00081       {
00082       }
00083 
00084       virtual void onUpdate(ServerPublicationHandle h, 
00085                             const Data& etag, 
00086                             const SipMessage& pub, 
00087                             const Contents* contents,
00088                             const SecurityAttributes* attrs,
00089                             int expires)
00090       {
00091          add(h, contents);
00092       }
00093 
00094       virtual void onRemoved(ServerPublicationHandle h, const Data& etag, const SipMessage& pub, int expires)
00095       {
00096          mSecurity.removeUserCert(h->getPublisher());
00097       }
00098    private:
00099       void add(ServerPublicationHandle h, const Contents* contents)
00100       {
00101          if (h->getDocumentKey() == h->getPublisher())
00102          {
00103             const X509Contents* x509 = dynamic_cast<const X509Contents*>(contents);
00104             assert(x509);
00105             mSecurity.addUserCertDER(h->getPublisher(), x509->getBodyData());
00106             h->send(h->accept(200));
00107          }
00108          else
00109          {
00110             h->send(h->accept(403)); // !jf! is this the correct code? 
00111          }
00112       }
00113 
00114       Security& mSecurity;
00115 };
00116 
00117 class PrivateKeyPublicationHandler : public ServerPublicationHandler
00118 {
00119    public:
00120       PrivateKeyPublicationHandler(Security& security) : mSecurity(security)
00121       {
00122       }
00123 
00124       virtual void onInitial(ServerPublicationHandle h, 
00125                              const Data& etag, 
00126                              const SipMessage& pub, 
00127                              const Contents* contents,
00128                              const SecurityAttributes* attrs, 
00129                              int expires)
00130       {
00131          add(h, contents);
00132       }
00133 
00134       virtual void onExpired(ServerPublicationHandle h, const Data& etag)
00135       {
00136          mSecurity.removeUserPrivateKey(h->getPublisher());
00137       }
00138 
00139       virtual void onRefresh(ServerPublicationHandle, 
00140                              const Data& etag, 
00141                              const SipMessage& pub, 
00142                              const Contents* contents,
00143                              const SecurityAttributes* attrs,
00144                              int expires)
00145       {
00146       }
00147 
00148       virtual void onUpdate(ServerPublicationHandle h, 
00149                             const Data& etag, 
00150                             const SipMessage& pub, 
00151                             const Contents* contents,
00152                             const SecurityAttributes* attrs,
00153                             int expires)
00154       {
00155          add(h, contents);
00156       }
00157 
00158       virtual void onRemoved(ServerPublicationHandle h, const Data& etag, const SipMessage& pub, int expires)
00159       {
00160          mSecurity.removeUserPrivateKey(h->getPublisher());
00161       }
00162 
00163    private:
00164       void add(ServerPublicationHandle h, const Contents* contents)
00165       {
00166          if (h->getDocumentKey() == h->getPublisher())
00167          {
00168             const Pkcs8Contents* pkcs8 = dynamic_cast<const Pkcs8Contents*>(contents);
00169             assert(pkcs8);
00170             mSecurity.addUserPrivateKeyDER(h->getPublisher(), pkcs8->getBodyData());
00171          }
00172          else
00173          {
00174             h->send(h->accept(403)); // !jf! is this the correct code? 
00175          }
00176       }
00177       
00178       Security& mSecurity;
00179 };
00180 
00181 class CertSubscriptionHandler : public ServerSubscriptionHandler
00182 {
00183    public:
00184       CertSubscriptionHandler(Security& security) : mSecurity(security)
00185       {
00186       }
00187 
00188       virtual void onNewSubscription(ServerSubscriptionHandle h, const SipMessage& sub)
00189       {
00190          if (!mSecurity.hasUserCert(h->getDocumentKey()))
00191          {
00192             // !jf! really need to do this async. send neutral state in the meantime,
00193             // blah blah blah
00194             mSecurity.generateUserCert(h->getDocumentKey());
00195          }
00196 
00197          if (mSecurity.hasUserCert(h->getDocumentKey()))
00198          {
00199             X509Contents x509(mSecurity.getUserCertDER(h->getDocumentKey()));
00200             h->send(h->update(&x509));
00201          }
00202          else
00203          {
00204             h->reject(404);
00205          }
00206       }
00207 
00208       virtual void onPublished(ServerSubscriptionHandle associated, 
00209                                ServerPublicationHandle publication, 
00210                                const Contents* contents,
00211                                const SecurityAttributes* attrs)
00212       {
00213          associated->send(associated->update(contents));
00214       }
00215       
00216 
00217       virtual void onTerminated(ServerSubscriptionHandle)
00218       {
00219       }
00220 
00221       virtual void onError(ServerSubscriptionHandle, const SipMessage& msg)
00222       {
00223       }
00224 
00225    private:
00226       Security& mSecurity;
00227 };
00228 
00229 class PrivateKeySubscriptionHandler : public ServerSubscriptionHandler
00230 {
00231    public:
00232       PrivateKeySubscriptionHandler(Security& security) : mSecurity(security)
00233       {
00234       }
00235 
00236       virtual void onNewSubscription(ServerSubscriptionHandle h, const SipMessage& sub)
00237       {
00238          if (h->getDocumentKey() != h->getSubscriber())
00239          {
00240             h->send(h->accept(403)); // !jf! is this the correct code? 
00241          }
00242          else if (mSecurity.hasUserCert(h->getDocumentKey()))
00243          {
00244             Pkcs8Contents pkcs(mSecurity.getUserPrivateKeyDER(h->getDocumentKey()));
00245             h->send(h->update(&pkcs));
00246          }
00247          else
00248          {
00249             h->reject(404);
00250          }
00251       }
00252 
00253       virtual void onPublished(ServerSubscriptionHandle associated, 
00254                                ServerPublicationHandle publication, 
00255                                const Contents* contents,
00256                                const SecurityAttributes* attrs)
00257       {
00258          associated->send(associated->update(contents));
00259       }
00260 
00261       virtual void onTerminated(ServerSubscriptionHandle)
00262       {
00263       }
00264 
00265       virtual void onError(ServerSubscriptionHandle, const SipMessage& msg)
00266       {
00267       }
00268 
00269    private:
00270       Security& mSecurity;
00271 };
00272    
00273    
00274 
00275 class CertServer : public OutOfDialogHandler,  public DialogUsageManager
00276 {
00277    public:
00278       CertServer(const resip::NameAddr& me, SipStack& stack) : 
00279          DialogUsageManager(stack),
00280          mCertServer(*getSecurity()),
00281          mPrivateKeyServer(*getSecurity()),
00282          mCertUpdater(*getSecurity()),
00283          mPrivateKeyUpdater(*getSecurity()),
00284          mDone(false)
00285       {
00286          addTransport(UDP, 5100);
00287          addTransport(TCP, 5100);
00288          addTransport(TLS, 5101, V4, Data::Empty, me.uri().host(), Data::Empty);
00289          
00290          mProfile = new MasterProfile;
00291          mProfile->clearSupportedMethods();
00292          mProfile->addSupportedMethod(PUBLISH);
00293          mProfile->addSupportedMethod(SUBSCRIBE);
00294          mProfile->validateAcceptEnabled() = true;
00295          mProfile->validateContentEnabled() = true;
00296          mProfile->addSupportedMimeType(PUBLISH, Pkcs8Contents::getStaticType());
00297          mProfile->addSupportedMimeType(SUBSCRIBE, Pkcs8Contents::getStaticType());
00298          mProfile->addSupportedMimeType(PUBLISH, X509Contents::getStaticType());
00299          mProfile->addSupportedMimeType(SUBSCRIBE, X509Contents::getStaticType());
00300          
00301          mProfile.setDefaultFrom(me);
00302          setMasterProfile(mProfile);
00303 
00304          addServerSubscriptionHandler(Symbols::Credential, &mPrivateKeyServer);
00305          addServerSubscriptionHandler(Symbols::Certificate, &mCertServer);
00306          addServerPublicationHandler(Symbols::Credential, &mPrivateKeyUpdater);
00307          addServerPublicationHandler(Symbols::Certificate, &mCertUpdater);
00308          addOutOfDialogHandler(OPTIONS, this);
00309          
00310          //setServerAuthManager(std::auto_ptr<ServerAuthManager>(new ServerAuthManager(mProfile)));
00311 
00312          DialogUsageManager::run();
00313       }
00314 
00315       ~CertServer()
00316       {
00317       }
00318       
00319       void run()
00320       {
00321          while ( !mDone )
00322          {
00323             while (process());
00324             usleep(5);
00325 
00326             if (finished)
00327             {
00328                // graceful shutdown
00329                exit(0);
00330             }
00331          }
00332       }
00333 
00334       virtual void onSuccess(ClientOutOfDialogReqHandle, const SipMessage& successResponse)
00335       {
00336       }
00337       
00338       virtual void onFailure(ClientOutOfDialogReqHandle, const SipMessage& errorResponse)
00339       {
00340       }
00341 
00342       virtual void onReceivedRequest(ServerOutOfDialogReqHandle, const SipMessage& request)
00343       {
00344       }
00345 
00346    private:
00347       SharedPtr<MasterProfile> mProfile;
00348       CertSubscriptionHandler mCertServer;
00349       PrivateKeySubscriptionHandler mPrivateKeyServer;
00350       CertPublicationHandler mCertUpdater;
00351       PrivateKeyPublicationHandler mPrivateKeyUpdater;
00352       bool mDone;
00353 };
00354 
00355 int 
00356 main (int argc, char** argv)
00357 {
00358    char* logType = "COUT";
00359    char* logLevel = "DEBUG";
00360    char* myUrl = "sip:localhost:7001";
00361    char* bindAddr = 0;
00362    int v6 = 0;
00363 
00364 #if defined(HAVE_POPT_H)
00365    struct poptOption table[] = {
00366       {"log-type",    'l', POPT_ARG_STRING, &logType,   0, "where to send logging messages", "syslog|cerr|cout"},
00367       {"log-level",   'v', POPT_ARG_STRING, &logLevel,  0, "specify the default log level", "DEBUG|INFO|WARNING|ALERT"},
00368       {"name" ,       'n', POPT_ARG_STRING, &myUrl,     0, "my url", 0},
00369       {"bind",        'b', POPT_ARG_STRING, &bindAddr,  0, "interface address to bind to",0},
00370       {"v6",          '6', POPT_ARG_NONE,   &v6     ,   0, "ipv6", 0},
00371       POPT_AUTOHELP
00372       { NULL, 0, 0, NULL, 0 }
00373    };
00374    poptContext context = poptGetContext(NULL, argc, const_cast<const char**>(argv), table, 0);
00375    poptGetNextOpt(context);
00376 #endif
00377    Log::initialize(logType, logLevel, argv[0]);
00378 
00379 #ifndef _WIN32
00380    if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR)
00381    {
00382       cerr << "Couldn't install signal handler for SIGPIPE" << endl;
00383       exit(-1);
00384    }
00385 
00386    if ( signal( SIGINT, signalHandler ) == SIG_ERR )
00387    {
00388       cerr << "Couldn't install signal handler for SIGINT" << endl;
00389       exit( -1 );
00390    }
00391 
00392    if ( signal( SIGTERM, signalHandler ) == SIG_ERR )
00393    {
00394       cerr << "Couldn't install signal handler for SIGTERM" << endl;
00395       exit( -1 );
00396    }
00397 #endif
00398 
00399    NameAddr domain(myUrl);
00400    SipStack stack;
00401    CertServer server(domain, stack);
00402    server.run();
00403    return 0;
00404 }
00405 
00406 
00407 /* ====================================================================
00408  * The Vovida Software License, Version 1.0 
00409  * 
00410  * Copyright (c) 2000 Vovida Networks, Inc.  All rights reserved.
00411  * 
00412  * Redistribution and use in source and binary forms, with or without
00413  * modification, are permitted provided that the following conditions
00414  * are met:
00415  * 
00416  * 1. Redistributions of source code must retain the above copyright
00417  *    notice, this list of conditions and the following disclaimer.
00418  * 
00419  * 2. Redistributions in binary form must reproduce the above copyright
00420  *    notice, this list of conditions and the following disclaimer in
00421  *    the documentation and/or other materials provided with the
00422  *    distribution.
00423  * 
00424  * 3. The names "VOCAL", "Vovida Open Communication Application Library",
00425  *    and "Vovida Open Communication Application Library (VOCAL)" must
00426  *    not be used to endorse or promote products derived from this
00427  *    software without prior written permission. For written
00428  *    permission, please contact vocal@vovida.org.
00429  *
00430  * 4. Products derived from this software may not be called "VOCAL", nor
00431  *    may "VOCAL" appear in their name, without prior written
00432  *    permission of Vovida Networks, Inc.
00433  * 
00434  * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED
00435  * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
00436  * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND
00437  * NON-INFRINGEMENT ARE DISCLAIMED.  IN NO EVENT SHALL VOVIDA
00438  * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES
00439  * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL,
00440  * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO,
00441  * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR
00442  * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY
00443  * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
00444  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE
00445  * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH
00446  * DAMAGE.
00447  * 
00448  * ====================================================================
00449  * 
00450  * This software consists of voluntary contributions made by Vovida
00451  * Networks, Inc. and many individuals on behalf of Vovida Networks,
00452  * Inc.  For more information on Vovida Networks, Inc., please see
00453  * <http://www.vovida.org/>.
00454  *
00455  */