res_pjsip: add "via_addr", "via_port", "call_id" to contact
[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         pjsip_via_hdr *via_hdr;
451         pjsip_via_hdr *via_hdr_last;
452         char *via_addr = NULL;
453         int via_port = 0;
454         pjsip_cid_hdr *call_id_hdr;
455         char *call_id = NULL;
456         size_t alloc_size;
457
458         /* So we don't count static contacts against max_contacts we prune them out from the container */
459         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
460
461         if (registrar_validate_contacts(task_data->rdata, contacts, task_data->aor, &added, &updated, &deleted)) {
462                 /* The provided Contact headers do not conform to the specification */
463                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 400, NULL, NULL, NULL);
464                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_invalid_contacts_provided");
465                 ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
466                                 ast_sorcery_object_get_id(task_data->endpoint));
467                 return PJ_TRUE;
468         }
469
470         if (registrar_validate_path(task_data, &path_str)) {
471                 /* Ensure that intervening proxies did not make invalid modifications to the request */
472                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 420, NULL, NULL, NULL);
473                 ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
474                                 ast_sorcery_object_get_id(task_data->endpoint));
475                 return PJ_TRUE;
476         }
477
478         if ((MAX(added - deleted, 0) + (!task_data->aor->remove_existing ? ao2_container_count(contacts) : 0)) > task_data->aor->max_contacts) {
479                 /* Enforce the maximum number of contacts */
480                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 403, NULL, NULL, NULL);
481                 ast_sip_report_failed_acl(task_data->endpoint, task_data->rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
482                 ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
483                                 ast_sorcery_object_get_id(task_data->endpoint), ast_sorcery_object_get_id(task_data->aor), task_data->aor->max_contacts);
484                 return PJ_TRUE;
485         }
486
487         if (!(details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256))) {
488                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), task_data->rdata, 500, NULL, NULL, NULL);
489                 return PJ_TRUE;
490         }
491
492         user_agent_hdr = pjsip_msg_find_hdr_by_name(task_data->rdata->msg_info.msg, &USER_AGENT, NULL);
493         if (user_agent_hdr) {
494                 alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
495                 user_agent = ast_alloca(alloc_size);
496                 ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
497         }
498
499         /* Find the first Via header */
500         via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_VIA, NULL);
501         if (via_hdr) {
502                 /* Find the last Via header */
503                 while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg,
504                                 PJSIP_H_VIA, via_hdr->next)) != NULL) {
505                         via_hdr_last = via_hdr;
506                 }
507                 alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1;
508                 via_addr = ast_alloca(alloc_size);
509                 ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size);
510                 via_port=via_hdr_last->sent_by.port;
511         }
512
513         call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL);
514         if (call_id_hdr) {
515                 alloc_size = pj_strlen(&call_id_hdr->id) + 1;
516                 call_id = ast_alloca(alloc_size);
517                 ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size);
518         }
519
520         /* Iterate each provided Contact header and add, update, or delete */
521         while ((contact_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
522                 int expiration;
523                 char contact_uri[pjsip_max_url_size];
524                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
525
526                 if (contact_hdr->star) {
527                         /* A star means to unregister everything, so do so for the possible contacts */
528                         ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, (void *)aor_name);
529                         break;
530                 }
531
532                 if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
533                         /* This registrar only currently supports sip: and sips: URI schemes */
534                         continue;
535                 }
536
537                 expiration = registrar_get_expiration(task_data->aor, contact_hdr, task_data->rdata);
538                 details.uri = pjsip_uri_get_uri(contact_hdr->uri);
539                 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
540
541                 if (!(contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details))) {
542                         /* If they are actually trying to delete a contact that does not exist... be forgiving */
543                         if (!expiration) {
544                                 ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
545                                         contact_uri, aor_name);
546                                 continue;
547                         }
548
549                         if (ast_sip_location_add_contact_nolock(task_data->aor, contact_uri, ast_tvadd(ast_tvnow(),
550                                 ast_samp2tv(expiration, 1)), path_str ? ast_str_buffer(path_str) : NULL,
551                                         user_agent, via_addr, via_port, call_id, task_data->endpoint)) {
552                                 ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
553                                                 contact_uri, aor_name);
554                                 continue;
555                         }
556
557                         ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
558                                 contact_uri, aor_name, expiration);
559                         ast_test_suite_event_notify("AOR_CONTACT_ADDED",
560                                         "Contact: %s\r\n"
561                                         "AOR: %s\r\n"
562                                         "Expiration: %d\r\n"
563                                         "UserAgent: %s",
564                                         contact_uri,
565                                         aor_name,
566                                         expiration,
567                                         user_agent);
568                 } else if (expiration) {
569                         struct ast_sip_contact *contact_update;
570
571                         contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
572                         if (!contact_update) {
573                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
574                                         contact->uri, expiration);
575                                 continue;
576                         }
577
578                         contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
579                         contact_update->qualify_frequency = task_data->aor->qualify_frequency;
580                         contact_update->authenticate_qualify = task_data->aor->authenticate_qualify;
581                         if (path_str) {
582                                 ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
583                         }
584                         if (user_agent) {
585                                 ast_string_field_set(contact_update, user_agent, user_agent);
586                         }
587                         if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
588                                 ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
589                         }
590
591                         if (ast_sip_location_update_contact(contact_update)) {
592                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
593                                         contact->uri, expiration);
594                                 ast_sip_location_delete_contact(contact);
595                                 continue;
596                         }
597                         ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
598                                 contact_uri, aor_name, expiration);
599                         ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
600                                         "Contact: %s\r\n"
601                                         "AOR: %s\r\n"
602                                         "Expiration: %d\r\n"
603                                         "UserAgent: %s",
604                                         contact_uri,
605                                         aor_name,
606                                         expiration,
607                                         contact_update->user_agent);
608                         ao2_cleanup(contact_update);
609                 } else {
610                         /* We want to report the user agent that was actually in the removed contact */
611                         ast_sip_location_delete_contact(contact);
612                         ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
613                         ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
614                                         "Contact: %s\r\n"
615                                         "AOR: %s\r\n"
616                                         "UserAgent: %s",
617                                         contact_uri,
618                                         aor_name,
619                                         contact->user_agent);
620                 }
621         }
622
623         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
624
625         /* If the AOR is configured to remove any existing contacts that have not been updated/added as a result of this REGISTER
626          * do so
627          */
628         if (task_data->aor->remove_existing) {
629                 ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, registrar_delete_contact, NULL);
630         }
631
632         /* Re-retrieve contacts.  Caller will clean up the original container. */
633         contacts = ast_sip_location_retrieve_aor_contacts_nolock(task_data->aor);
634         response_contact = ao2_callback(contacts, 0, NULL, NULL);
635
636         /* Send a response containing all of the contacts (including static) that are present on this AOR */
637         if (ast_sip_create_response(task_data->rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
638                 ao2_cleanup(response_contact);
639                 ao2_cleanup(contacts);
640                 return PJ_TRUE;
641         }
642         ao2_cleanup(response_contact);
643
644         /* Add the date header to the response, some UAs use this to set their date and time */
645         registrar_add_date_header(tdata);
646
647         ao2_callback(contacts, 0, registrar_add_contact, tdata);
648         ao2_cleanup(contacts);
649
650         if ((expires_hdr = pjsip_msg_find_hdr(task_data->rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
651                 expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(task_data->aor, NULL, task_data->rdata));
652                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
653         }
654
655         ast_sip_send_stateful_response(task_data->rdata, tdata, task_data->endpoint);
656
657         return PJ_TRUE;
658 }
659
660 static int rx_task(void *data)
661 {
662         int res;
663         struct rx_task_data *task_data = data;
664         struct ao2_container *contacts = NULL;
665         struct ast_named_lock *lock;
666         const char *aor_name = ast_sorcery_object_get_id(task_data->aor);
667
668         lock = ast_named_lock_get(AST_NAMED_LOCK_TYPE_RWLOCK, "aor", aor_name);
669         if (!lock) {
670                 ao2_cleanup(task_data);
671                 return PJ_TRUE;
672         }
673
674         ao2_wrlock(lock);
675         contacts = ast_sip_location_retrieve_aor_contacts_nolock(task_data->aor);
676         if (!contacts) {
677                 ao2_unlock(lock);
678                 ast_named_lock_put(lock);
679                 ao2_cleanup(task_data);
680                 return PJ_TRUE;
681         }
682
683         res = rx_task_core(task_data, contacts, aor_name);
684         ao2_cleanup(contacts);
685         ao2_unlock(lock);
686         ast_named_lock_put(lock);
687         ao2_cleanup(task_data);
688
689         return res;
690 }
691
692 static int match_aor(const char *aor_name, const char *id)
693 {
694         if (ast_strlen_zero(aor_name)) {
695                 return 0;
696         }
697
698         if (!strcmp(aor_name, id)) {
699                 ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
700                 return 1;
701         }
702
703         return 0;
704 }
705
706 static char *find_aor_name(const char *username, const char *domain, const char *aors)
707 {
708         char *configured_aors;
709         char *aor_name;
710         char *id_domain;
711         struct ast_sip_domain_alias *alias;
712
713         id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
714         sprintf(id_domain, "%s@%s", username, domain);
715
716         /* Look for exact match on username@domain */
717         configured_aors = ast_strdupa(aors);
718         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
719                 if (match_aor(aor_name, id_domain)) {
720                         return ast_strdup(aor_name);
721                 }
722         }
723
724         /* If there's a domain alias, look for exact match on username@domain_alias */
725         alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
726         if (alias) {
727                 char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
728
729                 sprintf(id_domain, "%s@%s", username, alias->domain);
730                 ao2_cleanup(alias);
731
732                 configured_aors = ast_strdupa(aors);
733                 while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
734                         if (match_aor(aor_name, id_domain_alias)) {
735                                 return ast_strdup(aor_name);
736                         }
737                 }
738         }
739
740         /* Look for exact match on username only */
741         configured_aors = ast_strdupa(aors);
742         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
743                 if (match_aor(aor_name, username)) {
744                         return ast_strdup(aor_name);
745                 }
746         }
747
748         return NULL;
749 }
750
751 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
752 {
753         RAII_VAR(struct serializer *, ser, NULL, ao2_cleanup);
754         struct rx_task_data *task_data;
755
756         RAII_VAR(struct ast_sip_endpoint *, endpoint,
757                  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
758         RAII_VAR(struct ast_sip_aor *, aor, NULL, ao2_cleanup);
759         char *domain_name = NULL;
760         char *username = NULL;
761         RAII_VAR(char *, aor_name, NULL, ast_free);
762         int i;
763
764         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
765                 return PJ_FALSE;
766         }
767
768         if (ast_strlen_zero(endpoint->aors)) {
769                 /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
770                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
771                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
772                 ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
773                 return PJ_TRUE;
774         }
775
776         if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
777                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
778                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
779                 ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
780                 return PJ_TRUE;
781         }
782
783         for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); i++) {
784                 pjsip_sip_uri *uri;
785                 pjsip_authorization_hdr *header = NULL;
786
787                 switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
788                 case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME :
789                         uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
790
791                         domain_name = ast_alloca(uri->host.slen + 1);
792                         ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
793                         username = ast_alloca(uri->user.slen + 1);
794                         ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
795
796                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
797                         if (aor_name) {
798                                 ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
799                         }
800                         break;
801                 case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME :
802                         while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
803                                 header ? header->next : NULL))) {
804                                 if (header && !pj_stricmp2(&header->scheme, "digest")) {
805                                         username = ast_alloca(header->credential.digest.username.slen + 1);
806                                         ast_copy_pj_str(username, &header->credential.digest.username, header->credential.digest.username.slen + 1);
807                                         domain_name = ast_alloca(header->credential.digest.realm.slen + 1);
808                                         ast_copy_pj_str(domain_name, &header->credential.digest.realm, header->credential.digest.realm.slen + 1);
809
810                                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
811                                         if (aor_name) {
812                                                 ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
813                                                 break;
814                                         }
815                                 }
816                         }
817                         break;
818                 default:
819                         continue;
820                 }
821
822                 if (aor_name) {
823                         break;
824                 }
825         }
826
827         if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
828                 /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
829                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
830                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
831                 ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s'\n", username, ast_sorcery_object_get_id(endpoint));
832                 return PJ_TRUE;
833         }
834
835         if (!aor->max_contacts) {
836                 /* Registration is not permitted for this AOR */
837                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
838                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
839                 ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
840                                 ast_sorcery_object_get_id(aor), ast_sorcery_object_get_id(endpoint));
841                 return PJ_TRUE;
842         }
843
844         if (!(ser = serializer_find_or_create(aor_name))) {
845                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
846                 ast_sip_report_mem_limit(endpoint, rdata);
847                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not get serializer\n",
848                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
849                 return PJ_TRUE;
850         }
851
852         if (!(task_data = rx_task_data_create(rdata, endpoint, aor))) {
853                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
854                 ast_sip_report_mem_limit(endpoint, rdata);
855                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not create rx_task_data\n",
856                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
857                 return PJ_TRUE;
858         }
859
860         if (ast_sip_push_task(ser->serializer, rx_task, task_data)) {
861                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
862                 ast_sip_report_mem_limit(endpoint, rdata);
863                 ast_log(LOG_WARNING, "Endpoint '%s' unable to register on AOR '%s' - could not serialize task\n",
864                         ast_sorcery_object_get_id(endpoint), ast_sorcery_object_get_id(aor));
865                 ao2_ref(task_data, -1);
866         }
867         return PJ_TRUE;
868 }
869
870 /* function pointer to callback needs to be within the module
871    in order to avoid problems with an undefined symbol */
872 static int sip_contact_to_str(void *acp, void *arg, int flags)
873 {
874         return ast_sip_contact_to_str(acp, arg, flags);
875 }
876
877 static int ami_registrations_aor(void *obj, void *arg, int flags)
878 {
879         struct ast_sip_aor *aor = obj;
880         struct ast_sip_ami *ami = arg;
881         int *count = ami->arg;
882         RAII_VAR(struct ast_str *, buf,
883                  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
884
885         if (!buf) {
886                 return -1;
887         }
888
889         ast_sip_sorcery_object_to_ami(aor, &buf);
890         ast_str_append(&buf, 0, "Contacts: ");
891         ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
892         ast_str_append(&buf, 0, "\r\n");
893
894         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
895         (*count)++;
896         return 0;
897 }
898
899 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
900 {
901         struct ast_sip_endpoint *endpoint = obj;
902         return ast_sip_for_each_aor(
903                 endpoint->aors, ami_registrations_aor, arg);
904 }
905
906 static int ami_registrations_endpoints(void *arg)
907 {
908         RAII_VAR(struct ao2_container *, endpoints,
909                  ast_sip_get_endpoints(), ao2_cleanup);
910
911         if (!endpoints) {
912                 return 0;
913         }
914
915         ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
916         return 0;
917 }
918
919 static int ami_show_registrations(struct mansession *s, const struct message *m)
920 {
921         int count = 0;
922         struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
923
924         astman_send_listack(s, m, "Following are Events for each Inbound registration",
925                 "start");
926
927         ami_registrations_endpoints(&ami);
928
929         astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
930         astman_send_list_complete_end(s);
931         return 0;
932 }
933
934 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
935
936 static pjsip_module registrar_module = {
937         .name = { "Registrar", 9 },
938         .id = -1,
939         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
940         .on_rx_request = registrar_on_rx_request,
941 };
942
943 static int load_module(void)
944 {
945         const pj_str_t STR_REGISTER = { "REGISTER", 8 };
946
947         CHECK_PJPROJECT_MODULE_LOADED();
948
949         ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
950         /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
951         ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
952
953         CHECK_PJSIP_MODULE_LOADED();
954
955         if (!(serializers = ao2_container_alloc(
956                       SERIALIZER_BUCKETS, serializer_hash, serializer_cmp))) {
957                 return AST_MODULE_LOAD_DECLINE;
958         }
959
960         if (ast_sip_register_service(&registrar_module)) {
961                 return AST_MODULE_LOAD_DECLINE;
962         }
963
964         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
965                 ast_sip_unregister_service(&registrar_module);
966                 return AST_MODULE_LOAD_DECLINE;
967         }
968
969         ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
970                                  ami_show_registrations);
971
972         return AST_MODULE_LOAD_SUCCESS;
973 }
974
975 static int unload_module(void)
976 {
977         ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
978         ast_sip_unregister_service(&registrar_module);
979
980         ao2_cleanup(serializers);
981         return 0;
982 }
983
984 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
985         .support_level = AST_MODULE_SUPPORT_CORE,
986         .load = load_module,
987         .unload = unload_module,
988         .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
989 );