>From 64aaf8ac60e50e1ad2ed219e83e4b070890c7f92 Mon Sep 17 00:00:00 2001
From: Rob Day <rkd@rkd.me.uk>
Date: Sat, 28 Dec 2013 20:44:00 +0000
Subject: [PATCH 4/4] Updated example S-CSCF config with working authentication

---
 examples/scscf/kamailio.cfg | 123 ++++++++++++++++++++++++++------------------
 1 file changed, 74 insertions(+), 49 deletions(-)

diff --git a/examples/scscf/kamailio.cfg b/examples/scscf/kamailio.cfg
index 4fa09b0..93b10e0 100644
--- a/examples/scscf/kamailio.cfg
+++ b/examples/scscf/kamailio.cfg
@@ -44,7 +44,7 @@ log_stderror=no
 sip_warning=no
 #!endif
 
-/* uncomment and configure the following line if you want Kamailio to 
+/* uncomment and configure the following line if you want Kamailio to
    bind on a specific interface/port/proto (default bind on all available) */
 #!ifdef NETWORK_INTERFACE
 listen=NETWORK_INTERFACE
@@ -123,7 +123,7 @@ loadmodule "cdp_avp.so"
 loadmodule "ims_diameter_ro.so"
 #!endif
 
-loadmodule "ims_usrloc_scscf.so" 
+loadmodule "ims_usrloc_scscf.so"
 loadmodule "ims_registrar_scscf.so"
 loadmodule "ims_auth.so"
 loadmodule "ims_isc.so"
@@ -223,7 +223,7 @@ modparam("siptrace", "hep_mode_on", 1)
 # -- ims_auth params --
 modparam("ims_auth", "name", URI)
 modparam("ims_auth", "registration_default_algorithm", REG_AUTH_DEFAULT_ALG)
-modparam("ims_auth","ignore_failed_auth",1)
+modparam("ims_auth","ignore_failed_auth",0)
 #!ifdef CXDX_FORCED_PEER
 modparam("ims_auth", "cxdx_forced_peer", CXDX_FORCED_PEER)
 #!endif
@@ -304,7 +304,7 @@ route {
 		route(subscribe);
 		break;
         }
-	
+
 	#Set DLG flag to track dialogs using dialog2
 	if (!is_method("REGISTER|SUBSCRIBE"))
 		setflag(FLT_DIALOG);
@@ -324,13 +324,13 @@ route {
 
 		# Originating
 		route(orig);
-    		break;                          
+    		break;
 	} else {
 		isc_from_as("term");
 		if ($retcode == -2) {
 			# Treat as originating, since it was retargeted:
 			route(orig);
-	    		break;                          
+	    		break;
 		}
 		if ((is_in_profile("orig") || has_totag()) && ($route_uri =~ "sip:mo@"+".*")) {
 			route(orig_subsequent);
@@ -363,7 +363,7 @@ route {
 route[REQINIT] {
 	# Trace this message
 #!ifdef CAPTURE_NODE
-	sip_trace();	
+	sip_trace();
 	setflag(FLT_CAPTURE);
 #!endif
 
@@ -387,8 +387,8 @@ route[REQINIT] {
 	if (is_method("OPTIONS") && (uri==myself)) {
 		options_reply();
 		exit;
-	}	
-	
+	}
+
 	# Ignore Re-Transmits:
 	if (t_lookup_request()) {
 		exit;
@@ -430,32 +430,57 @@ route[XMLRPC] {
 # Route for handling Registrations:
 ######################################################################
 route[REGISTER] {
-	xlog("L_ERR", "Enter register block");
-	t_newtran();
-	
-	ims_www_authenticate(NETWORKNAME);
-
-	#check to see if user is authenticated - ie sip header has auth information - (already challenged)
-	if ($avp(maa_return_code) == 1) {
-		# user has not been authenticated. Lets send a challenge via 401 Unauthorized
-		ims_www_challenge("$td"); 
-		exit;
-	} else {
-		# We need to check if this user is registered or not
-		if (!impu_registered("location")) {
-			save("location");
-			if ($avp(saa_return_code) == 1) {
-				isc_match_filter_reg("0","location");
-				exit;
-			}
-		} else {
-			save("location");
-			if($avp(saa_return_code) == 1) {
-				isc_match_filter_reg("1","location");
-				exit;
-			}
-		}
-	}
+        xlog("L_DBG", "Enter register block");
+        if (!t_newtran()) {    #absorb retransmissions
+                sl_reply("500","Could not create transaction");
+                exit;
+        }
+        if (!ims_www_authenticate(NETWORKNAME)) {
+                if ($? == -2) {
+                        t_reply("403", "Authentication Failed");
+                        exit;
+                } else if ($? == -3) {
+                        t_reply("400", "Bad Request");
+                        exit;
+                } else {
+                        #user has not been authenticated. Lets send a challenge via 401 Unauthorized
+                        xlog("L_DBG","About to challenge! auth_ims\n");
+                        ims_www_challenge("$td");
+                        #this is async so to know status we have to check the reply avp
+                        xlog("L_DBG","maa_return code is $avp(s:maa_return_code)\n");
+
+                        switch ($avp(s:maa_return_code)){
+                                case 1: #success
+                                        xlog("L_DBG", "MAR success - 401/407 response sent from module");
+                                        break;
+                                case -1: #failure
+                                        xlog("L_ERR", "MAR failure - error response sent from module");
+                                        break;
+                                case -2: #error
+                                        xlog("L_ERR", "MAR error - sending error response now");
+                                        t_reply("500", "MAR failed");
+                                        break;
+                                default:
+                                        xlog("L_ERR", "Unknown return code from MAR, value is [$avp(s:uaa_return_code)]");
+                                        t_reply("500", "Unknown response code from MAR");
+                                        break;
+                        }
+                        exit;
+                }
+        } else {
+                xlog("L_DBG", "Auth succeeded\n");
+                # We need to check if this user is registered or not
+                if (!impu_registered("location")) {
+                        xlog("L_DBG", "Not REGISTERED\n");
+                        isc_match_filter_reg("0","location");
+                        save("location");
+                        exit;
+                } else {
+                        isc_match_filter_reg("1","location");
+                        save("location");
+                        exit;
+                }
+        }
 }
 
 ######################################################################
@@ -483,7 +508,7 @@ route[orig]
 	# }
 	if (is_method("INVITE|SUBSCRIBE")) {
 		$avp(RR_CUSTOM_USER_AVP)="mo";
-        	record_route();    
+        	record_route();
 	}
 
 #!ifdef WITH_RO
@@ -496,12 +521,12 @@ route[orig]
 			sl_send_reply("402","Payment required");
 			exit;
 		}
-		xlog("L_DBG","CCR Request success\n");    
+		xlog("L_DBG","CCR Request success\n");
 	}
 #!endif
 	# check if dialog saved as fwded to AS
 	if (isc_match_filter("orig", "location")) {
-		t_on_failure("isc_orig_failure");       
+		t_on_failure("isc_orig_failure");
 		xlog("Orig - msg was fwded to AS\n");
 		exit;
 	}
@@ -513,7 +538,7 @@ route[orig]
 
 	# Check for PSTN destinations:
 	if (is_method("INVITE")) {
-		route(PSTN_handling);	
+		route(PSTN_handling);
 	}
 
 	t_on_reply("orig_reply");
@@ -550,7 +575,7 @@ onreply_route[orig_reply]
 route[orig_subsequent]
 {
 	xlog("L_DBG","Orig_Subsequent\n");
-	
+
 	if (!is_method("ACK")) {
 		t_on_reply("orig_subsequent_reply");
 	}
@@ -572,10 +597,10 @@ onreply_route[orig_subsequent_reply]
 ######################################################################
 failure_route[isc_orig_failure]
 {
-	xlog("L_DBG","ISC_Orig_failure\n");     
+	xlog("L_DBG","ISC_Orig_failure\n");
 
 	if (t_check_status("(408)|(5..)")){
-		t_on_failure("isc_orig_failure");   
+		t_on_failure("isc_orig_failure");
 		if (isc_match_filter("orig","location")){
 			xlog("L_DBG","ISC_Orig_failure - msg was fwded to AS\n");
 			exit;
@@ -610,7 +635,7 @@ route[term]
 	if (is_method("INVITE|SUBSCRIBE")) {
 		$avp(RR_CUSTOM_USER_AVP)="mt";
 		$avp(i:20)="mt";
-		record_route();    
+		record_route();
 	}
 
 	# check if dialog saved as fwded to AS
@@ -625,7 +650,7 @@ route[term]
 			if (!t_newtran()) {
 				sl_reply_error();
 				exit;
-			}                              
+			}
 			t_reply("404","Not Found - destination user not found on this S-CSCF");
 			exit;
 		}
@@ -634,7 +659,7 @@ route[term]
 		if (!t_newtran()) {
 			sl_reply_error();
 			exit;
-		}                              
+		}
 		t_reply("404","Not Found - destination user not found on this S-CSCF");
 		exit;
 	}
@@ -652,9 +677,9 @@ failure_route[isc_term_failure]
 	xlog("L_DBG","ISC_term_failure\n");
 
 	if (t_check_status("(408)|(5..)")){
-		t_on_failure("isc_term_failure");       
+		t_on_failure("isc_term_failure");
 		if (isc_match_filter("term","location")){
-			xlog("L_DBG","Term - msg was fwded to AS\n");    
+			xlog("L_DBG","Term - msg was fwded to AS\n");
 			exit;
 		}
 
@@ -698,7 +723,7 @@ route[PSTN_handling]
 	if ($rU =~ "[0-9]+") {
 		if (dp_translate("1")) {
 			xlog("L_INFO", "R-URI rewritten to $rU - M=$rm R=$ru F=$fu T=$tu IP=$si:$sp ID=$ci\n");
-		}			
+		}
 	}
 #!endif
 	if ($rU =~ "\+[0-9]+") {
@@ -736,7 +761,7 @@ failure_route[PSTN_failure] {
 	# - receive a 5xx or 6xx reply from the proxy.
 	if (t_branch_timeout() || t_check_status("[5-6]..")) {
 		if (ds_next_dst()) {
-			# Do Failover in case problems:		
+			# Do Failover in case problems:
 			t_on_failure("PSTN_failure");
 			t_relay();
 		} else {
-- 
1.8.3.2

