[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]

rpms/elinks/devel elinks-0.11.1-negotiate.patch, NONE, 1.1 .cvsignore, 1.17, 1.18 elinks.spec, 1.34, 1.35 sources, 1.17, 1.18



Author: kzak

Update of /cvs/dist/rpms/elinks/devel
In directory cvs.devel.redhat.com:/tmp/cvs-serv14629

Modified Files:
	.cvsignore elinks.spec sources 
Added Files:
	elinks-0.11.1-negotiate.patch 
Log Message:
add negotiate-auth support

elinks-0.11.1-negotiate.patch:
 Makefile.config.in                 |    1 
 config.h.in                        |    3 
 configure.in                       |   24 +++
 src/protocol/http/Makefile         |    2 
 src/protocol/http/http.c           |   50 +++++--
 src/protocol/http/http_negotiate.c |  259 +++++++++++++++++++++++++++++++++++++
 src/protocol/http/http_negotiate.h |   16 ++
 src/util/base64.c                  |   36 ++++-
 src/util/base64.h                  |    3 
 9 files changed, 376 insertions(+), 18 deletions(-)

--- NEW FILE elinks-0.11.1-negotiate.patch ---
--- elinks-0.11.1/Makefile.config.in.negotiate	2006-01-29 14:10:33.000000000 +0100
+++ elinks-0.11.1/Makefile.config.in	2006-06-09 13:09:41.000000000 +0200
@@ -148,6 +148,7 @@
 CONFIG_WIN32 = @CONFIG_WIN32@
 CONFIG_XBEL_BOOKMARKS = @CONFIG_XBEL_BOOKMARKS@
 CONFIG_XMLTO = @CONFIG_XMLTO@
+CONFIG_GSSAPI = @CONFIG_GSSAPI@
 
 DEFS = @DEFS@
 CFLAGS = @CFLAGS@
--- elinks-0.11.1/config.h.in.negotiate	2006-01-29 14:10:46.000000000 +0100
+++ elinks-0.11.1/config.h.in	2006-06-09 13:09:41.000000000 +0200
@@ -84,6 +84,9 @@
 /* Define if you want: gpm support */
 #undef CONFIG_GPM
 
+/* Define if you want: GssApi support */
+#undef CONFIG_GSSAPI
+
 /* Define if you want: Guile support */
 #undef CONFIG_GUILE
 
--- elinks-0.11.1/src/protocol/http/Makefile.negotiate	2006-01-29 14:10:39.000000000 +0100
+++ elinks-0.11.1/src/protocol/http/Makefile	2006-06-09 13:09:41.000000000 +0200
@@ -1,6 +1,8 @@
 top_builddir=../../..
 include $(top_builddir)/Makefile.config
 
+OBJS-$(CONFIG_GSSAPI)	+= http_negotiate.o
+
 OBJS = blacklist.o codes.o http.o
 
 include $(top_srcdir)/Makefile.lib
--- /dev/null	2006-05-28 11:31:41.625940250 +0200
+++ elinks-0.11.1/src/protocol/http/http_negotiate.h	2006-06-09 13:09:41.000000000 +0200
@@ -0,0 +1,16 @@
+
+#ifndef EL__PROTOCOL_HTTP_HTTP_NEGOTIATE_H
+#define EL__PROTOCOL_HTTP_HTTP_NEGOTIATE_H
+
+#define PROTOCOL_HTTP_GSSNEG	1
+#define PROTOCOL_HTTP_NEG	2
+
+
+int http_negotiate_input(struct connection *conn, struct uri *uri, 
+					int type, unsigned char *data);
+
+int http_negotiate_output(struct uri *uri, struct string *header);
+
+
+#endif /* EL_PROTOCOL_HTTP_HTTP_NEGOTIATE_H */
+
--- /dev/null	2006-05-28 11:31:41.625940250 +0200
+++ elinks-0.11.1/src/protocol/http/http_negotiate.c	2006-06-09 13:14:25.000000000 +0200
@@ -0,0 +1,259 @@
+/* 
+ * HTTP Negotiate authentication method -- based on GSSAPI
+ *
+ * The Microsoft version with SPNEGO is unsupported. If you look for way how
+ * extend this code with SPNEGO see libcurl or firefox source code where is
+ * supported GSSAPI+SPNEGO.
+ *
+ * Copyright (C) 2006 Red Hat, Inc.
+ * Karel Zak <kzak redhat com> 
+ */
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <stdio.h>
+#include <string.h>
+#include <stdarg.h>
+#include <stdlib.h>
+#include <ctype.h>
+#include <errno.h>
+
+#include <gssapi/gssapi.h>
+
+#include "elinks.h"
+#include "network/connection.h"
+#include "protocol/uri.h"
+#include "protocol/http/http.h"
+#include "protocol/http/http_negotiate.h"
+#include "util/base64.h"
+#include "main/object.h"
+#include "util/lists.h"
+
+struct negotiate {
+	OBJECT_HEAD(struct negotiate);
+
+	struct uri 	*uri;
+	
+	int 		type; 			/* GSS-Negotiate or Negotiate or zero */
+	OM_uint32	status;
+	gss_ctx_id_t	context;
+	gss_name_t	server_name;
+	gss_buffer_desc output_token;
+};
+
+static INIT_LIST_HEAD(negotiate_list);
+
+static struct negotiate *
+http_negotiate_get(struct uri *uri, int *isnew, int alloc)
+{
+	struct negotiate *neg;
+	
+	foreach (neg, negotiate_list) {	
+		if (compare_uri(neg->uri, uri, URI_HTTP_REFERRER_HOST))
+			return neg;
+	}
+	if (!alloc)	
+		return NULL;
+	if (isnew)
+		*isnew = 1;
+
+	if (!(neg = mem_calloc(1, sizeof(*neg))))
+		return NULL;
+		
+	memset(neg, 0, sizeof(*neg));
+	neg->uri = get_uri_reference(uri);	
+	
+	return neg;
+}
+
+static void
+http_negotiate_save(struct negotiate *neg)
+{
+	add_to_list(negotiate_list, neg);
+}
+
+static void 
+http_negotiate_cleanup(struct negotiate *neg, int full)
+{
+	OM_uint32 minor_status;
+
+	if (neg->context != GSS_C_NO_CONTEXT)
+		gss_delete_sec_context(&minor_status, &neg->context, GSS_C_NO_BUFFER);
+
+	if (neg->output_token.length != 0)
+		gss_release_buffer(&minor_status, &neg->output_token);
+
+	if (full && neg->server_name)
+		gss_release_name(&minor_status, &neg->server_name);
+
+	if (full)
+		memset(neg, 0, sizeof(*neg));
+}
+
+static int
+http_negotiate_get_name(struct connection *conn, struct negotiate *neg)
+{
+	OM_uint32 major_status, minor_status;
+	gss_buffer_desc token = GSS_C_EMPTY_BUFFER;
+	char name[2048];
+	const char* service;
+	struct uri *uri = conn->proxied_uri;
+
+	/* GSSAPI implementation by Globus (known as GSI) requires the name to be
+	of form "<service>/<fqdn>" instead of <service>@<fqdn> (ie. slash instead
+	of at-sign). Also GSI servers are often identified as 'host' not 'khttp'.
+	Change following lines if you want to use GSI */
+
+	/* IIS uses the <service>@<fqdn> form but uses 'http' as the service name */
+
+	if (neg->type == PROTOCOL_HTTP_GSSNEG)
+		service = "KHTTP";
+	else
+		service = "HTTP";
+
+	token.length = strlen(service) + 1 + uri->hostlen + 1;
+	if (token.length + 1 > sizeof(name))
+		return EMSGSIZE;
+
+	snprintf(name, token.length, "%s %*s", service, uri->hostlen, uri->host);
+
+	token.value = (void *) name;
+	major_status = gss_import_name(&minor_status,
+			 &token,
+			 GSS_C_NT_HOSTBASED_SERVICE,
+			 &neg->server_name);
+
+	return GSS_ERROR(major_status) ? -1 : 0;
+}
+
+#define GSSNEG_LEN	sizeof("GSS-Negotiate")
+#define NEG_LEN		sizeof("Negotiate")
+
+static int
+http_negotiate_parse_data(unsigned char *data, int type, 
+			gss_buffer_desc *token)
+{
+	int len = 0;
+	unsigned char *end;
+
+	if (data==NULL || *data=='\0')
+		return 0;
+	
+	data += type==PROTOCOL_HTTP_GSSNEG ? GSSNEG_LEN : NEG_LEN;
+	
+	while(*data && isspace((int)*data)) 
+		data++;
+	
+	if (*data=='\0' || *data==ASCII_CR || *data==ASCII_LF)
+		return 0;	/* no data */
+	
+	end = data;
+	while (isalnum((int) *end) || *end=='=')
+		end++;
+
+	/* Ignore line if we encountered an unexpected char. */
+	if (*end != ASCII_CR && *end != ASCII_LF)
+		return 0;
+
+	len = end - data;
+	
+	if (!len)
+		return 0;
+	
+	token->value = (void *) base64_decode_bin(data, len, &token->length);
+	
+	if (!token->value)
+		return -1;
+
+	return 0;
+}
+
+int 
+http_negotiate_input(struct connection *conn, struct uri *uri, 
+					int type, unsigned char *data)
+{
+	OM_uint32 major_status, minor_status, minor_status2;
+	gss_buffer_desc input_token = GSS_C_EMPTY_BUFFER;
+	gss_buffer_desc output_token = GSS_C_EMPTY_BUFFER;
+	struct negotiate *neg;
+	int ret, isnew = 0;
+
+	neg = http_negotiate_get(uri, &isnew, 1);
+	
+	if (neg->context) {
+		if (type != PROTOCOL_HTTP_GSSNEG) 
+			return -1;
+	}
+	neg->type = type;
+
+	if (neg->context && neg->status == GSS_S_COMPLETE) {
+		/* We finished succesfully our part of authentication, but server
+		 * rejected it (since we're again here). Exit with an error since we
+		 * can't invent anything better */
+		http_negotiate_cleanup(neg, 1);
+		return -1;
+	}
+	if (neg->server_name == NULL && (ret = http_negotiate_get_name(conn, neg)))
+		return ret;
+	if (data && http_negotiate_parse_data(data, type, &input_token)) 
+		return -1;
+	
+	major_status = gss_init_sec_context(&minor_status,
+					    GSS_C_NO_CREDENTIAL,
+					    &neg->context,
+					    neg->server_name,
+					    GSS_C_NO_OID,
+					    GSS_C_DELEG_FLAG,
+					    0,
+					    GSS_C_NO_CHANNEL_BINDINGS,
+					    &input_token,
+					    NULL,
+					    &output_token,
+					    NULL,
+					    NULL);
+	if (input_token.length > 0)
+		gss_release_buffer(&minor_status2, &input_token);
+	neg->status = major_status;
+
+	if (GSS_ERROR(major_status)) 
+		return -1;
+	if (output_token.length == 0) 
+		return -1;
+
+	neg->output_token = output_token;
+
+	if (isnew)
+		http_negotiate_save(neg);
+
+	return 0;
+}
+
+int
+http_negotiate_output(struct uri *uri, struct string *header)
+{
+	struct negotiate *neg;
+	char *encoded = NULL;
+	int len = 0;
+
+	neg = http_negotiate_get(uri, NULL, 0);	
+	if (neg==NULL || neg->output_token.length==0) 
+		return -1;
+	
+	encoded = base64_encode_bin((unsigned char *) neg->output_token.value, 
+				neg->output_token.length, &len);
+
+	if (encoded==NULL || len==0)
+	    return -1;
+
+	add_to_string(header, "Authorization: ");
+	add_to_string(header, neg->type==PROTOCOL_HTTP_GSSNEG ? 
+				"GSS-Negotiate " : "Negotiate ");
+	add_to_string(header, encoded);
+	add_crlf_to_string(header);
+	
+	http_negotiate_cleanup(neg, 0);
+	return 0;
+}
+
--- elinks-0.11.1/src/protocol/http/http.c.negotiate	2006-01-29 14:10:39.000000000 +0100
+++ elinks-0.11.1/src/protocol/http/http.c	2006-06-09 13:09:41.000000000 +0200
@@ -47,6 +47,9 @@
 #include "util/memory.h"
 #include "util/string.h"
 
+#ifdef CONFIG_GSSAPI
+#include "http_negotiate.h"
+#endif
 
 struct http_version {
 	int major;
@@ -82,7 +85,6 @@
 	int code;
 };
 
-
 static struct auth_entry proxy_auth;
 
 static unsigned char *accept_charset = NULL;
@@ -551,7 +553,7 @@
 	int trace = get_opt_bool("protocol.http.trace");
 	struct string header;
 	unsigned char *post_data = NULL;
-	struct auth_entry *entry;
+	struct auth_entry *entry = NULL;
 	struct uri *uri = conn->proxied_uri; /* Set to the real uri */
 	unsigned char *optstr;
 	int use_connect, talking_to_proxy;
@@ -808,7 +810,11 @@
 		add_crlf_to_string(&header);
 	}
 
-	entry = find_auth(uri);
+#ifdef CONFIG_GSSAPI
+	if (http_negotiate_output(uri, &header) != 0)
+#endif
+		entry = find_auth(uri);
+	
 	if (entry) {
 		if (entry->digest) {
 			unsigned char *response;
@@ -1327,12 +1333,12 @@
 	return 0;
 }
 
-
-static void
-check_http_authentication(struct uri *uri, unsigned char *header,
-			  unsigned char *header_field)
+static int
+check_http_authentication(struct connection *conn, struct uri *uri, 
+		unsigned char *header, unsigned char *header_field)
 {
 	unsigned char *str, *d;
+	int ret = 0;
 
 	d = parse_header(header, header_field, &str);
 	while (d) {
@@ -1358,10 +1364,24 @@
 			mem_free(d);
 			break;
 		}
-
+#ifdef CONFIG_GSSAPI
+		else if (!strncasecmp(d, "GSS-Negotiate", 13)) {
+			if (http_negotiate_input(conn, uri, PROTOCOL_HTTP_GSSNEG, str)==0)
+				ret = 1;
+			mem_free(d);
+			break;
+		}
+		else if (!strncasecmp(d, "Negotiate", 9)) {
+			if (http_negotiate_input(conn, uri, PROTOCOL_HTTP_NEG, str)==0)
+				ret = 1;
+			mem_free(d);
+			break;
+		}
+#endif
 		mem_free(d);
 		d = parse_header(str, header_field, &str);
 	}
+	return ret;
 }
 
 
@@ -1588,11 +1608,17 @@
 	}
 
 	if (h == 401) {
-		unsigned char *head = conn->cached->head;
-
-		check_http_authentication(uri, head, "WWW-Authenticate");
+		int ret = check_http_authentication(conn, uri, 
+				conn->cached->head, "WWW-Authenticate");
+	
+		
+		if (ret) {
+			// XXX: mem_free(conn->cached->head);
+			retry_connection(conn, S_RESTART);
+			return;
+		}
+	
 	}
-
 	if (h == 407) {
 		unsigned char *str;
 
--- elinks-0.11.1/src/util/base64.c.negotiate	2006-01-29 14:10:39.000000000 +0100
+++ elinks-0.11.1/src/util/base64.c	2006-06-09 13:09:41.000000000 +0200
@@ -17,14 +17,21 @@
 unsigned char *
 base64_encode(register unsigned char *in)
 {
+	assert(in && *in);
+	if_assert_failed return NULL;
+	
+	return base64_encode_bin((char *) in, strlen(in), NULL);
+}
+
+unsigned char *
+base64_encode_bin(register unsigned char *in, int inlen, int *outlen)
+{
 	unsigned char *out;
 	unsigned char *outstr;
-	int inlen;
 
 	assert(in && *in);
 	if_assert_failed return NULL;
 
-	inlen = strlen(in);
 	out = outstr = mem_alloc((inlen / 3) * 4 + 4 + 1);
 	if (!out) return NULL;
 
@@ -49,16 +56,29 @@
 	}
 	*out = 0;
 
+	if (outlen)
+		*outlen = out-outstr;
+
 	return outstr;
 }
 
-/* Base64 decoding is used only with the CONFIG_FORMHIST feature, so i'll #ifdef it */
-#ifdef CONFIG_FORMHIST
+/* Base64 decoding is used only with the CONFIG_FORMHIST or CONFIG_GSSAPI 
+   feature, so i'll #ifdef it */
+#if  defined(CONFIG_FORMHIST) || defined(CONFIG_GSSAPI)
+
+unsigned char *
+base64_decode(register unsigned char *in) 
+{
+	assert(in && *in);
+	if_assert_failed return NULL;
+
+	return base64_decode_bin(in, strlen(in), NULL);
+}
 
 /* base64_decode:  @in string to decode
  *		   returns the string decoded (must be freed by the caller) */
 unsigned char *
-base64_decode(register unsigned char *in)
+base64_decode_bin(register unsigned char *in, int inlen, int *outlen)
 {
 	static unsigned char is_base64_char[256]; /* static to force initialization at zero */
 	static unsigned char decode[256];
@@ -71,7 +91,7 @@
 	assert(in && *in);
 	if_assert_failed return NULL;
 
-	outstr = out = mem_alloc(strlen(in) / 4 * 3 + 1);
+	outstr = out = mem_alloc(inlen / 4 * 3 + 1);
 	if (!outstr) return NULL;
 
 	if (!once) {
@@ -123,6 +143,10 @@
 	}
 
 	*out = 0;
+
+	if (outlen)
+		*outlen = out-outstr;
+
 	return outstr;
 
 decode_error:
--- elinks-0.11.1/src/util/base64.h.negotiate	2006-01-29 14:10:39.000000000 +0100
+++ elinks-0.11.1/src/util/base64.h	2006-06-09 13:09:41.000000000 +0200
@@ -4,4 +4,7 @@
 unsigned char *base64_encode(unsigned char *);
 unsigned char *base64_decode(unsigned char *);
 
+unsigned char *base64_encode_bin(unsigned char *, int, int *);
+unsigned char *base64_decode_bin(unsigned char *, int, int *);
+
 #endif
--- elinks-0.11.1/configure.in.negotiate	2006-06-09 13:09:41.000000000 +0200
+++ elinks-0.11.1/configure.in	2006-06-09 13:09:41.000000000 +0200
@@ -447,6 +447,30 @@
 	[  --without-idn           disable international domain names support])
 
 dnl ===================================================================
+dnl Check for GSSAPI, optional even if installed.
+dnl ===================================================================
+
+enable_gssapi="no";
+
+AC_ARG_WITH(gssapi, [  --with-gssapi           enable GSSAPI support],
+            [ if test "x$withval" != xno; then enable_gssapi=yes; fi ])
+
+AC_MSG_CHECKING([for GSSAPI])
+
+if test "$enable_gssapi" = "yes"; then
+	AC_MSG_RESULT(yes)
+	GSSAPI_CFLAGS=`krb5-config --cflags gssapi`
+	GSSAPI_LIBS=`krb5-config --libs gssapi`
+	CFLAGS="$GSSAPI_CFLAGS $CFLAGS"
+	LIBS="$GSSAPI_LIBS $LIBS"
+ 	EL_CONFIG(CONFIG_GSSAPI, [GssApi])
+else
+	AC_MSG_RESULT(no)
+fi
+
+AC_SUBST(CONFIG_GSSAPI)
+
+dnl ===================================================================
 dnl Bookmark and XBEL support
 dnl ===================================================================
 


Index: .cvsignore
===================================================================
RCS file: /cvs/dist/rpms/elinks/devel/.cvsignore,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- .cvsignore	29 May 2006 20:35:05 -0000	1.17
+++ .cvsignore	9 Jun 2006 12:08:47 -0000	1.18
@@ -1,2 +1 @@
 elinks-0.11.1.tar.bz2
-manual-0.82-en.tar.bz2


Index: elinks.spec
===================================================================
RCS file: /cvs/dist/rpms/elinks/devel/elinks.spec,v
retrieving revision 1.34
retrieving revision 1.35
diff -u -r1.34 -r1.35
--- elinks.spec	29 May 2006 20:35:05 -0000	1.34
+++ elinks.spec	9 Jun 2006 12:08:47 -0000	1.35
@@ -2,14 +2,21 @@
 Name: elinks
 Summary: A text-mode Web browser.
 Version: 0.11.1
-Release: 2
+Release: 3
 Source: http://elinks.or.cz/download/elinks-%{version}.tar.bz2
-Source1: http://links.sourceforge.net/download/docs/manual-0.82-en.tar.bz2
 Group: Applications/Internet
 URL: http://elinks.or.cz/
 BuildRoot: %{_tmppath}/%{name}-buildroot
-BuildRequires: autoconf, automake, openssl-devel, pkgconfig
-BuildRequires: bzip2-devel, expat-devel, libidn-devel
+
+BuildRequires: autoconf
+BuildRequires: automake
+BuildRequires: pkgconfig
+BuildRequires: openssl-devel
+BuildRequires: krb5-devel
+BuildRequires: bzip2-devel
+BuildRequires: expat-devel
+BuildRequires: libidn-devel
+
 License: GPL
 Provides: webclient
 Obsoletes: links
@@ -22,6 +29,7 @@
 Patch4: elinks-0.11.0-sysname.patch
 Patch5: elinks-0.10.1-xterm.patch
 Patch6: elinks-0.11.0-union.patch
+Patch7: elinks-0.11.1-negotiate.patch
 
 %description
 Links is a text-based Web browser. Links does not display any images,
@@ -30,7 +38,7 @@
 quickly and swiftly displays Web pages.
 
 %prep
-%setup -q -a 1 -n %{name}-%{version}
+%setup -q -n %{name}-%{version}
 
 # Prevent crash when HOME is unset (bug #90663).
 %patch0 -p1 -b .noegd
@@ -45,6 +53,9 @@
 %patch5 -p1 -b .xterm
 # Fix #157300 - Strange behavior on ppc64
 %patch6 -p1 -b .union
+# Fix #194096 – elinks should support negotiate-auth
+%patch7 -p1 -b .negotiate
+
 
 %build
 #aclocal
@@ -53,7 +64,7 @@
 ./autogen.sh
 
 export CFLAGS="$RPM_OPT_FLAGS $(getconf LFS_CFLAGS)"
-%configure %{?rescue:--without-gpm} --without-x
+%configure %{?rescue:--without-gpm} --without-x --with-gssapi
 %if "%{rescue}" != ""
 perl -pi -e "s,-O2,-O2 -Os,g" Make* */Make*
 %endif
@@ -72,7 +83,7 @@
 
 %files -f elinks.lang
 %defattr(-,root,root)
-%doc README SITES TODO manual-0.82-en
+%doc README SITES TODO
 %{_bindir}/links
 %{_bindir}/elinks
 %{_mandir}/man1/links.1*
@@ -80,6 +91,9 @@
 %{_mandir}/man5/*
 
 %changelog
+* Fri Jun  9 2006 Karel Zak <kzak redhat com> 0.11.1-3
+- added negotiate-auth (GSSAPI) support -- EXPERIMENTAL!
+
 * Mon May 29 2006 Karel Zak <kzak redhat com> 0.11.1-2
 - update to new upstream version
 


Index: sources
===================================================================
RCS file: /cvs/dist/rpms/elinks/devel/sources,v
retrieving revision 1.17
retrieving revision 1.18
diff -u -r1.17 -r1.18
--- sources	29 May 2006 20:35:05 -0000	1.17
+++ sources	9 Jun 2006 12:08:47 -0000	1.18
@@ -1,2 +1 @@
 db0d62394b03938eec81b749e49dfbbc  elinks-0.11.1.tar.bz2
-947950d4974c25f95f1a3988bf88cb21  manual-0.82-en.tar.bz2


[Date Prev][Date Next]   [Thread Prev][Thread Next]   [Thread Index] [Date Index] [Author Index]