Re: problem with Kerberose and TDS 7.2

Frediano Ziglio <[email protected]>
Newsgroups gmane.comp.db.tds.freetds
Message-ID <[email protected]>
2011/5/7 Frediano Ziglio <[email protected]>:
> Il giorno ven, 06/05/2011 alle 18.41 -0400, [email protected] ha
> scritto:
>> Using bsqlodbc and TDS 7.2 with Kerberos, I get a protocol error.  Dropping to
>> 7.1 works, as does using a non-kerberos login:
>>
>> $ TDSVER=7.2 TDSDUMP=dump  bsqlodbc -S $S -v <<< "select cast('1 mar 2011' as date) as march" || less -S dump
>> bsqlodbc:273: Verbose operation enabled
>> bsqlodbc: error -1: SQLConnect: SQL_ERROR: failed
>> bsqlodbc: error 20020: 08S01: [unixODBC][FreeTDS][SQL Server]Bad token from the server: Datastream processing out of sync
>> "[unixODBC][FreeTDS][SQL Server]Unable to connect to data source"
>>
>> Start of dump:
>>
>> log.c:196:Starting log file for FreeTDS 0.83.dev.20110103
>>         on 2011-05-06 18:34:25 with debug flags 0x4fff.
>> iconv.c:330:tds_iconv_open(0x1914a440, UTF-8)
>> iconv.c:187:local name for ISO-8859-1 is ISO-8859-1
>> iconv.c:187:local name for UTF-8 is UTF-8
>> iconv.c:187:local name for UCS-2LE is UCS-2LE
>> iconv.c:187:local name for UCS-2BE is UCS-2BE
>> iconv.c:349:setting up conversions for client charset "UTF-8"
>> iconv.c:351:preparing iconv for "UTF-8" <-> "UCS-2LE" conversion
>> iconv.c:391:preparing iconv for "ISO-8859-1" <-> "UCS-2LE" conversion
>> iconv.c:394:tds_iconv_open: done
>> net.c:205:Connecting to xx.xx.xx.xx port xxx (TDS version 7.2)
>> net.c:270:tds_open_socket: connect(2) returned "Operation now in progress"
>> net.c:310:tds_open_socket() succeeded
>> util.c:156:Changed query state from DEAD to IDLE
>> net.c:741:Sending packet
>> 0000 12 01 00 3a 00 00 00 00-00 00 1a 00 06 01 00 20 |...:.... ....... |
>> 0010 00 01 02 00 21 00 0c 03-00 2d 00 04 04 00 31 00 |....!... .-....1.|
>> 0020 01 ff 09 00 00 00 00 00-02 4d 53 53 51 4c 53 65 |........ .MSSQLSe|
>> 0030 72 76 65 72 00 d8 06 00-00 00                   |rver.... ..|
>>
>> net.c:555:Received header
>> 0000 04 01 00 2b 00 00 01 00-                        |...+....|
>>
>> net.c:609:Received packet
>> 0000 04 01 00 2b 00 00 01 00-00 00 1a 00 06 01 00 20 |...+.... ....... |
>> 0010 00 01 02 00 21 00 01 03-00 22 00 00 04 00 22 00 |....!... ."....".|
>> 0020 01 ff 0a 32 06 40 00 00-02 00 00                |...2.@.. ...|
>>
>> login.c:1051:detected flag 2
>> gssapi.c:172:kerberos name MSSQLSvc/[deleted...]
>> login.c:776:quietly sending TDS 7+ login packet
>> token.c:328:tds_process_login_tokens()
>> net.c:555:Received header
>> 0000 04 01 00 91 00 00 01 00-                        |........|
>>
>> net.c:609:Received packet
>> 0000 04 01 00 91 00 00 01 00-ed 86 00 60 81 83 06 09 |........ ...`....|
>> 0010 2a 86 48 86 f7 12 01 02-02 02 00 6f 74 30 72 a0 |*.H..... ...ot0r.|
>> 0020 03 02 01 05 a1 03 02 01-0f a2 66 30 64 a0 03 02 |........ ..f0d...|
>> 0030 01 17 a2 5d 04 5b 4f 9d-cc 42 98 44 53 4f e4 b9 |...].[O. .B.DSO..|
>> 0040 1f 72 6f 69 16 58 88 1e-bc 2a 54 ca a5 0d eb d3 |.roi.X.. .*T.....|
>> 0050 1c 47 70 cb de 79 3c 54-84 6e 6f 37 d2 5e fc dc |.Gp..y<T .no7.^..|
>> 0060 b3 d5 5f 82 dc 06 13 2a-73 1e 22 6c 70 78 26 11 |.._....* s."lpx&.|
>> 0070 81 7b 31 9a cd 49 35 39-dd 25 84 0c 81 4a 41 9e |.{1..I59 .%...JA.|
>> 0080 b2 a4 28 ce 20 c3 3f d4-23 87 7d de 22 87 cd 24 |..(. .?. #.}."..$|
>> 0090 31                     -                        |1|
>>
>> token.c:337:looking for login token, got  ed(AUTH)
>> token.c:456:TDS_AUTH_TOKEN PDU size 134
>> token.c:337:looking for login token, got  60()
>> token.c:122:tds_process_default_tokens() marker is 60()
>> util.c:156:Changed query state from IDLE to DEAD
>> util.c:331:tdserror(0x19149060, 0x1914a440, 20020, 0)
>> odbc.c:2271:msgno 20020 20003
>> util.c:361:tdserror: client library returned TDS_INT_CANCEL(2)
>> util.c:384:tdserror: returning TDS_INT_CANCEL(2)
>> token.c:256:Unknown marker: 96(60)!!
>> login.c:460:login packet accepted
>> == end ==
>>
>> Well, not exactly *accepted*.
>>
>
> I see two problems. In gssapi.c tds_gss_handle_next is not expected to
> receive authentication so it returns fail. In token.c,
> tds_process_login_tokens fail for tds_process_auth is ignored leading to
> protocol mismatch. To solve second just remove TDS_AUTH_TOKEN case in
> tds_process_login_tokens. The first... I don't know, I note in gssapi.c
> that there are some lines commented out
>
> /*
>        if (maj_stat == GSS_S_CONTINUE_NEEDED) {
>                if (recv_token(s, &token_flags, &recv_tok) < 0) {
>                        (void) gss_release_name(&min_stat,
> &target_name);
>                        return -1;
>                }
>                token_ptr = &recv_tok;
>        }
> */
>
> Probably recv_token would read our authentication token !!
>
> freddy77
>

Mumble... but is Kerberose the romantic version of Kerberos ?? :)

Try this patch ;-)

bye
  freddy77

_______________________________________________
FreeTDS mailing list
[email protected]
http://lists.ibiblio.org/mailman/listinfo/freetds
kerberos.diff (application/octet-stream, 4.8 KB)
Index: freetds92/src/tds/gssapi.c
===================================================================
--- freetds92.orig/src/tds/gssapi.c	2011-05-07 22:38:41.562516002 +0200
+++ freetds92/src/tds/gssapi.c	2011-05-07 22:38:41.582516002 +0200
@@ -86,6 +86,7 @@
 	gss_ctx_id_t gss_context;
 	gss_name_t target_name;
 	char *sname;
+	OM_uint32 last_stat;
 } TDSGSSAUTH;
 
 static int
@@ -111,10 +112,44 @@
 	return TDS_SUCCEED;
 }
 
+static int tds_gss_continue(TDSSOCKET * tds, struct tds_gss_auth *auth, gss_buffer_desc *token_ptr);
+
 static int
 tds_gss_handle_next(TDSSOCKET * tds, struct tds_authentication * auth, size_t len)
 {
-	return TDS_FAIL;
+	int res;
+	gss_buffer_desc recv_tok;
+
+	if (((struct tds_gss_auth *) auth)->last_stat != GSS_S_CONTINUE_NEEDED)
+		return TDS_FAIL;
+
+	if (auth->packet) {
+		OM_uint32 min_stat;
+		gss_buffer_desc send_tok;
+
+		send_tok.value = (void *) auth->packet;
+		send_tok.length = auth->packet_len;
+		gss_release_buffer(&min_stat, &send_tok);
+		auth->packet = NULL;
+	}
+
+	recv_tok.length = len;
+	recv_tok.value = (char* ) malloc(len);
+	if (!recv_tok.value)
+		return TDS_FAIL;
+	tds_get_n(tds, recv_tok.value, len);
+
+	res = tds_gss_continue(tds, (struct tds_gss_auth *) auth, &recv_tok);
+	free(recv_tok.value);
+	if (res != TDS_SUCCEED)
+		return TDS_FAIL;
+
+	if (auth->packet_len) {
+		tds->out_flag = TDS7_AUTH;
+		tds_put_n(tds, auth->packet, auth->packet_len);
+		return tds_flush_packet(tds);
+	}
+	return TDS_SUCCEED;
 }
 
 /**
@@ -137,15 +172,13 @@
 	 * a bit more verbose
 	 * dinamically load library ??
 	 */
-	gss_buffer_desc send_tok, *token_ptr;
+	gss_buffer_desc send_tok;
 	OM_uint32 maj_stat, min_stat;
 	/* same as GSS_KRB5_NT_PRINCIPAL_NAME but do not require .so library */
 	static gss_OID_desc nt_principal = { 10, "\x2a\x86\x48\x86\xf7\x12\x01\x02\x02\x01" };
-	OM_uint32 ret_flags;
 	const char *server_name;
 	/* Storage for reentrant getaddrby* calls */
 	char buffer[4096];
-	int gssapi_flags;
 
 	struct tds_gss_auth *auth = (struct tds_gss_auth *) calloc(1, sizeof(struct tds_gss_auth));
 
@@ -154,6 +187,8 @@
 
 	auth->tds_auth.free = tds_gss_free;
 	auth->tds_auth.handle_next = tds_gss_handle_next;
+	auth->gss_context = GSS_C_NO_CONTEXT;
+	auth->last_stat = GSS_S_COMPLETE;
 
 	server_name = tds_dstr_cstr(&tds->connection->server_host_name);
 	if (strchr(server_name, '.') == NULL) {
@@ -178,11 +213,26 @@
 	send_tok.value = auth->sname;
 	send_tok.length = strlen(auth->sname);
 	maj_stat = gss_import_name(&min_stat, &send_tok, &nt_principal, &auth->target_name);
-	if (maj_stat != GSS_S_COMPLETE) {
+
+	if (maj_stat != GSS_S_COMPLETE
+	    || tds_gss_continue(tds, auth, GSS_C_NO_BUFFER) == TDS_FAIL) {
 		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
 		return NULL;
 	}
 
+	return (TDSAUTHENTICATION *) auth;
+}
+
+static int 
+tds_gss_continue(TDSSOCKET * tds, struct tds_gss_auth *auth, gss_buffer_desc *token_ptr)
+{
+	gss_buffer_desc send_tok;
+	OM_uint32 maj_stat, min_stat;
+	OM_uint32 ret_flags;
+	int gssapi_flags;
+
+	auth->last_stat = GSS_S_COMPLETE;
+
 	send_tok.value = NULL;
 	send_tok.length = 0;
 
@@ -202,9 +252,6 @@
 	 * and only if the server has another token to send us.
 	 */
 
-	token_ptr = GSS_C_NO_BUFFER;
-	auth->gss_context = GSS_C_NO_CONTEXT;
-
 	/* We may ask for delegation based on config in the tds.conf and other conf files */
 	/* We always want to ask for the mutual, replay, and integ flags */
 	gssapi_flags = GSS_C_MUTUAL_FLAG | GSS_C_REPLAY_FLAG | GSS_C_INTEG_FLAG;
@@ -219,25 +266,10 @@
 					token_ptr, NULL,	/* ignore mech type */
 					&send_tok, &ret_flags, NULL);	/* ignore time_rec */
 
-/*
-	if (token_ptr != GSS_C_NO_BUFFER)
-		free(recv_tok.value);
-*/
-
-/*
-	if (send_tok.length != 0) {
-		if (send_token(s, v1_format ? 0 : TOKEN_CONTEXT, &send_tok) < 0) {
-			(void) gss_release_buffer(&min_stat, &send_tok);
-			(void) gss_release_name(&min_stat, &target_name);
-			return -1;
-		}
-*/
-/*	(void) gss_release_buffer(&min_stat, &send_tok); */
-
+	auth->last_stat = maj_stat;
 	if (maj_stat != GSS_S_COMPLETE && maj_stat != GSS_S_CONTINUE_NEEDED) {
 		gss_release_buffer(&min_stat, &send_tok);
-		tds_gss_free(tds, (TDSAUTHENTICATION *) auth);
-		return NULL;
+		return TDS_FAIL;
 	}
 
 /*
@@ -252,7 +284,7 @@
 
 	auth->tds_auth.packet = (TDS_UCHAR *) send_tok.value;
 	auth->tds_auth.packet_len = send_tok.length;
-	return (TDSAUTHENTICATION *) auth;
+	return TDS_SUCCEED;
 }
 
 #endif
Index: freetds92/src/tds/token.c
===================================================================
--- freetds92.orig/src/tds/token.c	2011-05-07 22:38:41.582516002 +0200
+++ freetds92/src/tds/token.c	2011-05-07 22:38:41.582516002 +0200
@@ -337,9 +337,6 @@
 		tdsdump_log(TDS_DBG_FUNC, "looking for login token, got  %x(%s)\n", marker, tds_token_name(marker));
 
 		switch (marker) {
-		case TDS_AUTH_TOKEN:
-			tds_process_auth(tds);
-			break;
 		case TDS_LOGINACK_TOKEN:
 			/* TODO function */
 			tds->tds71rev1 = 0;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.