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