[Asterisk-code-review] Create auth tests for realm and digest algorithm (testsuite[18])

Friendly Automation asteriskteam at digium.com
Fri May 21 07:07:55 CDT 2021


Friendly Automation has submitted this change. ( https://gerrit.asterisk.org/c/testsuite/+/15902 )

Change subject: Create auth tests for realm and digest algorithm
......................................................................

Create auth tests for realm and digest algorithm

Created 3 new test cases ...
 * multiple_realm_multiple_digest
 * single_realm_multiple_digest
 * single_realm_single_digest
Each test case tests 6 different variations of the scenario.

Also updated the sipp.dtd.

ASTERISK-29397

Change-Id: I64d8ca768cf7a2c55ca4a256ec37bf4c712b4004
---
M contrib/sipp/sipp.dtd
M tests/channels/pjsip/auth/tests.yaml
A tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/configs/ast1/pjsip.conf
A tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/sipp/multiple_realm_multiple_digest_options.xml
A tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/test-config.yaml
A tests/channels/pjsip/auth/uac/single_realm_multiple_digest/configs/ast1/pjsip.conf
A tests/channels/pjsip/auth/uac/single_realm_multiple_digest/sipp/single_realm_multiple_digest_options.xml
A tests/channels/pjsip/auth/uac/single_realm_multiple_digest/test-config.yaml
A tests/channels/pjsip/auth/uac/single_realm_single_digest/configs/ast1/pjsip.conf
A tests/channels/pjsip/auth/uac/single_realm_single_digest/sipp/single_realm_single_digest_options.xml
A tests/channels/pjsip/auth/uac/single_realm_single_digest/test-config.yaml
A tests/channels/pjsip/auth/uac/tests.yaml
12 files changed, 959 insertions(+), 0 deletions(-)

Approvals:
  Joshua Colp: Looks good to me, but someone else must approve
  Kevin Harwell: Looks good to me, but someone else must approve
  George Joseph: Looks good to me, approved
  Friendly Automation: Approved for Submit



diff --git a/contrib/sipp/sipp.dtd b/contrib/sipp/sipp.dtd
index e839071..e2ba1f5 100644
--- a/contrib/sipp/sipp.dtd
+++ b/contrib/sipp/sipp.dtd
@@ -78,6 +78,8 @@
 <!ATTLIST ereg regexp CDATA #REQUIRED >
 <!ATTLIST ereg search_in (msg|hdr) "msg" >
 <!ATTLIST ereg start_line (true|false) #IMPLIED >
+<!ATTLIST ereg occurence CDATA #IMPLIED >
+
 
 <!ELEMENT log EMPTY >
 <!ATTLIST log message CDATA #REQUIRED >
diff --git a/tests/channels/pjsip/auth/tests.yaml b/tests/channels/pjsip/auth/tests.yaml
index 5ab2b6a..7275618 100644
--- a/tests/channels/pjsip/auth/tests.yaml
+++ b/tests/channels/pjsip/auth/tests.yaml
@@ -1,2 +1,3 @@
 tests:
+    - dir: 'uac'
     - dir: 'uas'
diff --git a/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/configs/ast1/pjsip.conf b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..7031962
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/configs/ast1/pjsip.conf
@@ -0,0 +1,143 @@
+[system]
+type = system
+timer_b = 32000
+timer_t1 = 500
+
+[local]
+type=transport
+protocol=udp
+bind=127.0.0.1
+
+[aor_template](!)
+type=aor
+qualify_frequency=0
+
+[star_good]
+type = auth
+auth_type = userpass
+username = staruser
+password = starpasswd
+realm = star
+
+[star_bad]
+type = auth
+auth_type = userpass
+username = starbad
+password = starpasswd
+realm = star
+
+[ast_good]
+type = auth
+auth_type = userpass
+username = astuser
+password = astpasswd
+realm = ast
+
+[ast_bad]
+type = auth
+auth_type = userpass
+username = astbad
+password = astpasswd
+realm = ast
+
+[wildcard_good_star]
+type = auth
+auth_type = userpass
+username = staruser
+password = starpasswd
+
+[wildcard_good_ast]
+type = auth
+auth_type = userpass
+username = astuser
+password = astpasswd
+realm = *
+
+; This will fail because the password is bad
+[wildcard_bad]
+type = auth
+auth_type = userpass
+username = optbad
+password = optbad
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match
+;
+[sipp2](aor_template)
+contact = sip:sipp2 at 127.0.0.2:5060
+[sipp2]
+type = endpoint
+aors=sipp2
+outbound_auth = star_good,ast_bad
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match.  Same a above but testing that having the
+; wildcard_first doesn't change the behavior.
+;
+[sipp3](aor_template)
+contact = sip:sipp3 at 127.0.0.3:5060
+[sipp3]
+type = endpoint
+aors=sipp3
+outbound_auth = wildcard_bad,star_good
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good configured.
+;
+; Having 2 wildcard entries for an endpoint is a
+; misconfiguration but we should only ever consider
+; the first one we find.  The inverse order is tested
+; in a different test case.
+;
+[sipp4](aor_template)
+contact = sip:sipp4 at 127.0.0.4:5060
+[sipp4]
+type = endpoint
+aors=sipp4
+outbound_auth = wildcard_good_star,wildcard_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_is good configured.
+; ast_bad should be discarded because it's neither
+; a wilcard nor an exact realm match.
+;
+[sipp5](aor_template)
+contact = sip:sipp5 at 127.0.0.5:5060
+[sipp5]
+type = endpoint
+aors=sipp5
+outbound_auth = wildcard_good_star,ast_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure reversing the order doesn't change the behavior.
+;
+[sipp6](aor_template)
+contact = sip:sipp6 at 127.0.0.6:5060
+[sipp6]
+type = endpoint
+aors=sipp6
+outbound_auth = ast_bad,wildcard_good_star
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure using a realm of "*" is considered a wildcard.
+;
+[sipp7](aor_template)
+contact = sip:sipp7 at 127.0.0.7:5060
+[sipp7]
+type = endpoint
+aors=sipp7
+outbound_auth = star_bad,wildcard_good_ast
diff --git a/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/sipp/multiple_realm_multiple_digest_options.xml b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/sipp/multiple_realm_multiple_digest_options.xml
new file mode 100644
index 0000000..140e78b
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/sipp/multiple_realm_multiple_digest_options.xml
@@ -0,0 +1,119 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- If you have a smart XML editor, using the sipp dtd can be a big help -->
+<!DOCTYPE scenario SYSTEM "../../../../../../../contrib/sipp/sipp.dtd">
+<scenario name="single_realm_single_digest_options">
+
+	<recv request="OPTIONS">
+	</recv>
+
+	<!--
+		The nonce and opaque have no meaning other than they're properly formatted.
+		We're going to send a multiple challenges with the "star" realm and "md5",
+		"sha256" and "sha256-512" digest algorithms.  At the time this test was
+		written, only "md5" responses should be received from asterisk.
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 401 Authorization Required
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+      WWW-Authenticate: Digest realm="ast",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256,qop="auth"
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256-512,qop="auth"
+      WWW-Authenticate: Digest realm="ast",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=md5,qop="auth"
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256,qop="auth"
+      WWW-Authenticate: Digest realm="ast",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256-512,qop="auth"
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=md5,qop="auth"
+
+    ]]>
+	</send>
+
+	<!--
+		sipp has issues with multiple headers with the same name.  If you don't specify
+		occurrence, it checks the first header it finds so both eregs below would be
+		matched against the first Authorization header.  To get around this, we
+		have to specify which header occurrence we want to test. Since Asterisk will
+		add Authorization headers in the same order as the WWW-Authenticate headers
+		it received, occurrence 1 has to match the first md5 header (ast) and occurrence
+		2 has to match the second (star).
+	-->
+	<recv request="OPTIONS">
+		<action>
+			<!-- Look for an "ast" realm -->
+			<ereg regexp="Digest .*username=.(astuser)..*realm=.(ast)."
+				search_in="hdr" header="Authorization:" occurence="1"
+				assign_to="junk,username_ast,realm_ast"/>
+
+			<log message="ast: [$username_ast]"/>
+
+			<!-- Look for a "star" realm -->
+			<ereg regexp="Digest .*username=.(staruser)..*realm=.(star)."
+				search_in="hdr" header="Authorization:"  occurence="2"
+				assign_to="junk,username_star,realm_star"/>
+
+			<log message="star: [$username_star]"/>
+
+		</action>
+	</recv>
+
+	<!--
+		One of the realms has to pass.
+	-->
+	<nop test="username_star" next="goodauth"/>
+	<nop test="username_ast" next="goodauth"/>
+
+	<!--
+		We're not testing Asterisk's ability to handle repeated auth failures
+		so we just send back a 503 and terminate the test with prejudice
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 503 Service Unavailable
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+
+    ]]>
+	</send>
+
+	<nop>
+		<action>
+			<!--
+				Terminate the test with prejudice.
+				sipp will return a non-zero return code which
+				will cause the test to fail.
+			-->
+			<exec int_cmd="stop_now"/>
+		</action>
+	</nop>
+
+	<!-- Auth passed so just send back an OK and we're done -->
+	<label id="goodauth"/>
+
+	<send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: [len]
+
+    ]]>
+	</send>
+
+	<Reference variables="junk,username_ast,username_star,realm_ast,realm_star"/>
+</scenario>
diff --git a/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/test-config.yaml b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/test-config.yaml
new file mode 100644
index 0000000..6338bcc
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/multiple_realm_multiple_digest/test-config.yaml
@@ -0,0 +1,62 @@
+tinfo:
+    summary: 'Test Multiple Realm Multiple Digest authentication using OPTIONS'
+    description: |
+        Each sipp scenario does exactly the same thing just listening on
+        different addresses. The endpoint we qualify determines the exact auth
+        scenario we're testing.
+        On fully-booted, we just send 1 Qualify command to each of the endpoints
+        and if any of the sipp instances fails to authenticate, the test fails.
+        See pjsip.conf for the exact auth scenarios.
+        The test is fast since the sipp instances are all run in parallel as are
+        the Qualify commands.  The test should also be immune to timing variances
+        since the test case doesn't issue the AMI commands until the sipp scenarios
+        are started.
+
+test-modules:
+    test-object:
+        config-section: sipp-config
+        typename: 'sipp.SIPpTestCase'
+    modules:
+        -
+            config-section: ami-config
+            typename: 'pluggable_modules.EventActionModule'
+
+sipp-config:
+    memcheck-delay-stop: 7
+    fail-on-any: True
+    test-iterations:
+        -
+            scenarios:
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.2', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.3', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.4', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.5', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.6', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'multiple_realm_multiple_digest_options.xml', '-i': '127.0.0.7', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+
+ami-config:
+    -
+        ami-start:
+        ami-actions:
+            - { action: { Action: 'PJSIPQualify', ActionID: '12342', Endpoint: 'sipp2' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12343', Endpoint: 'sipp3' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12344', Endpoint: 'sipp4' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12345', Endpoint: 'sipp5' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12346', Endpoint: 'sipp6' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12347', Endpoint: 'sipp7' } }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'res_pjsip'
+        - asterisk : 'res_pjsip_outbound_registration'
+        - asterisk : 'res_pjsip_outbound_authenticator_digest'
+    tags:
+        - pjsip
diff --git a/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/configs/ast1/pjsip.conf b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..c69373c
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/configs/ast1/pjsip.conf
@@ -0,0 +1,151 @@
+[system]
+type = system
+timer_b = 32000
+timer_t1 = 500
+
+[local]
+type=transport
+protocol=udp
+bind=127.0.0.1
+
+[aor_template](!)
+type=aor
+qualify_frequency=0
+
+;
+; The sipp scenario expects a Authorization header with...
+; realm = star
+; username = optuser
+; password = optpasswd
+;
+
+[star_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = star
+
+[star_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswdbad
+realm = star
+
+[ast_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = ast
+
+[ast_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswdbad
+realm = ast
+
+[wildcard_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+
+[wildcard_good2]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = *
+
+; This will fail because the password is bad
+[wildcard_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optbad
+
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match
+;
+[sipp2](aor_template)
+contact = sip:sipp2 at 127.0.0.2:5060
+[sipp2]
+type = endpoint
+aors=sipp2
+outbound_auth = star_good,wildcard_bad
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match.  Same a above but testing that having the
+; wildcard_first doesn't change the behavior.
+;
+[sipp3](aor_template)
+contact = sip:sipp3 at 127.0.0.3:5060
+[sipp3]
+type = endpoint
+aors=sipp3
+outbound_auth = wildcard_bad,star_good
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good configured.
+;
+; Having 2 wildcard entries for an endpoint is a
+; misconfiguration but we should only ever consider
+; the first one we find.  The inverse order is tested
+; in a different test case.
+;
+[sipp4](aor_template)
+contact = sip:sipp4 at 127.0.0.4:5060
+[sipp4]
+type = endpoint
+aors=sipp4
+outbound_auth = wildcard_good,wildcard_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_is good configured.
+; ast_bad should be discarded because it's neither
+; a wilcard nor an exact realm match.
+;
+[sipp5](aor_template)
+contact = sip:sipp5 at 127.0.0.5:5060
+[sipp5]
+type = endpoint
+aors=sipp5
+outbound_auth = wildcard_good,ast_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure reversing the order doesn't change the behavior.
+;
+[sipp6](aor_template)
+contact = sip:sipp6 at 127.0.0.6:5060
+[sipp6]
+type = endpoint
+aors=sipp6
+outbound_auth = ast_bad,wildcard_good
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure using a realm of "*" is considered a wildcard.
+;
+[sipp7](aor_template)
+contact = sip:sipp7 at 127.0.0.7:5060
+[sipp7]
+type = endpoint
+aors=sipp7
+outbound_auth = ast_bad,wildcard_good2
diff --git a/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/sipp/single_realm_multiple_digest_options.xml b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/sipp/single_realm_multiple_digest_options.xml
new file mode 100644
index 0000000..2e15d36
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/sipp/single_realm_multiple_digest_options.xml
@@ -0,0 +1,102 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- If you have a smart XML editor, using the sipp dtd can be a big help -->
+<!DOCTYPE scenario SYSTEM "../../../../../../../contrib/sipp/sipp.dtd">
+<scenario name="single_realm_single_digest_options">
+
+	<recv request="OPTIONS">
+	</recv>
+
+	<!--
+		The nonce and opaque have no meaning other than they're properly formatted.
+		We're going to send a multiple challenges with the "star" realm and "md5",
+		"sha256" and "sha256-512" digest algorithms.  At the time this test was
+		written, only an "md5" response should be received from asterisk.
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 401 Authorization Required
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256,qop="auth"
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=md5,qop="auth"
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=sha256-512,qop="auth"
+
+    ]]>
+	</send>
+
+	<recv request="OPTIONS">
+		<action>
+			<ereg regexp="Digest .*username=.(.+)..*realm=.(star)."
+				search_in="hdr" header="Authorization:"
+				assign_to="junk,username,realm"/>
+			<!--
+				sipp will examine the returned Authentication header and
+				validate the username and password.
+			-->
+			<verifyauth assign_to="authvalid" username="optuser"
+				password="optpasswd"/>
+		</action>
+	</recv>
+
+	<!--
+		If authvalid is set, the alidation was successful so skip on
+		down to sending an OK.
+	-->
+	<nop test="authvalid" next="goodauth"/>
+
+	<!--
+		We're not testing Asterisk's ability to handle repeated auth failures
+		so we just send back a 503 and terminate the test with prejudice
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 503 Service Unavailable
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+
+    ]]>
+	</send>
+
+	<nop>
+		<action>
+			<!--
+				Terminate the test with prejudice.
+				sipp will return a non-zero return code which
+				will cause the test to fail.
+			-->
+			<exec int_cmd="stop_now"/>
+		</action>
+	</nop>
+
+	<!-- Auth passed so just send back an OK and we're done -->
+	<label id="goodauth"/>
+
+	<send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: [len]
+
+    ]]>
+	</send>
+
+	<Reference variables="junk,username,realm"/>
+</scenario>
diff --git a/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/test-config.yaml b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/test-config.yaml
new file mode 100644
index 0000000..e6b48ad
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_multiple_digest/test-config.yaml
@@ -0,0 +1,62 @@
+tinfo:
+    summary: 'Test Single Realm Multiple Digest authentication using OPTIONS'
+    description: |
+        Each sipp scenario does exactly the same thing just listening on
+        different addresses. The endpoint we qualify determines the exact auth
+        scenario we're testing.
+        On fully-booted, we just send 1 Qualify command to each of the endpoints
+        and if any of the sipp instances fails to authenticate, the test fails.
+        See pjsip.conf for the exact auth scenarios.
+        The test is fast since the sipp instances are all run in parallel as are
+        the Qualify commands.  The test should also be immune to timing variances
+        since the test case doesn't issue the AMI commands until the sipp scenarios
+        are started.
+
+test-modules:
+    test-object:
+        config-section: sipp-config
+        typename: 'sipp.SIPpTestCase'
+    modules:
+        -
+            config-section: ami-config
+            typename: 'pluggable_modules.EventActionModule'
+
+sipp-config:
+    memcheck-delay-stop: 7
+    fail-on-any: True
+    test-iterations:
+        -
+            scenarios:
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.2', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.3', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.4', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.5', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.6', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_multiple_digest_options.xml', '-i': '127.0.0.7', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+
+ami-config:
+    -
+        ami-start:
+        ami-actions:
+            - { action: { Action: 'PJSIPQualify', ActionID: '12342', Endpoint: 'sipp2' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12343', Endpoint: 'sipp3' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12344', Endpoint: 'sipp4' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12345', Endpoint: 'sipp5' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12346', Endpoint: 'sipp6' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12347', Endpoint: 'sipp7' } }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'res_pjsip'
+        - asterisk : 'res_pjsip_outbound_registration'
+        - asterisk : 'res_pjsip_outbound_authenticator_digest'
+    tags:
+        - pjsip
diff --git a/tests/channels/pjsip/auth/uac/single_realm_single_digest/configs/ast1/pjsip.conf b/tests/channels/pjsip/auth/uac/single_realm_single_digest/configs/ast1/pjsip.conf
new file mode 100644
index 0000000..c69373c
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_single_digest/configs/ast1/pjsip.conf
@@ -0,0 +1,151 @@
+[system]
+type = system
+timer_b = 32000
+timer_t1 = 500
+
+[local]
+type=transport
+protocol=udp
+bind=127.0.0.1
+
+[aor_template](!)
+type=aor
+qualify_frequency=0
+
+;
+; The sipp scenario expects a Authorization header with...
+; realm = star
+; username = optuser
+; password = optpasswd
+;
+
+[star_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = star
+
+[star_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswdbad
+realm = star
+
+[ast_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = ast
+
+[ast_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswdbad
+realm = ast
+
+[wildcard_good]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+
+[wildcard_good2]
+type = auth
+auth_type = userpass
+username = optuser
+password = optpasswd
+realm = *
+
+; This will fail because the password is bad
+[wildcard_bad]
+type = auth
+auth_type = userpass
+username = optuser
+password = optbad
+
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match
+;
+[sipp2](aor_template)
+contact = sip:sipp2 at 127.0.0.2:5060
+[sipp2]
+type = endpoint
+aors=sipp2
+outbound_auth = star_good,wildcard_bad
+
+;
+; This endpoint should pass because star_good is used
+; and the wildcard is discarded because we found an exact
+; realm match.  Same a above but testing that having the
+; wildcard_first doesn't change the behavior.
+;
+[sipp3](aor_template)
+contact = sip:sipp3 at 127.0.0.3:5060
+[sipp3]
+type = endpoint
+aors=sipp3
+outbound_auth = wildcard_bad,star_good
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good configured.
+;
+; Having 2 wildcard entries for an endpoint is a
+; misconfiguration but we should only ever consider
+; the first one we find.  The inverse order is tested
+; in a different test case.
+;
+[sipp4](aor_template)
+contact = sip:sipp4 at 127.0.0.4:5060
+[sipp4]
+type = endpoint
+aors=sipp4
+outbound_auth = wildcard_good,wildcard_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_is good configured.
+; ast_bad should be discarded because it's neither
+; a wilcard nor an exact realm match.
+;
+[sipp5](aor_template)
+contact = sip:sipp5 at 127.0.0.5:5060
+[sipp5]
+type = endpoint
+aors=sipp5
+outbound_auth = wildcard_good,ast_bad
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure reversing the order doesn't change the behavior.
+;
+[sipp6](aor_template)
+contact = sip:sipp6 at 127.0.0.6:5060
+[sipp6]
+type = endpoint
+aors=sipp6
+outbound_auth = ast_bad,wildcard_good
+
+;
+; This endpoint should pass even though there's no exact
+; realm match because wildcard_good is configured.
+;
+; Same scenario as the previous endpoint but making
+; sure using a realm of "*" is considered a wildcard.
+;
+[sipp7](aor_template)
+contact = sip:sipp7 at 127.0.0.7:5060
+[sipp7]
+type = endpoint
+aors=sipp7
+outbound_auth = ast_bad,wildcard_good2
diff --git a/tests/channels/pjsip/auth/uac/single_realm_single_digest/sipp/single_realm_single_digest_options.xml b/tests/channels/pjsip/auth/uac/single_realm_single_digest/sipp/single_realm_single_digest_options.xml
new file mode 100644
index 0000000..1e83130
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_single_digest/sipp/single_realm_single_digest_options.xml
@@ -0,0 +1,99 @@
+<?xml version="1.0" encoding="ISO-8859-1" ?>
+<!-- If you have a smart XML editor, using the sipp dtd can be a big help -->
+<!DOCTYPE scenario SYSTEM "../../../../../../../contrib/sipp/sipp.dtd">
+<scenario name="single_realm_single_digest_options">
+
+	<recv request="OPTIONS">
+	</recv>
+
+	<!--
+		The nonce and opaque have no meaning other than they're properly formatted.
+		We're going to send a single challenge with the "star" realm and "md5"
+		digest algorithm.  99.999% of the cases.
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 401 Authorization Required
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+      WWW-Authenticate: Digest realm="star",nonce="1618496418/76de4d6a2e8750da189999715d6d55b1",opaque="4982d4386a93d85d",algorithm=md5,qop="auth"
+
+    ]]>
+	</send>
+
+	<recv request="OPTIONS">
+		<action>
+			<ereg regexp="Digest .*username=.(.+)..*realm=.(star)."
+				search_in="hdr" header="Authorization:"
+				assign_to="junk,username,realm"/>
+			<!--
+				sipp will examine the returned Authentication header and
+				validate the username and password.
+			-->
+			<verifyauth assign_to="authvalid" username="optuser"
+				password="optpasswd"/>
+		</action>
+	</recv>
+
+	<!--
+		If authvalid is set, the alidation was successful so skip on
+		down to sending an OK.
+	-->
+	<nop test="authvalid" next="goodauth"/>
+
+	<!--
+		We're not testing Asterisk's ability to handle repeated auth failures
+		so we just send back a 503 and terminate the test with prejudice
+	-->
+	<send>
+    <![CDATA[
+
+      SIP/2.0 503 Service Unavailable
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: 0
+
+    ]]>
+	</send>
+
+	<nop>
+		<action>
+			<!--
+				Terminate the test with prejudice.
+				sipp will return a non-zero return code which
+				will cause the test to fail.
+			-->
+			<exec int_cmd="stop_now"/>
+		</action>
+	</nop>
+
+	<!-- Auth passed so just send back an OK and we're done -->
+	<label id="goodauth"/>
+
+	<send>
+    <![CDATA[
+
+      SIP/2.0 200 OK
+      [last_Via:]
+      [last_From:]
+      [last_To:];tag=[pid]SIPpTag01[call_number]
+      [last_Call-ID:]
+      [last_CSeq:]
+      Contact: <sip:[local_ip]:[local_port];transport=[transport]>
+      Content-Length: [len]
+
+    ]]>
+	</send>
+
+	<Reference variables="junk,username,realm"/>
+</scenario>
diff --git a/tests/channels/pjsip/auth/uac/single_realm_single_digest/test-config.yaml b/tests/channels/pjsip/auth/uac/single_realm_single_digest/test-config.yaml
new file mode 100644
index 0000000..aa9be41
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/single_realm_single_digest/test-config.yaml
@@ -0,0 +1,62 @@
+tinfo:
+    summary: 'Test Single Realm Single Digest authentication using OPTIONS'
+    description: |
+        Each sipp scenario does exactly the same thing just listening on
+        different addresses. The endpoint we qualify determines the exact auth
+        scenario we're testing.
+        On fully-booted, we just send 1 Qualify command to each of the endpoints
+        and if any of the sipp instances fails to authenticate, the test fails.
+        See pjsip.conf for the exact auth scenarios.
+        The test is fast since the sipp instances are all run in parallel as are
+        the Qualify commands.  The test should also be immune to timing variances
+        since the test case doesn't issue the AMI commands until the sipp scenarios
+        are started.
+
+test-modules:
+    test-object:
+        config-section: sipp-config
+        typename: 'sipp.SIPpTestCase'
+    modules:
+        -
+            config-section: ami-config
+            typename: 'pluggable_modules.EventActionModule'
+
+sipp-config:
+    memcheck-delay-stop: 7
+    fail-on-any: True
+    test-iterations:
+        -
+            scenarios:
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.2', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.3', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.4', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.5', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.6', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+                - { 'key-args': {'scenario': 'single_realm_single_digest_options.xml', '-i': '127.0.0.7', '-p': '5060' },
+                    'ordered-args': ['-nd', '-bind_local'] }
+
+ami-config:
+    -
+        ami-start:
+        ami-actions:
+            - { action: { Action: 'PJSIPQualify', ActionID: '12342', Endpoint: 'sipp2' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12343', Endpoint: 'sipp3' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12344', Endpoint: 'sipp4' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12345', Endpoint: 'sipp5' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12346', Endpoint: 'sipp6' } }
+            - { action: { Action: 'PJSIPQualify', ActionID: '12347', Endpoint: 'sipp7' } }
+
+properties:
+    dependencies:
+        - sipp :
+            version : 'v3.0'
+        - asterisk : 'res_pjsip'
+        - asterisk : 'res_pjsip_outbound_registration'
+        - asterisk : 'res_pjsip_outbound_authenticator_digest'
+    tags:
+        - pjsip
diff --git a/tests/channels/pjsip/auth/uac/tests.yaml b/tests/channels/pjsip/auth/uac/tests.yaml
new file mode 100644
index 0000000..3a6b8be
--- /dev/null
+++ b/tests/channels/pjsip/auth/uac/tests.yaml
@@ -0,0 +1,5 @@
+tests:
+    - test: 'single_realm_single_digest'
+    - test: 'single_realm_multiple_digest'
+    - test: 'multiple_realm_multiple_digest'
+    
\ No newline at end of file

-- 
To view, visit https://gerrit.asterisk.org/c/testsuite/+/15902
To unsubscribe, or for help writing mail filters, visit https://gerrit.asterisk.org/settings

Gerrit-Project: testsuite
Gerrit-Branch: 18
Gerrit-Change-Id: I64d8ca768cf7a2c55ca4a256ec37bf4c712b4004
Gerrit-Change-Number: 15902
Gerrit-PatchSet: 3
Gerrit-Owner: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Friendly Automation
Gerrit-Reviewer: George Joseph <gjoseph at digium.com>
Gerrit-Reviewer: Joshua Colp <jcolp at sangoma.com>
Gerrit-Reviewer: Kevin Harwell <kharwell at digium.com>
Gerrit-MessageType: merged
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <http://lists.digium.com/pipermail/asterisk-code-review/attachments/20210521/5d797c67/attachment-0001.html>


More information about the asterisk-code-review mailing list