]> git.ipfire.org Git - thirdparty/asterisk.git/commitdiff
res_pjsip.c: OPTIONS processing can now optionally skip authentication
authorSean Bright <sean.bright@gmail.com>
Fri, 23 Apr 2021 17:37:20 +0000 (13:37 -0400)
committerFriendly Automation <jenkins2@gerrit.asterisk.org>
Wed, 28 Apr 2021 21:39:06 +0000 (16:39 -0500)
ASTERISK-27477 #close

Change-Id: I68f6715bba92a525149e35d142a49377a34a1193

configs/samples/pjsip.conf.sample
contrib/ast-db-manage/config/versions/c20d6e3992f4_add_allow_unauthenticated_options.py [new file with mode: 0644]
doc/CHANGES-staging/pjsip_endpoint_unauthenticated_options.txt [new file with mode: 0644]
include/asterisk/res_pjsip.h
res/res_pjsip.c
res/res_pjsip/pjsip_configuration.c

index de3e8664ed33ad2d8c392ff5f628bdecc30ebeda..7b4c7aac1eff4e9845e190ef31c315775e4d2e5b 100644 (file)
                            ; happens to the call if verification fails; it's up to
                            ; you to determine what to do with the results.
                            ; (default: no)
+;allow_unauthenticated_options =
+                           ; By default, chan_pjsip will challenge an incoming
+                           ; OPTIONS request for authentication credentials just
+                           ; as it would an INVITE request. This is consistent
+                           ; with RFC 3261.
+                           ; There are many UAs that use an OPTIONS request as a
+                           ; "ping" and they expect a 200 response indicating that
+                           ; the remote party is up and running without a need to
+                           ; authenticate.
+                           ; Setting allow_unauthenticated_options to 'yes' will
+                           ; instruct chan_pjsip to skip the authentication step
+                           ; when it receives an OPTIONS request for this
+                           ; endpoint.
+                           ; There are security implications to enabling this
+                           ; setting as it can allow information disclosure to
+                           ; occur - specifically, if enabled, an external party
+                           ; could enumerate and find the endpoint name by
+                           ; sending OPTIONS requests and examining the
+                           ; responses.
+                           ; (default: no)
 
 ;==========================AUTH SECTION OPTIONS=========================
 ;[auth]
diff --git a/contrib/ast-db-manage/config/versions/c20d6e3992f4_add_allow_unauthenticated_options.py b/contrib/ast-db-manage/config/versions/c20d6e3992f4_add_allow_unauthenticated_options.py
new file mode 100644 (file)
index 0000000..deec532
--- /dev/null
@@ -0,0 +1,29 @@
+"""add allow_unauthenticated_options
+
+Revision ID: c20d6e3992f4
+Revises: 8915fcc5766f
+Create Date: 2021-04-23 13:44:38.296558
+
+"""
+
+# revision identifiers, used by Alembic.
+revision = 'c20d6e3992f4'
+down_revision = '8915fcc5766f'
+
+from alembic import op
+import sqlalchemy as sa
+from sqlalchemy.dialects.postgresql import ENUM
+
+AST_BOOL_NAME = 'ast_bool_values'
+AST_BOOL_VALUES = [ '0', '1',
+                    'off', 'on',
+                    'false', 'true',
+                    'no', 'yes' ]
+
+def upgrade():
+    ast_bool_values = ENUM(*AST_BOOL_VALUES, name=AST_BOOL_NAME, create_type=False)
+    op.add_column('ps_endpoints', sa.Column('allow_unauthenticated_options', ast_bool_values))
+
+def downgrade():
+    op.drop_column('ps_endpoints', 'allow_unauthenticated_options')
+    pass
diff --git a/doc/CHANGES-staging/pjsip_endpoint_unauthenticated_options.txt b/doc/CHANGES-staging/pjsip_endpoint_unauthenticated_options.txt
new file mode 100644 (file)
index 0000000..9c8d32c
--- /dev/null
@@ -0,0 +1,5 @@
+Subject: res_pjsip
+
+PJSIP endpoints can now be configured to skip authentication when
+handling OPTIONS requests by setting the allow_unauthenticated_options
+configuration property to 'yes.'
index 5e3e439fda7c33467450ebc9af37ef635444572e..2020ca8782c3a9030564800602ebfcb93a7bc6cc 100644 (file)
@@ -915,6 +915,8 @@ struct ast_sip_endpoint {
        unsigned int ignore_183_without_sdp;
        /*! Enable STIR/SHAKEN support on this endpoint */
        unsigned int stir_shaken;
+       /*! Should we authenticate OPTIONS requests per RFC 3261? */
+       unsigned int allow_unauthenticated_options;
 };
 
 /*! URI parameter for symmetric transport */
index 53198eacf200d562a0a3ad088b87859d1cf2586f..775b63f8d1af41bcc86c890a678144d23ee88c8e 100644 (file)
                                                INVITEs, an Identity header will be added.</para>
                                        </description>
                                </configOption>
+                               <configOption name="allow_unauthenticated_options" default="no">
+                                       <synopsis>Skip authentication when receiving OPTIONS requests</synopsis>
+                                       <description><para>
+                                               RFC 3261 says that the response to an OPTIONS request MUST be the
+                                               same had the request been an INVITE. Some UAs use OPTIONS requests
+                                               like a 'ping' and the expectation is that they will return a
+                                               200 OK.</para>
+                                               <para>Enabling <literal>allow_unauthenticated_options</literal>
+                                               will skip authentication of OPTIONS requests for the given
+                                               endpoint.</para>
+                                               <para>There are security implications to enabling this setting as
+                                               it can allow information disclosure to occur - specifically, if
+                                               enabled, an external party could enumerate and find the endpoint
+                                               name by sending OPTIONS requests and examining the
+                                               responses.</para>
+                                       </description>
+                               </configOption>
                        </configObject>
                        <configObject name="auth">
                                <synopsis>Authentication type</synopsis>
@@ -3307,6 +3324,12 @@ void ast_sip_unregister_authenticator(struct ast_sip_authenticator *auth)
 
 int ast_sip_requires_authentication(struct ast_sip_endpoint *endpoint, pjsip_rx_data *rdata)
 {
+       if (endpoint->allow_unauthenticated_options
+               && !pjsip_method_cmp(&rdata->msg_info.msg->line.req.method, &pjsip_options_method)) {
+               ast_debug(3, "Skipping OPTIONS authentication due to endpoint configuration\n");
+               return 0;
+       }
+
        if (!registered_authenticator) {
                ast_log(LOG_WARNING, "No SIP authenticator registered. Assuming authentication is not required\n");
                return 0;
index 80bad02b37d5e801494a9b0f27d041562117e48a..6d12c6f6ec841b566e5331bc3e6ea9e0a6d8e06f 100644 (file)
@@ -2153,6 +2153,7 @@ int ast_res_pjsip_initialize_configuration(void)
                "prefer: pending, operation: intersect, keep: all",
                codec_prefs_handler, outgoing_answer_codec_prefs_to_str, NULL, 0, 0);
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "stir_shaken", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, stir_shaken));
+       ast_sorcery_object_field_register(sip_sorcery, "endpoint", "allow_unauthenticated_options", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, allow_unauthenticated_options));
 
        if (ast_sip_initialize_sorcery_transport()) {
                ast_log(LOG_ERROR, "Failed to register SIP transport support with sorcery\n");