|
reSIProcate/stack
9694
|
00001 #if defined(HAVE_CONFIG_H) 00002 #include "config.h" 00003 #endif 00004 00005 #include <cstring> 00006 #include <cassert> 00007 #include <stdio.h> 00008 #include <signal.h> 00009 //#define USE_CURSES 00010 00011 #ifdef USE_CURSES 00012 #include <ncurses.h> 00013 #else 00014 #include <iostream> 00015 #include <cstdio> 00016 00017 #ifdef WIN32 00018 #include <io.h> 00019 #else 00020 #include <unistd.h> 00021 #endif 00022 00023 typedef void WINDOW; 00024 // !ah! Really ought to check for ncurses and be a bit better behaved than this. 00025 #if !defined(TRUE) 00026 #define TRUE true 00027 #endif 00028 #if !defined(FALSE) 00029 #define FALSE false 00030 #endif 00031 00032 char ACS_HLINE=1; 00033 char ACS_VLINE=2; 00034 WINDOW* stdscr=0; 00035 WINDOW* newwin(...) { return NULL; }; 00036 void waddstr(WINDOW*, const char* text) { std::clog << text; }; 00037 char getch() 00038 { 00039 char buf[1]; 00040 int r = read(fileno(stdin),&buf,1); 00041 if ( r ==1 ) 00042 { 00043 return buf[0]; 00044 } 00045 return 0; 00046 }; 00047 00048 void werase(WINDOW*) {}; 00049 void wrefresh(...) {}; 00050 void mvhline(...) {}; 00051 void refresh(...) {}; 00052 void getmaxyx(...) {}; 00053 void clearok(...) {}; 00054 void waddch(...) {}; 00055 void initscr(...) {}; 00056 void cbreak(...) {}; 00057 void noecho(...) {}; 00058 void nonl(...) {}; 00059 void intrflush(...) {}; 00060 void keypad(...) {}; 00061 void scrollok(...) {}; 00062 void wmove(...) {}; 00063 void mvvline(...) {}; 00064 #endif 00065 00066 00067 00068 #ifndef WIN32 00069 #include <sys/time.h> 00070 #include <sys/types.h> 00071 #include <unistd.h> 00072 #include <stdlib.h> 00073 #endif 00074 00075 #include "rutil/FdPoll.hxx" 00076 #include "rutil/Socket.hxx" 00077 #include "rutil/Logger.hxx" 00078 #include "resip/stack/SipStack.hxx" 00079 #include "resip/stack/Uri.hxx" 00080 #include "resip/stack/TuIM.hxx" 00081 00082 #ifdef USE_SSL 00083 #include "resip/stack/ssl/Security.hxx" 00084 #endif 00085 00086 static int myMain(int argc, char* argv[]); 00087 00088 using namespace resip; 00089 using namespace std; 00090 00091 #define RESIPROCATE_SUBSYSTEM Subsystem::SIP 00092 00093 static WINDOW* commandWin=0; 00094 static WINDOW* textWin=0; 00095 static WINDOW* statusWin=0; 00096 00097 static TuIM* tuIM; 00098 static Uri dest; 00099 00100 void 00101 displayPres() 00102 { 00103 werase(statusWin); 00104 00105 for( int i=0; i<tuIM->getNumBuddies();i++) 00106 { 00107 Uri uri = tuIM->getBuddyUri(i); 00108 Data status; 00109 bool online = tuIM->getBuddyStatus(i,&status); 00110 const char* stat = (online)?"online":"offline"; 00111 00112 waddstr(statusWin,uri.getAor().c_str()); 00113 waddstr(statusWin," "); 00114 waddstr(statusWin,stat); 00115 waddstr(statusWin," "); 00116 waddstr(statusWin,status.c_str()); 00117 waddstr(statusWin,"\n"); 00118 } 00119 00120 wrefresh(statusWin); 00121 } 00122 00123 bool 00124 processStdin( Uri* dest, bool sign, bool encryp ) 00125 { 00126 static unsigned int num=0; 00127 static char buf[1024]; 00128 00129 char c = getch(); 00130 00131 if ( c == 0 ) 00132 { 00133 return true; 00134 } 00135 00136 if ( c == '\f' ) 00137 { 00138 clearok(textWin,TRUE); 00139 clearok(statusWin,TRUE); 00140 clearok(commandWin,TRUE); 00141 00142 assert( num < sizeof(buf) ); 00143 buf[num] = 0; 00144 werase(commandWin); 00145 waddstr(commandWin,buf); 00146 00147 wrefresh(textWin); 00148 wrefresh(statusWin); 00149 wrefresh(commandWin); 00150 00151 return true; 00152 } 00153 00154 #if 0 00155 char junk[6]; 00156 junk[0]=' '; 00157 junk[1]='0'+(c/100); 00158 junk[2]='0'+((c/10)%10); 00159 junk[3]='0'+(c%10); 00160 junk[4]=' '; 00161 junk[5]=0; 00162 waddstr(commandWin,junk); 00163 #endif 00164 00165 if ( (c == '\a') || (c == '\b') || (c == 4 ) || (c == 0x7F) ) 00166 { 00167 if ( num > 0 ) 00168 { 00169 num--; 00170 } 00171 buf[num]=0; 00172 00173 werase(commandWin); 00174 waddstr(commandWin,buf); 00175 wrefresh(commandWin); 00176 00177 return true; 00178 } 00179 00180 if ( (c == '\r') || (c == '\n') || (num+2>=sizeof(buf)) ) 00181 { 00182 buf[num] =0; 00183 00184 if ( (num>3) && (!strncmp("to:",buf,3)) ) 00185 { 00186 buf[num] = 0; 00187 *dest = Uri(Data(buf+3)); 00188 00189 //cerr << "Set destination to <" << *dest << ">"; 00190 waddstr(textWin,"Set destination to "); 00191 waddstr(textWin, Data::from(*dest).c_str()); 00192 waddstr(textWin,"\n"); 00193 wrefresh(textWin); 00194 } 00195 else if ( (num>4) && (!strncmp("add:",buf,4)) ) 00196 { 00197 buf[num] = 0; 00198 Uri uri(Data(buf+4)); 00199 00200 //cerr << "Subscribing to buddy <" << uri << ">"; 00201 waddstr(textWin, "Subscribing to "); 00202 waddstr(textWin, Data::from(uri).c_str()); 00203 waddstr(textWin, "\n"); 00204 wrefresh(textWin); 00205 00206 tuIM->addBuddy( uri, Data::Empty ); 00207 displayPres(); 00208 } 00209 else if ( (num>=7) && (!strncmp("status:",buf,7)) ) 00210 { 00211 buf[num] = 0; 00212 Data stat(buf+7); 00213 00214 //cerr << "setting presence status to <" << stat << ">"; 00215 waddstr(textWin,"Set presece status to <"); 00216 waddstr(textWin,stat.c_str()); 00217 waddstr(textWin,">\n"); 00218 wrefresh(textWin); 00219 00220 tuIM->setMyPresence( !stat.empty(), stat ); 00221 } 00222 else if ( (num==1) && (!strncmp(".",buf,1)) ) 00223 { 00224 //DebugLog( << "Got a period - end program" ); 00225 return false; 00226 } 00227 else 00228 { 00229 if ( num >= 1 ) 00230 { 00231 assert( num < sizeof(buf) ); 00232 buf[num] = 0; 00233 Data text(buf); 00234 00235 Data destValue = dest->getAor(); 00236 00237 DebugLog( << "Destination is " << destValue ); 00238 00239 Data encFor = Data::Empty; 00240 if (encryp) 00241 { 00242 encFor = dest->getAorNoPort(); 00243 } 00244 00245 DebugLog( << "Destination encrypt for is " << encFor ); 00246 00247 if ( tuIM->haveCerts(sign,encFor) ) 00248 { 00249 waddstr(textWin,"To: "); 00250 waddstr(textWin,destValue.c_str()); 00251 waddstr(textWin," "); 00252 waddstr(textWin,text.c_str()); 00253 waddstr(textWin,"\n"); 00254 wrefresh(textWin); 00255 00256 tuIM->sendPage( text , *dest, sign , encFor ); 00257 } 00258 else 00259 { 00260 waddstr(textWin,"Don't have aproperate certificates to sign and encrypt a message to "); 00261 waddstr(textWin,destValue.c_str()); 00262 waddstr(textWin,"\n"); 00263 wrefresh(textWin); 00264 } 00265 } 00266 } 00267 00268 num = 0; 00269 00270 werase(commandWin); 00271 wrefresh(commandWin); 00272 } 00273 else 00274 { 00275 buf[num++] = c; 00276 assert( num < sizeof(buf) ); 00277 00278 waddch(commandWin,c); 00279 wrefresh(commandWin); 00280 } 00281 00282 return true; 00283 } 00284 00285 class StdInWatcher : public resip::FdPollItemIf 00286 { 00287 public: 00288 StdInWatcher(Uri* dest, bool sign, bool encrypt) : 00289 mDest(dest), 00290 mSign(sign), 00291 mEncrypt(encrypt), 00292 mKeepGoing(true) 00293 {} 00294 00295 virtual ~StdInWatcher(){} 00296 00297 virtual void processPollEvent(FdPollEventMask mask) 00298 { 00299 mKeepGoing=processStdin(mDest, mSign, mEncrypt); 00300 } 00301 00302 inline bool keepGoing() const {return mKeepGoing;} 00303 00304 private: 00305 Uri* mDest; 00306 bool mSign; 00307 bool mEncrypt; 00308 bool mKeepGoing; 00309 00310 }; // class StdInWatcher 00311 00312 00313 class TestCallback: public TuIM::Callback 00314 { 00315 public: 00316 virtual void presenceUpdate(const Uri& dest, bool open, const Data& status ); 00317 virtual void receivedPage( const Data& msg, const Uri& from , 00318 const Data& signedBy, SignatureStatus sigStatus, 00319 bool wasEncryped ); 00320 virtual void sendPageFailed( const Uri& dest,int respNumber ); 00321 virtual void registrationFailed(const resip::Uri&, int respNumber); 00322 virtual void registrationWorked(const Uri& dest ); 00323 virtual void receivePageFailed(const Uri& sender); 00324 }; 00325 00326 00327 void 00328 TestCallback::presenceUpdate(const Uri& from, bool open, const Data& status ) 00329 { 00330 const char* stat = (open)?"online":"offline"; 00331 //cout << from << " set presence to " << stat << " " << status.c_str() << endl; 00332 00333 waddstr(textWin,"Status: "); 00334 waddstr(textWin, from.getAor().c_str()); 00335 waddstr(textWin," is "); 00336 waddstr(textWin,stat); 00337 waddstr(textWin," "); 00338 waddstr(textWin,status.c_str()); 00339 waddstr(textWin,"\n"); 00340 00341 wrefresh(textWin); 00342 00343 displayPres(); 00344 } 00345 00346 void 00347 TestCallback::receivedPage( const Data& msg, const Uri& from, 00348 const Data& signedBy, SignatureStatus sigStatus, 00349 bool wasEncryped ) 00350 { 00351 //DebugLog(<< "In TestPageCallback"); 00352 00353 if ( dest != from ) 00354 { 00355 dest = from; 00356 //cerr << "Set destination to <" << *mDest << ">" << endl; 00357 waddstr(textWin,"Set destination to "); 00358 waddstr(textWin, Data::from(dest).c_str()); 00359 waddstr(textWin,"\n"); 00360 } 00361 00362 //cout << from; 00363 00364 waddstr(textWin,"From: "); 00365 waddstr(textWin,from.getAor().c_str()); 00366 00367 if ( !wasEncryped ) 00368 { 00369 //cout << " -NOT SECURE- "; 00370 waddstr(textWin," -NOT SECURE-"); 00371 } 00372 else 00373 { 00374 waddstr(textWin," -secure-"); 00375 } 00376 switch ( sigStatus ) 00377 { 00378 case SignatureSelfSigned: 00379 //cout << " -self signed signature (bad)- "; 00380 waddstr(textWin,"bad signature"); 00381 break; 00382 case SignatureIsBad: 00383 //cout << " -bad signature- "; 00384 waddstr(textWin,"bad signature"); 00385 break; 00386 case SignatureNone: 00387 //cout << " -no signature- "; 00388 waddstr(textWin,"no signature"); 00389 break; 00390 case SignatureTrusted: 00391 //cout << " <signed " << signedBy << " > "; 00392 waddstr(textWin,"signed "); 00393 waddstr(textWin,signedBy.c_str()); 00394 break; 00395 case SignatureCATrusted: 00396 //cout << " <ca signed " << signedBy << " > "; 00397 waddstr(textWin,"ca signed " ); 00398 waddstr(textWin,signedBy.c_str()); 00399 break; 00400 case SignatureNotTrusted: 00401 //cout << " <signed " << signedBy << " NOT TRUSTED > "; 00402 waddstr(textWin,"untrusted signature "); 00403 waddstr(textWin,signedBy.c_str()); 00404 break; 00405 } 00406 00407 //cout << " says:" << endl; 00408 //cout << msg.escaped() << endl; 00409 waddstr(textWin, " says: "); 00410 waddstr(textWin, msg.escaped().c_str() ); 00411 waddstr(textWin, "\n"); 00412 00413 wrefresh(textWin); 00414 } 00415 00416 00417 void 00418 TestCallback::sendPageFailed( const Uri& target, int respNum ) 00419 { 00420 //InfoLog(<< "In TestErrCallback"); 00421 // cerr << "Message to " << dest << " failed" << endl; 00422 Data num(respNum); 00423 00424 waddstr(textWin,"Message to "); 00425 waddstr(textWin, Data::from(target).c_str()); 00426 waddstr(textWin," failed ("); 00427 waddstr(textWin,num.c_str()); 00428 waddstr(textWin," response)\n"); 00429 wrefresh(textWin); 00430 } 00431 00432 00433 void 00434 TestCallback::receivePageFailed( const Uri& target ) 00435 { 00436 //InfoLog(<< "In TestErrCallback"); 00437 // cerr << "Message to " << dest << " failed" << endl; 00438 00439 waddstr(textWin,"Can not understand messager from "); 00440 waddstr(textWin, Data::from(target).c_str()); 00441 waddstr(textWin,"\n"); 00442 wrefresh(textWin); 00443 } 00444 00445 00446 void 00447 TestCallback::registrationFailed(const resip::Uri& target, int respNum ) 00448 { 00449 Data num(respNum); 00450 00451 waddstr(textWin,"Registration to "); 00452 waddstr(textWin, Data::from(target).c_str()); 00453 waddstr(textWin," failed ("); 00454 waddstr(textWin,num.c_str()); 00455 waddstr(textWin," response)\n"); 00456 wrefresh(textWin); 00457 } 00458 00459 00460 void 00461 TestCallback::registrationWorked(const resip::Uri& target) 00462 { 00463 waddstr(textWin,"Registration to "); 00464 waddstr(textWin, Data::from(target).c_str()); 00465 waddstr(textWin," worked"); 00466 wrefresh(textWin); 00467 } 00468 00469 00470 int 00471 main(int argc, char* argv[]) 00472 { 00473 #ifndef _WIN32 00474 if ( signal( SIGPIPE, SIG_IGN) == SIG_ERR) 00475 { 00476 cerr << "Couldn't install signal handler for SIGPIPE" << endl; 00477 exit(-1); 00478 } 00479 #endif 00480 00481 int r; 00482 00483 try 00484 { 00485 r = myMain( argc, argv ); 00486 } 00487 catch( ... ) 00488 { 00489 ErrLog( << "Got a exception passed all the way to the top of limp" ); 00490 exit(-1); 00491 } 00492 00493 return r; 00494 } 00495 00496 00497 static int 00498 myMain(int argc, char* argv[]) 00499 { 00500 Log::initialize(Log::Cerr, Log::Err, argv[0]); 00501 Log::setLevel(Log::Warning); 00502 00503 InfoLog(<<"Test Driver for IM Starting"); 00504 00505 int port = 5060; 00506 int tlsPort = 0; 00507 int dtlsPort = 0; 00508 Uri aor; 00509 bool haveAor=false; 00510 dest = Uri("sip:nobody@example.com"); 00511 Data aorPassword; 00512 Uri contact("sip:user@"); 00513 bool haveContact=false; 00514 Uri outbound; 00515 bool noRegister = false; 00516 Data tlsDomain = Data::Empty; 00517 00518 Data sendMsg = Data::Empty; 00519 00520 int numAdd=0; 00521 Data addList[100]; 00522 int numPub=0; 00523 Data pubList[100]; 00524 bool encryp=false; 00525 bool sign=false; 00526 Data key("password"); 00527 bool useTls = true; 00528 bool noTls = false; 00529 bool noTcp = false; 00530 bool prefUdp = false; 00531 bool prefTls = false; 00532 bool prefDtls = false; 00533 bool prefTcp = false; 00534 bool noUdp = false; 00535 bool noV6 = false; 00536 bool noV4 = false; 00537 bool genUserCert = false; 00538 00539 for ( int i=1; i<argc; i++) 00540 { 00541 if (!strcmp(argv[i],"-vv")) 00542 { 00543 Log::setLevel(Log::Stack); 00544 } 00545 else if (!strcmp(argv[i],"-v")) 00546 { 00547 Log::setLevel(Log::Info); 00548 } 00549 else if (!strcmp(argv[i],"-encrypt")) 00550 { 00551 encryp = true; 00552 } 00553 else if (!strcmp(argv[i],"-genUserCert")) 00554 { 00555 genUserCert = true; 00556 } 00557 else if (!strcmp(argv[i],"-noRegister")) 00558 { 00559 noRegister = true; 00560 } 00561 else if (!strcmp(argv[i],"-sign")) 00562 { 00563 sign = true; 00564 } 00565 else if (!strcmp(argv[i],"-tlsDomain")) 00566 { 00567 i++; 00568 assert( i<argc ); 00569 tlsDomain = Data(argv[i]); 00570 } 00571 else if (!strcmp(argv[i],"-ssl")) 00572 { 00573 useTls = false; 00574 } 00575 else if (!strcmp(argv[i],"-noTcp")) 00576 { 00577 noTcp = true; 00578 } 00579 else if (!strcmp(argv[i],"-noTls")) 00580 { 00581 noTls = true; 00582 } 00583 else if (!strcmp(argv[i],"-noUdp")) 00584 { 00585 noUdp = true; 00586 } 00587 else if (!strcmp(argv[i],"-prefTcp")) 00588 { 00589 prefTcp = true; 00590 } 00591 else if (!strcmp(argv[i],"-prefTls")) 00592 { 00593 prefTls = true; 00594 } 00595 else if (!strcmp(argv[i],"-prefUdp")) 00596 { 00597 prefUdp = true; 00598 } 00599 else if (!strcmp(argv[i],"-noV6")) 00600 { 00601 noV6 = true; 00602 } 00603 else if (!strcmp(argv[i],"-noV4")) 00604 { 00605 noV4 = true; 00606 } 00607 else if (!strcmp(argv[i],"-port")) 00608 { 00609 i++; 00610 assert( i<argc ); 00611 port = atoi( argv[i] ); 00612 } 00613 else if (!strcmp(argv[i],"-tlsPort")) 00614 { 00615 i++; 00616 assert( i<argc ); 00617 tlsPort = atoi( argv[i] ); 00618 } 00619 else if (!strcmp(argv[i],"-dtlsPort")) 00620 { 00621 i++; 00622 assert( i<argc ); 00623 dtlsPort = atoi( argv[i] ); 00624 } 00625 else if (!strcmp(argv[i],"-aor")) 00626 { 00627 i++; 00628 assert( i<argc ); 00629 try 00630 { 00631 aor = Uri(Data(argv[i])); 00632 } 00633 catch (...) 00634 { 00635 ErrLog( <<"AOR URI is not valid - must start with sip: "); 00636 exit(-1); 00637 } 00638 haveAor=true; 00639 } 00640 else if (!strcmp(argv[i],"-outbound")) 00641 { 00642 i++; 00643 assert( i<argc ); 00644 try 00645 { 00646 outbound = Uri(Data(argv[i])); 00647 } 00648 catch (...) 00649 { 00650 ErrLog( <<"Outbound URI is not valid - must start with sip: "); 00651 exit(-1); 00652 } 00653 } 00654 else if (!strcmp(argv[i],"-send")) 00655 { 00656 i++; 00657 assert( i<argc ); 00658 sendMsg = Data(argv[i]); 00659 } 00660 else if (!strcmp(argv[i],"-contact")) 00661 { 00662 i++; 00663 assert( i<argc ); 00664 try 00665 { 00666 contact = Uri(Data(argv[i])); 00667 } 00668 catch (...) 00669 { 00670 ErrLog( <<"Contact URI is not valid - must start with sip: "); 00671 exit(-1); 00672 } 00673 haveContact=true; 00674 } 00675 else if (!strcmp(argv[i],"-add")) 00676 { 00677 i++; 00678 assert( i<argc ); 00679 addList[numAdd++] = Data(argv[i]); 00680 assert( numAdd < 100 ); 00681 try 00682 { 00683 // CJ TODO FIX 00684 //Uri uri( Data(argv[i]) ); 00685 } 00686 catch (...) 00687 { 00688 ErrLog( <<"URI in -add is not valid - must start with sip: "); 00689 exit(-1); 00690 } 00691 } 00692 else if (!strcmp(argv[i],"-pub")) 00693 { 00694 i++; 00695 assert( i<argc ); 00696 pubList[numPub++] = Data(argv[i]); 00697 assert( numPub < 100 ); 00698 try 00699 { 00700 // CJ TODO FIX 00701 //Uri uri(Data(argv[i])); 00702 } 00703 catch (...) 00704 { 00705 ErrLog( <<"Pub URI is not valid - must start with sip: "); 00706 exit(-1); 00707 } 00708 } 00709 else if (!strcmp(argv[i],"-aorPassword")) 00710 { 00711 i++; 00712 assert( i<argc ); 00713 aorPassword = Data(argv[i]); 00714 } 00715 else if (!strcmp(argv[i],"-to")) 00716 { 00717 i++; 00718 assert( i<argc ); 00719 try 00720 { 00721 dest = Uri(Data(argv[i])); 00722 } 00723 catch (...) 00724 { 00725 ErrLog( <<"To URI is not valid - must start with sip: "); 00726 exit(-1); 00727 } 00728 } 00729 else if (!strcmp(argv[i],"-key")) 00730 { 00731 i++; 00732 assert( i<argc ); 00733 key = Data(argv[i]); 00734 } 00735 else 00736 { 00737 clog <<"Bad command line opion: " << argv[i] << endl; 00738 clog <<"options are: " << endl 00739 << "\t [-v] [-vv] [-tls] [-port 5060] [-tlsport 5061]" << endl 00740 << "\t [-aor sip:alice@example.com] [-aorPassword password]" << endl 00741 << "\t [-to sip:friend@example.com] [-add sip:buddy@example.com]" << endl 00742 << "\t [-sign] [-encrypt] [-key secret]" << endl 00743 << "\t [-contact sip:me@example.com] " << endl 00744 << "\t [-outbound \"sip:example.com;lr\"] " << endl 00745 << "\t [-noRegister] " << endl 00746 << "\t [-pub sip:foo.com] " << endl 00747 << "\t [-tlsDomain foo.com] " << endl 00748 << "\t [-send myMessage] " << endl; 00749 clog << endl 00750 << " -v is verbose" << endl 00751 << " -vv is very verbose" << endl 00752 << " -noV6 don't use IPv6" << endl 00753 << " -noV4 don't use IPv4" << endl 00754 << " -noUdp don't use UDP" << endl 00755 << " -noTcp don't use TCP" << endl 00756 << " -noTls don't use TLS" << endl 00757 << " -prefUdp prefer UDP" << endl 00758 << " -prefTcp prefer TCP" << endl 00759 << " -prefTls prefer TLS" << endl 00760 << " -port sets the UDP and TCP port to listen on" << endl 00761 << " -tlsPort sets the port to listen for TLS on" << endl 00762 << " -tlsDomain domainName - sets tls and dtls to act as tls server instead of client" << endl 00763 << " -ssl - use ssl instead of tls" << endl 00764 << " -aor sets the proxy and user name to register with" << endl 00765 << " -aorPassword sets the password to use for registration" << endl 00766 << " -noRegister causes it not to register - by default the AOR is registered" << endl 00767 << " -to sets initial location to send messages to" << endl 00768 << " -outbound sets the outbound proxy" << endl 00769 << " -add adds a budy who's presence will be monitored" << endl 00770 << " -pub adds a State Agent to send publishes too" << endl 00771 << " -sign signs message you send and -encryp encrypt them " << endl 00772 << " -send takes a string (needs to be quoted if it has spaces) " 00773 << "and sends it as an IM " << endl 00774 << "\t(You need PKI certs for this to work)" << endl 00775 << " -key allows you to enter a secret used to load your private key."<< endl 00776 << " If you set the secret to - the system will querry you for it."<< endl 00777 << " -contact overrides your SIP contact - can be used for NAT games" << endl 00778 << "\t there can be many -add " << endl 00779 << " -genUserCert - generate a new user cert" << endl 00780 << " " << endl 00781 << "Examples" << endl 00782 << "An example command line for a user with account name alice at example.com is:" << endl 00783 << "\t" << argv[0] << " -aor \"alice@example.com\" -aorPassword \"secret\"" << endl 00784 << "to watch the presence of bob and charlie add" << endl 00785 << "\t-add \"sip:bob@bilboxi.com\" -add \"charlie@example.com\" " << endl 00786 << "If Alice was behind a NAT that had a public address of 1.2.3.4 and had forwarded" << endl 00787 << "port 5070 on this NAT to the machine Alice was using, then the following " << endl 00788 << "options would be added" << endl 00789 << "\t-contact \"sip:alice@1.2.3.4:5070\" -port 5070" << endl 00790 << "" << endl 00791 << endl; 00792 exit(1); 00793 } 00794 } 00795 00796 //InfoLog( << "Using port " << port ); 00797 00798 #ifdef USE_SSL 00799 InfoLog( << "Setting up Security" ); 00800 Security* security=NULL; 00801 try 00802 { 00803 char cert_dir[ 1024 ] ; 00804 char *home_dir = getenv( "HOME" ) ; 00805 00806 cert_dir[ 0 ] = '\0' ; 00807 ::strcat( cert_dir, home_dir ) ; 00808 ::strcat( cert_dir, "/.sipCerts/" ) ; 00809 00810 security = new Security( cert_dir ) ; 00811 00812 // ::free( home_dir ) ; // CJ TODO mem leak 00813 } 00814 catch( ... ) 00815 { 00816 security = NULL; 00817 ErrLog( << "Got a exception setting up Security" ); 00818 } 00819 00820 SipStack sipStack( security ); 00821 #else 00822 SipStack sipStack( false /*multihtread*/ ); 00823 #endif 00824 00825 if ( key == Data("-") ) 00826 { 00827 clog << "Please enter password to use to load your private key: "; 00828 char buf[1024]; 00829 cin.get(buf,1024); 00830 key = Data(buf); 00831 InfoLog( << "Certificate key set to <" << key << ">" ); 00832 } 00833 00834 #ifdef USE_SSL 00835 try 00836 { 00837 Security* security = sipStack.getSecurity(); 00838 assert(security != 0); 00839 } 00840 catch( ... ) 00841 { 00842 ErrLog( << "Got an exception creating security object " ); 00843 } 00844 00845 try 00846 { 00847 assert(security != 0); 00848 security->preload(); 00849 } 00850 catch( ... ) 00851 { 00852 ErrLog( << "Got a exception pre loading certificates" ); 00853 } 00854 00855 00856 if (genUserCert) 00857 { 00858 assert( security ); 00859 security->generateUserCert(aor.getAor()); 00860 } 00861 #endif 00862 00863 DebugLog( << "About to add the transports " ); 00864 if (port!=0) 00865 { 00866 if ( noUdp != true ) 00867 { 00868 if (!noV4) sipStack.addTransport(UDP, port, V4); 00869 #ifdef USE_IPV6 00870 if (!noV6) sipStack.addTransport(UDP, port, V6); 00871 #endif 00872 } 00873 if ( noTcp != true ) 00874 { 00875 if (!noV4) sipStack.addTransport(TCP, port, V4); 00876 #ifdef USE_IPV6 00877 if (!noV6) sipStack.addTransport(TCP, port, V6); 00878 #endif 00879 } 00880 } 00881 #ifdef USE_SSL 00882 if ( tlsPort != 0 ) 00883 { 00884 if ( noTls != true ) 00885 { 00886 if (!noV4) 00887 { 00888 sipStack.addTransport(TLS, tlsPort, V4, StunDisabled, Data::Empty, tlsDomain ); 00889 } 00890 //if (!noV6) sipStack.addTlsTransport(tlsPort,Data::Empty,Data::Empty,Data::Empty,V6); 00891 } 00892 } 00893 #ifdef USE_DTLS 00894 if ( dtlsPort != 0 ) 00895 { 00896 if ( noTls != true ) 00897 { 00898 if (!noV4) 00899 { 00900 sipStack.addTransport(DTLS, dtlsPort, V4, StunDisabled, Data::Empty, tlsDomain ); 00901 } 00902 } 00903 } 00904 #endif 00905 #endif 00906 00907 DebugLog( << "Done adding the transports " ); 00908 00909 if (!haveContact) 00910 { 00911 // contact.port() = port; 00912 // contact.host() = sipStack.getHostname(); 00913 } 00914 00915 if ( haveAor ) 00916 { 00917 if (!haveContact) 00918 { 00919 contact.user() = aor.user(); 00920 #ifdef USE_SSL 00921 if ( aor.scheme() == "sips" ) 00922 { 00923 contact.scheme() = aor.scheme(); 00924 //contact.port() = tlsPort; 00925 } 00926 #endif 00927 } 00928 } 00929 else 00930 { 00931 aor.port() = port; 00932 aor.host() = sipStack.getHostname(); 00933 aor.user() = Data("user"); 00934 } 00935 00936 InfoLog( << "aor is " << aor ); 00937 InfoLog( << "contact is " << contact ); 00938 TestCallback callback; 00939 tuIM = new TuIM(&sipStack,aor,contact,&callback); 00940 00941 Data name("SIPimp.org/0.2.5 (curses)"); 00942 tuIM->setUAName( name ); 00943 00944 if ( !outbound.host().empty() ) 00945 { 00946 tuIM->setOutboundProxy( outbound ); 00947 } 00948 00949 // setup prefered outbound transport 00950 if ( prefUdp ) 00951 { 00952 tuIM->setDefaultProtocol( UDP ); 00953 } 00954 if ( prefTcp ) 00955 { 00956 tuIM->setDefaultProtocol( TCP ); 00957 } 00958 if ( prefTls ) 00959 { 00960 tuIM->setDefaultProtocol( TLS ); 00961 } 00962 if ( prefDtls ) 00963 { 00964 tuIM->setDefaultProtocol( DTLS ); 00965 } 00966 00967 if ( haveAor ) 00968 { 00969 if ( !noRegister ) 00970 { 00971 tuIM->registerAor( aor, aorPassword ); 00972 } 00973 } 00974 00975 initscr(); 00976 cbreak(); 00977 noecho(); 00978 nonl(); 00979 intrflush(stdscr, FALSE); 00980 keypad(stdscr, TRUE); 00981 00982 int rows=0; 00983 int cols=0; 00984 getmaxyx(stdscr,rows,cols); /* get the number of rows and columns */ 00985 00986 commandWin = newwin(2,cols,rows-2,0); 00987 scrollok(commandWin, TRUE); 00988 wmove(commandWin,0,0); 00989 00990 textWin = newwin(rows-3,cols*3/4,0,0); 00991 scrollok(textWin, TRUE); 00992 wmove(textWin,0,0); 00993 00994 statusWin = newwin(rows-3,cols-(cols*3/4)-1,0,1+cols*3/4); 00995 scrollok(statusWin, FALSE); 00996 wmove(statusWin,0,0); 00997 00998 mvhline(rows-3,0,ACS_HLINE,cols); 00999 mvvline(0,(cols*3/4),ACS_VLINE,rows-3); 01000 refresh(); 01001 01002 for ( int i=0; i<numAdd; i++ ) 01003 { 01004 Uri uri(addList[i]); 01005 tuIM->addBuddy( uri, Data::Empty ); 01006 } 01007 01008 for ( int i=0; i<numPub; i++ ) 01009 { 01010 Uri uri(pubList[i]); 01011 tuIM->addStateAgent( uri ); 01012 } 01013 01014 displayPres(); 01015 01016 waddstr(textWin,"Use -help on the command line to view options\n"); 01017 waddstr(textWin,"To set where your messages will get sent type\n"); 01018 waddstr(textWin," to: sip:alice@example.com \n"); 01019 waddstr(textWin,"To monitores someeone presence type\n"); 01020 waddstr(textWin," add: sip:buddy@example.com \n"); 01021 waddstr(textWin,"To change you online status type\n"); 01022 waddstr(textWin," status: in meeting\n"); 01023 waddstr(textWin,"To set yourself to offline type\n"); 01024 waddstr(textWin," status:\n"); 01025 waddstr(textWin,"To exit type a single period\n"); 01026 waddstr(textWin,"\n"); 01027 wrefresh(textWin); 01028 01029 if ( !sendMsg.empty() ) 01030 { 01031 tuIM->sendPage( sendMsg , dest, sign , (encryp) ? 01032 (dest.getAorNoPort()) : (Data::Empty) ); 01033 } 01034 01035 StdInWatcher watcher(&dest,sign,encryp); 01036 FdPollItemHandle wh=sipStack.getPollGrp()->addPollItem(fileno(stdin), FPEM_Read, &watcher); 01037 01038 while (1) 01039 { 01040 try 01041 { 01042 sipStack.process( 50 ); 01043 } 01044 catch (...) 01045 { 01046 ErrLog( << "Got a exception from sipStack::process" ); 01047 } 01048 01049 if(!watcher.keepGoing()) 01050 { 01051 break; 01052 } 01053 01054 try 01055 { 01056 tuIM->process(); 01057 } 01058 catch (...) 01059 { 01060 ErrLog( << "Got a exception passed from TuIM::process" ); 01061 } 01062 } 01063 01064 sipStack.getPollGrp()->delPollItem(wh); 01065 01066 return 0; 01067 } 01068 /* ==================================================================== 01069 * The Vovida Software License, Version 1.0 01070 * 01071 * Copyright (c) 2000 Vovida Networks, Inc. All rights reserved. 01072 * 01073 * Redistribution and use in source and binary forms, with or without 01074 * modification, are permitted provided that the following conditions 01075 * are met: 01076 * 01077 * 1. Redistributions of source code must retain the above copyright 01078 * notice, this list of conditions and the following disclaimer. 01079 * 01080 * 2. Redistributions in binary form must reproduce the above copyright 01081 * notice, this list of conditions and the following disclaimer in 01082 * the documentation and/or other materials provided with the 01083 * distribution. 01084 * 01085 * 3. The names "VOCAL", "Vovida Open Communication Application Library", 01086 * and "Vovida Open Communication Application Library (VOCAL)" must 01087 * not be used to endorse or promote products derived from this 01088 * software without prior written permission. For written 01089 * permission, please contact vocal@vovida.org. 01090 * 01091 * 4. Products derived from this software may not be called "VOCAL", nor 01092 * may "VOCAL" appear in their name, without prior written 01093 * permission of Vovida Networks, Inc. 01094 * 01095 * THIS SOFTWARE IS PROVIDED "AS IS" AND ANY EXPRESSED OR IMPLIED 01096 * WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES 01097 * OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE, TITLE AND 01098 * NON-INFRINGEMENT ARE DISCLAIMED. IN NO EVENT SHALL VOVIDA 01099 * NETWORKS, INC. OR ITS CONTRIBUTORS BE LIABLE FOR ANY DIRECT DAMAGES 01100 * IN EXCESS OF $1,000, NOR FOR ANY INDIRECT, INCIDENTAL, SPECIAL, 01101 * EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT LIMITED TO, 01102 * PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, DATA, OR 01103 * PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY THEORY 01104 * OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT 01105 * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE 01106 * USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH 01107 * DAMAGE. 01108 * 01109 * ==================================================================== 01110 * 01111 * This software consists of voluntary contributions made by Vovida 01112 * Networks, Inc. and many individuals on behalf of Vovida Networks, 01113 * Inc. For more information on Vovida Networks, Inc., please see 01114 * <http://www.vovida.org/>. 01115 * 01116 */
1.7.5.1