|
reSIProcate/DialogUsageManager
9694
|
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 */
1.7.5.1