]> 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)
committerGeorge Joseph <gjoseph@digium.com>
Thu, 29 Apr 2021 12:44:41 +0000 (07:44 -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 ba269a3d1f34dd2516c59640e5e5d67ae74fff01..bc791aded22d1dcf1eb0d611e8333c379e0c0e81 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 81161f38a78bd2fa6538ba45e654305ead7efa76..a094205acb3c4fd2e161e0579861e4c22542282e 100644 (file)
@@ -839,6 +839,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 4978a24f2aee68a2e26f371df0249a269be8287f..0df0e1dfc46de03ea57e6297940a5cbe47fa304e 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>
@@ -2990,6 +3007,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 a4968431c70631155c6b8441ebe4ffc7665eb003..5bf65eb6e1d37d04b0f7c7233ee28dc17ff46b65 100644 (file)
@@ -1968,6 +1968,7 @@ int ast_res_pjsip_initialize_configuration(void)
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "suppress_q850_reason_headers", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, suppress_q850_reason_headers));
        ast_sorcery_object_field_register(sip_sorcery, "endpoint", "ignore_183_without_sdp", "no", OPT_BOOL_T, 1, FLDSET(struct ast_sip_endpoint, ignore_183_without_sdp));
        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");