[Freeswitch-svn] [commit] r2861 - freeswitch/trunk/src/mod/endpoints/mod_sofia

Freeswitch SVN anthm at freeswitch.org
Thu Sep 28 21:07:52 EDT 2006


Author: anthm
Date: Thu Sep 28 21:07:51 2006
New Revision: 2861

Modified:
   freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c

Log:
more auth

Modified: freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c
==============================================================================
--- freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	(original)
+++ freeswitch/trunk/src/mod/endpoints/mod_sofia/mod_sofia.c	Thu Sep 28 21:07:51 2006
@@ -101,6 +101,10 @@
 typedef struct sip_alias_node sip_alias_node_t;
 
 typedef enum {
+	PFLAG_AUTH_CALLS = (1 << 0),
+} PFLAGS;
+
+typedef enum {
 	TFLAG_IO = (1 << 0),
 	TFLAG_INBOUND = (1 << 1),
 	TFLAG_OUTBOUND = (1 << 2),
@@ -149,6 +153,7 @@
 	int codec_ms;
 	int dtmf_duration;
 	unsigned int flags;
+	unsigned int pflags;
 	uint32_t max_calls;
 	nua_t *nua;
 	switch_memory_pool_t *pool;
@@ -1343,9 +1348,13 @@
 	if ((host = strchr(dest, '%'))) {
 		char buf[128];
 		*host++ = '\0';
-		find_reg_url(profile, dest, host, buf, sizeof(buf));
-		tech_pvt->dest = switch_core_session_strdup(nsession, buf);
-		dest = tech_pvt->dest + 4;
+		if (find_reg_url(profile, dest, host, buf, sizeof(buf))) {
+			tech_pvt->dest = switch_core_session_strdup(nsession, buf);
+			dest = tech_pvt->dest + 4;
+		} else {
+			terminate_session(&nsession, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+			goto done;
+		}
 	} else {
 		tech_pvt->dest = switch_core_session_alloc(nsession, strlen(dest) + 5);
 		snprintf(tech_pvt->dest, strlen(dest) + 5, "sip:%s", dest);
@@ -1655,70 +1664,7 @@
 
 }
 
-static void sip_i_invite(nua_t *nua, 
-						 sofia_profile_t *profile,
-						 nua_handle_t *nh, 
-						 switch_core_session_t *session, 
-						 sip_t const *sip,
-						 tagi_t tags[])
-{
 
-	
-	if (!session) {
-		if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
-			private_object_t *tech_pvt = NULL;
-			switch_channel_t *channel = NULL;
-			sip_from_t const *from = sip->sip_from;
-			sip_to_t const *to = sip->sip_to;
-			char *displayname;
-			char username[256];
-
-
-			if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
-				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
-				terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
-				return;
-			}
-
-			displayname = switch_core_session_strdup(session, (char *) from->a_display);
-			if (*displayname == '"') {
-				char *p;
-				
-				displayname++;
-				if ((p = strchr(displayname, '"'))) {
-					*p = '\0';
-				}
-			}
-			
-			snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
-			attach_private(session, profile, tech_pvt, username);
-
-			snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
-			tech_pvt->contact = sip_contact_create(tech_pvt->home, URL_STRING_MAKE(username), NULL);
-			
-			channel = switch_core_session_get_channel(session);
-			switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
-			
-			if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
-																	  (char *) from->a_url->url_user,
-																	  profile->dialplan,
-																	  displayname,
-																	  (char *) from->a_url->url_user,
-																	  (char *) from->a_url->url_host,
-																	  NULL,
-																	  NULL,
-																	  NULL,
-																	  (char *)modname,
-																	  profile->context,
-																	  (char *) to->a_url->url_user)) != 0) {
-				switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
-			}
-			switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
-			nua_handle_bind(nh, session);
-		}
-	}
-}
-
 static char *get_auth_data(char *dbname, char *nonce, char *npassword, uint32_t len, switch_mutex_t *mutex)
 {
 	switch_core_db_t *db;
@@ -1780,12 +1726,18 @@
 	return ret;
 }
 
-static void sip_i_register(nua_t *nua,
-						   sofia_profile_t *profile,
-						   nua_handle_t *nh,
-						   switch_core_session_t *session,
-						   sip_t const *sip,
-						   tagi_t tags[])
+
+typedef enum {
+	REG_REGISTER,
+	REG_INVITE
+} sofia_regtype_t;
+
+static uint8_t handle_register(nua_t *nua,
+							   sofia_profile_t *profile,
+							   nua_handle_t *nh,
+							   switch_core_session_t *session,
+							   sip_t const *sip,
+							   sofia_regtype_t regtype)
 {
 	sip_from_t const *from = sip->sip_from;
 	sip_expires_t const *expires = sip->sip_expires;
@@ -1801,9 +1753,15 @@
 	char *contact_user = (char *) contact->m_url->url_user;
 	char *contact_host = (char *) contact->m_url->url_host;
 	char buf[512];
-	char *passwd;
-	uint8_t ok = 0, stale = 0;
+	char *passwd = NULL;
+	uint8_t ok = 0, stale = 0, ret = 0;
+	long exptime = expires ? expires->ex_delta : 60;
 
+	if (regtype == REG_REGISTER) {
+		authorization = sip->sip_authorization;
+	} else if (regtype == REG_INVITE) {
+		authorization = sip->sip_proxy_authorization;
+	}
 	
 	if (authorization) {
 		int index;
@@ -1811,7 +1769,6 @@
 		char npassword[512] = "";
 		char *nonce, *uri, *qop, *cnonce, *nc, *input, *response;
 		nonce = uri = qop = cnonce = nc = response = NULL;
-
 		for(index = 0; (cur=(char*)authorization->au_params[index]); index++) {
 			char *var, *val, *p, *work; 
 			var = val = work = NULL;
@@ -1845,13 +1802,21 @@
 			}
 		}
 
-		
 		if (get_auth_data(profile->dbname, nonce, npassword, sizeof(npassword), profile->reg_mutex)) {
 			su_md5_t ctx;
 			char uridigest[2 * SU_MD5_DIGEST_SIZE + 1];
 			char bigdigest[2 * SU_MD5_DIGEST_SIZE + 1];
+			char *regstr;
 
-			input = switch_core_db_mprintf("REGISTER:%q", uri);
+			if (regtype == REG_REGISTER) {
+				regstr = "REGISTER";
+			} else if (regtype == REG_INVITE) {
+				regstr = "INVITE";
+			} else {
+				regstr = "WTF";
+			}
+
+			input = switch_core_db_mprintf("%s:%q", regstr, uri);
 			su_md5_init(&ctx);
 			su_md5_strupdate(&ctx, input);
 			su_md5_hexdigest(&ctx, uridigest);
@@ -1884,7 +1849,7 @@
 
 		if (!ok && !stale) {
 			nua_respond(nh, SIP_401_UNAUTHORIZED, TAG_END());
-			return;
+			return 1;
 		}
 	} 
 
@@ -1896,17 +1861,18 @@
 				 contact_host 
 				 );
 
-
-		if (switch_xml_locate("directory", "domain", "name", (char *)from->a_url->url_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
+		
+		if (switch_xml_locate("directory", "domain", "name", from_host, &xml, &domain, params) != SWITCH_STATUS_SUCCESS) {
 			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_ERROR, "open of directory failed\n");
 			nua_respond(nh, SIP_401_UNAUTHORIZED, SIPTAG_CONTACT(contact), TAG_END());
-			return;
+			return 1;
 		}
 
 		if (!(user = switch_xml_find_child(domain, "user", "id", from_user))) {
+			switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_WARNING, "can't find user [%s@%s]\n", from_user, from_host);
 			nua_respond(nh, SIP_401_UNAUTHORIZED, SIPTAG_CONTACT(contact), TAG_END());
 			switch_xml_free(xml);
-			return;
+			return 1;
 		}
 	
 
@@ -1919,7 +1885,6 @@
 			if (!strcasecmp(var, "password")) {
 				passwd = val;
 			}
-	
 		}
 	
 		if (passwd) {
@@ -1954,16 +1919,30 @@
 											  stale ? " stale=\"true\"," : "");
 
 
-			nua_respond(nh, SIP_401_UNAUTHORIZED,
-						SIPTAG_WWW_AUTHENTICATE_STR(auth_str),
-						TAG_END());
+			if (regtype == REG_REGISTER) {
+				nua_respond(nh, SIP_401_UNAUTHORIZED,
+							SIPTAG_WWW_AUTHENTICATE_STR(auth_str),
+							TAG_END());
+			} else if (regtype == REG_INVITE) {
+				nua_respond(nh, SIP_407_PROXY_AUTH_REQUIRED,
+							SIPTAG_PROXY_AUTHENTICATE_STR(auth_str),
+							TAG_END());
 
+			}
+
 			execute_sql(profile->dbname, sql, profile->reg_mutex);
 			switch_core_db_free(sql);
 			switch_core_db_free(auth_str);
+			ret = 1;
+		} else {
+			ret = 0;
 		}
+		
 		switch_xml_free(xml);
-		return;
+
+		if (ret) {
+			return ret;
+		}
 	}
 
 	if (!find_reg_url(profile, from_user, from_host, buf, sizeof(buf))) {
@@ -1972,24 +1951,26 @@
 									 from_host,
 									 contact_user,
 									 contact_host,
-									 (long) time(NULL) + (long)expires->ex_delta);
+									 (long) time(NULL) + (long)exptime);
+
 	} else {
 		sql = switch_core_db_mprintf("update sip_registrations set contact='sip:%q@%q', expires=%ld where user='%q' and host='%q'",
 									 contact_user,
                                      contact_host,
-									 (long) time(NULL) + (long)expires->ex_delta,
+									 (long) time(NULL) + (long)exptime,
 									 from_user,
 									 from_host);
 		
 	}
-	
+
+			
 	if (switch_event_create_subclass(&s_event, SWITCH_EVENT_CUSTOM, MY_EVENT_REGISTER) == SWITCH_STATUS_SUCCESS) {
 		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "profile-name", "%s", profile->name);
 		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-user", "%s", from_user);
 		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "from-host", "%s", from_host);
 		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-user", "%s", contact_user);
 		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "contact-host", "%s", contact_host);
-		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)expires->ex_delta);
+		switch_event_add_header(s_event, SWITCH_STACK_BOTTOM, "expires", "%ld", (long)exptime);
 		switch_event_fire(&s_event);
 	}
 
@@ -1999,20 +1980,106 @@
 		sql = NULL;
 	}
 	
-
-
-	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Got a Register from [%s@%s] contact [%s@%s] expires %ld\n", 
+	switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_DEBUG, "Register from [%s@%s] contact [%s@%s] expires %ld\n", 
 					  from_user, 
 					  from_host,
 					  contact_user,
 					  contact_host,
-					  (long)expires->ex_delta
+					  (long)exptime
 					  );
 
+	if (regtype == REG_REGISTER) {
+		nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact), TAG_END());
+		return 1;
+	}
 
-	nua_respond(nh, SIP_200_OK, SIPTAG_CONTACT(contact), TAG_END());
+	return 0;
 }
 
+
+
+static void sip_i_invite(nua_t *nua, 
+						 sofia_profile_t *profile,
+						 nua_handle_t *nh, 
+						 switch_core_session_t *session, 
+						 sip_t const *sip,
+						 tagi_t tags[])
+{
+
+
+	if (!session) {
+
+		if ((profile->pflags & PFLAG_AUTH_CALLS)) {
+			if (handle_register(nua, profile, nh, session, sip, REG_INVITE)) {
+				return;
+			}
+		}
+
+
+		if ((session = switch_core_session_request(&sofia_endpoint_interface, NULL))) {
+			private_object_t *tech_pvt = NULL;
+			switch_channel_t *channel = NULL;
+			sip_from_t const *from = sip->sip_from;
+			sip_to_t const *to = sip->sip_to;
+			char *displayname;
+			char username[256];
+
+
+			if (!(tech_pvt = (private_object_t *) switch_core_session_alloc(session, sizeof(private_object_t)))) {
+				switch_log_printf(SWITCH_CHANNEL_LOG, SWITCH_LOG_CRIT, "Hey where is my memory pool?\n");
+				terminate_session(&session, SWITCH_CAUSE_DESTINATION_OUT_OF_ORDER, __LINE__);
+				return;
+			}
+
+			displayname = switch_core_session_strdup(session, (char *) from->a_display);
+			if (*displayname == '"') {
+				char *p;
+				
+				displayname++;
+				if ((p = strchr(displayname, '"'))) {
+					*p = '\0';
+				}
+			}
+			
+			snprintf(username, sizeof(username), "%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
+			attach_private(session, profile, tech_pvt, username);
+
+			snprintf(username, sizeof(username), "sip:%s@%s", (char *) from->a_url->url_user, (char *) from->a_url->url_host);
+			tech_pvt->contact = sip_contact_create(tech_pvt->home, URL_STRING_MAKE(username), NULL);
+			
+			channel = switch_core_session_get_channel(session);
+			switch_channel_set_variable(channel, "endpoint_disposition", "INBOUND CALL");
+			
+			if ((tech_pvt->caller_profile = switch_caller_profile_new(switch_core_session_get_pool(session),
+																	  (char *) from->a_url->url_user,
+																	  profile->dialplan,
+																	  displayname,
+																	  (char *) from->a_url->url_user,
+																	  (char *) from->a_url->url_host,
+																	  NULL,
+																	  NULL,
+																	  NULL,
+																	  (char *)modname,
+																	  profile->context,
+																	  (char *) to->a_url->url_user)) != 0) {
+				switch_channel_set_caller_profile(channel, tech_pvt->caller_profile);
+			}
+			switch_set_flag_locked(tech_pvt, TFLAG_INBOUND);
+			nua_handle_bind(nh, session);
+		}
+	}
+}
+
+static void sip_i_register(nua_t *nua,
+						   sofia_profile_t *profile,
+						   nua_handle_t *nh,
+						   switch_core_session_t *session,
+						   sip_t const *sip,
+						   tagi_t tags[])
+{
+	handle_register(nua, profile, nh, session, sip, REG_REGISTER);
+}
+
 static void event_callback(nua_event_t   event,
 						   int           status,
 						   char const   *phrase,
@@ -2179,6 +2246,7 @@
 				   NUTAG_EARLY_MEDIA(1),				   
 				   NUTAG_AUTOANSWER(0),
 				   NUTAG_AUTOALERT(0),
+				   //NUTAG_AUTOTRYING(0),
 				   NUTAG_ALLOW("REGISTER"),
 				   SIPTAG_SUPPORTED_STR("100rel, precondition"),
 				   TAG_END());
@@ -2194,9 +2262,10 @@
 		nua_set_params(node->nua,
 					   NUTAG_EARLY_MEDIA(1),
 					   NUTAG_AUTOANSWER(0),
+					   NUTAG_AUTOALERT(0),
+					   //NUTAG_AUTOTRYING(0),
 					   NUTAG_ALLOW("REGISTER"),
 					   SIPTAG_SUPPORTED_STR("100rel, precondition"),
-					   NUTAG_AUTOALERT(0),
 					   TAG_END());
 		
 	}
@@ -2331,6 +2400,10 @@
 				profile->sipdomain = switch_core_strdup(profile->pool, val);
 			} else if (!strcmp(var, "rtp-timer-name")) {
 				profile->timer_name = switch_core_strdup(profile->pool, val);
+			} else if (!strcmp(var, "auth-calls")) {
+				if (switch_true(val)) {
+					profile->pflags |= PFLAG_AUTH_CALLS;
+				}
 			} else if (!strcmp(var, "ext-sip-ip")) {
 				profile->extsipip = switch_core_strdup(profile->pool, val);
 			} else if (!strcmp(var, "bitpacking")) {



More information about the Freeswitch-svn mailing list