changeset 11424:e1ab173ef3b5

[gaim-migrate @ 13661] prefs for STUN adjustments for NTLM in SIP committer: Tailor Script <tailor@pidgin.im>
author Thomas Butter <tbutter>
date Fri, 02 Sep 2005 09:09:04 +0000
parents 202a3b3c5a88
children 54fa445aff32
files src/core.c src/gtkprefs.c src/network.c src/protocols/simple/simple.c src/protocols/simple/simple.h src/stun.c src/stun.h
diffstat 7 files changed, 86 insertions(+), 32 deletions(-) [+]
line wrap: on
line diff
--- a/src/core.c	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/core.c	Fri Sep 02 09:09:04 2005 +0000
@@ -39,6 +39,7 @@
 #include "signals.h"
 #include "sslconn.h"
 #include "status.h"
+#include "stun.h"
 #include "sound.h"
 
 #ifdef HAVE_DBUS
@@ -121,6 +122,7 @@
 	gaim_proxy_init();
 	gaim_sound_init();
 	gaim_ssl_init();
+	gaim_stun_init();
 	gaim_xfers_init();
 
 	if (ops != NULL && ops->ui_init != NULL)
--- a/src/gtkprefs.c	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/gtkprefs.c	Fri Sep 02 09:09:04 2005 +0000
@@ -1022,7 +1022,7 @@
 {
 	GtkWidget *ret;
 	GtkWidget *vbox, *hbox, *entry;
-	GtkWidget *table, *label, *auto_ip_checkbox, *ports_checkbox, *spin_button;
+	GtkWidget *table, *label, *auto_ip_checkbox, *ports_checkbox, *spin_button, *stun_server_entry;
 	GtkSizeGroup *sg;
 	GaimProxyInfo *proxy_info;
 
@@ -1033,6 +1033,7 @@
 
 	auto_ip_checkbox = gaim_gtk_prefs_checkbox(_("_Autodetect IP Address"),
 			"/core/network/auto_ip", vbox);
+	stun_server_entry = gaim_gtk_prefs_labeled_entry(vbox,_("STUN Server"), "/core/network/stun_server", NULL);
 
 	table = gtk_table_new(2, 1, FALSE);
 	gtk_container_set_border_width(GTK_CONTAINER(table), 5);
--- a/src/network.c	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/network.c	Fri Sep 02 09:09:04 2005 +0000
@@ -144,6 +144,7 @@
 {
   const char *ip = NULL;
   GaimUPnPControlInfo* controlInfo = NULL;
+	struct stun_nattype *stun;
 
 	/* Check if the user specified an IP manually */
 	if (!gaim_prefs_get_bool("/core/network/auto_ip")) {
@@ -152,6 +153,14 @@
 			return ip;
 	}
 
+	if (ip == NULL || *ip == '\0') {
+		/* Check if STUN discovery was already done */
+		stun = gaim_stun_discover(NULL);
+		if(stun && stun->status>1)
+			return stun->publicip;
+	}	
+
+
   /* attempt to get the ip from a NAT device */
   if ((controlInfo = gaim_upnp_discover()) != NULL) {
     ip = gaim_upnp_get_public_ip(controlInfo);
--- a/src/protocols/simple/simple.c	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/protocols/simple/simple.c	Fri Sep 02 09:09:04 2005 +0000
@@ -275,12 +275,13 @@
 	} else if(auth->type == 2) { /* NTLM */
 		if(auth->nc == 3) {
 			ret = gaim_ntlm_gen_type3(sip->username, sip->password, "gaim", sip->servername, auth->nonce);
-			tmp = g_strdup_printf("NTLM %s\r\n",ret);
+			tmp = g_strdup_printf("NTLM qop=\"auth\" realm=\"%s\" targetname=\"%s\" response=\"%s\"\r\n",auth->realm, auth->target, ret);
 			g_free(ret);
 			return tmp;
 		}
 		ret = gaim_ntlm_gen_type1("gaim", sip->servername);
-		tmp = g_strdup_printf("NTLM %s\r\n", ret);
+/*		tmp = g_strdup_printf("NTLM qop=\"auth\" realm=\"%s\" targetname=\"%s\" response=\"%s\"\r\n", auth->realm, auth->target, ret); */
+		tmp = g_strdup_printf("NTLM qop=\"auth\" realm=\"%s\" targetname=\"%s\" response=\"010000003134303017f6dcfb4531f92f\"\r\n", auth->realm, auth->target);
 		g_free(ret);
 		return tmp;
 	}
@@ -294,6 +295,8 @@
 
 static void fill_auth(struct simple_account_data *sip, gchar *hdr, struct sip_auth *auth) {
 	int i=0;
+	char *tmp;
+	char *tmp2;
 	if(!hdr) {
 		gaim_debug_error("simple", "fill_auth: hdr==NULL\n");
 		return;
@@ -303,6 +306,21 @@
 		gaim_debug_info("simple", "found NTLM\n");
 		auth->type = 2;
 		if(!auth->nonce && !auth->nc) {
+			gchar **parts = g_strsplit(hdr, " ", 0);
+			while(parts[i]) {
+				if(!strncmp(parts[i],"targetname",10)) {
+					auth->target = g_strndup(parts[i]+12,strlen(parts[i]+12)-1);
+				}
+				if(!strncmp(parts[i],"realm",5)) {
+					tmp = strstr(hdr, "realm=");
+					tmp += 7;
+					tmp2 = strchr(tmp, '"');
+					*tmp2 = 0;
+					auth->realm = g_strdup(tmp);
+					*tmp2 = '"';
+				}
+				i++;
+			}
 			auth->nc = 1;
 		}
 		if(!auth->nonce && auth->nc==2) {
--- a/src/protocols/simple/simple.h	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/protocols/simple/simple.h	Fri Sep 02 09:09:04 2005 +0000
@@ -52,6 +52,7 @@
 	int type; /* 1 = Digest / 2 = NTLM */
         gchar *nonce;
         gchar *realm;
+	gchar *target;
 	int nc;
         HASHHEX HA1;
 	int retries;
--- a/src/stun.c	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/stun.c	Fri Sep 02 09:09:04 2005 +0000
@@ -40,6 +40,7 @@
 
 #include "debug.h"
 #include "account.h"
+#include "dnssrv.h"
 #include "stun.h"
 #include "prefs.h"
 
@@ -171,31 +172,28 @@
 		nattype.type = 2;
 	}
 }
-	
-struct stun_nattype *gaim_stun_discover(StunCallback cb) {
+
+static void do_test1(struct srv_response *resp, int results, gpointer sdata) {
+	char *servername = (char*)sdata;
 	static struct stun_header data;
-	int ret = 0;
-	const char *ip = gaim_prefs_get_string("/core/network/stun_ip");
-	int port = gaim_prefs_get_int("/core/network/stun_port");
-
-	if(!ip || !port) {
-		nattype.status = 0;
-		if(cb) cb(&nattype);
-		return &nattype;
+	int port = 3478;
+	int ret;
+	struct hostent *host;
+	
+	if(results) {
+		servername = resp[0].hostname;
+		port = resp[0].port;
 	}
-	
-	if(nattype.status == 1) { /* currently discovering */
-		if(cb) callbacks = g_slist_append(callbacks, cb);
-		return NULL;
+	gaim_debug_info("stun", "got %d SRV responses, server: %s, port: %d\n", results, servername, port);
+	if(!host->h_addr_list) {
+		return;
 	}
-	if(nattype.status != -1) { /* already discovered */
-		if(cb) cb(&nattype);
-		return &nattype;
-	}
+	host = gethostbyname(servername);
+	
 	if((fd = socket(AF_INET, SOCK_DGRAM, 0)) < 0) {
 		nattype.status = 0;
-		if(cb) cb(&nattype);
-		return &nattype;
+		do_callbacks();
+		return;
 	}
 
 	addr.sin_family = AF_INET;
@@ -206,16 +204,14 @@
 	}
 	if( ret < 0 ) {
 		nattype.status = 0;
-		if(cb) cb(&nattype);
-		return &nattype;
+                do_callbacks();
+		return;
 	}
 	incb = gaim_input_add(fd, GAIM_INPUT_READ, reply_cb, NULL);
 	
-	if(port == 0 || ip == NULL || ip[0] == '\0') return NULL;
-	
 	addr.sin_family = AF_INET;
 	addr.sin_port = htons(port);
-	addr.sin_addr.s_addr = inet_addr(ip);
+	memcpy(&addr.sin_addr.s_addr,*(host->h_addr_list),4);
 
 	data.type = htons(0x0001);
 	data.len = 0;
@@ -226,13 +222,39 @@
 	
 	if( sendto(fd, &data, sizeof(struct stun_header), 0, (struct sockaddr *)&addr, sizeof(struct sockaddr_in)) < sizeof(struct stun_header)) {
 			nattype.status = 0;
-			if(cb) cb(&nattype);
-			return &nattype;
+	                do_callbacks();
+			return;
 	}
 	test = 1;
 	packet = &data;
 	packetsize = sizeof(struct stun_header);
-	if(cb) callbacks = g_slist_append(callbacks, cb);
 	timeout = gaim_timeout_add(500, (GSourceFunc)timeoutfunc, NULL);
-	return NULL;
+	g_free(resp);
 }
+
+struct stun_nattype *gaim_stun_discover(StunCallback cb) {
+	const char *servername = gaim_prefs_get_string("/core/network/stun_server");
+
+	gaim_debug_info("stun", "using server %s\n", servername);
+	if(nattype.status == 1) { /* currently discovering */
+		if(cb) callbacks = g_slist_append(callbacks, cb);
+		return NULL;
+	}
+	if(nattype.status != -1) { /* already discovered */
+		if(cb) cb(&nattype);
+		return &nattype;
+	}
+
+	if(!servername || (strlen(servername)<2)) {
+		nattype.status = 0;
+		if(cb) cb(&nattype);
+		return &nattype;
+	}
+	callbacks = g_slist_append(callbacks, cb);
+	gaim_srv_resolve("stun","udp",servername, do_test1, servername);
+	return &nattype;
+}
+
+void gaim_stun_init() {
+	gaim_prefs_add_string("/core/network/stun_server", "");
+}
--- a/src/stun.h	Fri Sep 02 06:57:54 2005 +0000
+++ b/src/stun.h	Fri Sep 02 09:09:04 2005 +0000
@@ -71,4 +71,5 @@
  */
 struct stun_nattype *gaim_stun_discover(StunCallback cb);
 
+void gaim_stun_init();
 #endif /* _GAIM_STUN_H_ */