Re: [PATCH] updated GSSAPI client split

Alexey Mahotkin <[email protected]>
Newsgroups gmane.comp.version-control.cvs.bugs
Message-ID <[email protected]>
>>>>> "DRP" == Derek Robert Price <[email protected]> writes:

 DRP> Hey, Alexey, that patch I sent you that revised your configure.in,
 DRP> acinclude.m4, and src/Makefile.am changes was broken.  You did it
 DRP> correctly the first time.  Sorry about that.

's ok.

Here is the really updated patch (sorry, but I had all the chances to die
in the car accident thirty minutes ago, so I do not have nerve to do proper
GNU-style ChangeLog entry :-D).  The patch applies with a minor fuzz.



2003-05-09  Alexey Mahotkin <[email protected]>

Move GSSAPI client stuff from client.c to gssapi-client.[ch];

move GSSAPI buffers from server.c to gssapi-client.[ch];

compile gssapi-client.c only if GSSAPI is found by configure;

move global `gcontext' variable to gssapi-client.c and use a simple
wrapper initialize_gssapi_buffers() in client.c to hide accesses to
it;



 acinclude.m4        |    2 
 configure.in        |    3 
 src/Makefile.am     |    5 
 src/client.c        |  182 -----------------------------
 src/client.h        |   15 --
 src/gssapi-client.c |  317 ++++++++++++++++++++++++++++++++++++++++++++++++++++
 src/gssapi-client.h |   38 ++++++
 src/server.c        |  135 ----------------------
 8 files changed, 372 insertions(+), 325 deletions(-)

--- ccvs/acinclude.m4~gssapi-client	Wed May  7 21:50:48 2003
+++ ccvs-alexm/acinclude.m4	Wed May  7 21:52:12 2003
@@ -102,6 +102,8 @@ if test x$acx_gssapi_cv_gssapi != xno; t
 [Define if you have GSSAPI with Kerberos version 5 available.])
   CPPFLAGS=$CPPFLAGS$GSSAPI_INCLUDES
 
+  client_objects="$client_objects gssapi-client.o"
+
   # locate any other headers
   dnl We don't use HAVE_KRB5_H anywhere, but including it here might make it
   dnl easier to spot errors by reading configure output
--- ccvs/configure.in~gssapi-client	Wed May  7 21:50:48 2003
+++ ccvs-alexm/configure.in	Wed May  7 21:50:56 2003
@@ -312,6 +312,9 @@ dnl just added libnsl above if we found 
 AC_SEARCH_LIBS(gethostbyname, netinet)
 
 
+AC_SUBST(client_objects)
+
+
 dnl
 dnl begin --with-*
 dnl
--- ccvs/src/client.c~gssapi-client	Wed May  7 21:50:48 2003
+++ ccvs-alexm/src/client.c	Wed May  7 21:58:09 2003
@@ -30,6 +30,8 @@
 #include "socket-client.h"
 #include "rsh-client.h"
 
+#include "gssapi-client.h"
+
 # if HAVE_KERBEROS
 
 #   include <krb.h>
@@ -45,17 +47,6 @@ static Key_schedule sched;
 
 # endif /* HAVE_KERBEROS */
 
-# ifdef HAVE_GSSAPI
-
-#   include "xgssapi.h"
-
-/* This is needed for GSSAPI encryption.  */
-static gss_ctx_id_t gcontext;
-
-static int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
-
-# endif /* HAVE_GSSAPI */
-
 static void add_prune_candidate PROTO((char *));
 
 /* All the commands.  */
@@ -3623,156 +3614,6 @@ start_tcp_server (root, to_server_p, fro
 
 #endif /* HAVE_KERBEROS */
 
-#ifdef HAVE_GSSAPI
-
-/* Receive a given number of bytes.  */
-
-static void
-recv_bytes (sock, buf, need)
-     int sock;
-     char *buf;
-     int need;
-{
-    while (need > 0)
-    {
-	int got;
-
-	got = recv (sock, buf, need, 0);
-	if (got <= 0)
-	    error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname,
-		   got == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
-
-	buf += got;
-	need -= got;
-    }
-}
-
-/* Connect to the server using GSSAPI authentication.  */
-
-/* FIXME
- *
- * This really needs to be rewritten to use a buffer and not a socket.
- * This would enable gserver to work with the SSL code I'm about to commit
- * since the SSL connection is going to look like a FIFO and not a socket.
- *
- * I think, basically, it will need to use buf_output and buf_read directly
- * since I don't think there is a read_bytes function - only read_line.
- *
- * recv_bytes could then be removed too.
- *
- * Besides, I added some cruft to reenable the socket which shouldn't be
- * there.  This would also enable its removal.
- */
-#define BUFSIZE 1024
-static int
-connect_to_gserver (root, sock, hostinfo)
-    cvsroot_t *root;
-    int sock;
-    struct hostent *hostinfo;
-{
-    char *str;
-    char buf[BUFSIZE];
-    gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
-    OM_uint32 stat_min, stat_maj;
-    gss_name_t server_name;
-
-    str = "BEGIN GSSAPI REQUEST\012";
-
-    if (send (sock, str, strlen (str), 0) < 0)
-	error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
-
-    if (strlen (hostinfo->h_name) > BUFSIZE - 5)
-	error (1, 0, "Internal error: hostname exceeds length of buffer");
-    sprintf (buf, "cvs@%s", hostinfo->h_name);
-    tok_in.length = strlen (buf);
-    tok_in.value = buf;
-    gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
-		     &server_name);
-
-    tok_in_ptr = GSS_C_NO_BUFFER;
-    gcontext = GSS_C_NO_CONTEXT;
-
-    do
-    {
-	stat_maj = gss_init_sec_context (&stat_min, GSS_C_NO_CREDENTIAL,
-					 &gcontext, server_name,
-					 GSS_C_NULL_OID,
-					 (GSS_C_MUTUAL_FLAG
-					  | GSS_C_REPLAY_FLAG),
-					 0, NULL, tok_in_ptr, NULL, &tok_out,
-					 NULL, NULL);
-	if (stat_maj != GSS_S_COMPLETE && stat_maj != GSS_S_CONTINUE_NEEDED)
-	{
-	    OM_uint32 message_context;
-	    OM_uint32 new_stat_min;
-
-	    message_context = 0;
-	    gss_display_status (&new_stat_min, stat_maj, GSS_C_GSS_CODE,
-                                GSS_C_NULL_OID, &message_context, &tok_out);
-	    error (0, 0, "GSSAPI authentication failed: %s",
-		   (char *) tok_out.value);
-
-	    message_context = 0;
-	    gss_display_status (&new_stat_min, stat_min, GSS_C_MECH_CODE,
-				GSS_C_NULL_OID, &message_context, &tok_out);
-	    error (1, 0, "GSSAPI authentication failed: %s",
-		   (char *) tok_out.value);
-	}
-
-	if (tok_out.length == 0)
-	{
-	    tok_in.length = 0;
-	}
-	else
-	{
-	    char cbuf[2];
-	    int need;
-
-	    cbuf[0] = (tok_out.length >> 8) & 0xff;
-	    cbuf[1] = tok_out.length & 0xff;
-	    if (send (sock, cbuf, 2, 0) < 0)
-		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
-	    if (send (sock, tok_out.value, tok_out.length, 0) < 0)
-		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
-
-	    recv_bytes (sock, cbuf, 2);
-	    need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff);
-
-	    if (need > sizeof buf)
-	    {
-		int got;
-
-		/* This usually means that the server sent us an error
-		   message.  Read it byte by byte and print it out.
-		   FIXME: This is a terrible error handling strategy.
-		   However, even if we fix the server, we will still
-		   want to do this to work with older servers.  */
-		buf[0] = cbuf[0];
-		buf[1] = cbuf[1];
-		got = recv (sock, buf + 2, sizeof buf - 2, 0);
-		if (got < 0)
-		    error (1, 0, "recv() from server %s: %s",
-			   root->hostname, SOCK_STRERROR (SOCK_ERRNO));
-		buf[got + 2] = '\0';
-		if (buf[got + 1] == '\n')
-		    buf[got + 1] = '\0';
-		error (1, 0, "error from server %s: %s", root->hostname,
-		       buf);
-	    }
-
-	    recv_bytes (sock, buf, need);
-	    tok_in.length = need;
-	}
-
-	tok_in.value = buf;
-	tok_in_ptr = &tok_in;
-    }
-    while (stat_maj == GSS_S_CONTINUE_NEEDED);
-
-    return 1;
-}
-
-#endif /* HAVE_GSSAPI */
 
 static int send_variable_proc PROTO ((Node *, void *));
 
@@ -4051,14 +3892,7 @@ start_server ()
 	    if (! supported_request ("Gssapi-encrypt"))
 		error (1, 0, "This server does not support encryption");
 	    send_to_server ("Gssapi-encrypt\012", 0);
-	    global_to_server = cvs_gssapi_wrap_buffer_initialize (global_to_server, 0,
-								  gcontext,
-								  ((BUFMEMERRPROC)
-								   NULL));
-	    global_from_server = cvs_gssapi_wrap_buffer_initialize (global_from_server, 1,
-								    gcontext,
-								    ((BUFMEMERRPROC)
-								     NULL));
+	    initialize_gssapi_buffers(&global_to_server, &global_from_server);
 	    cvs_gssapi_encrypt = 1;
 	}
 	else
@@ -4124,14 +3958,8 @@ start_server ()
 		error (1, 0,
 		       "This server does not support stream authentication");
 	    send_to_server ("Gssapi-authenticate\012", 0);
-	    global_to_server = cvs_gssapi_wrap_buffer_initialize (global_to_server, 0,
-								  gcontext,
-								  ((BUFMEMERRPROC)
-								   NULL));
-	    global_from_server = cvs_gssapi_wrap_buffer_initialize (global_from_server, 1,
-								    gcontext,
-								    ((BUFMEMERRPROC)
-								     NULL));
+	    initialize_gssapi_buffers(&global_to_server, &global_from_server);
+
 	}
 	else
 	    error (1, 0, "Stream authentication is only supported when using GSSAPI");
--- ccvs/src/client.h~gssapi-client	Wed May  7 21:50:48 2003
+++ ccvs-alexm/src/client.h	Wed May  7 21:50:56 2003
@@ -37,22 +37,7 @@ extern struct buffer *krb_encrypt_buffer
 
 #   endif /* HAVE_KERBEROS */
 
-#   ifdef HAVE_GSSAPI
-
-/* Set this to turn on GSSAPI encryption.  */
-extern int cvs_gssapi_encrypt;
-
-#   endif /* HAVE_GSSAPI */
-
 # endif /* ENCRYPTION */
-
-# ifdef HAVE_GSSAPI
-
-/* We can't declare the arguments without including gssapi.h, and I
-   don't want to do that in every file.  */
-extern struct buffer *cvs_gssapi_wrap_buffer_initialize ();
-
-# endif /* HAVE_GSSAPI */
 
 #endif /* defined (CLIENT_SUPPORT) || defined (SERVER_SUPPORT) */
 
--- /dev/null	Wed Jan  1 02:48:46 2003
+++ ccvs-alexm/src/gssapi-client.c	Wed May  7 22:08:03 2003
@@ -0,0 +1,317 @@
+/* CVS GSSAPI client stuff.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.  */
+
+
+#include <config.h>
+
+#include "cvs.h"
+
+#include "buffer.h"
+#include "socket-client.h"
+#include "gssapi-client.h"
+
+/* This is needed for GSSAPI encryption.  */
+gss_ctx_id_t gcontext;
+
+#   ifdef ENCRYPTION
+/* Whether to encrypt GSSAPI communication.  We use a global variable
+   like this because we use the same buffer type (gssapi_wrap) to
+   handle both authentication and encryption, and we don't want
+   multiple instances of that buffer in the communication stream.  */
+int cvs_gssapi_encrypt;
+#   endif
+
+
+/* Receive a given number of bytes.  */
+
+static void
+recv_bytes (sock, buf, need)
+     int sock;
+     char *buf;
+     int need;
+{
+    while (need > 0)
+    {
+	int got;
+
+	got = recv (sock, buf, need, 0);
+	if (got <= 0)
+	    error (1, 0, "recv() from server %s: %s", current_parsed_root->hostname,
+		   got == 0 ? "EOF" : SOCK_STRERROR (SOCK_ERRNO));
+
+	buf += got;
+	need -= got;
+    }
+}
+
+/* Connect to the server using GSSAPI authentication.  */
+
+/* FIXME
+ *
+ * This really needs to be rewritten to use a buffer and not a socket.
+ * This would enable gserver to work with the SSL code I'm about to commit
+ * since the SSL connection is going to look like a FIFO and not a socket.
+ *
+ * I think, basically, it will need to use buf_output and buf_read directly
+ * since I don't think there is a read_bytes function - only read_line.
+ *
+ * recv_bytes could then be removed too.
+ *
+ * Besides, I added some cruft to reenable the socket which shouldn't be
+ * there.  This would also enable its removal.
+ */
+#define BUFSIZE 1024
+int
+connect_to_gserver (root, sock, hostinfo)
+    cvsroot_t *root;
+    int sock;
+    struct hostent *hostinfo;
+{
+    char *str;
+    char buf[BUFSIZE];
+    gss_buffer_desc *tok_in_ptr, tok_in, tok_out;
+    OM_uint32 stat_min, stat_maj;
+    gss_name_t server_name;
+
+    str = "BEGIN GSSAPI REQUEST\012";
+
+    if (send (sock, str, strlen (str), 0) < 0)
+	error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+
+    if (strlen (hostinfo->h_name) > BUFSIZE - 5)
+	error (1, 0, "Internal error: hostname exceeds length of buffer");
+    sprintf (buf, "cvs@%s", hostinfo->h_name);
+    tok_in.length = strlen (buf);
+    tok_in.value = buf;
+    gss_import_name (&stat_min, &tok_in, GSS_C_NT_HOSTBASED_SERVICE,
+		     &server_name);
+
+    tok_in_ptr = GSS_C_NO_BUFFER;
+    gcontext = GSS_C_NO_CONTEXT;
+
+    do
+    {
+	stat_maj = gss_init_sec_context (&stat_min, GSS_C_NO_CREDENTIAL,
+					 &gcontext, server_name,
+					 GSS_C_NULL_OID,
+					 (GSS_C_MUTUAL_FLAG
+					  | GSS_C_REPLAY_FLAG),
+					 0, NULL, tok_in_ptr, NULL, &tok_out,
+					 NULL, NULL);
+	if (stat_maj != GSS_S_COMPLETE && stat_maj != GSS_S_CONTINUE_NEEDED)
+	{
+	    OM_uint32 message_context;
+	    OM_uint32 new_stat_min;
+
+	    message_context = 0;
+	    gss_display_status (&new_stat_min, stat_maj, GSS_C_GSS_CODE,
+                                GSS_C_NULL_OID, &message_context, &tok_out);
+	    error (0, 0, "GSSAPI authentication failed: %s",
+		   (char *) tok_out.value);
+
+	    message_context = 0;
+	    gss_display_status (&new_stat_min, stat_min, GSS_C_MECH_CODE,
+				GSS_C_NULL_OID, &message_context, &tok_out);
+	    error (1, 0, "GSSAPI authentication failed: %s",
+		   (char *) tok_out.value);
+	}
+
+	if (tok_out.length == 0)
+	{
+	    tok_in.length = 0;
+	}
+	else
+	{
+	    char cbuf[2];
+	    int need;
+
+	    cbuf[0] = (tok_out.length >> 8) & 0xff;
+	    cbuf[1] = tok_out.length & 0xff;
+	    if (send (sock, cbuf, 2, 0) < 0)
+		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+	    if (send (sock, tok_out.value, tok_out.length, 0) < 0)
+		error (1, 0, "cannot send: %s", SOCK_STRERROR (SOCK_ERRNO));
+
+	    recv_bytes (sock, cbuf, 2);
+	    need = ((cbuf[0] & 0xff) << 8) | (cbuf[1] & 0xff);
+
+	    if (need > sizeof buf)
+	    {
+		int got;
+
+		/* This usually means that the server sent us an error
+		   message.  Read it byte by byte and print it out.
+		   FIXME: This is a terrible error handling strategy.
+		   However, even if we fix the server, we will still
+		   want to do this to work with older servers.  */
+		buf[0] = cbuf[0];
+		buf[1] = cbuf[1];
+		got = recv (sock, buf + 2, sizeof buf - 2, 0);
+		if (got < 0)
+		    error (1, 0, "recv() from server %s: %s",
+			   root->hostname, SOCK_STRERROR (SOCK_ERRNO));
+		buf[got + 2] = '\0';
+		if (buf[got + 1] == '\n')
+		    buf[got + 1] = '\0';
+		error (1, 0, "error from server %s: %s", root->hostname,
+		       buf);
+	    }
+
+	    recv_bytes (sock, buf, need);
+	    tok_in.length = need;
+	}
+
+	tok_in.value = buf;
+	tok_in_ptr = &tok_in;
+    }
+    while (stat_maj == GSS_S_CONTINUE_NEEDED);
+
+    return 1;
+}
+
+
+/* A buffer interface using GSSAPI.  It is built on top of a
+   packetizing buffer.  */
+
+/* This structure is the closure field of the GSSAPI translation
+   routines.  */
+
+struct cvs_gssapi_wrap_data
+{
+    /* The GSSAPI context.  */
+    gss_ctx_id_t gcontext;
+};
+
+static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
+static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
+					 int *));
+
+/* Create a GSSAPI wrapping buffer.  We use a packetizing buffer with
+   GSSAPI wrapping routines.  */
+
+struct buffer *
+cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
+     struct buffer *buf;
+     int input;
+     gss_ctx_id_t gcontext;
+     void (*memory) PROTO((struct buffer *));
+{
+    struct cvs_gssapi_wrap_data *gd;
+
+    gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
+    gd->gcontext = gcontext;
+
+    return (packetizing_buffer_initialize
+	    (buf,
+	     input ? cvs_gssapi_wrap_input : NULL,
+	     input ? NULL : cvs_gssapi_wrap_output,
+	     gd,
+	     memory));
+}
+
+/* Unwrap data using GSSAPI.  */
+
+static int
+cvs_gssapi_wrap_input (fnclosure, input, output, size)
+     void *fnclosure;
+     const char *input;
+     char *output;
+     int size;
+{
+    struct cvs_gssapi_wrap_data *gd =
+	(struct cvs_gssapi_wrap_data *) fnclosure;
+    gss_buffer_desc inbuf, outbuf;
+    OM_uint32 stat_min;
+    int conf;
+
+    inbuf.value = (void *) input;
+    inbuf.length = size;
+
+    if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
+	!= GSS_S_COMPLETE)
+    {
+	error (1, 0, "gss_unwrap failed");
+    }
+
+    if (outbuf.length > size)
+	abort ();
+
+    memcpy (output, outbuf.value, outbuf.length);
+
+    /* The real packet size is stored in the data, so we don't need to
+       remember outbuf.length.  */
+
+    gss_release_buffer (&stat_min, &outbuf);
+
+    return 0;
+}
+
+/* Wrap data using GSSAPI.  */
+
+static int
+cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
+     void *fnclosure;
+     const char *input;
+     char *output;
+     int size;
+     int *translated;
+{
+    struct cvs_gssapi_wrap_data *gd =
+	(struct cvs_gssapi_wrap_data *) fnclosure;
+    gss_buffer_desc inbuf, outbuf;
+    OM_uint32 stat_min;
+    int conf_req, conf;
+
+    inbuf.value = (void *) input;
+    inbuf.length = size;
+
+#ifdef ENCRYPTION
+    conf_req = cvs_gssapi_encrypt;
+#else
+    conf_req = 0;
+#endif
+
+    if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
+		  &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
+	error (1, 0, "gss_wrap failed");
+
+    /* The packetizing buffer only permits us to add 100 bytes.
+       FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
+       This may need to be increased for a different GSSAPI
+       implementation, or we may need a different algorithm.  */
+    if (outbuf.length > size + 100)
+	abort ();
+
+    memcpy (output, outbuf.value, outbuf.length);
+
+    *translated = outbuf.length;
+
+    gss_release_buffer (&stat_min, &outbuf);
+
+    return 0;
+}
+
+void
+initialize_gssapi_buffers (to_server_p, from_server_p)
+     struct buffer **to_server_p;
+     struct buffer **from_server_p;
+{
+  *to_server_p = cvs_gssapi_wrap_buffer_initialize (*to_server_p, 0,
+						    gcontext,
+						    ((BUFMEMERRPROC)
+						     NULL));
+
+  *from_server_p = cvs_gssapi_wrap_buffer_initialize (*from_server_p, 1,
+						      gcontext,
+						      ((BUFMEMERRPROC)
+						       NULL));
+}
--- /dev/null	Wed Jan  1 02:48:46 2003
+++ ccvs-alexm/src/gssapi-client.h	Wed May  7 22:03:56 2003
@@ -0,0 +1,38 @@
+/* CVS GSSAPI client stuff.
+
+   This program is free software; you can redistribute it and/or modify
+   it under the terms of the GNU General Public License as published by
+   the Free Software Foundation; either version 2, or (at your option)
+   any later version.
+
+   This program is distributed in the hope that it will be useful,
+   but WITHOUT ANY WARRANTY; without even the implied warranty of
+   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
+   GNU General Public License for more details.  */
+
+
+#ifndef GSSAPI_CLIENT_H__
+#define GSSAPI_CLIENT_H__
+
+#include "xgssapi.h"
+
+#include "socket-client.h"
+
+/* Set this to turn on GSSAPI encryption.  */
+extern int cvs_gssapi_encrypt;
+
+extern gss_ctx_id_t gcontext;
+
+/* We can't declare the arguments without including gssapi.h, and I
+   don't want to do that in every file.  */
+struct buffer* cvs_gssapi_wrap_buffer_initialize PROTO((struct buffer *buf,
+							int input,
+							gss_ctx_id_t gcontext,
+							void (*memory) PROTO((struct buffer *))));
+
+int connect_to_gserver PROTO((cvsroot_t *, int, struct hostent *));
+
+extern void initialize_gssapi_buffers PROTO((struct buffer **to_server_p,
+					     struct buffer **from_server_p));
+
+#endif
--- ccvs/src/Makefile.am~gssapi-client	Wed May  7 21:50:48 2003
+++ ccvs-alexm/src/Makefile.am	Wed May  7 21:50:56 2003
@@ -94,7 +94,10 @@ cvs_SOURCES = \
 	update.h \
 	watch.h
 
-cvs_LDADD = \
+EXTRA_cvs_SOURCES = gssapi-client.c gssapi-client.h
+
+cvs_DEPENDENCIES = @client_objects@
+cvs_LDADD = @client_objects@ \
 	../diff/libdiff.a \
 	../lib/libcvs.a \
 	../zlib/libz.a
--- ccvs/src/server.c~gssapi-client	Wed May  7 21:50:49 2003
+++ ccvs-alexm/src/server.c	Wed May  7 21:50:56 2003
@@ -17,6 +17,9 @@
 #include "buffer.h"
 
 #if defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT)
+
+#include "gssapi-client.h"
+
 # ifdef HAVE_GSSAPI
 /* This stuff isn't included solely with SERVER_SUPPORT since some of these
  * functions (encryption & the like) get compiled with or without server
@@ -38,13 +41,6 @@ static void gserver_authenticate_connect
 /* Whether we are already wrapping GSSAPI communication.  */
 static int cvs_gssapi_wrapping;
 
-#   ifdef ENCRYPTION
-/* Whether to encrypt GSSAPI communication.  We use a global variable
-   like this because we use the same buffer type (gssapi_wrap) to
-   handle both authentication and encryption, and we don't want
-   multiple instances of that buffer in the communication stream.  */
-int cvs_gssapi_encrypt;
-#   endif
 # endif	/* HAVE_GSSAPI */
 #endif	/* defined(SERVER_SUPPORT) || defined(CLIENT_SUPPORT) */
 
@@ -5974,131 +5970,6 @@ int cvsencrypt;
 /* This global variable is non-zero if the users requests stream
    authentication on the command line.  */
 int cvsauthenticate;
-
-#ifdef HAVE_GSSAPI
-
-/* An buffer interface using GSSAPI.  This is built on top of a
-   packetizing buffer.  */
-
-/* This structure is the closure field of the GSSAPI translation
-   routines.  */
-
-struct cvs_gssapi_wrap_data
-{
-    /* The GSSAPI context.  */
-    gss_ctx_id_t gcontext;
-};
-
-static int cvs_gssapi_wrap_input PROTO((void *, const char *, char *, int));
-static int cvs_gssapi_wrap_output PROTO((void *, const char *, char *, int,
-					 int *));
-
-/* Create a GSSAPI wrapping buffer.  We use a packetizing buffer with
-   GSSAPI wrapping routines.  */
-
-struct buffer *
-cvs_gssapi_wrap_buffer_initialize (buf, input, gcontext, memory)
-     struct buffer *buf;
-     int input;
-     gss_ctx_id_t gcontext;
-     void (*memory) PROTO((struct buffer *));
-{
-    struct cvs_gssapi_wrap_data *gd;
-
-    gd = (struct cvs_gssapi_wrap_data *) xmalloc (sizeof *gd);
-    gd->gcontext = gcontext;
-
-    return (packetizing_buffer_initialize
-	    (buf,
-	     input ? cvs_gssapi_wrap_input : NULL,
-	     input ? NULL : cvs_gssapi_wrap_output,
-	     gd,
-	     memory));
-}
-
-/* Unwrap data using GSSAPI.  */
-
-static int
-cvs_gssapi_wrap_input (fnclosure, input, output, size)
-     void *fnclosure;
-     const char *input;
-     char *output;
-     int size;
-{
-    struct cvs_gssapi_wrap_data *gd =
-	(struct cvs_gssapi_wrap_data *) fnclosure;
-    gss_buffer_desc inbuf, outbuf;
-    OM_uint32 stat_min;
-    int conf;
-
-    inbuf.value = (void *) input;
-    inbuf.length = size;
-
-    if (gss_unwrap (&stat_min, gd->gcontext, &inbuf, &outbuf, &conf, NULL)
-	!= GSS_S_COMPLETE)
-    {
-	error (1, 0, "gss_unwrap failed");
-    }
-
-    if (outbuf.length > size)
-	abort ();
-
-    memcpy (output, outbuf.value, outbuf.length);
-
-    /* The real packet size is stored in the data, so we don't need to
-       remember outbuf.length.  */
-
-    gss_release_buffer (&stat_min, &outbuf);
-
-    return 0;
-}
-
-/* Wrap data using GSSAPI.  */
-
-static int
-cvs_gssapi_wrap_output (fnclosure, input, output, size, translated)
-     void *fnclosure;
-     const char *input;
-     char *output;
-     int size;
-     int *translated;
-{
-    struct cvs_gssapi_wrap_data *gd =
-	(struct cvs_gssapi_wrap_data *) fnclosure;
-    gss_buffer_desc inbuf, outbuf;
-    OM_uint32 stat_min;
-    int conf_req, conf;
-
-    inbuf.value = (void *) input;
-    inbuf.length = size;
-
-#ifdef ENCRYPTION
-    conf_req = cvs_gssapi_encrypt;
-#else
-    conf_req = 0;
-#endif
-
-    if (gss_wrap (&stat_min, gd->gcontext, conf_req, GSS_C_QOP_DEFAULT,
-		  &inbuf, &conf, &outbuf) != GSS_S_COMPLETE)
-	error (1, 0, "gss_wrap failed");
-
-    /* The packetizing buffer only permits us to add 100 bytes.
-       FIXME: I don't know what, if anything, is guaranteed by GSSAPI.
-       This may need to be increased for a different GSSAPI
-       implementation, or we may need a different algorithm.  */
-    if (outbuf.length > size + 100)
-	abort ();
-
-    memcpy (output, outbuf.value, outbuf.length);
-
-    *translated = outbuf.length;
-
-    gss_release_buffer (&stat_min, &outbuf);
-
-    return 0;
-}
-
-#endif /* HAVE_GSSAPI */
 
 #ifdef ENCRYPTION
 

_


--alexm
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.