1
0

mainrelay.c 87 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581158215831584158515861587158815891590159115921593159415951596159715981599160016011602160316041605160616071608160916101611161216131614161516161617161816191620162116221623162416251626162716281629163016311632163316341635163616371638163916401641164216431644164516461647164816491650165116521653165416551656165716581659166016611662166316641665166616671668166916701671167216731674167516761677167816791680168116821683168416851686168716881689169016911692169316941695169616971698169917001701170217031704170517061707170817091710171117121713171417151716171717181719172017211722172317241725172617271728172917301731173217331734173517361737173817391740174117421743174417451746174717481749175017511752175317541755175617571758175917601761176217631764176517661767176817691770177117721773177417751776177717781779178017811782178317841785178617871788178917901791179217931794179517961797179817991800180118021803180418051806180718081809181018111812181318141815181618171818181918201821182218231824182518261827182818291830183118321833183418351836183718381839184018411842184318441845184618471848184918501851185218531854185518561857185818591860186118621863186418651866186718681869187018711872187318741875187618771878187918801881188218831884188518861887188818891890189118921893189418951896189718981899190019011902190319041905190619071908190919101911191219131914191519161917191819191920192119221923192419251926192719281929193019311932193319341935193619371938193919401941194219431944194519461947194819491950195119521953195419551956195719581959196019611962196319641965196619671968196919701971197219731974197519761977197819791980198119821983198419851986198719881989199019911992199319941995199619971998199920002001200220032004200520062007200820092010201120122013201420152016201720182019202020212022202320242025202620272028202920302031203220332034203520362037203820392040204120422043204420452046204720482049205020512052205320542055205620572058205920602061206220632064206520662067206820692070207120722073207420752076207720782079208020812082208320842085208620872088208920902091209220932094209520962097209820992100210121022103210421052106210721082109211021112112211321142115211621172118211921202121212221232124212521262127212821292130213121322133213421352136213721382139214021412142214321442145214621472148214921502151215221532154215521562157215821592160216121622163216421652166216721682169217021712172217321742175217621772178217921802181218221832184218521862187218821892190219121922193219421952196219721982199220022012202220322042205220622072208220922102211221222132214221522162217221822192220222122222223222422252226222722282229223022312232223322342235223622372238223922402241224222432244224522462247224822492250225122522253225422552256225722582259226022612262226322642265226622672268226922702271227222732274227522762277227822792280228122822283228422852286228722882289229022912292229322942295229622972298229923002301230223032304230523062307230823092310231123122313231423152316231723182319232023212322232323242325232623272328232923302331233223332334233523362337233823392340234123422343234423452346234723482349235023512352235323542355235623572358235923602361236223632364236523662367236823692370237123722373237423752376237723782379238023812382238323842385238623872388238923902391239223932394239523962397239823992400240124022403240424052406240724082409241024112412241324142415241624172418241924202421242224232424242524262427242824292430243124322433243424352436243724382439244024412442244324442445244624472448244924502451245224532454245524562457245824592460246124622463246424652466246724682469247024712472247324742475247624772478247924802481248224832484248524862487248824892490249124922493249424952496249724982499250025012502250325042505250625072508250925102511251225132514251525162517251825192520252125222523252425252526252725282529253025312532253325342535253625372538253925402541254225432544254525462547254825492550255125522553255425552556255725582559256025612562256325642565256625672568256925702571257225732574257525762577257825792580258125822583258425852586258725882589259025912592259325942595259625972598259926002601260226032604260526062607260826092610261126122613261426152616261726182619262026212622262326242625262626272628262926302631263226332634263526362637263826392640264126422643264426452646264726482649265026512652265326542655265626572658265926602661266226632664266526662667
  1. /*
  2. * Copyright (C) 2011, 2012, 2013 Citrix Systems
  3. *
  4. * All rights reserved.
  5. *
  6. * Redistribution and use in source and binary forms, with or without
  7. * modification, are permitted provided that the following conditions
  8. * are met:
  9. * 1. Redistributions of source code must retain the above copyright
  10. * notice, this list of conditions and the following disclaimer.
  11. * 2. Redistributions in binary form must reproduce the above copyright
  12. * notice, this list of conditions and the following disclaimer in the
  13. * documentation and/or other materials provided with the distribution.
  14. * 3. Neither the name of the project nor the names of its contributors
  15. * may be used to endorse or promote products derived from this software
  16. * without specific prior written permission.
  17. *
  18. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  19. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  20. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  21. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  22. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  23. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  24. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  25. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  26. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  27. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  28. * SUCH DAMAGE.
  29. */
  30. #include "mainrelay.h"
  31. ////// TEMPORARY data //////////
  32. static int use_lt_credentials = 0;
  33. static int anon_credentials = 0;
  34. ////// TURNDB //////////////
  35. #if defined(TURNDB)
  36. #if defined(Q)
  37. #undef Q
  38. #endif
  39. #define Q(x) #x
  40. #if defined(QUOTE)
  41. #undef QUOTE
  42. #endif
  43. #define QUOTE(x) Q(x)
  44. #define DEFAULT_USERDB_FILE QUOTE(TURNDB)
  45. #else
  46. #define DEFAULT_USERDB_FILE "/usr/local/var/db/turndb"
  47. #endif
  48. //////TURN PARAMS STRUCTURE DEFINITION //////
  49. #define DEFAULT_GENERAL_RELAY_SERVERS_NUMBER (1)
  50. turn_params_t turn_params = {
  51. NULL, NULL,
  52. #if TLSv1_1_SUPPORTED
  53. NULL,
  54. #if TLSv1_2_SUPPORTED
  55. NULL,
  56. #endif
  57. #endif
  58. #if DTLS_SUPPORTED
  59. NULL,
  60. #endif
  61. #if DTLSv1_2_SUPPORTED
  62. NULL,
  63. #endif
  64. DH_1066, "", "", "",
  65. "turn_server_cert.pem","turn_server_pkey.pem", "", "",
  66. 0,0,0,0,
  67. #if !TLS_SUPPORTED
  68. 1,
  69. #else
  70. 0,
  71. #endif
  72. #if !DTLS_SUPPORTED
  73. 1,
  74. #else
  75. 0,
  76. #endif
  77. TURN_VERBOSE_NONE,0,0,
  78. "/var/run/turnserver.pid",
  79. DEFAULT_STUN_PORT,DEFAULT_STUN_TLS_PORT,0,0,1,
  80. 0,0,0,0,
  81. "",
  82. "",0,
  83. {
  84. NULL,NULL,NULL,NULL,NULL,NULL,NULL,NULL,0,0,NULL,NULL,NULL
  85. },
  86. {NULL, 0},{NULL, 0},
  87. NEV_UNKNOWN,
  88. { "Unknown", "UDP listening socket per session", "UDP thread per network endpoint", "UDP thread per CPU core" },
  89. //////////////// Relay servers //////////////////////////////////
  90. LOW_DEFAULT_PORTS_BOUNDARY,HIGH_DEFAULT_PORTS_BOUNDARY,0,0,0,"",
  91. 0,NULL,0,NULL,DEFAULT_GENERAL_RELAY_SERVERS_NUMBER,0,
  92. ////////////// Auth server /////////////////////////////////////
  93. "","",0,
  94. /////////////// AUX SERVERS ////////////////
  95. {NULL,0,{0,NULL}},0,
  96. /////////////// ALTERNATE SERVERS ////////////////
  97. {NULL,0,{0,NULL}},{NULL,0,{0,NULL}},
  98. /////////////// stop server ////////////////
  99. 0,
  100. /////////////// MISC PARAMS ////////////////
  101. 0,0,0,0,0,':',0,0,TURN_CREDENTIALS_NONE,0,0,0,0,0,0,
  102. ///////////// Users DB //////////////
  103. { (TURN_USERDB_TYPE)0, {"\0"}, {0,NULL, {NULL,0}} },
  104. ///////////// CPUs //////////////////
  105. DEFAULT_CPUS_NUMBER
  106. };
  107. //////////////// OpenSSL Init //////////////////////
  108. static void openssl_setup(void);
  109. /*
  110. * openssl genrsa -out pkey 2048
  111. * openssl req -new -key pkey -out cert.req
  112. * openssl x509 -req -days 365 -in cert.req -signkey pkey -out cert
  113. *
  114. */
  115. //////////// Common static process params ////////
  116. static gid_t procgroupid = 0;
  117. static uid_t procuserid = 0;
  118. static gid_t procgroupid_set = 0;
  119. static uid_t procuserid_set = 0;
  120. static char procusername[1025]="\0";
  121. static char procgroupname[1025]="\0";
  122. ////////////// Configuration functionality ////////////////////////////////
  123. static void read_config_file(int argc, char **argv, int pass);
  124. //////////////////////////////////////////////////
  125. static int make_local_listeners_list(void)
  126. {
  127. int ret = 0;
  128. struct ifaddrs * ifs = NULL;
  129. struct ifaddrs * ifa = NULL;
  130. char saddr[INET6_ADDRSTRLEN] = "";
  131. if((getifaddrs(&ifs) == 0) && ifs) {
  132. for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) {
  133. if(!(ifa->ifa_flags & IFF_UP))
  134. continue;
  135. if(!(ifa->ifa_addr))
  136. continue;
  137. if (ifa ->ifa_addr->sa_family == AF_INET) {
  138. if(!inet_ntop(AF_INET, &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr, saddr,
  139. INET_ADDRSTRLEN))
  140. continue;
  141. if(strstr(saddr,"169.254.") == saddr)
  142. continue;
  143. if(!strcmp(saddr,"0.0.0.0"))
  144. continue;
  145. } else if (ifa->ifa_addr->sa_family == AF_INET6) {
  146. if(!inet_ntop(AF_INET6, &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr, saddr,
  147. INET6_ADDRSTRLEN))
  148. continue;
  149. if(strstr(saddr,"fe80") == saddr)
  150. continue;
  151. if(!strcmp(saddr,"::"))
  152. continue;
  153. } else {
  154. continue;
  155. }
  156. add_listener_addr(saddr);
  157. if(!(ifa->ifa_flags & IFF_LOOPBACK))
  158. ret++;
  159. }
  160. freeifaddrs(ifs);
  161. }
  162. return ret;
  163. }
  164. static int make_local_relays_list(int allow_local, int family)
  165. {
  166. struct ifaddrs * ifs = NULL;
  167. struct ifaddrs * ifa = NULL;
  168. char saddr[INET6_ADDRSTRLEN] = "";
  169. getifaddrs(&ifs);
  170. int counter = 0;
  171. if (ifs) {
  172. for (ifa = ifs; ifa != NULL; ifa = ifa->ifa_next) {
  173. if(!(ifa->ifa_flags & IFF_UP))
  174. continue;
  175. if(!(ifa->ifa_name))
  176. continue;
  177. if(!(ifa ->ifa_addr))
  178. continue;
  179. if(!allow_local && (ifa->ifa_flags & IFF_LOOPBACK))
  180. continue;
  181. if (ifa ->ifa_addr->sa_family == AF_INET) {
  182. if(family != AF_INET)
  183. continue;
  184. if(!inet_ntop(AF_INET, &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr, saddr,
  185. INET_ADDRSTRLEN))
  186. continue;
  187. if(strstr(saddr,"169.254.") == saddr)
  188. continue;
  189. if(!strcmp(saddr,"0.0.0.0"))
  190. continue;
  191. } else if (ifa->ifa_addr->sa_family == AF_INET6) {
  192. if(family != AF_INET6)
  193. continue;
  194. if(!inet_ntop(AF_INET6, &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr, saddr,
  195. INET6_ADDRSTRLEN))
  196. continue;
  197. if(strstr(saddr,"fe80") == saddr)
  198. continue;
  199. if(!strcmp(saddr,"::"))
  200. continue;
  201. } else
  202. continue;
  203. if(add_relay_addr(saddr)>0) {
  204. counter += 1;
  205. }
  206. }
  207. freeifaddrs(ifs);
  208. }
  209. return counter;
  210. }
  211. int get_a_local_relay(int family, ioa_addr *relay_addr)
  212. {
  213. struct ifaddrs * ifs = NULL;
  214. int allow_local = 0;
  215. int ret = -1;
  216. char saddr[INET6_ADDRSTRLEN] = "";
  217. getifaddrs(&ifs);
  218. if (ifs) {
  219. galr_start:
  220. {
  221. struct ifaddrs *ifa = NULL;
  222. for (ifa = ifs; ifa != NULL ; ifa = ifa->ifa_next) {
  223. if (!(ifa->ifa_flags & IFF_UP))
  224. continue;
  225. if (!(ifa->ifa_name))
  226. continue;
  227. if (!(ifa->ifa_addr))
  228. continue;
  229. if (!allow_local && (ifa->ifa_flags & IFF_LOOPBACK))
  230. continue;
  231. if (ifa->ifa_addr->sa_family == AF_INET) {
  232. if (family != AF_INET)
  233. continue;
  234. if (!inet_ntop(AF_INET,
  235. &((struct sockaddr_in *) ifa->ifa_addr)->sin_addr,
  236. saddr, INET_ADDRSTRLEN))
  237. continue;
  238. if (strstr(saddr, "169.254.") == saddr)
  239. continue;
  240. if (!strcmp(saddr, "0.0.0.0"))
  241. continue;
  242. } else if (ifa->ifa_addr->sa_family == AF_INET6) {
  243. if (family != AF_INET6)
  244. continue;
  245. if (!inet_ntop(AF_INET6,
  246. &((struct sockaddr_in6 *) ifa->ifa_addr)->sin6_addr,
  247. saddr, INET6_ADDRSTRLEN))
  248. continue;
  249. if (strstr(saddr, "fe80") == saddr)
  250. continue;
  251. if (!strcmp(saddr, "::"))
  252. continue;
  253. } else
  254. continue;
  255. if (make_ioa_addr((const u08bits*) saddr, 0, relay_addr) < 0) {
  256. continue;
  257. } else {
  258. ret = 0;
  259. break;
  260. }
  261. }
  262. }
  263. if(ret<0 && !allow_local) {
  264. allow_local = 1;
  265. goto galr_start;
  266. }
  267. freeifaddrs(ifs);
  268. }
  269. return -1;
  270. }
  271. //////////////////////////////////////////////////
  272. static char Usage[] = "Usage: turnserver [options]\n"
  273. "Options:\n"
  274. " -d, --listening-device <device-name> Listener interface device (NOT RECOMMENDED. Optional, Linux only).\n"
  275. " -p, --listening-port <port> TURN listener port (Default: 3478).\n"
  276. " Note: actually, TLS & DTLS sessions can connect to the \"plain\" TCP & UDP port(s), too,\n"
  277. " if allowed by configuration.\n"
  278. " --tls-listening-port <port> TURN listener port for TLS & DTLS listeners\n"
  279. " (Default: 5349).\n"
  280. " Note: actually, \"plain\" TCP & UDP sessions can connect to the TLS & DTLS port(s), too,\n"
  281. " if allowed by configuration. The TURN server\n"
  282. " \"automatically\" recognizes the type of traffic. Actually, two listening\n"
  283. " endpoints (the \"plain\" one and the \"tls\" one) are equivalent in terms of\n"
  284. " functionality; but we keep both endpoints to satisfy the RFC 5766 specs.\n"
  285. " For secure TCP connections, we currently support SSL version 3 and\n"
  286. " TLS versions 1.0, 1.1 and 1.2. For secure UDP connections, we support\n"
  287. " DTLS version 1.\n"
  288. " --alt-listening-port<port> <port> Alternative listening port for STUN CHANGE_REQUEST (in RFC 5780 sense, \n"
  289. " or in old RFC 3489 sense, default is \"listening port plus one\").\n"
  290. " --alt-tls-listening-port <port> Alternative listening port for TLS and DTLS,\n"
  291. " the default is \"TLS/DTLS port plus one\".\n"
  292. " -L, --listening-ip <ip> Listener IP address of relay server. Multiple listeners can be specified.\n"
  293. " --aux-server <ip:port> Auxiliary STUN/TURN server listening endpoint.\n"
  294. " Auxiliary servers do not have alternative ports and\n"
  295. " they do not support RFC 5780 functionality (CHANGE REQUEST).\n"
  296. " Valid formats are 1.2.3.4:5555 for IPv4 and [1:2::3:4]:5555 for IPv6.\n"
  297. " --udp-self-balance (recommended for older Linuxes only) Automatically balance UDP traffic\n"
  298. " over auxiliary servers (if configured).\n"
  299. " The load balancing is using the ALTERNATE-SERVER mechanism.\n"
  300. " The TURN client must support 300 ALTERNATE-SERVER response for this functionality.\n"
  301. " -i, --relay-device <device-name> Relay interface device for relay sockets (NOT RECOMMENDED. Optional, Linux only).\n"
  302. " -E, --relay-ip <ip> Relay address (the local IP address that will be used to relay the\n"
  303. " packets to the peer).\n"
  304. " Multiple relay addresses may be used.\n"
  305. " The same IP(s) can be used as both listening IP(s) and relay IP(s).\n"
  306. " If no relay IP(s) specified, then the turnserver will apply the default\n"
  307. " policy: it will decide itself which relay addresses to be used, and it\n"
  308. " will always be using the client socket IP address as the relay IP address\n"
  309. " of the TURN session (if the requested relay address family is the same\n"
  310. " as the family of the client socket).\n"
  311. " -X, --external-ip <public-ip[/private-ip]> TURN Server public/private address mapping, if the server is behind NAT.\n"
  312. " In that situation, if a -X is used in form \"-X ip\" then that ip will be reported\n"
  313. " as relay IP address of all allocations. This scenario works only in a simple case\n"
  314. " when one single relay address is be used, and no STUN CHANGE_REQUEST\n"
  315. " functionality is required.\n"
  316. " That single relay address must be mapped by NAT to the 'external' IP.\n"
  317. " For that 'external' IP, NAT must forward ports directly (relayed port 12345\n"
  318. " must be always mapped to the same 'external' port 12345).\n"
  319. " In more complex case when more than one IP address is involved,\n"
  320. " that option must be used several times in the command line, each entry must\n"
  321. " have form \"-X public-ip/private-ip\", to map all involved addresses.\n"
  322. " --no-loopback-peers Disallow peers on the loopback addresses (127.x.x.x and ::1).\n"
  323. " --no-multicast-peers Disallow peers on well-known broadcast addresses (224.0.0.0 and above, and FFXX:*).\n"
  324. " -m, --relay-threads <number> Number of relay threads to handle the established connections\n"
  325. " (in addition to authentication thread and the listener thread).\n"
  326. " If explicitly set to 0 then application runs in single-threaded mode.\n"
  327. " If not set then a default OS-dependent optimal algorithm will be employed.\n"
  328. " The default thread number is the number of CPUs.\n"
  329. " In older systems (pre-Linux 3.9) the number of UDP relay threads always equals\n"
  330. " the number of listening endpoints (unless -m 0 is set).\n"
  331. " --min-port <port> Lower bound of the UDP port range for relay endpoints allocation.\n"
  332. " Default value is 49152, according to RFC 5766.\n"
  333. " --max-port <port> Upper bound of the UDP port range for relay endpoints allocation.\n"
  334. " Default value is 65535, according to RFC 5766.\n"
  335. " -v, --verbose 'Moderate' verbose mode.\n"
  336. " -V, --Verbose Extra verbose mode, very annoying (for debug purposes only).\n"
  337. " -o, --daemon Start process as daemon (detach from current shell).\n"
  338. " -f, --fingerprint Use fingerprints in the TURN messages.\n"
  339. " -a, --lt-cred-mech Use the long-term credential mechanism.\n"
  340. " -z, --no-auth Do not use any credential mechanism, allow anonymous access.\n"
  341. " -u, --user <user:pwd> User account, in form 'username:password', for long-term credentials.\n"
  342. " Cannot be used with TURN REST API.\n"
  343. " -r, --realm <realm> The default realm to be used for the users when no explicit\n"
  344. " origin/realm relationship was found in the database.\n"
  345. " Must be used with long-term credentials \n"
  346. " mechanism or with TURN REST API.\n"
  347. " --check-origin-consistency The flag that sets the origin consistency check:\n"
  348. " across the session, all requests must have the same\n"
  349. " main ORIGIN attribute value (if the ORIGIN was\n"
  350. " initially used by the session).\n"
  351. " -q, --user-quota <number> Per-user allocation quota: how many concurrent allocations a user can create.\n"
  352. " This option can also be set through the database, for a particular realm.\n"
  353. " -Q, --total-quota <number> Total allocations quota: global limit on concurrent allocations.\n"
  354. " This option can also be set through the database, for a particular realm.\n"
  355. " -s, --max-bps <number> Default max bytes-per-second bandwidth a TURN session is allowed to handle\n"
  356. " (input and output network streams are treated separately). Anything above\n"
  357. " that limit will be dropped or temporary suppressed\n"
  358. " (within the available buffer limits).\n"
  359. " This option can also be set through the database, for a particular realm.\n"
  360. " -B, --bps-capacity <number> Maximum server capacity.\n"
  361. " Total bytes-per-second bandwidth the TURN server is allowed to allocate\n"
  362. " for the sessions, combined (input and output network streams are treated separately).\n"
  363. " -c <filename> Configuration file name (default - turnserver.conf).\n"
  364. #if !defined(TURN_NO_SQLITE)
  365. " -b, , --db, --userdb <filename> SQLite database file name; default - /var/db/turndb or\n"
  366. " /usr/local/var/db/turndb or /var/lib/turn/turndb.\n"
  367. #endif
  368. #if !defined(TURN_NO_PQ)
  369. " -e, --psql-userdb, --sql-userdb <conn-string> PostgreSQL database connection string, if used (default - empty, no PostreSQL DB used).\n"
  370. " This database can be used for long-term credentials mechanism users,\n"
  371. " and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
  372. " See http://www.postgresql.org/docs/8.4/static/libpq-connect.html for 8.x PostgreSQL\n"
  373. " versions format, see \n"
  374. " http://www.postgresql.org/docs/9.2/static/libpq-connect.html#LIBPQ-CONNSTRING\n"
  375. " for 9.x and newer connection string formats.\n"
  376. #endif
  377. #if !defined(TURN_NO_MYSQL)
  378. " -M, --mysql-userdb <connection-string> MySQL database connection string, if used (default - empty, no MySQL DB used).\n"
  379. " This database can be used for long-term credentials mechanism users,\n"
  380. " and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
  381. " The connection string my be space-separated list of parameters:\n"
  382. " \"host=<ip-addr> dbname=<database-name> user=<database-user> \\\n password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n\n"
  383. " The connection string parameters for the secure communications (SSL):\n"
  384. " ca, capath, cert, key, cipher\n"
  385. " (see http://dev.mysql.com/doc/refman/5.1/en/ssl-options.html for the\n"
  386. " command options description).\n\n"
  387. " All connection-string parameters are optional.\n\n"
  388. #endif
  389. #if !defined(TURN_NO_MONGO)
  390. " -J, --mongo-userdb <connection-string> MongoDB connection string, if used (default - empty, no MongoDB used).\n"
  391. " This database can be used for long-term credentials mechanism users,\n"
  392. " and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
  393. #endif
  394. #if !defined(TURN_NO_HIREDIS)
  395. " -N, --redis-userdb <connection-string> Redis user database connection string, if used (default - empty, no Redis DB used).\n"
  396. " This database can be used for long-term credentials mechanism users,\n"
  397. " and it can store the secret value(s) for secret-based timed authentication in TURN RESP API.\n"
  398. " The connection string my be space-separated list of parameters:\n"
  399. " \"host=<ip-addr> dbname=<db-number> \\\n password=<database-user-password> port=<db-port> connect_timeout=<seconds>\".\n\n"
  400. " All connection-string parameters are optional.\n\n"
  401. " -O, --redis-statsdb <connection-string> Redis status and statistics database connection string, if used \n"
  402. " (default - empty, no Redis stats DB used).\n"
  403. " This database keeps allocations status information, and it can be also used for publishing\n"
  404. " and delivering traffic and allocation event notifications.\n"
  405. " The connection string has the same parameters as redis-userdb connection string.\n"
  406. #endif
  407. " --use-auth-secret TURN REST API flag.\n"
  408. " Flag that sets a special authorization option that is based upon authentication secret\n"
  409. " (TURN Server REST API, see TURNServerRESTAPI.pdf). This option is used with timestamp.\n"
  410. " --static-auth-secret <secret> 'Static' authentication secret value (a string) for TURN REST API only.\n"
  411. " If not set, then the turn server will try to use the 'dynamic' value\n"
  412. " in turn_secret table in user database (if present).\n"
  413. " That database value can be changed on-the-fly\n"
  414. " by a separate program, so this is why it is 'dynamic'.\n"
  415. " Multiple shared secrets can be used (both in the database and in the \"static\" fashion).\n"
  416. " --server-name Server name used for\n"
  417. " the oAuth authentication purposes.\n"
  418. " The default value is the realm name.\n"
  419. " --oauth Support oAuth authentication.\n"
  420. " -n Do not use configuration file, take all parameters from the command line only.\n"
  421. " --cert <filename> Certificate file, PEM format. Same file search rules\n"
  422. " applied as for the configuration file.\n"
  423. " If both --no-tls and --no_dtls options\n"
  424. " are specified, then this parameter is not needed.\n"
  425. " --pkey <filename> Private key file, PEM format. Same file search rules\n"
  426. " applied as for the configuration file.\n"
  427. " If both --no-tls and --no-dtls options\n"
  428. " --pkey-pwd <password> If the private key file is encrypted, then this password to be used.\n"
  429. " --cipher-list <\"cipher-string\"> Allowed OpenSSL cipher list for TLS/DTLS connections.\n"
  430. " Default value is \"DEFAULT\".\n"
  431. " --CA-file <filename> CA file in OpenSSL format.\n"
  432. " Forces TURN server to verify the client SSL certificates.\n"
  433. " By default, no CA is set and no client certificate check is performed.\n"
  434. " --ec-curve-name <curve-name> Curve name for EC ciphers, if supported by OpenSSL\n"
  435. " library (TLS and DTLS). The default value is prime256v1,\n"
  436. " if pre-OpenSSL 1.0.2 is used. With OpenSSL 1.0.2+,\n"
  437. " an optimal curve will be automatically calculated, if not defined\n"
  438. " by this option.\n"
  439. " --dh566 Use 566 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
  440. " --dh2066 Use 2066 bits predefined DH TLS key. Default size of the predefined key is 1066.\n"
  441. " --dh-file <dh-file-name> Use custom DH TLS key, stored in PEM format in the file.\n"
  442. " Flags --dh566 and --dh2066 are ignored when the DH key is taken from a file.\n"
  443. " --no-sslv3 Do not allow SSLv3 protocol.\n"
  444. " --no-tlsv1 Do not allow TLSv1/DTLSv1 protocol.\n"
  445. " --no-tlsv1_1 Do not allow TLSv1.1 protocol.\n"
  446. " --no-tlsv1_2 Do not allow TLSv1.2/DTLSv1.2 protocol.\n"
  447. " --no-udp Do not start UDP client listeners.\n"
  448. " --no-tcp Do not start TCP client listeners.\n"
  449. " --no-tls Do not start TLS client listeners.\n"
  450. " --no-dtls Do not start DTLS client listeners.\n"
  451. " --no-udp-relay Do not allow UDP relay endpoints, use only TCP relay option.\n"
  452. " --no-tcp-relay Do not allow TCP relay endpoints, use only UDP relay options.\n"
  453. " -l, --log-file <filename> Option to set the full path name of the log file.\n"
  454. " By default, the turnserver tries to open a log file in\n"
  455. " /var/log/turnserver/, /var/log, /var/tmp, /tmp and . (current) directories\n"
  456. " (which open operation succeeds first that file will be used).\n"
  457. " With this option you can set the definite log file name.\n"
  458. " The special names are \"stdout\" and \"-\" - they will force everything\n"
  459. " to the stdout; and \"syslog\" name will force all output to the syslog.\n"
  460. " --no-stdout-log Flag to prevent stdout log messages.\n"
  461. " By default, all log messages are going to both stdout and to\n"
  462. " a log file. With this option everything will be going to the log file only\n"
  463. " (unless the log file itself is stdout).\n"
  464. " --syslog Output all log information into the system log (syslog), do not use the file output.\n"
  465. " --simple-log This flag means that no log file rollover will be used, and the log file\n"
  466. " name will be constructed as-is, without PID and date appendage.\n"
  467. " This option can be used, for example, together with the logrotate tool.\n"
  468. " --stale-nonce Use extra security with nonce value having limited lifetime (600 secs).\n"
  469. " -S, --stun-only Option to set standalone STUN operation only, all TURN requests will be ignored.\n"
  470. " --no-stun Option to suppress STUN functionality, only TURN requests will be processed.\n"
  471. " --alternate-server <ip:port> Set the TURN server to redirect the allocate requests (UDP and TCP services).\n"
  472. " Multiple alternate-server options can be set for load balancing purposes.\n"
  473. " See the docs for more information.\n"
  474. " --tls-alternate-server <ip:port> Set the TURN server to redirect the allocate requests (DTLS and TLS services).\n"
  475. " Multiple alternate-server options can be set for load balancing purposes.\n"
  476. " See the docs for more information.\n"
  477. " -C, --rest-api-separator <SYMBOL> This is the timestamp/username separator symbol (character) in TURN REST API.\n"
  478. " The default value is ':'.\n"
  479. " --max-allocate-timeout=<seconds> Max time, in seconds, allowed for full allocation establishment. Default is 60.\n"
  480. " --allowed-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are explicitly allowed to connect to the \n"
  481. " turn server. Multiple allowed-peer-ip can be set.\n"
  482. " --denied-peer-ip=<ip[-ip]> Specifies an ip or range of ips that are not allowed to connect to the turn server.\n"
  483. " Multiple denied-peer-ip can be set.\n"
  484. " --pidfile <\"pid-file-name\"> File name to store the pid of the process.\n"
  485. " Default is /var/run/turnserver.pid (if superuser account is used) or\n"
  486. " /var/tmp/turnserver.pid .\n"
  487. " --secure-stun Require authentication of the STUN Binding request.\n"
  488. " By default, the clients are allowed anonymous access to the STUN Binding functionality.\n"
  489. " --proc-user <user-name> User name to run the turnserver process.\n"
  490. " After the initialization, the turnserver process\n"
  491. " will make an attempt to change the current user ID to that user.\n"
  492. " --proc-group <group-name> Group name to run the turnserver process.\n"
  493. " After the initialization, the turnserver process\n"
  494. " will make an attempt to change the current group ID to that group.\n"
  495. " --mobility Mobility with ICE (MICE) specs support.\n"
  496. " --no-cli Turn OFF the CLI support. By default it is always ON.\n"
  497. " --cli-ip=<IP> Local system IP address to be used for CLI server endpoint. Default value\n"
  498. " is 127.0.0.1.\n"
  499. " --cli-port=<port> CLI server port. Default is 5766.\n"
  500. " --cli-password=<password> CLI access password. Default is empty (no password).\n"
  501. " For the security reasons, it is recommended to use the encrypted\n"
  502. " for of the password (see the -P command in the turnadmin utility).\n"
  503. " The dollar signs in the encrypted form must be escaped.\n"
  504. " --server-relay Server relay. NON-STANDARD AND DANGEROUS OPTION. Only for those applications\n"
  505. " when we want to run server applications on the relay endpoints.\n"
  506. " This option eliminates the IP permissions check on the packets\n"
  507. " incoming to the relay endpoints.\n"
  508. " --cli-max-output-sessions Maximum number of output sessions in ps CLI command.\n"
  509. " This value can be changed on-the-fly in CLI. The default value is 256.\n"
  510. " --ne=[1|2|3] Set network engine type for the process (for internal purposes).\n"
  511. " -h Help\n"
  512. "\n"
  513. " For more information, see the wiki pages:\n"
  514. "\n"
  515. " http://code.google.com/p/coturn/w/list\n"
  516. "\n";
  517. static char AdminUsage[] = "Usage: turnadmin [command] [options]\n"
  518. "\nCommands:\n\n"
  519. " -P, --generate-encrypted-password Generate and print to the standard\n"
  520. " output an encrypted form of a password\n"
  521. " (for web admin user or CLI). See wiki, README or man\n"
  522. " pages for more detailed description.\n"
  523. " -k, --key generate long-term credential mechanism key for a user\n"
  524. " -a, --add add/update a long-term mechanism user\n"
  525. " -A, --add-admin add/update a web admin user\n"
  526. " -d, --delete delete a long-term mechanism user\n"
  527. " -D, --delete-admin delete an admin user\n"
  528. " -l, --list list all long-term mechanism users\n"
  529. " -L, --list-admin list all admin users\n"
  530. " -s, --set-secret=<value> Add shared secret for TURN RESP API\n"
  531. " -S, --show-secret Show stored shared secrets for TURN REST API\n"
  532. " -X, --delete-secret=<value> Delete a shared secret\n"
  533. " --delete-all-secrets Delete all shared secrets for REST API\n"
  534. " -O, --add-origin Add origin-to-realm relation.\n"
  535. " -R, --del-origin Delete origin-to-realm relation.\n"
  536. " -I, --list-origins List origin-to-realm relations.\n"
  537. " -g, --set-realm-option Set realm params: max-bps, total-quota, user-quota.\n"
  538. " -G, --list-realm-options List realm params.\n"
  539. "\nOptions with mandatory values:\n\n"
  540. #if !defined(TURN_NO_SQLITE)
  541. " -b, --db, --userdb SQLite database file, default value is /var/db/turndb or\n"
  542. " /usr/local/var/db/turndb or /var/lib/turn/turndb.\n"
  543. #endif
  544. #if !defined(TURN_NO_PQ)
  545. " -e, --psql-userdb, --sql-userdb PostgreSQL user database connection string, if PostgreSQL DB is used.\n"
  546. #endif
  547. #if !defined(TURN_NO_MYSQL)
  548. " -M, --mysql-userdb MySQL user database connection string, if MySQL DB is used.\n"
  549. #endif
  550. #if !defined(TURN_NO_MONGO)
  551. " -J, --mongo-userdb MongoDB user database connection string, if MongoDB is used.\n"
  552. #endif
  553. #if !defined(TURN_NO_HIREDIS)
  554. " -N, --redis-userdb Redis user database connection string, if Redis DB is used.\n"
  555. #endif
  556. " -u, --user Username\n"
  557. " -r, --realm Realm\n"
  558. " -p, --password Password\n"
  559. #if !defined(TURN_NO_SQLITE) || !defined(TURN_NO_PQ) || !defined(TURN_NO_MYSQL) || !defined(TURN_NO_MONGO) || !defined(TURN_NO_HIREDIS)
  560. " -o, --origin Origin\n"
  561. #endif
  562. " --max-bps Set value of realm's max-bps parameter.\n"
  563. " Setting to zero value means removal of the option.\n"
  564. " --total-quota Set value of realm's total-quota parameter.\n"
  565. " Setting to zero value means removal of the option.\n"
  566. " --user-quota Set value of realm's user-quota parameter.\n"
  567. " Setting to zero value means removal of the option.\n"
  568. " -h, --help Help\n";
  569. #define OPTIONS "c:d:p:L:E:X:i:m:l:r:u:b:B:e:M:J:N:O:q:Q:s:C:vVofhznaAS"
  570. #define ADMIN_OPTIONS "PgGORIHKYlLkaADSdb:e:M:J:N:u:r:p:s:X:o:h"
  571. enum EXTRA_OPTS {
  572. NO_UDP_OPT=256,
  573. NO_TCP_OPT,
  574. NO_TLS_OPT,
  575. NO_DTLS_OPT,
  576. NO_UDP_RELAY_OPT,
  577. NO_TCP_RELAY_OPT,
  578. TLS_PORT_OPT,
  579. ALT_PORT_OPT,
  580. ALT_TLS_PORT_OPT,
  581. CERT_FILE_OPT,
  582. PKEY_FILE_OPT,
  583. PKEY_PWD_OPT,
  584. MIN_PORT_OPT,
  585. MAX_PORT_OPT,
  586. STALE_NONCE_OPT,
  587. AUTH_SECRET_OPT,
  588. DEL_ALL_AUTH_SECRETS_OPT,
  589. STATIC_AUTH_SECRET_VAL_OPT,
  590. AUTH_SECRET_TS_EXP, /* deprecated */
  591. NO_STDOUT_LOG_OPT,
  592. SYSLOG_OPT,
  593. SIMPLE_LOG_OPT,
  594. AUX_SERVER_OPT,
  595. UDP_SELF_BALANCE_OPT,
  596. ALTERNATE_SERVER_OPT,
  597. TLS_ALTERNATE_SERVER_OPT,
  598. NO_MULTICAST_PEERS_OPT,
  599. NO_LOOPBACK_PEERS_OPT,
  600. MAX_ALLOCATE_TIMEOUT_OPT,
  601. ALLOWED_PEER_IPS,
  602. DENIED_PEER_IPS,
  603. CIPHER_LIST_OPT,
  604. PIDFILE_OPT,
  605. SECURE_STUN_OPT,
  606. CA_FILE_OPT,
  607. DH_FILE_OPT,
  608. NO_STUN_OPT,
  609. PROC_USER_OPT,
  610. PROC_GROUP_OPT,
  611. MOBILITY_OPT,
  612. NO_CLI_OPT,
  613. CLI_IP_OPT,
  614. CLI_PORT_OPT,
  615. CLI_PASSWORD_OPT,
  616. SERVER_RELAY_OPT,
  617. CLI_MAX_SESSIONS_OPT,
  618. EC_CURVE_NAME_OPT,
  619. DH566_OPT,
  620. DH2066_OPT,
  621. NE_TYPE_OPT,
  622. NO_SSLV2_OPT, /*deprecated*/
  623. NO_SSLV3_OPT,
  624. NO_TLSV1_OPT,
  625. NO_TLSV1_1_OPT,
  626. NO_TLSV1_2_OPT,
  627. CHECK_ORIGIN_CONSISTENCY_OPT,
  628. ADMIN_MAX_BPS_OPT,
  629. ADMIN_TOTAL_QUOTA_OPT,
  630. ADMIN_USER_QUOTA_OPT,
  631. SERVER_NAME_OPT,
  632. OAUTH_OPT
  633. };
  634. struct myoption {
  635. const char *name; /* name of long option */
  636. int has_arg; /* whether option takes an argument */
  637. int *flag; /* if not NULL, set *flag to val when option found */
  638. int val; /* if flag is not NULL, value to set *flag to. */
  639. /* if flag is NULL, return value */
  640. };
  641. struct uoptions {
  642. union {
  643. const struct myoption *m;
  644. const struct option *o;
  645. } u;
  646. };
  647. static const struct myoption long_options[] = {
  648. { "listening-device", required_argument, NULL, 'd' },
  649. { "listening-port", required_argument, NULL, 'p' },
  650. { "tls-listening-port", required_argument, NULL, TLS_PORT_OPT },
  651. { "alt-listening-port", required_argument, NULL, ALT_PORT_OPT },
  652. { "alt-tls-listening-port", required_argument, NULL, ALT_TLS_PORT_OPT },
  653. { "listening-ip", required_argument, NULL, 'L' },
  654. { "relay-device", required_argument, NULL, 'i' },
  655. { "relay-ip", required_argument, NULL, 'E' },
  656. { "external-ip", required_argument, NULL, 'X' },
  657. { "relay-threads", required_argument, NULL, 'm' },
  658. { "min-port", required_argument, NULL, MIN_PORT_OPT },
  659. { "max-port", required_argument, NULL, MAX_PORT_OPT },
  660. { "lt-cred-mech", optional_argument, NULL, 'a' },
  661. { "no-auth", optional_argument, NULL, 'z' },
  662. { "user", required_argument, NULL, 'u' },
  663. { "userdb", required_argument, NULL, 'b' },
  664. { "db", required_argument, NULL, 'b' },
  665. #if !defined(TURN_NO_PQ)
  666. { "psql-userdb", required_argument, NULL, 'e' },
  667. { "sql-userdb", required_argument, NULL, 'e' },
  668. #endif
  669. #if !defined(TURN_NO_MYSQL)
  670. { "mysql-userdb", required_argument, NULL, 'M' },
  671. #endif
  672. #if !defined(TURN_NO_MONGO)
  673. { "mongo-userdb", required_argument, NULL, 'J' },
  674. #endif
  675. #if !defined(TURN_NO_HIREDIS)
  676. { "redis-userdb", required_argument, NULL, 'N' },
  677. { "redis-statsdb", required_argument, NULL, 'O' },
  678. #endif
  679. { "use-auth-secret", optional_argument, NULL, AUTH_SECRET_OPT },
  680. { "static-auth-secret", required_argument, NULL, STATIC_AUTH_SECRET_VAL_OPT },
  681. /* deprecated: */ { "secret-ts-exp-time", optional_argument, NULL, AUTH_SECRET_TS_EXP },
  682. { "realm", required_argument, NULL, 'r' },
  683. { "server-name", required_argument, NULL, SERVER_NAME_OPT },
  684. { "oauth", optional_argument, NULL, OAUTH_OPT },
  685. { "user-quota", required_argument, NULL, 'q' },
  686. { "total-quota", required_argument, NULL, 'Q' },
  687. { "max-bps", required_argument, NULL, 's' },
  688. { "bps-capacity", required_argument, NULL, 'B' },
  689. { "verbose", optional_argument, NULL, 'v' },
  690. { "Verbose", optional_argument, NULL, 'V' },
  691. { "daemon", optional_argument, NULL, 'o' },
  692. { "fingerprint", optional_argument, NULL, 'f' },
  693. { "check-origin-consistency", optional_argument, NULL, CHECK_ORIGIN_CONSISTENCY_OPT },
  694. { "no-udp", optional_argument, NULL, NO_UDP_OPT },
  695. { "no-tcp", optional_argument, NULL, NO_TCP_OPT },
  696. { "no-tls", optional_argument, NULL, NO_TLS_OPT },
  697. { "no-dtls", optional_argument, NULL, NO_DTLS_OPT },
  698. { "no-udp-relay", optional_argument, NULL, NO_UDP_RELAY_OPT },
  699. { "no-tcp-relay", optional_argument, NULL, NO_TCP_RELAY_OPT },
  700. { "stale-nonce", optional_argument, NULL, STALE_NONCE_OPT },
  701. { "stun-only", optional_argument, NULL, 'S' },
  702. { "no-stun", optional_argument, NULL, NO_STUN_OPT },
  703. { "cert", required_argument, NULL, CERT_FILE_OPT },
  704. { "pkey", required_argument, NULL, PKEY_FILE_OPT },
  705. { "pkey-pwd", required_argument, NULL, PKEY_PWD_OPT },
  706. { "log-file", required_argument, NULL, 'l' },
  707. { "no-stdout-log", optional_argument, NULL, NO_STDOUT_LOG_OPT },
  708. { "syslog", optional_argument, NULL, SYSLOG_OPT },
  709. { "simple-log", optional_argument, NULL, SIMPLE_LOG_OPT },
  710. { "aux-server", required_argument, NULL, AUX_SERVER_OPT },
  711. { "udp-self-balance", optional_argument, NULL, UDP_SELF_BALANCE_OPT },
  712. { "alternate-server", required_argument, NULL, ALTERNATE_SERVER_OPT },
  713. { "tls-alternate-server", required_argument, NULL, TLS_ALTERNATE_SERVER_OPT },
  714. { "rest-api-separator", required_argument, NULL, 'C' },
  715. { "max-allocate-timeout", required_argument, NULL, MAX_ALLOCATE_TIMEOUT_OPT },
  716. { "no-multicast-peers", optional_argument, NULL, NO_MULTICAST_PEERS_OPT },
  717. { "no-loopback-peers", optional_argument, NULL, NO_LOOPBACK_PEERS_OPT },
  718. { "allowed-peer-ip", required_argument, NULL, ALLOWED_PEER_IPS },
  719. { "denied-peer-ip", required_argument, NULL, DENIED_PEER_IPS },
  720. { "cipher-list", required_argument, NULL, CIPHER_LIST_OPT },
  721. { "pidfile", required_argument, NULL, PIDFILE_OPT },
  722. { "secure-stun", optional_argument, NULL, SECURE_STUN_OPT },
  723. { "CA-file", required_argument, NULL, CA_FILE_OPT },
  724. { "dh-file", required_argument, NULL, DH_FILE_OPT },
  725. { "proc-user", required_argument, NULL, PROC_USER_OPT },
  726. { "proc-group", required_argument, NULL, PROC_GROUP_OPT },
  727. { "mobility", optional_argument, NULL, MOBILITY_OPT },
  728. { "no-cli", optional_argument, NULL, NO_CLI_OPT },
  729. { "cli-ip", required_argument, NULL, CLI_IP_OPT },
  730. { "cli-port", required_argument, NULL, CLI_PORT_OPT },
  731. { "cli-password", required_argument, NULL, CLI_PASSWORD_OPT },
  732. { "server-relay", optional_argument, NULL, SERVER_RELAY_OPT },
  733. { "cli-max-output-sessions", required_argument, NULL, CLI_MAX_SESSIONS_OPT },
  734. { "ec-curve-name", required_argument, NULL, EC_CURVE_NAME_OPT },
  735. { "dh566", optional_argument, NULL, DH566_OPT },
  736. { "dh2066", optional_argument, NULL, DH2066_OPT },
  737. { "ne", required_argument, NULL, NE_TYPE_OPT },
  738. { "no-sslv2", optional_argument, NULL, NO_SSLV2_OPT }, /* deprecated */
  739. { "no-sslv3", optional_argument, NULL, NO_SSLV3_OPT },
  740. { "no-tlsv1", optional_argument, NULL, NO_TLSV1_OPT },
  741. { "no-tlsv1_1", optional_argument, NULL, NO_TLSV1_1_OPT },
  742. { "no-tlsv1_2", optional_argument, NULL, NO_TLSV1_2_OPT },
  743. { NULL, no_argument, NULL, 0 }
  744. };
  745. static const struct myoption admin_long_options[] = {
  746. {"generate-encrypted-password", no_argument, NULL, 'P' },
  747. { "key", no_argument, NULL, 'k' },
  748. { "add", no_argument, NULL, 'a' },
  749. { "delete", no_argument, NULL, 'd' },
  750. { "list", no_argument, NULL, 'l' },
  751. { "list-admin", no_argument, NULL, 'L' },
  752. { "set-secret", required_argument, NULL, 's' },
  753. { "show-secret", no_argument, NULL, 'S' },
  754. { "delete-secret", required_argument, NULL, 'X' },
  755. { "delete-all-secrets", no_argument, NULL, DEL_ALL_AUTH_SECRETS_OPT },
  756. { "add-admin", no_argument, NULL, 'A' },
  757. { "delete-admin", no_argument, NULL, 'D' },
  758. #if !defined(TURN_NO_SQLITE)
  759. { "userdb", required_argument, NULL, 'b' },
  760. { "db", required_argument, NULL, 'b' },
  761. #endif
  762. #if !defined(TURN_NO_PQ)
  763. { "psql-userdb", required_argument, NULL, 'e' },
  764. { "sql-userdb", required_argument, NULL, 'e' },
  765. #endif
  766. #if !defined(TURN_NO_MYSQL)
  767. { "mysql-userdb", required_argument, NULL, 'M' },
  768. #endif
  769. #if !defined(TURN_NO_MONGO)
  770. { "mongo-userdb", required_argument, NULL, 'J' },
  771. #endif
  772. #if !defined(TURN_NO_HIREDIS)
  773. { "redis-userdb", required_argument, NULL, 'N' },
  774. #endif
  775. { "user", required_argument, NULL, 'u' },
  776. { "realm", required_argument, NULL, 'r' },
  777. { "password", required_argument, NULL, 'p' },
  778. { "add-origin", no_argument, NULL, 'O' },
  779. { "del-origin", no_argument, NULL, 'R' },
  780. { "list-origins", required_argument, NULL, 'I' },
  781. { "origin", required_argument, NULL, 'o' },
  782. { "set-realm-option", no_argument, NULL, 'g' },
  783. { "list-realm-option", no_argument, NULL, 'G' },
  784. { "user-quota", required_argument, NULL, ADMIN_USER_QUOTA_OPT },
  785. { "total-quota", required_argument, NULL, ADMIN_TOTAL_QUOTA_OPT },
  786. { "max-bps", required_argument, NULL, ADMIN_MAX_BPS_OPT },
  787. { "help", no_argument, NULL, 'h' },
  788. { NULL, no_argument, NULL, 0 }
  789. };
  790. static int get_bool_value(const char* s)
  791. {
  792. if(!s || !(s[0])) return 1;
  793. if(s[0]=='0' || s[0]=='n' || s[0]=='N' || s[0]=='f' || s[0]=='F') return 0;
  794. if(s[0]=='y' || s[0]=='Y' || s[0]=='t' || s[0]=='T') return 1;
  795. if(s[0]>'0' && s[0]<='9') return 1;
  796. if(!strcmp(s,"off") || !strcmp(s,"OFF") || !strcmp(s,"Off")) return 0;
  797. if(!strcmp(s,"on") || !strcmp(s,"ON") || !strcmp(s,"On")) return 1;
  798. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown boolean value: %s. You can use on/off, yes/no, 1/0, true/false.\n",s);
  799. exit(-1);
  800. }
  801. static void set_option(int c, char *value)
  802. {
  803. if(value && value[0]=='=') {
  804. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option -%c is possibly used incorrectly. The short form of the option must be used as this: -%c <value>, no \'equals\' sign may be used, that sign is used only with long form options (like --user=<username>).\n",(char)c,(char)c);
  805. }
  806. switch (c) {
  807. case SERVER_NAME_OPT:
  808. STRCPY(turn_params.oauth_server_name,value);
  809. break;
  810. case OAUTH_OPT:
  811. if(!ENC_ALG_NUM) {
  812. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: option --oauth is not supported; ignored.\n");
  813. } else {
  814. turn_params.oauth = get_bool_value(value);
  815. }
  816. break;
  817. case NO_SSLV2_OPT:
  818. //deprecated
  819. break;
  820. case NO_SSLV3_OPT:
  821. turn_params.no_sslv3 = get_bool_value(value);
  822. break;
  823. case NO_TLSV1_OPT:
  824. turn_params.no_tlsv1 = get_bool_value(value);
  825. break;
  826. case NO_TLSV1_1_OPT:
  827. turn_params.no_tlsv1_1 = get_bool_value(value);
  828. break;
  829. case NO_TLSV1_2_OPT:
  830. turn_params.no_tlsv1_2 = get_bool_value(value);
  831. break;
  832. case NE_TYPE_OPT:
  833. {
  834. int ne = atoi(value);
  835. if((ne<(int)NEV_MIN)||(ne>(int)NEV_MAX)) {
  836. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: wrong version of the network engine: %d\n",ne);
  837. }
  838. turn_params.net_engine_version = (NET_ENG_VERSION)ne;
  839. }
  840. break;
  841. case DH566_OPT:
  842. if(get_bool_value(value))
  843. turn_params.dh_key_size = DH_566;
  844. break;
  845. case DH2066_OPT:
  846. if(get_bool_value(value))
  847. turn_params.dh_key_size = DH_2066;
  848. break;
  849. case EC_CURVE_NAME_OPT:
  850. STRCPY(turn_params.ec_curve_name,value);
  851. break;
  852. case CLI_MAX_SESSIONS_OPT:
  853. cli_max_output_sessions = atoi(value);
  854. break;
  855. case SERVER_RELAY_OPT:
  856. turn_params.server_relay = get_bool_value(value);
  857. break;
  858. case MOBILITY_OPT:
  859. turn_params.mobility = get_bool_value(value);
  860. break;
  861. case NO_CLI_OPT:
  862. use_cli = !get_bool_value(value);
  863. break;
  864. case CLI_IP_OPT:
  865. if(make_ioa_addr((const u08bits*)value,0,&cli_addr)<0) {
  866. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"Cannot set cli address: %s\n",value);
  867. } else{
  868. cli_addr_set = 1;
  869. }
  870. break;
  871. case CLI_PORT_OPT:
  872. cli_port = atoi(value);
  873. break;
  874. case CLI_PASSWORD_OPT:
  875. STRCPY(cli_password,value);
  876. break;
  877. case PROC_USER_OPT: {
  878. struct passwd* pwd = getpwnam(value);
  879. if(!pwd) {
  880. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown user name: %s\n",value);
  881. exit(-1);
  882. } else {
  883. procuserid = pwd->pw_uid;
  884. procuserid_set = 1;
  885. STRCPY(procusername,value);
  886. }
  887. }
  888. break;
  889. case PROC_GROUP_OPT: {
  890. struct group* gr = getgrnam(value);
  891. if(!gr) {
  892. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown group name: %s\n",value);
  893. exit(-1);
  894. } else {
  895. procgroupid = gr->gr_gid;
  896. procgroupid_set = 1;
  897. STRCPY(procgroupname,value);
  898. }
  899. }
  900. break;
  901. case 'i':
  902. STRCPY(turn_params.relay_ifname, value);
  903. break;
  904. case 'm':
  905. #if defined(OPENSSL_THREADS)
  906. if(atoi(value)>MAX_NUMBER_OF_GENERAL_RELAY_SERVERS) {
  907. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: max number of relay threads is 128.\n");
  908. turn_params.general_relay_servers_number = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS;
  909. } else if(atoi(value)<=0) {
  910. turn_params.general_relay_servers_number = 0;
  911. } else {
  912. turn_params.general_relay_servers_number = atoi(value);
  913. }
  914. #else
  915. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: OpenSSL version is too old OR does not support threading,\n I am using single thread for relaying.\n");
  916. #endif
  917. break;
  918. case 'd':
  919. STRCPY(turn_params.listener_ifname, value);
  920. break;
  921. case 'p':
  922. turn_params.listener_port = atoi(value);
  923. break;
  924. case TLS_PORT_OPT:
  925. turn_params.tls_listener_port = atoi(value);
  926. break;
  927. case ALT_PORT_OPT:
  928. turn_params.alt_listener_port = atoi(value);
  929. break;
  930. case ALT_TLS_PORT_OPT:
  931. turn_params.alt_tls_listener_port = atoi(value);
  932. break;
  933. case MIN_PORT_OPT:
  934. turn_params.min_port = atoi(value);
  935. break;
  936. case MAX_PORT_OPT:
  937. turn_params.max_port = atoi(value);
  938. break;
  939. case SECURE_STUN_OPT:
  940. turn_params.secure_stun = get_bool_value(value);
  941. break;
  942. case NO_MULTICAST_PEERS_OPT:
  943. turn_params.no_multicast_peers = get_bool_value(value);
  944. break;
  945. case NO_LOOPBACK_PEERS_OPT:
  946. turn_params.no_loopback_peers = get_bool_value(value);
  947. break;
  948. case STALE_NONCE_OPT:
  949. turn_params.stale_nonce = get_bool_value(value);
  950. break;
  951. case MAX_ALLOCATE_TIMEOUT_OPT:
  952. TURN_MAX_ALLOCATE_TIMEOUT = atoi(value);
  953. TURN_MAX_ALLOCATE_TIMEOUT_STUN_ONLY = atoi(value);
  954. break;
  955. case 'S':
  956. turn_params.stun_only = get_bool_value(value);
  957. break;
  958. case NO_STUN_OPT:
  959. turn_params.no_stun = get_bool_value(value);
  960. break;
  961. case 'L':
  962. add_listener_addr(value);
  963. break;
  964. case 'E':
  965. add_relay_addr(value);
  966. break;
  967. case 'X':
  968. if(value) {
  969. char *div = strchr(value,'/');
  970. if(div) {
  971. char *nval=turn_strdup(value);
  972. div = strchr(nval,'/');
  973. div[0]=0;
  974. ++div;
  975. ioa_addr apub,apriv;
  976. if(make_ioa_addr((const u08bits*)nval,0,&apub)<0) {
  977. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",nval);
  978. } else {
  979. if(make_ioa_addr((const u08bits*)div,0,&apriv)<0) {
  980. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",div);
  981. } else {
  982. ioa_addr_add_mapping(&apub,&apriv);
  983. }
  984. }
  985. turn_free(nval,strlen(nval)+1);
  986. } else {
  987. if(turn_params.external_ip) {
  988. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "You cannot define external IP more than once in the configuration\n");
  989. } else {
  990. turn_params.external_ip = (ioa_addr*)allocate_super_memory_engine(turn_params.listener.ioa_eng, sizeof(ioa_addr));
  991. if(make_ioa_addr((const u08bits*)value,0,turn_params.external_ip)<0) {
  992. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",value);
  993. turn_free(turn_params.external_ip,sizeof(ioa_addr));
  994. turn_params.external_ip = NULL;
  995. }
  996. }
  997. }
  998. }
  999. break;
  1000. case 'v':
  1001. if(get_bool_value(value)) {
  1002. turn_params.verbose = TURN_VERBOSE_NORMAL;
  1003. } else {
  1004. turn_params.verbose = TURN_VERBOSE_NONE;
  1005. }
  1006. break;
  1007. case 'V':
  1008. if(get_bool_value(value)) {
  1009. turn_params.verbose = TURN_VERBOSE_EXTRA;
  1010. }
  1011. break;
  1012. case 'o':
  1013. turn_params.turn_daemon = get_bool_value(value);
  1014. break;
  1015. case 'a':
  1016. if (get_bool_value(value)) {
  1017. turn_params.ct = TURN_CREDENTIALS_LONG_TERM;
  1018. use_lt_credentials=1;
  1019. } else {
  1020. turn_params.ct = TURN_CREDENTIALS_UNDEFINED;
  1021. use_lt_credentials=0;
  1022. }
  1023. break;
  1024. case 'z':
  1025. if (!get_bool_value(value)) {
  1026. turn_params.ct = TURN_CREDENTIALS_UNDEFINED;
  1027. anon_credentials = 0;
  1028. } else {
  1029. turn_params.ct = TURN_CREDENTIALS_NONE;
  1030. anon_credentials = 1;
  1031. }
  1032. break;
  1033. case 'f':
  1034. turn_params.fingerprint = get_bool_value(value);
  1035. break;
  1036. case 'u':
  1037. add_static_user_account(value);
  1038. break;
  1039. case 'b':
  1040. #if defined(TURN_NO_SQLITE)
  1041. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Options -b, --userdb and --db are not supported because SQLite is not supported in this build.\n");
  1042. #else
  1043. STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
  1044. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE;
  1045. #endif
  1046. break;
  1047. #if !defined(TURN_NO_PQ)
  1048. case 'e':
  1049. STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
  1050. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ;
  1051. break;
  1052. #endif
  1053. #if !defined(TURN_NO_MYSQL)
  1054. case 'M':
  1055. STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
  1056. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL;
  1057. break;
  1058. #endif
  1059. #if !defined(TURN_NO_MONGO)
  1060. case 'J':
  1061. STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
  1062. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO;
  1063. break;
  1064. #endif
  1065. #if !defined(TURN_NO_HIREDIS)
  1066. case 'N':
  1067. STRCPY(turn_params.default_users_db.persistent_users_db.userdb, value);
  1068. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS;
  1069. break;
  1070. case 'O':
  1071. STRCPY(turn_params.redis_statsdb, value);
  1072. turn_params.use_redis_statsdb = 1;
  1073. break;
  1074. #endif
  1075. case AUTH_SECRET_OPT:
  1076. turn_params.use_auth_secret_with_timestamp = 1;
  1077. break;
  1078. case STATIC_AUTH_SECRET_VAL_OPT:
  1079. add_to_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets,value);
  1080. turn_params.use_auth_secret_with_timestamp = 1;
  1081. break;
  1082. case AUTH_SECRET_TS_EXP:
  1083. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Option --secret-ts-exp-time deprecated and has no effect.\n");
  1084. break;
  1085. case 'r':
  1086. set_default_realm_name(value);
  1087. break;
  1088. case 'q':
  1089. turn_params.total_quota = (vint)atoi(value);
  1090. get_realm(NULL)->options.perf_options.user_quota = atoi(value);
  1091. break;
  1092. case 'Q':
  1093. turn_params.user_quota = (vint)atoi(value);
  1094. get_realm(NULL)->options.perf_options.total_quota = atoi(value);
  1095. break;
  1096. case 's':
  1097. turn_params.max_bps = (band_limit_t)strtoul(value,NULL,10);
  1098. get_realm(NULL)->options.perf_options.max_bps = (band_limit_t)strtoul(value,NULL,10);
  1099. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed per session\n",(unsigned long)turn_params.max_bps);
  1100. break;
  1101. case 'B':
  1102. turn_params.bps_capacity = (band_limit_t)strtoul(value,NULL,10);
  1103. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "%lu bytes per second allowed, combined server capacity\n",(unsigned long)turn_params.bps_capacity);
  1104. break;
  1105. case CHECK_ORIGIN_CONSISTENCY_OPT:
  1106. turn_params.check_origin = get_bool_value(value);
  1107. break;
  1108. case NO_UDP_OPT:
  1109. turn_params.no_udp = get_bool_value(value);
  1110. break;
  1111. case NO_TCP_OPT:
  1112. turn_params.no_tcp = get_bool_value(value);
  1113. break;
  1114. case NO_UDP_RELAY_OPT:
  1115. turn_params.no_udp_relay = get_bool_value(value);
  1116. break;
  1117. case NO_TCP_RELAY_OPT:
  1118. turn_params.no_tcp_relay = get_bool_value(value);
  1119. break;
  1120. case NO_TLS_OPT:
  1121. #if !TLS_SUPPORTED
  1122. turn_params.no_tls = 1;
  1123. #else
  1124. turn_params.no_tls = get_bool_value(value);
  1125. #endif
  1126. break;
  1127. case NO_DTLS_OPT:
  1128. #if DTLS_SUPPORTED
  1129. turn_params.no_dtls = get_bool_value(value);
  1130. #else
  1131. turn_params.no_dtls = 1;
  1132. #endif
  1133. break;
  1134. case CERT_FILE_OPT:
  1135. STRCPY(turn_params.cert_file,value);
  1136. break;
  1137. case CA_FILE_OPT:
  1138. STRCPY(turn_params.ca_cert_file,value);
  1139. break;
  1140. case DH_FILE_OPT:
  1141. STRCPY(turn_params.dh_file,value);
  1142. break;
  1143. case PKEY_FILE_OPT:
  1144. STRCPY(turn_params.pkey_file,value);
  1145. break;
  1146. case PKEY_PWD_OPT:
  1147. STRCPY(turn_params.tls_password,value);
  1148. break;
  1149. case ALTERNATE_SERVER_OPT:
  1150. add_alternate_server(value);
  1151. break;
  1152. case AUX_SERVER_OPT:
  1153. add_aux_server(value);
  1154. break;
  1155. case UDP_SELF_BALANCE_OPT:
  1156. turn_params.udp_self_balance = get_bool_value(value);
  1157. break;
  1158. case TLS_ALTERNATE_SERVER_OPT:
  1159. add_tls_alternate_server(value);
  1160. break;
  1161. case ALLOWED_PEER_IPS:
  1162. if (add_ip_list_range(value, NULL, &turn_params.ip_whitelist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "White listing: %s\n", value);
  1163. break;
  1164. case DENIED_PEER_IPS:
  1165. if (add_ip_list_range(value, NULL, &turn_params.ip_blacklist) == 0) TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Black listing: %s\n", value);
  1166. break;
  1167. case CIPHER_LIST_OPT:
  1168. STRCPY(turn_params.cipher_list,value);
  1169. break;
  1170. case PIDFILE_OPT:
  1171. STRCPY(turn_params.pidfile,value);
  1172. break;
  1173. case 'C':
  1174. if(value && *value) {
  1175. turn_params.rest_api_separator=*value;
  1176. }
  1177. break;
  1178. /* these options have been already taken care of before: */
  1179. case 'l':
  1180. case NO_STDOUT_LOG_OPT:
  1181. case SYSLOG_OPT:
  1182. case SIMPLE_LOG_OPT:
  1183. case 'c':
  1184. case 'n':
  1185. case 'h':
  1186. break;
  1187. default:
  1188. fprintf(stderr,"\n%s\n", Usage);
  1189. exit(-1);
  1190. }
  1191. }
  1192. static int parse_arg_string(char *sarg, int *c, char **value)
  1193. {
  1194. int i = 0;
  1195. char *name = sarg;
  1196. while(*sarg) {
  1197. if((*sarg==' ') || (*sarg=='=') || (*sarg=='\t')) {
  1198. *sarg=0;
  1199. do {
  1200. ++sarg;
  1201. } while((*sarg==' ') || (*sarg=='=') || (*sarg=='\t'));
  1202. *value = sarg;
  1203. break;
  1204. }
  1205. ++sarg;
  1206. *value=sarg;
  1207. }
  1208. if(value && *value && **value=='\"') {
  1209. *value += 1;
  1210. size_t len = strlen(*value);
  1211. while(len>0 && (
  1212. ((*value)[len-1]=='\n') ||
  1213. ((*value)[len-1]=='\r') ||
  1214. ((*value)[len-1]==' ') ||
  1215. ((*value)[len-1]=='\t')
  1216. ) ) {
  1217. (*value)[--len]=0;
  1218. }
  1219. if(len>0 && (*value)[len-1]=='\"') {
  1220. (*value)[--len]=0;
  1221. }
  1222. }
  1223. while(long_options[i].name) {
  1224. if(strcmp(long_options[i].name,name)) {
  1225. ++i;
  1226. continue;
  1227. }
  1228. *c=long_options[i].val;
  1229. return 0;
  1230. }
  1231. return -1;
  1232. }
  1233. static void read_config_file(int argc, char **argv, int pass)
  1234. {
  1235. static char config_file[1025] = DEFAULT_CONFIG_FILE;
  1236. if(pass == 0) {
  1237. if (argv) {
  1238. int i = 0;
  1239. for (i = 0; i < argc; i++) {
  1240. if (!strcmp(argv[i], "-c")) {
  1241. if (i < argc - 1) {
  1242. STRCPY(config_file, argv[i + 1]);
  1243. } else {
  1244. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Wrong usage of -c option\n");
  1245. }
  1246. } else if (!strcmp(argv[i], "-n")) {
  1247. turn_params.do_not_use_config_file = 1;
  1248. config_file[0]=0;
  1249. return;
  1250. } else if (!strcmp(argv[i], "-h")) {
  1251. printf("\n%s\n",Usage);
  1252. exit(0);
  1253. }
  1254. }
  1255. }
  1256. }
  1257. if (!turn_params.do_not_use_config_file && config_file[0]) {
  1258. FILE *f = NULL;
  1259. char *full_path_to_config_file = NULL;
  1260. full_path_to_config_file = find_config_file(config_file, 1);
  1261. if (full_path_to_config_file)
  1262. f = fopen(full_path_to_config_file, "r");
  1263. if (f && full_path_to_config_file) {
  1264. char sbuf[1025];
  1265. char sarg[1035];
  1266. for (;;) {
  1267. char *s = fgets(sbuf, sizeof(sbuf) - 1, f);
  1268. if (!s)
  1269. break;
  1270. s = skip_blanks(s);
  1271. if (s[0] == '#')
  1272. continue;
  1273. if (!s[0])
  1274. continue;
  1275. size_t slen = strlen(s);
  1276. while (slen && ((s[slen - 1] == 10) || (s[slen - 1] == 13)))
  1277. s[--slen] = 0;
  1278. if (slen) {
  1279. int c = 0;
  1280. char *value = NULL;
  1281. STRCPY(sarg, s);
  1282. if (parse_arg_string(sarg, &c, &value) < 0) {
  1283. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "Bad configuration format: %s\n",
  1284. sarg);
  1285. } else if((pass == 0) && (c == 'l')) {
  1286. set_logfile(value);
  1287. } else if((pass==0) && (c==NO_STDOUT_LOG_OPT)) {
  1288. set_no_stdout_log(get_bool_value(value));
  1289. } else if((pass==0) && (c==SYSLOG_OPT)) {
  1290. set_log_to_syslog(get_bool_value(value));
  1291. } else if((pass==0) && (c==SIMPLE_LOG_OPT)) {
  1292. set_simple_log(get_bool_value(value));
  1293. } else if((pass == 0) && (c != 'u')) {
  1294. set_option(c, value);
  1295. } else if((pass > 0) && (c == 'u')) {
  1296. set_option(c, value);
  1297. }
  1298. }
  1299. }
  1300. fclose(f);
  1301. } else
  1302. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: Cannot find config file: %s. Default and command-line settings will be used.\n",
  1303. config_file);
  1304. }
  1305. }
  1306. static int adminmain(int argc, char **argv)
  1307. {
  1308. int c = 0;
  1309. TURNADMIN_COMMAND_TYPE ct = TA_COMMAND_UNKNOWN;
  1310. int is_admin = 0;
  1311. u08bits user[STUN_MAX_USERNAME_SIZE+1]="\0";
  1312. u08bits realm[STUN_MAX_REALM_SIZE+1]="\0";
  1313. u08bits pwd[STUN_MAX_PWD_SIZE+1]="\0";
  1314. u08bits secret[AUTH_SECRET_SIZE+1]="\0";
  1315. u08bits origin[STUN_MAX_ORIGIN_SIZE+1]="\0";
  1316. perf_options_t po = {(band_limit_t)-1,-1,-1};
  1317. struct uoptions uo;
  1318. uo.u.m = admin_long_options;
  1319. int print_enc_password = 0;
  1320. while (((c = getopt_long(argc, argv, ADMIN_OPTIONS, uo.u.o, NULL)) != -1)) {
  1321. switch (c){
  1322. case 'P':
  1323. if(pwd[0]) {
  1324. char result[257];
  1325. generate_new_enc_password((char*)pwd, result);
  1326. printf("%s\n",result);
  1327. exit(0);
  1328. }
  1329. print_enc_password = 1;
  1330. break;
  1331. case 'g':
  1332. ct = TA_SET_REALM_OPTION;
  1333. break;
  1334. case 'G':
  1335. ct = TA_LIST_REALM_OPTIONS;
  1336. break;
  1337. case ADMIN_USER_QUOTA_OPT:
  1338. po.user_quota = (vint)atoi(optarg);
  1339. break;
  1340. case ADMIN_TOTAL_QUOTA_OPT:
  1341. po.total_quota = (vint)atoi(optarg);
  1342. break;
  1343. case ADMIN_MAX_BPS_OPT:
  1344. po.max_bps = (vint)atoi(optarg);
  1345. break;
  1346. case 'O':
  1347. ct = TA_ADD_ORIGIN;
  1348. break;
  1349. case 'R':
  1350. ct = TA_DEL_ORIGIN;
  1351. break;
  1352. case 'I':
  1353. ct = TA_LIST_ORIGINS;
  1354. break;
  1355. case 'o':
  1356. STRCPY(origin,optarg);
  1357. break;
  1358. case 'k':
  1359. ct = TA_PRINT_KEY;
  1360. break;
  1361. case 'a':
  1362. ct = TA_UPDATE_USER;
  1363. break;
  1364. case 'd':
  1365. ct = TA_DELETE_USER;
  1366. break;
  1367. case 'A':
  1368. ct = TA_UPDATE_USER;
  1369. is_admin = 1;
  1370. break;
  1371. case 'D':
  1372. ct = TA_DELETE_USER;
  1373. is_admin = 1;
  1374. break;
  1375. case 'l':
  1376. ct = TA_LIST_USERS;
  1377. break;
  1378. case 'L':
  1379. ct = TA_LIST_USERS;
  1380. is_admin = 1;
  1381. break;
  1382. case 's':
  1383. ct = TA_SET_SECRET;
  1384. STRCPY(secret,optarg);
  1385. break;
  1386. case 'S':
  1387. ct = TA_SHOW_SECRET;
  1388. break;
  1389. case 'X':
  1390. ct = TA_DEL_SECRET;
  1391. if(optarg)
  1392. STRCPY(secret,optarg);
  1393. break;
  1394. case DEL_ALL_AUTH_SECRETS_OPT:
  1395. ct = TA_DEL_SECRET;
  1396. break;
  1397. #if !defined(TURN_NO_SQLITE)
  1398. case 'b':
  1399. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
  1400. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_SQLITE;
  1401. break;
  1402. #endif
  1403. #if !defined(TURN_NO_PQ)
  1404. case 'e':
  1405. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
  1406. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_PQ;
  1407. break;
  1408. #endif
  1409. #if !defined(TURN_NO_MYSQL)
  1410. case 'M':
  1411. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
  1412. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MYSQL;
  1413. break;
  1414. #endif
  1415. #if !defined(TURN_NO_MONGO)
  1416. case 'J':
  1417. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
  1418. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_MONGO;
  1419. break;
  1420. #endif
  1421. #if !defined(TURN_NO_HIREDIS)
  1422. case 'N':
  1423. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,optarg);
  1424. turn_params.default_users_db.userdb_type = TURN_USERDB_TYPE_REDIS;
  1425. break;
  1426. #endif
  1427. case 'u':
  1428. STRCPY(user,optarg);
  1429. if(!is_secure_username((u08bits*)user)) {
  1430. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name structure or symbols, choose another name: %s\n",user);
  1431. exit(-1);
  1432. }
  1433. if(SASLprep((u08bits*)user)<0) {
  1434. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong user name: %s\n",user);
  1435. exit(-1);
  1436. }
  1437. break;
  1438. case 'r':
  1439. set_default_realm_name(optarg);
  1440. STRCPY(realm,optarg);
  1441. if(SASLprep((u08bits*)realm)<0) {
  1442. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong realm: %s\n",realm);
  1443. exit(-1);
  1444. }
  1445. break;
  1446. case 'p':
  1447. STRCPY(pwd,optarg);
  1448. if(SASLprep((u08bits*)pwd)<0) {
  1449. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong password: %s\n",pwd);
  1450. exit(-1);
  1451. }
  1452. if(print_enc_password) {
  1453. char result[257];
  1454. generate_new_enc_password((char*)pwd, result);
  1455. printf("%s\n",result);
  1456. exit(0);
  1457. }
  1458. break;
  1459. case 'h':
  1460. printf("\n%s\n", AdminUsage);
  1461. exit(0);
  1462. break;
  1463. default:
  1464. fprintf(stderr,"\n%s\n", AdminUsage);
  1465. exit(-1);
  1466. }
  1467. }
  1468. #if !defined(TURN_NO_SQLITE)
  1469. if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE))
  1470. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE);
  1471. #endif
  1472. if(ct == TA_COMMAND_UNKNOWN) {
  1473. fprintf(stderr,"\n%s\n", AdminUsage);
  1474. exit(-1);
  1475. }
  1476. argc -= optind;
  1477. argv += optind;
  1478. if(argc != 0) {
  1479. fprintf(stderr,"\n%s\n", AdminUsage);
  1480. exit(-1);
  1481. }
  1482. return adminuser(user, realm, pwd, secret, origin, ct, &po, is_admin);
  1483. }
  1484. static void print_features(unsigned long mfn)
  1485. {
  1486. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nRFC 3489/5389/5766/5780/6062/6156 STUN/TURN Server\nVersion %s\n",TURN_SOFTWARE);
  1487. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nMax number of open files/sockets allowed for this process: %lu\n",mfn);
  1488. if(turn_params.net_engine_version == NEV_UDP_SOCKET_PER_ENDPOINT)
  1489. mfn = mfn/3;
  1490. else
  1491. mfn = mfn/2;
  1492. mfn = ((unsigned long)(mfn/500))*500;
  1493. if(mfn<500)
  1494. mfn = 500;
  1495. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nDue to the open files/sockets limitation,\nmax supported number of TURN Sessions possible is: %lu (approximately)\n",mfn);
  1496. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n\n==== Show him the instruments, Practical Frost: ====\n\n");
  1497. /*
  1498. Frost stepped forward and opened the polished case with a theatrical
  1499. flourish. It was a masterful piece of craftsmanship. As the lid was
  1500. pulled back, the many trays inside lifted and fanned out, displaying
  1501. Glokta’s tools in all their gruesome glory. There were blades of every
  1502. size and shape, needles curved and straight, bottles of oil and acid,
  1503. nails and screws, clamps and pliers, saws, hammers, chisels. Metal, wood
  1504. and glass glittered in the bright lamplight, all polished to mirror
  1505. brightness and honed to a murderous sharpness.
  1506. */
  1507. #if !TLS_SUPPORTED
  1508. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS is not supported\n");
  1509. #else
  1510. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS supported\n");
  1511. #endif
  1512. #if !DTLS_SUPPORTED
  1513. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS is not supported\n");
  1514. #else
  1515. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS supported\n");
  1516. #if DTLSv1_2_SUPPORTED
  1517. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 supported\n");
  1518. #else
  1519. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS 1.2 is not supported\n");
  1520. #endif
  1521. #endif
  1522. #if ALPN_SUPPORTED
  1523. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN supported\n");
  1524. #else
  1525. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TURN/STUN ALPN is not supported\n");
  1526. #endif
  1527. if(!ENC_ALG_NUM) {
  1528. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) is not supported\n");
  1529. } else {
  1530. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Third-party authorization (oAuth) supported\n");
  1531. #if defined(TURN_NO_GCM)
  1532. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) is not supported\n");
  1533. #else
  1534. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "GCM (AEAD) supported\n");
  1535. #endif
  1536. }
  1537. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "OpenSSL compile-time version: %s\n",OPENSSL_VERSION_TEXT);
  1538. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n");
  1539. #if !defined(TURN_NO_SQLITE)
  1540. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite supported, default database location is %s\n",DEFAULT_USERDB_FILE);
  1541. #else
  1542. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "SQLite is not supported\n");
  1543. #endif
  1544. #if !defined(TURN_NO_HIREDIS)
  1545. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis supported\n");
  1546. #else
  1547. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Redis is not supported\n");
  1548. #endif
  1549. #if !defined(TURN_NO_PQ)
  1550. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL supported\n");
  1551. #else
  1552. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "PostgreSQL is not supported\n");
  1553. #endif
  1554. #if !defined(TURN_NO_MYSQL)
  1555. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL supported\n");
  1556. #else
  1557. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL is not supported\n");
  1558. #endif
  1559. #if !defined(TURN_NO_MONGO)
  1560. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB supported\n");
  1561. #else
  1562. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MongoDB is not supported\n");
  1563. #endif
  1564. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\n");
  1565. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default Net Engine version: %d (%s)\n\n=====================================================\n\n", (int)turn_params.net_engine_version, turn_params.net_engine_version_txt[(int)turn_params.net_engine_version]);
  1566. }
  1567. #if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__)
  1568. #include <linux/version.h>
  1569. #endif
  1570. static void set_network_engine(void)
  1571. {
  1572. if(turn_params.net_engine_version != NEV_UNKNOWN)
  1573. return;
  1574. turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT;
  1575. #if defined(SO_REUSEPORT)
  1576. #if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__)
  1577. turn_params.net_engine_version = NEV_UDP_SOCKET_PER_THREAD;
  1578. #else /* BSD ? */
  1579. turn_params.net_engine_version = NEV_UDP_SOCKET_PER_SESSION;
  1580. #endif /* Linux */
  1581. #else /* defined(SO_REUSEPORT) */
  1582. #if defined(__linux__) || defined(__LINUX__) || defined(__linux) || defined(linux__) || defined(LINUX) || defined(__LINUX) || defined(LINUX__)
  1583. #if LINUX_VERSION_CODE >= KERNEL_VERSION(2,6,33)
  1584. //net_engine_version = NEV_UDP_SOCKET_PER_SESSION;
  1585. turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT;
  1586. #else
  1587. turn_params.net_engine_version = NEV_UDP_SOCKET_PER_ENDPOINT;
  1588. #endif /* Linux version */
  1589. #endif /* Linux */
  1590. #endif /* defined(SO_REUSEPORT) */
  1591. }
  1592. static void drop_privileges(void)
  1593. {
  1594. if(procgroupid_set) {
  1595. if(getgid() != procgroupid) {
  1596. if (setgid(procgroupid) != 0) {
  1597. perror("setgid: Unable to change group privileges");
  1598. exit(-1);
  1599. } else {
  1600. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid);
  1601. }
  1602. } else {
  1603. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep GID: %s(%lu)\n", procgroupname, (unsigned long)procgroupid);
  1604. }
  1605. }
  1606. if(procuserid_set) {
  1607. if(procuserid != getuid()) {
  1608. if (setuid(procuserid) != 0) {
  1609. perror("setuid: Unable to change user privileges");
  1610. exit(-1);
  1611. } else {
  1612. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "New UID: %s(%lu)\n", procusername, (unsigned long)procuserid);
  1613. }
  1614. } else {
  1615. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Keep UID: %s(%lu)\n", procusername, (unsigned long)procuserid);
  1616. }
  1617. }
  1618. }
  1619. static void init_domain(void)
  1620. {
  1621. #if !defined(TURN_NO_GETDOMAINNAME)
  1622. if(getdomainname(turn_params.domain,sizeof(turn_params.domain)-1)<0) {
  1623. turn_params.domain[0]=0;
  1624. } else if(!strcmp(turn_params.domain,"(none)")) {
  1625. turn_params.domain[0]=0;
  1626. }
  1627. #endif
  1628. }
  1629. int main(int argc, char **argv)
  1630. {
  1631. int c = 0;
  1632. IS_TURN_SERVER = 1;
  1633. set_execdir();
  1634. init_super_memory();
  1635. #if !defined(TURN_NO_HIREDIS)
  1636. redis_async_init();
  1637. #endif
  1638. init_domain();
  1639. create_default_realm();
  1640. init_turn_server_addrs_list(&turn_params.alternate_servers_list);
  1641. init_turn_server_addrs_list(&turn_params.tls_alternate_servers_list);
  1642. init_turn_server_addrs_list(&turn_params.aux_servers_list);
  1643. set_network_engine();
  1644. init_listener();
  1645. init_secrets_list(&turn_params.default_users_db.ram_db.static_auth_secrets);
  1646. init_dynamic_ip_lists();
  1647. if (!strstr(argv[0], "turnadmin")) {
  1648. struct uoptions uo;
  1649. uo.u.m = long_options;
  1650. while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) {
  1651. switch (c){
  1652. case 'l':
  1653. set_logfile(optarg);
  1654. break;
  1655. case NO_STDOUT_LOG_OPT:
  1656. set_no_stdout_log(get_bool_value(optarg));
  1657. break;
  1658. case SYSLOG_OPT:
  1659. set_log_to_syslog(get_bool_value(optarg));
  1660. break;
  1661. case SIMPLE_LOG_OPT:
  1662. set_simple_log(get_bool_value(optarg));
  1663. break;
  1664. default:
  1665. ;
  1666. }
  1667. }
  1668. }
  1669. optind = 0;
  1670. #if !TLS_SUPPORTED
  1671. turn_params.no_tls = 1;
  1672. #endif
  1673. #if !DTLS_SUPPORTED
  1674. turn_params.no_dtls = 1;
  1675. #endif
  1676. #if defined(_SC_NPROCESSORS_ONLN)
  1677. {
  1678. turn_params.cpus = (long)sysconf(_SC_NPROCESSORS_CONF);
  1679. if(turn_params.cpus<DEFAULT_CPUS_NUMBER)
  1680. turn_params.cpus = DEFAULT_CPUS_NUMBER;
  1681. else if(turn_params.cpus>MAX_NUMBER_OF_GENERAL_RELAY_SERVERS)
  1682. turn_params.cpus = MAX_NUMBER_OF_GENERAL_RELAY_SERVERS;
  1683. turn_params.general_relay_servers_number = (turnserver_id)turn_params.cpus;
  1684. }
  1685. #endif
  1686. ns_bzero(&turn_params.default_users_db,sizeof(default_users_db_t));
  1687. turn_params.default_users_db.ram_db.static_accounts = ur_string_map_create(turn_free_simple);
  1688. if(strstr(argv[0],"turnadmin"))
  1689. return adminmain(argc,argv);
  1690. {
  1691. unsigned long mfn = set_system_parameters(1);
  1692. print_features(mfn);
  1693. }
  1694. read_config_file(argc,argv,0);
  1695. struct uoptions uo;
  1696. uo.u.m = long_options;
  1697. while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) {
  1698. if(c != 'u')
  1699. set_option(c,optarg);
  1700. }
  1701. read_config_file(argc,argv,1);
  1702. if(!get_realm(NULL)->options.name[0]) {
  1703. STRCPY(get_realm(NULL)->options.name,turn_params.domain);
  1704. }
  1705. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Domain name: %s\n",turn_params.domain);
  1706. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Default realm: %s\n",get_realm(NULL)->options.name);
  1707. if(turn_params.oauth && turn_params.oauth_server_name[0]) {
  1708. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "oAuth server name: %s\n",turn_params.oauth_server_name);
  1709. }
  1710. optind = 0;
  1711. while (((c = getopt_long(argc, argv, OPTIONS, uo.u.o, NULL)) != -1)) {
  1712. if(c == 'u') {
  1713. set_option(c,optarg);
  1714. }
  1715. }
  1716. if(turn_params.bps_capacity && !(turn_params.max_bps)) {
  1717. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: If you set the --bps-capacity option, then you must set --max-bps options, too.\n");
  1718. exit(-1);
  1719. }
  1720. if(turn_params.no_udp_relay && turn_params.no_tcp_relay) {
  1721. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: --no-udp-relay and --no-tcp-relay options cannot be used together.\n");
  1722. exit(-1);
  1723. }
  1724. if(turn_params.no_udp_relay) {
  1725. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-udp-relay: UDP relay endpoints are not allowed.\n");
  1726. }
  1727. if(turn_params.no_tcp_relay) {
  1728. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "\nCONFIG: --no-tcp-relay: TCP relay endpoints are not allowed.\n");
  1729. }
  1730. if(turn_params.server_relay) {
  1731. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIG: WARNING: --server-relay: NON-STANDARD AND DANGEROUS OPTION.\n");
  1732. }
  1733. #if !defined(TURN_NO_SQLITE)
  1734. if(!strlen(turn_params.default_users_db.persistent_users_db.userdb) && (turn_params.default_users_db.userdb_type == TURN_USERDB_TYPE_SQLITE))
  1735. STRCPY(turn_params.default_users_db.persistent_users_db.userdb,DEFAULT_USERDB_FILE);
  1736. #endif
  1737. argc -= optind;
  1738. argv += optind;
  1739. if(argc>0) {
  1740. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIGURATION ALERT: Unknown argument: %s\n",argv[argc-1]);
  1741. }
  1742. if(use_lt_credentials && anon_credentials) {
  1743. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "\nCONFIG ERROR: -a and -z options cannot be used together.\n");
  1744. exit(-1);
  1745. }
  1746. if(!use_lt_credentials && !anon_credentials) {
  1747. if(turn_params.default_users_db.ram_db.users_number) {
  1748. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you specified long-term user accounts, (-u option) \n but you did not specify the long-term credentials option\n (-a or --lt-cred-mech option).\n I am turning --lt-cred-mech ON for you, but double-check your configuration.\n");
  1749. turn_params.ct = TURN_CREDENTIALS_LONG_TERM;
  1750. use_lt_credentials=1;
  1751. } else {
  1752. turn_params.ct = TURN_CREDENTIALS_NONE;
  1753. use_lt_credentials=0;
  1754. }
  1755. }
  1756. if(use_lt_credentials) {
  1757. if(!get_realm(NULL)->options.name[0]) {
  1758. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you did specify the long-term credentials usage\n but you did not specify the default realm option (-r option).\n Check your configuration.\n");
  1759. }
  1760. }
  1761. if(anon_credentials) {
  1762. if(turn_params.default_users_db.ram_db.users_number) {
  1763. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "\nCONFIGURATION ALERT: you specified user accounts, (-u option) \n but you also specified the anonymous user access option (-z or --no-auth option).\n User accounts will be ignored.\n");
  1764. turn_params.ct = TURN_CREDENTIALS_NONE;
  1765. use_lt_credentials=0;
  1766. }
  1767. }
  1768. openssl_setup();
  1769. int local_listeners = 0;
  1770. if (!turn_params.listener.addrs_number) {
  1771. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "NO EXPLICIT LISTENER ADDRESS(ES) ARE CONFIGURED\n");
  1772. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "===========Discovering listener addresses: =========\n");
  1773. int maddrs = make_local_listeners_list();
  1774. if((maddrs<1) || !turn_params.listener.addrs_number) {
  1775. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: Cannot configure any meaningful IP listener address\n", __FUNCTION__);
  1776. fprintf(stderr,"\n%s\n", Usage);
  1777. exit(-1);
  1778. }
  1779. local_listeners = 1;
  1780. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n");
  1781. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total: %d 'real' addresses discovered\n",maddrs);
  1782. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n");
  1783. }
  1784. if (!turn_params.relays_number) {
  1785. if(!local_listeners && turn_params.listener.addrs_number && turn_params.listener.addrs) {
  1786. size_t la = 0;
  1787. for(la=0;la<turn_params.listener.addrs_number;la++) {
  1788. if(turn_params.listener.addrs[la]) {
  1789. add_relay_addr(turn_params.listener.addrs[la]);
  1790. }
  1791. }
  1792. }
  1793. if (!turn_params.relays_number) {
  1794. turn_params.default_relays = 1;
  1795. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "NO EXPLICIT RELAY ADDRESS(ES) ARE CONFIGURED\n");
  1796. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "===========Discovering relay addresses: =============\n");
  1797. if(make_local_relays_list(0,AF_INET)<1) {
  1798. make_local_relays_list(1,AF_INET);
  1799. }
  1800. if(make_local_relays_list(0,AF_INET6)<1) {
  1801. make_local_relays_list(1,AF_INET6);
  1802. }
  1803. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n");
  1804. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "Total: %d relay addresses discovered\n",(int)turn_params.relays_number);
  1805. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "=====================================================\n");
  1806. }
  1807. if (!turn_params.relays_number) {
  1808. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: You must specify the relay address(es)\n",
  1809. __FUNCTION__);
  1810. fprintf(stderr,"\n%s\n", Usage);
  1811. exit(-1);
  1812. }
  1813. }
  1814. if(turn_params.external_ip && turn_params.relay_addrs) {
  1815. size_t ir = 0;
  1816. for(ir = 0; ir < turn_params.relays_number; ++ir) {
  1817. if(turn_params.relay_addrs[ir]) {
  1818. const char* sra = (const char*)turn_params.relay_addrs[ir];
  1819. if((strstr(sra,"127.0.0.1") != sra)&&(strstr(sra,"::1")!=sra)) {
  1820. ioa_addr ra;
  1821. if(make_ioa_addr((const u08bits*)sra,0,&ra)<0) {
  1822. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"-X : Wrong address format: %s\n",sra);
  1823. } else if(ra.ss.sa_family == turn_params.external_ip->ss.sa_family) {
  1824. ioa_addr_add_mapping(turn_params.external_ip,&ra);
  1825. }
  1826. }
  1827. }
  1828. }
  1829. }
  1830. if(turn_params.turn_daemon) {
  1831. #if !defined(TURN_HAS_DAEMON)
  1832. pid_t pid = fork();
  1833. if(pid>0)
  1834. exit(0);
  1835. if(pid<0) {
  1836. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n");
  1837. exit(-1);
  1838. }
  1839. #else
  1840. if(daemon(1,0)<0) {
  1841. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: Cannot start daemon process\n");
  1842. exit(-1);
  1843. }
  1844. reset_rtpprintf();
  1845. #endif
  1846. }
  1847. if(turn_params.pidfile[0]) {
  1848. char s[2049];
  1849. FILE *f = fopen(turn_params.pidfile,"w");
  1850. if(f) {
  1851. STRCPY(s,turn_params.pidfile);
  1852. } else {
  1853. snprintf(s,sizeof(s),"Cannot create pid file: %s",turn_params.pidfile);
  1854. perror(s);
  1855. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "%s\n", s);
  1856. {
  1857. const char *pfs[] = {"/var/run/turnserver.pid",
  1858. "/var/spool/turnserver.pid",
  1859. "/var/turnserver.pid",
  1860. "/var/tmp/turnserver.pid",
  1861. "/tmp/turnserver.pid",
  1862. "turnserver.pid",
  1863. NULL};
  1864. const char **ppfs = pfs;
  1865. while(*ppfs) {
  1866. f = fopen(*ppfs,"w");
  1867. if(f) {
  1868. STRCPY(s,*ppfs);
  1869. break;
  1870. } else {
  1871. ++ppfs;
  1872. }
  1873. }
  1874. }
  1875. }
  1876. if(f) {
  1877. fprintf(f,"%lu\n",(unsigned long)getpid());
  1878. fclose(f);
  1879. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "pid file created: %s\n", s);
  1880. }
  1881. }
  1882. setup_server();
  1883. drop_privileges();
  1884. run_listener_server(&(turn_params.listener));
  1885. return 0;
  1886. }
  1887. ////////// OpenSSL locking ////////////////////////////////////////
  1888. #if defined(OPENSSL_THREADS)
  1889. static char some_buffer[65536];
  1890. //array larger than anything that OpenSSL may need:
  1891. static pthread_mutex_t mutex_buf[256];
  1892. static int mutex_buf_initialized = 0;
  1893. static void locking_function(int mode, int n, const char *file, int line) {
  1894. UNUSED_ARG(file);
  1895. UNUSED_ARG(line);
  1896. if(mutex_buf_initialized && (n < CRYPTO_num_locks())) {
  1897. if (mode & CRYPTO_LOCK)
  1898. pthread_mutex_lock(&(mutex_buf[n]));
  1899. else
  1900. pthread_mutex_unlock(&(mutex_buf[n]));
  1901. }
  1902. }
  1903. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1904. static void id_function(CRYPTO_THREADID *ctid)
  1905. {
  1906. CRYPTO_THREADID_set_numeric(ctid, (unsigned long)pthread_self());
  1907. }
  1908. #else
  1909. static unsigned long id_function(void)
  1910. {
  1911. return (unsigned long)pthread_self();
  1912. }
  1913. #endif
  1914. #endif
  1915. static int THREAD_setup(void) {
  1916. #if defined(OPENSSL_THREADS)
  1917. int i;
  1918. some_buffer[0] = 0;
  1919. for (i = 0; i < CRYPTO_num_locks(); i++) {
  1920. pthread_mutex_init(&(mutex_buf[i]), NULL);
  1921. }
  1922. mutex_buf_initialized = 1;
  1923. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1924. CRYPTO_THREADID_set_callback(id_function);
  1925. #else
  1926. CRYPTO_set_id_callback(id_function);
  1927. #endif
  1928. CRYPTO_set_locking_callback(locking_function);
  1929. #endif
  1930. return 1;
  1931. }
  1932. int THREAD_cleanup(void);
  1933. int THREAD_cleanup(void) {
  1934. #if defined(OPENSSL_THREADS)
  1935. int i;
  1936. if (!mutex_buf_initialized)
  1937. return 0;
  1938. #if OPENSSL_VERSION_NUMBER >= 0x10000000L
  1939. CRYPTO_THREADID_set_callback(NULL);
  1940. #else
  1941. CRYPTO_set_id_callback(NULL);
  1942. #endif
  1943. CRYPTO_set_locking_callback(NULL);
  1944. for (i = 0; i < CRYPTO_num_locks(); i++) {
  1945. pthread_mutex_destroy(&(mutex_buf[i]));
  1946. }
  1947. mutex_buf_initialized = 0;
  1948. #endif
  1949. return 1;
  1950. }
  1951. static void adjust_key_file_name(char *fn, const char* file_title, int critical)
  1952. {
  1953. char *full_path_to_file = NULL;
  1954. if(!fn[0]) {
  1955. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"\nERROR: you must set the %s file parameter\n",file_title);
  1956. goto keyerr;
  1957. } else {
  1958. full_path_to_file = find_config_file(fn, 1);
  1959. {
  1960. FILE *f = full_path_to_file ? fopen(full_path_to_file,"r") : NULL;
  1961. if(!f) {
  1962. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot find %s file: %s (1)\n",file_title,fn);
  1963. goto keyerr;
  1964. } else {
  1965. fclose(f);
  1966. }
  1967. }
  1968. if(!full_path_to_file) {
  1969. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot find %s file: %s (2)\n",file_title,fn);
  1970. goto keyerr;
  1971. }
  1972. strncpy(fn,full_path_to_file,sizeof(turn_params.cert_file)-1);
  1973. fn[sizeof(turn_params.cert_file)-1]=0;
  1974. if(full_path_to_file)
  1975. turn_free(full_path_to_file,strlen(full_path_to_file)+1);
  1976. return;
  1977. }
  1978. keyerr:
  1979. {
  1980. if(critical) {
  1981. turn_params.no_tls = 1;
  1982. turn_params.no_dtls = 1;
  1983. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"WARNING: cannot start TLS and DTLS listeners because %s file is not set properly\n",file_title);
  1984. }
  1985. if(full_path_to_file)
  1986. turn_free(full_path_to_file,strlen(full_path_to_file)+1);
  1987. return;
  1988. }
  1989. }
  1990. static void adjust_key_file_names(void)
  1991. {
  1992. if(turn_params.ca_cert_file[0])
  1993. adjust_key_file_name(turn_params.ca_cert_file,"CA",1);
  1994. adjust_key_file_name(turn_params.cert_file,"certificate",1);
  1995. adjust_key_file_name(turn_params.pkey_file,"private key",1);
  1996. if(turn_params.dh_file[0])
  1997. adjust_key_file_name(turn_params.dh_file,"DH key",0);
  1998. }
  1999. static DH *get_dh566(void) {
  2000. unsigned char dh566_p[] = {
  2001. 0x36,0x53,0xA8,0x9C,0x3C,0xF1,0xD1,0x1B,0x2D,0xA2,0x64,0xDE,
  2002. 0x59,0x3B,0xE3,0x8C,0x27,0x74,0xC2,0xBE,0x9B,0x6D,0x56,0xE7,
  2003. 0xDF,0xFF,0x67,0x6A,0xD2,0x0C,0xE8,0x9E,0x52,0x00,0x05,0xB3,
  2004. 0x53,0xF7,0x1C,0x41,0xB2,0xAC,0x38,0x16,0x32,0x3A,0x8E,0x90,
  2005. 0x6C,0x7E,0xD1,0x44,0xCB,0xF9,0x2D,0x1E,0x4A,0x9A,0x32,0x81,
  2006. 0x58,0xE1,0xE1,0x17,0xC1,0x9C,0xF1,0x1E,0x96,0x2D,0x5F
  2007. };
  2008. // -----BEGIN DH PARAMETERS-----
  2009. //MEwCRzZTqJw88dEbLaJk3lk744wndMK+m21W59//Z2rSDOieUgAFs1P3HEGyrDgW
  2010. //MjqOkGx+0UTL+S0eSpoygVjh4RfBnPEeli1fAgEF
  2011. // -----END DH PARAMETERS-----
  2012. unsigned char dh566_g[] = { 0x05 };
  2013. DH *dh;
  2014. if ((dh = DH_new()) == NULL )
  2015. return (NULL );
  2016. dh->p = BN_bin2bn(dh566_p, sizeof(dh566_p), NULL );
  2017. dh->g = BN_bin2bn(dh566_g, sizeof(dh566_g), NULL );
  2018. if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);}
  2019. return (dh);
  2020. }
  2021. static DH *get_dh1066(void) {
  2022. unsigned char dh1066_p[] = {
  2023. 0x02,0x0E,0x26,0x6F,0xAA,0x9F,0xA8,0xE5,0x3F,0x70,0x88,0xF1,
  2024. 0xA9,0x29,0xAE,0x1A,0x2B,0xA8,0x2F,0xE8,0xE5,0x0E,0x81,0x78,
  2025. 0xD7,0x12,0x41,0xDC,0xE2,0xD5,0x10,0x6F,0x8A,0x35,0x23,0xCE,
  2026. 0x66,0x93,0x67,0x14,0xEA,0x0A,0x61,0xD4,0x43,0x63,0x5C,0xDF,
  2027. 0xDE,0xF5,0xB9,0xC6,0xB4,0x8C,0xBA,0x1A,0x25,0x9F,0x73,0x0F,
  2028. 0x1E,0x1A,0x97,0x42,0x2E,0x60,0x9E,0x4C,0x3C,0x70,0x6A,0xFB,
  2029. 0xDD,0xAA,0x7A,0x48,0xA5,0x1E,0x87,0xC8,0xA3,0x5E,0x26,0x40,
  2030. 0x1B,0xDE,0x08,0x5E,0xA2,0xB8,0xE8,0x76,0x43,0xE8,0xF1,0x4B,
  2031. 0x35,0x4C,0x38,0x92,0xB9,0xFF,0x61,0xE6,0x6C,0xBA,0xF9,0x16,
  2032. 0x36,0x3C,0x69,0x2D,0x57,0x90,0x62,0x8A,0xD0,0xD4,0xFB,0xB2,
  2033. 0x5A,0x61,0x99,0xA9,0xE8,0x93,0x80,0xA2,0xB7,0xDC,0xB1,0x6A,
  2034. 0xAF,0xE3
  2035. };
  2036. // -----BEGIN DH PARAMETERS-----
  2037. // MIGMAoGGAg4mb6qfqOU/cIjxqSmuGiuoL+jlDoF41xJB3OLVEG+KNSPOZpNnFOoK
  2038. // YdRDY1zf3vW5xrSMuholn3MPHhqXQi5gnkw8cGr73ap6SKUeh8ijXiZAG94IXqK4
  2039. // 6HZD6PFLNUw4krn/YeZsuvkWNjxpLVeQYorQ1PuyWmGZqeiTgKK33LFqr+MCAQI=
  2040. // -----END DH PARAMETERS-----
  2041. unsigned char dh1066_g[] = { 0x02 };
  2042. DH *dh;
  2043. if ((dh = DH_new()) == NULL )
  2044. return (NULL );
  2045. dh->p = BN_bin2bn(dh1066_p, sizeof(dh1066_p), NULL );
  2046. dh->g = BN_bin2bn(dh1066_g, sizeof(dh1066_g), NULL );
  2047. if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);}
  2048. return (dh);
  2049. }
  2050. static DH *get_dh2066(void) {
  2051. unsigned char dh2066_p[] = {
  2052. 0x03,0x31,0x77,0x20,0x58,0xA6,0x69,0xA3,0x9D,0x2D,0x5E,0xE0,
  2053. 0x5C,0x46,0x82,0x0F,0x9E,0x80,0xF0,0x00,0x2A,0xF9,0x0F,0x62,
  2054. 0x1F,0x89,0xCE,0x7D,0x2A,0xFD,0xC5,0x9A,0x7C,0x6A,0x60,0x2C,
  2055. 0xF1,0xDD,0xD4,0x4D,0x6B,0xCD,0xE9,0x95,0xDB,0x42,0x97,0xBA,
  2056. 0xE4,0xAF,0x41,0x38,0x8F,0x57,0x31,0xA4,0x39,0xDD,0x31,0xC3,
  2057. 0x6F,0x98,0x0E,0xE3,0xB1,0x43,0xD1,0x36,0xB0,0x01,0x28,0x42,
  2058. 0x71,0xD3,0xB0,0x36,0xA0,0x47,0x99,0x25,0x9B,0x32,0xF5,0x86,
  2059. 0xB1,0x13,0x5C,0x24,0x8D,0x8D,0x7F,0xE2,0x7F,0x9A,0xC1,0x52,
  2060. 0x58,0xC0,0x63,0xAA,0x00,0x7C,0x1F,0x11,0xBD,0xAC,0x4C,0x2D,
  2061. 0xE0,0xA2,0x9D,0x4E,0x21,0xE4,0x0B,0xCD,0x24,0x92,0xD2,0x37,
  2062. 0x27,0x84,0x59,0x90,0x46,0x2F,0xD5,0xB9,0x27,0x93,0x18,0x88,
  2063. 0xBD,0x91,0x5B,0x87,0x55,0x56,0xD8,0x1B,0xE4,0xCF,0x1C,0xAA,
  2064. 0xBC,0xCF,0x80,0x1E,0x35,0x2D,0xB1,0xBC,0x35,0x31,0x92,0x62,
  2065. 0x3C,0x91,0x8D,0x62,0xDA,0xCF,0x83,0x63,0x12,0x4B,0x30,0x80,
  2066. 0xEE,0x82,0x3C,0x2C,0xD2,0x17,0x13,0x1F,0xF9,0x62,0x33,0x5C,
  2067. 0x63,0xD8,0x75,0x5B,0xAA,0x16,0x5A,0x36,0x49,0x17,0x77,0xB7,
  2068. 0x74,0xBD,0x3E,0x3F,0x98,0x20,0x59,0x5E,0xC7,0x72,0xE8,0xA3,
  2069. 0x89,0x21,0xB4,0x3C,0x25,0xF4,0xF4,0x21,0x96,0x5A,0xA6,0x77,
  2070. 0xFF,0x2C,0x3A,0xFC,0x98,0x5F,0xC1,0xBF,0x2A,0xCF,0xB8,0x62,
  2071. 0x67,0x23,0xE8,0x2F,0xCC,0x7B,0x32,0x1B,0x6B,0x33,0x67,0x0A,
  2072. 0xCB,0xD0,0x1F,0x65,0xD7,0x84,0x54,0xF6,0xF1,0x88,0xB5,0xBB,
  2073. 0x0C,0x63,0x65,0x34,0xE4,0x66,0x4B
  2074. };
  2075. // -----BEGIN DH PARAMETERS-----
  2076. //MIIBCgKCAQMDMXcgWKZpo50tXuBcRoIPnoDwACr5D2Ific59Kv3FmnxqYCzx3dRN
  2077. //a83pldtCl7rkr0E4j1cxpDndMcNvmA7jsUPRNrABKEJx07A2oEeZJZsy9YaxE1wk
  2078. //jY1/4n+awVJYwGOqAHwfEb2sTC3gop1OIeQLzSSS0jcnhFmQRi/VuSeTGIi9kVuH
  2079. //VVbYG+TPHKq8z4AeNS2xvDUxkmI8kY1i2s+DYxJLMIDugjws0hcTH/liM1xj2HVb
  2080. //qhZaNkkXd7d0vT4/mCBZXsdy6KOJIbQ8JfT0IZZapnf/LDr8mF/BvyrPuGJnI+gv
  2081. //zHsyG2szZwrL0B9l14RU9vGItbsMY2U05GZLAgEF
  2082. // -----END DH PARAMETERS-----
  2083. unsigned char dh2066_g[] = { 0x05 };
  2084. DH *dh;
  2085. if ((dh = DH_new()) == NULL )
  2086. return (NULL );
  2087. dh->p = BN_bin2bn(dh2066_p, sizeof(dh2066_p), NULL );
  2088. dh->g = BN_bin2bn(dh2066_g, sizeof(dh2066_g), NULL );
  2089. if ((dh->p == NULL )|| (dh->g == NULL)){ DH_free(dh); return(NULL);}
  2090. return (dh);
  2091. }
  2092. static int pem_password_func(char *buf, int size, int rwflag, void *password)
  2093. {
  2094. UNUSED_ARG(rwflag);
  2095. strncpy(buf, (char * )(password), size);
  2096. buf[size - 1] = 0;
  2097. return (strlen(buf));
  2098. }
  2099. #if ALPN_SUPPORTED
  2100. static int ServerALPNCallback(SSL *ssl,
  2101. const unsigned char **out,
  2102. unsigned char *outlen,
  2103. const unsigned char *in,
  2104. unsigned int inlen,
  2105. void *arg) {
  2106. UNUSED_ARG(ssl);
  2107. UNUSED_ARG(arg);
  2108. unsigned char sa_len = (unsigned char)strlen(STUN_ALPN);
  2109. unsigned char ta_len = (unsigned char)strlen(TURN_ALPN);
  2110. unsigned char ha_len = (unsigned char)strlen(HTTP_ALPN);
  2111. int found_http = 0;
  2112. const unsigned char *ptr = in;
  2113. while(ptr < (in+inlen)) {
  2114. unsigned char current_len = *ptr;
  2115. if(ptr+1+current_len > in+inlen)
  2116. break;
  2117. if((!turn_params.no_stun) && (current_len == sa_len) && (memcmp(ptr+1,STUN_ALPN,sa_len)==0)) {
  2118. *out = ptr+1;
  2119. *outlen = sa_len;
  2120. SSL_set_app_data(ssl,STUN_ALPN);
  2121. return SSL_TLSEXT_ERR_OK;
  2122. }
  2123. if((!turn_params.stun_only) && (current_len == ta_len) && (memcmp(ptr+1,TURN_ALPN,ta_len)==0)) {
  2124. *out = ptr+1;
  2125. *outlen = ta_len;
  2126. SSL_set_app_data(ssl,TURN_ALPN);
  2127. return SSL_TLSEXT_ERR_OK;
  2128. }
  2129. if((current_len == ha_len) && (memcmp(ptr+1,HTTP_ALPN,ha_len)==0)) {
  2130. *out = ptr+1;
  2131. *outlen = ta_len;
  2132. SSL_set_app_data(ssl,HTTP_ALPN);
  2133. found_http = 1;
  2134. }
  2135. ptr += 1 + current_len;
  2136. }
  2137. if(found_http)
  2138. return SSL_TLSEXT_ERR_OK;
  2139. return SSL_TLSEXT_ERR_NOACK; //???
  2140. }
  2141. #endif
  2142. static void set_ctx(SSL_CTX* ctx, const char *protocol)
  2143. {
  2144. #if ALPN_SUPPORTED
  2145. SSL_CTX_set_alpn_select_cb(ctx, ServerALPNCallback, NULL);
  2146. #endif
  2147. SSL_CTX_set_default_passwd_cb_userdata(ctx, turn_params.tls_password);
  2148. SSL_CTX_set_default_passwd_cb(ctx, pem_password_func);
  2149. if(!(turn_params.cipher_list[0]))
  2150. STRCPY(turn_params.cipher_list,DEFAULT_CIPHER_LIST);
  2151. SSL_CTX_set_cipher_list(ctx, turn_params.cipher_list);
  2152. SSL_CTX_set_session_cache_mode(ctx, SSL_SESS_CACHE_OFF);
  2153. if (!SSL_CTX_use_certificate_chain_file(ctx, turn_params.cert_file)) {
  2154. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no certificate found\n", protocol);
  2155. } else {
  2156. print_abs_file_name(protocol, ": Certificate", turn_params.cert_file);
  2157. }
  2158. if (!SSL_CTX_use_PrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) {
  2159. if (!SSL_CTX_use_RSAPrivateKey_file(ctx, turn_params.pkey_file, SSL_FILETYPE_PEM)) {
  2160. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: no valid private key found, or invalid private key password provided\n", protocol);
  2161. } else {
  2162. print_abs_file_name(protocol, ": Private RSA key", turn_params.pkey_file);
  2163. }
  2164. } else {
  2165. print_abs_file_name(protocol, ": Private key", turn_params.pkey_file);
  2166. }
  2167. if (!SSL_CTX_check_private_key(ctx)) {
  2168. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: invalid private key\n", protocol);
  2169. }
  2170. if(turn_params.ca_cert_file[0]) {
  2171. if (!SSL_CTX_load_verify_locations(ctx, turn_params.ca_cert_file, NULL )) {
  2172. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot load CA from file: %s\n", turn_params.ca_cert_file);
  2173. }
  2174. SSL_CTX_set_client_CA_list(ctx,SSL_load_client_CA_file(turn_params.ca_cert_file));
  2175. /* Set to require peer (client) certificate verification */
  2176. SSL_CTX_set_verify(ctx, SSL_VERIFY_PEER | SSL_VERIFY_FAIL_IF_NO_PEER_CERT | SSL_VERIFY_CLIENT_ONCE, NULL);
  2177. /* Set the verification depth to 9 */
  2178. SSL_CTX_set_verify_depth(ctx, 9);
  2179. } else {
  2180. SSL_CTX_set_verify(ctx, SSL_VERIFY_NONE, NULL);
  2181. }
  2182. #if !defined(OPENSSL_NO_EC) && defined(OPENSSL_EC_NAMED_CURVE)
  2183. { //Elliptic curve algorithms:
  2184. int nid = 0;
  2185. int set_auto_curve = 0;
  2186. const char* curve_name = turn_params.ec_curve_name;
  2187. if (!(curve_name[0])) {
  2188. #if !SSL_SESSION_ECDH_AUTO_SUPPORTED
  2189. curve_name = DEFAULT_EC_CURVE_NAME;
  2190. #endif
  2191. set_auto_curve = 1;
  2192. }
  2193. if(curve_name[0]) {
  2194. {
  2195. nid = OBJ_sn2nid(curve_name);
  2196. if (nid == 0) {
  2197. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,"unknown curve name: %s\n",curve_name);
  2198. curve_name = DEFAULT_EC_CURVE_NAME;
  2199. nid = OBJ_sn2nid(curve_name);
  2200. set_auto_curve = 1;
  2201. }
  2202. }
  2203. {
  2204. EC_KEY *ecdh = EC_KEY_new_by_curve_name(nid);
  2205. if (!ecdh) {
  2206. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR,
  2207. "%s: ERROR: allocate EC suite\n",__FUNCTION__);
  2208. set_auto_curve = 1;
  2209. } else {
  2210. SSL_CTX_set_tmp_ecdh(ctx, ecdh);
  2211. EC_KEY_free(ecdh);
  2212. }
  2213. }
  2214. }
  2215. if(set_auto_curve) {
  2216. #if SSL_SESSION_ECDH_AUTO_SUPPORTED
  2217. SSL_CTX_set_ecdh_auto(ctx,1);
  2218. #endif
  2219. set_auto_curve = 0;
  2220. }
  2221. }
  2222. #endif
  2223. {//DH algorithms:
  2224. DH *dh = NULL;
  2225. if(turn_params.dh_file[0]) {
  2226. FILE *paramfile = fopen(turn_params.dh_file, "r");
  2227. if (!paramfile) {
  2228. perror("Cannot open DH file");
  2229. } else {
  2230. dh = PEM_read_DHparams(paramfile, NULL, NULL, NULL);
  2231. fclose(paramfile);
  2232. if(dh) {
  2233. turn_params.dh_key_size = DH_CUSTOM;
  2234. }
  2235. }
  2236. }
  2237. if(!dh) {
  2238. if(turn_params.dh_key_size == DH_566)
  2239. dh = get_dh566();
  2240. else if(turn_params.dh_key_size == DH_2066)
  2241. dh = get_dh2066();
  2242. else
  2243. dh = get_dh1066();
  2244. }
  2245. /*
  2246. if(!dh) {
  2247. dh = DH_new();
  2248. DH_generate_parameters_ex(dh, 32, DH_GENERATOR_2, 0);
  2249. DH_generate_key(dh);
  2250. }
  2251. */
  2252. if(!dh) {
  2253. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot allocate DH suite\n",__FUNCTION__);
  2254. } else {
  2255. if (1 != SSL_CTX_set_tmp_dh (ctx, dh)) {
  2256. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "%s: ERROR: cannot set DH\n",__FUNCTION__);
  2257. }
  2258. DH_free (dh);
  2259. }
  2260. }
  2261. {
  2262. int op = 0;
  2263. #if defined(SSL_OP_NO_SSLv2)
  2264. op |= SSL_OP_NO_SSLv2;
  2265. #endif
  2266. if(turn_params.no_sslv3)
  2267. op |= SSL_OP_NO_SSLv3;
  2268. if(turn_params.no_tlsv1)
  2269. op |= SSL_OP_NO_TLSv1;
  2270. #if defined(SSL_OP_NO_TLSv1_1)
  2271. if(turn_params.no_tlsv1_1)
  2272. op |= SSL_OP_NO_TLSv1_1;
  2273. #endif
  2274. #if defined(SSL_OP_NO_TLSv1_2)
  2275. if(turn_params.no_tlsv1_2)
  2276. op |= SSL_OP_NO_TLSv1_2;
  2277. #endif
  2278. #if defined(SSL_OP_NO_DTLSv1) && DTLS_SUPPORTED
  2279. if(turn_params.no_tlsv1)
  2280. op |= SSL_OP_NO_DTLSv1;
  2281. #endif
  2282. #if defined(SSL_OP_NO_DTLSv1_2) && DTLSv1_2_SUPPORTED
  2283. if(turn_params.no_tlsv1_2)
  2284. op |= SSL_OP_NO_DTLSv1_2;
  2285. #endif
  2286. #if defined(SSL_OP_CIPHER_SERVER_PREFERENCE)
  2287. op |= SSL_OP_CIPHER_SERVER_PREFERENCE;
  2288. #endif
  2289. #if defined(SSL_OP_SINGLE_DH_USE)
  2290. op |= SSL_OP_SINGLE_DH_USE;
  2291. #endif
  2292. #if defined(SSL_OP_SINGLE_ECDH_USE)
  2293. op |= SSL_OP_SINGLE_ECDH_USE;
  2294. #endif
  2295. SSL_CTX_set_options(ctx, op);
  2296. }
  2297. }
  2298. static void openssl_setup(void)
  2299. {
  2300. THREAD_setup();
  2301. SSL_load_error_strings();
  2302. OpenSSL_add_ssl_algorithms();
  2303. #if !TLS_SUPPORTED
  2304. if(!turn_params.no_tls) {
  2305. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "WARNING: TLS is not supported\n");
  2306. turn_params.no_tls = 1;
  2307. }
  2308. #endif
  2309. if(!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.cert_file[0]) {
  2310. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"\nWARNING: certificate file is not specified, I cannot start TLS/DTLS services.\nOnly 'plain' UDP/TCP listeners can be started.\n");
  2311. turn_params.no_tls = 1;
  2312. turn_params.no_dtls = 1;
  2313. }
  2314. if(!(turn_params.no_tls && turn_params.no_dtls) && !turn_params.pkey_file[0]) {
  2315. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING,"\nWARNING: private key file is not specified, I cannot start TLS/DTLS services.\nOnly 'plain' UDP/TCP listeners can be started.\n");
  2316. turn_params.no_tls = 1;
  2317. turn_params.no_dtls = 1;
  2318. }
  2319. if(!(turn_params.no_tls && turn_params.no_dtls)) {
  2320. adjust_key_file_names();
  2321. }
  2322. if(!turn_params.no_tls) {
  2323. turn_params.tls_ctx_ssl23 = SSL_CTX_new(SSLv23_server_method()); /*compatibility mode */
  2324. set_ctx(turn_params.tls_ctx_ssl23,"SSL23");
  2325. if(!turn_params.no_tlsv1) {
  2326. turn_params.tls_ctx_v1_0 = SSL_CTX_new(TLSv1_server_method());
  2327. set_ctx(turn_params.tls_ctx_v1_0,"TLS1.0");
  2328. }
  2329. #if TLSv1_1_SUPPORTED
  2330. if(!turn_params.no_tlsv1_1) {
  2331. turn_params.tls_ctx_v1_1 = SSL_CTX_new(TLSv1_1_server_method());
  2332. set_ctx(turn_params.tls_ctx_v1_1,"TLS1.1");
  2333. }
  2334. #if TLSv1_2_SUPPORTED
  2335. if(!turn_params.no_tlsv1_2) {
  2336. turn_params.tls_ctx_v1_2 = SSL_CTX_new(TLSv1_2_server_method());
  2337. set_ctx(turn_params.tls_ctx_v1_2,"TLS1.2");
  2338. }
  2339. #endif
  2340. #endif
  2341. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "TLS cipher suite: %s\n",turn_params.cipher_list);
  2342. }
  2343. if(!turn_params.no_dtls) {
  2344. #if !DTLS_SUPPORTED
  2345. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "ERROR: DTLS is not supported.\n");
  2346. #else
  2347. if(OPENSSL_VERSION_NUMBER < 0x10000000L) {
  2348. TURN_LOG_FUNC(TURN_LOG_LEVEL_WARNING, "WARNING: TURN Server was compiled with rather old OpenSSL version, DTLS may not be working correctly.\n");
  2349. }
  2350. #if DTLSv1_2_SUPPORTED
  2351. turn_params.dtls_ctx = SSL_CTX_new(DTLS_server_method());
  2352. turn_params.dtls_ctx_v1_2 = SSL_CTX_new(DTLSv1_2_server_method());
  2353. set_ctx(turn_params.dtls_ctx_v1_2,"DTLS1.2");
  2354. SSL_CTX_set_read_ahead(turn_params.dtls_ctx_v1_2, 1);
  2355. #else
  2356. turn_params.dtls_ctx = SSL_CTX_new(DTLSv1_server_method());
  2357. #endif
  2358. set_ctx(turn_params.dtls_ctx,"DTLS");
  2359. SSL_CTX_set_read_ahead(turn_params.dtls_ctx, 1);
  2360. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "DTLS cipher suite: %s\n",turn_params.cipher_list);
  2361. #endif
  2362. }
  2363. }
  2364. ///////////////////////////////