res_pjsip_registrar.c 27 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833
  1. /*
  2. * Asterisk -- An open source telephony toolkit.
  3. *
  4. * Copyright (C) 2013, Digium, Inc.
  5. *
  6. * Joshua Colp <jcolp@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. /*** MODULEINFO
  19. <depend>pjproject</depend>
  20. <depend>res_pjsip</depend>
  21. <support_level>core</support_level>
  22. ***/
  23. #include "asterisk.h"
  24. #include <pjsip.h>
  25. #include <pjsip_ua.h>
  26. #include "asterisk/res_pjsip.h"
  27. #include "asterisk/module.h"
  28. #include "asterisk/test.h"
  29. #include "asterisk/taskprocessor.h"
  30. #include "asterisk/manager.h"
  31. #include "res_pjsip/include/res_pjsip_private.h"
  32. /*** DOCUMENTATION
  33. <manager name="PJSIPShowRegistrationsInbound" language="en_US">
  34. <synopsis>
  35. Lists PJSIP inbound registrations.
  36. </synopsis>
  37. <syntax />
  38. <description>
  39. <para>
  40. In response <literal>InboundRegistrationDetail</literal> events showing configuration and status
  41. information are raised for each inbound registration object. As well as <literal>AuthDetail</literal>
  42. events for each associated auth object. Once all events are completed an
  43. <literal>InboundRegistrationDetailComplete</literal> is issued.
  44. </para>
  45. </description>
  46. </manager>
  47. ***/
  48. /*! \brief Internal function which returns the expiration time for a contact */
  49. static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
  50. {
  51. pjsip_expires_hdr *expires;
  52. int expiration = aor->default_expiration;
  53. if (contact->expires != -1) {
  54. /* Expiration was provided with the contact itself */
  55. expiration = contact->expires;
  56. } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
  57. /* Expiration was provided using the Expires header */
  58. expiration = expires->ivalue;
  59. }
  60. /* If the value has explicitly been set to 0, do not enforce */
  61. if (!expiration) {
  62. return expiration;
  63. }
  64. /* Enforce the range that we will allow for expiration */
  65. if (expiration < aor->minimum_expiration) {
  66. expiration = aor->minimum_expiration;
  67. } else if (expiration > aor->maximum_expiration) {
  68. expiration = aor->maximum_expiration;
  69. }
  70. return expiration;
  71. }
  72. /*! \brief Structure used for finding contact */
  73. struct registrar_contact_details {
  74. /*! \brief Pool used for parsing URI */
  75. pj_pool_t *pool;
  76. /*! \brief URI being looked for */
  77. pjsip_uri *uri;
  78. };
  79. /*! \brief Callback function for finding a contact */
  80. static int registrar_find_contact(void *obj, void *arg, int flags)
  81. {
  82. struct ast_sip_contact *contact = obj;
  83. const struct registrar_contact_details *details = arg;
  84. pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
  85. return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
  86. }
  87. /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
  88. static int registrar_validate_contacts(const pjsip_rx_data *rdata, struct ao2_container *contacts, struct ast_sip_aor *aor, int *added, int *updated, int *deleted)
  89. {
  90. pjsip_contact_hdr *previous = NULL, *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
  91. struct registrar_contact_details details = {
  92. .pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
  93. };
  94. if (!details.pool) {
  95. return -1;
  96. }
  97. while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
  98. int expiration = registrar_get_expiration(aor, contact, rdata);
  99. RAII_VAR(struct ast_sip_contact *, existing, NULL, ao2_cleanup);
  100. if (contact->star) {
  101. /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
  102. if ((expiration != 0) || previous) {
  103. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  104. return -1;
  105. }
  106. continue;
  107. } else if (previous && previous->star) {
  108. /* If there is a previous contact and it is a '*' this is a deal breaker */
  109. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  110. return -1;
  111. }
  112. previous = contact;
  113. if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
  114. continue;
  115. }
  116. details.uri = pjsip_uri_get_uri(contact->uri);
  117. /* Determine if this is an add, update, or delete for policy enforcement purposes */
  118. if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, &details))) {
  119. if (expiration) {
  120. (*added)++;
  121. }
  122. } else if (expiration) {
  123. (*updated)++;
  124. } else {
  125. (*deleted)++;
  126. }
  127. }
  128. /* The provided contacts are acceptable, huzzah! */
  129. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  130. return 0;
  131. }
  132. /*! \brief Callback function which prunes static contacts */
  133. static int registrar_prune_static(void *obj, void *arg, int flags)
  134. {
  135. struct ast_sip_contact *contact = obj;
  136. return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
  137. }
  138. /*! \brief Internal function used to delete a contact from an AOR */
  139. static int registrar_delete_contact(void *obj, void *arg, int flags)
  140. {
  141. struct ast_sip_contact *contact = obj;
  142. const char *aor_name = arg;
  143. ast_sip_location_delete_contact(contact);
  144. if (!ast_strlen_zero(aor_name)) {
  145. ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact->uri, aor_name);
  146. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  147. "Contact: %s\r\n"
  148. "AOR: %s\r\n"
  149. "UserAgent: %s",
  150. contact->uri,
  151. aor_name,
  152. contact->user_agent);
  153. }
  154. return 0;
  155. }
  156. /*! \brief Internal function which adds a contact to a response */
  157. static int registrar_add_contact(void *obj, void *arg, int flags)
  158. {
  159. struct ast_sip_contact *contact = obj;
  160. pjsip_tx_data *tdata = arg;
  161. pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
  162. pj_str_t uri;
  163. pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
  164. hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
  165. hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
  166. pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
  167. return 0;
  168. }
  169. /*! \brief Helper function which adds a Date header to a response */
  170. static void registrar_add_date_header(pjsip_tx_data *tdata)
  171. {
  172. char date[256];
  173. struct tm tm;
  174. time_t t = time(NULL);
  175. gmtime_r(&t, &tm);
  176. strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
  177. ast_sip_add_header(tdata, "Date", date);
  178. }
  179. #define SERIALIZER_BUCKETS 59
  180. static struct ao2_container *serializers;
  181. /*! \brief Serializer with associated aor key */
  182. struct serializer {
  183. /* Serializer to distribute tasks to */
  184. struct ast_taskprocessor *serializer;
  185. /* The name of the aor to associate with the serializer */
  186. char aor_name[0];
  187. };
  188. static void serializer_destroy(void *obj)
  189. {
  190. struct serializer *ser = obj;
  191. ast_taskprocessor_unreference(ser->serializer);
  192. }
  193. static struct serializer *serializer_create(const char *aor_name)
  194. {
  195. size_t size = strlen(aor_name) + 1;
  196. struct serializer *ser = ao2_alloc(
  197. sizeof(*ser) + size, serializer_destroy);
  198. if (!ser) {
  199. return NULL;
  200. }
  201. if (!(ser->serializer = ast_sip_create_serializer())) {
  202. ao2_ref(ser, -1);
  203. return NULL;
  204. }
  205. strcpy(ser->aor_name, aor_name);
  206. return ser;
  207. }
  208. static struct serializer *serializer_find_or_create(const char *aor_name)
  209. {
  210. struct serializer *ser = ao2_find(serializers, aor_name, OBJ_SEARCH_KEY);
  211. if (ser) {
  212. return ser;
  213. }
  214. if (!(ser = serializer_create(aor_name))) {
  215. return NULL;
  216. }
  217. ao2_link(serializers, ser);
  218. return ser;
  219. }
  220. static int serializer_hash(const void *obj, const int flags)
  221. {
  222. const struct serializer *object;
  223. const char *key;
  224. switch (flags & OBJ_SEARCH_MASK) {
  225. case OBJ_SEARCH_KEY:
  226. key = obj;
  227. return ast_str_hash(key);
  228. case OBJ_SEARCH_OBJECT:
  229. object = obj;
  230. return ast_str_hash(object->aor_name);
  231. default:
  232. /* Hash can only work on something with a full key. */
  233. ast_assert(0);
  234. return 0;
  235. }
  236. }
  237. static int serializer_cmp(void *obj_left, void *obj_right, int flags)
  238. {
  239. const struct serializer *object_left = obj_left;
  240. const struct serializer *object_right = obj_right;
  241. const char *right_key = obj_right;
  242. int cmp;
  243. switch (flags & OBJ_SEARCH_MASK) {
  244. case OBJ_SEARCH_OBJECT:
  245. right_key = object_right->aor_name;
  246. /* Fall through */
  247. case OBJ_SEARCH_KEY:
  248. cmp = strcmp(object_left->aor_name, right_key);
  249. break;
  250. case OBJ_SEARCH_PARTIAL_KEY:
  251. /*
  252. * We could also use a partial key struct containing a length
  253. * so strlen() does not get called for every comparison instead.
  254. */
  255. cmp = strncmp(object_left->aor_name, right_key, strlen(right_key));
  256. break;
  257. default:
  258. cmp = 0;
  259. break;
  260. }
  261. return cmp ? 0 : CMP_MATCH;
  262. }
  263. struct rx_task_data {
  264. pjsip_rx_data *rdata;
  265. struct ast_sip_endpoint *endpoint;
  266. struct ast_sip_aor *aor;
  267. };
  268. static void rx_task_data_destroy(void *obj)
  269. {
  270. struct rx_task_data *task_data = obj;
  271. pjsip_rx_data_free_cloned(task_data->rdata);
  272. ao2_cleanup(task_data->endpoint);
  273. ao2_cleanup(task_data->aor);
  274. }
  275. static struct rx_task_data *rx_task_data_create(pjsip_rx_data *rdata,
  276. struct ast_sip_endpoint *endpoint,
  277. struct ast_sip_aor *aor)
  278. {
  279. struct rx_task_data *task_data = ao2_alloc(
  280. sizeof(*task_data), rx_task_data_destroy);
  281. if (!task_data) {
  282. return NULL;
  283. }
  284. pjsip_rx_data_clone(rdata, 0, &task_data->rdata);
  285. task_data->endpoint = endpoint;
  286. ao2_ref(task_data->endpoint, +1);
  287. task_data->aor = aor;
  288. ao2_ref(task_data->aor, +1);
  289. return task_data;
  290. }
  291. static const pj_str_t path_hdr_name = { "Path", 4 };
  292. static int build_path_data(struct rx_task_data *task_data, struct ast_str **path_str)
  293. {
  294. pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_hdr_name, NULL);
  295. if (!path_hdr) {
  296. return 0;
  297. }
  298. *path_str = ast_str_create(64);
  299. if (!path_str) {
  300. return -1;
  301. }
  302. ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
  303. while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
  304. ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
  305. }
  306. return 0;
  307. }
  308. static int registrar_validate_path(struct rx_task_data *task_data, struct ast_str **path_str)
  309. {
  310. const pj_str_t path_supported_name = { "path", 4 };
  311. pjsip_supported_hdr *supported_hdr;
  312. int i;
  313. if (!task_data->aor->support_path) {
  314. return 0;
  315. }
  316. if (build_path_data(task_data, path_str)) {
  317. return -1;
  318. }
  319. if (!*path_str) {
  320. return 0;
  321. }
  322. supported_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
  323. if (!supported_hdr) {
  324. return -1;
  325. }
  326. /* Find advertised path support */
  327. for (i = 0; i < supported_hdr->count; i++) {
  328. if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
  329. return 0;
  330. }
  331. }
  332. /* Path header present, but support not advertised */
  333. return -1;
  334. }
  335. static int rx_task(void *data)
  336. {
  337. static const pj_str_t USER_AGENT = { "User-Agent", 10 };
  338. RAII_VAR(struct rx_task_data *, task_data, data, ao2_cleanup);
  339. RAII_VAR(struct ao2_container *, contacts, NULL, ao2_cleanup);
  340. int added = 0, updated = 0, deleted = 0;
  341. pjsip_contact_hdr *contact_hdr = NULL;
  342. struct registrar_contact_details details = { 0, };
  343. pjsip_tx_data *tdata;
  344. pjsip_response_addr addr;
  345. const char *aor_name = ast_sorcery_object_get_id(task_data->aor);
  346. RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
  347. struct ast_sip_contact *response_contact;
  348. char *user_agent = NULL;
  349. pjsip_user_agent_hdr *user_agent_hdr;
  350. /* Retrieve the current contacts, we'll need to know whether to update or not */
  351. contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor);
  352. /* So we don't count static contacts against max_contacts we prune them out from the container */
  353. ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
  354. if (registrar_validate_contacts(task_data->rdata, contacts, task_data->aor, &added, &updated, &deleted)) {
  355. /* The provided Contact headers do not conform to the specification */
  356. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 400, NULL, NULL, NULL);
  357. ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_invalid_contacts_provided");
  358. ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
  359. ast_sorcery_object_get_id(task_data->endpoint));
  360. return PJ_TRUE;
  361. }
  362. if (registrar_validate_path(task_data, &path_str)) {
  363. /* Ensure that intervening proxies did not make invalid modifications to the request */
  364. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 420, NULL, NULL, NULL);
  365. ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
  366. ast_sorcery_object_get_id(task_data->endpoint));
  367. return PJ_TRUE;
  368. }
  369. if ((MAX(added - deleted, 0) + (!task_data->aor->remove_existing ? ao2_container_count(contacts) : 0)) > task_data->aor->max_contacts) {
  370. /* Enforce the maximum number of contacts */
  371. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 403, NULL, NULL, NULL);
  372. ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
  373. ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
  374. ast_sorcery_object_get_id(task_data->endpoint), ast_sorcery_object_get_id(task_data->aor), task_data->aor->max_contacts);
  375. return PJ_TRUE;
  376. }
  377. if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
  378. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 500, NULL, NULL, NULL);
  379. return PJ_TRUE;
  380. }
  381. user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL);
  382. if (user_agent_hdr) {
  383. size_t alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
  384. user_agent = ast_alloca(alloc_size);
  385. ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
  386. }
  387. /* Iterate each provided Contact header and add, update, or delete */
  388. while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
  389. int expiration;
  390. char contact_uri[PJSIP_MAX_URL_SIZE];
  391. RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
  392. if (contact_hdr->star) {
  393. /* A star means to unregister everything, so do so for the possible contacts */
  394. ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, (void *)aor_name);
  395. break;
  396. }
  397. if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
  398. /* This registrar only currently supports sip: and sips: URI schemes */
  399. continue;
  400. }
  401. expiration = registrar_get_expiration(task_data->aor, contact_hdr, task_data->rdata);
  402. details.uri = pjsip_uri_get_uri(contact_hdr->uri);
  403. pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
  404. if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
  405. /* If they are actually trying to delete a contact that does not exist... be forgiving */
  406. if (!expiration) {
  407. ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
  408. contact_uri, aor_name);
  409. continue;
  410. }
  411. if (ast_sip_location_add_contact(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(),
  412. ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL,
  413. user_agent)) {
  414. ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
  415. contact_uri, aor_name);
  416. continue;
  417. }
  418. ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
  419. contact_uri, aor_name, expiration);
  420. ast_test_suite_event_notify("AOR_CONTACT_ADDED",
  421. "Contact: %s\r\n"
  422. "AOR: %s\r\n"
  423. "Expiration: %d\r\n"
  424. "UserAgent: %s",
  425. contact_uri,
  426. aor_name,
  427. expiration,
  428. user_agent);
  429. } else if (expiration) {
  430. struct ast_sip_contact *contact_update;
  431. contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
  432. if (!contact_update) {
  433. ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
  434. contact->uri, expiration);
  435. continue;
  436. }
  437. contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
  438. contact_update->qualify_frequency = task_data->aor->qualify_frequency;
  439. contact_update->authenticate_qualify = task_data->aor->authenticate_qualify;
  440. if (path_str) {
  441. ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
  442. }
  443. if (user_agent) {
  444. ast_string_field_set(contact_update, user_agent, user_agent);
  445. }
  446. if (ast_sip_location_update_contact(contact_update)) {
  447. ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
  448. contact->uri, expiration);
  449. ast_sorcery_delete(ast_sip_get_sorcery(), contact);
  450. continue;
  451. }
  452. ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
  453. contact_uri, aor_name, expiration);
  454. ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
  455. "Contact: %s\r\n"
  456. "AOR: %s\r\n"
  457. "Expiration: %d\r\n"
  458. "UserAgent: %s",
  459. contact_uri,
  460. aor_name,
  461. expiration,
  462. contact_update->user_agent);
  463. ao2_cleanup(contact_update);
  464. } else {
  465. /* We want to report the user agent that was actually in the removed contact */
  466. user_agent = ast_strdupa(contact->user_agent);
  467. ast_sip_location_delete_contact(contact);
  468. ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
  469. ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
  470. "Contact: %s\r\n"
  471. "AOR: %s\r\n"
  472. "UserAgent: %s",
  473. contact_uri,
  474. aor_name,
  475. user_agent);
  476. }
  477. }
  478. pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
  479. /* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
  480. * do so
  481. */
  482. if (task_data->aor->remove_existing) {
  483. ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
  484. }
  485. /* Update the contacts as things will probably have changed */
  486. ao2_cleanup(contacts);
  487. contacts = ast_sip_location_retrieve_aor_contacts(task_data->aor);
  488. response_contact = ao2_callback(contacts, 0, NULL, NULL);
  489. /* Send a response containing all of the contacts (including static) that are present on this AOR */
  490. if (ast_sip_create_response(task_data->rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
  491. ao2_cleanup(response_contact);
  492. return PJ_TRUE;
  493. }
  494. ao2_cleanup(response_contact);
  495. /* Add the date header to the response, some UAs use this to set their date and time */
  496. registrar_add_date_header(tdata);
  497. ao2_callback(contacts, 0, registrar_add_contact, tdata);
  498. if (pjsip_get_response_addr(tdata->pool, task_data->rdata, &addr) == PJ_SUCCESS) {
  499. ast_sip_send_response(&addr, tdata, task_data->endpoint);
  500. } else {
  501. pjsip_tx_data_dec_ref(tdata);
  502. }
  503. return PJ_TRUE;
  504. }
  505. static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
  506. {
  507. RAII_VAR(struct serializer *, ser, NULL, ao2_cleanup);
  508. struct rx_task_data *task_data;
  509. RAII_VAR(struct ast_sip_endpoint *, endpoint,
  510. ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
  511. RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
  512. pjsip_sip_uri *uri;
  513. char *domain_name;
  514. char *configured_aors, *aor_name;
  515. RAII_VAR(struct ast_str *, id, NULL, ast_free);
  516. if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
  517. return PJ_FALSE;
  518. }
  519. if (ast_strlen_zero(endpoint->aors)) {
  520. /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
  521. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  522. ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
  523. ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
  524. return PJ_TRUE;
  525. }
  526. if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
  527. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
  528. ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
  529. ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
  530. return PJ_TRUE;
  531. }
  532. uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
  533. domain_name = ast_alloca(uri->host.slen + 1);
  534. ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
  535. configured_aors = ast_strdupa(endpoint->aors);
  536. /* Iterate the configured AORs to see if the user or the user+domain match */
  537. while ((aor_name = strsep(&configured_aors, ","))) {
  538. struct ast_sip_domain_alias *alias = NULL;
  539. if (!pj_strcmp2(&uri->user, aor_name)) {
  540. break;
  541. }
  542. if (!id && !(id = ast_str_create(uri->user.slen + uri->host.slen + 2))) {
  543. return PJ_TRUE;
  544. }
  545. ast_str_set(&id, 0, "%.*s@", (int)uri->user.slen, uri->user.ptr);
  546. if ((alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain_name))) {
  547. ast_str_append(&id, 0, "%s", alias->domain);
  548. ao2_cleanup(alias);
  549. } else {
  550. ast_str_append(&id, 0, "%s", domain_name);
  551. }
  552. if (!strcmp(aor_name, ast_str_buffer(id))) {
  553. ast_free(id);
  554. break;
  555. }
  556. }
  557. if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
  558. /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
  559. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
  560. ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
  561. ast_log(LOG_WARNING, "AOR '%.*s' not found for endpoint '%s'\n", (int)uri->user.slen, uri->user.ptr, ast_sorcery_object_get_id(endpoint));
  562. return PJ_TRUE;
  563. }
  564. if (!aor->max_contacts) {
  565. /* Registration is not permitted for this AOR */
  566. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  567. ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
  568. ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
  569. ast_sorcery_object_get_id(aor), ast_sorcery_object_get_id(endpoint));
  570. return PJ_TRUE;
  571. }
  572. if (!(ser = serializer_find_or_create(aor_name))) {
  573. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  574. ast_sip_report_mem_limit(endpoint, rdata);
  575. ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not get serializer\n",
  576. ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
  577. return PJ_TRUE;
  578. }
  579. if (!(task_data = rx_task_data_create(rdata, endpoint, aor))) {
  580. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  581. ast_sip_report_mem_limit(endpoint, rdata);
  582. ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not create rx_task_data\n",
  583. ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
  584. return PJ_TRUE;
  585. }
  586. if (ast_sip_push_task(ser->serializer, rx_task, task_data)) {
  587. pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
  588. ast_sip_report_mem_limit(endpoint, rdata);
  589. ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not serialize task\n",
  590. ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
  591. ao2_ref(task_data, -1);
  592. }
  593. return PJ_TRUE;
  594. }
  595. /* function pointer to callback needs to be within the module
  596. in order to avoid problems with an undefined symbol */
  597. static int sip_contact_to_str(void *acp, void *arg, int flags)
  598. {
  599. return ast_sip_contact_to_str(acp, arg, flags);
  600. }
  601. static int ami_registrations_aor(void *obj, void *arg, int flags)
  602. {
  603. struct ast_sip_aor *aor = obj;
  604. struct ast_sip_ami *ami = arg;
  605. int *count = ami->arg;
  606. RAII_VAR(struct ast_str *, buf,
  607. ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
  608. if (!buf) {
  609. return -1;
  610. }
  611. ast_sip_sorcery_object_to_ami(aor, &buf);
  612. ast_str_append(&buf, 0, "Contacts: ");
  613. ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
  614. ast_str_append(&buf, 0, "\r\n");
  615. astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
  616. (*count)++;
  617. return 0;
  618. }
  619. static int ami_registrations_endpoint(void *obj, void *arg, int flags)
  620. {
  621. struct ast_sip_endpoint *endpoint = obj;
  622. return ast_sip_for_each_aor(
  623. endpoint->aors, ami_registrations_aor, arg);
  624. }
  625. static int ami_registrations_endpoints(void *arg)
  626. {
  627. RAII_VAR(struct ao2_container *, endpoints,
  628. ast_sip_get_endpoints(), ao2_cleanup);
  629. if (!endpoints) {
  630. return 0;
  631. }
  632. ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
  633. return 0;
  634. }
  635. static int ami_show_registrations(struct mansession *s, const struct message *m)
  636. {
  637. int count = 0;
  638. struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
  639. astman_send_listack(s, m, "Following are Events for each Inbound "
  640. "registration", "start");
  641. ami_registrations_endpoints(&ami);
  642. astman_append(s, "Event: InboundRegistrationDetailComplete\r\n");
  643. if (!ast_strlen_zero(ami.action_id)) {
  644. astman_append(s, "ActionID: %s\r\n", ami.action_id);
  645. }
  646. astman_append(s, "EventList: Complete\r\n"
  647. "ListItems: %d\r\n\r\n", count);
  648. return 0;
  649. }
  650. #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
  651. static pjsip_module registrar_module = {
  652. .name = { "Registrar", 9 },
  653. .id = -1,
  654. .priority = PJSIP_MOD_PRIORITY_APPLICATION,
  655. .on_rx_request = registrar_on_rx_request,
  656. };
  657. static int load_module(void)
  658. {
  659. const pj_str_t STR_REGISTER = { "REGISTER", 8 };
  660. CHECK_PJSIP_MODULE_LOADED();
  661. if (!(serializers = ao2_container_alloc(
  662. SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) {
  663. return AST_MODULE_LOAD_DECLINE;
  664. }
  665. if (ast_sip_register_service(&registrar_module)) {
  666. return AST_MODULE_LOAD_DECLINE;
  667. }
  668. if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
  669. ast_sip_unregister_service(&registrar_module);
  670. return AST_MODULE_LOAD_DECLINE;
  671. }
  672. ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
  673. ami_show_registrations);
  674. return AST_MODULE_LOAD_SUCCESS;
  675. }
  676. static int unload_module(void)
  677. {
  678. ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
  679. ast_sip_unregister_service(&registrar_module);
  680. ao2_cleanup(serializers);
  681. return 0;
  682. }
  683. AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
  684. .support_level = AST_MODULE_SUPPORT_CORE,
  685. .load = load_module,
  686. .unload = unload_module,
  687. .load_pri = AST_MODPRI_APP_DEPEND,
  688. );