dbd_mysql.c 38 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647484950515253545556575859606162636465666768697071727374757677787980818283848586878889909192939495969798991001011021031041051061071081091101111121131141151161171181191201211221231241251261271281291301311321331341351361371381391401411421431441451461471481491501511521531541551561571581591601611621631641651661671681691701711721731741751761771781791801811821831841851861871881891901911921931941951961971981992002012022032042052062072082092102112122132142152162172182192202212222232242252262272282292302312322332342352362372382392402412422432442452462472482492502512522532542552562572582592602612622632642652662672682692702712722732742752762772782792802812822832842852862872882892902912922932942952962972982993003013023033043053063073083093103113123133143153163173183193203213223233243253263273283293303313323333343353363373383393403413423433443453463473483493503513523533543553563573583593603613623633643653663673683693703713723733743753763773783793803813823833843853863873883893903913923933943953963973983994004014024034044054064074084094104114124134144154164174184194204214224234244254264274284294304314324334344354364374384394404414424434444454464474484494504514524534544554564574584594604614624634644654664674684694704714724734744754764774784794804814824834844854864874884894904914924934944954964974984995005015025035045055065075085095105115125135145155165175185195205215225235245255265275285295305315325335345355365375385395405415425435445455465475485495505515525535545555565575585595605615625635645655665675685695705715725735745755765775785795805815825835845855865875885895905915925935945955965975985996006016026036046056066076086096106116126136146156166176186196206216226236246256266276286296306316326336346356366376386396406416426436446456466476486496506516526536546556566576586596606616626636646656666676686696706716726736746756766776786796806816826836846856866876886896906916926936946956966976986997007017027037047057067077087097107117127137147157167177187197207217227237247257267277287297307317327337347357367377387397407417427437447457467477487497507517527537547557567577587597607617627637647657667677687697707717727737747757767777787797807817827837847857867877887897907917927937947957967977987998008018028038048058068078088098108118128138148158168178188198208218228238248258268278288298308318328338348358368378388398408418428438448458468478488498508518528538548558568578588598608618628638648658668678688698708718728738748758768778788798808818828838848858868878888898908918928938948958968978988999009019029039049059069079089099109119129139149159169179189199209219229239249259269279289299309319329339349359369379389399409419429439449459469479489499509519529539549559569579589599609619629639649659669679689699709719729739749759769779789799809819829839849859869879889899909919929939949959969979989991000100110021003100410051006100710081009101010111012101310141015101610171018101910201021102210231024102510261027102810291030103110321033103410351036103710381039104010411042104310441045104610471048104910501051105210531054105510561057105810591060106110621063106410651066106710681069107010711072107310741075107610771078107910801081108210831084108510861087108810891090109110921093109410951096109710981099110011011102110311041105110611071108110911101111111211131114111511161117111811191120112111221123112411251126112711281129113011311132113311341135113611371138113911401141114211431144114511461147114811491150115111521153115411551156115711581159116011611162116311641165116611671168116911701171117211731174117511761177117811791180118111821183118411851186118711881189119011911192119311941195119611971198119912001201120212031204120512061207120812091210121112121213121412151216121712181219122012211222122312241225122612271228122912301231123212331234123512361237123812391240124112421243124412451246124712481249125012511252125312541255125612571258125912601261126212631264126512661267126812691270127112721273127412751276
  1. /*
  2. * Copyright (C) 2011, 2012, 2013 Citrix Systems
  3. * Copyright (C) 2014 Vivocha S.p.A.
  4. *
  5. * All rights reserved.
  6. *
  7. * Redistribution and use in source and binary forms, with or without
  8. * modification, are permitted provided that the following conditions
  9. * are met:
  10. * 1. Redistributions of source code must retain the above copyright
  11. * notice, this list of conditions and the following disclaimer.
  12. * 2. Redistributions in binary form must reproduce the above copyright
  13. * notice, this list of conditions and the following disclaimer in the
  14. * documentation and/or other materials provided with the distribution.
  15. * 3. Neither the name of the project nor the names of its contributors
  16. * may be used to endorse or promote products derived from this software
  17. * without specific prior written permission.
  18. *
  19. * THIS SOFTWARE IS PROVIDED BY THE PROJECT AND CONTRIBUTORS ``AS IS'' AND
  20. * ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE
  21. * IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE
  22. * ARE DISCLAIMED. IN NO EVENT SHALL THE PROJECT OR CONTRIBUTORS BE LIABLE
  23. * FOR ANY DIRECT, INDIRECT, INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL
  24. * DAMAGES (INCLUDING, BUT NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS
  25. * OR SERVICES; LOSS OF USE, DATA, OR PROFITS; OR BUSINESS INTERRUPTION)
  26. * HOWEVER CAUSED AND ON ANY THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT
  27. * LIABILITY, OR TORT (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY
  28. * OUT OF THE USE OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF
  29. * SUCH DAMAGE.
  30. */
  31. #include "../mainrelay.h"
  32. #include "dbd_mysql.h"
  33. #if !defined(TURN_NO_MYSQL)
  34. #include <mysql.h>
  35. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  36. static int donot_print_connection_success = 0;
  37. struct _Myconninfo {
  38. char *host;
  39. char *dbname;
  40. char *user;
  41. char *password;
  42. unsigned int port;
  43. unsigned int connect_timeout;
  44. /* SSL ==>> */
  45. char *key;
  46. char *ca;
  47. char *cert;
  48. char *capath;
  49. char *cipher;
  50. /* <<== SSL : see http://dev.mysql.com/doc/refman/5.0/en/mysql-ssl-set.html */
  51. };
  52. typedef struct _Myconninfo Myconninfo;
  53. static void MyconninfoFree(Myconninfo *co) {
  54. if(co) {
  55. if(co->host) turn_free(co->host,strlen(co->host)+1);
  56. if(co->dbname) turn_free(co->dbname, strlen(co->dbname)+1);
  57. if(co->user) turn_free(co->user, strlen(co->user)+1);
  58. if(co->password) turn_free(co->password, strlen(co->password)+1);
  59. if(co->key) turn_free(co->key, strlen(co->key)+1);
  60. if(co->ca) turn_free(co->ca, strlen(co->ca)+1);
  61. if(co->cert) turn_free(co->cert, strlen(co->cert)+1);
  62. if(co->capath) turn_free(co->capath, strlen(co->capath)+1);
  63. if(co->cipher) turn_free(co->cipher, strlen(co->cipher)+1);
  64. ns_bzero(co,sizeof(Myconninfo));
  65. }
  66. }
  67. static Myconninfo *MyconninfoParse(char *userdb, char **errmsg) {
  68. Myconninfo *co = (Myconninfo*)turn_malloc(sizeof(Myconninfo));
  69. ns_bzero(co,sizeof(Myconninfo));
  70. if(userdb) {
  71. char *s0=turn_strdup(userdb);
  72. char *s = s0;
  73. while(s && *s) {
  74. while(*s && (*s==' ')) ++s;
  75. char *snext = strstr(s," ");
  76. if(snext) {
  77. *snext = 0;
  78. ++snext;
  79. }
  80. char* seq = strstr(s,"=");
  81. if(!seq) {
  82. MyconninfoFree(co);
  83. co = NULL;
  84. if(errmsg) {
  85. *errmsg = turn_strdup(s);
  86. }
  87. break;
  88. }
  89. *seq = 0;
  90. if(!strcmp(s,"host"))
  91. co->host = turn_strdup(seq+1);
  92. else if(!strcmp(s,"ip"))
  93. co->host = turn_strdup(seq+1);
  94. else if(!strcmp(s,"addr"))
  95. co->host = turn_strdup(seq+1);
  96. else if(!strcmp(s,"ipaddr"))
  97. co->host = turn_strdup(seq+1);
  98. else if(!strcmp(s,"hostaddr"))
  99. co->host = turn_strdup(seq+1);
  100. else if(!strcmp(s,"dbname"))
  101. co->dbname = turn_strdup(seq+1);
  102. else if(!strcmp(s,"db"))
  103. co->dbname = turn_strdup(seq+1);
  104. else if(!strcmp(s,"database"))
  105. co->dbname = turn_strdup(seq+1);
  106. else if(!strcmp(s,"user"))
  107. co->user = turn_strdup(seq+1);
  108. else if(!strcmp(s,"uname"))
  109. co->user = turn_strdup(seq+1);
  110. else if(!strcmp(s,"name"))
  111. co->user = turn_strdup(seq+1);
  112. else if(!strcmp(s,"username"))
  113. co->user = turn_strdup(seq+1);
  114. else if(!strcmp(s,"password"))
  115. co->password = turn_strdup(seq+1);
  116. else if(!strcmp(s,"pwd"))
  117. co->password = turn_strdup(seq+1);
  118. else if(!strcmp(s,"passwd"))
  119. co->password = turn_strdup(seq+1);
  120. else if(!strcmp(s,"secret"))
  121. co->password = turn_strdup(seq+1);
  122. else if(!strcmp(s,"port"))
  123. co->port = (unsigned int)atoi(seq+1);
  124. else if(!strcmp(s,"p"))
  125. co->port = (unsigned int)atoi(seq+1);
  126. else if(!strcmp(s,"connect_timeout"))
  127. co->connect_timeout = (unsigned int)atoi(seq+1);
  128. else if(!strcmp(s,"timeout"))
  129. co->connect_timeout = (unsigned int)atoi(seq+1);
  130. else if(!strcmp(s,"key"))
  131. co->key = turn_strdup(seq+1);
  132. else if(!strcmp(s,"ssl-key"))
  133. co->key = turn_strdup(seq+1);
  134. else if(!strcmp(s,"ca"))
  135. co->ca = turn_strdup(seq+1);
  136. else if(!strcmp(s,"ssl-ca"))
  137. co->ca = turn_strdup(seq+1);
  138. else if(!strcmp(s,"capath"))
  139. co->capath = turn_strdup(seq+1);
  140. else if(!strcmp(s,"ssl-capath"))
  141. co->capath = turn_strdup(seq+1);
  142. else if(!strcmp(s,"cert"))
  143. co->cert = turn_strdup(seq+1);
  144. else if(!strcmp(s,"ssl-cert"))
  145. co->cert = turn_strdup(seq+1);
  146. else if(!strcmp(s,"cipher"))
  147. co->cipher = turn_strdup(seq+1);
  148. else if(!strcmp(s,"ssl-cipher"))
  149. co->cipher = turn_strdup(seq+1);
  150. else {
  151. MyconninfoFree(co);
  152. co = NULL;
  153. if(errmsg) {
  154. *errmsg = turn_strdup(s);
  155. }
  156. break;
  157. }
  158. s = snext;
  159. }
  160. turn_free(s0, strlen(s0)+1);
  161. }
  162. if(co) {
  163. if(!(co->dbname))
  164. co->dbname=turn_strdup("0");
  165. if(!(co->host))
  166. co->host=turn_strdup("127.0.0.1");
  167. if(!(co->user))
  168. co->user=turn_strdup("");
  169. if(!(co->password))
  170. co->password=turn_strdup("");
  171. }
  172. return co;
  173. }
  174. static MYSQL *get_mydb_connection(void) {
  175. persistent_users_db_t *pud = get_persistent_users_db();
  176. MYSQL *mydbconnection = (MYSQL*)pthread_getspecific(connection_key);
  177. if(mydbconnection) {
  178. if(mysql_ping(mydbconnection)) {
  179. mysql_close(mydbconnection);
  180. mydbconnection=NULL;
  181. (void) pthread_setspecific(connection_key, mydbconnection);
  182. }
  183. }
  184. if(!mydbconnection) {
  185. char *errmsg=NULL;
  186. Myconninfo *co=MyconninfoParse(pud->userdb, &errmsg);
  187. if(!co) {
  188. if(errmsg) {
  189. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error: %s\n",pud->userdb,errmsg);
  190. turn_free(errmsg,strlen(errmsg)+1);
  191. } else {
  192. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error\n",pud->userdb);
  193. }
  194. } else if(errmsg) {
  195. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection <%s>, connection string format error: %s\n",pud->userdb,errmsg);
  196. turn_free(errmsg,strlen(errmsg)+1);
  197. MyconninfoFree(co);
  198. } else if(!(co->dbname)) {
  199. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "MySQL Database name is not provided: <%s>\n",pud->userdb);
  200. MyconninfoFree(co);
  201. } else {
  202. mydbconnection = mysql_init(NULL);
  203. if(!mydbconnection) {
  204. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot initialize MySQL DB connection\n");
  205. } else {
  206. if(co->connect_timeout)
  207. mysql_options(mydbconnection,MYSQL_OPT_CONNECT_TIMEOUT,&(co->connect_timeout));
  208. if(co->ca || co->capath || co->cert || co->cipher || co->key) {
  209. mysql_ssl_set(mydbconnection, co->key, co->cert, co->ca, co->capath, co->cipher);
  210. }
  211. MYSQL *conn = mysql_real_connect(mydbconnection, co->host, co->user, co->password, co->dbname, co->port, NULL, CLIENT_IGNORE_SIGPIPE);
  212. if(!conn) {
  213. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot open MySQL DB connection: <%s>, runtime error\n",pud->userdb);
  214. mysql_close(mydbconnection);
  215. mydbconnection=NULL;
  216. } else if(mysql_select_db(mydbconnection, co->dbname)) {
  217. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Cannot connect to MySQL DB: %s\n",co->dbname);
  218. mysql_close(mydbconnection);
  219. mydbconnection=NULL;
  220. } else if(!donot_print_connection_success) {
  221. TURN_LOG_FUNC(TURN_LOG_LEVEL_INFO, "MySQL DB connection success: %s\n",pud->userdb);
  222. donot_print_connection_success = 1;
  223. }
  224. }
  225. MyconninfoFree(co);
  226. }
  227. if(mydbconnection) {
  228. (void) pthread_setspecific(connection_key, mydbconnection);
  229. }
  230. }
  231. return mydbconnection;
  232. }
  233. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  234. static int mysql_get_auth_secrets(secrets_list_t *sl, u08bits *realm) {
  235. int ret = -1;
  236. MYSQL * myc = get_mydb_connection();
  237. if(myc) {
  238. char statement[TURN_LONG_STRING_SIZE];
  239. snprintf(statement,sizeof(statement)-1,"select value from turn_secret where realm='%s'",realm);
  240. int res = mysql_query(myc, statement);
  241. if(res) {
  242. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  243. } else {
  244. MYSQL_RES *mres = mysql_store_result(myc);
  245. if(!mres) {
  246. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  247. } else if(mysql_field_count(myc)==1) {
  248. for(;;) {
  249. MYSQL_ROW row = mysql_fetch_row(mres);
  250. if(!row) {
  251. break;
  252. } else {
  253. if(row[0]) {
  254. unsigned long *lengths = mysql_fetch_lengths(mres);
  255. if(lengths) {
  256. size_t sz = lengths[0];
  257. char auth_secret[TURN_LONG_STRING_SIZE];
  258. ns_bcopy(row[0],auth_secret,sz);
  259. auth_secret[sz]=0;
  260. add_to_secrets_list(sl,auth_secret);
  261. }
  262. }
  263. }
  264. }
  265. ret = 0;
  266. }
  267. if(mres)
  268. mysql_free_result(mres);
  269. }
  270. }
  271. return ret;
  272. }
  273. static int mysql_get_user_key(u08bits *usname, u08bits *realm, hmackey_t key) {
  274. int ret = -1;
  275. MYSQL * myc = get_mydb_connection();
  276. if(myc) {
  277. char statement[TURN_LONG_STRING_SIZE];
  278. snprintf(statement,sizeof(statement),"select hmackey from turnusers_lt where name='%s' and realm='%s'",usname,realm);
  279. int res = mysql_query(myc, statement);
  280. if(res) {
  281. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  282. } else {
  283. MYSQL_RES *mres = mysql_store_result(myc);
  284. if(!mres) {
  285. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  286. } else if(mysql_field_count(myc)!=1) {
  287. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  288. } else {
  289. MYSQL_ROW row = mysql_fetch_row(mres);
  290. if(row && row[0]) {
  291. unsigned long *lengths = mysql_fetch_lengths(mres);
  292. if(lengths) {
  293. size_t sz = get_hmackey_size(turn_params.shatype)*2;
  294. if(lengths[0]<sz) {
  295. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key format: string length=%d (must be %d): user %s\n",(int)lengths[0],(int)sz,usname);
  296. } else {
  297. char kval[sizeof(hmackey_t)+sizeof(hmackey_t)+1];
  298. ns_bcopy(row[0],kval,sz);
  299. kval[sz]=0;
  300. if(convert_string_key_to_binary(kval, key, sz/2)<0) {
  301. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Wrong key: %s, user %s\n",kval,usname);
  302. } else {
  303. ret = 0;
  304. }
  305. }
  306. }
  307. }
  308. }
  309. if(mres)
  310. mysql_free_result(mres);
  311. }
  312. }
  313. return ret;
  314. }
  315. static int mysql_get_oauth_key(const u08bits *kid, oauth_key_data_raw *key) {
  316. int ret = -1;
  317. char statement[TURN_LONG_STRING_SIZE];
  318. snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key from oauth_key where kid='%s'",(const char*)kid);
  319. MYSQL * myc = get_mydb_connection();
  320. if(myc) {
  321. int res = mysql_query(myc, statement);
  322. if(res) {
  323. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  324. } else {
  325. MYSQL_RES *mres = mysql_store_result(myc);
  326. if(!mres) {
  327. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  328. } else if(mysql_field_count(myc)!=8) {
  329. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  330. } else {
  331. MYSQL_ROW row = mysql_fetch_row(mres);
  332. if(row && row[0]) {
  333. unsigned long *lengths = mysql_fetch_lengths(mres);
  334. if(lengths) {
  335. STRCPY((char*)key->kid,kid);
  336. ns_bcopy(row[0],key->ikm_key,lengths[0]);
  337. key->ikm_key[lengths[0]]=0;
  338. char stimestamp[128];
  339. ns_bcopy(row[1],stimestamp,lengths[1]);
  340. stimestamp[lengths[1]]=0;
  341. key->timestamp = (u64bits)strtoull(stimestamp,NULL,10);
  342. char slifetime[128];
  343. ns_bcopy(row[2],slifetime,lengths[2]);
  344. slifetime[lengths[2]]=0;
  345. key->lifetime = (u32bits)strtoul(slifetime,NULL,10);
  346. ns_bcopy(row[3],key->hkdf_hash_func,lengths[3]);
  347. key->hkdf_hash_func[lengths[3]]=0;
  348. ns_bcopy(row[4],key->as_rs_alg,lengths[4]);
  349. key->as_rs_alg[lengths[4]]=0;
  350. ns_bcopy(row[5],key->as_rs_key,lengths[5]);
  351. key->as_rs_key[lengths[5]]=0;
  352. ns_bcopy(row[6],key->auth_alg,lengths[6]);
  353. key->auth_alg[lengths[6]]=0;
  354. ns_bcopy(row[7],key->auth_key,lengths[7]);
  355. key->auth_key[lengths[7]]=0;
  356. ret = 0;
  357. }
  358. }
  359. }
  360. if(mres)
  361. mysql_free_result(mres);
  362. }
  363. }
  364. return ret;
  365. }
  366. static int mysql_list_oauth_keys(secrets_list_t *kids,secrets_list_t *hkdfs,secrets_list_t *teas,secrets_list_t *aas,secrets_list_t *tss,secrets_list_t *lts) {
  367. oauth_key_data_raw key_;
  368. oauth_key_data_raw *key=&key_;
  369. int ret = -1;
  370. char statement[TURN_LONG_STRING_SIZE];
  371. snprintf(statement,sizeof(statement),"select ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key,kid from oauth_key order by kid");
  372. MYSQL * myc = get_mydb_connection();
  373. if(myc) {
  374. int res = mysql_query(myc, statement);
  375. if(res) {
  376. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  377. } else {
  378. MYSQL_RES *mres = mysql_store_result(myc);
  379. if(!mres) {
  380. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  381. } else if(mysql_field_count(myc)!=9) {
  382. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  383. } else {
  384. MYSQL_ROW row = mysql_fetch_row(mres);
  385. while(row) {
  386. unsigned long *lengths = mysql_fetch_lengths(mres);
  387. if(lengths) {
  388. ns_bcopy(row[0],key->ikm_key,lengths[0]);
  389. key->ikm_key[lengths[0]]=0;
  390. char stimestamp[128];
  391. ns_bcopy(row[1],stimestamp,lengths[1]);
  392. stimestamp[lengths[1]]=0;
  393. key->timestamp = (u64bits)strtoull(stimestamp,NULL,10);
  394. char slifetime[128];
  395. ns_bcopy(row[2],slifetime,lengths[2]);
  396. slifetime[lengths[2]]=0;
  397. key->lifetime = (u32bits)strtoul(slifetime,NULL,10);
  398. ns_bcopy(row[3],key->hkdf_hash_func,lengths[3]);
  399. key->hkdf_hash_func[lengths[3]]=0;
  400. ns_bcopy(row[4],key->as_rs_alg,lengths[4]);
  401. key->as_rs_alg[lengths[4]]=0;
  402. ns_bcopy(row[5],key->as_rs_key,lengths[5]);
  403. key->as_rs_key[lengths[5]]=0;
  404. ns_bcopy(row[6],key->auth_alg,lengths[6]);
  405. key->auth_alg[lengths[6]]=0;
  406. ns_bcopy(row[7],key->auth_key,lengths[7]);
  407. key->auth_key[lengths[7]]=0;
  408. ns_bcopy(row[8],key->kid,lengths[8]);
  409. key->kid[lengths[8]]=0;
  410. if(kids) {
  411. add_to_secrets_list(kids,key->kid);
  412. add_to_secrets_list(hkdfs,key->hkdf_hash_func);
  413. add_to_secrets_list(teas,key->as_rs_alg);
  414. add_to_secrets_list(aas,key->auth_alg);
  415. {
  416. char ts[256];
  417. snprintf(ts,sizeof(ts)-1,"%llu",(unsigned long long)key->timestamp);
  418. add_to_secrets_list(tss,ts);
  419. }
  420. {
  421. char lt[256];
  422. snprintf(lt,sizeof(lt)-1,"%lu",(unsigned long)key->lifetime);
  423. add_to_secrets_list(lts,lt);
  424. }
  425. } else {
  426. printf(" kid=%s, ikm_key=%s, timestamp=%llu, lifetime=%lu, hkdf_hash_func=%s, as_rs_alg=%s, as_rs_key=%s, auth_alg=%s, auth_key=%s\n",
  427. key->kid, key->ikm_key, (unsigned long long)key->timestamp, (unsigned long)key->lifetime, key->hkdf_hash_func,
  428. key->as_rs_alg, key->as_rs_key, key->auth_alg, key->auth_key);
  429. }
  430. }
  431. row = mysql_fetch_row(mres);
  432. }
  433. }
  434. if(mres)
  435. mysql_free_result(mres);
  436. }
  437. }
  438. return ret;
  439. }
  440. static int mysql_set_user_key(u08bits *usname, u08bits *realm, const char *key)
  441. {
  442. int ret = -1;
  443. char statement[TURN_LONG_STRING_SIZE];
  444. MYSQL * myc = get_mydb_connection();
  445. if(myc) {
  446. snprintf(statement,sizeof(statement),"insert into turnusers_lt (realm,name,hmackey) values('%s','%s','%s')",realm,usname,key);
  447. int res = mysql_query(myc, statement);
  448. if(!res) {
  449. ret = 0;
  450. } else {
  451. snprintf(statement,sizeof(statement),"update turnusers_lt set hmackey='%s' where name='%s' and realm='%s'",key,usname,realm);
  452. res = mysql_query(myc, statement);
  453. if(!res) {
  454. ret = 0;
  455. } else {
  456. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n",mysql_error(myc));
  457. }
  458. }
  459. }
  460. return ret;
  461. }
  462. static int mysql_set_oauth_key(oauth_key_data_raw *key)
  463. {
  464. int ret = -1;
  465. char statement[TURN_LONG_STRING_SIZE];
  466. MYSQL * myc = get_mydb_connection();
  467. if(myc) {
  468. snprintf(statement,sizeof(statement),"insert into oauth_key (kid,ikm_key,timestamp,lifetime,hkdf_hash_func,as_rs_alg,as_rs_key,auth_alg,auth_key) values('%s','%s',%llu,%lu,'%s','%s','%s','%s','%s')",
  469. key->kid,key->ikm_key,(unsigned long long)key->timestamp,(unsigned long)key->lifetime,
  470. key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key);
  471. int res = mysql_query(myc, statement);
  472. if(res) {
  473. snprintf(statement,sizeof(statement),"update oauth_key set ikm_key='%s',timestamp=%lu,lifetime=%lu, hkdf_hash_func = '%s', as_rs_alg='%s',as_rs_key='%s',auth_alg='%s',auth_key='%s' where kid='%s'",key->ikm_key,(unsigned long)key->timestamp,(unsigned long)key->lifetime,
  474. key->hkdf_hash_func,key->as_rs_alg,key->as_rs_key,key->auth_alg,key->auth_key,key->kid);
  475. res = mysql_query(myc, statement);
  476. if(res) {
  477. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating oauth key information: %s\n",mysql_error(myc));
  478. } else {
  479. ret = 0;
  480. }
  481. } else {
  482. ret = 0;
  483. }
  484. }
  485. return ret;
  486. }
  487. static int mysql_del_user(u08bits *usname, u08bits *realm) {
  488. int ret = -1;
  489. char statement[TURN_LONG_STRING_SIZE];
  490. MYSQL * myc = get_mydb_connection();
  491. if(myc) {
  492. snprintf(statement,sizeof(statement),"delete from turnusers_lt where name='%s' and realm='%s'",usname,realm);
  493. int res = mysql_query(myc, statement);
  494. if(res) {
  495. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting user key information: %s\n",mysql_error(myc));
  496. } else {
  497. ret = 0;
  498. }
  499. }
  500. return ret;
  501. }
  502. static int mysql_del_oauth_key(const u08bits *kid) {
  503. int ret = -1;
  504. char statement[TURN_LONG_STRING_SIZE];
  505. MYSQL * myc = get_mydb_connection();
  506. if(myc) {
  507. snprintf(statement,sizeof(statement),"delete from oauth_key where kid = '%s'",(const char*)kid);
  508. int res = mysql_query(myc, statement);
  509. if(res) {
  510. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting oauth key information: %s\n",mysql_error(myc));
  511. } else {
  512. ret = 0;
  513. }
  514. }
  515. return ret;
  516. }
  517. static int mysql_list_users(u08bits *realm, secrets_list_t *users, secrets_list_t *realms)
  518. {
  519. int ret = -1;
  520. char statement[TURN_LONG_STRING_SIZE];
  521. u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0";
  522. if(!realm) realm=realm0;
  523. MYSQL * myc = get_mydb_connection();
  524. if(myc) {
  525. if(realm[0]) {
  526. snprintf(statement,sizeof(statement),"select name, realm from turnusers_lt where realm='%s' order by name",realm);
  527. } else {
  528. snprintf(statement,sizeof(statement),"select name, realm from turnusers_lt order by realm,name");
  529. }
  530. int res = mysql_query(myc, statement);
  531. if(res) {
  532. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  533. } else {
  534. MYSQL_RES *mres = mysql_store_result(myc);
  535. if(!mres) {
  536. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  537. } else if(mysql_field_count(myc)!=2) {
  538. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  539. } else {
  540. for(;;) {
  541. MYSQL_ROW row = mysql_fetch_row(mres);
  542. if(!row) {
  543. break;
  544. } else {
  545. if(row[0]) {
  546. if(users) {
  547. add_to_secrets_list(users,row[0]);
  548. if(realms) {
  549. if(row[1]) {
  550. add_to_secrets_list(realms,row[1]);
  551. } else {
  552. add_to_secrets_list(realms,(char*)realm);
  553. }
  554. }
  555. } else {
  556. printf("%s[%s]\n", row[0], row[1]);
  557. }
  558. }
  559. }
  560. }
  561. ret = 0;
  562. }
  563. if(mres)
  564. mysql_free_result(mres);
  565. }
  566. }
  567. return ret;
  568. }
  569. static int mysql_list_secrets(u08bits *realm, secrets_list_t *secrets, secrets_list_t *realms)
  570. {
  571. int ret = -1;
  572. u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0";
  573. if(!realm) realm=realm0;
  574. char statement[TURN_LONG_STRING_SIZE];
  575. if (realm[0]) {
  576. snprintf(statement, sizeof(statement), "select value,realm from turn_secret where realm='%s' order by value", realm);
  577. } else {
  578. snprintf(statement, sizeof(statement), "select value,realm from turn_secret order by realm,value");
  579. }
  580. donot_print_connection_success=1;
  581. MYSQL * myc = get_mydb_connection();
  582. if(myc) {
  583. int res = mysql_query(myc, statement);
  584. if(res) {
  585. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  586. } else {
  587. MYSQL_RES *mres = mysql_store_result(myc);
  588. if(!mres) {
  589. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  590. } else if(mysql_field_count(myc)!=2) {
  591. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  592. } else {
  593. for(;;) {
  594. MYSQL_ROW row = mysql_fetch_row(mres);
  595. if(!row) {
  596. break;
  597. } else {
  598. const char* kval = row[0];
  599. if(kval) {
  600. const char* rval = row[1];
  601. if(secrets) {
  602. add_to_secrets_list(secrets,kval);
  603. if(realms) {
  604. if(rval && *rval) {
  605. add_to_secrets_list(realms,rval);
  606. } else {
  607. add_to_secrets_list(realms,(char*)realm);
  608. }
  609. }
  610. } else {
  611. printf("%s[%s]\n",kval,rval);
  612. }
  613. }
  614. }
  615. }
  616. ret = 0;
  617. }
  618. if(mres)
  619. mysql_free_result(mres);
  620. }
  621. }
  622. return ret;
  623. }
  624. static int mysql_del_secret(u08bits *secret, u08bits *realm) {
  625. int ret = -1;
  626. donot_print_connection_success=1;
  627. char statement[TURN_LONG_STRING_SIZE];
  628. MYSQL * myc = get_mydb_connection();
  629. if (myc) {
  630. if(!secret || (secret[0]==0))
  631. snprintf(statement,sizeof(statement),"delete from turn_secret where realm='%s'",realm);
  632. else
  633. snprintf(statement,sizeof(statement),"delete from turn_secret where value='%s' and realm='%s'",secret,realm);
  634. mysql_query(myc, statement);
  635. ret = 0;
  636. }
  637. return ret;
  638. }
  639. static int mysql_set_secret(u08bits *secret, u08bits *realm) {
  640. int ret = -1;
  641. donot_print_connection_success = 1;
  642. char statement[TURN_LONG_STRING_SIZE];
  643. MYSQL * myc = get_mydb_connection();
  644. if (myc) {
  645. snprintf(statement,sizeof(statement),"insert into turn_secret (realm,value) values('%s','%s')",realm,secret);
  646. int res = mysql_query(myc, statement);
  647. if (res) {
  648. TURN_LOG_FUNC(
  649. TURN_LOG_LEVEL_ERROR,
  650. "Error inserting/updating secret key information: %s\n",
  651. mysql_error(myc));
  652. } else {
  653. ret = 0;
  654. }
  655. }
  656. return ret;
  657. }
  658. static int mysql_set_permission_ip(const char *kind, u08bits *realm, const char* ip, int del)
  659. {
  660. int ret = -1;
  661. u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0";
  662. if(!realm) realm=realm0;
  663. donot_print_connection_success = 1;
  664. char statement[TURN_LONG_STRING_SIZE];
  665. MYSQL * myc = get_mydb_connection();
  666. if (myc) {
  667. if(del) {
  668. snprintf(statement, sizeof(statement), "delete from %s_peer_ip where realm = '%s' and ip_range = '%s'", kind, (char*)realm, ip);
  669. } else {
  670. snprintf(statement, sizeof(statement), "insert into %s_peer_ip (realm,ip_range) values('%s','%s')", kind, (char*)realm, ip);
  671. }
  672. int res = mysql_query(myc, statement);
  673. if (res) {
  674. TURN_LOG_FUNC(
  675. TURN_LOG_LEVEL_ERROR,
  676. "Error inserting permission ip information: %s\n",
  677. mysql_error(myc));
  678. } else {
  679. ret = 0;
  680. }
  681. }
  682. return ret;
  683. }
  684. static int mysql_add_origin(u08bits *origin, u08bits *realm) {
  685. int ret = -1;
  686. char statement[TURN_LONG_STRING_SIZE];
  687. MYSQL * myc = get_mydb_connection();
  688. if (myc) {
  689. snprintf(statement,sizeof(statement),"insert into turn_origin_to_realm (origin,realm) values('%s','%s')",origin,realm);
  690. int res = mysql_query(myc, statement);
  691. if (res) {
  692. TURN_LOG_FUNC(
  693. TURN_LOG_LEVEL_ERROR,
  694. "Error inserting origin information: %s\n",
  695. mysql_error(myc));
  696. } else {
  697. ret = 0;
  698. }
  699. }
  700. return ret;
  701. }
  702. static int mysql_del_origin(u08bits *origin) {
  703. int ret = -1;
  704. char statement[TURN_LONG_STRING_SIZE];
  705. MYSQL * myc = get_mydb_connection();
  706. if (myc) {
  707. snprintf(statement,sizeof(statement),"delete from turn_origin_to_realm where origin='%s'",origin);
  708. int res = mysql_query(myc, statement);
  709. if (res) {
  710. TURN_LOG_FUNC(
  711. TURN_LOG_LEVEL_ERROR,
  712. "Error deleting origin information: %s\n",
  713. mysql_error(myc));
  714. } else {
  715. ret = 0;
  716. }
  717. }
  718. return ret;
  719. }
  720. static int mysql_list_origins(u08bits *realm, secrets_list_t *origins, secrets_list_t *realms)
  721. {
  722. int ret = -1;
  723. u08bits realm0[STUN_MAX_REALM_SIZE+1] = "\0";
  724. if(!realm) realm=realm0;
  725. donot_print_connection_success = 1;
  726. MYSQL * myc = get_mydb_connection();
  727. if(myc) {
  728. char statement[TURN_LONG_STRING_SIZE];
  729. if(realm && realm[0]) {
  730. snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm where realm='%s' order by origin",realm);
  731. } else {
  732. snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm order by realm,origin");
  733. }
  734. int res = mysql_query(myc, statement);
  735. if(res) {
  736. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  737. } else {
  738. MYSQL_RES *mres = mysql_store_result(myc);
  739. if(!mres) {
  740. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  741. } else if(mysql_field_count(myc)!=2) {
  742. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  743. } else {
  744. for(;;) {
  745. MYSQL_ROW row = mysql_fetch_row(mres);
  746. if(!row) {
  747. break;
  748. } else {
  749. if(row[0] && row[1]) {
  750. const char* kval = row[0];
  751. const char* rval = row[1];
  752. if(origins) {
  753. add_to_secrets_list(origins,kval);
  754. if(realms) {
  755. if(rval && *rval) {
  756. add_to_secrets_list(realms,rval);
  757. } else {
  758. add_to_secrets_list(realms,(char*)realm);
  759. }
  760. }
  761. } else {
  762. printf("%s ==>> %s\n",kval,rval);
  763. }
  764. }
  765. }
  766. }
  767. ret = 0;
  768. }
  769. if(mres)
  770. mysql_free_result(mres);
  771. }
  772. }
  773. return ret;
  774. }
  775. static int mysql_set_realm_option_one(u08bits *realm, unsigned long value, const char* opt) {
  776. int ret = -1;
  777. char statement[TURN_LONG_STRING_SIZE];
  778. MYSQL * myc = get_mydb_connection();
  779. if (myc) {
  780. {
  781. snprintf(statement,sizeof(statement),"delete from turn_realm_option where realm='%s' and opt='%s'",realm,opt);
  782. mysql_query(myc, statement);
  783. }
  784. if(value>0) {
  785. snprintf(statement,sizeof(statement),"insert into turn_realm_option (realm,opt,value) values('%s','%s','%lu')",realm,opt,(unsigned long)value);
  786. int res = mysql_query(myc, statement);
  787. if (res) {
  788. TURN_LOG_FUNC(
  789. TURN_LOG_LEVEL_ERROR,
  790. "Error inserting realm option information: %s\n",
  791. mysql_error(myc));
  792. } else {
  793. ret = 0;
  794. }
  795. }
  796. }
  797. return ret;
  798. }
  799. static int mysql_list_realm_options(u08bits *realm) {
  800. int ret = -1;
  801. donot_print_connection_success = 1;
  802. char statement[TURN_LONG_STRING_SIZE];
  803. MYSQL * myc = get_mydb_connection();
  804. if(myc) {
  805. if(realm && realm[0]) {
  806. snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option where realm='%s' order by realm,opt",realm);
  807. } else {
  808. snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option order by realm,opt");
  809. }
  810. int res = mysql_query(myc, statement);
  811. if(res) {
  812. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  813. } else {
  814. MYSQL_RES *mres = mysql_store_result(myc);
  815. if(!mres) {
  816. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  817. } else if(mysql_field_count(myc)!=3) {
  818. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  819. } else {
  820. for(;;) {
  821. MYSQL_ROW row = mysql_fetch_row(mres);
  822. if(!row) {
  823. break;
  824. } else {
  825. if(row[0] && row[1] && row[2]) {
  826. printf("%s[%s]=%s\n",row[1],row[0],row[2]);
  827. }
  828. }
  829. }
  830. ret = 0;
  831. }
  832. if(mres)
  833. mysql_free_result(mres);
  834. }
  835. }
  836. return ret;
  837. }
  838. static void mysql_auth_ping(void * rch) {
  839. UNUSED_ARG(rch);
  840. MYSQL * myc = get_mydb_connection();
  841. if(myc) {
  842. char statement[TURN_LONG_STRING_SIZE];
  843. STRCPY(statement,"select value from turn_secret");
  844. int res = mysql_query(myc, statement);
  845. if(res) {
  846. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  847. } else {
  848. MYSQL_RES *mres = mysql_store_result(myc);
  849. if(!mres) {
  850. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  851. } else {
  852. mysql_free_result(mres);
  853. }
  854. }
  855. }
  856. }
  857. static int mysql_get_ip_list(const char *kind, ip_range_list_t * list) {
  858. int ret = -1;
  859. MYSQL * myc = get_mydb_connection();
  860. if(myc) {
  861. char statement[TURN_LONG_STRING_SIZE];
  862. snprintf(statement,sizeof(statement),"select ip_range,realm from %s_peer_ip",kind);
  863. int res = mysql_query(myc, statement);
  864. if(res) {
  865. static int wrong_table_reported = 0;
  866. if(!wrong_table_reported) {
  867. wrong_table_reported = 1;
  868. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information; probably, the tables 'allowed_peer_ip' and/or 'denied_peer_ip' have to be upgraded to include the realm column.\n");
  869. }
  870. snprintf(statement, sizeof(statement), "select ip_range,'' from %s_peer_ip", kind);
  871. res = mysql_query(myc, statement);
  872. }
  873. if(res == 0) {
  874. MYSQL_RES *mres = mysql_store_result(myc);
  875. if(mres && mysql_field_count(myc)==2) {
  876. for(;;) {
  877. MYSQL_ROW row = mysql_fetch_row(mres);
  878. if(!row) {
  879. break;
  880. } else {
  881. if(row[0]) {
  882. unsigned long *lengths = mysql_fetch_lengths(mres);
  883. if(lengths) {
  884. size_t sz = lengths[0];
  885. char kval[TURN_LONG_STRING_SIZE];
  886. ns_bcopy(row[0],kval,sz);
  887. kval[sz]=0;
  888. sz = lengths[1];
  889. char rval[TURN_LONG_STRING_SIZE];
  890. ns_bcopy(row[1],rval,sz);
  891. rval[sz]=0;
  892. add_ip_list_range(kval,rval,list);
  893. }
  894. }
  895. }
  896. }
  897. ret = 0;
  898. }
  899. if(mres)
  900. mysql_free_result(mres);
  901. }
  902. }
  903. return ret;
  904. }
  905. static void mysql_reread_realms(secrets_list_t * realms_list) {
  906. MYSQL * myc = get_mydb_connection();
  907. if(myc) {
  908. char statement[TURN_LONG_STRING_SIZE];
  909. {
  910. snprintf(statement,sizeof(statement),"select origin,realm from turn_origin_to_realm");
  911. int res = mysql_query(myc, statement);
  912. if(res == 0) {
  913. MYSQL_RES *mres = mysql_store_result(myc);
  914. if(mres && mysql_field_count(myc)==2) {
  915. ur_string_map *o_to_realm_new = ur_string_map_create(turn_free_simple);
  916. for(;;) {
  917. MYSQL_ROW row = mysql_fetch_row(mres);
  918. if(!row) {
  919. break;
  920. } else {
  921. if(row[0] && row[1]) {
  922. unsigned long *lengths = mysql_fetch_lengths(mres);
  923. if(lengths) {
  924. size_t sz = lengths[0];
  925. char oval[513];
  926. ns_bcopy(row[0],oval,sz);
  927. oval[sz]=0;
  928. char *rval=turn_strdup(row[1]);
  929. get_realm(rval);
  930. ur_string_map_value_type value = (ur_string_map_value_type)rval;
  931. ur_string_map_put(o_to_realm_new, (const ur_string_map_key_type) oval, value);
  932. }
  933. }
  934. }
  935. }
  936. update_o_to_realm(o_to_realm_new);
  937. }
  938. if(mres)
  939. mysql_free_result(mres);
  940. }
  941. }
  942. {
  943. size_t i = 0;
  944. size_t rlsz = 0;
  945. lock_realms();
  946. rlsz = realms_list->sz;
  947. unlock_realms();
  948. for (i = 0; i<rlsz; ++i) {
  949. char *realm = realms_list->secrets[i];
  950. realm_params_t* rp = get_realm(realm);
  951. lock_realms();
  952. rp->options.perf_options.max_bps = turn_params.max_bps;
  953. unlock_realms();
  954. lock_realms();
  955. rp->options.perf_options.total_quota = turn_params.total_quota;
  956. unlock_realms();
  957. lock_realms();
  958. rp->options.perf_options.user_quota = turn_params.user_quota;
  959. unlock_realms();
  960. }
  961. }
  962. snprintf(statement,sizeof(statement),"select realm,opt,value from turn_realm_option");
  963. int res = mysql_query(myc, statement);
  964. if(res == 0) {
  965. MYSQL_RES *mres = mysql_store_result(myc);
  966. if(mres && mysql_field_count(myc)==3) {
  967. for(;;) {
  968. MYSQL_ROW row = mysql_fetch_row(mres);
  969. if(!row) {
  970. break;
  971. } else {
  972. if(row[0] && row[1] && row[2]) {
  973. unsigned long *lengths = mysql_fetch_lengths(mres);
  974. if(lengths) {
  975. char rval[513];
  976. size_t sz = lengths[0];
  977. ns_bcopy(row[0],rval,sz);
  978. rval[sz]=0;
  979. char oval[513];
  980. sz = lengths[1];
  981. ns_bcopy(row[1],oval,sz);
  982. oval[sz]=0;
  983. char vval[513];
  984. sz = lengths[2];
  985. ns_bcopy(row[2],vval,sz);
  986. vval[sz]=0;
  987. realm_params_t* rp = get_realm(rval);
  988. if(!strcmp(oval,"max-bps"))
  989. rp->options.perf_options.max_bps = (band_limit_t)atol(vval);
  990. else if(!strcmp(oval,"total-quota"))
  991. rp->options.perf_options.total_quota = (vint)atoi(vval);
  992. else if(!strcmp(oval,"user-quota"))
  993. rp->options.perf_options.user_quota = (vint)atoi(vval);
  994. else {
  995. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown realm option: %s\n", oval);
  996. }
  997. }
  998. }
  999. }
  1000. }
  1001. }
  1002. if(mres)
  1003. mysql_free_result(mres);
  1004. }
  1005. }
  1006. }
  1007. /////////////////////////////////////////////////////
  1008. static int mysql_get_admin_user(const u08bits *usname, u08bits *realm, password_t pwd)
  1009. {
  1010. int ret = -1;
  1011. realm[0]=0;
  1012. pwd[0]=0;
  1013. MYSQL * myc = get_mydb_connection();
  1014. if(myc) {
  1015. char statement[TURN_LONG_STRING_SIZE];
  1016. snprintf(statement,sizeof(statement),"select realm,password from admin_user where name='%s'",usname);
  1017. int res = mysql_query(myc, statement);
  1018. if(res) {
  1019. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  1020. } else {
  1021. MYSQL_RES *mres = mysql_store_result(myc);
  1022. if(!mres) {
  1023. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  1024. } else if(mysql_field_count(myc)!=2) {
  1025. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  1026. } else {
  1027. MYSQL_ROW row = mysql_fetch_row(mres);
  1028. if(row && row[0]) {
  1029. strncpy((char*)realm,row[0],STUN_MAX_REALM_SIZE);
  1030. strncpy((char*)pwd,row[1],STUN_MAX_PWD_SIZE);
  1031. ret = 0;
  1032. }
  1033. }
  1034. if(mres)
  1035. mysql_free_result(mres);
  1036. }
  1037. }
  1038. return ret;
  1039. }
  1040. static int mysql_set_admin_user(const u08bits *usname, const u08bits *realm, const password_t pwd)
  1041. {
  1042. int ret = -1;
  1043. char statement[TURN_LONG_STRING_SIZE];
  1044. donot_print_connection_success=1;
  1045. MYSQL * myc = get_mydb_connection();
  1046. if(myc) {
  1047. snprintf(statement,sizeof(statement),"insert into admin_user (realm,name,password) values('%s','%s','%s')",realm,usname,pwd);
  1048. int res = mysql_query(myc, statement);
  1049. if(!res) {
  1050. ret = 0;
  1051. } else {
  1052. snprintf(statement,sizeof(statement),"update admin_user set realm='%s',password='%s' where name='%s'",realm,pwd,usname);
  1053. res = mysql_query(myc, statement);
  1054. if(!res) {
  1055. ret = 0;
  1056. } else {
  1057. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error inserting/updating user key information: %s\n",mysql_error(myc));
  1058. }
  1059. }
  1060. }
  1061. return ret;
  1062. }
  1063. static int mysql_del_admin_user(const u08bits *usname)
  1064. {
  1065. int ret = -1;
  1066. char statement[TURN_LONG_STRING_SIZE];
  1067. donot_print_connection_success=1;
  1068. MYSQL * myc = get_mydb_connection();
  1069. if(myc) {
  1070. snprintf(statement,sizeof(statement),"delete from admin_user where name='%s'",usname);
  1071. int res = mysql_query(myc, statement);
  1072. if(res) {
  1073. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error deleting admin user information: %s\n",mysql_error(myc));
  1074. } else {
  1075. ret = 0;
  1076. }
  1077. }
  1078. return ret;
  1079. }
  1080. static int mysql_list_admin_users(void)
  1081. {
  1082. int ret = -1;
  1083. char statement[TURN_LONG_STRING_SIZE];
  1084. donot_print_connection_success=1;
  1085. MYSQL * myc = get_mydb_connection();
  1086. if(myc) {
  1087. snprintf(statement,sizeof(statement),"select name, realm from admin_user order by realm,name");
  1088. int res = mysql_query(myc, statement);
  1089. if(res) {
  1090. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  1091. } else {
  1092. MYSQL_RES *mres = mysql_store_result(myc);
  1093. if(!mres) {
  1094. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Error retrieving MySQL DB information: %s\n",mysql_error(myc));
  1095. } else if(mysql_field_count(myc)!=2) {
  1096. TURN_LOG_FUNC(TURN_LOG_LEVEL_ERROR, "Unknown error retrieving MySQL DB information: %s\n",statement);
  1097. } else {
  1098. for(;;) {
  1099. MYSQL_ROW row = mysql_fetch_row(mres);
  1100. if(!row) {
  1101. break;
  1102. } else {
  1103. if(row[0]) {
  1104. if(row[1] && row[1][0]) {
  1105. printf("%s[%s]\n",row[0],row[1]);
  1106. } else {
  1107. printf("%s\n",row[0]);
  1108. }
  1109. }
  1110. }
  1111. }
  1112. ret = 0;
  1113. }
  1114. if(mres)
  1115. mysql_free_result(mres);
  1116. }
  1117. }
  1118. return ret;
  1119. }
  1120. //////////////////////////////////////////////////////
  1121. static const turn_dbdriver_t driver = {
  1122. &mysql_get_auth_secrets,
  1123. &mysql_get_user_key,
  1124. &mysql_set_user_key,
  1125. &mysql_del_user,
  1126. &mysql_list_users,
  1127. &mysql_list_secrets,
  1128. &mysql_del_secret,
  1129. &mysql_set_secret,
  1130. &mysql_add_origin,
  1131. &mysql_del_origin,
  1132. &mysql_list_origins,
  1133. &mysql_set_realm_option_one,
  1134. &mysql_list_realm_options,
  1135. &mysql_auth_ping,
  1136. &mysql_get_ip_list,
  1137. &mysql_set_permission_ip,
  1138. &mysql_reread_realms,
  1139. &mysql_set_oauth_key,
  1140. &mysql_get_oauth_key,
  1141. &mysql_del_oauth_key,
  1142. &mysql_list_oauth_keys,
  1143. &mysql_get_admin_user,
  1144. &mysql_set_admin_user,
  1145. &mysql_del_admin_user,
  1146. &mysql_list_admin_users
  1147. };
  1148. const turn_dbdriver_t * get_mysql_dbdriver(void) {
  1149. return &driver;
  1150. }
  1151. ///////////////////////////////////////////////////////////////////////////////////////////////////////////
  1152. #else
  1153. const turn_dbdriver_t * get_mysql_dbdriver(void) {
  1154. return NULL;
  1155. }
  1156. #endif