ns_turn_msg.c 42 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128112911301131113211331134113511361137113811391140114111421143114411451146114711481149115011511152115311541155115611571158115911601161116211631164116511661167116811691170117111721173117411751176117711781179118011811182118311841185118611871188118911901191119211931194119511961197119811991200120112021203120412051206120712081209121012111212121312141215121612171218121912201221122212231224122512261227122812291230123112321233123412351236123712381239124012411242124312441245124612471248124912501251125212531254125512561257125812591260126112621263126412651266126712681269127012711272127312741275127612771278127912801281128212831284128512861287128812891290129112921293129412951296129712981299130013011302130313041305130613071308130913101311131213131314131513161317131813191320132113221323132413251326132713281329133013311332133313341335133613371338133913401341134213431344134513461347134813491350135113521353135413551356135713581359136013611362136313641365136613671368136913701371137213731374137513761377137813791380138113821383138413851386138713881389139013911392139313941395139613971398139914001401140214031404140514061407140814091410141114121413141414151416141714181419142014211422142314241425142614271428142914301431143214331434143514361437143814391440144114421443144414451446144714481449145014511452145314541455145614571458145914601461146214631464146514661467146814691470147114721473147414751476147714781479148014811482148314841485148614871488148914901491149214931494149514961497149814991500150115021503150415051506150715081509151015111512151315141515151615171518151915201521152215231524152515261527152815291530153115321533153415351536153715381539154015411542154315441545154615471548154915501551155215531554155515561557155815591560156115621563156415651566156715681569157015711572157315741575157615771578157915801581
  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 "ns_turn_msg.h"
  31. #include "ns_turn_msg_addr.h"
  32. ///////////// Security functions implementation from ns_turn_msg.h ///////////
  33. #include <openssl/md5.h>
  34. #include <openssl/hmac.h>
  35. #include <openssl/ssl.h>
  36. #include <openssl/err.h>
  37. #include <openssl/rand.h>
  38. #include <stdlib.h>
  39. ///////////
  40. long turn_random(void)
  41. {
  42. long ret = 0;
  43. if(!RAND_bytes((unsigned char *)&ret,sizeof(ret)))
  44. ret = random();
  45. return ret;
  46. }
  47. void turn_random32_size(u32bits *ar, size_t sz)
  48. {
  49. if(!RAND_bytes((unsigned char *)ar, sz<<2)<0) {
  50. size_t i;
  51. for(i=0;i<sz;++i) {
  52. ar[i] = (u32bits)random();
  53. }
  54. }
  55. }
  56. int stun_calculate_hmac(const u08bits *buf, size_t len, const u08bits *key, size_t keylen, u08bits *hmac, unsigned int *hmac_len, SHATYPE shatype)
  57. {
  58. ERR_clear_error();
  59. UNUSED_ARG(shatype);
  60. #if !defined(OPENSSL_NO_SHA256) && defined(SSL_TXT_SHA256)
  61. if(shatype == SHATYPE_SHA256) {
  62. if (!HMAC(EVP_sha256(), key, keylen, buf, len, hmac, hmac_len)) {
  63. return -1;
  64. }
  65. } else
  66. #endif
  67. if (!HMAC(EVP_sha1(), key, keylen, buf, len, hmac, hmac_len)) {
  68. return -1;
  69. }
  70. return 0;
  71. }
  72. int stun_produce_integrity_key_str(u08bits *uname, u08bits *realm, u08bits *upwd, hmackey_t key, SHATYPE shatype)
  73. {
  74. ERR_clear_error();
  75. UNUSED_ARG(shatype);
  76. size_t ulen = strlen((s08bits*)uname);
  77. size_t rlen = strlen((s08bits*)realm);
  78. size_t plen = strlen((s08bits*)upwd);
  79. size_t sz = ulen+1+rlen+1+plen+1+10;
  80. size_t strl = ulen+1+rlen+1+plen;
  81. u08bits *str = (u08bits*)malloc(sz+1);
  82. strncpy((s08bits*)str,(s08bits*)uname,sz);
  83. str[ulen]=':';
  84. strncpy((s08bits*)str+ulen+1,(s08bits*)realm,sz-ulen-1);
  85. str[ulen+1+rlen]=':';
  86. strncpy((s08bits*)str+ulen+1+rlen+1,(s08bits*)upwd,sz-ulen-1-rlen-1);
  87. str[strl]=0;
  88. #if !defined(OPENSSL_NO_SHA256) && defined(SSL_TXT_SHA256)
  89. if(shatype == SHATYPE_SHA256) {
  90. unsigned int keylen = 0;
  91. EVP_MD_CTX ctx;
  92. EVP_DigestInit(&ctx,EVP_sha256());
  93. EVP_DigestUpdate(&ctx,str,strl);
  94. EVP_DigestFinal(&ctx,key,&keylen);
  95. } else
  96. #endif
  97. {
  98. MD5_CTX ctx;
  99. MD5_Init(&ctx);
  100. MD5_Update(&ctx,str,strl);
  101. MD5_Final(key,&ctx);
  102. }
  103. free(str);
  104. return 0;
  105. }
  106. /////////////////////////////////////////////////////////////////
  107. static u32bits ns_crc32(const u08bits *buffer, u32bits len);
  108. void print_hmac(const char *name, const void *s, size_t len);
  109. /////////////////////////////////////////////////////////////////
  110. int stun_get_command_message_len_str(const u08bits* buf, size_t len)
  111. {
  112. if (len < STUN_HEADER_LENGTH)
  113. return -1;
  114. return (int) (nswap16(((const u16bits*)(buf))[1]) + STUN_HEADER_LENGTH);
  115. }
  116. static int stun_set_command_message_len_str(u08bits* buf, int len) {
  117. if(len<STUN_HEADER_LENGTH) return -1;
  118. ((u16bits*)buf)[1]=nswap16((u16bits)(len-STUN_HEADER_LENGTH));
  119. return 0;
  120. }
  121. /////////// Low-level binary //////////////////////////////////////////////
  122. u16bits stun_make_type(u16bits method) {
  123. method = method & 0x0FFF;
  124. return ((method & 0x000F) | ((method & 0x0070)<<1) |
  125. ((method & 0x0380)<<2) | ((method & 0x0C00)<<2));
  126. }
  127. u16bits stun_get_method_str(const u08bits *buf, size_t len) {
  128. if(!buf || len<2) return (u16bits)-1;
  129. u16bits tt = nswap16(((const u16bits*)buf)[0]);
  130. return (tt & 0x000F) | ((tt & 0x00E0)>>1) |
  131. ((tt & 0x0E00)>>2) | ((tt & 0x3000)>>2);
  132. }
  133. u16bits stun_get_msg_type_str(const u08bits *buf, size_t len) {
  134. if(!buf || len<2) return (u16bits)-1;
  135. return ((nswap16(((const u16bits*)buf)[0])) & 0x3FFF);
  136. }
  137. int is_channel_msg_str(const u08bits* buf, size_t blen) {
  138. return (buf && blen>=4 && STUN_VALID_CHANNEL(nswap16(((const u16bits*)buf)[0])));
  139. }
  140. /////////////// message types /////////////////////////////////
  141. int stun_is_command_message_str(const u08bits* buf, size_t blen)
  142. {
  143. if (buf && blen >= STUN_HEADER_LENGTH) {
  144. if (!STUN_VALID_CHANNEL(nswap16(((const u16bits*)buf)[0]))) {
  145. if ((((u08bits) buf[0]) & ((u08bits) (0xC0))) == 0) {
  146. if (nswap32(((const u32bits*)(buf))[1])
  147. == STUN_MAGIC_COOKIE) {
  148. u16bits len = nswap16(((const u16bits*)(buf))[1]);
  149. if ((len & 0x0003) == 0) {
  150. if ((size_t) (len + STUN_HEADER_LENGTH) == blen) {
  151. return 1;
  152. }
  153. }
  154. }
  155. }
  156. }
  157. }
  158. return 0;
  159. }
  160. int old_stun_is_command_message_str(const u08bits* buf, size_t blen, u32bits *cookie)
  161. {
  162. if (buf && blen >= STUN_HEADER_LENGTH) {
  163. if (!STUN_VALID_CHANNEL(nswap16(((const u16bits*)buf)[0]))) {
  164. if ((((u08bits) buf[0]) & ((u08bits) (0xC0))) == 0) {
  165. if (nswap32(((const u32bits*)(buf))[1])
  166. != STUN_MAGIC_COOKIE) {
  167. u16bits len = nswap16(((const u16bits*)(buf))[1]);
  168. if ((len & 0x0003) == 0) {
  169. if ((size_t) (len + STUN_HEADER_LENGTH) == blen) {
  170. *cookie = nswap32(((const u32bits*)(buf))[1]);
  171. return 1;
  172. }
  173. }
  174. }
  175. }
  176. }
  177. }
  178. return 0;
  179. }
  180. int stun_is_command_message_full_check_str(const u08bits* buf, size_t blen, int must_check_fingerprint, int *fingerprint_present) {
  181. if(!stun_is_command_message_str(buf,blen))
  182. return 0;
  183. stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, blen, STUN_ATTRIBUTE_FINGERPRINT);
  184. if(!sar) {
  185. if(fingerprint_present)
  186. *fingerprint_present = 0;
  187. if(stun_get_method_str(buf,blen) == STUN_METHOD_BINDING) {
  188. return 1;
  189. }
  190. return !must_check_fingerprint;
  191. }
  192. if(stun_attr_get_len(sar) != 4)
  193. return 0;
  194. const u32bits* fingerprint = (const u32bits*)stun_attr_get_value(sar);
  195. if(!fingerprint)
  196. return !must_check_fingerprint;
  197. u32bits crc32len = (u32bits)((((const u08bits*)fingerprint)-buf)-4);
  198. int ret = (*fingerprint == nswap32(ns_crc32(buf,crc32len) ^ ((u32bits)0x5354554e)));
  199. if(ret && fingerprint_present)
  200. *fingerprint_present = ret;
  201. return ret;
  202. }
  203. int stun_is_command_message_offset_str(const u08bits* buf, size_t blen, int offset) {
  204. return stun_is_command_message_str(buf + offset, blen);
  205. }
  206. int stun_is_request_str(const u08bits* buf, size_t len) {
  207. if(is_channel_msg_str(buf,len)) return 0;
  208. return IS_STUN_REQUEST(stun_get_msg_type_str(buf,len));
  209. }
  210. int stun_is_success_response_str(const u08bits* buf, size_t len) {
  211. if(is_channel_msg_str(buf,len)) return 0;
  212. return IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len));
  213. }
  214. int stun_is_error_response_str(const u08bits* buf, size_t len, int *err_code, u08bits *err_msg, size_t err_msg_size) {
  215. if(is_channel_msg_str(buf,len)) return 0;
  216. if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) {
  217. if(err_code) {
  218. stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE);
  219. if(sar) {
  220. if(stun_attr_get_len(sar)>=4) {
  221. const u08bits* val = (const u08bits*)stun_attr_get_value(sar);
  222. *err_code=(int)(val[2]*100 + val[3]);
  223. if(err_msg && err_msg_size>0) {
  224. err_msg[0]=0;
  225. if(stun_attr_get_len(sar)>4) {
  226. size_t msg_len = stun_attr_get_len(sar) - 4;
  227. if(msg_len>(err_msg_size-1))
  228. msg_len=err_msg_size - 1;
  229. ns_bcopy(val+4, err_msg, msg_len);
  230. err_msg[msg_len]=0;
  231. }
  232. }
  233. }
  234. }
  235. }
  236. return 1;
  237. }
  238. return 0;
  239. }
  240. int stun_is_challenge_response_str(const u08bits* buf, size_t len, int *err_code, u08bits *err_msg, size_t err_msg_size,
  241. u08bits *realm, u08bits *nonce)
  242. {
  243. int ret = stun_is_error_response_str(buf, len, err_code, err_msg, err_msg_size);
  244. if(ret && (((*err_code) == 401) || ((*err_code) == 438) || ((*err_code) == SHA_TOO_WEAK_ERROR_CODE))) {
  245. stun_attr_ref sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_REALM);
  246. if(sar) {
  247. const u08bits *value = stun_attr_get_value(sar);
  248. if(value) {
  249. size_t vlen = (size_t)stun_attr_get_len(sar);
  250. ns_bcopy(value,realm,vlen);
  251. realm[vlen]=0;
  252. sar = stun_attr_get_first_by_type_str(buf,len,STUN_ATTRIBUTE_NONCE);
  253. if(sar) {
  254. value = stun_attr_get_value(sar);
  255. if(value) {
  256. vlen = (size_t)stun_attr_get_len(sar);
  257. ns_bcopy(value,nonce,vlen);
  258. nonce[vlen]=0;
  259. return 1;
  260. }
  261. }
  262. }
  263. }
  264. }
  265. return 0;
  266. }
  267. int stun_is_response_str(const u08bits* buf, size_t len) {
  268. if(is_channel_msg_str(buf,len)) return 0;
  269. if(IS_STUN_SUCCESS_RESP(stun_get_msg_type_str(buf,len))) return 1;
  270. if(IS_STUN_ERR_RESP(stun_get_msg_type_str(buf,len))) return 1;
  271. return 0;
  272. }
  273. int stun_is_indication_str(const u08bits* buf, size_t len) {
  274. if(is_channel_msg_str(buf,len)) return 0;
  275. return IS_STUN_INDICATION(stun_get_msg_type_str(buf,len));
  276. }
  277. u16bits stun_make_request(u16bits method) {
  278. return GET_STUN_REQUEST(stun_make_type(method));
  279. }
  280. u16bits stun_make_indication(u16bits method) {
  281. return GET_STUN_INDICATION(stun_make_type(method));
  282. }
  283. u16bits stun_make_success_response(u16bits method) {
  284. return GET_STUN_SUCCESS_RESP(stun_make_type(method));
  285. }
  286. u16bits stun_make_error_response(u16bits method) {
  287. return GET_STUN_ERR_RESP(stun_make_type(method));
  288. }
  289. //////////////// INIT ////////////////////////////////////////////
  290. void stun_init_buffer_str(u08bits *buf, size_t *len) {
  291. *len=STUN_HEADER_LENGTH;
  292. ns_bzero(buf,*len);
  293. }
  294. void stun_init_command_str(u16bits message_type, u08bits* buf, size_t *len) {
  295. stun_init_buffer_str(buf,len);
  296. message_type &= (u16bits)(0x3FFF);
  297. ((u16bits*)buf)[0]=nswap16(message_type);
  298. ((u16bits*)buf)[1]=0;
  299. ((u32bits*)buf)[1]=nswap32(STUN_MAGIC_COOKIE);
  300. stun_tid_generate_in_message_str(buf,NULL);
  301. }
  302. void old_stun_init_command_str(u16bits message_type, u08bits* buf, size_t *len, u32bits cookie) {
  303. stun_init_buffer_str(buf,len);
  304. message_type &= (u16bits)(0x3FFF);
  305. ((u16bits*)buf)[0]=nswap16(message_type);
  306. ((u16bits*)buf)[1]=0;
  307. ((u32bits*)buf)[1]=nswap32(cookie);
  308. stun_tid_generate_in_message_str(buf,NULL);
  309. }
  310. void stun_init_request_str(u16bits method, u08bits* buf, size_t *len) {
  311. stun_init_command_str(stun_make_request(method), buf, len);
  312. }
  313. void stun_init_indication_str(u16bits method, u08bits* buf, size_t *len) {
  314. stun_init_command_str(stun_make_indication(method), buf, len);
  315. }
  316. void stun_init_success_response_str(u16bits method, u08bits* buf, size_t *len, stun_tid* id) {
  317. stun_init_command_str(stun_make_success_response(method), buf, len);
  318. if(id) {
  319. stun_tid_message_cpy(buf, id);
  320. }
  321. }
  322. void old_stun_init_success_response_str(u16bits method, u08bits* buf, size_t *len, stun_tid* id, u32bits cookie) {
  323. old_stun_init_command_str(stun_make_success_response(method), buf, len, cookie);
  324. if(id) {
  325. stun_tid_message_cpy(buf, id);
  326. }
  327. }
  328. static void stun_init_error_response_common_str(u08bits* buf, size_t *len,
  329. u16bits error_code, const u08bits *reason,
  330. stun_tid* id)
  331. {
  332. if (!reason) {
  333. switch (error_code){
  334. case 300:
  335. reason = (const u08bits *) "Try Alternate";
  336. break;
  337. case 400:
  338. reason = (const u08bits *) "Bad Request";
  339. break;
  340. case 401:
  341. reason = (const u08bits *) "Unauthorized";
  342. break;
  343. case 404:
  344. reason = (const u08bits *) "Not Found";
  345. break;
  346. case 420:
  347. reason = (const u08bits *) "Unknown Attribute";
  348. break;
  349. case 438:
  350. reason = (const u08bits *) "Stale Nonce";
  351. break;
  352. case 500:
  353. reason = (const u08bits *) "Server Error";
  354. break;
  355. default:
  356. reason = (const u08bits *) "Unknown Error";
  357. break;
  358. };
  359. }
  360. u08bits avalue[513];
  361. avalue[0] = 0;
  362. avalue[1] = 0;
  363. avalue[2] = (u08bits) (error_code / 100);
  364. avalue[3] = (u08bits) (error_code % 100);
  365. strncpy((s08bits*) (avalue + 4), (const s08bits*) reason, sizeof(avalue)-4);
  366. avalue[sizeof(avalue)-1]=0;
  367. int alen = 4 + strlen((const s08bits*) (avalue+4));
  368. //"Manual" padding for compatibility with classic old stun:
  369. {
  370. int rem = alen % 4;
  371. if(rem) {
  372. alen +=(4-rem);
  373. }
  374. }
  375. stun_attr_add_str(buf, len, STUN_ATTRIBUTE_ERROR_CODE, (u08bits*) avalue, alen);
  376. if (id) {
  377. stun_tid_message_cpy(buf, id);
  378. }
  379. }
  380. void old_stun_init_error_response_str(u16bits method, u08bits* buf, size_t *len,
  381. u16bits error_code, const u08bits *reason,
  382. stun_tid* id, u32bits cookie)
  383. {
  384. old_stun_init_command_str(stun_make_error_response(method), buf, len, cookie);
  385. stun_init_error_response_common_str(buf, len,
  386. error_code, reason,
  387. id);
  388. }
  389. void stun_init_error_response_str(u16bits method, u08bits* buf, size_t *len,
  390. u16bits error_code, const u08bits *reason,
  391. stun_tid* id)
  392. {
  393. stun_init_command_str(stun_make_error_response(method), buf, len);
  394. stun_init_error_response_common_str(buf, len,
  395. error_code, reason,
  396. id);
  397. }
  398. /////////// CHANNEL ////////////////////////////////////////////////
  399. int stun_init_channel_message_str(u16bits chnumber, u08bits* buf, size_t *len, int length, int do_padding)
  400. {
  401. u16bits rlen = (u16bits)length;
  402. if(length<0 || (MAX_STUN_MESSAGE_SIZE<(4+length))) return -1;
  403. ((u16bits*)(buf))[0]=nswap16(chnumber);
  404. ((u16bits*)(buf))[1]=nswap16((u16bits)length);
  405. if(do_padding && (rlen & 0x0003))
  406. rlen = ((rlen>>2)+1)<<2;
  407. *len=4+rlen;
  408. return 0;
  409. }
  410. int stun_is_channel_message_str(const u08bits *buf, size_t *blen, u16bits* chnumber, int mandatory_padding)
  411. {
  412. u16bits datalen_header;
  413. u16bits datalen_actual;
  414. if (!blen || (*blen < 4))
  415. return 0;
  416. u16bits chn = nswap16(((const u16bits*)(buf))[0]);
  417. if (!STUN_VALID_CHANNEL(chn))
  418. return 0;
  419. if(*blen>(u16bits)-1)
  420. *blen=(u16bits)-1;
  421. datalen_actual = (u16bits)(*blen) - 4;
  422. datalen_header = ((const u16bits*)buf)[1];
  423. datalen_header = nswap16(datalen_header);
  424. if (datalen_header > datalen_actual)
  425. return 0;
  426. if (datalen_header != datalen_actual) {
  427. /* maybe there are padding bytes for 32-bit alignment. Mandatory for TCP. Optional for UDP */
  428. if(datalen_actual & 0x0003) {
  429. if(mandatory_padding) {
  430. return 0;
  431. } else if ((datalen_actual < datalen_header) || (datalen_header == 0)) {
  432. return 0;
  433. } else {
  434. u16bits diff = datalen_actual - datalen_header;
  435. if (diff > 3)
  436. return 0;
  437. }
  438. }
  439. }
  440. *blen = datalen_header + 4;
  441. if (chnumber)
  442. *chnumber = chn;
  443. return 1;
  444. }
  445. ////////// STUN message ///////////////////////////////
  446. static inline int sheadof(const char *head, const char* full)
  447. {
  448. while(*head) {
  449. if(*head != *full)
  450. return 0;
  451. ++head;++full;
  452. }
  453. return 1;
  454. }
  455. static inline const char* findstr(const char *hay, size_t slen, const char *needle)
  456. {
  457. const char *ret = NULL;
  458. if(hay && slen && needle) {
  459. size_t nlen=strlen(needle);
  460. if(nlen<=slen) {
  461. size_t smax = slen-nlen+1;
  462. size_t i;
  463. const char *sp = hay;
  464. for(i=0;i<smax;++i) {
  465. if(sheadof(needle,sp+i)) {
  466. ret = sp+i;
  467. break;
  468. }
  469. }
  470. }
  471. }
  472. return ret;
  473. }
  474. static inline int is_http_get_inline(const char *s, size_t blen) {
  475. if(s && blen>=12) {
  476. if((s[0]=='G')&&(s[1]=='E')&&(s[2]=='T')&&(s[3]==' ')) {
  477. const char *sp=findstr(s+4,blen-4,"HTTP");
  478. if(sp) {
  479. sp += 4;
  480. size_t diff_blen = sp-s;
  481. if(diff_blen+4 <= blen) {
  482. sp=findstr(sp,blen-diff_blen,"\r\n\r\n");
  483. if(sp) {
  484. return (int)(sp-s+4);
  485. }
  486. }
  487. }
  488. }
  489. }
  490. return 0;
  491. }
  492. int is_http_get(const char *s, size_t blen) {
  493. return is_http_get_inline(s, blen);
  494. }
  495. int stun_get_message_len_str(u08bits *buf, size_t blen, int padding, size_t *app_len) {
  496. if (buf && blen) {
  497. /* STUN request/response ? */
  498. if (buf && blen >= STUN_HEADER_LENGTH) {
  499. if (!STUN_VALID_CHANNEL(nswap16(((const u16bits*)buf)[0]))) {
  500. if ((((u08bits) buf[0]) & ((u08bits) (0xC0))) == 0) {
  501. if (nswap32(((const u32bits*)(buf))[1])
  502. == STUN_MAGIC_COOKIE) {
  503. u16bits len = nswap16(((const u16bits*)(buf))[1]);
  504. if ((len & 0x0003) == 0) {
  505. len += STUN_HEADER_LENGTH;
  506. if ((size_t) len <= blen) {
  507. *app_len = (size_t)len;
  508. return (int)len;
  509. }
  510. }
  511. }
  512. }
  513. }
  514. }
  515. //HTTP request ?
  516. {
  517. int http_len = is_http_get_inline(((char*)buf), blen);
  518. if((http_len>0) && ((size_t)http_len<=blen)) {
  519. *app_len = (size_t)http_len;
  520. return http_len;
  521. }
  522. }
  523. /* STUN channel ? */
  524. if(blen>=4) {
  525. u16bits chn=nswap16(((const u16bits*)(buf))[0]);
  526. if(STUN_VALID_CHANNEL(chn)) {
  527. u16bits bret = (4+(nswap16(((const u16bits*)(buf))[1])));
  528. *app_len = bret;
  529. if(padding && (bret & 0x0003)) {
  530. bret = ((bret>>2)+1)<<2;
  531. }
  532. if(bret<=blen) {
  533. return bret;
  534. }
  535. }
  536. }
  537. }
  538. return -1;
  539. }
  540. ////////// ALLOCATE ///////////////////////////////////
  541. int stun_set_allocate_request_str(u08bits* buf, size_t *len, u32bits lifetime, int address_family,
  542. u08bits transport, int mobile) {
  543. stun_init_request_str(STUN_METHOD_ALLOCATE, buf, len);
  544. //REQUESTED-TRANSPORT
  545. {
  546. u08bits field[4];
  547. field[0]=transport;
  548. field[1]=0;
  549. field[2]=0;
  550. field[3]=0;
  551. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_TRANSPORT,field,sizeof(field))<0) return -1;
  552. }
  553. //LIFETIME
  554. {
  555. if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME;
  556. u32bits field=nswap32(lifetime);
  557. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(u08bits*)(&field),sizeof(field))<0) return -1;
  558. }
  559. if(mobile) {
  560. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(const u08bits*)"",0)<0) return -1;
  561. }
  562. //ADRESS-FAMILY
  563. switch (address_family) {
  564. case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4:
  565. case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6:
  566. {
  567. u08bits field[4];
  568. field[0] = (u08bits)address_family;
  569. field[1]=0;
  570. field[2]=0;
  571. field[3]=0;
  572. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY,field,sizeof(field))<0) return -1;
  573. break;
  574. }
  575. case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT:
  576. /* ignore */
  577. break;
  578. default:
  579. return -1;
  580. };
  581. return 0;
  582. }
  583. int stun_set_allocate_response_str(u08bits* buf, size_t *len, stun_tid* tid,
  584. const ioa_addr *relayed_addr, const ioa_addr *reflexive_addr,
  585. u32bits lifetime, int error_code, const u08bits *reason,
  586. u64bits reservation_token, char* mobile_id) {
  587. if(!error_code) {
  588. stun_init_success_response_str(STUN_METHOD_ALLOCATE, buf, len, tid);
  589. if(relayed_addr) {
  590. if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS,relayed_addr)<0) return -1;
  591. }
  592. if(reflexive_addr) {
  593. if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS,reflexive_addr)<0) return -1;
  594. }
  595. if(reservation_token) {
  596. reservation_token=nswap64(reservation_token);
  597. stun_attr_add_str(buf,len,STUN_ATTRIBUTE_RESERVATION_TOKEN,(u08bits*)(&reservation_token),8);
  598. }
  599. {
  600. if(lifetime<1) lifetime=STUN_DEFAULT_ALLOCATE_LIFETIME;
  601. else if(lifetime>STUN_MAX_ALLOCATE_LIFETIME) lifetime = STUN_MAX_ALLOCATE_LIFETIME;
  602. u32bits field=nswap32(lifetime);
  603. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_LIFETIME,(u08bits*)(&field),sizeof(field))<0) return -1;
  604. }
  605. if(mobile_id && *mobile_id) {
  606. if(stun_attr_add_str(buf,len,STUN_ATTRIBUTE_MOBILITY_TICKET,(u08bits*)mobile_id,strlen(mobile_id))<0) return -1;
  607. }
  608. } else {
  609. stun_init_error_response_str(STUN_METHOD_ALLOCATE, buf, len, error_code, reason, tid);
  610. }
  611. return 0;
  612. }
  613. /////////////// CHANNEL BIND ///////////////////////////////////////
  614. u16bits stun_set_channel_bind_request_str(u08bits* buf, size_t *len,
  615. const ioa_addr* peer_addr, u16bits channel_number) {
  616. if(!STUN_VALID_CHANNEL(channel_number)) {
  617. channel_number = 0x4000 + ((u16bits)(((u32bits)turn_random())%(0x7FFF-0x4000+1)));
  618. }
  619. stun_init_request_str(STUN_METHOD_CHANNEL_BIND, buf, len);
  620. if(stun_attr_add_channel_number_str(buf, len, channel_number)<0) return 0;
  621. if(!peer_addr) {
  622. ioa_addr ca;
  623. ns_bzero(&ca,sizeof(ioa_addr));
  624. if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, &ca)<0) return 0;
  625. } else {
  626. if(stun_attr_add_addr_str(buf,len,STUN_ATTRIBUTE_XOR_PEER_ADDRESS, peer_addr)<0) return 0;
  627. }
  628. return channel_number;
  629. }
  630. void stun_set_channel_bind_response_str(u08bits* buf, size_t *len, stun_tid* tid, int error_code, const u08bits *reason) {
  631. if(!error_code) {
  632. stun_init_success_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, tid);
  633. } else {
  634. stun_init_error_response_str(STUN_METHOD_CHANNEL_BIND, buf, len, error_code, reason, tid);
  635. }
  636. }
  637. /////////////// BINDING ///////////////////////////////////////
  638. void stun_set_binding_request_str(u08bits* buf, size_t *len) {
  639. stun_init_request_str(STUN_METHOD_BINDING, buf, len);
  640. }
  641. int stun_set_binding_response_str(u08bits* buf, size_t *len, stun_tid* tid,
  642. const ioa_addr *reflexive_addr, int error_code, const u08bits *reason,
  643. u32bits cookie, int old_stun)
  644. {
  645. if (!error_code) {
  646. if (!old_stun) {
  647. stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid);
  648. } else {
  649. old_stun_init_success_response_str(STUN_METHOD_BINDING, buf, len, tid, cookie);
  650. }
  651. if(!old_stun) {
  652. if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS, reflexive_addr) < 0)
  653. return -1;
  654. }
  655. if (stun_attr_add_addr_str(buf, len, STUN_ATTRIBUTE_MAPPED_ADDRESS, reflexive_addr) < 0)
  656. return -1;
  657. } else if (!old_stun) {
  658. stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid);
  659. } else {
  660. old_stun_init_error_response_str(STUN_METHOD_BINDING, buf, len, error_code, reason, tid, cookie);
  661. }
  662. return 0;
  663. }
  664. int stun_is_binding_request_str(const u08bits* buf, size_t len, size_t offset)
  665. {
  666. if(offset < len) {
  667. buf += offset;
  668. len -= offset;
  669. if (stun_is_command_message_str(buf, len)) {
  670. if (stun_is_request_str(buf, len) && (stun_get_method_str(buf, len) == STUN_METHOD_BINDING)) {
  671. return 1;
  672. }
  673. }
  674. }
  675. return 0;
  676. }
  677. int stun_is_binding_response_str(const u08bits* buf, size_t len) {
  678. if(stun_is_command_message_str(buf,len) &&
  679. (stun_get_method_str(buf,len)==STUN_METHOD_BINDING)) {
  680. if(stun_is_response_str(buf,len)) {
  681. return 1;
  682. }
  683. }
  684. return 0;
  685. }
  686. /////////////////////////////// TID ///////////////////////////////
  687. int stun_tid_equals(const stun_tid *id1, const stun_tid *id2) {
  688. if(id1==id2) return 1;
  689. if(!id1) return 0;
  690. if(!id2) return 0;
  691. {
  692. unsigned int i=0;
  693. for(i=0;i<STUN_TID_SIZE;++i) {
  694. if(id1->tsx_id[i]!=id2->tsx_id[i]) return 0;
  695. }
  696. }
  697. return 1;
  698. }
  699. void stun_tid_cpy(stun_tid *id1, const stun_tid *id2) {
  700. if(!id1) return;
  701. if(!id2) return;
  702. ns_bcopy((const void*)(id2->tsx_id),(void*)(id1->tsx_id),STUN_TID_SIZE);
  703. }
  704. static void stun_tid_string_cpy(u08bits* s, const stun_tid* id) {
  705. if(s && id) {
  706. ns_bcopy((const void*)(id->tsx_id),s,STUN_TID_SIZE);
  707. }
  708. }
  709. static void stun_tid_from_string(const u08bits* s, stun_tid* id) {
  710. if(s && id) {
  711. ns_bcopy(s,(void*)(id->tsx_id),STUN_TID_SIZE);
  712. }
  713. }
  714. void stun_tid_from_message_str(const u08bits* buf, size_t len, stun_tid* id) {
  715. UNUSED_ARG(len);
  716. stun_tid_from_string(buf+8, id);
  717. }
  718. void stun_tid_message_cpy(u08bits* buf, const stun_tid* id) {
  719. if(buf && id) {
  720. stun_tid_string_cpy(buf+8, id);
  721. }
  722. }
  723. void stun_tid_generate(stun_tid* id) {
  724. if(id) {
  725. u32bits *w=(u32bits*)(id->tsx_id);
  726. turn_random32_size(w,3);
  727. }
  728. }
  729. void stun_tid_generate_in_message_str(u08bits* buf, stun_tid* id) {
  730. stun_tid tmp;
  731. if(!id) id=&tmp;
  732. stun_tid_generate(id);
  733. stun_tid_message_cpy(buf, id);
  734. }
  735. /////////////////// TIME ////////////////////////////////////////////////////////
  736. u32bits stun_adjust_allocate_lifetime(u32bits lifetime) {
  737. if(!lifetime) return STUN_DEFAULT_ALLOCATE_LIFETIME;
  738. else if(lifetime<STUN_MIN_ALLOCATE_LIFETIME) return STUN_MIN_ALLOCATE_LIFETIME;
  739. else if(lifetime>STUN_MAX_ALLOCATE_LIFETIME) return STUN_MAX_ALLOCATE_LIFETIME;
  740. return lifetime;
  741. }
  742. ////////////// ATTR /////////////////////////////////////////////////////////////
  743. int stun_attr_get_type(stun_attr_ref attr) {
  744. if(attr)
  745. return (int)(nswap16(((const u16bits*)attr)[0]));
  746. return -1;
  747. }
  748. int stun_attr_get_len(stun_attr_ref attr) {
  749. if(attr)
  750. return (int)(nswap16(((const u16bits*)attr)[1]));
  751. return -1;
  752. }
  753. const u08bits* stun_attr_get_value(stun_attr_ref attr) {
  754. if(attr) {
  755. int len = (int)(nswap16(((const u16bits*)attr)[1]));
  756. if(len<1) return NULL;
  757. return ((const u08bits*)attr)+4;
  758. }
  759. return NULL;
  760. }
  761. int stun_get_requested_address_family(stun_attr_ref attr)
  762. {
  763. if (attr) {
  764. int len = (int) (nswap16(((const u16bits*)attr)[1]));
  765. if (len != 4)
  766. return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID;
  767. int val = ((const u08bits*) attr)[4];
  768. switch (val){
  769. case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV4:
  770. return val;
  771. case STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_IPV6:
  772. return val;
  773. default:
  774. return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_INVALID;
  775. };
  776. }
  777. return STUN_ATTRIBUTE_REQUESTED_ADDRESS_FAMILY_VALUE_DEFAULT;
  778. }
  779. u16bits stun_attr_get_channel_number(stun_attr_ref attr) {
  780. if(attr) {
  781. const u08bits* value = stun_attr_get_value(attr);
  782. if(value && (stun_attr_get_len(attr) >= 2)) {
  783. u16bits cn=nswap16(((const u16bits*)value)[0]);
  784. if(STUN_VALID_CHANNEL(cn)) return cn;
  785. }
  786. }
  787. return 0;
  788. }
  789. band_limit_t stun_attr_get_bandwidth(stun_attr_ref attr) {
  790. if(attr) {
  791. const u08bits* value = stun_attr_get_value(attr);
  792. if(value && (stun_attr_get_len(attr) >= 4)) {
  793. u32bits bps=nswap32(((const u32bits*)value)[0]);
  794. return (band_limit_t)(bps << 7);
  795. }
  796. }
  797. return 0;
  798. }
  799. u64bits stun_attr_get_reservation_token_value(stun_attr_ref attr) {
  800. if(attr) {
  801. const u08bits* value = stun_attr_get_value(attr);
  802. if(value && (stun_attr_get_len(attr) == 8)) {
  803. return nswap64(((const u64bits*)value)[0]);
  804. }
  805. }
  806. return 0;
  807. }
  808. int stun_attr_is_addr(stun_attr_ref attr) {
  809. if(attr) {
  810. switch(stun_attr_get_type(attr)) {
  811. case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
  812. case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
  813. case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
  814. case STUN_ATTRIBUTE_MAPPED_ADDRESS:
  815. case STUN_ATTRIBUTE_ALTERNATE_SERVER:
  816. case OLD_STUN_ATTRIBUTE_RESPONSE_ADDRESS:
  817. case OLD_STUN_ATTRIBUTE_SOURCE_ADDRESS:
  818. case OLD_STUN_ATTRIBUTE_CHANGED_ADDRESS:
  819. case OLD_STUN_ATTRIBUTE_REFLECTED_FROM:
  820. case STUN_ATTRIBUTE_RESPONSE_ORIGIN:
  821. case STUN_ATTRIBUTE_OTHER_ADDRESS:
  822. return 1;
  823. break;
  824. default:
  825. ;
  826. };
  827. }
  828. return 0;
  829. }
  830. u08bits stun_attr_get_even_port(stun_attr_ref attr) {
  831. if(attr) {
  832. const u08bits* value=stun_attr_get_value(attr);
  833. if(value) {
  834. if((u08bits)(value[0]) > 0x7F) return 1;
  835. }
  836. }
  837. return 0;
  838. }
  839. stun_attr_ref stun_attr_get_first_by_type_str(const u08bits* buf, size_t len, u16bits attr_type) {
  840. stun_attr_ref attr=stun_attr_get_first_str(buf,len);
  841. while(attr) {
  842. if(stun_attr_get_type(attr) == attr_type) {
  843. return attr;
  844. }
  845. attr=stun_attr_get_next_str(buf,len,attr);
  846. }
  847. return NULL;
  848. }
  849. stun_attr_ref stun_attr_get_first_str(const u08bits* buf, size_t len) {
  850. if(stun_get_command_message_len_str(buf,len)>STUN_HEADER_LENGTH) {
  851. return (stun_attr_ref)(buf+STUN_HEADER_LENGTH);
  852. }
  853. return NULL;
  854. }
  855. stun_attr_ref stun_attr_get_next_str(const u08bits* buf, size_t len, stun_attr_ref prev) {
  856. if(!prev) return stun_attr_get_first_str(buf,len);
  857. else {
  858. const u08bits* end = buf + stun_get_command_message_len_str(buf,len);
  859. int attrlen=stun_attr_get_len(prev);
  860. u16bits rem4 = ((u16bits)attrlen) & 0x0003;
  861. if(rem4) {
  862. attrlen = attrlen+4-(int)rem4;
  863. }
  864. const u08bits* attr_end=(const u08bits*)prev+4+attrlen;
  865. if(attr_end<end) return attr_end;
  866. return NULL;
  867. }
  868. }
  869. int stun_attr_add_str(u08bits* buf, size_t *len, u16bits attr, const u08bits* avalue, int alen) {
  870. if(alen<0) alen=0;
  871. u08bits tmp[1];
  872. if(!avalue) {
  873. alen=0;
  874. avalue=tmp;
  875. }
  876. int clen = stun_get_command_message_len_str(buf,*len);
  877. int newlen = clen + 4 + alen;
  878. int newlenrem4=newlen & 0x00000003;
  879. if(newlenrem4) {
  880. newlen=newlen+(4-newlenrem4);
  881. }
  882. if(newlen>=MAX_STUN_MESSAGE_SIZE) return -1;
  883. else {
  884. u08bits* attr_start=buf+clen;
  885. u16bits *attr_start_16t=(u16bits*)attr_start;
  886. stun_set_command_message_len_str(buf,newlen);
  887. *len = newlen;
  888. attr_start_16t[0]=nswap16(attr);
  889. attr_start_16t[1]=nswap16(alen);
  890. if(alen>0) ns_bcopy(avalue,attr_start+4,alen);
  891. return 0;
  892. }
  893. }
  894. int stun_attr_add_addr_str(u08bits *buf, size_t *len, u16bits attr_type, const ioa_addr* ca) {
  895. stun_tid tid;
  896. stun_tid_from_message_str(buf, *len, &tid);
  897. int xor_ed=0;
  898. switch(attr_type) {
  899. case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
  900. case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
  901. case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
  902. xor_ed=1;
  903. break;
  904. default:
  905. ;
  906. };
  907. ioa_addr public_addr;
  908. map_addr_from_private_to_public(ca,&public_addr);
  909. u08bits cfield[64];
  910. int clen=0;
  911. if(stun_addr_encode(&public_addr, cfield, &clen, xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) {
  912. return -1;
  913. }
  914. if(stun_attr_add_str(buf,len,attr_type,(u08bits*)(&cfield),clen)<0) return -1;
  915. return 0;
  916. }
  917. int stun_attr_get_addr_str(const u08bits *buf, size_t len, stun_attr_ref attr, ioa_addr* ca, const ioa_addr *default_addr) {
  918. stun_tid tid;
  919. stun_tid_from_message_str(buf, len, &tid);
  920. ioa_addr public_addr;
  921. ns_bzero(ca,sizeof(ioa_addr));
  922. int attr_type = stun_attr_get_type(attr);
  923. if(attr_type<0) return -1;
  924. int xor_ed=0;
  925. switch(attr_type) {
  926. case STUN_ATTRIBUTE_XOR_MAPPED_ADDRESS:
  927. case STUN_ATTRIBUTE_XOR_PEER_ADDRESS:
  928. case STUN_ATTRIBUTE_XOR_RELAYED_ADDRESS:
  929. xor_ed=1;
  930. break;
  931. default:
  932. ;
  933. };
  934. const u08bits *cfield=stun_attr_get_value(attr);
  935. if(!cfield) return -1;
  936. if(stun_addr_decode(&public_addr, cfield, stun_attr_get_len(attr), xor_ed, STUN_MAGIC_COOKIE, tid.tsx_id)<0) {
  937. return -1;
  938. }
  939. map_addr_from_public_to_private(&public_addr, ca);
  940. if(default_addr && addr_any_no_port(ca) && !addr_any_no_port(default_addr)) {
  941. int port = addr_get_port(ca);
  942. addr_cpy(ca,default_addr);
  943. addr_set_port(ca,port);
  944. }
  945. return 0;
  946. }
  947. int stun_attr_get_first_addr_str(const u08bits *buf, size_t len, u16bits attr_type, ioa_addr* ca, const ioa_addr *default_addr) {
  948. stun_attr_ref attr=stun_attr_get_first_str(buf,len);
  949. while(attr) {
  950. if(stun_attr_is_addr(attr) && (attr_type == stun_attr_get_type(attr))) {
  951. if(stun_attr_get_addr_str(buf,len,attr,ca,default_addr)==0) {
  952. return 0;
  953. }
  954. }
  955. attr=stun_attr_get_next_str(buf,len,attr);
  956. }
  957. return -1;
  958. }
  959. int stun_attr_add_channel_number_str(u08bits* buf, size_t *len, u16bits chnumber) {
  960. u16bits field[2];
  961. field[0]=nswap16(chnumber);
  962. field[1]=0;
  963. return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_CHANNEL_NUMBER,(u08bits*)(field),sizeof(field));
  964. }
  965. int stun_attr_add_bandwidth_str(u08bits* buf, size_t *len, band_limit_t bps0) {
  966. u32bits bps = (band_limit_t)(bps0 >> 7);
  967. u32bits field=nswap32(bps);
  968. return stun_attr_add_str(buf,len,STUN_ATTRIBUTE_NEW_BANDWIDTH,(u08bits*)(&field),sizeof(field));
  969. }
  970. u16bits stun_attr_get_first_channel_number_str(const u08bits *buf, size_t len) {
  971. stun_attr_ref attr=stun_attr_get_first_str(buf,len);
  972. while(attr) {
  973. if(stun_attr_get_type(attr) == STUN_ATTRIBUTE_CHANNEL_NUMBER) {
  974. u16bits ret = stun_attr_get_channel_number(attr);
  975. if(STUN_VALID_CHANNEL(ret)) {
  976. return ret;
  977. }
  978. }
  979. attr=stun_attr_get_next_str(buf,len,attr);
  980. }
  981. return 0;
  982. }
  983. ////////////// FINGERPRINT ////////////////////////////
  984. int stun_attr_add_fingerprint_str(u08bits *buf, size_t *len)
  985. {
  986. u32bits crc32 = 0;
  987. stun_attr_add_str(buf, len, STUN_ATTRIBUTE_FINGERPRINT, (u08bits*)&crc32, 4);
  988. crc32 = ns_crc32(buf,*len-8);
  989. *((u32bits*)(buf+*len-4)) = nswap32(crc32 ^ ((u32bits)0x5354554e));
  990. return 0;
  991. }
  992. ////////////// CRC ///////////////////////////////////////////////
  993. #define CRC_MASK 0xFFFFFFFFUL
  994. #define UPDATE_CRC(crc, c) crc = crctable[(u08bits)crc ^ (u08bits)(c)] ^ (crc >> 8)
  995. static const u32bits crctable[256] = {
  996. 0x00000000, 0x77073096, 0xee0e612c, 0x990951ba,
  997. 0x076dc419, 0x706af48f, 0xe963a535, 0x9e6495a3,
  998. 0x0edb8832, 0x79dcb8a4, 0xe0d5e91e, 0x97d2d988,
  999. 0x09b64c2b, 0x7eb17cbd, 0xe7b82d07, 0x90bf1d91,
  1000. 0x1db71064, 0x6ab020f2, 0xf3b97148, 0x84be41de,
  1001. 0x1adad47d, 0x6ddde4eb, 0xf4d4b551, 0x83d385c7,
  1002. 0x136c9856, 0x646ba8c0, 0xfd62f97a, 0x8a65c9ec,
  1003. 0x14015c4f, 0x63066cd9, 0xfa0f3d63, 0x8d080df5,
  1004. 0x3b6e20c8, 0x4c69105e, 0xd56041e4, 0xa2677172,
  1005. 0x3c03e4d1, 0x4b04d447, 0xd20d85fd, 0xa50ab56b,
  1006. 0x35b5a8fa, 0x42b2986c, 0xdbbbc9d6, 0xacbcf940,
  1007. 0x32d86ce3, 0x45df5c75, 0xdcd60dcf, 0xabd13d59,
  1008. 0x26d930ac, 0x51de003a, 0xc8d75180, 0xbfd06116,
  1009. 0x21b4f4b5, 0x56b3c423, 0xcfba9599, 0xb8bda50f,
  1010. 0x2802b89e, 0x5f058808, 0xc60cd9b2, 0xb10be924,
  1011. 0x2f6f7c87, 0x58684c11, 0xc1611dab, 0xb6662d3d,
  1012. 0x76dc4190, 0x01db7106, 0x98d220bc, 0xefd5102a,
  1013. 0x71b18589, 0x06b6b51f, 0x9fbfe4a5, 0xe8b8d433,
  1014. 0x7807c9a2, 0x0f00f934, 0x9609a88e, 0xe10e9818,
  1015. 0x7f6a0dbb, 0x086d3d2d, 0x91646c97, 0xe6635c01,
  1016. 0x6b6b51f4, 0x1c6c6162, 0x856530d8, 0xf262004e,
  1017. 0x6c0695ed, 0x1b01a57b, 0x8208f4c1, 0xf50fc457,
  1018. 0x65b0d9c6, 0x12b7e950, 0x8bbeb8ea, 0xfcb9887c,
  1019. 0x62dd1ddf, 0x15da2d49, 0x8cd37cf3, 0xfbd44c65,
  1020. 0x4db26158, 0x3ab551ce, 0xa3bc0074, 0xd4bb30e2,
  1021. 0x4adfa541, 0x3dd895d7, 0xa4d1c46d, 0xd3d6f4fb,
  1022. 0x4369e96a, 0x346ed9fc, 0xad678846, 0xda60b8d0,
  1023. 0x44042d73, 0x33031de5, 0xaa0a4c5f, 0xdd0d7cc9,
  1024. 0x5005713c, 0x270241aa, 0xbe0b1010, 0xc90c2086,
  1025. 0x5768b525, 0x206f85b3, 0xb966d409, 0xce61e49f,
  1026. 0x5edef90e, 0x29d9c998, 0xb0d09822, 0xc7d7a8b4,
  1027. 0x59b33d17, 0x2eb40d81, 0xb7bd5c3b, 0xc0ba6cad,
  1028. 0xedb88320, 0x9abfb3b6, 0x03b6e20c, 0x74b1d29a,
  1029. 0xead54739, 0x9dd277af, 0x04db2615, 0x73dc1683,
  1030. 0xe3630b12, 0x94643b84, 0x0d6d6a3e, 0x7a6a5aa8,
  1031. 0xe40ecf0b, 0x9309ff9d, 0x0a00ae27, 0x7d079eb1,
  1032. 0xf00f9344, 0x8708a3d2, 0x1e01f268, 0x6906c2fe,
  1033. 0xf762575d, 0x806567cb, 0x196c3671, 0x6e6b06e7,
  1034. 0xfed41b76, 0x89d32be0, 0x10da7a5a, 0x67dd4acc,
  1035. 0xf9b9df6f, 0x8ebeeff9, 0x17b7be43, 0x60b08ed5,
  1036. 0xd6d6a3e8, 0xa1d1937e, 0x38d8c2c4, 0x4fdff252,
  1037. 0xd1bb67f1, 0xa6bc5767, 0x3fb506dd, 0x48b2364b,
  1038. 0xd80d2bda, 0xaf0a1b4c, 0x36034af6, 0x41047a60,
  1039. 0xdf60efc3, 0xa867df55, 0x316e8eef, 0x4669be79,
  1040. 0xcb61b38c, 0xbc66831a, 0x256fd2a0, 0x5268e236,
  1041. 0xcc0c7795, 0xbb0b4703, 0x220216b9, 0x5505262f,
  1042. 0xc5ba3bbe, 0xb2bd0b28, 0x2bb45a92, 0x5cb36a04,
  1043. 0xc2d7ffa7, 0xb5d0cf31, 0x2cd99e8b, 0x5bdeae1d,
  1044. 0x9b64c2b0, 0xec63f226, 0x756aa39c, 0x026d930a,
  1045. 0x9c0906a9, 0xeb0e363f, 0x72076785, 0x05005713,
  1046. 0x95bf4a82, 0xe2b87a14, 0x7bb12bae, 0x0cb61b38,
  1047. 0x92d28e9b, 0xe5d5be0d, 0x7cdcefb7, 0x0bdbdf21,
  1048. 0x86d3d2d4, 0xf1d4e242, 0x68ddb3f8, 0x1fda836e,
  1049. 0x81be16cd, 0xf6b9265b, 0x6fb077e1, 0x18b74777,
  1050. 0x88085ae6, 0xff0f6a70, 0x66063bca, 0x11010b5c,
  1051. 0x8f659eff, 0xf862ae69, 0x616bffd3, 0x166ccf45,
  1052. 0xa00ae278, 0xd70dd2ee, 0x4e048354, 0x3903b3c2,
  1053. 0xa7672661, 0xd06016f7, 0x4969474d, 0x3e6e77db,
  1054. 0xaed16a4a, 0xd9d65adc, 0x40df0b66, 0x37d83bf0,
  1055. 0xa9bcae53, 0xdebb9ec5, 0x47b2cf7f, 0x30b5ffe9,
  1056. 0xbdbdf21c, 0xcabac28a, 0x53b39330, 0x24b4a3a6,
  1057. 0xbad03605, 0xcdd70693, 0x54de5729, 0x23d967bf,
  1058. 0xb3667a2e, 0xc4614ab8, 0x5d681b02, 0x2a6f2b94,
  1059. 0xb40bbe37, 0xc30c8ea1, 0x5a05df1b, 0x2d02ef8d,
  1060. };
  1061. /*
  1062. #define CRCPOLY 0xEDB88320UL
  1063. reversed 0x04C11DB7
  1064. 1110 1101 1001 1000 1000 0011 0010 0000
  1065. static void make_crctable(void)
  1066. {
  1067. uint i, j;
  1068. u32bits r;
  1069. for (i = 0; i < 256; ++i) {
  1070. r = i;
  1071. for (j = 8; j > 0; --j) {
  1072. if (r & 1)
  1073. r = (r >> 1) ^ CRCPOLY;
  1074. else
  1075. r >>= 1;
  1076. }
  1077. crctable[i] = r;
  1078. }
  1079. }
  1080. */
  1081. static u32bits ns_crc32(const u08bits *buffer, u32bits len)
  1082. {
  1083. u32bits crc = CRC_MASK;
  1084. while ( len-- ) UPDATE_CRC( crc, *buffer++ );
  1085. return (~crc);
  1086. }
  1087. //////////// SASLprep RFC 4013 /////////////////////////////////////////
  1088. /* We support only basic ASCII table */
  1089. int SASLprep(u08bits *s)
  1090. {
  1091. if(s) {
  1092. u08bits *strin = s;
  1093. u08bits *strout = s;
  1094. for(;;) {
  1095. u08bits c = *strin;
  1096. if(!c) {
  1097. *strout=0;
  1098. break;
  1099. }
  1100. switch(c) {
  1101. case 0xAD:
  1102. ++strin;
  1103. break;
  1104. case 0xA0:
  1105. case 0x20:
  1106. *strout=0x20;
  1107. ++strout;
  1108. ++strin;
  1109. break;
  1110. case 0x7F:
  1111. return -1;
  1112. default:
  1113. if(c<0x1F)
  1114. return -1;
  1115. if(c>=0x80 && c<=0x9F)
  1116. return -1;
  1117. *strout=c;
  1118. ++strout;
  1119. ++strin;
  1120. };
  1121. }
  1122. }
  1123. return 0;
  1124. }
  1125. //////////////// Message Integrity ////////////////////////////
  1126. size_t get_hmackey_size(SHATYPE shatype)
  1127. {
  1128. if(shatype == SHATYPE_SHA256)
  1129. return 32;
  1130. return 16;
  1131. }
  1132. void print_bin_func(const char *name, size_t len, const void *s, const char *func)
  1133. {
  1134. printf("<%s>:<%s>:len=%d:[",func,name,(int)len);
  1135. size_t i;
  1136. for(i=0;i<len;i++) {
  1137. printf("%02x",(int)((const u08bits*)s)[i]);
  1138. }
  1139. printf("]\n");
  1140. }
  1141. int stun_attr_add_integrity_str(turn_credential_type ct, u08bits *buf, size_t *len, hmackey_t key, st_password_t pwd, SHATYPE shatype)
  1142. {
  1143. u08bits hmac[MAXSHASIZE];
  1144. unsigned int shasize;
  1145. switch(shatype) {
  1146. case SHATYPE_SHA256:
  1147. shasize = SHA256SIZEBYTES;
  1148. break;
  1149. default:
  1150. shasize = SHA1SIZEBYTES;
  1151. };
  1152. if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY, hmac, shasize)<0)
  1153. return -1;
  1154. if(ct == TURN_CREDENTIALS_SHORT_TERM) {
  1155. if(stun_calculate_hmac(buf, *len-4-shasize, pwd, strlen((char*)pwd), buf+*len-shasize, &shasize, shatype)<0)
  1156. return -1;
  1157. } else {
  1158. if(stun_calculate_hmac(buf, *len-4-shasize, key, get_hmackey_size(shatype), buf+*len-shasize, &shasize, shatype)<0)
  1159. return -1;
  1160. }
  1161. return 0;
  1162. }
  1163. int stun_attr_add_integrity_by_user_str(u08bits *buf, size_t *len, u08bits *uname, u08bits *realm, u08bits *upwd, u08bits *nonce, SHATYPE shatype)
  1164. {
  1165. hmackey_t key;
  1166. if(stun_produce_integrity_key_str(uname, realm, upwd, key, shatype)<0)
  1167. return -1;
  1168. if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0)
  1169. return -1;
  1170. if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_NONCE, nonce, strlen((s08bits*)nonce))<0)
  1171. return -1;
  1172. if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_REALM, realm, strlen((s08bits*)realm))<0)
  1173. return -1;
  1174. st_password_t p;
  1175. return stun_attr_add_integrity_str(TURN_CREDENTIALS_LONG_TERM, buf, len, key, p, shatype);
  1176. }
  1177. int stun_attr_add_integrity_by_user_short_term_str(u08bits *buf, size_t *len, u08bits *uname, st_password_t pwd, SHATYPE shatype)
  1178. {
  1179. if(stun_attr_add_str(buf, len, STUN_ATTRIBUTE_USERNAME, uname, strlen((s08bits*)uname))<0)
  1180. return -1;
  1181. hmackey_t key;
  1182. return stun_attr_add_integrity_str(TURN_CREDENTIALS_SHORT_TERM, buf, len, key, pwd, shatype);
  1183. }
  1184. void print_hmac(const char *name, const void *s, size_t len)
  1185. {
  1186. printf("%s:len=%d:[",name,(int)len);
  1187. size_t i;
  1188. for(i=0;i<len;i++) {
  1189. printf("%02x",(int)((const u08bits*)s)[i]);
  1190. }
  1191. printf("]\n");
  1192. }
  1193. /*
  1194. * Return -1 if failure, 0 if the integrity is not correct, 1 if OK
  1195. */
  1196. int stun_check_message_integrity_by_key_str(turn_credential_type ct, u08bits *buf, size_t len, hmackey_t key, st_password_t pwd, SHATYPE shatype, int *too_weak)
  1197. {
  1198. int res = 0;
  1199. u08bits new_hmac[MAXSHASIZE];
  1200. unsigned int shasize;
  1201. const u08bits *old_hmac = NULL;
  1202. stun_attr_ref sar = stun_attr_get_first_by_type_str(buf, len, STUN_ATTRIBUTE_MESSAGE_INTEGRITY);
  1203. if (!sar)
  1204. return -1;
  1205. int sarlen = stun_attr_get_len(sar);
  1206. switch(sarlen) {
  1207. case SHA256SIZEBYTES:
  1208. shasize = SHA256SIZEBYTES;
  1209. if(shatype != SHATYPE_SHA256)
  1210. return -1;
  1211. break;
  1212. case SHA1SIZEBYTES:
  1213. shasize = SHA1SIZEBYTES;
  1214. if(shatype != SHATYPE_SHA1) {
  1215. if(too_weak)
  1216. *too_weak = 1;
  1217. return -1;
  1218. }
  1219. break;
  1220. default:
  1221. return -1;
  1222. };
  1223. int orig_len = stun_get_command_message_len_str(buf, len);
  1224. if (orig_len < 0)
  1225. return -1;
  1226. int new_len = ((const u08bits*) sar - buf) + 4 + shasize;
  1227. if (new_len > orig_len)
  1228. return -1;
  1229. if (stun_set_command_message_len_str(buf, new_len) < 0)
  1230. return -1;
  1231. if(ct == TURN_CREDENTIALS_SHORT_TERM) {
  1232. res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, pwd, strlen((char*)pwd), new_hmac, &shasize, shatype);
  1233. } else {
  1234. res = stun_calculate_hmac(buf, (size_t) new_len - 4 - shasize, key, get_hmackey_size(shatype), new_hmac, &shasize, shatype);
  1235. }
  1236. stun_set_command_message_len_str(buf, orig_len);
  1237. if(res<0)
  1238. return -1;
  1239. old_hmac = stun_attr_get_value(sar);
  1240. if(!old_hmac)
  1241. return -1;
  1242. if(bcmp(old_hmac,new_hmac,shasize))
  1243. return 0;
  1244. return 1;
  1245. }
  1246. /*
  1247. * Return -1 if failure, 0 if the integrity is not correct, 1 if OK
  1248. */
  1249. int stun_check_message_integrity_str(turn_credential_type ct, u08bits *buf, size_t len, u08bits *uname, u08bits *realm, u08bits *upwd, SHATYPE shatype)
  1250. {
  1251. hmackey_t key;
  1252. st_password_t pwd;
  1253. if(ct == TURN_CREDENTIALS_SHORT_TERM)
  1254. strncpy((char*)pwd,(char*)upwd,sizeof(st_password_t));
  1255. else if (stun_produce_integrity_key_str(uname, realm, upwd, key, shatype) < 0)
  1256. return -1;
  1257. return stun_check_message_integrity_by_key_str(ct, buf, len, key, pwd, shatype, NULL);
  1258. }
  1259. /* RFC 5780 */
  1260. int stun_attr_get_change_request_str(stun_attr_ref attr, int *change_ip, int *change_port)
  1261. {
  1262. if(stun_attr_get_len(attr) == 4) {
  1263. const u08bits* value = stun_attr_get_value(attr);
  1264. if(value) {
  1265. *change_ip = (value[3] & (u08bits)0x04);
  1266. *change_port = (value[3] & (u08bits)0x02);
  1267. return 0;
  1268. }
  1269. }
  1270. return -1;
  1271. }
  1272. int stun_attr_add_change_request_str(u08bits *buf, size_t *len, int change_ip, int change_port)
  1273. {
  1274. u08bits avalue[4]={0,0,0,0};
  1275. if(change_ip) {
  1276. if(change_port) {
  1277. avalue[3] = 0x06;
  1278. } else {
  1279. avalue[3] = 0x04;
  1280. }
  1281. } else if(change_port) {
  1282. avalue[3]=0x02;
  1283. }
  1284. return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_CHANGE_REQUEST, avalue, 4);
  1285. }
  1286. int stun_attr_get_response_port_str(stun_attr_ref attr)
  1287. {
  1288. if(stun_attr_get_len(attr) >= 2) {
  1289. const u08bits* value = stun_attr_get_value(attr);
  1290. if(value) {
  1291. return nswap16(((const u16bits*)value)[0]);
  1292. }
  1293. }
  1294. return -1;
  1295. }
  1296. int stun_attr_add_response_port_str(u08bits *buf, size_t *len, u16bits port)
  1297. {
  1298. u08bits avalue[4]={0,0,0,0};
  1299. u16bits *port_ptr = (u16bits*)avalue;
  1300. *port_ptr = nswap16(port);
  1301. return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_RESPONSE_PORT, avalue, 4);
  1302. }
  1303. int stun_attr_get_padding_len_str(stun_attr_ref attr) {
  1304. int len = stun_attr_get_len(attr);
  1305. if(len<0)
  1306. return -1;
  1307. return (u16bits)len;
  1308. }
  1309. int stun_attr_add_padding_str(u08bits *buf, size_t *len, u16bits padding_len)
  1310. {
  1311. u08bits avalue[0xFFFF];
  1312. ns_bzero(avalue,padding_len);
  1313. return stun_attr_add_str(buf, len, STUN_ATTRIBUTE_PADDING, avalue, padding_len);
  1314. }
  1315. ///////////////////////////////////////////////////////////////