res_pjsip: module load priority
[asterisk/asterisk.git] / res / res_pjsip_registrar.c
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
19 /*** MODULEINFO
20         <depend>pjproject</depend>
21         <depend>res_pjproject</depend>
22         <depend>res_pjsip</depend>
23         <support_level>core</support_level>
24  ***/
25
26 #include "asterisk.h"
27
28 #include <pjsip.h>
29 #include <pjsip_ua.h>
30
31 #include "asterisk/res_pjsip.h"
32 #include "asterisk/module.h"
33 #include "asterisk/paths.h"
34 #include "asterisk/test.h"
35 #include "asterisk/taskprocessor.h"
36 #include "asterisk/manager.h"
37 #include "asterisk/named_locks.h"
38 #include "asterisk/res_pjproject.h"
39 #include "res_pjsip/include/res_pjsip_private.h"
40
41 /*** DOCUMENTATION
42         <manager name="PJSIPShowRegistrationsInbound" language="en_US">
43                 <synopsis>
44                         Lists PJSIP inbound registrations.
45                 </synopsis>
46                 <syntax />
47                 <description>
48                         <para>
49                         In response <literal>InboundRegistrationDetail</literal> events showing configuration and status
50                         information are raised for each inbound registration object.  As well as <literal>AuthDetail</literal>
51                         events for each associated auth object.  Once all events are completed an
52                         <literal>InboundRegistrationDetailComplete</literal> is issued.
53                         </para>
54                 </description>
55         </manager>
56  ***/
57
58 static int pj_max_hostname = PJ_MAX_HOSTNAME;
59 static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
60
61 /*! \brief Internal function which returns the expiration time for a contact */
62 static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
63 {
64         pjsip_expires_hdr *expires;
65         int expiration = aor->default_expiration;
66
67         if (contact && contact->expires != -1) {
68                 /* Expiration was provided with the contact itself */
69                 expiration = contact->expires;
70         } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
71                 /* Expiration was provided using the Expires header */
72                 expiration = expires->ivalue;
73         }
74
75         /* If the value has explicitly been set to 0, do not enforce */
76         if (!expiration) {
77                 return expiration;
78         }
79
80         /* Enforce the range that we will allow for expiration */
81         if (expiration < aor->minimum_expiration) {
82                 expiration = aor->minimum_expiration;
83         } else if (expiration > aor->maximum_expiration) {
84                 expiration = aor->maximum_expiration;
85         }
86
87         return expiration;
88 }
89
90 /*! \brief Structure used for finding contact */
91 struct registrar_contact_details {
92         /*! \brief Pool used for parsing URI */
93         pj_pool_t *pool;
94         /*! \brief URI being looked for */
95         pjsip_sip_uri *uri;
96 };
97
98 /*! \brief Callback function for finding a contact */
99 static int registrar_find_contact(void *obj, void *arg, int flags)
100 {
101         struct ast_sip_contact *contact = obj;
102         const struct registrar_contact_details *details = arg;
103         pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
104
105         return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH | CMP_STOP : 0;
106 }
107
108 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
109 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)
110 {
111         pjsip_contact_hdr *previous = NULL, *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
112         struct registrar_contact_details details = {
113                 .pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
114         };
115
116         if (!details.pool) {
117                 return -1;
118         }
119
120         while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
121                 int expiration = registrar_get_expiration(aor, contact, rdata);
122                 RAII_VAR(struct ast_sip_contact *, existing, NULL, ao2_cleanup);
123                 char contact_uri[pjsip_max_url_size];
124
125                 if (contact->star) {
126                         /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
127                         if ((expiration != 0) || previous) {
128                                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
129                                 return -1;
130                         }
131                         continue;
132                 } else if (previous && previous->star) {
133                         /* If there is a previous contact and it is a '*' this is a deal breaker */
134                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
135                         return -1;
136                 }
137                 previous = contact;
138
139                 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
140                         continue;
141                 }
142
143                 details.uri = pjsip_uri_get_uri(contact->uri);
144
145                 /* pjsip_uri_print returns -1 if there's not enough room in the buffer */
146                 if (pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)) < 0) {
147                         /* If the total length of the uri is greater than pjproject can handle, go no further */
148                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
149                         return -1;
150                 }
151
152                 if (details.uri->host.slen >= pj_max_hostname) {
153                         /* If the length of the hostname is greater than pjproject can handle, go no further */
154                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
155                         return -1;
156                 }
157
158                 /* Determine if this is an add, update, or delete for policy enforcement purposes */
159                 if (!(existing = ao2_callback(contacts, 0, registrar_find_contact, &details))) {
160                         if (expiration) {
161                                 (*added)++;
162                         }
163                 } else if (expiration) {
164                         (*updated)++;
165                 } else {
166                         (*deleted)++;
167                 }
168         }
169
170         /* The provided contacts are acceptable, huzzah! */
171         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
172         return 0;
173 }
174
175 /*! \brief Callback function which prunes static contacts */
176 static int registrar_prune_static(void *obj, void *arg, int flags)
177 {
178         struct ast_sip_contact *contact = obj;
179
180         return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
181 }
182
183 /*! \brief Internal function used to delete a contact from an AOR */
184 static int registrar_delete_contact(void *obj, void *arg, int flags)
185 {
186         struct ast_sip_contact *contact = obj;
187         const char *aor_name = arg;
188
189         ast_sip_location_delete_contact(contact);
190         if (!ast_strlen_zero(aor_name)) {
191                 ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact->uri, aor_name);
192                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
193                                 "Contact: %s\r\n"
194                                 "AOR: %s\r\n"
195                                 "UserAgent: %s",
196                                 contact->uri,
197                                 aor_name,
198                                 contact->user_agent);
199         }
200
201         return 0;
202 }
203
204 /*! \brief Internal function which adds a contact to a response */
205 static int registrar_add_contact(void *obj, void *arg, int flags)
206 {
207         struct ast_sip_contact *contact = obj;
208         pjsip_tx_data *tdata = arg;
209         pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
210         pj_str_t uri;
211
212         pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
213         hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
214         hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
215
216         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
217
218         return 0;
219 }
220
221 /*! \brief Helper function which adds a Date header to a response */
222 static void registrar_add_date_header(pjsip_tx_data *tdata)
223 {
224         char date[256];
225         struct tm tm;
226         time_t t = time(NULL);
227
228         gmtime_r(&t, &tm);
229         strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
230
231         ast_sip_add_header(tdata, "Date", date);
232 }
233
234 #define SERIALIZER_BUCKETS 59
235
236 static struct ao2_container *serializers;
237
238 /*! \brief Serializer with associated aor key */
239 struct serializer {
240         /* Serializer to distribute tasks to */
241         struct ast_taskprocessor *serializer;
242         /* The name of the aor to associate with the serializer */
243         char aor_name[0];
244 };
245
246 static void serializer_destroy(void *obj)
247 {
248         struct serializer *ser = obj;
249
250         ast_taskprocessor_unreference(ser->serializer);
251 }
252
253 static struct serializer *serializer_create(const char *aor_name)
254 {
255         char tps_name[AST_TASKPROCESSOR_MAX_NAME + 1];
256         size_t size = strlen(aor_name) + 1;
257         struct serializer *ser = ao2_alloc(
258                 sizeof(*ser) + size, serializer_destroy);
259
260         if (!ser) {
261                 return NULL;
262         }
263
264         /* Create name with seq number appended. */
265         ast_taskprocessor_build_name(tps_name, sizeof(tps_name), "pjsip/aor/%s",
266                 aor_name);
267
268         if (!(ser->serializer = ast_sip_create_serializer(tps_name))) {
269                 ao2_ref(ser, -1);
270                 return NULL;
271         }
272
273         strcpy(ser->aor_name, aor_name);
274         return ser;
275 }
276
277 static struct serializer *serializer_find_or_create(const char *aor_name)
278 {
279         struct serializer *ser = ao2_find(serializers, aor_name, OBJ_SEARCH_KEY);
280
281         if (ser) {
282                 return ser;
283         }
284
285         if (!(ser = serializer_create(aor_name))) {
286                 return NULL;
287         }
288
289         ao2_link(serializers, ser);
290         return ser;
291 }
292
293 static int serializer_hash(const void *obj, const int flags)
294 {
295         const struct serializer *object;
296         const char *key;
297
298         switch (flags & OBJ_SEARCH_MASK) {
299         case OBJ_SEARCH_KEY:
300                 key = obj;
301                 return ast_str_hash(key);
302         case OBJ_SEARCH_OBJECT:
303                 object = obj;
304                 return ast_str_hash(object->aor_name);
305         default:
306                 /* Hash can only work on something with a full key. */
307                 ast_assert(0);
308                 return 0;
309         }
310 }
311
312 static int serializer_cmp(void *obj_left, void *obj_right, int flags)
313 {
314         const struct serializer *object_left = obj_left;
315         const struct serializer *object_right = obj_right;
316         const char *right_key = obj_right;
317         int cmp;
318
319         switch (flags & OBJ_SEARCH_MASK) {
320         case OBJ_SEARCH_OBJECT:
321                 right_key = object_right->aor_name;
322                 /* Fall through */
323         case OBJ_SEARCH_KEY:
324                 cmp = strcmp(object_left->aor_name, right_key);
325                 break;
326         case OBJ_SEARCH_PARTIAL_KEY:
327                 /*
328                  * We could also use a partial key struct containing a length
329                  * so strlen() does not get called for every comparison instead.
330                  */
331                 cmp = strncmp(object_left->aor_name, right_key, strlen(right_key));
332                 break;
333         default:
334                 cmp = 0;
335                 break;
336         }
337
338         return cmp ? 0 : CMP_MATCH;
339 }
340
341 struct rx_task_data {
342         pjsip_rx_data *rdata;
343         struct ast_sip_endpoint *endpoint;
344         struct ast_sip_aor *aor;
345 };
346
347 static void rx_task_data_destroy(void *obj)
348 {
349         struct rx_task_data *task_data = obj;
350
351         pjsip_rx_data_free_cloned(task_data->rdata);
352         ao2_cleanup(task_data->endpoint);
353         ao2_cleanup(task_data->aor);
354 }
355
356 static struct rx_task_data *rx_task_data_create(pjsip_rx_data *rdata,
357                                                 struct ast_sip_endpoint *endpoint,
358                                                 struct ast_sip_aor *aor)
359 {
360         struct rx_task_data *task_data = ao2_alloc(
361                 sizeof(*task_data), rx_task_data_destroy);
362
363         if (!task_data) {
364                 return NULL;
365         }
366
367         pjsip_rx_data_clone(rdata, 0, &task_data->rdata);
368
369         task_data->endpoint = endpoint;
370         ao2_ref(task_data->endpoint, +1);
371
372         task_data->aor = aor;
373         ao2_ref(task_data->aor, +1);
374
375         return task_data;
376 }
377
378 static const pj_str_t path_hdr_name = { "Path", 4 };
379
380 static int build_path_data(struct rx_task_data *task_data, struct ast_str **path_str)
381 {
382         pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &path_hdr_name, NULL);
383
384         if (!path_hdr) {
385                 return 0;
386         }
387
388         *path_str = ast_str_create(64);
389         if (!path_str) {
390                 return -1;
391         }
392
393         ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
394
395         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))) {
396                 ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
397         }
398
399         return 0;
400 }
401
402 static int registrar_validate_path(struct rx_task_data *task_data, struct ast_str **path_str)
403 {
404         const pj_str_t path_supported_name = { "path", 4 };
405         pjsip_supported_hdr *supported_hdr;
406         int i;
407
408         if (!task_data->aor->support_path) {
409                 return 0;
410         }
411
412         if (build_path_data(task_data, path_str)) {
413                 return -1;
414         }
415
416         if (!*path_str) {
417                 return 0;
418         }
419
420         supported_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
421         if (!supported_hdr) {
422                 return -1;
423         }
424
425         /* Find advertised path support */
426         for (i = 0; i < supported_hdr->count; i++) {
427                 if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
428                         return 0;
429                 }
430         }
431
432         /* Path header present, but support not advertised */
433         return -1;
434 }
435
436 static int rx_task_core(struct rx_task_data *task_data, struct ao2_container *contacts,
437         const char *aor_name)
438 {
439         static const pj_str_t USER_AGENT = { "User-Agent", 10 };
440
441         int added = 0, updated = 0, deleted = 0;
442         pjsip_contact_hdr *contact_hdr = NULL;
443         struct registrar_contact_details details = { 0, };
444         pjsip_tx_data *tdata;
445         RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
446         struct ast_sip_contact *response_contact;
447         char *user_agent = NULL;
448         pjsip_user_agent_hdr *user_agent_hdr;
449         pjsip_expires_hdr *expires_hdr;
450
451         /* So we don't count static contacts against max_contacts we prune them out from the container */
452         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
453
454         if (registrar_validate_contacts(task_data->rdata, contacts, task_data->aor, &added, &updated, &deleted)) {
455                 /* The provided Contact headers do not conform to the specification */
456                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 400, NULL, NULL, NULL);
457                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_invalid_contacts_provided");
458                 ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
459                                 ast_sorcery_object_get_id(task_data->endpoint));
460                 return PJ_TRUE;
461         }
462
463         if (registrar_validate_path(task_data, &path_str)) {
464                 /* Ensure that intervening proxies did not make invalid modifications to the request */
465                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 420, NULL, NULL, NULL);
466                 ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
467                                 ast_sorcery_object_get_id(task_data->endpoint));
468                 return PJ_TRUE;
469         }
470
471         if ((MAX(added - deleted, 0) + (!task_data->aor->remove_existing ? ao2_container_count(contacts) : 0)) > task_data->aor->max_contacts) {
472                 /* Enforce the maximum number of contacts */
473                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 403, NULL, NULL, NULL);
474                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
475                 ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
476                                 ast_sorcery_object_get_id(task_data->endpoint), ast_sorcery_object_get_id(task_data->aor), task_data->aor->max_contacts);
477                 return PJ_TRUE;
478         }
479
480         if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
481                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 500, NULL, NULL, NULL);
482                 return PJ_TRUE;
483         }
484
485         user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL);
486         if (user_agent_hdr) {
487                 size_t alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
488                 user_agent = ast_alloca(alloc_size);
489                 ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
490         }
491
492         /* Iterate each provided Contact header and add, update, or delete */
493         while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
494                 int expiration;
495                 char contact_uri[pjsip_max_url_size];
496                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
497
498                 if (contact_hdr->star) {
499                         /* A star means to unregister everything, so do so for the possible contacts */
500                         ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, (void *)aor_name);
501                         break;
502                 }
503
504                 if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
505                         /* This registrar only currently supports sip: and sips: URI schemes */
506                         continue;
507                 }
508
509                 expiration = registrar_get_expiration(task_data->aor, contact_hdr, task_data->rdata);
510                 details.uri = pjsip_uri_get_uri(contact_hdr->uri);
511                 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
512
513                 if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
514                         /* If they are actually trying to delete a contact that does not exist... be forgiving */
515                         if (!expiration) {
516                                 ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
517                                         contact_uri, aor_name);
518                                 continue;
519                         }
520
521                         if (ast_sip_location_add_contact_nolock(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(),
522                                 ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL,
523                                         user_agent, task_data->endpoint)) {
524                                 ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
525                                                 contact_uri, aor_name);
526                                 continue;
527                         }
528
529                         ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
530                                 contact_uri, aor_name, expiration);
531                         ast_test_suite_event_notify("AOR_CONTACT_ADDED",
532                                         "Contact: %s\r\n"
533                                         "AOR: %s\r\n"
534                                         "Expiration: %d\r\n"
535                                         "UserAgent: %s",
536                                         contact_uri,
537                                         aor_name,
538                                         expiration,
539                                         user_agent);
540                 } else if (expiration) {
541                         struct ast_sip_contact *contact_update;
542
543                         contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
544                         if (!contact_update) {
545                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
546                                         contact->uri, expiration);
547                                 continue;
548                         }
549
550                         contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
551                         contact_update->qualify_frequency = task_data->aor->qualify_frequency;
552                         contact_update->authenticate_qualify = task_data->aor->authenticate_qualify;
553                         if (path_str) {
554                                 ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
555                         }
556                         if (user_agent) {
557                                 ast_string_field_set(contact_update, user_agent, user_agent);
558                         }
559                         if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
560                                 ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
561                         }
562
563                         if (ast_sip_location_update_contact(contact_update)) {
564                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
565                                         contact->uri, expiration);
566                                 ast_sip_location_delete_contact(contact);
567                                 continue;
568                         }
569                         ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
570                                 contact_uri, aor_name, expiration);
571                         ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
572                                         "Contact: %s\r\n"
573                                         "AOR: %s\r\n"
574                                         "Expiration: %d\r\n"
575                                         "UserAgent: %s",
576                                         contact_uri,
577                                         aor_name,
578                                         expiration,
579                                         contact_update->user_agent);
580                         ao2_cleanup(contact_update);
581                 } else {
582                         /* We want to report the user agent that was actually in the removed contact */
583                         ast_sip_location_delete_contact(contact);
584                         ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
585                         ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
586                                         "Contact: %s\r\n"
587                                         "AOR: %s\r\n"
588                                         "UserAgent: %s",
589                                         contact_uri,
590                                         aor_name,
591                                         contact->user_agent);
592                 }
593         }
594
595         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
596
597         /* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
598          * do so
599          */
600         if (task_data->aor->remove_existing) {
601                 ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
602         }
603
604         /* Re-retrieve contacts.  Caller will clean up the original container. */
605         contacts = ast_sip_location_retrieve_aor_contacts_nolock(task_data->aor);
606         response_contact = ao2_callback(contacts, 0, NULL, NULL);
607
608         /* Send a response containing all of the contacts (including static) that are present on this AOR */
609         if (ast_sip_create_response(task_data->rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
610                 ao2_cleanup(response_contact);
611                 ao2_cleanup(contacts);
612                 return PJ_TRUE;
613         }
614         ao2_cleanup(response_contact);
615
616         /* Add the date header to the response, some UAs use this to set their date and time */
617         registrar_add_date_header(tdata);
618
619         ao2_callback(contacts, 0, registrar_add_contact, tdata);
620         ao2_cleanup(contacts);
621
622         if ((expires_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
623                 expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(task_data->aor, NULL, task_data->rdata));
624                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
625         }
626
627         ast_sip_send_stateful_response(task_data->rdata, tdata, task_data->endpoint);
628
629         return PJ_TRUE;
630 }
631
632 static int rx_task(void *data)
633 {
634         int res;
635         struct rx_task_data *task_data = data;
636         struct ao2_container *contacts = NULL;
637         struct ast_named_lock *lock;
638         const char *aor_name = ast_sorcery_object_get_id(task_data->aor);
639
640         lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", aor_name);
641         if (!lock) {
642                 ao2_cleanup(task_data);
643                 return PJ_TRUE;
644         }
645
646         ao2_wrlock(lock);
647         contacts = ast_sip_location_retrieve_aor_contacts_nolock(task_data->aor);
648         if (!contacts) {
649                 ao2_unlock(lock);
650                 ast_named_lock_put(lock);
651                 ao2_cleanup(task_data);
652                 return PJ_TRUE;
653         }
654
655         res = rx_task_core(task_data, contacts, aor_name);
656         ao2_cleanup(contacts);
657         ao2_unlock(lock);
658         ast_named_lock_put(lock);
659         ao2_cleanup(task_data);
660
661         return res;
662 }
663
664 static int match_aor(const char *aor_name, const char *id)
665 {
666         if (ast_strlen_zero(aor_name)) {
667                 return 0;
668         }
669
670         if (!strcmp(aor_name, id)) {
671                 ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
672                 return 1;
673         }
674
675         return 0;
676 }
677
678 static char *find_aor_name(const char *username, const char *domain, const char *aors)
679 {
680         char *configured_aors;
681         char *aor_name;
682         char *id_domain;
683         struct ast_sip_domain_alias *alias;
684
685         id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
686         sprintf(id_domain, "%s@%s", username, domain);
687
688         /* Look for exact match on username@domain */
689         configured_aors = ast_strdupa(aors);
690         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
691                 if (match_aor(aor_name, id_domain)) {
692                         return ast_strdup(aor_name);
693                 }
694         }
695
696         /* If there's a domain alias, look for exact match on username@domain_alias */
697         alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
698         if (alias) {
699                 char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
700
701                 sprintf(id_domain, "%s@%s", username, alias->domain);
702                 ao2_cleanup(alias);
703
704                 configured_aors = ast_strdupa(aors);
705                 while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
706                         if (match_aor(aor_name, id_domain_alias)) {
707                                 return ast_strdup(aor_name);
708                         }
709                 }
710         }
711
712         /* Look for exact match on username only */
713         configured_aors = ast_strdupa(aors);
714         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
715                 if (match_aor(aor_name, username)) {
716                         return ast_strdup(aor_name);
717                 }
718         }
719
720         return NULL;
721 }
722
723 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
724 {
725         RAII_VAR(struct serializer *, ser, NULL, ao2_cleanup);
726         struct rx_task_data *task_data;
727
728         RAII_VAR(struct ast_sip_endpoint *, endpoint,
729                  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
730         RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
731         char *domain_name = NULL;
732         char *username = NULL;
733         RAII_VAR(char *, aor_name, NULL, ast_free);
734         int i;
735
736         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
737                 return PJ_FALSE;
738         }
739
740         if (ast_strlen_zero(endpoint->aors)) {
741                 /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
742                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
743                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
744                 ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
745                 return PJ_TRUE;
746         }
747
748         if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
749                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
750                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
751                 ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
752                 return PJ_TRUE;
753         }
754
755         for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); i++) {
756                 pjsip_sip_uri *uri;
757                 pjsip_authorization_hdr *header = NULL;
758
759                 switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
760                 case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME :
761                         uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
762
763                         domain_name = ast_alloca(uri->host.slen + 1);
764                         ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
765                         username = ast_alloca(uri->user.slen + 1);
766                         ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
767
768                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
769                         if (aor_name) {
770                                 ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
771                         }
772                         break;
773                 case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME :
774                         while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
775                                 header ? header->next : NULL))) {
776                                 if (header && !pj_stricmp2(&header->scheme, "digest")) {
777                                         username = ast_alloca(header->credential.digest.username.slen + 1);
778                                         ast_copy_pj_str(username, &header->credential.digest.username, header->credential.digest.username.slen + 1);
779                                         domain_name = ast_alloca(header->credential.digest.realm.slen + 1);
780                                         ast_copy_pj_str(domain_name, &header->credential.digest.realm, header->credential.digest.realm.slen + 1);
781
782                                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
783                                         if (aor_name) {
784                                                 ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
785                                                 break;
786                                         }
787                                 }
788                         }
789                         break;
790                 default:
791                         continue;
792                 }
793
794                 if (aor_name) {
795                         break;
796                 }
797         }
798
799         if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
800                 /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
801                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
802                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
803                 ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s'\n", username, ast_sorcery_object_get_id(endpoint));
804                 return PJ_TRUE;
805         }
806
807         if (!aor->max_contacts) {
808                 /* Registration is not permitted for this AOR */
809                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
810                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
811                 ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
812                                 ast_sorcery_object_get_id(aor), ast_sorcery_object_get_id(endpoint));
813                 return PJ_TRUE;
814         }
815
816         if (!(ser = serializer_find_or_create(aor_name))) {
817                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
818                 ast_sip_report_mem_limit(endpoint, rdata);
819                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not get serializer\n",
820                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
821                 return PJ_TRUE;
822         }
823
824         if (!(task_data = rx_task_data_create(rdata, endpoint, aor))) {
825                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
826                 ast_sip_report_mem_limit(endpoint, rdata);
827                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not create rx_task_data\n",
828                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
829                 return PJ_TRUE;
830         }
831
832         if (ast_sip_push_task(ser->serializer, rx_task, task_data)) {
833                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
834                 ast_sip_report_mem_limit(endpoint, rdata);
835                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not serialize task\n",
836                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
837                 ao2_ref(task_data, -1);
838         }
839         return PJ_TRUE;
840 }
841
842 /* function pointer to callback needs to be within the module
843    in order to avoid problems with an undefined symbol */
844 static int sip_contact_to_str(void *acp, void *arg, int flags)
845 {
846         return ast_sip_contact_to_str(acp, arg, flags);
847 }
848
849 static int ami_registrations_aor(void *obj, void *arg, int flags)
850 {
851         struct ast_sip_aor *aor = obj;
852         struct ast_sip_ami *ami = arg;
853         int *count = ami->arg;
854         RAII_VAR(struct ast_str *, buf,
855                  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
856
857         if (!buf) {
858                 return -1;
859         }
860
861         ast_sip_sorcery_object_to_ami(aor, &buf);
862         ast_str_append(&buf, 0, "Contacts: ");
863         ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
864         ast_str_append(&buf, 0, "\r\n");
865
866         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
867         (*count)++;
868         return 0;
869 }
870
871 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
872 {
873         struct ast_sip_endpoint *endpoint = obj;
874         return ast_sip_for_each_aor(
875                 endpoint->aors, ami_registrations_aor, arg);
876 }
877
878 static int ami_registrations_endpoints(void *arg)
879 {
880         RAII_VAR(struct ao2_container *, endpoints,
881                  ast_sip_get_endpoints(), ao2_cleanup);
882
883         if (!endpoints) {
884                 return 0;
885         }
886
887         ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
888         return 0;
889 }
890
891 static int ami_show_registrations(struct mansession *s, const struct message *m)
892 {
893         int count = 0;
894         struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
895
896         astman_send_listack(s, m, "Following are Events for each Inbound registration",
897                 "start");
898
899         ami_registrations_endpoints(&ami);
900
901         astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
902         astman_send_list_complete_end(s);
903         return 0;
904 }
905
906 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
907
908 static pjsip_module registrar_module = {
909         .name = { "Registrar", 9 },
910         .id = -1,
911         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
912         .on_rx_request = registrar_on_rx_request,
913 };
914
915 static int load_module(void)
916 {
917         const pj_str_t STR_REGISTER = { "REGISTER", 8 };
918
919         CHECK_PJPROJECT_MODULE_LOADED();
920
921         ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
922         /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
923         ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
924
925         CHECK_PJSIP_MODULE_LOADED();
926
927         if (!(serializers = ao2_container_alloc(
928                       SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) {
929                 return AST_MODULE_LOAD_DECLINE;
930         }
931
932         if (ast_sip_register_service(&registrar_module)) {
933                 return AST_MODULE_LOAD_DECLINE;
934         }
935
936         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
937                 ast_sip_unregister_service(&registrar_module);
938                 return AST_MODULE_LOAD_DECLINE;
939         }
940
941         ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
942                                  ami_show_registrations);
943
944         return AST_MODULE_LOAD_SUCCESS;
945 }
946
947 static int unload_module(void)
948 {
949         ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
950         ast_sip_unregister_service(&registrar_module);
951
952         ao2_cleanup(serializers);
953         return 0;
954 }
955
956 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
957         .support_level = AST_MODULE_SUPPORT_CORE,
958         .load = load_module,
959         .unload = unload_module,
960         .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
961 );