app_osplookup.c 61 KB

12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576777879808182838485868788899091929394959697989910010110210310410510610710810911011111211311411511611711811912012112212312412512612712812913013113213313413513613713813914014114214314414514614714814915015115215315415515615715815916016116216316416516616716816917017117217317417517617717817918018118218318418518618718818919019119219319419519619719819920020120220320420520620720820921021121221321421521621721821922022122222322422522622722822923023123223323423523623723823924024124224324424524624724824925025125225325425525625725825926026126226326426526626726826927027127227327427527627727827928028128228328428528628728828929029129229329429529629729829930030130230330430530630730830931031131231331431531631731831932032132232332432532632732832933033133233333433533633733833934034134234334434534634734834935035135235335435535635735835936036136236336436536636736836937037137237337437537637737837938038138238338438538638738838939039139239339439539639739839940040140240340440540640740840941041141241341441541641741841942042142242342442542642742842943043143243343443543643743843944044144244344444544644744844945045145245345445545645745845946046146246346446546646746846947047147247347447547647747847948048148248348448548648748848949049149249349449549649749849950050150250350450550650750850951051151251351451551651751851952052152252352452552652752852953053153253353453553653753853954054154254354454554654754854955055155255355455555655755855956056156256356456556656756856957057157257357457557657757857958058158258358458558658758858959059159259359459559659759859960060160260360460560660760860961061161261361461561661761861962062162262362462562662762862963063163263363463563663763863964064164264364464564664764864965065165265365465565665765865966066166266366466566666766866967067167267367467567667767867968068168268368468568668768868969069169269369469569669769869970070170270370470570670770870971071171271371471571671771871972072172272372472572672772872973073173273373473573673773873974074174274374474574674774874975075175275375475575675775875976076176276376476576676776876977077177277377477577677777877978078178278378478578678778878979079179279379479579679779879980080180280380480580680780880981081181281381481581681781881982082182282382482582682782882983083183283383483583683783883984084184284384484584684784884985085185285385485585685785885986086186286386486586686786886987087187287387487587687787887988088188288388488588688788888989089189289389489589689789889990090190290390490590690790890991091191291391491591691791891992092192292392492592692792892993093193293393493593693793893994094194294394494594694794894995095195295395495595695795895996096196296396496596696796896997097197297397497597697797897998098198298398498598698798898999099199299399499599699799899910001001100210031004100510061007100810091010101110121013101410151016101710181019102010211022102310241025102610271028102910301031103210331034103510361037103810391040104110421043104410451046104710481049105010511052105310541055105610571058105910601061106210631064106510661067106810691070107110721073107410751076107710781079108010811082108310841085108610871088108910901091109210931094109510961097109810991100110111021103110411051106110711081109111011111112111311141115111611171118111911201121112211231124112511261127112811291130113111321133113411351136113711381139114011411142114311441145114611471148114911501151115211531154115511561157115811591160116111621163116411651166116711681169117011711172117311741175117611771178117911801181118211831184118511861187118811891190119111921193119411951196119711981199120012011202120312041205120612071208120912101211121212131214121512161217121812191220122112221223122412251226122712281229123012311232123312341235123612371238123912401241124212431244124512461247124812491250125112521253125412551256125712581259126012611262126312641265126612671268126912701271127212731274127512761277127812791280128112821283128412851286128712881289129012911292129312941295129612971298129913001301130213031304130513061307130813091310131113121313131413151316131713181319132013211322132313241325132613271328132913301331133213331334133513361337133813391340134113421343134413451346134713481349135013511352135313541355135613571358135913601361136213631364136513661367136813691370137113721373137413751376137713781379138013811382138313841385138613871388138913901391139213931394139513961397139813991400140114021403140414051406140714081409141014111412141314141415141614171418141914201421142214231424142514261427142814291430143114321433143414351436143714381439144014411442144314441445144614471448144914501451145214531454145514561457145814591460146114621463146414651466146714681469147014711472147314741475147614771478147914801481148214831484148514861487148814891490149114921493149414951496149714981499150015011502150315041505150615071508150915101511151215131514151515161517151815191520152115221523152415251526152715281529153015311532153315341535153615371538153915401541154215431544154515461547154815491550155115521553155415551556155715581559156015611562156315641565156615671568156915701571157215731574157515761577157815791580158115821583158415851586158715881589159015911592159315941595159615971598159916001601160216031604160516061607160816091610161116121613161416151616161716181619162016211622162316241625162616271628162916301631163216331634163516361637163816391640164116421643164416451646164716481649165016511652165316541655165616571658165916601661166216631664166516661667166816691670167116721673167416751676167716781679168016811682168316841685168616871688168916901691169216931694169516961697169816991700170117021703170417051706170717081709171017111712171317141715171617171718171917201721172217231724172517261727172817291730173117321733173417351736173717381739174017411742174317441745174617471748174917501751175217531754175517561757175817591760176117621763176417651766176717681769177017711772177317741775177617771778177917801781178217831784178517861787178817891790179117921793179417951796179717981799180018011802180318041805180618071808180918101811181218131814181518161817181818191820182118221823182418251826182718281829183018311832183318341835183618371838183918401841184218431844184518461847184818491850185118521853185418551856185718581859186018611862186318641865186618671868186918701871187218731874187518761877187818791880188118821883188418851886188718881889189018911892189318941895189618971898189919001901190219031904190519061907190819091910191119121913191419151916191719181919192019211922192319241925192619271928192919301931193219331934193519361937193819391940194119421943194419451946194719481949195019511952195319541955195619571958195919601961196219631964196519661967196819691970197119721973197419751976197719781979198019811982198319841985198619871988198919901991199219931994199519961997199819992000200120022003200420052006200720082009201020112012201320142015201620172018201920202021202220232024202520262027202820292030203120322033203420352036203720382039204020412042
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 1999 - 2006, Digium, Inc.
  5. *
  6. * Mark Spencer <markster@digium.com>
  7. *
  8. * See http://www.asterisk.org for more information about
  9. * the Asterisk project. Please do not directly contact
  10. * any of the maintainers of this project for assistance;
  11. * the project provides a web site, mailing lists and IRC
  12. * channels for your use.
  13. *
  14. * This program is free software, distributed under the terms of
  15. * the GNU General Public License Version 2. See the LICENSE file
  16. * at the top of the source tree.
  17. */
  18. /*!
  19. * \file
  20. * \brief Open Settlement Protocol (OSP) Applications
  21. *
  22. * \author Mark Spencer <markster@digium.com>
  23. *
  24. * \extref The OSP Toolkit: http://www.transnexus.com
  25. * \extref OpenSSL http://www.openssl.org
  26. *
  27. * \ingroup applications
  28. */
  29. /*** MODULEINFO
  30. <depend>osptk</depend>
  31. <depend>ssl</depend>
  32. ***/
  33. #include "asterisk.h"
  34. ASTERISK_FILE_VERSION(__FILE__, "$Revision$")
  35. #include <osp/osp.h>
  36. #include <osp/osputils.h>
  37. #include "asterisk/paths.h"
  38. #include "asterisk/lock.h"
  39. #include "asterisk/config.h"
  40. #include "asterisk/utils.h"
  41. #include "asterisk/causes.h"
  42. #include "asterisk/channel.h"
  43. #include "asterisk/app.h"
  44. #include "asterisk/module.h"
  45. #include "asterisk/pbx.h"
  46. #include "asterisk/cli.h"
  47. #include "asterisk/astosp.h"
  48. /* OSP Buffer Sizes */
  49. #define OSP_INTSTR_SIZE ((unsigned int)16) /* OSP signed/unsigned int string buffer size */
  50. #define OSP_NORSTR_SIZE ((unsigned int)256) /* OSP normal string buffer size */
  51. #define OSP_TOKSTR_SIZE ((unsigned int)4096) /* OSP token string buffer size */
  52. #define OSP_TECHSTR_SIZE ((unsigned int)32) /* OSP signed/unsigned int string buffer size */
  53. #define OSP_UUID_SIZE ((unsigned int)16) /* UUID size */
  54. #define OSP_UUIDSTR_SIZE ((unsigned int)36) /* UUID string size */
  55. /* OSP Authentication Policy */
  56. enum osp_authpolicy {
  57. OSP_AUTH_NO, /* Accept any call */
  58. OSP_AUTH_YES, /* Accept call with valid OSP token or without OSP token */
  59. OSP_AUTH_EXCLUSIVE /* Only accept call with valid OSP token */
  60. };
  61. /* Call ID type*/
  62. #define OSP_CALLID_UNDEFINED ((unsigned int)0) /* UNDEFINED */
  63. #define OSP_CALLID_H323 ((unsigned int)(1 << 0)) /* H.323 */
  64. #define OSP_CALLID_SIP ((unsigned int)(1 << 1)) /* SIP */
  65. #define OSP_CALLID_IAX ((unsigned int)(1 << 2)) /* IAX2 */
  66. #define OSP_CALLID_MAXNUM ((unsigned int)3) /* Max number of call ID type */
  67. /* OSP Supported Destination Protocols */
  68. #define OSP_PROT_H323 ((char*)"H323") /* H323 Q931 protocol name*/
  69. #define OSP_PROT_SIP ((char*)"SIP") /* SIP protocol name */
  70. #define OSP_PROT_IAX ((char*)"IAX") /* IAX protocol name */
  71. #define OSP_PROT_OTHER ((char*)"OTHER") /* Other protocol name */
  72. /* OSP supported Destination Tech */
  73. #if 0
  74. #define OSP_TECH_H323 ((char*)"OOH323") /* OOH323 tech name */
  75. #endif
  76. #define OSP_TECH_H323 ((char*)"H323") /* OH323 tech name */
  77. #define OSP_TECH_SIP ((char*)"SIP") /* SIP tech name */
  78. #define OSP_TECH_IAX ((char*)"IAX2") /* IAX2 tech name */
  79. /* SIP OSP header field name */
  80. #define OSP_SIP_HEADER ((char*)"P-OSP-Auth-Token: ")
  81. /* OSP Constants */
  82. #define OSP_INVALID_HANDLE ((int)-1) /* Invalid OSP handle, provider, transaction etc. */
  83. #define OSP_CONFIG_FILE ((const char*)"osp.conf") /* OSP configuration file name */
  84. #define OSP_GENERAL_CAT ((const char*)"general") /* OSP global configuration context name */
  85. #define OSP_DEF_PROVIDER ((const char*)"default") /* OSP default provider context name */
  86. #define OSP_MAX_CERTS ((unsigned int)10) /* OSP max number of cacerts */
  87. #define OSP_MAX_SRVS ((unsigned int)10) /* OSP max number of service points */
  88. #define OSP_DEF_MAXCONNECTIONS ((unsigned int)20) /* OSP default max_connections */
  89. #define OSP_MIN_MAXCONNECTIONS ((unsigned int)1) /* OSP min max_connections */
  90. #define OSP_MAX_MAXCONNECTIONS ((unsigned int)1000) /* OSP max max_connections */
  91. #define OSP_DEF_RETRYDELAY ((unsigned int)0) /* OSP default retry delay */
  92. #define OSP_MIN_RETRYDELAY ((unsigned int)0) /* OSP min retry delay */
  93. #define OSP_MAX_RETRYDELAY ((unsigned int)10) /* OSP max retry delay */
  94. #define OSP_DEF_RETRYLIMIT ((unsigned int)2) /* OSP default retry times */
  95. #define OSP_MIN_RETRYLIMIT ((unsigned int)0) /* OSP min retry times */
  96. #define OSP_MAX_RETRYLIMIT ((unsigned int)100) /* OSP max retry times */
  97. #define OSP_DEF_TIMEOUT ((unsigned int)500) /* OSP default timeout in ms */
  98. #define OSP_MIN_TIMEOUT ((unsigned int)200) /* OSP min timeout in ms */
  99. #define OSP_MAX_TIMEOUT ((unsigned int)10000) /* OSP max timeout in ms */
  100. #define OSP_DEF_AUTHPOLICY ((enum osp_authpolicy)OSP_AUTH_YES)
  101. #define OSP_AUDIT_URL ((const char*)"localhost") /* OSP default Audit URL */
  102. #define OSP_LOCAL_VALIDATION ((int)1) /* Validate OSP token locally */
  103. #define OSP_SSL_LIFETIME ((unsigned int)300) /* SSL life time, in seconds */
  104. #define OSP_HTTP_PERSISTENCE ((int)1) /* In seconds */
  105. #define OSP_CUSTOMER_ID ((const char*)"") /* OSP customer ID */
  106. #define OSP_DEVICE_ID ((const char*)"") /* OSP device ID */
  107. #define OSP_DEF_DESTINATIONS ((unsigned int)5) /* OSP default max number of destinations */
  108. #define OSP_DEF_TIMELIMIT ((unsigned int)0) /* OSP default duration limit, no limit */
  109. #define OSP_DEF_PROTOCOL OSP_PROT_SIP /* OSP default destination protocol, SIP */
  110. /* OSP Provider */
  111. struct osp_provider {
  112. char name[OSP_NORSTR_SIZE]; /* OSP provider context name */
  113. char privatekey[OSP_NORSTR_SIZE]; /* OSP private key file name */
  114. char localcert[OSP_NORSTR_SIZE]; /* OSP local cert file name */
  115. unsigned int cacount; /* Number of cacerts */
  116. char cacerts[OSP_MAX_CERTS][OSP_NORSTR_SIZE]; /* Cacert file names */
  117. unsigned int spcount; /* Number of service points */
  118. char srvpoints[OSP_MAX_SRVS][OSP_NORSTR_SIZE]; /* Service point URLs */
  119. int maxconnections; /* Max number of connections */
  120. int retrydelay; /* Retry delay */
  121. int retrylimit; /* Retry limit */
  122. int timeout; /* Timeout in ms */
  123. char source[OSP_NORSTR_SIZE]; /* IP of self */
  124. enum osp_authpolicy authpolicy; /* OSP authentication policy */
  125. char* defaultprotocol; /* OSP default destination protocol */
  126. OSPTPROVHANDLE handle; /* OSP provider handle */
  127. struct osp_provider* next; /* Pointer to next OSP provider */
  128. };
  129. /* Call ID */
  130. struct osp_callid {
  131. unsigned char buf[OSPC_CALLID_MAXSIZE]; /* Call ID string */
  132. unsigned int len; /* Call ID length */
  133. };
  134. /* OSP Application In/Output Results */
  135. struct osp_result {
  136. int inhandle; /* Inbound transaction handle */
  137. int outhandle; /* Outbound transaction handle */
  138. unsigned int intimelimit; /* Inbound duration limit */
  139. unsigned int outtimelimit; /* Outbound duration limit */
  140. char tech[OSP_TECHSTR_SIZE]; /* Outbound Asterisk TECH string */
  141. char dest[OSP_NORSTR_SIZE]; /* Outbound destination IP address */
  142. char called[OSP_NORSTR_SIZE]; /* Outbound called number, may be translated */
  143. char calling[OSP_NORSTR_SIZE]; /* Outbound calling number, may be translated */
  144. char token[OSP_TOKSTR_SIZE]; /* Outbound OSP token */
  145. char networkid[OSP_NORSTR_SIZE]; /* Outbound network ID */
  146. unsigned int numresults; /* Number of remain outbound destinations */
  147. struct osp_callid outcallid; /* Outbound call ID */
  148. };
  149. /* OSP Module Global Variables */
  150. AST_MUTEX_DEFINE_STATIC(osplock); /* Lock of OSP provider list */
  151. static int osp_initialized = 0; /* Init flag */
  152. static int osp_hardware = 0; /* Hardware accelleration flag */
  153. static struct osp_provider* ospproviders = NULL; /* OSP provider list */
  154. static unsigned int osp_tokenformat = TOKEN_ALGO_SIGNED; /* Token format supported */
  155. /* OSP Client Wrapper APIs */
  156. /*!
  157. * \brief Create OSP provider handle according to configuration
  158. * \param cfg OSP configuration
  159. * \param provider OSP provider context name
  160. * \return 1 Success, 0 Failed, -1 Error
  161. */
  162. static int osp_create_provider(
  163. struct ast_config* cfg,
  164. const char* provider)
  165. {
  166. int res;
  167. unsigned int t, i, j;
  168. struct osp_provider* p;
  169. struct ast_variable* v;
  170. OSPTPRIVATEKEY privatekey;
  171. OSPTCERT localcert;
  172. const char* psrvpoints[OSP_MAX_SRVS];
  173. OSPTCERT cacerts[OSP_MAX_CERTS];
  174. const OSPTCERT* pcacerts[OSP_MAX_CERTS];
  175. int error = OSPC_ERR_NO_ERROR;
  176. if (!(p = ast_calloc(1, sizeof(*p)))) {
  177. ast_log(LOG_ERROR, "Out of memory\n");
  178. return -1;
  179. }
  180. ast_copy_string(p->name, provider, sizeof(p->name));
  181. snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s-privatekey.pem", ast_config_AST_KEY_DIR, provider);
  182. snprintf(p->localcert, sizeof(p->localcert), "%s/%s-localcert.pem", ast_config_AST_KEY_DIR, provider);
  183. p->maxconnections = OSP_DEF_MAXCONNECTIONS;
  184. p->retrydelay = OSP_DEF_RETRYDELAY;
  185. p->retrylimit = OSP_DEF_RETRYLIMIT;
  186. p->timeout = OSP_DEF_TIMEOUT;
  187. p->authpolicy = OSP_DEF_AUTHPOLICY;
  188. p->defaultprotocol = OSP_DEF_PROTOCOL;
  189. p->handle = OSP_INVALID_HANDLE;
  190. v = ast_variable_browse(cfg, provider);
  191. while(v) {
  192. if (!strcasecmp(v->name, "privatekey")) {
  193. if (v->value[0] == '/') {
  194. ast_copy_string(p->privatekey, v->value, sizeof(p->privatekey));
  195. } else {
  196. snprintf(p->privatekey, sizeof(p->privatekey), "%s/%s", ast_config_AST_KEY_DIR, v->value);
  197. }
  198. ast_debug(1, "OSP: privatekey '%s'\n", p->privatekey);
  199. } else if (!strcasecmp(v->name, "localcert")) {
  200. if (v->value[0] == '/') {
  201. ast_copy_string(p->localcert, v->value, sizeof(p->localcert));
  202. } else {
  203. snprintf(p->localcert, sizeof(p->localcert), "%s/%s", ast_config_AST_KEY_DIR, v->value);
  204. }
  205. ast_debug(1, "OSP: localcert '%s'\n", p->localcert);
  206. } else if (!strcasecmp(v->name, "cacert")) {
  207. if (p->cacount < OSP_MAX_CERTS) {
  208. if (v->value[0] == '/') {
  209. ast_copy_string(p->cacerts[p->cacount], v->value, sizeof(p->cacerts[0]));
  210. } else {
  211. snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s", ast_config_AST_KEY_DIR, v->value);
  212. }
  213. ast_debug(1, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
  214. p->cacount++;
  215. } else {
  216. ast_log(LOG_WARNING, "OSP: Too many CA Certificates at line %d\n", v->lineno);
  217. }
  218. } else if (!strcasecmp(v->name, "servicepoint")) {
  219. if (p->spcount < OSP_MAX_SRVS) {
  220. ast_copy_string(p->srvpoints[p->spcount], v->value, sizeof(p->srvpoints[0]));
  221. ast_debug(1, "OSP: servicepoint[%d]: '%s'\n", p->spcount, p->srvpoints[p->spcount]);
  222. p->spcount++;
  223. } else {
  224. ast_log(LOG_WARNING, "OSP: Too many Service Points at line %d\n", v->lineno);
  225. }
  226. } else if (!strcasecmp(v->name, "maxconnections")) {
  227. if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_MAXCONNECTIONS) && (t <= OSP_MAX_MAXCONNECTIONS)) {
  228. p->maxconnections = t;
  229. ast_debug(1, "OSP: maxconnections '%d'\n", t);
  230. } else {
  231. ast_log(LOG_WARNING, "OSP: maxconnections should be an integer from %d to %d, not '%s' at line %d\n",
  232. OSP_MIN_MAXCONNECTIONS, OSP_MAX_MAXCONNECTIONS, v->value, v->lineno);
  233. }
  234. } else if (!strcasecmp(v->name, "retrydelay")) {
  235. if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_RETRYDELAY) && (t <= OSP_MAX_RETRYDELAY)) {
  236. p->retrydelay = t;
  237. ast_debug(1, "OSP: retrydelay '%d'\n", t);
  238. } else {
  239. ast_log(LOG_WARNING, "OSP: retrydelay should be an integer from %d to %d, not '%s' at line %d\n",
  240. OSP_MIN_RETRYDELAY, OSP_MAX_RETRYDELAY, v->value, v->lineno);
  241. }
  242. } else if (!strcasecmp(v->name, "retrylimit")) {
  243. if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_RETRYLIMIT) && (t <= OSP_MAX_RETRYLIMIT)) {
  244. p->retrylimit = t;
  245. ast_debug(1, "OSP: retrylimit '%d'\n", t);
  246. } else {
  247. ast_log(LOG_WARNING, "OSP: retrylimit should be an integer from %d to %d, not '%s' at line %d\n",
  248. OSP_MIN_RETRYLIMIT, OSP_MAX_RETRYLIMIT, v->value, v->lineno);
  249. }
  250. } else if (!strcasecmp(v->name, "timeout")) {
  251. if ((sscanf(v->value, "%30d", &t) == 1) && (t >= OSP_MIN_TIMEOUT) && (t <= OSP_MAX_TIMEOUT)) {
  252. p->timeout = t;
  253. ast_debug(1, "OSP: timeout '%d'\n", t);
  254. } else {
  255. ast_log(LOG_WARNING, "OSP: timeout should be an integer from %d to %d, not '%s' at line %d\n",
  256. OSP_MIN_TIMEOUT, OSP_MAX_TIMEOUT, v->value, v->lineno);
  257. }
  258. } else if (!strcasecmp(v->name, "source")) {
  259. ast_copy_string(p->source, v->value, sizeof(p->source));
  260. ast_debug(1, "OSP: source '%s'\n", p->source);
  261. } else if (!strcasecmp(v->name, "authpolicy")) {
  262. if ((sscanf(v->value, "%30d", &t) == 1) && ((t == OSP_AUTH_NO) || (t == OSP_AUTH_YES) || (t == OSP_AUTH_EXCLUSIVE))) {
  263. p->authpolicy = t;
  264. ast_debug(1, "OSP: authpolicy '%d'\n", t);
  265. } else {
  266. ast_log(LOG_WARNING, "OSP: authpolicy should be %d, %d or %d, not '%s' at line %d\n",
  267. OSP_AUTH_NO, OSP_AUTH_YES, OSP_AUTH_EXCLUSIVE, v->value, v->lineno);
  268. }
  269. } else if (!strcasecmp(v->name, "defaultprotocol")) {
  270. if (!strcasecmp(v->value, OSP_PROT_SIP)) {
  271. p->defaultprotocol = OSP_PROT_SIP;
  272. ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
  273. } else if (!strcasecmp(v->value, OSP_PROT_H323)) {
  274. p->defaultprotocol = OSP_PROT_H323;
  275. ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
  276. } else if (!strcasecmp(v->value, OSP_PROT_IAX)) {
  277. p->defaultprotocol = OSP_PROT_IAX;
  278. ast_debug(1, "OSP: default protocol '%s'\n", p->defaultprotocol);
  279. } else {
  280. ast_log(LOG_WARNING, "OSP: default protocol should be %s, %s, %s, or %s not '%s' at line %d\n",
  281. OSP_PROT_SIP, OSP_PROT_H323, OSP_PROT_IAX, OSP_PROT_OTHER, v->value, v->lineno);
  282. }
  283. }
  284. v = v->next;
  285. }
  286. error = OSPPUtilLoadPEMPrivateKey((unsigned char*)p->privatekey, &privatekey);
  287. if (error != OSPC_ERR_NO_ERROR) {
  288. ast_log(LOG_WARNING, "OSP: Unable to load privatekey '%s', error '%d'\n", p->privatekey, error);
  289. ast_free(p);
  290. return 0;
  291. }
  292. error = OSPPUtilLoadPEMCert((unsigned char*)p->localcert, &localcert);
  293. if (error != OSPC_ERR_NO_ERROR) {
  294. ast_log(LOG_WARNING, "OSP: Unable to load localcert '%s', error '%d'\n", p->localcert, error);
  295. if (privatekey.PrivateKeyData) {
  296. ast_free(privatekey.PrivateKeyData);
  297. }
  298. ast_free(p);
  299. return 0;
  300. }
  301. if (p->cacount < 1) {
  302. snprintf(p->cacerts[p->cacount], sizeof(p->cacerts[0]), "%s/%s-cacert.pem", ast_config_AST_KEY_DIR, provider);
  303. ast_debug(1, "OSP: cacert[%d]: '%s'\n", p->cacount, p->cacerts[p->cacount]);
  304. p->cacount++;
  305. }
  306. for (i = 0; i < p->cacount; i++) {
  307. error = OSPPUtilLoadPEMCert((unsigned char*)p->cacerts[i], &cacerts[i]);
  308. if (error != OSPC_ERR_NO_ERROR) {
  309. ast_log(LOG_WARNING, "OSP: Unable to load cacert '%s', error '%d'\n", p->cacerts[i], error);
  310. for (j = 0; j < i; j++) {
  311. if (cacerts[j].CertData) {
  312. ast_free(cacerts[j].CertData);
  313. }
  314. }
  315. if (localcert.CertData) {
  316. ast_free(localcert.CertData);
  317. }
  318. if (privatekey.PrivateKeyData) {
  319. ast_free(privatekey.PrivateKeyData);
  320. }
  321. ast_free(p);
  322. return 0;
  323. }
  324. pcacerts[i] = &cacerts[i];
  325. }
  326. for (i = 0; i < p->spcount; i++) {
  327. psrvpoints[i] = p->srvpoints[i];
  328. }
  329. error = OSPPProviderNew(
  330. p->spcount,
  331. psrvpoints,
  332. NULL,
  333. OSP_AUDIT_URL,
  334. &privatekey,
  335. &localcert,
  336. p->cacount,
  337. pcacerts,
  338. OSP_LOCAL_VALIDATION,
  339. OSP_SSL_LIFETIME,
  340. p->maxconnections,
  341. OSP_HTTP_PERSISTENCE,
  342. p->retrydelay,
  343. p->retrylimit,
  344. p->timeout,
  345. OSP_CUSTOMER_ID,
  346. OSP_DEVICE_ID,
  347. &p->handle);
  348. if (error != OSPC_ERR_NO_ERROR) {
  349. ast_log(LOG_WARNING, "OSP: Unable to create provider '%s', error '%d'\n", provider, error);
  350. ast_free(p);
  351. res = -1;
  352. } else {
  353. ast_debug(1, "OSP: provider '%s'\n", provider);
  354. ast_mutex_lock(&osplock);
  355. p->next = ospproviders;
  356. ospproviders = p;
  357. ast_mutex_unlock(&osplock);
  358. res = 1;
  359. }
  360. for (i = 0; i < p->cacount; i++) {
  361. if (cacerts[i].CertData) {
  362. ast_free(cacerts[i].CertData);
  363. }
  364. }
  365. if (localcert.CertData) {
  366. ast_free(localcert.CertData);
  367. }
  368. if (privatekey.PrivateKeyData) {
  369. ast_free(privatekey.PrivateKeyData);
  370. }
  371. return res;
  372. }
  373. /*!
  374. * \brief Get OSP provider by name
  375. * \param name OSP provider context name
  376. * \param provider OSP provider structure
  377. * \return 1 Success, 0 Failed, -1 Error
  378. */
  379. static int osp_get_provider(
  380. const char* name,
  381. struct osp_provider** provider)
  382. {
  383. int res = 0;
  384. struct osp_provider* p;
  385. ast_mutex_lock(&osplock);
  386. p = ospproviders;
  387. while(p) {
  388. if (!strcasecmp(p->name, name)) {
  389. *provider = p;
  390. ast_debug(1, "OSP: find provider '%s'\n", name);
  391. res = 1;
  392. break;
  393. }
  394. p = p->next;
  395. }
  396. ast_mutex_unlock(&osplock);
  397. return res;
  398. }
  399. /*!
  400. * \brief Create OSP transaction handle
  401. * \param provider OSP provider context name
  402. * \param transaction OSP transaction handle, output
  403. * \param sourcesize Size of source buffer, in/output
  404. * \param source Source of provider, output
  405. * \return 1 Success, 0 Failed, -1 Error
  406. */
  407. static int osp_create_transaction(
  408. const char* provider,
  409. int* transaction,
  410. unsigned int sourcesize,
  411. char* source)
  412. {
  413. int res = 0;
  414. struct osp_provider* p;
  415. int error;
  416. ast_mutex_lock(&osplock);
  417. p = ospproviders;
  418. while(p) {
  419. if (!strcasecmp(p->name, provider)) {
  420. error = OSPPTransactionNew(p->handle, transaction);
  421. if (error == OSPC_ERR_NO_ERROR) {
  422. ast_debug(1, "OSP: transaction '%d'\n", *transaction);
  423. ast_copy_string(source, p->source, sourcesize);
  424. ast_debug(1, "OSP: source '%s'\n", source);
  425. res = 1;
  426. } else {
  427. *transaction = OSP_INVALID_HANDLE;
  428. ast_debug(1, "OSP: Unable to create transaction handle, error '%d'\n", error);
  429. res = -1;
  430. }
  431. break;
  432. }
  433. p = p->next;
  434. }
  435. ast_mutex_unlock(&osplock);
  436. return res;
  437. }
  438. /*!
  439. * \brief Convert address to "[x.x.x.x]" or "host.domain" format
  440. * \param src Source address string
  441. * \param dst Destination address string
  442. * \param buffersize Size of dst buffer
  443. */
  444. static void osp_convert_address(
  445. const char* src,
  446. char* dst,
  447. int buffersize)
  448. {
  449. struct in_addr inp;
  450. if (inet_aton(src, &inp) != 0) {
  451. snprintf(dst, buffersize, "[%s]", src);
  452. } else {
  453. snprintf(dst, buffersize, "%s", src);
  454. }
  455. }
  456. /*!
  457. * \brief Validate OSP token of inbound call
  458. * \param transaction OSP transaction handle
  459. * \param source Source of inbound call
  460. * \param destination Destination of inbound call
  461. * \param calling Calling number
  462. * \param called Called number
  463. * \param token OSP token, may be empty
  464. * \param timelimit Call duration limit, output
  465. * \return 1 Success, 0 Failed, -1 Error
  466. */
  467. static int osp_validate_token(
  468. int transaction,
  469. const char* source,
  470. const char* destination,
  471. const char* calling,
  472. const char* called,
  473. const char* token,
  474. unsigned int* timelimit)
  475. {
  476. int res;
  477. int tokenlen;
  478. unsigned char tokenstr[OSP_TOKSTR_SIZE];
  479. char src[OSP_NORSTR_SIZE];
  480. char dst[OSP_NORSTR_SIZE];
  481. unsigned int authorised;
  482. unsigned int dummy = 0;
  483. int error;
  484. tokenlen = ast_base64decode(tokenstr, token, strlen(token));
  485. osp_convert_address(source, src, sizeof(src));
  486. osp_convert_address(destination, dst, sizeof(dst));
  487. error = OSPPTransactionValidateAuthorisation(
  488. transaction,
  489. src,
  490. dst,
  491. NULL,
  492. NULL,
  493. calling ? calling : "",
  494. OSPC_E164,
  495. called,
  496. OSPC_E164,
  497. 0,
  498. NULL,
  499. tokenlen,
  500. (char*)tokenstr,
  501. &authorised,
  502. timelimit,
  503. &dummy,
  504. NULL,
  505. osp_tokenformat);
  506. if (error != OSPC_ERR_NO_ERROR) {
  507. ast_debug(1, "OSP: Unable to validate inbound token\n");
  508. res = -1;
  509. } else if (authorised) {
  510. ast_debug(1, "OSP: Authorised\n");
  511. res = 1;
  512. } else {
  513. ast_debug(1, "OSP: Unauthorised\n");
  514. res = 0;
  515. }
  516. return res;
  517. }
  518. /*!
  519. * \brief Choose min duration limit
  520. * \param in Inbound duration limit
  521. * \param out Outbound duration limit
  522. * \return min duration limit
  523. */
  524. static unsigned int osp_choose_timelimit(
  525. unsigned int in,
  526. unsigned int out)
  527. {
  528. if (in == OSP_DEF_TIMELIMIT) {
  529. return out;
  530. } else if (out == OSP_DEF_TIMELIMIT) {
  531. return in;
  532. } else {
  533. return in < out ? in : out;
  534. }
  535. }
  536. /*!
  537. * \brief Choose min duration limit
  538. * \param provider OSP provider
  539. * \param called Called number
  540. * \param calling Calling number
  541. * \param destination Destination IP in '[x.x.x.x]' format
  542. * \param tokenlen OSP token length
  543. * \param token OSP token
  544. * \param reason Failure reason, output
  545. * \param result OSP lookup results, in/output
  546. * \return 1 Success, 0 Failed, -1 Error
  547. */
  548. static int osp_check_destination(
  549. struct osp_provider* provider,
  550. const char* called,
  551. const char* calling,
  552. char* destination,
  553. unsigned int tokenlen,
  554. const char* token,
  555. enum OSPEFAILREASON* reason,
  556. struct osp_result* result)
  557. {
  558. int res;
  559. OSPE_DEST_OSP_ENABLED enabled;
  560. OSPE_DEST_PROT protocol;
  561. int error;
  562. if (strlen(destination) <= 2) {
  563. ast_debug(1, "OSP: Wrong destination format '%s'\n", destination);
  564. *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
  565. return -1;
  566. }
  567. if ((error = OSPPTransactionIsDestOSPEnabled(result->outhandle, &enabled)) != OSPC_ERR_NO_ERROR) {
  568. ast_debug(1, "OSP: Unable to get destination OSP version, error '%d'\n", error);
  569. *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
  570. return -1;
  571. }
  572. if (enabled == OSPE_OSP_FALSE) {
  573. result->token[0] = '\0';
  574. } else {
  575. ast_base64encode(result->token, (const unsigned char*)token, tokenlen, sizeof(result->token) - 1);
  576. }
  577. if ((error = OSPPTransactionGetDestNetworkId(result->outhandle, result->networkid)) != OSPC_ERR_NO_ERROR) {
  578. ast_debug(1, "OSP: Unable to get destination network ID, error '%d'\n", error);
  579. result->networkid[0] = '\0';
  580. }
  581. if ((error = OSPPTransactionGetDestProtocol(result->outhandle, &protocol)) != OSPC_ERR_NO_ERROR) {
  582. ast_debug(1, "OSP: Unable to get destination protocol, error '%d'\n", error);
  583. *reason = OSPC_FAIL_NORMAL_UNSPECIFIED;
  584. result->token[0] = '\0';
  585. result->networkid[0] = '\0';
  586. return -1;
  587. }
  588. res = 1;
  589. /* Strip leading and trailing brackets */
  590. destination[strlen(destination) - 1] = '\0';
  591. switch(protocol) {
  592. case OSPE_DEST_PROT_H323_SETUP:
  593. ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_H323);
  594. ast_copy_string(result->tech, OSP_TECH_H323, sizeof(result->tech));
  595. ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
  596. ast_copy_string(result->called, called, sizeof(result->called));
  597. ast_copy_string(result->calling, calling, sizeof(result->calling));
  598. break;
  599. case OSPE_DEST_PROT_SIP:
  600. ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_SIP);
  601. ast_copy_string(result->tech, OSP_TECH_SIP, sizeof(result->tech));
  602. ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
  603. ast_copy_string(result->called, called, sizeof(result->called));
  604. ast_copy_string(result->calling, calling, sizeof(result->calling));
  605. break;
  606. case OSPE_DEST_PROT_IAX:
  607. ast_debug(1, "OSP: protocol '%s'\n", OSP_PROT_IAX);
  608. ast_copy_string(result->tech, OSP_TECH_IAX, sizeof(result->tech));
  609. ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
  610. ast_copy_string(result->called, called, sizeof(result->called));
  611. ast_copy_string(result->calling, calling, sizeof(result->calling));
  612. break;
  613. case OSPE_DEST_PROT_UNDEFINED:
  614. case OSPE_DEST_PROT_UNKNOWN:
  615. ast_debug(1, "OSP: unknown/undefined protocol '%d'\n", protocol);
  616. ast_debug(1, "OSP: use default protocol '%s'\n", provider->defaultprotocol);
  617. ast_copy_string(result->tech, provider->defaultprotocol, sizeof(result->tech));
  618. ast_copy_string(result->dest, destination + 1, sizeof(result->dest));
  619. ast_copy_string(result->called, called, sizeof(result->called));
  620. ast_copy_string(result->calling, calling, sizeof(result->calling));
  621. break;
  622. case OSPE_DEST_PROT_H323_LRQ:
  623. default:
  624. ast_log(LOG_WARNING, "OSP: unsupported protocol '%d'\n", protocol);
  625. *reason = OSPC_FAIL_PROTOCOL_ERROR;
  626. result->token[0] = '\0';
  627. result->networkid[0] = '\0';
  628. res = 0;
  629. break;
  630. }
  631. return res;
  632. }
  633. /*!
  634. * \brief Convert Asterisk status to TC code
  635. * \param cause Asterisk hangup cause
  636. * \return OSP TC code
  637. */
  638. static enum OSPEFAILREASON asterisk2osp(
  639. int cause)
  640. {
  641. return (enum OSPEFAILREASON)cause;
  642. }
  643. /*!
  644. * \brief OSP Authentication function
  645. * \param provider OSP provider context name
  646. * \param transaction OSP transaction handle, output
  647. * \param source Source of inbound call
  648. * \param calling Calling number
  649. * \param called Called number
  650. * \param token OSP token, may be empty
  651. * \param timelimit Call duration limit, output
  652. * \return 1 Authenricated, 0 Unauthenticated, -1 Error
  653. */
  654. static int osp_auth(
  655. const char* provider,
  656. int* transaction,
  657. const char* source,
  658. const char* calling,
  659. const char* called,
  660. const char* token,
  661. unsigned int* timelimit)
  662. {
  663. int res;
  664. struct osp_provider* p;
  665. char dest[OSP_NORSTR_SIZE];
  666. *transaction = OSP_INVALID_HANDLE;
  667. *timelimit = OSP_DEF_TIMELIMIT;
  668. if ((res = osp_get_provider(provider, &p)) <= 0) {
  669. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
  670. return res;
  671. }
  672. switch (p->authpolicy) {
  673. case OSP_AUTH_NO:
  674. res = 1;
  675. break;
  676. case OSP_AUTH_EXCLUSIVE:
  677. if (ast_strlen_zero(token)) {
  678. res = 0;
  679. } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
  680. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  681. *transaction = OSP_INVALID_HANDLE;
  682. res = 0;
  683. } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
  684. OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
  685. }
  686. break;
  687. case OSP_AUTH_YES:
  688. default:
  689. if (ast_strlen_zero(token)) {
  690. res = 1;
  691. } else if ((res = osp_create_transaction(provider, transaction, sizeof(dest), dest)) <= 0) {
  692. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  693. *transaction = OSP_INVALID_HANDLE;
  694. res = 0;
  695. } else if((res = osp_validate_token(*transaction, source, dest, calling, called, token, timelimit)) <= 0) {
  696. OSPPTransactionRecordFailure(*transaction, OSPC_FAIL_CALL_REJECTED);
  697. }
  698. break;
  699. }
  700. return res;
  701. }
  702. /*!
  703. * \brief Create a UUID
  704. * \param uuid UUID buffer
  705. * \param buffersize UUID buffer size
  706. * \return 1 Created, -1 Error
  707. */
  708. static int osp_create_uuid(
  709. unsigned char* uuid,
  710. unsigned int* buffersize)
  711. {
  712. int i, res;
  713. long int* tmp;
  714. if (*buffersize >= OSP_UUID_SIZE) {
  715. tmp = (long int*)uuid;
  716. for (i = 0; i < OSP_UUID_SIZE / sizeof(long int); i++) {
  717. tmp[i] = ast_random();
  718. }
  719. *buffersize = OSP_UUID_SIZE;
  720. res = 1;
  721. } else {
  722. res = -1;
  723. }
  724. return res;
  725. }
  726. /*!
  727. * \brief UUID to string
  728. * \param uuid UUID
  729. * \param buffer String buffer
  730. * \param buffersize String buffer size
  731. * \return 1 Successed, -1 Error
  732. */
  733. static int osp_uuid2str(
  734. unsigned char* uuid,
  735. char* buffer,
  736. unsigned int buffersize)
  737. {
  738. int res;
  739. if (buffersize > OSP_UUIDSTR_SIZE) {
  740. snprintf(buffer, buffersize, "%02x%02x%02x%02x-%02x%02x-%02x%02x-%02x%02x-%02x%02x%02x%02x%02x%02x",
  741. uuid[0], uuid[1], uuid[2], uuid[3], uuid[4], uuid[5], uuid[6], uuid[7],
  742. uuid[8], uuid[9], uuid[10], uuid[11], uuid[12], uuid[13], uuid[14], uuid[15]);
  743. res = 1;
  744. } else {
  745. res = -1;
  746. }
  747. return res;
  748. }
  749. /*!
  750. * \brief Create a call ID according to the type
  751. * \param type Call ID type
  752. * \param callid Call ID buffer
  753. * \return 1 Created, 0 Not create, -1 Error
  754. */
  755. static int osp_create_callid(
  756. unsigned int type,
  757. struct osp_callid* callid)
  758. {
  759. int res;
  760. callid->len = sizeof(callid->buf);
  761. switch (type) {
  762. case OSP_CALLID_H323:
  763. res = osp_create_uuid(callid->buf, &callid->len);
  764. break;
  765. case OSP_CALLID_SIP:
  766. case OSP_CALLID_IAX:
  767. res = 0;
  768. default:
  769. res = -1;
  770. break;
  771. }
  772. if ((res != 1) && (callid->len != 0)) {
  773. callid->buf[0] = '\0';
  774. callid->len = 0;
  775. }
  776. return res;
  777. }
  778. /*!
  779. * \brief OSP Lookup function
  780. * \param provider OSP provider context name
  781. * \param srcdev Source device of outbound call
  782. * \param calling Calling number
  783. * \param called Called number
  784. * \param callidtypes Call ID types
  785. * \param result Lookup results
  786. * \return 1 Found , 0 No route, -1 Error
  787. */
  788. static int osp_lookup(
  789. const char* provider,
  790. const char* srcdev,
  791. const char* calling,
  792. const char* called,
  793. unsigned int callidtypes,
  794. struct osp_result* result)
  795. {
  796. int res;
  797. struct osp_provider* p;
  798. char source[OSP_NORSTR_SIZE];
  799. char callingnum[OSP_NORSTR_SIZE];
  800. char callednum[OSP_NORSTR_SIZE];
  801. char destination[OSP_NORSTR_SIZE];
  802. unsigned int tokenlen;
  803. char token[OSP_TOKSTR_SIZE];
  804. char src[OSP_NORSTR_SIZE];
  805. char dev[OSP_NORSTR_SIZE];
  806. unsigned int i, type;
  807. struct osp_callid callid;
  808. unsigned int callidnum;
  809. OSPTCALLID* callids[OSP_CALLID_MAXNUM];
  810. unsigned int dummy = 0;
  811. enum OSPEFAILREASON reason;
  812. int error;
  813. result->outhandle = OSP_INVALID_HANDLE;
  814. result->tech[0] = '\0';
  815. result->dest[0] = '\0';
  816. result->called[0] = '\0';
  817. result->calling[0] = '\0';
  818. result->token[0] = '\0';
  819. result->networkid[0] = '\0';
  820. result->numresults = 0;
  821. result->outtimelimit = OSP_DEF_TIMELIMIT;
  822. if ((res = osp_get_provider(provider, &p)) <= 0) {
  823. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
  824. return res;
  825. }
  826. if ((res = osp_create_transaction(provider, &result->outhandle, sizeof(source), source)) <= 0) {
  827. ast_debug(1, "OSP: Unable to generate transaction handle\n");
  828. result->outhandle = OSP_INVALID_HANDLE;
  829. if (result->inhandle != OSP_INVALID_HANDLE) {
  830. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  831. }
  832. return -1;
  833. }
  834. callidnum = 0;
  835. callids[0] = NULL;
  836. for (i = 0; i < OSP_CALLID_MAXNUM; i++) {
  837. type = 1 << i;
  838. if (callidtypes & type) {
  839. error = osp_create_callid(type, &callid);
  840. if (error == 1) {
  841. callids[callidnum] = OSPPCallIdNew(callid.len, callid.buf);
  842. callidnum++;
  843. }
  844. }
  845. }
  846. osp_convert_address(source, src, sizeof(src));
  847. osp_convert_address(srcdev, dev, sizeof(dev));
  848. result->numresults = OSP_DEF_DESTINATIONS;
  849. error = OSPPTransactionRequestAuthorisation(
  850. result->outhandle,
  851. src,
  852. dev,
  853. calling ? calling : "",
  854. OSPC_E164,
  855. called,
  856. OSPC_E164,
  857. NULL,
  858. callidnum,
  859. callids,
  860. NULL,
  861. &result->numresults,
  862. &dummy,
  863. NULL);
  864. for (i = 0; i < callidnum; i++) {
  865. OSPPCallIdDelete(&callids[i]);
  866. }
  867. if (error != OSPC_ERR_NO_ERROR) {
  868. ast_debug(1, "OSP: Unable to request authorization\n");
  869. result->numresults = 0;
  870. if (result->inhandle != OSP_INVALID_HANDLE) {
  871. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  872. }
  873. return -1;
  874. }
  875. if (!result->numresults) {
  876. ast_debug(1, "OSP: No more destination\n");
  877. if (result->inhandle != OSP_INVALID_HANDLE) {
  878. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  879. }
  880. return 0;
  881. }
  882. result->outcallid.len = sizeof(result->outcallid.buf);
  883. tokenlen = sizeof(token);
  884. error = OSPPTransactionGetFirstDestination(
  885. result->outhandle,
  886. 0,
  887. NULL,
  888. NULL,
  889. &result->outtimelimit,
  890. &result->outcallid.len,
  891. result->outcallid.buf,
  892. sizeof(callednum),
  893. callednum,
  894. sizeof(callingnum),
  895. callingnum,
  896. sizeof(destination),
  897. destination,
  898. 0,
  899. NULL,
  900. &tokenlen,
  901. token);
  902. if (error != OSPC_ERR_NO_ERROR) {
  903. ast_debug(1, "OSP: Unable to get first route\n");
  904. result->numresults = 0;
  905. result->outtimelimit = OSP_DEF_TIMELIMIT;
  906. if (result->inhandle != OSP_INVALID_HANDLE) {
  907. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  908. }
  909. return -1;
  910. }
  911. result->numresults--;
  912. result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
  913. ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
  914. ast_debug(1, "OSP: called '%s'\n", callednum);
  915. ast_debug(1, "OSP: calling '%s'\n", callingnum);
  916. ast_debug(1, "OSP: destination '%s'\n", destination);
  917. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  918. if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
  919. return 1;
  920. }
  921. if (!result->numresults) {
  922. ast_debug(1, "OSP: No more destination\n");
  923. result->outtimelimit = OSP_DEF_TIMELIMIT;
  924. OSPPTransactionRecordFailure(result->outhandle, reason);
  925. if (result->inhandle != OSP_INVALID_HANDLE) {
  926. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  927. }
  928. return 0;
  929. }
  930. while(result->numresults) {
  931. result->outcallid.len = sizeof(result->outcallid.buf);
  932. tokenlen = sizeof(token);
  933. error = OSPPTransactionGetNextDestination(
  934. result->outhandle,
  935. reason,
  936. 0,
  937. NULL,
  938. NULL,
  939. &result->outtimelimit,
  940. &result->outcallid.len,
  941. result->outcallid.buf,
  942. sizeof(callednum),
  943. callednum,
  944. sizeof(callingnum),
  945. callingnum,
  946. sizeof(destination),
  947. destination,
  948. 0,
  949. NULL,
  950. &tokenlen,
  951. token);
  952. if (error == OSPC_ERR_NO_ERROR) {
  953. result->numresults--;
  954. result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
  955. ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
  956. ast_debug(1, "OSP: called '%s'\n", callednum);
  957. ast_debug(1, "OSP: calling '%s'\n", callingnum);
  958. ast_debug(1, "OSP: destination '%s'\n", destination);
  959. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  960. if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
  961. break;
  962. } else if (!result->numresults) {
  963. ast_debug(1, "OSP: No more destination\n");
  964. OSPPTransactionRecordFailure(result->outhandle, reason);
  965. if (result->inhandle != OSP_INVALID_HANDLE) {
  966. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  967. }
  968. res = 0;
  969. break;
  970. }
  971. } else {
  972. ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
  973. result->numresults = 0;
  974. result->outtimelimit = OSP_DEF_TIMELIMIT;
  975. if (result->inhandle != OSP_INVALID_HANDLE) {
  976. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  977. }
  978. res = -1;
  979. break;
  980. }
  981. }
  982. return res;
  983. }
  984. /*!
  985. * \brief OSP Lookup Next function
  986. * \param provider OSP provider name
  987. * \param cause Asterisk hangup cuase
  988. * \param result Lookup results, in/output
  989. * \return 1 Found , 0 No route, -1 Error
  990. */
  991. static int osp_next(
  992. const char* provider,
  993. int cause,
  994. struct osp_result* result)
  995. {
  996. int res;
  997. struct osp_provider* p;
  998. char callingnum[OSP_NORSTR_SIZE];
  999. char callednum[OSP_NORSTR_SIZE];
  1000. char destination[OSP_NORSTR_SIZE];
  1001. unsigned int tokenlen;
  1002. char token[OSP_TOKSTR_SIZE];
  1003. enum OSPEFAILREASON reason;
  1004. int error;
  1005. result->tech[0] = '\0';
  1006. result->dest[0] = '\0';
  1007. result->called[0] = '\0';
  1008. result->calling[0] = '\0';
  1009. result->token[0] = '\0';
  1010. result->networkid[0] = '\0';
  1011. result->outtimelimit = OSP_DEF_TIMELIMIT;
  1012. if ((res = osp_get_provider(provider, &p)) <= 0) {
  1013. ast_debug(1, "OSP: Unabe to find OSP provider '%s'\n", provider);
  1014. return res;
  1015. }
  1016. if (result->outhandle == OSP_INVALID_HANDLE) {
  1017. ast_debug(1, "OSP: Transaction handle undefined\n");
  1018. result->numresults = 0;
  1019. if (result->inhandle != OSP_INVALID_HANDLE) {
  1020. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1021. }
  1022. return -1;
  1023. }
  1024. reason = asterisk2osp(cause);
  1025. if (!result->numresults) {
  1026. ast_debug(1, "OSP: No more destination\n");
  1027. OSPPTransactionRecordFailure(result->outhandle, reason);
  1028. if (result->inhandle != OSP_INVALID_HANDLE) {
  1029. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1030. }
  1031. return 0;
  1032. }
  1033. while(result->numresults) {
  1034. result->outcallid.len = sizeof(result->outcallid.buf);
  1035. tokenlen = sizeof(token);
  1036. error = OSPPTransactionGetNextDestination(
  1037. result->outhandle,
  1038. reason,
  1039. 0,
  1040. NULL,
  1041. NULL,
  1042. &result->outtimelimit,
  1043. &result->outcallid.len,
  1044. result->outcallid.buf,
  1045. sizeof(callednum),
  1046. callednum,
  1047. sizeof(callingnum),
  1048. callingnum,
  1049. sizeof(destination),
  1050. destination,
  1051. 0,
  1052. NULL,
  1053. &tokenlen,
  1054. token);
  1055. if (error == OSPC_ERR_NO_ERROR) {
  1056. result->numresults--;
  1057. result->outtimelimit = osp_choose_timelimit(result->intimelimit, result->outtimelimit);
  1058. ast_debug(1, "OSP: outtimelimit '%d'\n", result->outtimelimit);
  1059. ast_debug(1, "OSP: called '%s'\n", callednum);
  1060. ast_debug(1, "OSP: calling '%s'\n", callingnum);
  1061. ast_debug(1, "OSP: destination '%s'\n", destination);
  1062. ast_debug(1, "OSP: token size '%d'\n", tokenlen);
  1063. if ((res = osp_check_destination(p, callednum, callingnum, destination, tokenlen, token, &reason, result)) > 0) {
  1064. res = 1;
  1065. break;
  1066. } else if (!result->numresults) {
  1067. ast_debug(1, "OSP: No more destination\n");
  1068. OSPPTransactionRecordFailure(result->outhandle, reason);
  1069. if (result->inhandle != OSP_INVALID_HANDLE) {
  1070. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NO_ROUTE_TO_DEST);
  1071. }
  1072. res = 0;
  1073. break;
  1074. }
  1075. } else {
  1076. ast_debug(1, "OSP: Unable to get route, error '%d'\n", error);
  1077. result->token[0] = '\0';
  1078. result->numresults = 0;
  1079. result->outtimelimit = OSP_DEF_TIMELIMIT;
  1080. if (result->inhandle != OSP_INVALID_HANDLE) {
  1081. OSPPTransactionRecordFailure(result->inhandle, OSPC_FAIL_NORMAL_UNSPECIFIED);
  1082. }
  1083. res = -1;
  1084. break;
  1085. }
  1086. }
  1087. return res;
  1088. }
  1089. /*!
  1090. * \brief OSP Finish function
  1091. * \param handle OSP in/outbound transaction handle
  1092. * \param recorded If failure reason has been recorded
  1093. * \param cause Asterisk hangup cause
  1094. * \param start Call start time
  1095. * \param connect Call connect time
  1096. * \param end Call end time
  1097. * \param release Who release first, 0 source, 1 destination
  1098. * \return 1 Success, 0 Failed, -1 Error
  1099. */
  1100. static int osp_finish(
  1101. int handle,
  1102. int recorded,
  1103. int cause,
  1104. time_t start,
  1105. time_t connect,
  1106. time_t end,
  1107. unsigned int release)
  1108. {
  1109. int res;
  1110. enum OSPEFAILREASON reason;
  1111. time_t alert = 0;
  1112. unsigned isPddInfoPresent = 0;
  1113. unsigned pdd = 0;
  1114. unsigned int dummy = 0;
  1115. int error;
  1116. if (handle == OSP_INVALID_HANDLE) {
  1117. return 0;
  1118. }
  1119. if (!recorded) {
  1120. reason = asterisk2osp(cause);
  1121. OSPPTransactionRecordFailure(handle, reason);
  1122. }
  1123. error = OSPPTransactionReportUsage(
  1124. handle,
  1125. difftime(end, connect),
  1126. start,
  1127. end,
  1128. alert,
  1129. connect,
  1130. isPddInfoPresent,
  1131. pdd,
  1132. release,
  1133. (unsigned char*)"",
  1134. 0,
  1135. 0,
  1136. 0,
  1137. 0,
  1138. &dummy,
  1139. NULL);
  1140. if (error == OSPC_ERR_NO_ERROR) {
  1141. ast_debug(1, "OSP: Usage reported\n");
  1142. res = 1;
  1143. } else {
  1144. ast_debug(1, "OSP: Unable to report usage, error '%d'\n", error);
  1145. res = -1;
  1146. }
  1147. OSPPTransactionDelete(handle);
  1148. return res;
  1149. }
  1150. /* OSP Application APIs */
  1151. /*!
  1152. * \brief OSP Application OSPAuth
  1153. * \param chan Channel
  1154. * \param data Parameter
  1155. * \return 0 Success, -1 Failed
  1156. */
  1157. static int ospauth_exec(
  1158. struct ast_channel* chan,
  1159. void* data)
  1160. {
  1161. int res;
  1162. const char* provider = OSP_DEF_PROVIDER;
  1163. struct varshead* headp;
  1164. struct ast_var_t* current;
  1165. const char* source = "";
  1166. const char* token = "";
  1167. int handle;
  1168. unsigned int timelimit;
  1169. char buffer[OSP_INTSTR_SIZE];
  1170. const char* status;
  1171. char* tmp;
  1172. AST_DECLARE_APP_ARGS(args,
  1173. AST_APP_ARG(provider);
  1174. AST_APP_ARG(options);
  1175. );
  1176. if (!(tmp = ast_strdupa(data))) {
  1177. ast_log(LOG_ERROR, "Out of memory\n");
  1178. return -1;
  1179. }
  1180. AST_STANDARD_APP_ARGS(args, tmp);
  1181. if (!ast_strlen_zero(args.provider)) {
  1182. provider = args.provider;
  1183. }
  1184. ast_debug(1, "OSPAuth: provider '%s'\n", provider);
  1185. headp = &chan->varshead;
  1186. AST_LIST_TRAVERSE(headp, current, entries) {
  1187. if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
  1188. source = ast_var_value(current);
  1189. } else if (!strcasecmp(ast_var_name(current), "OSPINTOKEN")) {
  1190. token = ast_var_value(current);
  1191. }
  1192. }
  1193. ast_debug(1, "OSPAuth: source '%s'\n", source);
  1194. ast_debug(1, "OSPAuth: token size '%zd'\n", strlen(token));
  1195. if ((res = osp_auth(provider, &handle, source, chan->cid.cid_num, chan->exten, token, &timelimit)) > 0) {
  1196. status = AST_OSP_SUCCESS;
  1197. } else {
  1198. timelimit = OSP_DEF_TIMELIMIT;
  1199. if (!res) {
  1200. status = AST_OSP_FAILED;
  1201. } else {
  1202. status = AST_OSP_ERROR;
  1203. }
  1204. }
  1205. snprintf(buffer, sizeof(buffer), "%d", handle);
  1206. pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
  1207. ast_debug(1, "OSPAuth: OSPINHANDLE '%s'\n", buffer);
  1208. snprintf(buffer, sizeof(buffer), "%d", timelimit);
  1209. pbx_builtin_setvar_helper(chan, "OSPINTIMELIMIT", buffer);
  1210. ast_debug(1, "OSPAuth: OSPINTIMELIMIT '%s'\n", buffer);
  1211. pbx_builtin_setvar_helper(chan, "OSPAUTHSTATUS", status);
  1212. ast_debug(1, "OSPAuth: %s\n", status);
  1213. if(res <= 0) {
  1214. res = -1;
  1215. } else {
  1216. res = 0;
  1217. }
  1218. return res;
  1219. }
  1220. /*!
  1221. * \brief OSP Application OSPLookup
  1222. * \param chan Channel
  1223. * \param data Parameter
  1224. * \return 0 Success, -1 Failed
  1225. */
  1226. static int osplookup_exec(
  1227. struct ast_channel* chan,
  1228. void* data)
  1229. {
  1230. int res, cres;
  1231. const char* provider = OSP_DEF_PROVIDER;
  1232. struct varshead* headp;
  1233. struct ast_var_t* current;
  1234. const char* srcdev = "";
  1235. const char* netid = "";
  1236. char buffer[OSP_TOKSTR_SIZE];
  1237. unsigned int callidtypes = OSP_CALLID_UNDEFINED;
  1238. struct osp_result result;
  1239. const char* status;
  1240. char* tmp;
  1241. AST_DECLARE_APP_ARGS(args,
  1242. AST_APP_ARG(exten);
  1243. AST_APP_ARG(provider);
  1244. AST_APP_ARG(options);
  1245. );
  1246. if (ast_strlen_zero(data)) {
  1247. ast_log(LOG_WARNING, "OSPLookup: Arg required, OSPLookup(exten[|provider[|options]])\n");
  1248. return -1;
  1249. }
  1250. if (!(tmp = ast_strdupa(data))) {
  1251. ast_log(LOG_ERROR, "Out of memory\n");
  1252. return -1;
  1253. }
  1254. AST_STANDARD_APP_ARGS(args, tmp);
  1255. ast_debug(1, "OSPLookup: exten '%s'\n", args.exten);
  1256. if (!ast_strlen_zero(args.provider)) {
  1257. provider = args.provider;
  1258. }
  1259. ast_debug(1, "OSPlookup: provider '%s'\n", provider);
  1260. if (args.options) {
  1261. if (strchr(args.options, 'h')) {
  1262. callidtypes |= OSP_CALLID_H323;
  1263. }
  1264. if (strchr(args.options, 's')) {
  1265. callidtypes |= OSP_CALLID_SIP;
  1266. }
  1267. if (strchr(args.options, 'i')) {
  1268. callidtypes |= OSP_CALLID_IAX;
  1269. }
  1270. }
  1271. ast_debug(1, "OSPLookup: call id types '%d'\n", callidtypes);
  1272. result.inhandle = OSP_INVALID_HANDLE;
  1273. result.intimelimit = OSP_DEF_TIMELIMIT;
  1274. headp = &chan->varshead;
  1275. AST_LIST_TRAVERSE(headp, current, entries) {
  1276. if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
  1277. if (sscanf(ast_var_value(current), "%30d", &result.inhandle) != 1) {
  1278. result.inhandle = OSP_INVALID_HANDLE;
  1279. }
  1280. } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
  1281. if (sscanf(ast_var_value(current), "%30d", &result.intimelimit) != 1) {
  1282. result.intimelimit = OSP_DEF_TIMELIMIT;
  1283. }
  1284. } else if (!strcasecmp(ast_var_name(current), "OSPINNETWORKID")) {
  1285. netid = ast_var_value(current);
  1286. } else if (!strcasecmp(ast_var_name(current), "OSPPEERIP")) {
  1287. srcdev = ast_var_value(current);
  1288. }
  1289. }
  1290. ast_debug(1, "OSPLookup: OSPINHANDLE '%d'\n", result.inhandle);
  1291. ast_debug(1, "OSPLookup: OSPINTIMELIMIT '%d'\n", result.intimelimit);
  1292. ast_debug(1, "OSPLookup: OSPINNETWORKID '%s'\n", netid);
  1293. ast_debug(1, "OSPLookup: source device '%s'\n", srcdev);
  1294. if ((cres = ast_autoservice_start(chan)) < 0) {
  1295. return -1;
  1296. }
  1297. if ((res = osp_lookup(provider, srcdev, chan->cid.cid_num, args.exten, callidtypes, &result)) > 0) {
  1298. status = AST_OSP_SUCCESS;
  1299. } else {
  1300. result.tech[0] = '\0';
  1301. result.dest[0] = '\0';
  1302. result.called[0] = '\0';
  1303. result.calling[0] = '\0';
  1304. result.token[0] = '\0';
  1305. result.networkid[0] = '\0';
  1306. result.numresults = 0;
  1307. result.outtimelimit = OSP_DEF_TIMELIMIT;
  1308. result.outcallid.buf[0] = '\0';
  1309. result.outcallid.len = 0;
  1310. if (!res) {
  1311. status = AST_OSP_FAILED;
  1312. } else {
  1313. status = AST_OSP_ERROR;
  1314. }
  1315. }
  1316. snprintf(buffer, sizeof(buffer), "%d", result.outhandle);
  1317. pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
  1318. ast_debug(1, "OSPLookup: OSPOUTHANDLE '%s'\n", buffer);
  1319. pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
  1320. ast_debug(1, "OSPLookup: OSPTECH '%s'\n", result.tech);
  1321. pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
  1322. ast_debug(1, "OSPLookup: OSPDEST '%s'\n", result.dest);
  1323. pbx_builtin_setvar_helper(chan, "OSPCALLED", result.called);
  1324. ast_debug(1, "OSPLookup: OSPCALLED '%s'\n", result.called);
  1325. pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
  1326. ast_debug(1, "OSPLookup: OSPCALLING '%s'\n", result.calling);
  1327. pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
  1328. ast_debug(1, "OSPLookup: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
  1329. snprintf(buffer, sizeof(buffer), "%d", result.numresults);
  1330. pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
  1331. ast_debug(1, "OSPLookup: OSPRESULTS '%s'\n", buffer);
  1332. snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
  1333. pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
  1334. ast_debug(1, "OSPLookup: OSPOUTTIMELIMIT '%s'\n", buffer);
  1335. snprintf(buffer, sizeof(buffer), "%d", callidtypes);
  1336. pbx_builtin_setvar_helper(chan, "OSPOUTCALLIDTYPES", buffer);
  1337. ast_debug(1, "OSPLookup: OSPOUTCALLIDTYPES '%s'\n", buffer);
  1338. pbx_builtin_setvar_helper(chan, "OSPLOOKUPSTATUS", status);
  1339. ast_debug(1, "OSPLookup: %s\n", status);
  1340. if (!strcasecmp(result.tech, OSP_TECH_H323)) {
  1341. if ((callidtypes & OSP_CALLID_H323) && (result.outcallid.len != 0)) {
  1342. osp_uuid2str(result.outcallid.buf, buffer, sizeof(buffer));
  1343. } else {
  1344. buffer[0] = '\0';
  1345. }
  1346. pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
  1347. snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
  1348. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1349. } else if (!strcasecmp(result.tech, OSP_TECH_SIP)) {
  1350. snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
  1351. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1352. if (!ast_strlen_zero(result.token)) {
  1353. snprintf(buffer, sizeof(buffer), "%s%s", OSP_SIP_HEADER, result.token);
  1354. pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
  1355. ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
  1356. }
  1357. } else if (!strcasecmp(result.tech, OSP_TECH_IAX)) {
  1358. snprintf(buffer, sizeof(buffer), "%s/%s/%s", result.tech, result.dest, result.called);
  1359. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1360. }
  1361. if ((cres = ast_autoservice_stop(chan)) < 0) {
  1362. return -1;
  1363. }
  1364. if(res <= 0) {
  1365. res = -1;
  1366. } else {
  1367. res = 0;
  1368. }
  1369. return res;
  1370. }
  1371. /*!
  1372. * \brief OSP Application OSPNext
  1373. * \param chan Channel
  1374. * \param data Parameter
  1375. * \return 0 Success, -1 Failed
  1376. */
  1377. static int ospnext_exec(
  1378. struct ast_channel* chan,
  1379. void* data)
  1380. {
  1381. int res;
  1382. const char* provider = OSP_DEF_PROVIDER;
  1383. int cause = 0;
  1384. struct varshead* headp;
  1385. struct ast_var_t* current;
  1386. struct osp_result result;
  1387. char buffer[OSP_TOKSTR_SIZE];
  1388. unsigned int callidtypes = OSP_CALLID_UNDEFINED;
  1389. const char* status;
  1390. char* tmp;
  1391. AST_DECLARE_APP_ARGS(args,
  1392. AST_APP_ARG(cause);
  1393. AST_APP_ARG(provider);
  1394. AST_APP_ARG(options);
  1395. );
  1396. if (ast_strlen_zero(data)) {
  1397. ast_log(LOG_WARNING, "OSPNext: Arg required, OSPNext(cause[|provider[|options]])\n");
  1398. return -1;
  1399. }
  1400. if (!(tmp = ast_strdupa(data))) {
  1401. ast_log(LOG_ERROR, "Out of memory\n");
  1402. return -1;
  1403. }
  1404. AST_STANDARD_APP_ARGS(args, tmp);
  1405. if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
  1406. cause = 0;
  1407. }
  1408. ast_debug(1, "OSPNext: cause '%d'\n", cause);
  1409. if (!ast_strlen_zero(args.provider)) {
  1410. provider = args.provider;
  1411. }
  1412. ast_debug(1, "OSPlookup: provider '%s'\n", provider);
  1413. result.inhandle = OSP_INVALID_HANDLE;
  1414. result.outhandle = OSP_INVALID_HANDLE;
  1415. result.intimelimit = OSP_DEF_TIMELIMIT;
  1416. result.numresults = 0;
  1417. headp = &chan->varshead;
  1418. AST_LIST_TRAVERSE(headp, current, entries) {
  1419. if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
  1420. if (sscanf(ast_var_value(current), "%30d", &result.inhandle) != 1) {
  1421. result.inhandle = OSP_INVALID_HANDLE;
  1422. }
  1423. } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
  1424. if (sscanf(ast_var_value(current), "%30d", &result.outhandle) != 1) {
  1425. result.outhandle = OSP_INVALID_HANDLE;
  1426. }
  1427. } else if (!strcasecmp(ast_var_name(current), "OSPINTIMELIMIT")) {
  1428. if (sscanf(ast_var_value(current), "%30d", &result.intimelimit) != 1) {
  1429. result.intimelimit = OSP_DEF_TIMELIMIT;
  1430. }
  1431. } else if (!strcasecmp(ast_var_name(current), "OSPOUTCALLIDTYPES")) {
  1432. if (sscanf(ast_var_value(current), "%30d", &callidtypes) != 1) {
  1433. callidtypes = OSP_CALLID_UNDEFINED;
  1434. }
  1435. } else if (!strcasecmp(ast_var_name(current), "OSPRESULTS")) {
  1436. if (sscanf(ast_var_value(current), "%30d", &result.numresults) != 1) {
  1437. result.numresults = 0;
  1438. }
  1439. }
  1440. }
  1441. ast_debug(1, "OSPNext: OSPINHANDLE '%d'\n", result.inhandle);
  1442. ast_debug(1, "OSPNext: OSPOUTHANDLE '%d'\n", result.outhandle);
  1443. ast_debug(1, "OSPNext: OSPINTIMELIMIT '%d'\n", result.intimelimit);
  1444. ast_debug(1, "OSPNext: OSPOUTCALLIDTYPES '%d'\n", callidtypes);
  1445. ast_debug(1, "OSPNext: OSPRESULTS '%d'\n", result.numresults);
  1446. if ((res = osp_next(provider, cause, &result)) > 0) {
  1447. status = AST_OSP_SUCCESS;
  1448. } else {
  1449. result.tech[0] = '\0';
  1450. result.dest[0] = '\0';
  1451. result.called[0] = '\0';
  1452. result.calling[0] = '\0';
  1453. result.token[0] = '\0';
  1454. result.networkid[0] = '\0';
  1455. result.numresults = 0;
  1456. result.outtimelimit = OSP_DEF_TIMELIMIT;
  1457. result.outcallid.buf[0] = '\0';
  1458. result.outcallid.len = 0;
  1459. if (!res) {
  1460. status = AST_OSP_FAILED;
  1461. } else {
  1462. status = AST_OSP_ERROR;
  1463. }
  1464. }
  1465. pbx_builtin_setvar_helper(chan, "OSPTECH", result.tech);
  1466. ast_debug(1, "OSPNext: OSPTECH '%s'\n", result.tech);
  1467. pbx_builtin_setvar_helper(chan, "OSPDEST", result.dest);
  1468. ast_debug(1, "OSPNext: OSPDEST '%s'\n", result.dest);
  1469. pbx_builtin_setvar_helper(chan, "OSPCALLED", result.called);
  1470. ast_debug(1, "OSPNext: OSPCALLED'%s'\n", result.called);
  1471. pbx_builtin_setvar_helper(chan, "OSPCALLING", result.calling);
  1472. ast_debug(1, "OSPNext: OSPCALLING '%s'\n", result.calling);
  1473. pbx_builtin_setvar_helper(chan, "OSPOUTTOKEN", result.token);
  1474. ast_debug(1, "OSPNext: OSPOUTTOKEN size '%zd'\n", strlen(result.token));
  1475. snprintf(buffer, sizeof(buffer), "%d", result.numresults);
  1476. pbx_builtin_setvar_helper(chan, "OSPRESULTS", buffer);
  1477. ast_debug(1, "OSPNext: OSPRESULTS '%s'\n", buffer);
  1478. snprintf(buffer, sizeof(buffer), "%d", result.outtimelimit);
  1479. pbx_builtin_setvar_helper(chan, "OSPOUTTIMELIMIT", buffer);
  1480. ast_debug(1, "OSPNext: OSPOUTTIMELIMIT '%s'\n", buffer);
  1481. pbx_builtin_setvar_helper(chan, "OSPNEXTSTATUS", status);
  1482. ast_debug(1, "OSPNext: %s\n", status);
  1483. if (!strcasecmp(result.tech, OSP_TECH_H323)) {
  1484. if ((callidtypes & OSP_CALLID_H323) && (result.outcallid.len != 0)) {
  1485. osp_uuid2str(result.outcallid.buf, buffer, sizeof(buffer));
  1486. } else {
  1487. buffer[0] = '\0';
  1488. }
  1489. pbx_builtin_setvar_helper(chan, "OSPOUTCALLID", buffer);
  1490. snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
  1491. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1492. } else if (!strcasecmp(result.tech, OSP_TECH_SIP)) {
  1493. snprintf(buffer, sizeof(buffer), "%s/%s@%s", result.tech, result.called, result.dest);
  1494. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1495. if (!ast_strlen_zero(result.token)) {
  1496. snprintf(buffer, sizeof(buffer), "%s%s", OSP_SIP_HEADER, result.token);
  1497. pbx_builtin_setvar_helper(chan, "_SIPADDHEADER", buffer);
  1498. ast_debug(1, "OSPLookup: SIPADDHEADER size '%zd'\n", strlen(buffer));
  1499. }
  1500. } else if (!strcasecmp(result.tech, OSP_TECH_IAX)) {
  1501. snprintf(buffer, sizeof(buffer), "%s/%s/%s", result.tech, result.dest, result.called);
  1502. pbx_builtin_setvar_helper(chan, "OSPDIALSTR", buffer);
  1503. }
  1504. if(res <= 0) {
  1505. res = -1;
  1506. } else {
  1507. res = 0;
  1508. }
  1509. return res;
  1510. }
  1511. /*!
  1512. * \brief OSP Application OSPFinish
  1513. * \param chan Channel
  1514. * \param data Parameter
  1515. * \return 0 Success, -1 Failed
  1516. */
  1517. static int ospfinished_exec(
  1518. struct ast_channel* chan,
  1519. void* data)
  1520. {
  1521. int res = 1;
  1522. int cause = 0;
  1523. struct varshead* headp;
  1524. struct ast_var_t* current;
  1525. int inhandle = OSP_INVALID_HANDLE;
  1526. int outhandle = OSP_INVALID_HANDLE;
  1527. int recorded = 0;
  1528. time_t start, connect, end;
  1529. unsigned int release;
  1530. char buffer[OSP_INTSTR_SIZE];
  1531. const char* status;
  1532. char* tmp;
  1533. AST_DECLARE_APP_ARGS(args,
  1534. AST_APP_ARG(cause);
  1535. AST_APP_ARG(options);
  1536. );
  1537. if (!(tmp = ast_strdupa(data))) {
  1538. ast_log(LOG_ERROR, "Out of memory\n");
  1539. return -1;
  1540. }
  1541. AST_STANDARD_APP_ARGS(args, tmp);
  1542. headp = &chan->varshead;
  1543. AST_LIST_TRAVERSE(headp, current, entries) {
  1544. if (!strcasecmp(ast_var_name(current), "OSPINHANDLE")) {
  1545. if (sscanf(ast_var_value(current), "%30d", &inhandle) != 1) {
  1546. inhandle = OSP_INVALID_HANDLE;
  1547. }
  1548. } else if (!strcasecmp(ast_var_name(current), "OSPOUTHANDLE")) {
  1549. if (sscanf(ast_var_value(current), "%30d", &outhandle) != 1) {
  1550. outhandle = OSP_INVALID_HANDLE;
  1551. }
  1552. } else if (!recorded &&
  1553. (!strcasecmp(ast_var_name(current), "OSPAUTHSTATUS") ||
  1554. !strcasecmp(ast_var_name(current), "OSPLOOKUPSTATUS") ||
  1555. !strcasecmp(ast_var_name(current), "OSPNEXTSTATUS")))
  1556. {
  1557. if (strcasecmp(ast_var_value(current), AST_OSP_SUCCESS)) {
  1558. recorded = 1;
  1559. }
  1560. }
  1561. }
  1562. ast_debug(1, "OSPFinish: OSPINHANDLE '%d'\n", inhandle);
  1563. ast_debug(1, "OSPFinish: OSPOUTHANDLE '%d'\n", outhandle);
  1564. ast_debug(1, "OSPFinish: recorded '%d'\n", recorded);
  1565. if (!ast_strlen_zero(args.cause) && sscanf(args.cause, "%30d", &cause) != 1) {
  1566. cause = 0;
  1567. }
  1568. ast_debug(1, "OSPFinish: cause '%d'\n", cause);
  1569. if (chan->cdr) {
  1570. start = chan->cdr->start.tv_sec;
  1571. connect = chan->cdr->answer.tv_sec;
  1572. if (connect) {
  1573. end = time(NULL);
  1574. } else {
  1575. end = connect;
  1576. }
  1577. } else {
  1578. start = 0;
  1579. connect = 0;
  1580. end = 0;
  1581. }
  1582. ast_debug(1, "OSPFinish: start '%ld'\n", start);
  1583. ast_debug(1, "OSPFinish: connect '%ld'\n", connect);
  1584. ast_debug(1, "OSPFinish: end '%ld'\n", end);
  1585. release = ast_check_hangup(chan) ? 0 : 1;
  1586. if (osp_finish(outhandle, recorded, cause, start, connect, end, release) <= 0) {
  1587. ast_debug(1, "OSPFinish: Unable to report usage for outbound call\n");
  1588. }
  1589. switch (cause) {
  1590. case AST_CAUSE_NORMAL_CLEARING:
  1591. break;
  1592. default:
  1593. cause = AST_CAUSE_NO_ROUTE_DESTINATION;
  1594. break;
  1595. }
  1596. if (osp_finish(inhandle, recorded, cause, start, connect, end, release) <= 0) {
  1597. ast_debug(1, "OSPFinish: Unable to report usage for inbound call\n");
  1598. }
  1599. snprintf(buffer, sizeof(buffer), "%d", OSP_INVALID_HANDLE);
  1600. pbx_builtin_setvar_helper(chan, "OSPOUTHANDLE", buffer);
  1601. pbx_builtin_setvar_helper(chan, "OSPINHANDLE", buffer);
  1602. if (res > 0) {
  1603. status = AST_OSP_SUCCESS;
  1604. } else if (!res) {
  1605. status = AST_OSP_FAILED;
  1606. } else {
  1607. status = AST_OSP_ERROR;
  1608. }
  1609. pbx_builtin_setvar_helper(chan, "OSPFINISHSTATUS", status);
  1610. if(!res) {
  1611. res = -1;
  1612. } else {
  1613. res = 0;
  1614. }
  1615. return res;
  1616. }
  1617. /* OSP Module APIs */
  1618. static int osp_unload(void);
  1619. static int osp_load(int reload)
  1620. {
  1621. const char* t;
  1622. unsigned int v;
  1623. struct ast_config* cfg;
  1624. struct ast_flags config_flags = { reload ? CONFIG_FLAG_FILEUNCHANGED : 0 };
  1625. int error = OSPC_ERR_NO_ERROR;
  1626. if ((cfg = ast_config_load(OSP_CONFIG_FILE, config_flags)) == CONFIG_STATUS_FILEUNCHANGED)
  1627. return 0;
  1628. if (cfg) {
  1629. if (reload)
  1630. osp_unload();
  1631. t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "accelerate");
  1632. if (t && ast_true(t)) {
  1633. if ((error = OSPPInit(1)) != OSPC_ERR_NO_ERROR) {
  1634. ast_log(LOG_WARNING, "OSP: Unable to enable hardware accelleration\n");
  1635. OSPPInit(0);
  1636. } else {
  1637. osp_hardware = 1;
  1638. }
  1639. } else {
  1640. OSPPInit(0);
  1641. }
  1642. ast_debug(1, "OSP: osp_hardware '%d'\n", osp_hardware);
  1643. t = ast_variable_retrieve(cfg, OSP_GENERAL_CAT, "tokenformat");
  1644. if (t) {
  1645. if ((sscanf(t, "%30d", &v) == 1) &&
  1646. ((v == TOKEN_ALGO_SIGNED) || (v == TOKEN_ALGO_UNSIGNED) || (v == TOKEN_ALGO_BOTH)))
  1647. {
  1648. osp_tokenformat = v;
  1649. } else {
  1650. ast_log(LOG_WARNING, "tokenformat should be an integer from %d, %d or %d, not '%s'\n",
  1651. TOKEN_ALGO_SIGNED, TOKEN_ALGO_UNSIGNED, TOKEN_ALGO_BOTH, t);
  1652. }
  1653. }
  1654. ast_debug(1, "OSP: osp_tokenformat '%d'\n", osp_tokenformat);
  1655. t = ast_category_browse(cfg, NULL);
  1656. while(t) {
  1657. if (strcasecmp(t, OSP_GENERAL_CAT)) {
  1658. osp_create_provider(cfg, t);
  1659. }
  1660. t = ast_category_browse(cfg, t);
  1661. }
  1662. osp_initialized = 1;
  1663. ast_config_destroy(cfg);
  1664. } else {
  1665. ast_log(LOG_WARNING, "OSP: Unable to find configuration. OSP support disabled\n");
  1666. return 0;
  1667. }
  1668. ast_debug(1, "OSP: osp_initialized '%d'\n", osp_initialized);
  1669. return 1;
  1670. }
  1671. static int osp_unload(void)
  1672. {
  1673. struct osp_provider* p;
  1674. struct osp_provider* next;
  1675. if (osp_initialized) {
  1676. ast_mutex_lock(&osplock);
  1677. p = ospproviders;
  1678. while(p) {
  1679. next = p->next;
  1680. OSPPProviderDelete(p->handle, 0);
  1681. ast_free(p);
  1682. p = next;
  1683. }
  1684. ospproviders = NULL;
  1685. ast_mutex_unlock(&osplock);
  1686. OSPPCleanup();
  1687. osp_tokenformat = TOKEN_ALGO_SIGNED;
  1688. osp_hardware = 0;
  1689. osp_initialized = 0;
  1690. }
  1691. return 0;
  1692. }
  1693. static char *handle_cli_osp_show(struct ast_cli_entry *e, int cmd, struct ast_cli_args *a)
  1694. {
  1695. int i;
  1696. int found = 0;
  1697. struct osp_provider* p;
  1698. const char* provider = NULL;
  1699. const char* tokenalgo;
  1700. switch (cmd) {
  1701. case CLI_INIT:
  1702. e->command = "osp show";
  1703. e->usage =
  1704. "Usage: osp show\n"
  1705. " Displays information on Open Settlement Protocol support\n";
  1706. return NULL;
  1707. case CLI_GENERATE:
  1708. return NULL;
  1709. }
  1710. if ((a->argc < 2) || (a->argc > 3))
  1711. return CLI_SHOWUSAGE;
  1712. if (a->argc > 2)
  1713. provider = a->argv[2];
  1714. if (!provider) {
  1715. switch (osp_tokenformat) {
  1716. case TOKEN_ALGO_BOTH:
  1717. tokenalgo = "Both";
  1718. break;
  1719. case TOKEN_ALGO_UNSIGNED:
  1720. tokenalgo = "Unsigned";
  1721. break;
  1722. case TOKEN_ALGO_SIGNED:
  1723. default:
  1724. tokenalgo = "Signed";
  1725. break;
  1726. }
  1727. ast_cli(a->fd, "OSP: %s %s %s\n",
  1728. osp_initialized ? "Initialized" : "Uninitialized", osp_hardware ? "Accelerated" : "Normal", tokenalgo);
  1729. }
  1730. ast_mutex_lock(&osplock);
  1731. p = ospproviders;
  1732. while(p) {
  1733. if (!provider || !strcasecmp(p->name, provider)) {
  1734. if (found) {
  1735. ast_cli(a->fd, "\n");
  1736. }
  1737. ast_cli(a->fd, " == OSP Provider '%s' == \n", p->name);
  1738. ast_cli(a->fd, "Local Private Key: %s\n", p->privatekey);
  1739. ast_cli(a->fd, "Local Certificate: %s\n", p->localcert);
  1740. for (i = 0; i < p->cacount; i++) {
  1741. ast_cli(a->fd, "CA Certificate %d: %s\n", i + 1, p->cacerts[i]);
  1742. }
  1743. for (i = 0; i < p->spcount; i++) {
  1744. ast_cli(a->fd, "Service Point %d: %s\n", i + 1, p->srvpoints[i]);
  1745. }
  1746. ast_cli(a->fd, "Max Connections: %d\n", p->maxconnections);
  1747. ast_cli(a->fd, "Retry Delay: %d seconds\n", p->retrydelay);
  1748. ast_cli(a->fd, "Retry Limit: %d\n", p->retrylimit);
  1749. ast_cli(a->fd, "Timeout: %d milliseconds\n", p->timeout);
  1750. ast_cli(a->fd, "Source: %s\n", strlen(p->source) ? p->source : "<unspecified>");
  1751. ast_cli(a->fd, "Auth Policy %d\n", p->authpolicy);
  1752. ast_cli(a->fd, "Default protocol %s\n", p->defaultprotocol);
  1753. ast_cli(a->fd, "OSP Handle: %d\n", p->handle);
  1754. found++;
  1755. }
  1756. p = p->next;
  1757. }
  1758. ast_mutex_unlock(&osplock);
  1759. if (!found) {
  1760. if (provider) {
  1761. ast_cli(a->fd, "Unable to find OSP provider '%s'\n", provider);
  1762. } else {
  1763. ast_cli(a->fd, "No OSP providers configured\n");
  1764. }
  1765. }
  1766. return CLI_SUCCESS;
  1767. }
  1768. static const char* app1= "OSPAuth";
  1769. static const char* synopsis1 = "OSP authentication";
  1770. static const char* descrip1 =
  1771. " OSPAuth([provider[,options]]): Authenticate a SIP INVITE by OSP and sets\n"
  1772. "the variables:\n"
  1773. " ${OSPINHANDLE}: The inbound call transaction handle\n"
  1774. " ${OSPINTIMELIMIT}: The inbound call duration limit in seconds\n"
  1775. "\n"
  1776. "This application sets the following channel variable upon completion:\n"
  1777. " OSPAUTHSTATUS The status of the OSP Auth attempt as a text string, one of\n"
  1778. " SUCCESS | FAILED | ERROR\n";
  1779. static const char* app2= "OSPLookup";
  1780. static const char* synopsis2 = "Lookup destination by OSP";
  1781. static const char* descrip2 =
  1782. " OSPLookup(exten[,provider[,options]]): Looks up an extension via OSP and sets\n"
  1783. "the variables, where 'n' is the number of the result beginning with 1:\n"
  1784. " ${OSPOUTHANDLE}: The OSP Handle for anything remaining\n"
  1785. " ${OSPTECH}: The technology to use for the call\n"
  1786. " ${OSPDEST}: The destination to use for the call\n"
  1787. " ${OSPCALLED}: The called number to use for the call\n"
  1788. " ${OSPCALLING}: The calling number to use for the call\n"
  1789. " ${OSPDIALSTR}: The dial command string\n"
  1790. " ${OSPOUTTOKEN}: The actual OSP token as a string\n"
  1791. " ${OSPOUTTIMELIMIT}: The outbound call duration limit in seconds\n"
  1792. " ${OSPOUTCALLIDTYPES}: The outbound call id types\n"
  1793. " ${OSPOUTCALLID}: The outbound call id\n"
  1794. " ${OSPRESULTS}: The number of OSP results total remaining\n"
  1795. "\n"
  1796. "The option string may contain the following character:\n"
  1797. " 'h' -- generate H323 call id for the outbound call\n"
  1798. " 's' -- generate SIP call id for the outbound call. Have not been implemented\n"
  1799. " 'i' -- generate IAX call id for the outbound call. Have not been implemented\n"
  1800. "This application sets the following channel variable upon completion:\n"
  1801. " OSPLOOKUPSTATUS The status of the OSP Lookup attempt as a text string, one of\n"
  1802. " SUCCESS | FAILED | ERROR\n";
  1803. static const char* app3 = "OSPNext";
  1804. static const char* synopsis3 = "Lookup next destination by OSP";
  1805. static const char* descrip3 =
  1806. " OSPNext(cause[,provider[,options]]): Looks up the next OSP Destination for ${OSPOUTHANDLE}\n"
  1807. "See OSPLookup for more information\n"
  1808. "\n"
  1809. "This application sets the following channel variable upon completion:\n"
  1810. " OSPNEXTSTATUS The status of the OSP Next attempt as a text string, one of\n"
  1811. " SUCCESS | FAILED | ERROR\n";
  1812. static const char* app4 = "OSPFinish";
  1813. static const char* synopsis4 = "Record OSP entry";
  1814. static const char* descrip4 =
  1815. " OSPFinish([status[,options]]): Records call state for ${OSPINHANDLE}, according to\n"
  1816. "status, which should be one of BUSY, CONGESTION, ANSWER, NOANSWER, or CHANUNAVAIL\n"
  1817. "or coincidentally, just what the Dial application stores in its ${DIALSTATUS}.\n"
  1818. "\n"
  1819. "This application sets the following channel variable upon completion:\n"
  1820. " OSPFINISHSTATUS The status of the OSP Finish attempt as a text string, one of\n"
  1821. " SUCCESS | FAILED | ERROR \n";
  1822. static struct ast_cli_entry cli_osp[] = {
  1823. AST_CLI_DEFINE(handle_cli_osp_show, "Displays OSF information")
  1824. };
  1825. static int load_module(void)
  1826. {
  1827. int res;
  1828. if (!osp_load(0))
  1829. return AST_MODULE_LOAD_DECLINE;
  1830. ast_cli_register_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
  1831. res = ast_register_application(app1, ospauth_exec, synopsis1, descrip1);
  1832. res |= ast_register_application(app2, osplookup_exec, synopsis2, descrip2);
  1833. res |= ast_register_application(app3, ospnext_exec, synopsis3, descrip3);
  1834. res |= ast_register_application(app4, ospfinished_exec, synopsis4, descrip4);
  1835. return res;
  1836. }
  1837. static int unload_module(void)
  1838. {
  1839. int res;
  1840. res = ast_unregister_application(app4);
  1841. res |= ast_unregister_application(app3);
  1842. res |= ast_unregister_application(app2);
  1843. res |= ast_unregister_application(app1);
  1844. ast_cli_unregister_multiple(cli_osp, sizeof(cli_osp) / sizeof(struct ast_cli_entry));
  1845. osp_unload();
  1846. return res;
  1847. }
  1848. static int reload(void)
  1849. {
  1850. osp_load(1);
  1851. return 0;
  1852. }
  1853. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_DEFAULT, "Open Settlement Protocol Applications",
  1854. .load = load_module,
  1855. .unload = unload_module,
  1856. .reload = reload,
  1857. );