loader: Add dependency fields to module structures.
[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
50                         and status information are raised for all contacts, static or dynamic.  Once all events
51                         are completed an <literal>InboundRegistrationDetailComplete</literal> is issued.
52                         </para>
53                         <warning><para>
54                                 This command just dumps all coonfigured AORs with contacts, even if the contact
55                                 is a permanent one.  To really get just inbound registrations, use
56                                 <literal>PJSIPShowRegistrationInboundContactStatuses</literal>.
57                         </para>
58                         </warning>
59                 </description>
60                 <see-also>
61                         <ref type="manager" module="res_pjsip_registrar">PJSIPShowRegistrationInboundContactStatuses</ref>
62                 </see-also>
63         </manager>
64         <manager name="PJSIPShowRegistrationInboundContactStatuses" language="en_US">
65                 <synopsis>
66                         Lists ContactStatuses for PJSIP inbound registrations.
67                 </synopsis>
68                 <syntax />
69                 <description>
70                         <para>
71                         In response, <literal>ContactStatusDetail</literal> events showing status information
72                         are raised for each inbound registration (dynamic contact) object.  Once all events
73                         are completed a <literal>ContactStatusDetailComplete</literal> event is issued.
74                         </para>
75                 </description>
76         </manager>
77  ***/
78
79 static int pj_max_hostname = PJ_MAX_HOSTNAME;
80 static int pjsip_max_url_size = PJSIP_MAX_URL_SIZE;
81
82 /*! \brief Internal function which returns the expiration time for a contact */
83 static int registrar_get_expiration(const struct ast_sip_aor *aor, const pjsip_contact_hdr *contact, const pjsip_rx_data *rdata)
84 {
85         pjsip_expires_hdr *expires;
86         int expiration = aor->default_expiration;
87
88         if (contact && contact->expires != -1) {
89                 /* Expiration was provided with the contact itself */
90                 expiration = contact->expires;
91         } else if ((expires = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
92                 /* Expiration was provided using the Expires header */
93                 expiration = expires->ivalue;
94         }
95
96         /* If the value has explicitly been set to 0, do not enforce */
97         if (!expiration) {
98                 return expiration;
99         }
100
101         /* Enforce the range that we will allow for expiration */
102         if (expiration < aor->minimum_expiration) {
103                 expiration = aor->minimum_expiration;
104         } else if (expiration > aor->maximum_expiration) {
105                 expiration = aor->maximum_expiration;
106         }
107
108         return expiration;
109 }
110
111 /*! \brief Structure used for finding contact */
112 struct registrar_contact_details {
113         /*! \brief Pool used for parsing URI */
114         pj_pool_t *pool;
115         /*! \brief URI being looked for */
116         pjsip_sip_uri *uri;
117 };
118
119 /*! \brief Callback function for finding a contact */
120 static int registrar_find_contact(void *obj, void *arg, int flags)
121 {
122         struct ast_sip_contact *contact = obj;
123         const struct registrar_contact_details *details = arg;
124         pjsip_uri *contact_uri = pjsip_parse_uri(details->pool, (char*)contact->uri, strlen(contact->uri), 0);
125
126         return (pjsip_uri_cmp(PJSIP_URI_IN_CONTACT_HDR, details->uri, contact_uri) == PJ_SUCCESS) ? CMP_MATCH : 0;
127 }
128
129 /*! \brief Internal function which validates provided Contact headers to confirm that they are acceptable, and returns number of contacts */
130 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)
131 {
132         pjsip_contact_hdr *previous = NULL;
133         pjsip_contact_hdr *contact = (pjsip_contact_hdr *)&rdata->msg_info.msg->hdr;
134         struct registrar_contact_details details = {
135                 .pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(), "Contact Comparison", 256, 256),
136         };
137
138         if (!details.pool) {
139                 return -1;
140         }
141
142         while ((contact = (pjsip_contact_hdr *) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact->next))) {
143                 int expiration = registrar_get_expiration(aor, contact, rdata);
144                 struct ast_sip_contact *existing;
145                 char contact_uri[pjsip_max_url_size];
146
147                 if (contact->star) {
148                         /* The expiration MUST be 0 when a '*' contact is used and there must be no other contact */
149                         if (expiration != 0 || previous) {
150                                 pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
151                                 return -1;
152                         }
153                         /* Count all contacts to delete */
154                         *deleted = ao2_container_count(contacts);
155                         previous = contact;
156                         continue;
157                 } else if (previous && previous->star) {
158                         /* If there is a previous contact and it is a '*' this is a deal breaker */
159                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
160                         return -1;
161                 }
162                 previous = contact;
163
164                 if (!PJSIP_URI_SCHEME_IS_SIP(contact->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact->uri)) {
165                         continue;
166                 }
167
168                 details.uri = pjsip_uri_get_uri(contact->uri);
169
170                 /* pjsip_uri_print returns -1 if there's not enough room in the buffer */
171                 if (pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri)) < 0) {
172                         /* If the total length of the uri is greater than pjproject can handle, go no further */
173                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
174                         return -1;
175                 }
176
177                 if (details.uri->host.slen >= pj_max_hostname) {
178                         /* If the length of the hostname is greater than pjproject can handle, go no further */
179                         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
180                         return -1;
181                 }
182
183                 /* Determine if this is an add, update, or delete for policy enforcement purposes */
184                 existing = ao2_callback(contacts, 0, registrar_find_contact, &details);
185                 ao2_cleanup(existing);
186                 if (!existing) {
187                         if (expiration) {
188                                 ++*added;
189                         }
190                 } else if (expiration) {
191                         ++*updated;
192                 } else {
193                         ++*deleted;
194                 }
195         }
196
197         /* The provided contacts are acceptable, huzzah! */
198         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
199         return 0;
200 }
201
202 /*! \brief Callback function which prunes static contacts */
203 static int registrar_prune_static(void *obj, void *arg, int flags)
204 {
205         struct ast_sip_contact *contact = obj;
206
207         return ast_tvzero(contact->expiration_time) ? CMP_MATCH : 0;
208 }
209
210 /*! \brief Internal function used to delete a contact from an AOR */
211 static int registrar_delete_contact(void *obj, void *arg, int flags)
212 {
213         struct ast_sip_contact *contact = obj;
214         const char *aor_name = arg;
215
216         ast_sip_location_delete_contact(contact);
217         if (!ast_strlen_zero(aor_name)) {
218                 ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact->uri, aor_name);
219                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
220                                 "Contact: %s\r\n"
221                                 "AOR: %s\r\n"
222                                 "UserAgent: %s",
223                                 contact->uri,
224                                 aor_name,
225                                 contact->user_agent);
226         }
227
228         return CMP_MATCH;
229 }
230
231 /*! \brief Internal function which adds a contact to a response */
232 static int registrar_add_contact(void *obj, void *arg, int flags)
233 {
234         struct ast_sip_contact *contact = obj;
235         pjsip_tx_data *tdata = arg;
236         pjsip_contact_hdr *hdr = pjsip_contact_hdr_create(tdata->pool);
237         pj_str_t uri;
238
239         pj_strdup2_with_null(tdata->pool, &uri, contact->uri);
240         hdr->uri = pjsip_parse_uri(tdata->pool, uri.ptr, uri.slen, PJSIP_PARSE_URI_AS_NAMEADDR);
241         hdr->expires = ast_tvdiff_ms(contact->expiration_time, ast_tvnow()) / 1000;
242
243         pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)hdr);
244
245         return 0;
246 }
247
248 /*! \brief Helper function which adds a Date header to a response */
249 static void registrar_add_date_header(pjsip_tx_data *tdata)
250 {
251         char date[256];
252         struct tm tm;
253         time_t t = time(NULL);
254
255         gmtime_r(&t, &tm);
256         strftime(date, sizeof(date), "%a, %d %b %Y %T GMT", &tm);
257
258         ast_sip_add_header(tdata, "Date", date);
259 }
260
261 static const pj_str_t path_hdr_name = { "Path", 4 };
262
263 static int build_path_data(pjsip_rx_data *rdata, struct ast_str **path_str)
264 {
265         pjsip_generic_string_hdr *path_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, NULL);
266
267         if (!path_hdr) {
268                 return 0;
269         }
270
271         *path_str = ast_str_create(64);
272         if (!path_str) {
273                 return -1;
274         }
275
276         ast_str_set(path_str, 0, "%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
277
278         while ((path_hdr = (pjsip_generic_string_hdr *) pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &path_hdr_name, path_hdr->next))) {
279                 ast_str_append(path_str, 0, ",%.*s", (int)path_hdr->hvalue.slen, path_hdr->hvalue.ptr);
280         }
281
282         return 0;
283 }
284
285 static int registrar_validate_path(pjsip_rx_data *rdata, struct ast_sip_aor *aor, struct ast_str **path_str)
286 {
287         const pj_str_t path_supported_name = { "path", 4 };
288         pjsip_supported_hdr *supported_hdr;
289         int i;
290
291         if (!aor->support_path) {
292                 return 0;
293         }
294
295         if (build_path_data(rdata, path_str)) {
296                 return -1;
297         }
298
299         if (!*path_str) {
300                 return 0;
301         }
302
303         supported_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_SUPPORTED, NULL);
304         if (!supported_hdr) {
305                 return -1;
306         }
307
308         /* Find advertised path support */
309         for (i = 0; i < supported_hdr->count; i++) {
310                 if (!pj_stricmp(&supported_hdr->values[i], &path_supported_name)) {
311                         return 0;
312                 }
313         }
314
315         /* Path header present, but support not advertised */
316         return -1;
317 }
318
319 /*! Transport monitor for incoming REGISTER contacts */
320 struct contact_transport_monitor {
321         /*!
322          * \brief Sorcery contact name to remove on transport shutdown
323          * \note Stored after aor_name in space reserved when struct allocated.
324          */
325         char *contact_name;
326         /*! AOR name the contact is associated */
327         char aor_name[0];
328 };
329
330 static void register_contact_transport_shutdown_cb(void *data)
331 {
332         struct contact_transport_monitor *monitor = data;
333         struct ast_sip_contact *contact;
334         struct ast_sip_aor *aor;
335
336         aor = ast_sip_location_retrieve_aor(monitor->aor_name);
337         if (!aor) {
338                 return;
339         }
340
341         ao2_lock(aor);
342         contact = ast_sip_location_retrieve_contact(monitor->contact_name);
343         if (contact) {
344                 ast_sip_location_delete_contact(contact);
345                 ast_verb(3, "Removed contact '%s' from AOR '%s' due to transport shutdown\n",
346                         contact->uri, monitor->aor_name);
347                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
348                         "Contact: %s\r\n"
349                         "AOR: %s\r\n"
350                         "UserAgent: %s",
351                         contact->uri,
352                         monitor->aor_name,
353                         contact->user_agent);
354                 ao2_ref(contact, -1);
355         }
356         ao2_unlock(aor);
357         ao2_ref(aor, -1);
358 }
359
360 AST_VECTOR(excess_contact_vector, struct ast_sip_contact *);
361
362 static int vec_contact_cmp(struct ast_sip_contact *left, struct ast_sip_contact *right)
363 {
364         struct ast_sip_contact *left_contact = left;
365         struct ast_sip_contact *right_contact = right;
366
367         /* Sort from soonest to expire to last to expire */
368         return ast_tvcmp(left_contact->expiration_time, right_contact->expiration_time);
369 }
370
371 static int vec_contact_add(void *obj, void *arg, int flags)
372 {
373         struct ast_sip_contact *contact = obj;
374         struct excess_contact_vector *contact_vec = arg;
375
376         /*
377          * Performance wise, an insertion sort is fine because we
378          * shouldn't need to remove more than a handful of contacts.
379          * I expect we'll typically be removing only one contact.
380          */
381         AST_VECTOR_ADD_SORTED(contact_vec, contact, vec_contact_cmp);
382         if (AST_VECTOR_SIZE(contact_vec) == AST_VECTOR_MAX_SIZE(contact_vec)) {
383                 /*
384                  * We added a contact over the number we need to remove.
385                  * Remove the longest to expire contact from the vector
386                  * which is the last element in the vector.  It may be
387                  * the one we just added or the one we just added pushed
388                  * out an earlier contact from removal consideration.
389                  */
390                 --AST_VECTOR_SIZE(contact_vec);
391         }
392         return 0;
393 }
394
395 /*!
396  * \internal
397  * \brief Remove excess existing contacts that expire the soonest.
398  * \since 13.18.0
399  *
400  * \param contacts Container of unmodified contacts that could remove.
401  * \param to_remove Maximum number of contacts to remove.
402  *
403  * \return Nothing
404  */
405 static void remove_excess_contacts(struct ao2_container *contacts, unsigned int to_remove)
406 {
407         struct excess_contact_vector contact_vec;
408
409         /*
410          * Create a sorted vector to hold the to_remove soonest to
411          * expire contacts.  The vector has an extra space to
412          * temporarily hold the longest to expire contact that we
413          * won't remove.
414          */
415         if (AST_VECTOR_INIT(&contact_vec, to_remove + 1)) {
416                 return;
417         }
418         ao2_callback(contacts, OBJ_NODATA | OBJ_MULTIPLE, vec_contact_add, &contact_vec);
419
420         /*
421          * The vector should always be populated with the number
422          * of contacts we need to remove.  Just in case, we will
423          * remove all contacts in the vector even if the contacts
424          * container had fewer contacts than there should be.
425          */
426         ast_assert(AST_VECTOR_SIZE(&contact_vec) == to_remove);
427         to_remove = AST_VECTOR_SIZE(&contact_vec);
428
429         /* Remove the excess contacts that expire the soonest */
430         while (to_remove--) {
431                 struct ast_sip_contact *contact;
432
433                 contact = AST_VECTOR_GET(&contact_vec, to_remove);
434
435                 ast_sip_location_delete_contact(contact);
436                 ast_verb(3, "Removed contact '%s' from AOR '%s' due to remove_existing\n",
437                         contact->uri, contact->aor);
438                 ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
439                         "Contact: %s\r\n"
440                         "AOR: %s\r\n"
441                         "UserAgent: %s",
442                         contact->uri,
443                         contact->aor,
444                         contact->user_agent);
445         }
446
447         AST_VECTOR_FREE(&contact_vec);
448 }
449
450 struct aor_core_response {
451         /*! Tx data to use for statefull response.  NULL for stateless response. */
452         pjsip_tx_data *tdata;
453         /*! SIP response code to send in stateless response */
454         int code;
455 };
456
457 static void register_aor_core(pjsip_rx_data *rdata,
458         struct ast_sip_endpoint *endpoint,
459         struct ast_sip_aor *aor,
460         const char *aor_name,
461         struct ao2_container *contacts,
462         struct aor_core_response *response)
463 {
464         static const pj_str_t USER_AGENT = { "User-Agent", 10 };
465
466         int added = 0;
467         int updated = 0;
468         int deleted = 0;
469         int contact_count;
470         pjsip_contact_hdr *contact_hdr = NULL;
471         struct registrar_contact_details details = { 0, };
472         pjsip_tx_data *tdata;
473         RAII_VAR(struct ast_str *, path_str, NULL, ast_free);
474         struct ast_sip_contact *response_contact;
475         char *user_agent = NULL;
476         pjsip_user_agent_hdr *user_agent_hdr;
477         pjsip_expires_hdr *expires_hdr;
478         pjsip_via_hdr *via_hdr;
479         pjsip_via_hdr *via_hdr_last;
480         char *via_addr = NULL;
481         int via_port = 0;
482         pjsip_cid_hdr *call_id_hdr;
483         char *call_id = NULL;
484         size_t alloc_size;
485
486         /* So we don't count static contacts against max_contacts we prune them out from the container */
487         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE, registrar_prune_static, NULL);
488
489         if (registrar_validate_contacts(rdata, contacts, aor, &added, &updated, &deleted)) {
490                 /* The provided Contact headers do not conform to the specification */
491                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_contacts_provided");
492                 ast_log(LOG_WARNING, "Failed to validate contacts in REGISTER request from '%s'\n",
493                                 ast_sorcery_object_get_id(endpoint));
494                 response->code = 400;
495                 return;
496         }
497
498         if (registrar_validate_path(rdata, aor, &path_str)) {
499                 /* Ensure that intervening proxies did not make invalid modifications to the request */
500                 ast_log(LOG_WARNING, "Invalid modifications made to REGISTER request from '%s' by intervening proxy\n",
501                                 ast_sorcery_object_get_id(endpoint));
502                 response->code = 420;
503                 return;
504         }
505
506         if (aor->remove_existing) {
507                 /* Cumulative number of contacts affected by this registration */
508                 contact_count = MAX(updated + added - deleted,  0);
509         } else {
510                 /* Total contacts after this registration */
511                 contact_count = ao2_container_count(contacts) + added - deleted;
512         }
513         if (contact_count > aor->max_contacts) {
514                 /* Enforce the maximum number of contacts */
515                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_exceeds_maximum_configured_contacts");
516                 ast_log(LOG_WARNING, "Registration attempt from endpoint '%s' to AOR '%s' will exceed max contacts of %u\n",
517                                 ast_sorcery_object_get_id(endpoint), aor_name, aor->max_contacts);
518                 response->code = 403;
519                 return;
520         }
521
522         details.pool = pjsip_endpt_create_pool(ast_sip_get_pjsip_endpoint(),
523                 "Contact Comparison", 256, 256);
524         if (!details.pool) {
525                 response->code = 500;
526                 return;
527         }
528
529         user_agent_hdr = pjsip_msg_find_hdr_by_name(rdata->msg_info.msg, &USER_AGENT, NULL);
530         if (user_agent_hdr) {
531                 alloc_size = pj_strlen(&user_agent_hdr->hvalue) + 1;
532                 user_agent = ast_alloca(alloc_size);
533                 ast_copy_pj_str(user_agent, &user_agent_hdr->hvalue, alloc_size);
534         }
535
536         /* Find the first Via header */
537         via_hdr = via_hdr_last = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_VIA, NULL);
538         if (via_hdr) {
539                 /* Find the last Via header */
540                 while ( (via_hdr = (pjsip_via_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg,
541                                 PJSIP_H_VIA, via_hdr->next)) != NULL) {
542                         via_hdr_last = via_hdr;
543                 }
544                 alloc_size = pj_strlen(&via_hdr_last->sent_by.host) + 1;
545                 via_addr = ast_alloca(alloc_size);
546                 ast_copy_pj_str(via_addr, &via_hdr_last->sent_by.host, alloc_size);
547                 via_port=via_hdr_last->sent_by.port;
548         }
549
550         call_id_hdr = (pjsip_cid_hdr*) pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CALL_ID, NULL);
551         if (call_id_hdr) {
552                 alloc_size = pj_strlen(&call_id_hdr->id) + 1;
553                 call_id = ast_alloca(alloc_size);
554                 ast_copy_pj_str(call_id, &call_id_hdr->id, alloc_size);
555         }
556
557         /* Iterate each provided Contact header and add, update, or delete */
558         while ((contact_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_CONTACT, contact_hdr ? contact_hdr->next : NULL))) {
559                 int expiration;
560                 char contact_uri[pjsip_max_url_size];
561                 RAII_VAR(struct ast_sip_contact *, contact, NULL, ao2_cleanup);
562
563                 if (contact_hdr->star) {
564                         /* A star means to unregister everything, so do so for the possible contacts */
565                         ao2_callback(contacts, OBJ_NODATA | OBJ_UNLINK | OBJ_MULTIPLE,
566                                 registrar_delete_contact, (void *)aor_name);
567                         break;
568                 }
569
570                 if (!PJSIP_URI_SCHEME_IS_SIP(contact_hdr->uri) && !PJSIP_URI_SCHEME_IS_SIPS(contact_hdr->uri)) {
571                         /* This registrar only currently supports sip: and sips: URI schemes */
572                         continue;
573                 }
574
575                 expiration = registrar_get_expiration(aor, contact_hdr, rdata);
576                 details.uri = pjsip_uri_get_uri(contact_hdr->uri);
577                 pjsip_uri_print(PJSIP_URI_IN_CONTACT_HDR, details.uri, contact_uri, sizeof(contact_uri));
578
579                 contact = ao2_callback(contacts, OBJ_UNLINK, registrar_find_contact, &details);
580                 if (!contact) {
581                         int prune_on_boot = 0;
582                         pj_str_t host_name;
583
584                         /* If they are actually trying to delete a contact that does not exist... be forgiving */
585                         if (!expiration) {
586                                 ast_verb(3, "Attempted to remove non-existent contact '%s' from AOR '%s' by request\n",
587                                         contact_uri, aor_name);
588                                 continue;
589                         }
590
591                         /* Determine if the contact cannot survive a restart/boot. */
592                         if (details.uri->port == rdata->pkt_info.src_port
593                                 && !pj_strcmp(&details.uri->host,
594                                         pj_cstr(&host_name, rdata->pkt_info.src_name))
595                                 /* We have already checked if the URI scheme is sip: or sips: */
596                                 && PJSIP_TRANSPORT_IS_RELIABLE(rdata->tp_info.transport)) {
597                                 pj_str_t type_name;
598
599                                 /* Determine the transport parameter value */
600                                 if (!strcasecmp("WSS", rdata->tp_info.transport->type_name)) {
601                                         /* WSS is special, as it needs to be ws. */
602                                         pj_cstr(&type_name, "ws");
603                                 } else {
604                                         pj_cstr(&type_name, rdata->tp_info.transport->type_name);
605                                 }
606
607                                 if (!pj_stricmp(&details.uri->transport_param, &type_name)
608                                         && (endpoint->nat.rewrite_contact
609                                                 /* Websockets are always rewritten */
610                                                 || !pj_stricmp(&details.uri->transport_param,
611                                                         pj_cstr(&type_name, "ws")))) {
612                                         /*
613                                          * The contact was rewritten to the reliable transport's
614                                          * source address.  Disconnecting the transport for any
615                                          * reason invalidates the contact.
616                                          */
617                                         prune_on_boot = 1;
618                                 }
619                         }
620
621                         contact = ast_sip_location_create_contact(aor, contact_uri,
622                                 ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1)),
623                                 path_str ? ast_str_buffer(path_str) : NULL,
624                                 user_agent, via_addr, via_port, call_id, prune_on_boot, endpoint);
625                         if (!contact) {
626                                 ast_log(LOG_ERROR, "Unable to bind contact '%s' to AOR '%s'\n",
627                                         contact_uri, aor_name);
628                                 continue;
629                         }
630
631                         if (prune_on_boot) {
632                                 const char *contact_name;
633                                 struct contact_transport_monitor *monitor;
634
635                                 /*
636                                  * Monitor the transport in case it gets disconnected because
637                                  * the contact won't be valid anymore if that happens.
638                                  */
639                                 contact_name = ast_sorcery_object_get_id(contact);
640                                 monitor = ao2_alloc_options(sizeof(*monitor) + 2 + strlen(aor_name)
641                                         + strlen(contact_name), NULL, AO2_ALLOC_OPT_LOCK_NOLOCK);
642                                 if (monitor) {
643                                         strcpy(monitor->aor_name, aor_name);/* Safe */
644                                         monitor->contact_name = monitor->aor_name + strlen(aor_name) + 1;
645                                         strcpy(monitor->contact_name, contact_name);/* Safe */
646
647                                         ast_sip_transport_monitor_register(rdata->tp_info.transport,
648                                                 register_contact_transport_shutdown_cb, monitor);
649                                         ao2_ref(monitor, -1);
650                                 }
651                         }
652
653                         ast_verb(3, "Added contact '%s' to AOR '%s' with expiration of %d seconds\n",
654                                 contact_uri, aor_name, expiration);
655                         ast_test_suite_event_notify("AOR_CONTACT_ADDED",
656                                         "Contact: %s\r\n"
657                                         "AOR: %s\r\n"
658                                         "Expiration: %d\r\n"
659                                         "UserAgent: %s",
660                                         contact_uri,
661                                         aor_name,
662                                         expiration,
663                                         user_agent);
664                 } else if (expiration) {
665                         struct ast_sip_contact *contact_update;
666
667                         contact_update = ast_sorcery_copy(ast_sip_get_sorcery(), contact);
668                         if (!contact_update) {
669                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
670                                         contact->uri, expiration);
671                                 continue;
672                         }
673
674                         contact_update->expiration_time = ast_tvadd(ast_tvnow(), ast_samp2tv(expiration, 1));
675                         contact_update->qualify_frequency = aor->qualify_frequency;
676                         contact_update->authenticate_qualify = aor->authenticate_qualify;
677                         if (path_str) {
678                                 ast_string_field_set(contact_update, path, ast_str_buffer(path_str));
679                         }
680                         if (user_agent) {
681                                 ast_string_field_set(contact_update, user_agent, user_agent);
682                         }
683                         if (!ast_strlen_zero(ast_config_AST_SYSTEM_NAME)) {
684                                 ast_string_field_set(contact_update, reg_server, ast_config_AST_SYSTEM_NAME);
685                         }
686
687                         if (ast_sip_location_update_contact(contact_update)) {
688                                 ast_log(LOG_ERROR, "Failed to update contact '%s' expiration time to %d seconds.\n",
689                                         contact->uri, expiration);
690                                 ast_sip_location_delete_contact(contact);
691                                 continue;
692                         }
693                         ast_debug(3, "Refreshed contact '%s' on AOR '%s' with new expiration of %d seconds\n",
694                                 contact_uri, aor_name, expiration);
695                         ast_test_suite_event_notify("AOR_CONTACT_REFRESHED",
696                                         "Contact: %s\r\n"
697                                         "AOR: %s\r\n"
698                                         "Expiration: %d\r\n"
699                                         "UserAgent: %s",
700                                         contact_uri,
701                                         aor_name,
702                                         expiration,
703                                         contact_update->user_agent);
704                         ao2_cleanup(contact_update);
705                 } else {
706                         /* We want to report the user agent that was actually in the removed contact */
707                         ast_sip_location_delete_contact(contact);
708                         ast_verb(3, "Removed contact '%s' from AOR '%s' due to request\n", contact_uri, aor_name);
709                         ast_test_suite_event_notify("AOR_CONTACT_REMOVED",
710                                         "Contact: %s\r\n"
711                                         "AOR: %s\r\n"
712                                         "UserAgent: %s",
713                                         contact_uri,
714                                         aor_name,
715                                         contact->user_agent);
716                 }
717         }
718
719         pjsip_endpt_release_pool(ast_sip_get_pjsip_endpoint(), details.pool);
720
721         /*
722          * If the AOR is configured to remove any contacts over max_contacts
723          * that have not been updated/added/deleted as a result of this
724          * REGISTER do so.
725          *
726          * The contacts container currently holds the existing contacts that
727          * were not affected by this REGISTER.
728          */
729         if (aor->remove_existing) {
730                 /* Total contacts after this registration */
731                 contact_count = ao2_container_count(contacts) + updated + added;
732                 if (contact_count > aor->max_contacts) {
733                         /* Remove excess existing contacts that expire the soonest */
734                         remove_excess_contacts(contacts, contact_count - aor->max_contacts);
735                 }
736         }
737
738         /* Re-retrieve contacts.  Caller will clean up the original container. */
739         contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
740         if (!contacts) {
741                 response->code = 500;
742                 return;
743         }
744         response_contact = ao2_callback(contacts, 0, NULL, NULL);
745
746         /* Send a response containing all of the contacts (including static) that are present on this AOR */
747         if (ast_sip_create_response(rdata, 200, response_contact, &tdata) != PJ_SUCCESS) {
748                 ao2_cleanup(response_contact);
749                 ao2_cleanup(contacts);
750                 response->code = 500;
751                 return;
752         }
753         ao2_cleanup(response_contact);
754
755         /* Add the date header to the response, some UAs use this to set their date and time */
756         registrar_add_date_header(tdata);
757
758         ao2_callback(contacts, 0, registrar_add_contact, tdata);
759         ao2_cleanup(contacts);
760
761         if ((expires_hdr = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_EXPIRES, NULL))) {
762                 expires_hdr = pjsip_expires_hdr_create(tdata->pool, registrar_get_expiration(aor, NULL, rdata));
763                 pjsip_msg_add_hdr(tdata->msg, (pjsip_hdr*)expires_hdr);
764         }
765
766         response->tdata = tdata;
767 }
768
769 static int register_aor(pjsip_rx_data *rdata,
770         struct ast_sip_endpoint *endpoint,
771         struct ast_sip_aor *aor,
772         const char *aor_name)
773 {
774         struct aor_core_response response = {
775                 .code = 500,
776         };
777         struct ao2_container *contacts = NULL;
778
779         ao2_lock(aor);
780         contacts = ast_sip_location_retrieve_aor_contacts_nolock(aor);
781         if (!contacts) {
782                 ao2_unlock(aor);
783                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
784                         rdata, response.code, NULL, NULL, NULL);
785                 return PJ_TRUE;
786         }
787
788         register_aor_core(rdata, endpoint, aor, aor_name, contacts, &response);
789         ao2_cleanup(contacts);
790         ao2_unlock(aor);
791
792         /* Now send the REGISTER response to the peer */
793         if (response.tdata) {
794                 ast_sip_send_stateful_response(rdata, response.tdata, endpoint);
795         } else {
796                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(),
797                         rdata, response.code, NULL, NULL, NULL);
798         }
799         return PJ_TRUE;
800 }
801
802 static int match_aor(const char *aor_name, const char *id)
803 {
804         if (ast_strlen_zero(aor_name)) {
805                 return 0;
806         }
807
808         if (!strcmp(aor_name, id)) {
809                 ast_debug(3, "Matched id '%s' to aor '%s'\n", id, aor_name);
810                 return 1;
811         }
812
813         return 0;
814 }
815
816 static char *find_aor_name(const char *username, const char *domain, const char *aors)
817 {
818         char *configured_aors;
819         char *aors_buf;
820         char *aor_name;
821         char *id_domain;
822         struct ast_sip_domain_alias *alias;
823
824         id_domain = ast_alloca(strlen(username) + strlen(domain) + 2);
825         sprintf(id_domain, "%s@%s", username, domain);
826
827         aors_buf = ast_strdupa(aors);
828
829         /* Look for exact match on username@domain */
830         configured_aors = aors_buf;
831         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
832                 if (match_aor(aor_name, id_domain)) {
833                         return ast_strdup(aor_name);
834                 }
835         }
836
837         /* If there's a domain alias, look for exact match on username@domain_alias */
838         alias = ast_sorcery_retrieve_by_id(ast_sip_get_sorcery(), "domain_alias", domain);
839         if (alias) {
840                 char *id_domain_alias = ast_alloca(strlen(username) + strlen(alias->domain) + 2);
841
842                 sprintf(id_domain, "%s@%s", username, alias->domain);
843                 ao2_cleanup(alias);
844
845                 configured_aors = strcpy(aors_buf, aors);/* Safe */
846                 while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
847                         if (match_aor(aor_name, id_domain_alias)) {
848                                 return ast_strdup(aor_name);
849                         }
850                 }
851         }
852
853         if (ast_strlen_zero(username)) {
854                 /* No username, no match */
855                 return NULL;
856         }
857
858         /* Look for exact match on username only */
859         configured_aors = strcpy(aors_buf, aors);/* Safe */
860         while ((aor_name = ast_strip(strsep(&configured_aors, ",")))) {
861                 if (match_aor(aor_name, username)) {
862                         return ast_strdup(aor_name);
863                 }
864         }
865
866         return NULL;
867 }
868
869 static struct ast_sip_aor *find_registrar_aor(struct pjsip_rx_data *rdata, struct ast_sip_endpoint *endpoint)
870 {
871         struct ast_sip_aor *aor = NULL;
872         char *aor_name = NULL;
873         char *domain_name;
874         char *username = NULL;
875         int i;
876
877         for (i = 0; i < AST_VECTOR_SIZE(&endpoint->ident_method_order); ++i) {
878                 pjsip_sip_uri *uri;
879                 pjsip_authorization_hdr *header = NULL;
880
881                 switch (AST_VECTOR_GET(&endpoint->ident_method_order, i)) {
882                 case AST_SIP_ENDPOINT_IDENTIFY_BY_USERNAME:
883                         uri = pjsip_uri_get_uri(rdata->msg_info.to->uri);
884
885                         domain_name = ast_alloca(uri->host.slen + 1);
886                         ast_copy_pj_str(domain_name, &uri->host, uri->host.slen + 1);
887                         username = ast_alloca(uri->user.slen + 1);
888                         ast_copy_pj_str(username, &uri->user, uri->user.slen + 1);
889
890                         /*
891                          * We may want to match without any user options getting
892                          * in the way.
893                          */
894                         AST_SIP_USER_OPTIONS_TRUNCATE_CHECK(username);
895
896                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
897                         if (aor_name) {
898                                 ast_debug(3, "Matched aor '%s' by To username\n", aor_name);
899                         }
900                         break;
901                 case AST_SIP_ENDPOINT_IDENTIFY_BY_AUTH_USERNAME:
902                         while ((header = pjsip_msg_find_hdr(rdata->msg_info.msg, PJSIP_H_AUTHORIZATION,
903                                 header ? header->next : NULL))) {
904                                 if (header && !pj_stricmp2(&header->scheme, "digest")) {
905                                         username = ast_alloca(header->credential.digest.username.slen + 1);
906                                         ast_copy_pj_str(username, &header->credential.digest.username, header->credential.digest.username.slen + 1);
907                                         domain_name = ast_alloca(header->credential.digest.realm.slen + 1);
908                                         ast_copy_pj_str(domain_name, &header->credential.digest.realm, header->credential.digest.realm.slen + 1);
909
910                                         aor_name = find_aor_name(username, domain_name, endpoint->aors);
911                                         if (aor_name) {
912                                                 ast_debug(3, "Matched aor '%s' by Authentication username\n", aor_name);
913                                                 break;
914                                         }
915                                 }
916                         }
917                         break;
918                 default:
919                         continue;
920                 }
921
922                 if (aor_name) {
923                         break;
924                 }
925         }
926
927         if (ast_strlen_zero(aor_name) || !(aor = ast_sip_location_retrieve_aor(aor_name))) {
928                 /* The provided AOR name was not found (be it within the configuration or sorcery itself) */
929                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 404, NULL, NULL, NULL);
930                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_requested_aor_not_found");
931                 ast_log(LOG_WARNING, "AOR '%s' not found for endpoint '%s'\n",
932                         username ?: "", ast_sorcery_object_get_id(endpoint));
933         }
934         ast_free(aor_name);
935         return aor;
936 }
937
938 static pj_bool_t registrar_on_rx_request(struct pjsip_rx_data *rdata)
939 {
940         RAII_VAR(struct ast_sip_endpoint *, endpoint,
941                  ast_pjsip_rdata_get_endpoint(rdata), ao2_cleanup);
942         struct ast_sip_aor *aor;
943         const char *aor_name;
944
945         if (pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_register_method) || !endpoint) {
946                 return PJ_FALSE;
947         }
948
949         if (ast_strlen_zero(endpoint->aors)) {
950                 /* Short circuit early if the endpoint has no AORs configured on it, which means no registration possible */
951                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
952                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_attempt_without_configured_aors");
953                 ast_log(LOG_WARNING, "Endpoint '%s' has no configured AORs\n", ast_sorcery_object_get_id(endpoint));
954                 return PJ_TRUE;
955         }
956
957         if (!PJSIP_URI_SCHEME_IS_SIP(rdata->msg_info.to->uri) && !PJSIP_URI_SCHEME_IS_SIPS(rdata->msg_info.to->uri)) {
958                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 416, NULL, NULL, NULL);
959                 ast_sip_report_failed_acl(endpoint, rdata, "registrar_invalid_uri_in_to_received");
960                 ast_log(LOG_WARNING, "Endpoint '%s' attempted to register to an AOR with a non-SIP URI\n", ast_sorcery_object_get_id(endpoint));
961                 return PJ_TRUE;
962         }
963
964         aor = find_registrar_aor(rdata, endpoint);
965         if (!aor) {
966                 /* We've already responded about not finding an AOR. */
967                 return PJ_TRUE;
968         }
969
970         aor_name = ast_sorcery_object_get_id(aor);
971
972         if (!aor->max_contacts) {
973                 /* Registration is not permitted for this AOR */
974                 pjsip_endpt_respond_stateless(ast_sip_get_pjsip_endpoint(), rdata, 403, NULL, NULL, NULL);
975                 ast_sip_report_req_no_support(endpoint, rdata, "registrar_attempt_without_registration_permitted");
976                 ast_log(LOG_WARNING, "AOR '%s' has no configured max_contacts. Endpoint '%s' unable to register\n",
977                         aor_name, ast_sorcery_object_get_id(endpoint));
978         } else {
979                 register_aor(rdata, endpoint, aor, aor_name);
980         }
981         ao2_ref(aor, -1);
982         return PJ_TRUE;
983 }
984
985 /* function pointer to callback needs to be within the module
986    in order to avoid problems with an undefined symbol */
987 static int sip_contact_to_str(void *acp, void *arg, int flags)
988 {
989         return ast_sip_contact_to_str(acp, arg, flags);
990 }
991
992 static int ami_registrations_aor(void *obj, void *arg, int flags)
993 {
994         struct ast_sip_aor *aor = obj;
995         struct ast_sip_ami *ami = arg;
996         int *count = ami->arg;
997         RAII_VAR(struct ast_str *, buf,
998                  ast_sip_create_ami_event("InboundRegistrationDetail", ami), ast_free);
999
1000         if (!buf) {
1001                 return -1;
1002         }
1003
1004         ast_sip_sorcery_object_to_ami(aor, &buf);
1005         ast_str_append(&buf, 0, "Contacts: ");
1006         ast_sip_for_each_contact(aor, sip_contact_to_str, &buf);
1007         ast_str_append(&buf, 0, "\r\n");
1008
1009         astman_append(ami->s, "%s\r\n", ast_str_buffer(buf));
1010         (*count)++;
1011         return 0;
1012 }
1013
1014 static int ami_registrations_endpoint(void *obj, void *arg, int flags)
1015 {
1016         struct ast_sip_endpoint *endpoint = obj;
1017         return ast_sip_for_each_aor(
1018                 endpoint->aors, ami_registrations_aor, arg);
1019 }
1020
1021 static int ami_registrations_endpoints(void *arg)
1022 {
1023         RAII_VAR(struct ao2_container *, endpoints,
1024                  ast_sip_get_endpoints(), ao2_cleanup);
1025
1026         if (!endpoints) {
1027                 return 0;
1028         }
1029
1030         ao2_callback(endpoints, OBJ_NODATA, ami_registrations_endpoint, arg);
1031         return 0;
1032 }
1033
1034 static int ami_show_registrations(struct mansession *s, const struct message *m)
1035 {
1036         int count = 0;
1037         struct ast_sip_ami ami = { .s = s, .m = m, .arg = &count, .action_id = astman_get_header(m, "ActionID"), };
1038
1039         astman_send_listack(s, m, "Following are Events for each Inbound registration",
1040                 "start");
1041
1042         ami_registrations_endpoints(&ami);
1043
1044         astman_send_list_complete_start(s, m, "InboundRegistrationDetailComplete", count);
1045         astman_send_list_complete_end(s);
1046         return 0;
1047 }
1048
1049 static int ami_show_registration_contact_statuses(struct mansession *s, const struct message *m)
1050 {
1051         int count = 0;
1052         struct ast_sip_ami ami = { .s = s, .m = m, .arg = NULL, .action_id = astman_get_header(m, "ActionID"), };
1053         struct ao2_container *contacts = ast_sorcery_retrieve_by_fields(
1054                 ast_sip_get_sorcery(), "contact", AST_RETRIEVE_FLAG_MULTIPLE | AST_RETRIEVE_FLAG_ALL, NULL);
1055         struct ao2_iterator i;
1056         struct ast_sip_contact *contact;
1057
1058         astman_send_listack(s, m, "Following are ContactStatusEvents for each Inbound "
1059                             "registration", "start");
1060
1061         if (contacts) {
1062                 i = ao2_iterator_init(contacts, 0);
1063                 while ((contact = ao2_iterator_next(&i))) {
1064                         struct ast_sip_contact_wrapper wrapper;
1065
1066                         wrapper.aor_id = (char *)contact->aor;
1067                         wrapper.contact = contact;
1068                         wrapper.contact_id = (char *)ast_sorcery_object_get_id(contact);
1069
1070                         ast_sip_format_contact_ami(&wrapper, &ami, 0);
1071                         count++;
1072
1073                         ao2_ref(contact, -1);
1074                 }
1075                 ao2_iterator_destroy(&i);
1076                 ao2_ref(contacts, -1);
1077         }
1078
1079         astman_send_list_complete_start(s, m, "ContactStatusDetailComplete", count);
1080         astman_send_list_complete_end(s);
1081         return 0;
1082 }
1083
1084 #define AMI_SHOW_REGISTRATION_CONTACT_STATUSES "PJSIPShowRegistrationInboundContactStatuses"
1085 #define AMI_SHOW_REGISTRATIONS "PJSIPShowRegistrationsInbound"
1086
1087 static pjsip_module registrar_module = {
1088         .name = { "Registrar", 9 },
1089         .id = -1,
1090         .priority = PJSIP_MOD_PRIORITY_APPLICATION,
1091         .on_rx_request = registrar_on_rx_request,
1092 };
1093
1094 static int load_module(void)
1095 {
1096         const pj_str_t STR_REGISTER = { "REGISTER", 8 };
1097
1098         CHECK_PJPROJECT_MODULE_LOADED();
1099
1100         ast_pjproject_get_buildopt("PJ_MAX_HOSTNAME", "%d", &pj_max_hostname);
1101         /* As of pjproject 2.4.5, PJSIP_MAX_URL_SIZE isn't exposed yet but we try anyway. */
1102         ast_pjproject_get_buildopt("PJSIP_MAX_URL_SIZE", "%d", &pjsip_max_url_size);
1103
1104         CHECK_PJSIP_MODULE_LOADED();
1105
1106         if (ast_sip_register_service(&registrar_module)) {
1107                 return AST_MODULE_LOAD_DECLINE;
1108         }
1109
1110         if (pjsip_endpt_add_capability(ast_sip_get_pjsip_endpoint(), NULL, PJSIP_H_ALLOW, NULL, 1, &STR_REGISTER) != PJ_SUCCESS) {
1111                 ast_sip_unregister_service(&registrar_module);
1112                 return AST_MODULE_LOAD_DECLINE;
1113         }
1114
1115         ast_manager_register_xml(AMI_SHOW_REGISTRATIONS, EVENT_FLAG_SYSTEM,
1116                                  ami_show_registrations);
1117         ast_manager_register_xml(AMI_SHOW_REGISTRATION_CONTACT_STATUSES, EVENT_FLAG_SYSTEM,
1118                                  ami_show_registration_contact_statuses);
1119
1120         return AST_MODULE_LOAD_SUCCESS;
1121 }
1122
1123 static int unload_module(void)
1124 {
1125         ast_manager_unregister(AMI_SHOW_REGISTRATIONS);
1126         ast_manager_unregister(AMI_SHOW_REGISTRATION_CONTACT_STATUSES);
1127         ast_sip_unregister_service(&registrar_module);
1128         ast_sip_transport_monitor_unregister_all(register_contact_transport_shutdown_cb);
1129         return 0;
1130 }
1131
1132 AST_MODULE_INFO(ASTERISK_GPL_KEY, AST_MODFLAG_LOAD_ORDER, "PJSIP Registrar Support",
1133         .support_level = AST_MODULE_SUPPORT_CORE,
1134         .load = load_module,
1135         .unload = unload_module,
1136         .load_pri = AST_MODPRI_CHANNEL_DEPEND - 3,
1137         .requires = "res_pjproject,res_pjsip",
1138 );